Skip to content

v0.9.0

Choose a tag to compare

@OpenComplaiCTO OpenComplaiCTO released this 08 Oct 17:10
· 6 commits to main since this release

Breaking

Upgrading from 0.8: the 0.9 upgrade guide lists who each change affects and what to do.

  • opencomplai check --sign with no signing key (no key file and no
    SIGNING_KEY_PRIVATE) now exits 2 before doing anything and writes no
    artifact; it used to write an unsigned one and exit by result. For the old
    behaviour, plus a warning, use the new --sign-if-available. The GitHub
    Actions and GitLab CI connectors pass --sign-if-available unless
    SIGNING_KEY_PRIVATE is set, so keyless CI keeps working. halt approve
    follows the same rule. A signing error under --sign is now exit 2, not a warning.
  • A manifest that contains a systems key or is a top-level JSON array is now rejected with exit 2 (one manifest describes one system). Before, systems was ignored with a warning.
  • Dossiers are no longer HMAC-signed. With only LOCAL_SIGNING_KEY_PATH set a
    dossier is now unsigned (with a warning) instead of hmac-local; only an
    Ed25519 key signs. opencomplai verify --kind dossier reports such a dossier as invalid
    with code UNSUPPORTED_SIGNATURE (exit 1): it cannot be verified, which is not a finding of tampering
    (CHECKSUM_MISMATCH, BAD_SIGNATURE). Treat older hmac-local dossiers as unverifiable.
  • The Docker Compose stack now publishes the Prometheus (9090) and Grafana
    (3001) host ports on 127.0.0.1 by default; they used to be reachable
    from other machines. The gateway port is unchanged. If you reach either
    UI from another host, set OBSERVABILITY_BIND_ADDR=0.0.0.0 in
    infra/compose/.env and recreate the containers. Prometheus has no
    authentication and Grafana allows anonymous Viewer access, so read the
    "Network exposure" section of the observability docs first.
  • GET /v1/evidence/ledger-history-tips no longer builds a tenant's whole
    chain in memory. Called without parameters it behaves as before for
    ledgers of up to 10,000 events and answers 413 above that, with a
    message pointing at the new limit (1 to 5000) and after_seq
    parameters. With limit it returns one page: genesis, tips for that
    page and next_after_seq (null on the last page); after_seq without
    limit is a 422. The gateway forwards those two parameters (and no
    others). GET /v1/evidence/verify-chain now walks the chain in batches
    with constant memory and returns the same result, except that an event
    with a null seq now makes it return false. tools/verify-ledger
    pages through the tips at 5000 per request, so an older copy of the tool
    cannot check a ledger above the 10,000-event cap; it also reports a
    rate-limited gateway (HTTP 429) as such instead of as a connectivity
    error.
  • The opencomplai-ai base install no longer pulls transformers and onnxruntime: the deterministic codebert-onnx matcher never imported them, and the optional [onnx] extra still installs what the Python-API ONNX export needs.
  • SIGNING_KEY_PRIVATE is now validated as base64 (line wraps and a trailing newline are still
    accepted); a value containing other stray characters raises SigningKeyError
    instead of being silently decoded.
  • Evidence vault: the status of each GET /v1/portfolio row changed from compliant to scan_passed.

Added

  • Docs: eight new concept pages (rule-set versioning, roles and applicability, backlog order, agents, incidents, regimes, high-risk acceptance and published schemas) and a published-schemas index that states the $id pattern, the pin and re-pin rules and the observed compatibility practice; the compatibility promise is marked as needing founder review.
  • CLI reference pages for push, approve and resume, keys, ai, info and version, deployer-pack and the multi-manifest portfolio mode of check, a row for every verify kind in the verify page's Kinds table, and the README group paragraph now names every command group. A test fails when a command or group has no page or nav entry, when a page names an option the command does not have, or when a registered verify kind has no row.
  • Homebrew formula file under packaging/homebrew/ with the tap steps; the tap itself is not yet published.
  • opencomplai gaps --map-to DORA|EBA shows a mapped-only citation per EU AI Act article (human column and a mapped_regimes JSON block). Citations, not verdicts: low confidence, flagged for founder review, no statuses or exit codes change, and the default output is unchanged.
  • CLI: opencomplai eval --provider-base-url points --provider at an OpenAI-compatible endpoint (https, or plain http only for localhost); other plain-http hosts and URLs with credentials are rejected before any request is sent.
  • opencomplai check emits metadata-only oversight, agents, QMS and incident summaries (counts, enums, days and log heads, no free text), signed with the artifact so push forwards them unchanged; new options --oversight-log, --agent-log and --incident-register. A source that cannot be read is skipped with a warning.
  • CI: templates/opencomplai.yml is a GitLab CI/CD component file (inputs for stage, image, version, manifest, extra arguments, SARIF and push); it is not yet published in the GitLab CI/CD Catalog, so include it from a GitLab project that hosts a copy (the guide's <GITLAB-GROUP>/<PROJECT> path is a placeholder); docs/ci/azure-pipelines.yml is an Azure Pipelines template. Both run opencomplai check with --sign-if-available, --report-junit and --summary-md, publish the JUnit result even when the check fails, and fail the job on exit codes 1 to 4; see the new CI for GitLab and Azure guide.
  • A bundled prompt-injection seed corpus (SEED_PROMPT_INJECTION_V1, 16 short self-authored prompts, prompts only) and opencomplai eval without --sample-set, which now runs it offline instead of exiting 2. Prompts only, so offline the adversarial evaluator is SKIPPED; with --provider the live completions are scored. The corpus is lexical, English only, low confidence and flagged for founder review.
  • opencomplai agents verify-log checks an agent decision log's chain and signatures, lists entries outside the declared mandate (recomputed from the manifest's agent inventory, never from the log's own flag), and with --vault appends one agent_action event per entry to the evidence vault; opencomplai verify --kind agent-log verifies the same file offline. The mandate-matching rules are a design choice, flagged low confidence for founder review.
  • ISO/IEC 42001:2023 as a native framework pack: --target ISO_IEC_42001 (also compliance_targets) assesses 65 clause and Annex A rows, attestation-led (Unverified until a provider attestation is recorded in framework_inputs); only four rows (Clause 6.1.2, Clause 6.1.3, A.6.2.7, A.8.2) also look for a matching document, and the worse status wins. Preview data: every row is low confidence and flagged for founder review; nothing certifies ISO conformity. No new ComplianceTarget value; EU-only and NIST-only output is unchanged.
  • opencomplai deployer-pack build seals the Art. 13(3) instructions-for-use JSON into one pack named deployer_pack_<12 hex>.json after its own SHA-256, optionally signed (--sign exits 2 before writing when no key is available; the same inputs and day give byte-identical bytes). opencomplai verify --kind deployer-pack checks it offline and tells an unsigned pack from a tampered one. New vendored deployer_pack JSON schema. check adds metadata-only summaries.packs (hash, date, signer key id, item counts) from ./deployer-pack/ when packs exist there.
  • Note: deployer packs are generated offline and never uploaded; only the summaries.packs metadata is pushed, never pack text, the system id or any free text.
  • GitHub Action integrations/github-action: runs opencomplai check through a pinned uvx call, posts one sticky pull request comment from the Markdown summary, can upload the SARIF verdict, and fails the job with the check exit code. A self-test in the maintainers' CI runs the five examples/gate-demo systems through it. Marketplace listing is pending.
  • A declared agent_inventory is carried verbatim into the Annex IV dossier, on the local path and through the doc-generator service (opencomplai docs generate and check send it). A manifest without it produces the same dossier bytes and checksum as before. push sends only its counts (summaries.agents), never the inventory itself.
  • README gains a "Who it is for" section and a new guide, guides/works-alongside.md, says how OpenComplAI runs beside eval tools, agent-governance toolkits and GRC platforms, what is not built, when an accepted high-risk system exits 0 (only when no other EU AI Act row is Missing), that a preview import of the Agent Governance Toolkit file-sink log exists (agents import-log, capped at Partial, no gate effect) and that no bridge to Promptfoo or GRC platforms is built. Statements about other products on guides/works-alongside.md are unverified against those products and need founder review.
  • GPAI providers: opencomplai recommend now also writes a copyright-policy outline and a training-content summary draft for an Art. 53 row (low confidence, flagged for review).
  • opencomplai docs generate --render md|pdf also writes the Annex IV dossier as Markdown and/or PDF next to the JSON (local mode). Placeholders and missing items are marked NOT PROVIDED and an incomplete dossier carries an INCOMPLETE banner; the JSON, checksum and exit codes are unchanged.
  • opencomplai agents attest signs a statement that a key holder vouches for one agent's mandate hash until an expiry (pinned agent_attestation/v1 schema, golden vectors for other verifiers). opencomplai verify --kind agent-attestation checks it offline (signature, expiry, optionally --expect mandate_sha256=... and --expect now=...). A verified attestation means a key holder signed that hash, not that the mandate is lawful or complete.
  • opencomplai diff A B compares two check --with-gaps artifacts or gap reports and lists added, removed and changed verdicts plus the rule-set version delta, in human, json or markdown. --fail-on-regression exits 1 when any verdict got worse; no new exit code.
  • opencomplai rules changelog [--since V] prints the rule-set history, oldest first, with each entry's source, confidence and founder-review flag.
  • opencomplai approve and resume append to a signed, hash-chained oversight-log.json in the state directory, one entry per approval and per resume, naming the approver's role. approve --role is checked against the roles of the manifest's human_oversight block (read from --manifest, default system-manifest.json; a missing file or a manifest without the block behaves as before), and resume --key signs the entry (an entry is written unsigned, with a warning, when no key resolves). opencomplai verify --kind oversight-log reports edited, deleted or reordered entries as invalid and unsigned entries as unsigned, and prints the chain head and count. Removal of the newest entries is detectable only against a head you stored elsewhere; refused resumes are not logged.
  • opencomplai instructions generate renders an Art. 13(3) instructions-for-use pack (JSON and Markdown) from the manifest, listing every point the manifest does not capture as not captured. Six new optional manifest fields (provider_contact, foreseeable_misuse, input_data_specifications, predetermined_changes, expected_lifetime_and_maintenance, log_interpretation) are omitted when unset, so existing manifests keep the same bytes. The point list is low-assurance and flagged for founder review.
  • GPAI provider pack data: a template for the summary of training content (Art. 53(1)(d)) and a map from the three Code of Practice chapters to the Art. 53 / 55 obligations, with a validator and a docs page. Every row is low confidence and flagged for founder review; nothing is checked against the primary texts, and the code is voluntary with no presumption of conformity.
  • SDK AgentDecisionLog: a hash-chained, optionally signed log of an agent's decisions that an auditor can verify offline. Raw tool inputs are never stored, only their SHA-256. Detecting truncation needs the head and count stored elsewhere.
  • opencomplai incident now appends every declare, classify, notify and close to a signed, hash-chained incident-log.json (structured fields only, never the free text) and moves the system state on declare and close, writing the log entry first; a refused transition keeps its entry and exits 1. New opencomplai incident template renders draft authority-report and downstream-notice templates, flagged as not legally reviewed, and opencomplai verify --kind incident-log checks the log.
  • opencomplai incident (declare, classify, notify, close, status, export) keeps a local incident register and computes notification deadline clocks at read time from an injected clock. The day counts per class are low-confidence data flagged for founder review. New optional incident_contacts manifest field, omitted when empty, so existing manifests keep the same bytes.
  • Regulatory timeline: checker results, gaps, check --with-gaps and report list when each obligation applies, from a new data file that includes the Digital Omnibus dates (Annex III 2027-12-02, Annex I 2028-08-02). Every entry has a source and a confidence and is flagged for founder review; dates not confirmed are shown as "date unconfirmed". Presentation only: JSON output, signed artifacts and the checker engine are unchanged.
  • opencomplai accept writes a signed high-risk acceptance record bound to the manifest fingerprint under .opencomplai/acceptances/ for you to commit. opencomplai check reads it from the repository (not ~/.opencomplai) and, when valid, no longer counts EU_AIA_ART6_HIGH_RISK as a failure; Missing EU AI Act rows still fail (see Changed) and Art. 5 stays exit 3, and a stale, unsigned or tampered record is reported and ignored. The record embeds its public key, so it proves integrity, not identity: pin signers with OPENCOMPLAI_TRUSTED_KEY_IDS. accept --trap-approval --change-context <context> writes a trap approval; together with a valid acceptance, a check run with the same --change-context then no longer exits 4 for that trap or halts the system. What an acceptance statement means is flagged for founder review.
  • opencomplai check names every recorded operator role (roles=provider, deployer; a single role still prints role=provider), and articles that do not apply to the recorded session get no control and are counted in one line under --with-gaps.
  • opencomplai qms generate --manifest fills clauses (e), (h) and (i) from the manifest's declared fields without changing any clause status, lists EN 18286 (published, not harmonised) with a cross-check against harmonised_standards, and adds a flagged simplified-profile note when organisation_size is micro. New CLI pages for qms and fria; the recommend page now lists the live templates. The note and the EN 18286 wording are low-confidence, flagged for founder review.
  • Optional structured human_oversight manifest block (roles, authority, intervention, conditions, training and evidence pointers, escalation). validate-manifest rejects duplicate or empty roles and warns when no role can intervene; the Art. 14 gap row reads it as a manifest declaration, PARTIAL at most and never MET. A declared record_keeping block now feeds the Art. 12 row the same way.
  • The structured human_oversight block now appears in Annex IV section 3 of the dossier on the local path and through the doc-generator and gateway. A manifest without the block produces the same dossier bytes and checksum as before, and section 3 counts structured roles toward provider_supplied only together with monitoring and incident-response entries.
  • A declared agent inventory feeds the Art. 12, 14, 15 and 26 gap rows (decision log reference, approval tools linked to an intervening oversight role, guardrails, mandate). When a scan report is supplied, an agent framework or MCP server the scan detects but the inventory does not declare is reported as a gap; declared-but-undetected items are only listed. Heuristic, PARTIAL at most, never MET; no change without the inventory block.
  • opencomplai agents inventory, check and report read the manifest's agent inventory offline (no vault, no network): list the agent tree, validate it and cross-check it against an optional scan report (exit 2 invalid, 1 findings, 0 none; evidence only, never a verdict), and report the inventory with a draft responsibility map that attributes GPAI model duties (Art. 53, 55) to the upstream model provider. Every map row is low confidence and flagged for founder review; the wording is unverified.
  • recommend: article-specific templates for Art. 5, 10, 11, 15, 16, 24, 25 and 43.
  • A recorded checker session can move articles that do not apply to the system out of the gap report. They are listed under not_applicable with the reason and create no controls. Without a session, or when none is recorded, the output is unchanged. This is an operator-role reading flagged for founder review, not a legal determination.
  • EU article rows for Art. 26, 49, 72 and 73. The files each row reads are listed under Changed; none of them reads Met.
  • The four services and the gateway report the release version (was 0.1.0-dev), the internal opencomplai-core and opencomplai-cli floors equal the current version, and the version parity test covers all nine manifests. The gateway version samples in the docs follow.
  • opencomplai check takes --report-junit, --sarif-output and --summary-md to write a JUnit XML report, SARIF 2.1.0 of the check verdict and the Markdown job summary. Exit codes are unchanged, and a report that cannot be written only warns.
  • opencomplai check -m a.json -m b.json (repeatable; globs are expanded by the CLI) runs each manifest as its own system and writes <output-dir>/<system_id>/ plus an unsigned portfolio-summary.json. The exit code is the worst child code (4 trap > 3 policy block > 2 validation > 1 control fail > 0). With --report-junit, --sarif-output or --summary-md every system writes to the same path, so only the last system's report is kept (fix planned for 0.9.1).
  • POST /v1/hitl/overrides/{override_id}/second-approval completes a dual-control override: a distinct second approver sends the first approval's rationale_hash and their own rationale, and an override_second_approved ledger event is written before it is accepted. The gateway now forwards requires_dual_approval on POST /v1/hitl/overrides. In API-key mode every caller is the same principal, so two distinct approvers need JWT/OIDC.
  • The scanner detects SageMaker, the Databricks SDK, Weights and Biases, Langfuse and Vertex AI. databricks-sdk is a general workspace client, so it can flag Databricks use that is not AI (dependency confidence stays capped at 0.7).
  • opencomplai check --output-dir writes the artifact and sidecars to a chosen directory.
  • opencomplai qms generate --scaffold writes 13 starter policy files under docs/qms/ that read as
    Unfilled until completed; existing files are never overwritten.
  • Optional agent_inventory manifest block (agents, tools, models, mandate, delegation,
    guardrails, logging, responsibility map). validate-manifest and init --section-extras-file
    deep-check it and exit 2 on a dangling parent, a parent cycle, delegation deeper than
    max_depth, a dangling delegate or an unknown tool:<name> reference.
  • The scanner reads MCP server names from .mcp.json / mcp.json (MCP_SERVER evidence),
    detects more agent frameworks (langgraph, openai-agents, pydantic-ai, smolagents,
    google-adk, Mastra, litellm, azure-ai-inference), and reports a package listed in two
    signal categories once per category.
  • JSON Schemas for the compliance artifact (scan_status_artifact.schema.json)
    and the gap report (gap_report.schema.json), generated from the models with
    scripts/generate_artifact_schemas.py and guarded by a drift test.
  • opencomplai checker --entity-type can be repeated (a provider that also
    deploys). The checker runs once per role and merges the results; the roles go
    to operator_roles, and the obligation ids and one rationale line per role to
    checker_session, and the Markdown and JSON exports gain a Role rationale
    section. --write-manifest on an existing manifest now appends roles instead
    of overwriting it and no longer asks for the system id. Runs without
    --entity-type write the same manifest keys as before.
  • opencomplai verify <file> checks a signed file and reports verified,
    unsigned (no signature present) or invalid (signature does not match).
    It exits 0 only for verified; unsigned and invalid both exit 1, and bad
    input (missing file, bad JSON, unknown --kind, missing public key) exits 2.
    Kinds: artifact, dossier, deployer-pack, oversight-log, agent-log, incident-log and
    agent-attestation.
  • opencomplai verify --kind dossier verifies an Annex IV dossier: an Ed25519
    signature over the bundle is verified, an unsigned dossier is reported
    unsigned, and a legacy HMAC-signed, tampered or wrong-key dossier is
    invalid with a distinct code (UNSUPPORTED_SIGNATURE, CHECKSUM_MISMATCH,
    BAD_SIGNATURE).
  • A key-management page (docs/src/security/key-management.md), which keys rotate --help pointed at under a wrong path; both docstrings now name the
    real path.
  • Additive model fields for the 0.9.0 features: SystemManifest.operator_roles,
    organisation_size and record_keeping; CheckerSessionRef.obligation_ids
    and rationale; GapReport.not_applicable; and provenance fields on the
    scan status artifact (rule_set_version, cli_version, schema_version,
    manifest_sha256, timestamp, policy_bundle_version). Every one is left
    out of serialised output while unset, so existing manifests, reports and
    signatures are byte-identical. opencomplai check stamps all six on the
    artifact before signing (see the stamping entries below).
  • Library only: a shared signed, append-only hash-chain log primitive
    (opencomplai_core.signed_log), a resolve_key helper that prefers the
    SIGNING_KEY_PRIVATE env key and fails loudly when no key exists, and five
    new signing domains (oversight log, agent log, incident log, attestation,
    deployer pack). approve and resume, incident, agents verify-log, agents attest and deployer-pack build use them.
  • opencomplai check now stamps rule_set_version, cli_version,
    schema_version and manifest_sha256 (SHA-256 of the manifest file, CRLF
    read as LF) on the artifact before signing, so the signature covers them and
    survives push.
  • GPAI providers: Annex XI and XII documentation template and artifact probes for Art. 53 and 55, active for a recorded GPAI checker session (low confidence, flagged for review).
  • --sort priority on gaps, report and recommend lists rows by regulatory deadline, then severity, then fix effort (default stays article order, and default output is unchanged). gaps -o json gains an ordered top-level backlog block only under --sort priority; articles keep article order. Effort (S/M/L) is a maintainer engineering estimate stored in template_map.json, not a compliance claim; deadlines come from the regulatory timeline and rows without one sort last.
  • New guide "CI recipes for other systems": Jenkins, Bitbucket Pipelines and CircleCI recipes, exit-code notifications and an artifact-archiving note. The CI guide now uses opencomplai push instead of a raw curl upload.

Changed

  • Framework wording and the standing line in the README, docs and package READMEs now match the shipped ISO/IEC 42001 pack (native, attestation-led, partial, unreviewed) and the mapped-only DORA and EBA citations.
  • Regulatory timeline dates that are still unverified (ninth prohibition, Annex III, Annex I) now show confidence low instead of medium in gaps, check and report output; the gap-source provenance records for the GPAI documentation probes, the adversarial evaluator and the Art. 12 manifest declaration are added, and Art. 26, 49, 72 and 73 map rows read low confidence. No verdict changes.
  • The pre-commit hooks now pin opencomplai-cli to the revision's own version, and CI exercises them with pre-commit try-repo.
  • CLI: agents import-log reads the JSONL file audit sink of a runtime governance toolkit offline and agents dispute-report renders what each agent was told, decided and why for a date window (also from a native agent decision log). The AGT field preset is a low-confidence preview (override with --map); imported evidence is labelled "format-valid, not verified", capped at Partial, and has no effect on check, gaps or exit codes.
  • Install scripts scripts/install.sh and scripts/install.ps1 install the CLI with uv and a uv-managed Python (3.11 floor), tested in the maintainers' CI on Linux and Windows.
  • CLI: opencomplai init --from-model-card README.md imports a Hugging Face model card's front matter offline into training_data_description, model_architecture and performance_metrics, recorded as attested (not verified) in the manifest's new imported_evidence; explicit flags win and verdicts are unchanged.
  • Examples: new examples/gate-demo/ sandbox with five fictional systems that exit 3, 4, 1, 1 and 0 under opencomplai check (prohibited, trap, high-risk, accepted, limited); the README and docs home now point at it instead of the legacy gateway walkthrough in examples/sample-system/.
  • The GitHub Actions and GitLab CI connectors pass flags to opencomplai check (from the command line and from OPENCOMPLAI_CHECK_ARGS), and --commit-ref defaults to the CI SHA (GITHUB_SHA / CI_COMMIT_SHA).
  • The four OSS API bundles (api/docs-gen, api/egress, api/evidence, api/risk) now pin their direct dependencies to the root uv.lock versions instead of floors (vercel-blob keeps its floor). The next OSS deploy installs these versions.
  • Art. 15 now also draws on EVAL_ADVERSARIAL_V1: a skipped adversarial evaluator makes an otherwise Met Art. 15 Unverified (worst status wins). A passing run on the bundled seed corpus reads Partial, never Met (heuristic evidence). EVAL_CALIBRATION_V1 stays deliberately unmapped: it is GPAI opt-in and skipped by default, so mapping it would pin Art. 15 at Unverified for every non-GPAI system. Rule-set 1.6.0 history updated.
  • The Art. 13 gap row for an INSTRUCTIONS.md or docs/instructions* file now checks for Art. 13(3) topic markers (intended purpose or instructions for use, plus oversight, misuse, limitation, accuracy, maintenance or contact): a bare file reads Partial at 0.35 instead of 0.55, one with the markers Partial at 0.6, never Met. Heuristic keywords, low confidence, flagged for founder review; gaps output for a bare file changes.
  • Art. 12 now reads an event-log file (oversight-log.json anywhere in the repository): Partial at most, never Met, and Missing when none is found (it was Unverified), so the gap, check and report goldens moved. recommend now writes the Art. 12 template. The probe is low confidence and flagged for founder review.
  • recommend writes an instructions-for-use checklist (art13-instructions_for_use.md) for Art. 13 instead of the Art. 50 disclosure stub. Flagged for founder review.
  • opencomplai check with a valid acceptance record: Missing EU AI Act rows now fail the check (exit 1, the article ids listed in failed_controls; the Art. 6 row is not counted) instead of the Art. 6 failure, and a valid trap approval for the same --change-context turns exit 4 into that result without halting the system. Art. 5 stays exit 3 and a stale or invalid record stays exit 1. Behaviour changes only when a record exists. Policy choice flagged for founder review: an acceptance acknowledges the classification and removes no other obligation, which is why Missing rows gate. The CI connectors read the artifact result and inherit this.
  • The Art. 11, 26, 49 and 50 gap rows read real files: a dossier_*.json (Art. 11), a deployer use log (Art. 26), an EU database registration file (Art. 49) and the Art. 50 disclosure files that recommend writes. They show Missing without one and Partial with one, never Met; the Art. 13 notice does not count for Art. 50. Conventions flagged for founder review, not legal tests.
  • The gap, report and check golden outputs, the EU AI Act and NIST AI RMF framework data_version values and the principles page change for the new article rows.
  • Checker content: corrected citations (authorised representative Art. 22, deployer Art. 26), widened the FRIA question and obligation to Annex III 5(b)/5(c) deployers (Annex III systems only), added the Art. 6(4)/49(2) duty for providers relying on the Art. 6(3) derogation, and reworded social scoring in Art. 5 with the ninth prohibition flagged for review.
  • The checker version is now checker-2026-10-05, and the docs widget, checker-local.html and the golden vectors are synced to it. The needs_founder_review text comes from the entry above.
  • The root compliance-artifact.json is no longer tracked.
  • RULE_SET_VERSION bumped to 1.6.0 and ruleset_history.json added.
  • The codebert-onnx AI backend is now labelled as what it is: a
    deterministic code-signal matcher with fixed confidence values, not a
    CodeBERT model on ONNX Runtime. In MODEL_CATALOG["codebert-onnx"]
    (public API of opencomplai-ai) the values changed: display_name is
    now "Deterministic code-signal matcher (no model)" (was "CodeBERT
    code-signal matcher (deterministic, no download)"), runtime is
    deterministic (was onnxruntime) and license is AGPL-3.0-only
    (was MIT). ai status and the interactive ai configure picker
    show the new values, and so does any code that reads the catalog. The
    id is unchanged, so existing configs and annotations keep working.
  • ai status no longer prints a "model not yet downloaded" line for
    codebert-onnx or saas, which have nothing to download. It shows the
    cache directory, size and files as before, so GGUF models downloaded
    earlier stay visible.
  • The docs no longer tell users to install optimum[onnxruntime],
    expect a ~440 MB download, or read conf as a cosine similarity; only
    the GGUF models need the [deep] extra and a download. The prompt of
    the optional, Python-API-only ONNX export now names the export and says
    scans do not use its output.
  • Art. 17(1)(a)-(m) clause files now need content to count. A file with no
    matching keyword in its body, under 8 words of body text, or still holding a
    _fill in_ placeholder reads Unfilled (not Present) in qms generate and
    recommend; qms generate adds a Confidence column and unfilled_count. The
    whole-article Art. 17 row appends the per-clause counts once any clause file
    exists, and is never MET.
  • Art. 72 and 73 now read a post-market monitoring plan and a root incident-log.json, shown Missing when absent and never Met; two new recommend templates (post-market monitoring plan, serious incident report); the gap, check and report golden outputs are regenerated.
  • Internal CI hygiene: third-party GitHub Actions are pinned to full commit SHAs, every workflow declares least-privilege permissions, uv sync is --locked, the actionlint ignores are gone, and new DCO and secret-scan workflows plus a CODEOWNERS file are added. No behaviour change for users.
  • opencomplai serve page documents the PROJECT_ROOT argument, --host and --port, the loopback-only rule and the
    serve extra (thanks to @HarshRajSinghania, public pull request 89).
  • ControlCatalogEntry gains optional source, confidence and needs_founder_review fields. The evidence freshness windows for Art. 26, 49, 72 and 73 are placeholders and now say so (confidence low, flagged for founder review). Framework-pack rows carry the same fields from their data.
  • Node.js 24 LTS replaces Node.js 20, which reached end of life in April 2026: the gateway-api image builds on node:24-alpine (pinned by digest), every CI job runs Node 24, and contributors need Node.js 24.

Removed

  • .github/workflows/compliance-gate.yml.example: it pointed at an opencomplai/compliance-action@v1 repository and a gateway script that do not exist. Use integrations/github-action instead.

Fixed

  • The doc-generator README no longer says LOCAL_SIGNING_KEY_PATH signs dossiers (it signs nothing; dossiers are Ed25519-signed or unsigned) or that LOG_RETENTION_DAYS is recorded in the dossier (it is not read), the same claim is corrected in two source docstrings, and a test now scans shipped READMEs, the compose file and source docstrings for these claims.
  • Both pre-commit hooks failed to install because pre-commit builds the repository root and it could not be built; the root now installs as an empty package, and a test builds it.
  • Release workflow and security docs: publish-pypi.yml now refuses a tag that differs from the four package versions, runs the wheel smoke test before any upload, generates a CycloneDX SBOM per package (workflow artifact only) and supports a workflow_dispatch dry run that publishes nothing. SECURITY.md, the supply-chain page and the security guide no longer claim Ed25519-signed releases, npm audit, SLSA provenance for wheels or published 1.0.0 images, and a test keeps the claims in step with the workflows.
  • uv tool install opencomplai and pipx install opencomplai now install the opencomplai executable; package metadata gains classifiers and project URLs.
  • Docs wording corrected: the JS SDK pages say no SDK ships in this release, version samples are version-neutral, the JS/TS scanner coverage is described accurately, and the package READMEs carry the framework standing line.
  • gaps (several targets) and the HTML report show the NIST AI RMF subcategory text instead of an em dash in the Title column.
  • The HTML report's status/text filter now covers every framework table, not only the EU one.
  • Removed the unused _print_human helper from the CLI.
  • Service-mode check sends compliance_targets and framework_inputs to manifest validation, so a bad target set is rejected.
  • Model downloads for the AI plugin are now pinned to a commit and verified by sha256, so non-interactive GGUF downloads no longer refuse as unpinned. The phi-3.5-mini download now points at an existing repository (bartowski/Phi-3.5-mini-instruct-GGUF; the previous one does not exist).
  • A control waived by a manifest exclusion is re-derived once the exclusion is removed; manual waivers are left alone (new waiver_source field, vault migration 0010).
  • CLI input robustness. gaps and recommend --scan-report read what scan -o json prints
    (the output envelope or a bare report; UTF-8, UTF-8 with BOM, or the UTF-16 a PowerShell 5.1
    redirect writes). scan, gaps and check with -o json write one JSON document to stdout
    and send every other line to stderr. A wrongly typed opencomplai.yaml value (scan.fail_on,
    scan.framework_detectors, scan.allowlisted_categories, eval.threshold_overrides) exits 2
    with a clear message. An unknown key in the manifest warns on stderr, and --strict on gaps,
    scan and check makes it exit 2. check validates framework_inputs and --baseline
    before it writes evidence or a halt record, so bad input exits 2 and leaves nothing behind.
  • Art. 50 limited-risk pack: machine-readable marking of synthetic output is now cited as Art.50(2) (provider duty) and deepfake disclosure as a deployer duty; scan output now cites Art.50(4), first subparagraph / Art.50(4), second subparagraph. Paragraph and actor are flagged for founder review.
  • Artifact probes match real globs, skip .venv, node_modules and .git, and report each
    file once (a risk register found by two patterns is now "1 path(s)").
  • The Annex IV dossier no longer claims that logging and the evidence vault are
    enabled and that logs are kept 2555 days for every system. The Article 12
    record-keeping block now holds only what the manifest's record_keeping
    block declares: without it, logging and the vault read false, no
    log_retention_days key appears and provider_supplied is false;
    LOG_RETENTION_DAYS is no longer read. A failed Ed25519 signing attempt now
    warns instead of silently leaving the dossier unsigned.
  • A scan finding alone no longer reads Met in opencomplai gaps. A scan row is
    Met only when a mapped finding falls inside the declared Annex III areas;
    agent_framework, mcp_server and pii_dataflow detections (and findings
    with no mapped area) now read Unverified ("detected, no compliance
    verdict"), so they no longer make a control satisfied.
  • check --sign signed artifacts survive opencomplai push: check now
    stamps timestamp and policy_bundle_version before signing, so push no
    longer changes the signed payload and drops the signature.
  • check resolves commit_ref once (CI commit variable, then git rev-parse HEAD, else unresolved) instead of recording the literal HEAD; the
    artifact, gap_report and halt record agree.
  • check --sign and halt approve honour SIGNING_KEY_PRIVATE; a key file
    is no longer required. An explicit approve --key that does not exist still
    exits 2.
  • Docs and badge wording corrected to state only what the code does: the
    README and docs no longer claim audit-ready logs, SSO, additional rule
    engines, real-time webhooks or a closed beta; --scan-mode, the air-gap
    image recipe and the CI key requirement are described as they behave. The
    badge SVG now reads "OpenComplAI | scan passed".
  • The "AI intent skipped" message (and the "opencomplai-ai is not
    installed" error) printed pip install 'opencomplai-ai' because Rich
    read [deep] as markup and dropped it. They now show
    pip install 'opencomplai-ai[deep]'.
  • Compliance-artifact.json, scan-report.json and eval-report.json are now written as UTF-8, so Windows readers no longer fail on them.
  • QMS clause files written by qms generate --scaffold no longer read as Present for Art. 17(1)(k) and (m) when only their _fill in_ lines were deleted: the scaffold's own prompt questions are ignored when a clause file is checked for content, in qms generate, recommend, gaps and check.
  • The GitHub Action's sticky pull-request comment, when the summary is over 60000 bytes, is now cut on a character boundary instead of inside a multi-byte character, so the posted comment stays valid UTF-8 and still ends with the truncation note.
  • verify now exits 2 on an --expect key the kind does not use (artifact, dossier and deployer-pack take none), the oversight, incident and agent log kinds check --expect head= and --expect count= against the recorded anchor, and an empty log is reported invalid instead of verified, in verify and in agents verify-log.
  • Docs and help: the FAQ, the gaps reference and gaps --help, the data-model page and the ComplianceTarget docstring (and the published dossier JSON schema that copies it) now describe ISO/IEC 42001 as the native ISO_IEC_42001 pack, attestation-led (partial, unreviewed), instead of mapped only; and docs.opencomplai.com/cli/ now has a CLI reference index.
  • gaps, scan, check, accept and the agents inventory, agents check and agents report commands read the manifest as UTF-8, so a manifest with non-ASCII text no longer fails under a Windows code page. qms generate --manifest (and its --scan-report and --eval-report inputs) and the role check of approve --role still read files in the locale encoding.
  • sync/verify-sbom.sh checks the signing identity of the workflow that actually builds the release images (supply-chain.yml in Opencomplai/opencomplai-enterprise), accepts <service>:<version> and expands it to ghcr.io/opencomplai/opencomplai-enterprise/<service>, and takes OPENCOMPLAI_RELEASE_REPO for images built elsewhere. Verification works only if the GHCR packages are public.

Security

  • Gateway-api transitive dependencies are refreshed so all five service images pass the release vulnerability scan; the scan is recorded in infra/docker/TRIVY-LAST-RUN.md.

Full notes: CHANGELOG.md