Skip to content

Releases: Polycentric-Labs/evidentia

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 21:08
Immutable release. Only release title and notes can be modified.
v0.11.0
828a7f9

Highlights

Theme: The federal wave — three verified federal firsts on machine-readable rails. v0.11.0 ships the re-cut Wave 1-2 scope of the v0.11 plan: FedRAMP CR26 Security Decision Record emissionevidentia conmon ksi emits the SDR keySecurityIndicators block (10 families / 46 KSIs) conformant to FedRAMP's official 2026-06-24 schemas, vendored at pinned upstream SHAs (re-verified at the schemas' 1.0.0 graduation) and drift-watched weekly — the first production-grade open-source emitter of the CR26 SDR format, and the first from any established tool; OMB M-25-21 minimum-practice tracking — structured per-practice status for the memo's seven §4(b) practices with CAIO waiver objects carrying the annual re-certification and 30-day OMB-report clocks, structure the federal AI Use Case Inventory lacks entirely; and OMB M-25-22 acquisition-lifecycle tracking — Evidentia's first procurement surface, modeling the memo's six §4 phases as auditable records with the §4(a) high-impact determination tie-in. The cycle's OSCAL 1.2.1 → 1.2.2 evaluation closed with a ratified DEFER-WITH-TRIGGER verdict (emitted documents stay on 1.2.1; adoption triggers armed), and a pre-release claim-accuracy sweep re-verified every public claim against primary sources (parity restated at the live 93.4%; machine-gated counts; first-mover registry updated with explicit caveats). Test suite: 4,947 passed; mypy strict clean; ruff clean.

Deferred (ratified v0.12 plan re-cut, 2026-07-18 — see docs/releases/plans/v0.12-plan.md): Wave 4 phase 3 (EU-AI-Act ↔ ISO 42001 crosswalk) → v0.12-if-capacity; Wave 4 phases 1/2/4, Wave 3 DORA, and the medical-device traceability enrichment → v1.1; Waves 5-6 (OpenVEX/VSA, SARIF collector, auto-review) → post-1.0; arXiv preprint timing = open decision. The GUI parity pass for the five federal api-only verbs leads v0.12.

Changed

  • FedRAMP CR26 vendored schemas re-synced to the upstream 1.0.0 graduation (#198)
    (FedRAMP/schemas @ ae0dc43e, 2026-07-15 — caught by a manual drift probe
    inside the weekly sentinel's blind window): the Security Decision Record
    schema's $schemaVersion moved 0.1.0 → 1.0.0, fixing the Public-Preview
    draft's vacuous items wrapper nesting so the per-KSI constraints now
    actually enforce — constraints evidentia conmon ksi output already
    satisfies (emitted documents re-validated against upstream 1.0.0, zero
    emitter changes). fedramp-common-definitions re-vendored byte-identical at
    0.1.1; UPSTREAM.json pins refreshed (all 11 tracked $schemaVersions).
    The documented one-line cross-document $ref delta is retained — upstream
    fix PR #4 remains unmerged; the 1.0.0 graduation did not include it.

  • Claim-accuracy sweep across the public docs (#197) (pre-v0.11.0; every change
    traced to the 2026-07-15 primary-source verification pass): CLI↔GUI parity
    claims recomputed from the manifest (98% → 93.4%, 99 full / 7 api-only /
    0 cli-only — README badge, parity-coverage.md regenerated, positioning,
    enterprise-grade, ROADMAP); count drift fixed to the machine-gated truths
    (96 catalogs / 16 crosswalks / 14 collectors / 13 MCP tools / 4,900+ tests);
    the FedRAMP first-mover registry row updated to the shipped conmon ksi
    verb + CR26 SDR schema framing with explicit caveats, and two new
    first-mover rows registered (M-25-21 practice/waiver-clock tracking,
    M-25-22 acquisition lifecycle); the CISA SbD Pledge described as an
    alignment self-attestation everywhere (never a signatory claim; formal
    signing planned at v1.0); OSCAL-MCP landscape statements aligned to "one
    of several" (CISO Assistant ca_mcp + trestle-mcp exist); the stale
    "Sept 30 2026 FedRAMP mandate" framing replaced with CR26 FRC-CSO-JSN
    (mandatory 2027-01-01) + NTC-0009 (2027-11-01, Class D High,
    format-agnostic — never an "OSCAL mandate"); the unverifiable "18 months
    ahead" claim removed; GovReady-Q described as dormant, not defunct;
    OpenVEX / VSA rows moved to planned-tense with no version commitment; the
    federal-SI walk-through refreshed (M-25-21 primary lens consistently,
    M-26-05 rescission of the M-22-18 self-attestation form, the v0.11
    federal-wave surfaces added, resolved limitations pruned).

Fixed

  • Pre-tag review hardening of the Wave-2 federal surfaces (found by the
    v0.11.0 /pre-release-review security fan-out, fixed before tag):
    ai-gov set-high-impact no longer silently discards recorded M-25-21
    practice status + CAIO waiver provenance when a later call amends the
    determination's bases/rationale — the practices are carried forward per the
    model's retention contract (API + CLI; regression tests on both surfaces).
    conmon ksi now rejects duplicate KSI indicator keys in the status file
    (previously last-wins-merged, silently dropping a block from the emitted
    SDR — while still honoring legal YAML merge keys), warns when a
    --state-file anchor keys a cadence slug that matches no
    bundled cadence (its dates would otherwise be silently absent), and writes
    --out atomically with a clean error contract instead of a raw traceback on
    a missing/unwritable path. PracticeWaiver.issued_by and
    AIAcquisition.linked_system_id gained the max_length bound every sibling
    string field already carries.

Added

  • OMB M-25-22 AI acquisition-lifecycle tracking — evidentia ai-gov acquisition (#196) (v0.11 Wave 2; spec ratified 2026-07-14, lifecycle phases
    verified verbatim against the memo text): Evidentia's first procurement
    surface. AIAcquisition records track a procurement through the six §4
    phases (Identification of Requirements → Market Research & Planning →
    Solicitation Development → Selection and Award → Contract Administration
    → Contract Closeout) with status-only per-phase records (M-25-22 defines
    no waiver mechanism) and carry the §4(a) initial likely-high-impact
    determination in M-25-21 vocabulary plus an optional AI-registry link
    (acquisitions may precede registration). AIAcquisitionStore clones the
    registry-store pattern (UUID filenames, traversal guard, atomic writes,
    trusted-directory boundary, EVIDENTIA_AI_ACQUISITION_DIR).
    CLI ai-gov acquisition register|list|show|set-phase + API mirror under
    /api/ai-gov/acquisitions (parity api-only pending the next GUI pass);
    acquisition_progress() roll-up never fabricates a status for an
    unrecorded phase; AI_ACQUISITION_REGISTERED /
    AI_ACQUISITION_PHASE_RECORDED audit events.

  • OMB M-25-21 minimum-practice tracking — evidentia ai-gov set-practice
    (#195) (v0.11 Wave 2): fills the per-practice extension point reserved at
    v0.10.12. OMBHighImpactAssessment gains structured status for the seven
    §4(b) minimum risk-management practices (practice headings verified
    against the memo text), each recordable as implemented / in_progress /
    not_started / waived — waived requires a §4(a)(ii) CAIO waiver
    record
    (written determination, granting official, annual
    re-certification date, 30-day OMB report date), enforced by a model
    validator. practice_compliance() rolls up recorded / missing /
    satisfied without ever inventing a status for an unrecorded practice;
    waiver_certification_due() / waiver_omb_report_overdue() evaluate the
    memo's two waiver clocks. Ships as CLI verb + API mirror
    (POST /api/ai-gov/systems/{id}/set-practice, parity api-only pending
    the next GUI pass) + AI_SYSTEM_PRACTICE_RECORDED audit event. Persisted
    v0.10.12-era assessments load unchanged (the field defaults to empty —
    reported as missing, never as satisfied).

  • FedRAMP CR26 KSI emission — evidentia conmon ksi (#194) (v0.11 Wave 2,
    target re-verified against the live CR26 stack + ratified 2026-07-14; see
    the plan's §Wave 2 re-base record): emits the keySecurityIndicators
    block of a CR26 Security Decision Record as a standalone JSON
    document, validated OFFLINE against
    fedramp-security-decision-record-schema-2026-06-24.json before writing
    (rules SDR-CSO-FRR / SDR-CSX-KSI / SDR-CSO-MTD; in force for 20x since
    2026-07-04). Ships with:

    • the fedramp-ksi-2026 bundled catalog (10 families / 46 Key
      Security Indicators, generated verbatim from FedRAMP/rules
      fedramp-consolidated-rules.json at a pinned commit by
      scripts/catalogs/gen_fedramp_ksi.py, --check drift mode included)
      plus a KSI→NIST 800-53 Rev 5 crosswalk extracted from the upstream
      per-indicator controls declarations (base-control granularity;
      enhancement citations preserved verbatim in notes);
    • vendored CR26 schemas under evidentia_core/fedramp/schemas/ with
      full provenance pins (UPSTREAM.json) and one documented local delta:
      upstream publishes every cross-document $ref with the JSON Pointer in
      the URI path, which no conforming JSON Schema 2020-12 validator can
      resolve (FedRAMP/schemas#3; fix PR #4 unmerged) — the vendored copy
      moves the pointer into the fragment;
    • CONMON cadence integration: persistence_cycles entries in the
      operator's KSI status file render the SDR-CSX-KSI "cycle for measures
      implemented persistently" statements from the same cadence calendar the
      rest of evidentia conmon runs on (last-completed / next-due dates via
      --state-file);
    • the fedramp-schema-watch weekly sentinel (Wed 09:17 UTC):
      compares live FedRAMP/rules + FedRAMP/schemas against the
      UPSTREAM.json pins — NOTICE drift opens/updates a tracking issue; a KSI
      content change, MAJOR $schemaVersion bump, or a new dated ruleset
      (CR27) also reds the run. Both upstream repos are 2026 Public Preview
      drafts with same-day churn observed at vendor time — the pins rot
      without a watcher.
    • Operator doc: docs/fedramp-ksi.md. jsonschema + referencing
      promoted from transitive to direct evidentia-core dependencies...
Read more

v0.10.18

Choose a tag to compare

@github-actions github-actions released this 14 Jul 22:43
Immutable release. Only release title and notes can be modified.
v0.10.18
b6e83ee

Highlights

Theme: Container rebuild on a fresh hardened base (day-N CVE response). A rebuild-only patch fired by the post-publish rescan's fixable-only gate: the 2026-07-13 weekly rescan of the published v0.10.17 image surfaced DEBIAN-CVE-2026-34743 (xz-utils/liblzma 5.8.1-1, Medium 5.3) with a fix published upstream (5.8.1-1+deb13u1), and the standing policy is "a fix is now available → rebuild the published image on a fresh base". Both pinned bases move to their current digests (the same drift the base-freshness sentinel flagged in issue #182) and the image is rebuilt, smoke-tested, re-signed, and re-attested end-to-end; the post-publish rescan re-verifies the published image's CVE posture after release. This tag also ships everything that merged to main between v0.10.17 and the tag: the v0.11 cycle-open gate work (ROADMAP-currency gate + ROADMAP restructure, previously tracked as Unreleased) and the entire v0.11 hygiene track (H1–H6, below) — the hygiene PRs merged ahead of the tag, so the v0.11 plan's release boundary re-cuts to v0.11.0 = Waves 1–2. No package (packages/*/src) code changes beyond the version bump.

Added

  • ROADMAP-currency gate (scripts/check_roadmap_currency.py) — the
    roadmap's status headings must agree with the CHANGELOG's shipped
    ## [X.Y.Z] blocks: nothing PLANNED/RESERVED that has shipped, no SHIPPED
    entries inside a PLANNED cycle umbrella, exactly one open cycle, and the
    open cycle must link an on-disk plan doc (plus an advisory that every
    release in the latest cycle has its entry). CHANGELOG blocks are the
    source of truth — deliberately not git tags, which the shallow CI checkout
    cannot see and which unpublished ghost tags would poison. Runs in the
    required consistency scope and the pre-push hook, and was observed
    firing on the real v0.10.x roadmap drift (four shipped releases
    mis-marked PLANNED) before the tree was fixed. Two prose currency anchors
    registered alongside it (the deprecation-calendar closing line and the
    enterprise-grade maintenance-summary claim), so those live lines now
    force-update on every version bump and hard-fail when stale. Recorded as
    lesson 11 in docs/engineering-practices.md: a doc's currency claim is
    a gate or it is a lie.

Added (v0.11 hygiene track — H1–H6, merged ahead of this tag)

  • H2 — dependency-review.yml: GitHub-native diff-level dependency gate on
    every PR (actions/dependency-review-action v5.0.0, SHA-pinned,
    fail-on-severity: low) — blocks a PR introducing a known-vulnerable
    dependency before it lands in a lockfile.
  • H3 — verify-recipes.yml: the published consumer-verification recipes
    (PEP 740 wheel attestations, cosign signature + SLSA provenance,
    gh attestation verify, SBOM download + osv-scan) now run weekly against
    the latest Release with coverage assertions (8/8 wheels) and a recipe-drift
    guard coupling the workflow to docs/verification.md. Its dry-run already
    fixed real doc rot: the SBOM recipe moves off the deprecated
    osv-scanner scan --sbom form to scan source -L.
  • H4 — release-SBOM enrichment + NTIA gate (enrich_release_sbom.py +
    check_sbom_ntia.py, wired into release.yml and active in THIS release's
    build): the release-asset SBOM gains metadata.supplier/authors and
    first-party supplier/publisher/purl identity (osv-scanner previously
    skipped all 8 evidentia* components — "Neither CPE nor PURL found"), then
    an NTIA minimum-elements gate fails the build if the SBOM is structurally
    present but useless. Observed firing with 18 findings on the real v0.10.17
    SBOM before the enrichment.
  • H5 — uv-pilot-watch.yml: weekly graduation sentinel for the uv audit
    / UV_MALWARE_CHECK preview pilots (functional no-preview-flag probe + uv
    CHANGELOG stabilization scan; detect-and-nudge, never a gate).
  • H6 — four small deferrals: #18 changelog-vs-commits advisory diff (in
    verify-changelog.yml, always-exit-0); security-insights.yml CI-validated
    against the official OpenSSF v2.2.0 CUE schema (cue vet, vendored
    byte-identical schema — the gate fired on a real missing required
    rulesets field, fixed honestly); demo-image pyyaml hash-pin
    (--require-hashes); cflite-batch.yml 60-minute runtime cap.
  • Wave 1 OSCAL 1.2.2 verdict recorded (ROADMAP + v0.11 plan):
    DEFER-WITH-TRIGGER — emitted documents stay on OSCAL 1.2.1 (the 1.2.2
    schema delta is byte-identical for every emitted surface, while
    compliance-trestle v4.2.0 hard-rejects oscal-version: 1.2.2); plus fixes
    for live docs still claiming the POA&M emitter produces OSCAL 1.1.2 (false
    since v0.9.6).

Changed

  • Emitted CycloneDX SBOMs move 1.6 → 1.7 (H1) across all four emission
    sites (release asset, post-publish rescan, SSOT osv gate,
    PEP 770 per-wheel SBOMs), with the pinned osv-scanner bumped
    v2.3.8 → v2.4.0
    at all six install sites — v2.3.8 rejects CycloneDX 1.7
    ("invalid specification version"), a break the local full gate suite caught
    before it could ship; v2.4.0 verified against the repo's exact SSOT
    invocation. The gap-analyzer CycloneDX VEX emitter deliberately stays
    1.6 (a product schema surface, moving only with its own review).
  • setuptools floated to 83.0.0 (PYSEC-2026-3447, Medium 6.1, published
    2026-07-14 — the fixable-means-upgrade policy applied same-day), floating
    torch 2.11.0 → 2.13.0 + triton in the dev closure; two osv allowlist
    entries whose documented removal triggers fired were removed
    (GHSA-rrmf-rvhw-rf47: torch 2.13.0 exits the advisory's last_affected
    2.12.0; PYSEC-2025-183: the disputed pyjwt advisory was bounded upstream to
    last_affected 2.10.1, below the locked 2.13.0).
  • Container base digests refreshed (day-N CVE rebuild) — the
    dhi.io/python:3.13 distroless runtime pin moves
    b41747df…1842a6b9…, and the python:3.13-slim builder pin moves
    c33f0bc4…eb43ff12… in lockstep across its four sites (the main
    Dockerfile, the demo Dockerfile's assets stage, and the two
    interpreter-parity pip-compile runner pins in release.yml /
    container-build.yml). Fired by the post-publish rescan's fixable-only
    policy on DEBIAN-CVE-2026-34743; the 28 unfixable base-OS advisories
    remain notify-only per that policy, and the rescan re-verifies the
    published image after this release. The fresh DHI digest also
    restructured the base's python layout (/opt/python → the standard
    /usr/bin + /usr/lib/python3.13) — caught by the PR's container gate
    (exec /opt/venv/bin/evidentia: no such file or directory),
    CI-probe-verified against the exact pinned digest, and fixed by repointing
    the venv-fix stage's interpreter symlinks + pyvenv.cfg at /usr.
  • ROADMAP restructured at the v0.11 cycle open — the v0.10.x line is
    closed SHIPPED (16 published releases), the four mis-marked entries
    (v0.10.5 / v0.10.9 / v0.10.11 / v0.10.12) are corrected to SHIPPED, the
    four missing entries (v0.10.10 / v0.10.13 / v0.10.16 / v0.10.17) are
    backfilled, and v0.11 is promoted to the open cycle linking its plan doc
    (docs/releases/plans/v0.11-plan.md, ratified 2026-07-09).
    docs/enterprise-grade.md's header is restructured so its live currency
    claim sits on a single anchorable line. The quarterly safeguards-resweep
    issue template gains a practice-delta item (method recorded in
    docs/engineering-practices.md §Research rigor).

Verify the wheels (PEP 740 publish attestations)

Every wheel uploaded to PyPI from this release carries a
Sigstore-signed PEP 740 publish attestation. Verify locally:

pip install pypi-attestations
pypi-attestations verify pypi \
  --repository https://github.com/polycentric-labs/evidentia \
  "pypi:evidentia==0.10.18"

Verification confirms the wheel was built + published from
polycentric-labs/evidentia/release.yml@refs/tags/v0.10.18
under GitHub Actions OIDC — i.e., a malicious mirror cannot
serve a tampered wheel without the verification failing.

See docs/sigstore-quickstart.md
for the full verification narrative + supply-chain framing.

CHANGELOG

Full changelog (every release): CHANGELOG.md

Container image

  • ghcr.io/polycentric-labs/evidentia:v0.10.18
  • ghcr.io/polycentric-labs/evidentia:latest
  • Digest: sha256:a4bbf2b382c1d5a806bfe0ef525ab7d6a455ec9466ed2c0f6644d008e63da531

Verify (cosign keyless OIDC):

cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.18 \
  --certificate-identity-regexp 'https://github\.com/Polycentric-Labs/evidentia/\.github/workflows/release\.yml@refs/tags/v.*' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com'

Verify (SLSA build provenance):

gh attestation verify oci://ghcr.io/polycentric-labs/evidentia:v0.10.18 \
  -R Polycentric-Labs/evidentia

See docs/sigstore-quickstart.md
for the full verification narrative.

v0.10.17

Choose a tag to compare

@github-actions github-actions released this 09 Jul 21:54
Immutable release. Only release title and notes can be modified.
v0.10.17
ccbf737

Highlights

Theme: v0.10.x hardening close-out. The final v0.10.x release, completing the Horizon-A elite-engineering-practice arc. Lands a publish-safe release-pipeline preflight dry-run — a workflow_dispatch that runs the full build/validate path (gate + wheels + per-package SBOMs + reproducible double-build + container-from-local-wheels + smoke tests) but is structurally unable to publish (the publish jobs require github.event_name == 'push') — backed by v*-tag-only PyPI/GHCR deployment environments with required-reviewer approval, so a real release now pauses for an explicit deployment sign-off. Also: two real audit-logger security fixes surfaced by an adversarial review of the CodeQL 2.26.0 findings (CWE-117 log CR/LF injection + CWE-312 cleartext credential in an exception field); the dead CodeQL .qll path-injection sanitizer pack replaced with a Models-as-Data barrierModel extension (honestly dismissal-managed until the stock query consumes it); the Tier-1 demo image reworked to a shell-free distroless multi-stage build; CodSpeed perf reporting activated; CI job timeout caps; and a refreshed distroless base digest. No package API changes.

Added

  • Release-pipeline preflight dry-runrelease.yml now accepts a manual
    workflow_dispatch that runs the full pre-publish path (the SSOT gate suite +
    wheels + per-package SBOMs + the reproducible-build double-build + the
    container-built-from-local-wheels + the image smoke tests) without publishing,
    so the failure classes that previously surfaced only at tag time (a base/dep
    regression, a uvx exit-127, a pip-compile hash mismatch — the v0.10.14 /
    v0.10.15 ghost-tag failures) can be caught on-demand before a tag is cut
    (gh workflow run release.yml --ref main). The dry-run is structurally incapable
    of publishing: tag-guard and both publish jobs require github.event_name == 'push', so a dispatch — even one selected on a v* tag ref — yields
    publishable=false and publish-pypi / publish-container skip. As a second,
    platform-level belt the pypi and ghcr deployment environments are restricted
    to v* tag refs with required reviewers, so a real release now also pauses
    for an explicit deployment approval. See docs/release-checklist.md Step 5.6.

Changed

  • timeout-minutes caps added to the dast and codspeed jobs — the two
    observe-first suites added this cycle ran open-ended (schemathesis stateful
    fuzzing and CodSpeed Valgrind instrumentation), so a pathological path or a hung
    upload could tie up a runner indefinitely. Both now carry an explicit cap (dast
    30 min, codspeed 20 min), mirroring mutmut.yml's existing cap on the other
    heavy suite.
  • docker/Dockerfile.demo reworked to a shell-free multi-stage build — the
    Tier-1 hosted-demo image (the real CLI behind an argv allowlist) now builds its
    final stage FROM the distroless signed release base with COPY + ENV + USER
    • exec-form ENTRYPOINT only — no RUN, no /bin/sh. All the build-time shell
      work (vendoring pyyaml) moved to a python:3.13-slim assets builder stage,
      and the launcher + namespace shim are now committed files (docker/demo/) rather
      than printf-generated. It drops privileges to the distroless nonroot uid
      65532 (numeric — no useradd), replacing the pre-DHI USER evidentia
      (uid 1000) assumption that broke on the distroless migration. Runtime behavior is
      unchanged (still refuses a raw shell / off-allowlist argv, forced --offline,
      credential-empty); locally smoke-validated with --build-arg BASE=python:3.13-slim.
  • Refreshed the DHI runtime base image digest — the pinned
    dhi.io/python:3.13 base advanced to sha256:b41747df…, picking up the
    latest Docker Hardened Images patches; the release rebuilds on the fresh
    base (closes the base-freshness sentinel nudge, issue #143).
  • Documentation URL repointed to the owned docs domain — the
    evidentia package's project URL now points at https://docs.evidentiagrc.com
    (the published docs site on an owned domain) instead of an un-owned host.
  • Content currency — added the OMB M-24-10 → M-25-21 deprecation row to
    the deprecation calendar; refreshed the enterprise-grade maintenance
    summary through v0.10.16; de-dangled a stale cross-reference in the
    v0.9.1 security-review backfill.

Fixed

  • CodSpeed perf-regression pilot now reports — added the mode: simulation
    input that CodSpeed Action v4 now requires (the Valgrind instruction-counting
    instrument for standard GitHub-hosted runners; without it the step errored out
    before ever benchmarking, and step-level continue-on-error silently masked
    it as green). With the repo now registered on codspeed.io, the job benchmarks
    tests/benchmarks/ and reports per-PR perf deltas via the CodSpeed dashboard
    and PR comment. continue-on-error stays at the step level so a transient
    CodSpeed upload/outage remains non-blocking (observe-first); the
    perf-regression signal comes from the PR comment, not from failing the check.

Security

  • Audit log CR/LF injection + credential leakage hardened
    (evidentia_core.audit.logger). Two defects surfaced by an
    adversarial review of CodeQL 2.26.0 findings: (1) CWE-117 — in the
    default (non-JSON) logging mode the message is rendered verbatim by
    the stdlib formatter, so attacker-controlled CR/LF (e.g. a Metric
    name via POST /api/governance/metrics) could forge log lines;
    the plaintext-rendered message now escapes newlines. (2) CWE-312 —
    the secret scrubber covered only the free-text message, leaving a
    credential inlined in an exception string (error.message = str(exc)) in cleartext in the structured record; the error field's
    string values are now scrubbed too. Structured JSON emission was
    already newline-safe via json.dumps and is unchanged.

Fixed

  • CodeQL custom path-injection sanitizer pack removed (never loaded)
    — the validate_within / resolve_catalog_path py/path-injection
    false-positive class was held down by per-instance dismissals because
    the custom .qll sanitizer pack never loaded: packs: accepts only
    published registry specs (a local path was logged as "Invalid CodeQL
    pack specification" and ignored), and an external library pack cannot
    inject a barrier into a stock query anyway. Replaced with a
    Models-as-Data barrierModel extension (loaded via the config's
    dataExtensions: key, which does resolve cleanly). NOTE:
    py/path-injection does not yet consume MaD barrierModel, so the
    model is a forward-looking hook and this FP class remains
    dismissal-managed for now.
  • Unauthenticated 500 on POST /api/ai-gov/register — a
    whitespace-only provider/owner passed the request model's raw
    min_length but failed the whitespace-stripping registry model,
    raising an uncaught ValidationError. Now normalized to a structured
    400, matching the sibling update handler. Found by the new DAST work.

Added

  • CodSpeed performance-regression gate (non-required, observe-first)
    a pytest-codspeed micro-benchmark suite (tests/benchmarks/, excluded
    from the default collection) over the hot paths from docs/benchmarks.md:
    gap analysis (1 + 2 frameworks), catalog load, report serialization, and
    two API request paths (health + gap-reports). A new codspeed.yml
    workflow runs them under CodSpeed's instruction-counting runner and
    reports per-PR perf deltas. continue-on-error and not a required check;
    it lands inert until the repo is registered on codspeed.io (free OSS
    tier), then activates with no further change.
  • uv supply-chain pilots (non-required, observe-first) — two uv
    preview features run in test.yml as second opinions to the
    authoritative osv-scanner SBOM gate, both continue-on-error so they
    never block a merge: a uv audit advisory scan, and a
    UV_MALWARE_CHECK=1 sync that queries OSV MAL advisories for the locked
    closure (a resolution-time tripwire for known-malicious packages). The
    malware check runs in its own non-required job rather than on the
    required sync steps while the feature is in preview.
  • Stateful DAST suite + dast.yml sentinel — a schemathesis
    state-machine test (tests/dast/test_openapi_stateful.py) walks
    create→read→update→delete link chains over the ai-gov and catalog
    lifecycles (hunting IDOR / state-leak / stale-reference /
    sequence-dependent 5xx classes that stateless per-operation fuzzing
    cannot reach), complementing the existing stateless
    test_openapi_fuzz.py. A new non-required dast.yml workflow runs
    both on a weekly cron, manual dispatch, and API-surface PRs
    (observe-first; not a merge gate).
  • DAST-driven API schema + error-contract hardening — several
    fixes surfaced while building the stateful-DAST harness: OpenAPI
    links on the ai-gov register→get/put/delete and catalog
    import→delete lifecycles; UpdateSystemRequest's
    at-least-one-field rule mirrored into the published schema (anyOf);
    a non-whitespace pattern on the AI-system descriptor
    name/purpose so the schema matches the strip+min_length
    runtime; the system_id UUID shape documented on the lifecycle ops;
    and an app-wide handler normalizing FastAPI's hardcoded body-decode
    400 to the structured ErrorEnvelope shape every other deliberate
    error already carries.
  • EvidenceRef two-mode contract in the published schema — the
    at-least-one-of (artifact_id, file_path) and file_pathsha256
    business rules, previously enforced only by a Pydantic model validator,
    are now mirrored into the OpenAPI component via json_schema_extra
    (top-level anyOf + if/then). Closes a DAST RejectedPositiveData
    finding on POST /api/model-risk/models (schema-valid-but-422 bodies) and
    tightens the generated UI types.
  • PEP 770 per-wheel SBOMs — every published wh...
Read more

v0.10.16

Choose a tag to compare

@github-actions github-actions released this 02 Jul 03:07
Immutable release. Only release title and notes can be modified.
v0.10.16
0833299

Highlights

Theme: Engineering hardening + distroless container base — never ship a failed test again. Bundles the accumulated supply-chain work into one release: cryptography-native DSSE/in-toto air-gap signing, the atomic (validate-before-publish) release pipeline, and the migration of the published container onto a distroless Docker Hardened Images base (nonroot uid 65532; no shell, curl, or gpg). No package API changes. (The 0.10.14 and 0.10.15 tags were created but never published — in both cases the atomic release's validate-before-publish design stopped anything from shipping. 0.10.14's build caught a non-reproducible container-requirements-hash issue; 0.10.15 fixed that, built and validated everything, then failed pre-upload on a missing uv install in the restructured publish job's twine check — the publish jobs' first-ever live execution, since they cannot run in PR CI. 0.10.16 is the same release content plus both pipeline fixes.)

Added

  • Cryptography-native air-gap signing via DSSE/in-toto — a binary-free,
    network-free signing path that works inside distroless and minimal-base
    containers (evidentia_core.oscal.keysign). Operators pass a PEM/PKCS#8
    Ed25519 or RSA private key via --sign-with-key on evidentia gap analyze
    and evidentia traceability emit; Evidentia writes a .dsse.json sidecar
    (DSSE envelope carrying an in-toto Statement v1, signed with Ed25519 or
    RSA-PSS-SHA-256). Verify with evidentia oscal verify <artifact> --verify-key <pubkey.pem> --require-signature (fail-closed; pinned key
    required). Encrypted private keys are supported via the
    EVIDENTIA_SIGNING_KEY_PASSPHRASE env var (never a CLI flag). The API and
    MCP surfaces accept the signed artifacts for verification; the UI console
    verifies and emits unsigned (artifact signing remains an air-gap CLI
    operation). This path is the recommended signing method for air-gapped
    deployments and distroless containers where the gpg binary is absent.
  • docs/engineering-practices.md — a public account of the engineering safeguard stack (PR-flow + merge queue, atomic releases, SLSA provenance + cosign + SBOM + OIDC publishing, continuous fuzzing + Scorecard + CodeQL, verified docs) and the candid failure classes that shaped each safeguard.
  • Security posture documents. docs/SECURE-BY-DESIGN-PLEDGE.md (voluntary alignment with the CISA Secure by Design Pledge's seven goals), docs/slsa-source-track.md (an honest SLSA v1.2 Source Track self-assessment — the L3 technical controls are enforced and verifiable, the L4 two-party-review gap disclosed), docs/runbooks/ghsa-cve-issuance.md and docs/runbooks/release-rollback.md (maintainer runbooks for GHSA + CVE issuance via GitHub-as-CNA and for release rollback/yank per PEP 592), and a root security-insights.yml (OpenSSF Security Insights v2.2.0 manifest). All linked from SECURITY.md.

Changed

  • PR-flow + merge queue on main. A repository ruleset now requires a pull request, the full set of status checks, and a squash merge queue, with an empty bypass list — no direct push to main, including by administrators. This reverses the prior direct-push model so the complete CI matrix gates every change before it lands, not after. Every workflow producing a required check gained a merge_group trigger (paths-filtered workflows do not run on merge_group, so the container smoke test instead always runs with a step-level relevance early-exit).
  • Atomic release. release.yml builds and validates all artifacts — wheels, SBOM, and the container image (built from the locally-built wheels, not the package index) — before the irreversible PyPI publish, then pushes the byte-identical validated image. This closes the post-publish container-build-failure class (the v0.10.12 packages-only release) and the index-propagation race. The Dockerfile is now multi-stage with an INSTALL_SOURCE build argument; the operator default (install from PyPI) is unchanged.
  • Container base migrated to Docker Hardened Images. The published image now rides a distroless dhi.io/python:3.13 runtime (nonroot uid 65532, home /home/nonroot) built via a multi-stage python:3.13-slim builder that installs the hash-pinned closure into a venv — dropping the shell, curl, and gpg binaries from the runtime. Air-gap evidence signing inside the container uses the binary-free DSSE path (above); the GPG-emit code path fails closed (GPGNotAvailableError) when no gpg binary is present, and Sigstore stays online-only. The healthcheck is reimplemented in pure Python (no curl). Because cryptography became a direct core dependency with the DSSE signing path, the container closure now resolves cryptography 49.0.0 (≥48.0.1 — so GHSA-537c-gmf6-5ccf is fixed in the shipped image, not merely allowlisted). Honest framing: the win is post-exploitation attack-surface reduction plus keeping the fixable-rescan gate green, not a raw CVE-count cut (the distroless base still carries unfixable advisories, and removing curl is not egress denial — Python socket/urllib remain). A scheduled base-image freshness sentinel opens a tracking issue when the DHI base digest drifts or the published image ages past 90 days, so the day-N clock is reset by an ordinary rebuild-and-release rather than left to the rescan alone. NOT Alpine (musl breaks the manylinux AI/crypto wheels).
  • The container smoke test is now a required check. Restructured to run on every pull request with a relevance early-exit, so it reports success on changes that do not touch the container while still building whenever the Dockerfile or its inputs change — which is what lets it be required without blocking unrelated PRs.
  • Required-check concurrency. The four required-check workflows (test, consistency, container-build, secret-scan) now cancel in-progress runs only on pull_request events; push:[main] and merge_group runs always run to a green conclusion, so every main commit earns its own completed required check (no spurious cancelled runs on rapid back-to-back merges).
  • Post-publish container rescan gates on fixable advisories. The scheduled rescan of the published container image (post-publish-rescan.yml) no longer goes permanently red on day-N base-OS CVEs that have no upstream fix — the chronically-red-gate failure class the doctrine forbids (an osv-scanner dispatch on the published image reports 81 advisories, only 4 fixable). osv-scanner has no native fixable gate and exits non-zero on any advisory, so the job now captures the scan as JSON and a committed, unit-tested policy step (scripts/check_osv_fixable.py) fails only when a detected advisory has an applicable fix for the detected package — matched on the package's own ecosystem and name (exact down to the Debian release suffix), so a fix in an unrelated release that merely shares the CVE does not count (matching any shared-CVE affected entry would instead flag 110 of the 248 raw vulnerability records, not 4). Unfixable base-OS CVEs are notify-only, rendered in full to the run job-summary; the scan step fails closed on any osv-scanner exit code other than 0/1 (so a partial or errored scan that writes an empty result cannot be mistaken for a clean image), and a missing or malformed report is rejected too. The gate is expected to fire on the current published image until its 4 fixable advisories are cleared by a rebuild. The JSON schema and the fixable determination were verified empirically against real osv-scanner v2.3.8 output on the published image and captured as a committed regression fixture. The PyPI-closure rescan job is unchanged. Doctrine in docs/engineering-practices.md; the companion minimal-base-image migration that shrinks the OS-CVE surface itself ships in this release (see Container base migrated to Docker Hardened Images above).

Fixed

  • Flake-resistance policy (docs/testing-flake-policy.md) — bans wall-clock-timing assertions and treats a skipped or dead gate as a failure, after a Windows clock-granularity flake and a Hypothesis-deadline flake were eliminated.

Security

  • npm registry-signature verification. The frontend CI job runs npm audit signatures after npm ci, verifying installed UI tarballs against npm's registry signatures and maintainer Sigstore provenance — the JS/TS analogue of the Python side's PEP 740 attestations.
  • Release-tag root-of-trust protection. A server-side repository ruleset makes refs/tags/v* append-only (no force-move, no delete, signatures required), and GitHub Immutable Releases locks published release assets and tags — so the cosign certificate-identity binding on a signed tag cannot be silently broken after publish.

Verify the wheels (PEP 740 publish attestations)

Every wheel uploaded to PyPI from this release carries a
Sigstore-signed PEP 740 publish attestation. Verify locally:

pip install pypi-attestations
pypi-attestations verify pypi \
  --repository https://github.com/polycentric-labs/evidentia \
  "pypi:evidentia==0.10.16"

Verification confirms the wheel was built + published from
polycentric-labs/evidentia/release.yml@refs/tags/v0.10.16
under GitHub Actions OIDC — i.e., a malicious mirror cannot
serve a tampered wheel without the verification failing.

See docs/sigstore-quickstart.md
for the full verification narrative + supply-chain framing.

CHANGELOG

Full changelog (every release): CHANGELOG.md

Container image

  • ghcr.io/polycentric-labs/evidentia:v0.10.16
  • ghcr.io/polycentric-labs/evidentia:latest
  • Digest: sha256:52a8df7ee2d2c2a1afaff82d65e8b9f2e1b7e410bf03a57e956de7432d037c35

Verify (cosign keyless OIDC):

cosign verify ghcr.io/polycentric-labs/evide...
Read more

v0.10.13

Choose a tag to compare

@github-actions github-actions released this 24 Jun 01:25
v0.10.13
bfde9b1

Highlights

Theme: Patch — restore the container base to Python 3.13. v0.10.12 published to PyPI successfully, but its container image failed to build: the base had been bumped to python:3.14-slim, which the AI stack (litellm, requires-python <3.14) cannot resolve. This patch reverts the base to python:3.13-slim so the published container is complete and CVE-clean. The Python packages are otherwise identical to 0.10.12.

Fixed

  • Container base reverted to python:3.13-slim after a Dependabot bump (#83) to python:3.14-slim broke release.yml's container build. The 3.14 base contradicted the Dockerfile's own guard comment — litellm declares requires-python <3.14, so on a 3.14 base the resolver caps at litellm 1.83.7 (which carries CVE-2026-40217, HIGH) and the regenerated CVE-clean pin (litellm 1.89.x) is uninstallable; the container build failed only after the PyPI publish had already succeeded. Re-pinned to python:3.13-slim@sha256:c33f0bc… (the current 3.13-slim digest), realigning the FROM line with its own guard comment so the container resolves the CVE-clean AI stack. This regression surfaced the same cycle the patch/minor Dependabot auto-merge was removed in favour of human review — it is exactly the class of unreviewed-dependency-change that review catches.
  • Container smoke test un-broken — the gate that should have caught the above. container-build.yml's smoke test had silently exited at version-extraction on every push since v0.10.11: its sed for evidentia[gui]== never matched the pip-compile-normalized evidentia== line in the perennially-stale committed docker/requirements.txt (which bump_version.py never advances), so it never reached the build step. A chronically-red gate became noise that masked exactly the python:3.14 base regression above. The version is now read from PyPI's latest published release — self-correcting, with no dependency on the committed preview pin — so the smoke test builds the container on every Dockerfile change again, and an incompatible base-image bump is caught at PR/push time instead of at release.

Verify the wheels (PEP 740 publish attestations)

Every wheel uploaded to PyPI from this release carries a
Sigstore-signed PEP 740 publish attestation. Verify locally:

pip install pypi-attestations
pypi-attestations verify pypi \
  --repository https://github.com/polycentric-labs/evidentia \
  "pypi:evidentia==0.10.13"

Verification confirms the wheel was built + published from
polycentric-labs/evidentia/release.yml@refs/tags/v0.10.13
under GitHub Actions OIDC — i.e., a malicious mirror cannot
serve a tampered wheel without the verification failing.

See docs/sigstore-quickstart.md
for the full verification narrative + supply-chain framing.

CHANGELOG

Full changelog (every release): CHANGELOG.md

Container image

  • ghcr.io/polycentric-labs/evidentia:v0.10.13
  • ghcr.io/polycentric-labs/evidentia:latest
  • Digest: sha256:c8c7acbf4797fd5209cc9e3383f7f4b07e01af340b1e122c7368ee39364f023c

Verify (cosign keyless OIDC):

cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.13 \
  --certificate-identity-regexp 'https://github\.com/Polycentric-Labs/evidentia/\.github/workflows/release\.yml@refs/tags/v.*' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com'

Verify (SLSA build provenance):

gh attestation verify oci://ghcr.io/polycentric-labs/evidentia:v0.10.13 \
  -R Polycentric-Labs/evidentia

See docs/sigstore-quickstart.md
for the full verification narrative.

v0.10.12

Choose a tag to compare

@github-actions github-actions released this 23 Jun 22:57
v0.10.12
0a6e926

Highlights

Theme: v0.10.12 — full CLI↔GUI parity build-out + the OMB M-25-21 AI-governance migration. A feature-rich minor release: the local web console reaches ~98% CLI↔GUI parity (up from ~13% in v0.10.11), the AI-governance module migrates to current federal guidance (OMB M-25-21), and the supply-chain / security posture is hardened (continuous fuzzing, an SSRF fix, and OpenSSF Scorecard lifts).

Added

  • OMB M-25-21 "high-impact AI" model — the AI-governance module now reflects current federal guidance. OMB M-24-10 (the prior basis for the rights-impacting / safety-impacting / both / neither taxonomy) was rescinded on 2025-04-03 by M-25-21 ("Accelerating Federal Use of AI through Innovation, Governance, and Public Trust"), which collapses the old split into a single "high-impact AI" category — AI whose output is a principal basis for decisions with significant effect on civil rights/liberties/privacy, access to essential services (education, housing, insurance, credit, employment), critical government resources, human health & safety, critical infrastructure, or strategic assets. New core module evidentia_core.ai_governance.omb_m_25_21 ships HighImpactDetermination (high_impact / not_high_impact / not_assessed), HighImpactBasis (the six consequence areas), the OMBHighImpactAssessment sub-model (determination + bases + rationale), triggers_minimum_practices(), and crosswalk_from_legacy() (an explicit, operator-invoked old→new mapping — Evidentia never silently re-determines a persisted M-24-10 value). Surfaced as a matched CLI ↔ REST ↔ console triple — evidentia ai-gov set-high-impact <id> --determination <d> [--basis <b>]… [--rationale <t>], POST /api/ai-gov/systems/{id}/set-high-impact (RBAC write-gated), and a "High-impact AI (OMB M-25-21)" form + display on the /ai-gov console — plus a new omb_high_impact registry field, the AI_SYSTEM_HIGH_IMPACT_CLASSIFIED audit event, and the SCR change-classifier treating a not_high_impacthigh_impact escalation as transformative. Purely additive + backward-compatible: every existing M-24-10 inventory entry still loads. The seven M-25-21 minimum risk-management practices are documented this cycle; structured per-practice tracking is a v0.11 extension of OMBHighImpactAssessment.
  • Full CLI↔GUI parity build-out — the local web console grows to 22 consoles at ~98% CLI↔GUI parity (up from ~13% in v0.10.11), with matched REST endpoints for every new console (governance, retention, evidence, catalog management, risk-quantify, TPRM, continuous-monitoring, model-risk, POA&M, AI-governance, OSCAL-verify, traceability, collect, integrations). The two credentialed / network-egress consoles — Collect and Integrations — surface a UI guard when no AuthProvider is configured: a SecurityPostureBanner plus disabled run/push buttons (a convenience guard, not a server-side control — the endpoints stay open until an auth token is set, which is the real fix). Artifact signing remains an air-gap CLI operation (the consoles verify and emit unsigned only).
  • Init wizard write-to-disk pathPOST /api/init/commit lets the onboarding wizard write the generated system-context.yaml, control inventory, and catalog index to the server's working directory (skips existing files unless overwrite=true, mirroring evidentia init --force).

Changed

  • Web-console bundle reduced via route code-splitting — every console page is now lazy-loaded with React.lazy + a Suspense boundary, dropping the main chunk to 339 kB (105 kB gzip) and clearing the >500 kB build warning.
  • The CLI↔GUI parity gate is now bidirectional — a new inverse-completeness check requires every live OpenAPI operation to be either served by a CLI leaf or listed (with a rationale) in an api_extra allowlist; an unclassified endpoint or a stale allowlist row fails the gate.
  • Audit vocabulary fully typedEventAction.TRACEABILITY_EMITTED and EventAction.INTEGRATIONS_SERVICENOW_PUSH promoted from ECS-style dotted strings to enum members (byte-identical emission; existing SIEM queries unaffected), completing the typed-EventAction refactor. A new EventAction.RETENTION_METADATA_DELETED distinguishes a retention metadata delete (the REST DELETE /retention/{id}) from a secure WORM purge, so an auditor querying the action vocabulary can no longer read a metadata delete as a secure purge.
  • Console accessibility (WCAG 4.1.3 Status Messages) — fetch-error cards now announce via role="alert", async pending states via role="status" / aria-live, and the OSCAL-verify identity hint is associated to its disabled control via aria-describedby (12 files across the console set).
  • Dependency-update auto-merge removed — the v0.10.8 dependabot-automerge.yml workflow (which auto-enabled merge on green patch/minor Dependabot PRs) is removed and the repo allow_auto_merge setting is disabled. Dependabot itself stays fully on — grouped update PRs, alerts, and security updates — but dependency changes are now merged deliberately, after human review, rather than automatically. For a supply-chain-integrity tool the stronger posture is that every dependency change in this repo was reviewed by a human: the xz-utils / event-stream class of compromise ships as an innocuous, green-CI patch/minor bump, which is exactly what auto-merge would have admitted unattended.

Fixed

  • Evidence console empty-state hint — points operators to evidentia evidence save (which emits the lineage id) instead of the nonexistent evidence list command.
  • Framework-ID typo in operator guides — corrected nist-800-53-rev5-mod → the canonical nist-800-53-rev5-moderate across the SARIF / OCSF-detection / gap-analysis guides (the invalid id made gap analyze exit non-zero).

Security

  • SSRF + credential-exfil guard on the Tableau publish endpoint — the request-body server_url is now validated through network_guard.enforce_public_host (default-on private-IP block) + pin_resolved_host (anti-DNS-rebind), with https-only enforcement, closing a path by which a caller could reach a cloud-metadata endpoint (e.g. 169.254.169.254) and exfiltrate the Tableau PAT. Configuration is validated before the report lookup.
  • Continuous fuzzing (ClusterFuzzLite) + a fuzz-found DoS fix — six atheris harnesses (catalog import, OSCAL profile load/resolve, OSCAL verify, OCSF ingest, gap-report load, TPRM questionnaire) run in CI alongside cross-platform Hypothesis property tests; the first run found and fixed an uncaught-exception denial-of-service in oscal verify on malformed back-matter. This is the OpenSSF Scorecard "Fuzzing" lift; the harnesses graduate to OSS-Fuzz unchanged.
  • Pre-tag review hardeningoscal verify is now exhaustively guarded to return a verdict (never raise) on any malformed-but-valid-JSON document, completing the fuzz-found CWE-248 fix across the whole verify_digests + digest-extraction chain (the robustness harness no longer swallows TypeError, so it guards the invariant). The two open compute endpoints bound their inline inputs (risk/quantify scenarios ≤ 1000; oscal/verify content ≤ ~8 MB). And the SecurityPostureBanner + the web-console security model now state plainly that disabling the credentialed buttons is a UI convenience guard, not a server-side control — the API endpoints stay open until EVIDENTIA_API_AUTH_TOKEN_FILE is set. The six full-model create endpoints (governance challenges/metrics/workflows, POA&M items, TPRM vendors, model-risk models) now return 422 rather than an unhandled 500 on a malformed client id (a DAST-found response-contract fix), and the audit secret-scrubber additionally redacts the in-tree credential shapes it previously missed — fine-grained GitHub PATs, OpenAI/Anthropic keys, DSN-embedded passwords, and bearer tokens.

Deprecated

  • The OMB M-24-10 surfaceevidentia_core.ai_governance.omb_m_24_10.OMBImpactCategory, the omb_impact registry field, the ai-gov set-omb-impact CLI/REST verb, and the AI_SYSTEM_OMB_CLASSIFIED audit event — after M-24-10's 2025-04-03 rescission by M-25-21. Retained and fully backward-compatible (persisted inventories still load; no behaviour change; no runtime deprecation warning). Use the M-25-21 high-impact surface for new work, and omb_m_25_21.crosswalk_from_legacy to map a legacy value forward.

Documentation

  • GitHub Pages site on the owned domain — the Material-for-MkDocs documentation site is served at docs.evidentiagrc.com (CNAME + canonical site_url); a pages.yml workflow builds it under mkdocs build --strict. OpenSSF Scorecard was hardened in the same cycle (a SCORECARD_TOKEN for the branch-protection/webhooks checks; the SLSA build-provenance bundle is attached to each GitHub Release).
  • Operator console guides + screenshots — six new console walkthroughs, with bash and PowerShell command variants across every command-bearing guide; three new console screenshots (Collect, Integrations, Traceability); a new web-console-security.md concept page documenting the standing security model for evidentia serve (inherited controls, the anonymous-by-default posture + auth-gating, per-console exposure, and a hardening checklist); and a refresh of positioning-and-value.md §3 to the current v0.10.12 surface.
  • Windows verification recipes — the canonical docs/verification.md now carries the bash + PowerShell variants for every release-artifact verification recipe (PEP 740, cosign, SBOM, SLSA); the generated wiki mirror regenerates from it, so the two no longer drift.

Verify the wheels (PEP 740 publish attestations)

Every wheel uploaded to PyPI from this release carries a
Sigstore-signed PEP 740 publish attestation. Verify locally:

pip install pypi-attestations
pypi-attestations verify pypi \
  --repository https...
Read more

v0.10.11

Choose a tag to compare

@github-actions github-actions released this 17 Jun 20:18
v0.10.11
57f1ab3

Highlights

Theme: v0.10.11 — public demo completion + signed traceability + hygiene. Patch bump (v0.10.10 → v0.10.11). Finishes the public demo surface, promotes threat→control→evidence into a first-class signed capability, and clears the v0.10.10 follow-on hygiene. The full CLI↔GUI parity build-out (incl. a dedicated traceability console route) is the v0.10.12 cycle.

Added

  • Signed Control↔Threat Traceability Matrix — a new evidentia traceability emit verb produces a Sigstore-signable OSCAL profile mapping controls to the threats they mitigate. The representation was locked by a multi-model research pass (primary-source verified): a static control↔threat matrix is an OSCAL profile — NOT Assessment Results (a semantic abuse of an assessment-activity model) and NOT the OSCAL mapping model (released in 1.2.1, but control↔control only — its source/target are catalog/profile and items are control/statement, so it cannot target a threat ID). The profile imports a control catalog and adds a link rel="mitigates" + Evidentia-namespaced props to each control, with threats in integrity-hashed back-matter.resources[] (canonical JSON + SHA-256, the same tamper-evident pattern as the gap-analysis AR exporter). It signs via the existing --sign-with-gpg / --sign-with-sigstore path and round-trips through evidentia oscal verify (now generalized to locate any OSCAL model's back-matter, so digests + tamper detection work on the profile too). The relationship vocabulary is a domain mitigation set (mitigates / partially-mitigates / compensating / detects), deliberately NOT NIST OLIR (which is concept-to-concept / control↔control). Threat resource UUIDs + per-mapping IDs are derived deterministically (uuid5) so re-emitting the same matrix reproduces byte-identical evidence. Ships models/traceability.py, oscal/traceability_exporter.py, and an illustrative self-attested example (examples/traceability-DEMO-example.yaml). OWASP Threat-Dragon ingest, the MITRE CTID Mappings-Explorer crosswalk, and a CycloneDX representation are the v0.11 build.
  • OSCAL emit/verify console view (demo-gated, read-mostly). A new #/oscal route renders a gap run's emitted OSCAL Assessment Results — the document summary, its integrity-hashed back-matter resources, the signed artifact, and an illustrative verification panel (digests + Sigstore/Rekor + the air-gap GPG path) — by extracting a shared SignedArtifactCard + VerificationPanel (now reused by both the FDA demo and this view). Fixture-backed; wiring it to a live run + a real verify endpoint is v0.10.12 parity.
  • FDA-index build mode — a VITE_DEMO_FDA_INDEX flag renders FdaDemoPage full-bleed as the index (outside AppLayout), so fdademo.evidentiagrc.com can serve the in-repo bundle as the single source of truth, retiring the decoupled prototype fork. The build-time flag also tree-shakes the unused console routes. The main VITE_DEMO console deploy config (packages/evidentia-ui/vercel.json) shipped in v0.10.10; this completes the in-repo demo surface. Deploys + domain attaches remain operator-driven (Tier-4).

Security

  • Collector SSRF guard now runs before the optional driver import. The four SQL collectors (postgres / mysql / mssql / oracle) run the public-host SSRF guard (enforce_public_host) BEFORE importing their optional driver, so a private/loopback/link-local host is refused even when the driver is not installed — the security property is now verifiable in a no-extras environment (snowflake + databricks already guarded before their SDK import). A new CI no-extras smoke job asserts the guard with ZERO optional drivers installed, structurally backstopping the CI-vs-local extras gap that surfaced at v0.10.10. The SSRF tests are refactored to inject a fake driver module instead of pytest.importorskip.

Fixed

  • MetricCard DOM nesting — the value renders in a <div>, not a <p>, so the shipped #/demo/fda "Total gaps" card (a <Badge>, which is a <div>) no longer triggers a validateDOMNesting console error. Adds a regression guard.
  • oscal signgap analyze --sign-with-* doc correction in docs/threat-model.md + docs/troubleshooting.md (the removed verb), landing the edits stashed during the v0.10.10 ship.
  • Roadmap accuracy — the v0.11 "CycloneDX TM-BOM (ECMA-424 working-group track)" line overstated maturity; verification found no ratified CycloneDX TM-BOM type exists (CycloneDX = ECMA-424, current spec v1.7; threat data rides VEX + properties), so it is reframed as a forward-looking representation.
  • Demo console is labeled a partial-functionality preview ("Preview · synthetic data · partial functionality · no live backend") and the GapExportControl test no longer trips a jsdom Blob.stream console error.

Verify the wheels (PEP 740 publish attestations)

Every wheel uploaded to PyPI from this release carries a
Sigstore-signed PEP 740 publish attestation. Verify locally:

pip install pypi-attestations
pypi-attestations verify pypi \
  --repository https://github.com/polycentric-labs/evidentia \
  "pypi:evidentia==0.10.11"

Verification confirms the wheel was built + published from
polycentric-labs/evidentia/release.yml@refs/tags/v0.10.11
under GitHub Actions OIDC — i.e., a malicious mirror cannot
serve a tampered wheel without the verification failing.

See docs/sigstore-quickstart.md
for the full verification narrative + supply-chain framing.

CHANGELOG

Full changelog (every release): CHANGELOG.md

Container image

  • ghcr.io/polycentric-labs/evidentia:v0.10.11
  • ghcr.io/polycentric-labs/evidentia:latest
  • Digest: sha256:4ed6d4b1f1256252fa270a34bf4367ad9c9e8661f839e37e0b1eb96b42194600

Verify (cosign keyless OIDC):

cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.11 \
  --certificate-identity-regexp 'https://github\.com/Polycentric-Labs/evidentia/\.github/workflows/release\.yml@refs/tags/v.*' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com'

Verify (SLSA build provenance):

gh attestation verify oci://ghcr.io/polycentric-labs/evidentia:v0.10.11 \
  -R Polycentric-Labs/evidentia

See docs/sigstore-quickstart.md
for the full verification narrative.

v0.10.10

Choose a tag to compare

@github-actions github-actions released this 16 Jun 20:53
v0.10.10
477395b

Highlights

Theme: v0.10.10 — supply-chain hardening + the public demo suite. Patch bump (v0.10.9 → v0.10.10). Closes the v0.10.9 Step-7 container findings, the post-ship Security-tab disposition, and the two product findings the Tier-1 demo threat model surfaced; and lands the in-repo artifacts for a three-tier public demo.

Added

  • FDA Section 524B medical-device pack. Generic, public support for FDA premarket device cybersecurity, in four parts. (1) A real bundled catalog fda-524b-appendix1 (Tier A, the eight §V.B.1 security control categories — Authentication, Authorization, Cryptography, Code/Data/Execution Integrity, Confidentiality, Event Detection and Logging, Resiliency and Recovery, Updatability and Patchability — names verbatim from the Feb 3, 2026 guidance, characterizations in Evidentia's own words; framework count 92 → 93), reachable via CLI + API + the web console's Gap Analyze picker. (2) License-respecting stubs iso-14971 + aami-sw96 (placeholder + cite, no normative standard text) and two illustrative, self-attested crosswalks (fda-524b-appendix1 → iso-14971 / → aami-sw96) carrying the safety-vs-security risk-model note (ISO 14971 probability × severity vs AAMI SW96/TIR57 exploitability × severity on a shared patient-harm severity axis; 93 → 95). (3) A demo-only web-console route #/demo/fda (registered only in the VITE_DEMO=true build, inside the normal layout — the landing is untouched) that runs a synthetic, banner-labeled 524B gap analysis with zero backend, traces each STRIDE device threat → 524B control → verification test, and ends on an illustrative signed-evidence artifact, plus a synthetic display-fixture examples/fda-524b-DEMO-example-assessment.oscal.json (no signing key in the repo; it verifies nothing). (4) An FDA medical-device guide at docs/wiki/5-compliance/fda-medical-device-compliance.md. All content is generic and synthetic — no customer/third-party references.
  • Public demo suite (in-repo artifacts). Three surfaces telling one story (the bundled examples/meridian-fintech-v2 sample), per docs/demo-suite-design.md: Tier 2 — a static "demo mode" build of the web console (VITE_DEMO=true) that swaps the API client for a baked-fixtures module (src/lib/demo/), renders the SSE routes as canned streams, uses HashRouter for static subpath hosting, and shows a "DEMO · synthetic data · no live backend" banner — it issues zero /api calls (no backend, no credentials); Tier 0 — a self-hosted asciinema cast (packages/evidentia-ui/public/demo.cast, generated by scripts/demo/gen_cast.py from the real CLI run) + a vendored player embedded on the demo page + README; Tier 1 — a constrained argv-allowlist runner (evidentia.demo.runner) + a demo-profile docker/Dockerfile.demo enforcing the threat-model conditions (no raw shell, scrubbed env, forced --offline, network-free fixture-only verbs, built FROM the signed release digest). The deploy steps (Vercel, the hosted Tier-1 runner, the marketing-site link) are deferred Tier-4 actions, not part of this build.

Security

  • Container base Python 3.14 → 3.13 — removes three container CVEs at the root. The published v0.10.9 container was pinned to litellm 1.83.7 (the only release installable on Python 3.14), which carries CVE-2026-40217 (HIGH — sandbox escape in litellm's custom-code guardrail) and transitively held python-dotenv 1.0.1 (CVE-2026-28684) + aiohttp 3.13.5 (two client-cookie CVEs). litellm ≥ 1.84 — and the fix for all three — declares requires-python <3.14, so the ceiling was the python:3.14-slim base itself. Dropping the base to python:3.13-slim (digest-pinned) lets the container resolve the same CVE-clean set the library's uv.lock pins (litellm 1.89.0, aiohttp 3.14.1, python-dotenv 1.2.2, starlette 1.3.1) — and supersedes the v0.10.9 F-V109-4 "known limitation" (the aiohttp ceiling is gone). The live HIGH was not reachable (Evidentia uses litellm for completions, not the guardrail-proxy feature CVE-2026-40217 affects); the base change removes it regardless. Verified osv-clean by version; enforced by the new container osv-gate.
  • Collectors SSRF guard (threat-model T2), now rebind-resistant (closes F-V1010-S1). The OCSF collector's private-IP refusal (the v0.10.2 --block-private-ips) is lifted into a shared evidentia_core.network_guard.enforce_public_host and applied default-on to all 13 outbound collectors (okta, databricks, snowflake, github, vanta, drata, bitsight, securityscorecard + the 4 SQL adapters) and the API collectors router — closing the surface where an operator-supplied host (or, on an exposed serve, an anonymous request) could reach cloud-metadata / internal endpoints. The guard now PINS the validated IP through the actual connection so a TOCTOU DNS-rebind cannot bypass it: enforce_public_host returns the addresses it classified as public, and pin_resolved_host forces the connecting library's independent re-resolution back to those addresses for the duration of the request (a thread-local socket.getaddrinfo pin covering httpx, urllib, and the thin/pure-Python DB drivers + SDKs; libpq hostaddr for Postgres; ODBC HostNameInCertificate+IP-dial for MSSQL). The hostname is unchanged, so TLS SNI, the Host header, and certificate verification still target the original hostname — only the dialed IP is locked. This corrects the v0.10.2 known-limitation note ("single-resolve at pre-fetch time; DNS rebinding … out of scope"): rebinding between validation and connection is now defeated. Secure-by-default: internal-endpoint collection requires the opt-out (--allow-private-ips / block_private_ips=false); fail-closed on unresolvable hosts. The blocked set also covers RFC 6598 carrier-grade NAT (100.64.0.0/10), which cpython's ipaddress does not classify as private. SSRF + per-transport rebind regression tests cover the httpx, urllib, and SQL/psycopg paths. (AWS is unaffected — boto3 resolves SDK endpoints, not an operator host.)
  • tuf 6.0.0 → 7.0.0 (closes GHSA-qp9x-wp8f-qgjj) — sigstore 4.3.0 relaxed its tuf~=6.0 pin to tuf<8,>=6, firing the v0.10.7 removal trigger; the osv-scanner.toml ignore is dropped. The signing/verify paths (incl. the v0.10.9 Fulcio-cert-extension extraction) re-validate clean under sigstore 4.3.0.
  • Container osv-gate. release.yml + container-build.yml now osv-scan the regenerated docker/requirements.txt (pinned osv-scanner v2.3.8) after the regen and before the docker build, so a vulnerable container dependency hard-fails the build instead of shipping silently — the exact gap that let the v0.10.9 container HIGH through. (The F-V109-4 --upgrade regen fix, landed in the workflows during the v0.10.9 re-fire, is now also applied to bump_version.py's own regen path.)
  • Security-tab disposition (no code) — 6 accept-only alerts dismissed with rationale: torch GHSA-rrmf-rvhw-rf47 (no fix exists; the torch.jit.script path is unused), the two container-aiohttp client-cookie CVEs (moot after the base change), and 3 OpenSSF-Scorecard code-scanning signals (justified job-scoped contents:write + the org-level ruleset Scorecard can't see). Code-scanning is now 0-open.
  • Workspace dependency hygiene. python-multipart 0.0.27 → 0.0.32 and starlette 1.0.1 → 1.3.1 clear newly-surfaced osv advisories. cryptography GHSA-537c-gmf6-5ccf (a vulnerable statically-linked OpenSSL in the wheels; availability-only) is accepted-with-rationale in osv-scanner.toml — it is absent from every shipped artifact (the container ships evidentia[gui] and a base pip install evidentia pulls no cryptography; it surfaces only in the full-extras dev SBOM), the fix (48.0.1) is graph-blocked by py-ocsf-models 0.9.0's cryptography<47 cap, and the upstream cap-lift (prowler-cloud/py-ocsf-models#300 + PR #301) is the documented removal trigger.

Changed

  • serve posture hardening doc (threat-model T3)docs/threat-model.md documents that the container CMD defaults to serve --host 0.0.0.0 (online, no-auth) and recommends 127.0.0.1 binding, EVIDENTIA_API_AUTH_TOKEN_FILE for any non-loopback exposure, and --offline / EVIDENTIA_API_OFFLINE=1 when collectors aren't needed.
  • GitHub collector gained a --base-url flag (+ API field) for GitHub Enterprise endpoints; the new SSRF guard runs in the client constructor (a no-op for the default api.github.com).

Fixed

  • Config-test isolationfind_config_file gained an optional stop_at boundary; the config unit + API tests now bound the upward evidentia.yaml walk to their tmp tree, so a stray ancestor config (e.g. a ~/evidentia.yaml — pytest tmp dirs live under $HOME) can no longer leak into the suite and cause spurious failures.
  • Demo-suite polish (pre-release-review Step 3) — the demo gap view shows an honest "representative N of {total}" caption when the rendered rows are a subset; in-app links use the router so navigation survives the static HashRouter host; the demo SSE stream honors Cancel (AbortController); and the runner's never-satisfiable oscal verify allowlist vector is removed (deferred to a bundled signed fixture at Tier-1 deploy).

Verify the wheels (PEP 740 publish attestations)

Every wheel uploaded to PyPI from this release carries a
Sigstore-signed PEP 740 publish attestation. Verify locally:

pip install pypi-attestations
pypi-attestations verify pypi \
  --repository https://github.com/polycentric-labs/evidentia \
  "pypi:evidentia==0.10.10"

Verification confirms the wheel was built + published from
polycentric-labs/evidentia/release.yml@refs/tags/v0.10.10
under GitHub Actions OIDC — i.e., a malicious mirror cannot
serve a tampered wheel without the verification failing.

See [docs/sigstore-quickstart.m...

Read more

v0.10.9

Choose a tag to compare

@github-actions github-actions released this 12 Jun 04:27
v0.10.9
bf22966

Highlights

Theme: v0.10.9 — debt + robustness patch. Patch bump (v0.10.8 → v0.10.9). Closes the v0.10.8 ship findings and skill-iteration debt, and hardens the release machinery that cycle built.

Release summary: A consolidation cycle with one product-behavior fix and a set of release-machinery, UI-polish, and dependency items — every item traces to a named v0.10.8 finding or deferral. Product fix: the eval CLI's auto-sign now checks OIDC-token obtainability (not just GITHUB_ACTIONS), degrading gracefully to unsigned output with a warning in CI jobs lacking id-token: write instead of crashing (the F-V108-CI1 product fix — v0.10.8 only made the tests hermetic). Release machinery: the CLI↔GUI parity gate flips advisory → blocking, including a new parity check in the tag-time gate suite, so a parity regression can no longer reach PyPI; the uv-lock pin-drift pre-push check attributes drift per commit, eliminating the v0.10.8 false-positive class (SF-V108-3); the quarterly safeguards-resweep issue probe is idempotent across closed issues. Dependencies: the aiohttp accepted-CVE removal trigger fired — litellm 1.88.1 dropped its exact pin, aiohttp floats to 3.14.1, and both [[IgnoredVulns]] entries are removed. Alongside the cycle, a verified competitive/market research refresh corrected the positioning + integration-survey docs (every change traceable to a primary-source verification ledger). 3892 tests pass / 8 skipped; mypy strict 0/0 across 272 source files; ruff clean; frontend tsc + build + vitest 35/35. Workspace ships 8 PyPI packages unchanged from v0.10.8. Per-cycle detail in docs/v0.10.9-plan.md.

Added

  • lib/sse.ts shared SSE reader in the web console — one generic readSse<T> replaces the functionally identical per-page readers in ExplainPage and RiskGeneratePage, with a 6-case vitest spec locking in the exact streaming semantics (chunk-split frames, multi-data: records, keep-alive noise, trailing-partial discard). See commit 91742a3.
  • parity check in the tag-time gate suite. run_gate_suite.py --scope full now runs check_parity.py as its 8th check, so the irreversible publish is blocked on a CLI↔GUI parity regression, not just annotated. See commit 417c912.

Changed

  • Eval CLI auto-sign degrades gracefully without an OIDC token. _resolve_sign's auto-detect branch now additionally requires ACTIONS_ID_TOKEN_REQUEST_TOKEN + ACTIONS_ID_TOKEN_REQUEST_URL (present only in jobs with id-token: write); when CI is detected but no token is obtainable, the eval JSON is written unsigned with a stderr warning instead of crashing with SigstoreSigningError. An explicit --sign keeps attempt-and-raise semantics. 13 new tests cover the tri-state × token matrix. See commit 417c912.
  • CLI↔GUI parity gate is blocking. parity.yml propagates check_parity.py's exit code (the v0.10.8 advisory || echo escape is removed), completing the advisory → blocking flip planned at v0.10.8. See commit 417c912.
  • check_uv_lock_pin_drift attributes pin drift per commit (SF-V108-3): each commit touching uv.lock is diffed against its first parent (plus the working-tree pair), and the push blocks only when a single commit both bumps a workspace version and moves a third-party pin — a separately-committed dependency bump in the range no longer trips the gate (the v0.10.8 false-positive replays green; an aggregate-diff fallback preserves the old strictness on unusual topologies). See commit 417c912.
  • safeguards-resweep is idempotent across closed issues — exact-title matching across open and closed states; a deliberately closed quarterly tracking issue is no longer resurrected. See commit 417c912.
  • PoamPage uses the generated OpenAPI ControlGap-Output type, dropping the hand-rolled local widen. See commit 91742a3.
  • litellm 1.83.14 → 1.88.1, aiohttp 3.13.4 → 3.14.1. The documented aiohttp removal trigger fired: litellm 1.88.1 relaxed its exact aiohttp==3.13.4 pin to <4.0,>=3.10, so aiohttp floats past the 3.14.0 fix release and both accepted client-cookie CVE entries (GHSA-hg6j-4rv6-33pg, GHSA-jg22-mg44-37j8) are removed from osv-scanner.toml. See commit bd8650f.
  • The check_secrets test module resolves a usable bash (Git-for-Windows first) and skips with a precise reason when only the WSL System32 shim is on PATH, instead of failing 6/6 with exit 127 on Windows dev boxes. See commit 316582d.
  • readSse no longer swallows handler exceptions — the malformed-frame catch is narrowed to JSON.parse only, so an onEvent throw propagates to the caller instead of being silently eaten; the reader lock is released on all exits (try/finally).
  • The safeguards-resweep issue probe lists --state all --limit 100 without --search, removing the dependence on GitHub search tokenization and the 30-result default page; throwaway git-fixture repos in the pre-push-check tests pin commit.gpgsign=false so host signing config can't make them prompt or fail.

Fixed

  • CI secret-scan workflow — switched from gitleaks/gitleaks-action (which requires a paid GITLEAKS_LICENSE for organization-owned repos, so it failed at the license gate on every push without ever scanning) to the MIT-licensed gitleaks CLI binary (pinned v8.30.1, SHA256-verified, matching the osv-scanner pin). Running gitleaks end-to-end for the first time surfaced 7 findings, all verified as deliberately-fake test fixtures (the secret-scrubber test's placeholder credentials + fake 16-hex report_key test values) — now allowlisted by module path in .gitleaks.toml; no real secrets. See commit 3d7469a.

Docs

  • Verified competitive/market refresh (quarterly-ish resync; last full pass v0.9.5) applied to positioning-and-value.md + integration-survey.md + the ROADMAP: the Credo-AI self-host/air-gap reframe, the CISO-Assistant MCP correction, the DFAH claim narrowed to "first/only OSS GRC-toolkit implementation", five fabricated-claim strikes (incl. "NASDAQ: SNYK" and a non-existent arXiv citation), the PCAOB five-capabilities framing corrected to Evidentia's own mapping, and the FedRAMP machine-readable timeline re-based to NTC-0009 (2027-11-01, Class D High). Every correction traces to a primary-source verification ledger; all four kickoff regulatory designators (CR26 / RFC-0024 / SR 26-2 / OCC Bulletin 2026-13) double-verified on .gov sources — the shipped occ-sr-26-02 catalog stands. See commit 5cfaf06.

Security

  • F-V109-1 (HIGH, found by the in-cycle scoped security review): single-flag verify no longer silently skips identity pinning. verify_file previously built its identity policy only when both --expected-identity and --expected-issuer were supplied — passing exactly one silently discarded the constraint and verified under an any-signer UnsafeNoOp policy, so a tampered artifact re-signed under any OIDC identity reported VALID. Identity pinning now follows the cosign model (both-or-neither): a single flag is a hard usage error on evidentia eval verify (exit 2), a report-level failure on evidentia oscal verify, and a structured tool error on the verify_signed_artifact MCP tool. Pre-existing since the verify surface shipped; not a v0.10.9 regression.
  • F-V109-2 (MEDIUM): flag-less verification now warns that signer identity is unverified. evidentia eval verify without pinning flags checks the signature + transparency-log inclusion only — it now prints an explicit stderr warning that ANY Sigstore identity would pass and how to pin the signer (exit code unchanged for valid bundles; the MCP result payload carries the equivalent structured warning).
  • F-V109-3 (LOW): the verification output's issuer: line now shows the real OIDC issuer (extracted from the Fulcio certificate extension, OID 1.3.6.1.4.1.57264.1.8) instead of the constant Fulcio X.509 DN, so the human cross-check line can actually discriminate identity providers (clearly-labeled DN fallback when the extension is absent).
  • New accepted advisory: GHSA-rrmf-rvhw-rf47 (torch 2.11.0, CVE-2025-3000, GitHub-reviewed severity LOW, local-only torch.jit.script memory corruption). GitHub-reviewed into the GHSA database 2026-06-10 (NVD-published 2025-03); no fixed version exists (affected through the latest torch); torch is transitive-only via the optional faithfulness-semantic eval extra and no Evidentia source references torch. Operator-confirmed accept; re-validate by 2026-12-10. See commit bd8650f.
  • The aiohttp accepted-CVE pair is closed (not merely re-affirmed): the upstream block lifted and the fixed version now ships in uv.lock (see Changed).

Verify the wheels (PEP 740 publish attestations)

Every wheel uploaded to PyPI from this release carries a
Sigstore-signed PEP 740 publish attestation. Verify locally:

pip install pypi-attestations
pypi-attestations verify pypi \
  --repository https://github.com/polycentric-labs/evidentia \
  "pypi:evidentia==0.10.9"

Verification confirms the wheel was built + published from
polycentric-labs/evidentia/release.yml@refs/tags/v0.10.9
under GitHub Actions OIDC — i.e., a malicious mirror cannot
serve a tampered wheel without the verification failing.

See docs/sigstore-quickstart.md
for the full verification narrative + supply-chain framing.

CHANGELOG

Full changelog (every release): CHANGELOG.md

Container image

  • ghcr.io/polycentric-labs/evidentia:v0.10.9
  • ghcr.io/polycentric-labs/evidentia:latest
  • Digest: sha256:68750fa8cf260cb3f218d24294e101da5f38f2d92d15e9ecc815fce2c7fce6f6

Verify (cosign keyless OIDC):

cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.9 \
  --certificate-identity-r...
Read more

v0.10.8

Choose a tag to compare

@github-actions github-actions released this 05 Jun 04:28
v0.10.8
413cba1

Highlights

Theme: v0.10.8 — safeguards automation + CLI↔GUI parity + Tier-B GUI build-out. Patch bump (v0.10.7 → v0.10.8). Wires the v0.10.7 quality discipline into the automatic release mechanism and opens the CLI↔GUI parity programme.

Release summary: A release-hardening + parity + GUI-build-out cycle with no new end-user product capability — every item either automates a previously-manual safeguard, measures CLI↔GUI coverage, or surfaces an existing CLI/REST capability in the web console. Release-hardening: a tag-time gate job now runs the full check suite on the tagged commit and the PyPI/GHCR publish jobs needs: gate, so the irreversible publish is blocked on a red or stale tree (closing the gap that left the staleness guards pre-push-only); a consistency.yml CI job mirrors the version + docs-health + README guards onto every push/PR; the pre-push hook regenerates the README Recent-Releases block and fails if it drifted; and a secret-scan.yml (gitleaks) catches a committed credential even on a clone without the local hook. All of these (plus the pre-push hook and the tag-gate) read one declarative check-list via scripts/run_gate_suite.py, so the surfaces cannot drift (the v0.9.8 gate-fidelity lesson). CLI↔GUI parity: a new docs/cli-gui-parity.yaml manifest classifies every CLI leaf (full / api-only / cli-only / exempt) and scripts/check_parity.py enforces completeness + API-existence + GUI-existence + a cli-only debt-ratchet (catching the coverage gap a passing type-drift gate masks); GUI coverage rises 6.1% → 13.3% via four new Tier-B web screens. Phase-G upkeep: stale-branch flagging, Dependabot patch/minor auto-merge, and a quarterly safeguards re-sweep. 3869 tests pass / 14 skipped; mypy strict 0/0 across 272 source files; ruff clean. Workspace ships 8 PyPI packages unchanged from v0.10.7. Per-cycle detail in docs/v0.10.8-plan.md.

Added

  • Tag-time release gate. release.yml gains a gate job that runs the full SSOT check suite on the tagged commit, and the PyPI/GHCR publish jobs now needs: gate. A red or stale tree therefore can't reach the irreversible publish — scripts/run_gate_suite.py --scope full covers tests + types + lint + version-consistency + docs-health + osv, closing the gap that left those guards pre-push-only while the publish ran ungated. See commit 10efb09.
  • CI staleness mirror. New consistency.yml runs the same SSOT gate suite (--scope consistency: version-consistency + docs-health + README-releases) on every push/PR to main, so a stale version reference, broken doc cross-link, or stale README block fails fast rather than at tag time. See commit 10efb09.
  • README Recent-Releases auto-regen in the pre-push gate. A new pre-push check regenerates the README releases block from CHANGELOG.md and fails if it changed, making the v0.10.7-class README staleness mechanically impossible (the --check guard was version-only by design). See commit 586c1a3.
  • CI secret-scan. secret-scan.yml runs gitleaks on every push/PR to main with a shared .gitleaks.toml (upstream ruleset + a tests-fixtures/examples allowlist), complementing the local pre-push secret scan so a committed credential is caught even on a clone without the hook. See commit 2ef1fba.
  • CLI↔GUI parity manifest + gate. docs/cli-gui-parity.yaml classifies every CLI leaf; scripts/check_parity.py enforces completeness + API-existence + GUI-existence (catching the types-only illusion the OpenAPI-drift gate misses) + a cli-only debt-ratchet; parity.yml runs it advisory this release (blocking in v0.10.9); docs/parity-coverage.md is the generated burndown + the README badge. See commits 34a6c53, 57bf51f.
  • Four Tier-B web screens. POA&M (/poam) — list + severity/status filters + in-page detail + forward-only milestone state-transitions; TPRM (/tprm) — vendor list + tier/type filters + atomic create form; ConMon (/conmon) — read-only cadence browser; Explain (/explain) — framework + control-id picker + SSE-streamed plain-English explanation with an LLM-provider guard. Each follows the existing inline-useQuery + shadcn/ui patterns; vitest covers render + the primary interaction (29/29). GUI coverage 6.1% → 13.3% as 7 CLI leaves flip api-only → full. See commits b08ff49, 7de204e.
  • Phase-G upkeep automations. stale-branches.yml flags branches with no commit in >30d to the run summary (read-only, never deletes); dependabot-automerge.yml enables auto-merge on green patch/minor Dependabot PRs (gated to the dependabot[bot] actor; major bumps stay manual; requires the repo "Allow auto-merge" setting enabled separately); safeguards-resweep.yml opens a quarterly tracking issue to re-run the automated-vs-manual safeguards audit. All pass audit_workflow_permissions --strict (the 2 write-scoped workflows carry JUSTIFIED annotations). See commit f5ca9e7.
  • Operator-walkthrough wiki media. A web-console section added to manage-poam + conmon-deployment, the TPRM GUI walkthrough merged into manage-third-party-risk, and a new explain-controls guide — each with a captured screenshot under docs/wiki/images/. See commit 4318cff.
  • README hero refresh. A centered hero — the 2400×1260 OG brand card + a tight tagline + Get Started / Documentation / PyPI call-to-action buttons + the nine status badges centered beneath (presentation only; the Recent-Releases block + the container-tag version anchor untouched). See commit 87b851a.

Changed

  • pyjwt 2.12.1 → 2.13.0 — closes CVE-2026-48522 / 48524 / 48525 / 48526 (osv PYSEC-2026-175/177/178/179, up to CVSS 7.4), surfaced by the new osv gate; the bump resolves cleanly (only pyjwt moves) and the full suite re-validates green. See commit 7669ed3.
  • .gitleaks.toml is classified frozen in the version-tracking manifest — it carries a v0.10.8 audit-trail comment but no project-version literal, so the never-skip version-consistency guard flagged it once committed; classifying it alongside the other root-level config dotfiles resolves that. See commit d611588.

Docs

  • explain-controls.md intro corrected — the explanation is delivered over a Server-Sent-Events stream (a start frame, then a single terminal frame), not progressive token rendering; the prior wording over-stated incremental streaming. A G28 docs-from-verified-facts fix caught by diffing the guide against ExplainPage.tsx.
  • The v0.10.5 / v0.10.6 / v0.10.7 in-repo security-review docs were backfilled (v0.10.5/.6 honestly mark ship-telemetry VERIFY-LIMITED where no per-run JSON exists; v0.10.7 is fully verified). See commit 70e8057.
  • docs/sarif-ingestion-collector-design.md NEW — design spec for a v0.11 evidentia collect sarif ingestion collector (control-agnostic default + attestation-gated candidate mappings, mirroring the v0.10.1 OCSF ingest path); docs/integration-survey.md gains an agentic-security interop assessment (data-layer SARIF handoff; no code reuse across the PolyForm/Apache-2.0 boundary). See commits 10b0a5c, a99273a.
  • docs/v0.9.3-plan.md 3 stale cross-link WARNs fixed; the accepted tuf 6.0.0 osv-scanner.toml ignore gains a removal-trigger note (drop when sigstore ships tuf-7 support). See commit 244ec83.

Security

  • pyjwt four-CVE bump (see Changed) — the headline supply-chain fix this cycle, caught pre-tag by the new osv gate before publish.
  • The tag-time gate's osv step and the gitleaks CI secret-scan are net-new supply-chain safeguards that now run on the irreversible publish path, not just the local pre-push hook.

Verify the wheels (PEP 740 publish attestations)

Every wheel uploaded to PyPI from this release carries a
Sigstore-signed PEP 740 publish attestation. Verify locally:

pip install pypi-attestations
pypi-attestations verify pypi \
  --repository https://github.com/polycentric-labs/evidentia \
  "pypi:evidentia==0.10.8"

Verification confirms the wheel was built + published from
polycentric-labs/evidentia/release.yml@refs/tags/v0.10.8
under GitHub Actions OIDC — i.e., a malicious mirror cannot
serve a tampered wheel without the verification failing.

See docs/sigstore-quickstart.md
for the full verification narrative + supply-chain framing.

CHANGELOG

Full changelog (every release): CHANGELOG.md

Container image

  • ghcr.io/polycentric-labs/evidentia:v0.10.8
  • ghcr.io/polycentric-labs/evidentia:latest
  • Digest: sha256:19bee7abd9096125803a7faa682844867af81559d422c6f4f65e446c881b530f

Verify (cosign keyless OIDC):

cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.8 \
  --certificate-identity-regexp 'https://github\.com/Polycentric-Labs/evidentia/\.github/workflows/release\.yml@refs/tags/v.*' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com'

Verify (SLSA build provenance):

gh attestation verify oci://ghcr.io/polycentric-labs/evidentia:v0.10.8 \
  -R Polycentric-Labs/evidentia

See docs/sigstore-quickstart.md
for the full verification narrative.