Skip to content

feat: aicertify demo command + Markdown renderer bugfix (v0.7.1)#63

Merged
kmadan merged 3 commits into
mainfrom
feat/demo-command
May 14, 2026
Merged

feat: aicertify demo command + Markdown renderer bugfix (v0.7.1)#63
kmadan merged 3 commits into
mainfrom
feat/demo-command

Conversation

@kmadan
Copy link
Copy Markdown
Contributor

@kmadan kmadan commented May 14, 2026

Summary

Make pip install aicertify && aicertify demo actually work as a self-contained Quick Start. Three logical commits in one PR.

1. feat(cli): aicertify demo subcommand

The pre-existing CLI required --contract and --policy with no bundled sample, so the README's Quick Start line was not literally executable after pip install aicertify. This adds:

  • aicertify demo — loads a bundled sample contract (aicertify/_demo/sample_contract.json), runs the canonical evaluation pipeline against the EU AI Act policy set, and writes a Markdown report to the cwd. No contract file, no API keys required for the OPA path.
  • aicertify evaluate — the previous flat CLI, now under an explicit subcommand.
  • Backwards-compat shim: aicertify --contract X --policy Y … (pre-0.7.1 invocation) is silently rewritten to aicertify evaluate … so old scripts keep working.
  • Friendly platform-aware OPA-missing message instead of a stack trace.

The demo uses the same code path as aicertify evaluate and python examples/quickstart.py. Not a hand-crafted approximation — what users see in the demo report is what the canonical pipeline produces for any contract.

2. fix(report-generation): Markdown renderer bugs

Two pre-existing bugs blocked Markdown (and therefore PDF) reports from being generated whenever an EvaluationReport had any metric groups:

  • MetricGroup.metrics is List[Dict[str, Any]] per the model schema, populated as dicts by create_metric_group(). The renderer was using attribute access (metric.display_name, metric.value) → AttributeError.
  • EvaluationReport.summary is Dict[str, Any]. The renderer was appending it directly to a list of markdown lines that gets "\n".join-ed at the end → TypeError: sequence item N: expected str instance, dict found.

Affects every user who ran any --report-format markdown or --report-format pdf evaluation that produced metrics, not just the demo.

3. docs+release: v0.7.1

  • All 5 READMEs (en + zh-CN + ja-JP + ko-KR + hi-IN): Quick Start collapses to 3 honest, executable commands.
  • CHANGELOG: 0.7.1 entry.
  • AGENTS.md: useful commands updated.
  • Version bump to 0.7.1.

Test plan

  • Fresh venv + editable install + aicertify demo (with OPENAI_API_KEY in env) → ~30s run with full ML evaluator pipeline, clean Markdown report written
  • Same, with OPENAI_API_KEY unset → ~10s OPA-only run, same canonical Markdown report
  • aicertify demo --format json → JSON path still works
  • Generated report verified by hand (4 EU AI Act policies, pass/fail verdicts, metric breakdown, disclaimer)
  • All 3 commits clean — zero Co-Authored-By trailers
  • Manual after merge: bump tag v0.7.1, build wheel, twine upload dist/* to PyPI

Notes for the maintainer

  • The bundled sample contract uses a fixed UUID (00000000-0000-0000-0000-000000000d3e) and the required model_info field — verified against AiCertifyContract Pydantic schema.
  • The OPA binary still needs to be installed separately (~80 MB). The demo detects its absence and prints a copy-paste install command for Linux / macOS / Windows.
  • After this lands, the next PyPI release (v0.7.1) is what makes pip install aicertify && aicertify demo work for end users. v0.7.0 users will not have the demo subcommand until they upgrade.

kmadan added 3 commits May 14, 2026 19:39
The pre-existing CLI was a flat one-shot that required both --contract
and --policy, with no bundled sample. After a fresh `pip install
aicertify`, a user could not run anything without cloning the repo for
examples/sample_contract.json. The README's "Quick Start" line was
therefore not actually executable.

This change adds:

- `aicertify demo` — a self-contained subcommand. Loads a bundled
  sample contract (aicertify/_demo/sample_contract.json), runs the
  canonical evaluation pipeline against the EU AI Act policy set, and
  writes a Markdown report to the current working directory. Requires
  only the `opa` binary on PATH (no contract file, no API keys for
  the OPA path).
- `aicertify evaluate` — the previous flat CLI behaviour, now under an
  explicit subcommand.
- Backwards-compat shim: `aicertify --contract X --policy Y …` (the
  pre-0.7.1 invocation) is silently rewritten to `aicertify evaluate
  --contract X --policy Y …`, so old scripts keep working.
- Friendly platform-aware install message when the `opa` binary is not
  on PATH — replaces the previous stack trace.

The demo uses the same code path as `aicertify evaluate` and as
`python examples/quickstart.py`; it is not a hand-crafted approximation.
What a user sees in the demo report is what the canonical pipeline
produces.
Two pre-existing bugs in the Markdown report renderer prevented any
EvaluationReport from being formatted whenever metric groups were
present. The same path is shared by the PDF report (which converts
Markdown internally), so PDF reports were affected too.

1. `MetricGroup.metrics` is declared as `List[Dict[str, Any]]` in
   aicertify/models/report.py and `create_metric_group()` populates
   it with dicts. The renderer was reaching into each metric with
   attribute access (`metric.display_name`, `metric.value`), raising
   `AttributeError: 'dict' object has no attribute 'display_name'`
   the moment a policy returned any metric.

2. `EvaluationReport.summary` is declared as `Dict[str, Any]` and is
   populated as such by create_evaluation_report(). The renderer was
   appending it directly to a list of markdown lines that gets `"\n".
   join`-ed at the end, causing `TypeError: sequence item N: expected
   str instance, dict found`. Now the summary dict is rendered as one
   bullet per key, with display-cased labels.

Reproducible with:

  aicertify demo                                    # before: crashed
  aicertify evaluate --contract X --policy eu_ai_act \\
                     --report-format markdown        # before: crashed

After this fix, both paths produce a clean Markdown audit report. The
JSON path was unaffected (it never went through this renderer) and
keeps working as before.
- README.md and 4 translated READMEs (zh-CN, ja-JP, ko-KR, hi-IN):
  collapse the Quick Start to three honest, executable commands:

      pip install aicertify                       # ~3-5 min first install
      curl -L … opa … && chmod +x …               # one-time OPA binary
      aicertify demo                              # ~10 sec, no API keys

  Removes the previous "git clone the repo + python examples/quickstart.py"
  workaround. Adds an explicit pointer to the heavier examples/* path for
  users who want LangFair / DeepEval / PDF output.

- CHANGELOG: 0.7.1 entry documenting the demo subcommand, the back-compat
  shim, the OPA-binary detection UX, and the Markdown renderer bug fixes.

- AGENTS.md: "Useful commands" updated — `aicertify demo` is now the
  fastest sanity check; `aicertify evaluate` example replaces the path-y
  `python -m aicertify.cli --contract … --policy …` legacy invocation.

- Version bump to 0.7.1 in pyproject.toml + aicertify/__init__.py.
@github-actions github-actions Bot added 📝 documentation Improvements or additions to documentation 🚀 enhancement New feature or request labels May 14, 2026
@kmadan kmadan merged commit 3c89bd7 into main May 14, 2026
6 checks passed
@kmadan kmadan deleted the feat/demo-command branch May 14, 2026 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📝 documentation Improvements or additions to documentation 🚀 enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant