diff --git a/CHANGELOG.md b/CHANGELOG.md index 983f7f7a..0ebdfe08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +_No changes yet on the v0.11.x development branch._ + +## [0.11.0] - 2026-07-16 + +**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 emission** — `evidentia 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-16 — see [`docs/releases/plans/v0.12-plan.md`](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** +- **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 @@ -21,7 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 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** (pre-v0.11.0; every change +- **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, @@ -43,10 +51,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 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`** (v0.11 Wave 2; spec ratified 2026-07-14, lifecycle phases + 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 → @@ -64,7 +90,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `AI_ACQUISITION_PHASE_RECORDED` audit events. - **OMB M-25-21 minimum-practice tracking — `evidentia ai-gov set-practice`** - (v0.11 Wave 2): fills the per-practice extension point reserved at + (#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 / @@ -80,7 +106,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 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`** (v0.11 Wave 2, +- **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 diff --git a/CITATION.cff b/CITATION.cff index 6070792c..da9dd7b5 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -47,5 +47,5 @@ keywords: - slsa - python license: Apache-2.0 -version: 0.10.18 -date-released: '2026-07-13' +version: 0.11.0 +date-released: '2026-07-17' diff --git a/README.md b/README.md index f251c8d5..c422d5d1 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ For the full workspace (AI risk-statements, REST API, all collectors, MCP server pip install 'evidentia[ai,api,collectors,mcp]' ``` -Container: `docker pull ghcr.io/polycentric-labs/evidentia:v0.10.18` (cosign keyless OIDC + SLSA Provenance v1 verified). +Container: `docker pull ghcr.io/polycentric-labs/evidentia:v0.11.0` (cosign keyless OIDC + SLSA Provenance v1 verified). See the [Getting Started wiki section](https://github.com/Polycentric-Labs/evidentia/wiki/Getting-Started) for air-gapped install, virtualenv setup, and full extras matrix. @@ -121,12 +121,12 @@ See it first, no install — a self-hosted [asciinema](https://asciinema.org/) r ## Recent Releases +**v0.11.0 (2026-07-16)** — *The federal wave — three verified federal firsts on machine-readable rails*. **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. + **v0.10.18 (2026-07-14)** — *Container rebuild on a fresh hardened base*. **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. **v0.10.17 (2026-07-09)** — *v0.10.x hardening close-out*. **Release-pipeline preflight dry-run**, `release.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. -**v0.10.16 (2026-07-02)** — *Engineering hardening + distroless container base — never ship a failed test again*. **Cryptography-native air-gap signing via DSSE/in-toto**, a binary-free, network-free signing path that works inside distroless and minimal-base containers. - Full release history: [`CHANGELOG.md`](CHANGELOG.md) | [GitHub Releases](https://github.com/Polycentric-Labs/evidentia/releases) ## Community & Governance diff --git a/SECURITY.md b/SECURITY.md index 9c2deaab..02e79e21 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -70,7 +70,7 @@ a vulnerability in Evidentia's own code. | Version | Status | Reason | |---------|--------|--------| -| **`0.10.18`** | ✅ **Supported** | Latest patch. See the [CHANGELOG](CHANGELOG.md) and the latest `docs/releases/reviews/security-review-*.md` for what shipped and the CVE posture at this release. | +| **`0.11.0`** | ✅ **Supported** | Latest patch. See the [CHANGELOG](CHANGELOG.md) and the latest `docs/releases/reviews/security-review-*.md` for what shipped and the CVE posture at this release. | | Earlier patches | ❌ Deprecated | Pre-v1.0 single-supported-patch policy; upgrade to the latest patch. | | Legacy `controlbridge*` packages | ❌ Yanked from PyPI | Every version of every legacy package was yanked at the v0.6.0 rename. Upgrade path documented in [`RENAMED.md`](docs/archive/RENAMED.md). | @@ -172,7 +172,7 @@ Verify a release wheel: pip install pypi-attestations pypi-attestations verify pypi \ --repository https://github.com/Polycentric-Labs/evidentia \ - "pypi:evidentia-0.10.18-py3-none-any.whl" + "pypi:evidentia-0.11.0-py3-none-any.whl" ``` If verification fails, **stop and report immediately** via the diff --git a/docker/Dockerfile.demo b/docker/Dockerfile.demo index cf180973..d4b6ae18 100644 --- a/docker/Dockerfile.demo +++ b/docker/Dockerfile.demo @@ -58,7 +58,7 @@ # from cosign verification, NOT `:latest`): # docker build -f docker/Dockerfile.demo \ # --build-arg BASE=ghcr.io/polycentric-labs/evidentia@sha256: \ -# -t evidentia-demo:v0.10.18 . +# -t evidentia-demo:v0.11.0 . # # Smoke test (before the signed digest exists — BASE is overridable so the # multi-stage build + the allowlist/refusal logic are testable against a bare @@ -74,7 +74,7 @@ # docker run --rm --network none --read-only --tmpfs /tmp \ # --memory 512m --cpus 1 --pids-limit 256 \ # --security-opt no-new-privileges --cap-drop ALL \ -# evidentia-demo:v0.10.18 doctor +# evidentia-demo:v0.11.0 doctor # The signed release digest is the default BASE at deploy time. Declared here as a # GLOBAL ARG (before the first FROM) so the final stage's `FROM ${BASE}` can diff --git a/docker/requirements.in b/docker/requirements.in index b41fef39..abe92f20 100644 --- a/docker/requirements.in +++ b/docker/requirements.in @@ -1,2 +1,2 @@ -evidentia[gui]==0.10.18 +evidentia[gui]==0.11.0 urllib3>=2.7.0 diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index f43c2b84..194bceb6 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -1,6 +1,6 @@ # Evidentia roadmap -**Last updated: v0.10.18 (planning, July 2026).** +**Last updated: v0.11.0 (planning, July 2026).** > **Engineering practices** — how Evidentia is built, tested, and shipped (the > PR-flow + merge-queue gate, atomic releases, supply-chain integrity, and the @@ -2038,15 +2038,41 @@ DEFER-WITH-TRIGGER verdict and a same-day setuptools 83.0.0 fix v0.11.0's boundary re-cuts to Waves 1–2. No package (`packages/*/src`) code changes. -## v0.11 — Federal-compliance theme + AI governance — PLANNED +## v0.11 — Federal-compliance theme + AI governance — SHIPPED -**The open cycle** (opened 2026-07-09). Full plan: +Opened 2026-07-09; **closed 2026-07-16 with v0.11.0** (the re-cut +Wave 1–2 scope per the 2026-07-14 boundary re-cut — Wave 0 + the +hygiene track H1–H6 had shipped early inside v0.10.18). Full plan: [`v0.11-plan.md`](releases/plans/v0.11-plan.md) — wave sequencing, the cycle-hygiene track (the 2026-07 practice-delta adoptions + the v0.10.17 deferred queue), the medical-device row split, and the -ratification asks. Sourced from Phase B audit v3 + integration plan -§"Per-release detailed integration plan" §v0.11. Substantive minor -(~6-8 weeks): +ratification record. The remaining planned waves carry the **ratified +2026-07-16 disposition** in +[`v0.12-plan.md`](releases/plans/v0.12-plan.md) (Wave 4 phase 3 → +v0.12-if-capacity; Wave 4 phases 1/2/4 + Wave 3 DORA + medical-device +traceability → v1.1; Waves 5–6 → post-1.0; arXiv preprint = open +decision). + +### v0.11.0 — The federal wave — SHIPPED (released 2026-07-16) + +Three verified federal firsts on machine-readable rails: **FedRAMP +CR26 SDR emission** (`evidentia conmon ksi` — the SDR +`keySecurityIndicators` block, 10 families / 46 KSIs, conformant to +the official 2026-06-24 schemas vendored at pinned SHAs and re-verified +at their 1.0.0 graduation; weekly `fedramp-schema-watch` drift +sentinel; the first production-grade OSS emitter of the format), +**OMB M-25-21 minimum-practice tracking** (`ai-gov set-practice` — +seven §4(b) practices with CAIO waiver objects carrying the annual +re-cert + 30-day OMB-report clocks), and **OMB M-25-22 +acquisition-lifecycle tracking** (`ai-gov acquisition` — the six §4 +phases with the §4(a) high-impact tie-in). Plus the ratified OSCAL +1.2.2 DEFER-WITH-TRIGGER verdict and a pre-release claim-accuracy +sweep (parity restated at the live 93.4%; first-mover registry updated +with explicit caveats). Test suite 4,939 passed. The five federal +api-only parity rows lead the v0.12 GUI pass. + +The feature bullets below are the cycle's planning record; items not +shipped in v0.11.0 carry the ratified disposition above. - **KSI (Key Security Indicators) emission** — wires as third output mode on `evidentia conmon` alongside the 7 bundled cadences shipped @@ -2237,7 +2263,7 @@ engineering-hardening batch addressed all three: maintainer — checked at PRR Row 21). P3 FIPS container variant stays gated on the federal-SI OpenPGP-interop answer. -### Medical-device GRC feature line (v0.11 → v1.1+) — PLANNED (web-grounded research 2026-06-17) +### Medical-device GRC feature line (v1.1+; re-cut 2026-07-16 from v0.11) — RESERVED (web-grounded research 2026-06-17) The medical-device-security direction the v0.10.10 FDA Section 524B catalogs opened, scanned + validated in a multi-angle web-grounded research pass. **Each feature gets a dedicated `polycentric-labcoat` research fleet at build-time** — the entries below are the high-level scan + positioning, not build specs. Effort and tier are planning-grade. The throughline: **don't rebuild commodity layers (STRIDE authoring, CBOM scanners) — ingest them; the uncontested slice is the open, signed, OSCAL/BOM-emitting evidence wrapper.** @@ -2280,6 +2306,23 @@ Items deferred from Phase B audit v3 + integration plan §"v1.1+": - Architectural Tier 3 items from Phase B audit v3 (control-chart script ships skill-side; dynamic-install eBPF scan; etc.). +## v0.12 — Pre-1.0 hardening + GUI parity — PLANNED + +**The open cycle** (ratified 2026-07-16 at the v0.11.0 release prep). +Full plan: [`v0.12-plan.md`](releases/plans/v0.12-plan.md) — the +ratified disposition of the remaining v0.11 waves plus the LEAN v0.12 +scope: (1) the GUI parity pass for the five v0.11 federal api-only +verbs (+ the `version`/`init` exempt-reclassification decision); +(2) deprecation completions ahead of the v1.0.0 removals; +(3) api-stability freeze-prep (the surface audit the v1.0 stability +promise formalizes); (4) CR26 emitter coverage extension only if cheap +(FRR statements next); (5) the CR26-fragility watches (upstream PR #4 +delta drop, additionalProperties tightening, CR27 dated-fileset MAJOR, +the competitive-flip playbook, and the fresh-drift-probe-at-release +lesson). The v1.0 operator self-test is scheduled at v0.12 cycle-open +per [`v1.0-transition.md`](v1.0-transition.md) so reviewer outreach can +start while v0.12 builds. + ## v1.0 — Federal compliance shipped + API stability — RESERVED See [`docs/v1.0-transition.md`](v1.0-transition.md) for the full diff --git a/docs/capability-matrix.md b/docs/capability-matrix.md index 9bacbe0c..0e6d70f0 100644 --- a/docs/capability-matrix.md +++ b/docs/capability-matrix.md @@ -1,4 +1,4 @@ -# Evidentia capability matrix (v0.7.0 baseline · re-validated through v0.10.12) +# Evidentia capability matrix (v0.7.0 baseline · re-validated through v0.11.0) > Step-4 deliverable from the v0.7.0 comprehensive review (2026-04-25). > Functional + code-review + adversarial smoke testing of every public @@ -13,6 +13,33 @@ --- +## Re-validation snapshot — 2026-07-16 (v0.11.0 PRE-TAG) — the federal wave + +v0.11.0 ships the re-cut Wave 1–2 scope: FedRAMP CR26 SDR emission, OMB +M-25-21 minimum-practice tracking, and OMB M-25-22 acquisition-lifecycle +tracking, plus the ratified OSCAL 1.2.2 DEFER-WITH-TRIGGER verdict and a +pre-release claim-accuracy sweep. Unchanged subsystems are REUSED from the +v0.10.x matrices; this snapshot covers the federal-wave delta. + +### Surface delta — new in v0.11.0 + +| # | New surface | Kind | Verification | +|---|---|---|---| +| 1 | `evidentia conmon ksi` — CR26 Security Decision Record `keySecurityIndicators` emission (10 families / 46 KSIs; schema-valid full-SDR skeleton; official 2026-06-24 schemas vendored at pinned SHAs, re-verified at their 1.0.0 graduation) | CLI | 26 emitter tests incl. jsonschema round-trip against the vendored schemas; emitted output re-validated against upstream 1.0.0 at the graduation re-vendor; the 5 no-base-`statement` KSIs + 2 no-800-53-mapping KSIs covered explicitly | +| 2 | `ai-gov set-practice` — M-25-21 seven §4(b) practices; a WAIVED practice captures a CAIO waiver object recording the annual re-certification + 30-day OMB-report dates (the `waiver_certification_due` / `waiver_omb_report_overdue` clock helpers evaluate them; surfacing them in a verb/console is a v0.12 item) | CLI/API | 28 tests; waived-status model validator (waiver fields enforced); practice headings verified against the memo PDF; RBAC write-gated | +| 3 | `ai-gov acquisition register\|list\|show\|set-phase` — M-25-22 six §4 lifecycle phases, §4(a) high-impact tie-in | CLI/API | 26 tests; `AIAcquisitionStore` = registry-store clone (traversal guard, atomic writes, `EVIDENTIA_AI_ACQUISITION_DIR` isolation); phases verified verbatim against the memo | +| 4 | `fedramp-ksi-2026` catalog (46 indicators) + 800-53 rev5 crosswalk | Catalog | catalog-loader + crosswalk unit tests; `gen_fedramp_ksi.py --check` re-derives both from the pinned `FedRAMP/rules` dataset (2026.07.14.01) on demand (run at each re-vendor; not yet a standing CI gate) | +| 5 | `fedramp-schema-watch.yml` weekly drift sentinel | CI | Fired-live lesson recorded: upstream moved inside the blind window on 2026-07-15 (SDR 0.1.0 → 1.0.0); a fresh drift probe at the release gate caught it and the schemas were re-vendored pre-tag | + +### Parity baseline (G27 cross-surface walk) + +`check_parity` is green on all 5 checks. Counts: **99 full / 7 api-only / +0 cli-only / 11 exempt = 93.4% GUI coverage**. The 7 api-only rows are +expected and documented: the five v0.11 federal verbs (`ai-gov +set-practice` + the four `ai-gov acquisition` verbs — the GUI pass leads +v0.12) plus the two legacy chrome-surfaced utilities (`version`, `init`, +exempt-reclassification decision queued in the v0.12 plan). + ## Re-validation snapshot — 2026-06-23 (v0.10.12 PRE-TAG) — full CLI↔GUI parity build-out + OMB M-25-21 v0.10.12 closes the CLI↔GUI parity programme opened in v0.10.8: GUI coverage of diff --git a/docs/deprecation-calendar.md b/docs/deprecation-calendar.md index 2b7588ca..9733f058 100644 --- a/docs/deprecation-calendar.md +++ b/docs/deprecation-calendar.md @@ -23,7 +23,7 @@ | `evidentia_core.models.finding.SecurityFinding` (library class name) | `evidentia_core.models.finding.Finding` (same class, new canonical name) | v0.10.1 (2026-05-23) | **v1.0.0** (earliest major bump) | The `SecurityFinding` name is kept as a backward-compatible alias for ≥ 1 minor cycle per the deprecation policy. Both names refer to the same class — no runtime difference, no behavior change, `isinstance(obj, SecurityFinding)` and `isinstance(obj, Finding)` both succeed. The rename aligns with OCSF's "Finding" terminology (Compliance Finding, Detection Finding). No `DeprecationWarning` is emitted in v0.10.1 to avoid spamming the ~50+ existing call sites — the alias is silent. Operators / integrators are encouraged to switch to `Finding` in new code; existing code keeps working unchanged. | | `evidentia ai-gov set-omb-impact` (CLI) + `OMBImpactRequest` / `POST …/omb-impact` (API) — OMB **M-24-10** impact leveling | `evidentia ai-gov set-high-impact` + `HighImpactRequest` — OMB **M-25-21** high-impact determination | v0.10.12 (2026-06-23) | **v1.0.0** | OMB M-24-10 was rescinded 2025-04-03 and superseded by M-25-21. The legacy M-24-10 surface is retained as a backward-compatible alias per the deprecation policy; new code should record the M-25-21 high-impact determination instead. | -No other surfaces are currently deprecated as of v0.10.18. +No other surfaces are currently deprecated as of v0.11.0. --- diff --git a/docs/enterprise-grade.md b/docs/enterprise-grade.md index f7bd3efa..2f933ddb 100644 --- a/docs/enterprise-grade.md +++ b/docs/enterprise-grade.md @@ -1,7 +1,7 @@ # Enterprise-grade credibility checklist > Baseline established at v0.7.0 (historical). -> Maintenance summary current as of release v0.10.18. +> Maintenance summary current as of release v0.11.0. Evidentia's v0.7.0 release established the quality bar that Big-4 audit firms (Deloitte, PwC, KPMG, EY), FedRAMP Third-Party Assessor diff --git a/docs/releases/plans/v0.12-plan.md b/docs/releases/plans/v0.12-plan.md new file mode 100644 index 00000000..2d974d34 --- /dev/null +++ b/docs/releases/plans/v0.12-plan.md @@ -0,0 +1,77 @@ +# v0.12 plan — Pre-1.0 hardening + GUI parity + +**Status: RATIFIED 2026-07-16** (scope disposition approved as proposed; the +arXiv-preprint timing remains an explicitly open decision, to be settled at +detailed v0.12 planning). This plan RE-CUTS the ratified 2026-07-09 v0.11 +plan: v0.11.0 shipped the re-cut Wave 1–2 scope (per the 2026-07-14 boundary +re-cut recorded in [`v0.11-plan.md`](v0.11-plan.md)), and this document +records the ratified disposition of the remaining v0.11 waves. + +Scope philosophy: **LEAN**. v0.12 is the pre-1.0 hardening cycle — close the +parity debt the v0.11 federal wave created, complete the deprecation +lifecycle ahead of the v1.0 removals, and freeze-prep the API surface the +v1.0 stability promise will formalize. Feature expansion waits for the v1.x +line. + +--- + +## Disposition of remaining v0.11 waves (ratified 2026-07-16) + +| Ratified v0.11 item | New home | Rationale | +|---|---|---| +| Wave 4 phase 3 — first Apache-2.0 EU-AI-Act ↔ ISO/IEC 42001 crosswalk | **v0.12 if capacity** | Verified-open first-mover lane (forward claim, re-verify at build time); highest-value Wave-4 phase; self-contained data work | +| Wave 4 phases 1, 2, 4 — ISO 27001 climate amendment; NIST AI 600-1 + ISO/IEC 23894 Tier-B catalogs; CETS 225 Tier-C stub | **v1.1** | Catalog enrichment with no deadline pressure; defers cleanly | +| Wave 3 — DORA Art. 17 emitter + DORA-metrics extractor | **v1.1** | First-OSS-mover claim is forward/verify-at-build; DORA enforcement live but no date-forcing event inside the v0.12 window | +| Wave 5 — OpenVEX per-release publish + SLSA VSA emit | **v1.1+ (post-1.0)** | Attestation-surface expansion; no regulatory clock; integration-survey rows already moved to planned tense with no version commitment | +| Wave 6 — SARIF-ingestion collector (committed design doc) + auto-generated security-review docs | **v1.1+ (post-1.0)** | Design doc stays committed; build waits for the stable-API base | +| Wave 7 — arXiv preprint | **OPEN DECISION** (pre-1.0 priority stake vs v1.1) — settle at detailed v0.12 planning | Preprint establishes niche priority; publishing is maintainer-gated either way | +| Wave 7 — integration-survey competitive refresh | **v1.1+, or fold into the quarterly resync (next ~2026-09)** | The 2026-07-15 strategy pass already refreshed the load-bearing competitive facts | +| Medical-device Threat→Control→Test traceability enrichment (ratified IN for v0.11) | **v1.1** | v1.0-speed priority; extends the shipped v0.10.11 signed-OSCAL matrix and loses nothing by waiting | + +## v0.12 scope (ratified) + +1. **GUI parity pass** — surface the 5 Wave-2 api-only rows in the web + console (`ai-gov set-practice`, `ai-gov acquisition + register|list|show|set-phase`); decide the 2 legacy api-only rows + (`version`, `init` — chrome/index-surfaced; candidates for `exempt` + reclassification rather than console build). Target: parity back above + the ~98% line honestly, via shipped GUI rather than reclassification + alone. +2. **Deprecation completions** — final-cycle warnings for the three active + v1.0.0-targeted deprecations in + [`deprecation-calendar.md`](../../deprecation-calendar.md) + (`--last-completed-file`, `SecurityFinding` alias, the M-24-10 legacy + surface); removals execute AT v1.0.0, not in v0.12. +3. **api-stability freeze-prep** — audit the live public surface against + [`api-stability.md`](../../api-stability.md); enumerate any surface + shipped since the NORMATIVE promotion that the v1.0 stability promise + should cover (the Wave-2 federal surfaces in particular); publish the + delta as a freeze-candidate list. +4. **CR26 emitter coverage extension — only if cheap** — FRR statements as + the next SDR block after `keySecurityIndicators`; skip if upstream churn + makes it rework-prone inside the window. +5. **CR26-fragility watches wired in** — (a) FedRAMP/schemas PR #4 merge → + drop the vendored `$ref` delta + re-pin (the 2026-07-16 re-vendor at the + SDR 1.0.0 graduation retained it — upstream left the defect in place); + (b) watch for upstream `additionalProperties` tightening (the emitted + metadata block's validity depends on its absence); (c) a NEW dated + fileset (CR27) = MAJOR drift per the sentinel severity model; (d) + competitive-flip playbook: if a conformant CR26-SDR emitter ships from + an established tool, first-mover claim wording updates within the week + (the OSS-scoped phrasing survives); (e) lesson from 2026-07-15: the + weekly sentinel has a blind window — any release gate re-runs + `scripts/check_fedramp_upstream_drift.py` fresh. + +## v1.0 sequencing note + +Per [`v1.0-transition.md`](../../v1.0-transition.md), the operator self-test ++ demo/pitch recording is a hard acceptance gate before any external +presentation, and external-reviewer latency dominates the v1.0 calendar — +schedule the self-test at v0.12 cycle-open so reviewer outreach can start +while v0.12 builds. + +--- + +*Plan ratified at v0.11.0 release prep (2026-07-16); it also satisfies the +roadmap-currency gate (exactly-one-PLANNED-h2 + plan-doc-exists). Detailed +wave/sequencing planning follows after v0.11.0 ships.* diff --git a/docs/threat-model.md b/docs/threat-model.md index bfc87364..7fe2580c 100644 --- a/docs/threat-model.md +++ b/docs/threat-model.md @@ -3408,6 +3408,60 @@ by this entry. --- +## v0.11.0 attack-surface delta — the federal wave (PRE-TAG 2026-07-16) + +v0.11.0 adds three surface families; none opens a new network listener +or credential path. + +### Surface 1 — `evidentia conmon ksi` (CR26 SDR emission) + +File-in/file-out CLI verb: an operator-authored YAML status file +(`KsiStatusDocument`, Pydantic-validated) plus an optional CONMON state +file in, an SDR JSON document out. No network egress — validation runs +against the **vendored** FedRAMP schemas (offline / air-gap-consistent). +Threats + guards: + +- **Untrusted YAML input** — parsed with `yaml.safe_load` semantics via + the established loader path and validated against a strict Pydantic + model (unknown indicator IDs are a hard error against the bundled + `fedramp-ksi-2026` catalog; enum-constrained statuses/evidence types). +- **Vendored-schema supply chain** — the schemas are upstream content + committed in-tree; provenance is pinned in `UPSTREAM.json` (commit + + blob SHA + sha256 per file, one documented local delta) and + drift-watched weekly by `fedramp-schema-watch`, whose blind window is + compensated by a fresh drift probe at every release gate. +- **Output integrity** — deterministic snapshots via the explicit + `--last-updated` flag (SDR-CSO-MTD metadata); no secrets transit the + document. + +### Surface 2 — `ai-gov set-practice` (M-25-21) + `ai-gov acquisition` (M-25-22) + +New file-backed store (`AIAcquisitionStore`) cloned from the hardened +registry-store pattern: UUID filenames, path-traversal guard, +atomic writes, trusted-directory boundary via +`EVIDENTIA_AI_ACQUISITION_DIR`. The API mirrors +(`POST /api/ai-gov/systems/{id}/set-practice`, +`/api/ai-gov/acquisitions*`) inherit the existing ai-gov router +posture: localhost-bound default, RBAC write-gating (deny-by-default +403 tests), Pydantic validation with enum-constrained +practices/phases/statuses (every operator-supplied string field is +`max_length`-bounded), and structured-error responses. Unlike the +`register` / `classify` endpoints, the v0.11 mutating routes do not +carry the `X-Idempotency-Key` body-hash dedup mechanism — a retried +`register` acquisition creates a second record; retry-dedup for these +routes is a tracked v0.12 item. New audit events +(`AI_SYSTEM_PRACTICE_RECORDED`, `AI_ACQUISITION_REGISTERED`, +`AI_ACQUISITION_PHASE_RECORDED`) ride the ECS/AU-3 audit stream. + +### Surface 3 — `fedramp-schema-watch.yml` (weekly CI sentinel) + +Read-only upstream probe (stdlib + `gh` CLI on the runner token) with +`contents: read` and job-scoped `issues: write` for the tracking-issue +path; zizmor/least-privilege gated like the sibling sentinels. No +repository write access. + +--- + *First published v0.7.7 (2026-05). Origin: promoted from a project-internal deep-pass note to a public-surface doc to satisfy pre-release-review v4 G5 (threat-model existence gate) diff --git a/docs/verification.md b/docs/verification.md index bf43ff12..d57b4f79 100644 --- a/docs/verification.md +++ b/docs/verification.md @@ -21,10 +21,10 @@ pip install pypi-attestations # Verify a single wheel pypi-attestations verify pypi \ --repository https://github.com/Polycentric-Labs/evidentia \ - pypi:evidentia_core-0.10.18-py3-none-any.whl + pypi:evidentia_core-0.11.0-py3-none-any.whl # Expected output: -# OK: evidentia_core-0.10.18-py3-none-any.whl +# OK: evidentia_core-0.11.0-py3-none-any.whl ``` **PowerShell (Windows)** @@ -36,10 +36,10 @@ pip install pypi-attestations # Verify a single wheel pypi-attestations verify pypi ` --repository https://github.com/Polycentric-Labs/evidentia ` - pypi:evidentia_core-0.10.18-py3-none-any.whl + pypi:evidentia_core-0.11.0-py3-none-any.whl # Expected output: -# OK: evidentia_core-0.10.18-py3-none-any.whl +# OK: evidentia_core-0.11.0-py3-none-any.whl ``` Per-release sweep across all 8 packages: @@ -51,7 +51,7 @@ for pkg in evidentia evidentia_ai evidentia_api evidentia_collectors \ evidentia_core evidentia_eval evidentia_integrations evidentia_mcp; do pypi-attestations verify pypi \ --repository https://github.com/Polycentric-Labs/evidentia \ - "pypi:${pkg}-0.10.18-py3-none-any.whl" + "pypi:${pkg}-0.11.0-py3-none-any.whl" done ``` @@ -62,7 +62,7 @@ foreach ($pkg in 'evidentia','evidentia_ai','evidentia_api','evidentia_collector 'evidentia_core','evidentia_eval','evidentia_integrations','evidentia_mcp') { pypi-attestations verify pypi ` --repository https://github.com/Polycentric-Labs/evidentia ` - "pypi:${pkg}-0.10.18-py3-none-any.whl" + "pypi:${pkg}-0.11.0-py3-none-any.whl" } ``` @@ -75,8 +75,8 @@ foreach ($pkg in 'evidentia','evidentia_ai','evidentia_api','evidentia_collector # https://docs.sigstore.dev/system_config/installation/ # Verify the container's keyless OIDC signature -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/v0.10.18" \ +cosign verify ghcr.io/polycentric-labs/evidentia:v0.11.0 \ + --certificate-identity-regexp "https://github.com/Polycentric-Labs/evidentia/.github/workflows/release.yml@refs/tags/v0.11.0" \ --certificate-oidc-issuer https://token.actions.githubusercontent.com # Expected output: "The cosign claims were validated" + SLSA Provenance v1 JSON. @@ -89,8 +89,8 @@ cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.18 \ # https://docs.sigstore.dev/system_config/installation/ # Verify the container's keyless OIDC signature -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/v0.10.18" ` +cosign verify ghcr.io/polycentric-labs/evidentia:v0.11.0 ` + --certificate-identity-regexp "https://github.com/Polycentric-Labs/evidentia/.github/workflows/release.yml@refs/tags/v0.11.0" ` --certificate-oidc-issuer https://token.actions.githubusercontent.com # Expected output: "The cosign claims were validated" + SLSA Provenance v1 JSON. @@ -102,7 +102,7 @@ cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.18 ` ```bash # Download the SBOM -gh release download v0.10.18 --pattern 'evidentia-sbom.cdx.json' \ +gh release download v0.11.0 --pattern 'evidentia-sbom.cdx.json' \ --repo Polycentric-Labs/evidentia # Scan for vulnerabilities @@ -115,7 +115,7 @@ osv-scanner scan source -L evidentia-sbom.cdx.json ```powershell # Download the SBOM -gh release download v0.10.18 --pattern 'evidentia-sbom.cdx.json' ` +gh release download v0.11.0 --pattern 'evidentia-sbom.cdx.json' ` --repo Polycentric-Labs/evidentia # Scan for vulnerabilities @@ -132,8 +132,8 @@ attestation inline. To extract it: **Bash / Linux / macOS** ```bash -cosign verify-attestation ghcr.io/polycentric-labs/evidentia:v0.10.18 \ - --certificate-identity-regexp "https://github.com/Polycentric-Labs/evidentia/.github/workflows/release.yml@refs/tags/v0.10.18" \ +cosign verify-attestation ghcr.io/polycentric-labs/evidentia:v0.11.0 \ + --certificate-identity-regexp "https://github.com/Polycentric-Labs/evidentia/.github/workflows/release.yml@refs/tags/v0.11.0" \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ --type slsaprovenance1 ``` @@ -141,8 +141,8 @@ cosign verify-attestation ghcr.io/polycentric-labs/evidentia:v0.10.18 \ **PowerShell (Windows)** ```powershell -cosign verify-attestation ghcr.io/polycentric-labs/evidentia:v0.10.18 ` - --certificate-identity-regexp "https://github.com/Polycentric-Labs/evidentia/.github/workflows/release.yml@refs/tags/v0.10.18" ` +cosign verify-attestation ghcr.io/polycentric-labs/evidentia:v0.11.0 ` + --certificate-identity-regexp "https://github.com/Polycentric-Labs/evidentia/.github/workflows/release.yml@refs/tags/v0.11.0" ` --certificate-oidc-issuer https://token.actions.githubusercontent.com ` --type slsaprovenance1 ``` diff --git a/docs/wiki/1-getting-started/installation.md b/docs/wiki/1-getting-started/installation.md index 3dca1e59..375d4b82 100644 --- a/docs/wiki/1-getting-started/installation.md +++ b/docs/wiki/1-getting-started/installation.md @@ -28,7 +28,7 @@ Verify the install: ```bash evidentia version -# → Evidentia v0.10.18 +# → Evidentia v0.11.0 # → Python 3.12.x ``` @@ -83,9 +83,9 @@ Every release publishes a cosign-signed multi-arch image to GitHub Container Registry: ```bash -docker pull ghcr.io/polycentric-labs/evidentia:v0.10.18 -docker run --rm ghcr.io/polycentric-labs/evidentia:v0.10.18 version -# → Evidentia v0.10.18 +docker pull ghcr.io/polycentric-labs/evidentia:v0.11.0 +docker run --rm ghcr.io/polycentric-labs/evidentia:v0.11.0 version +# → Evidentia v0.11.0 # → Python 3.13.x ``` @@ -93,7 +93,7 @@ To run a gap analysis against a local inventory, mount your working directory: ```bash docker run --rm -v "$PWD:/work" -w /work \ - ghcr.io/polycentric-labs/evidentia:v0.10.18 \ + ghcr.io/polycentric-labs/evidentia:v0.11.0 \ gap analyze --inventory my-controls.yaml \ --frameworks nist-800-53-rev5-moderate --output gap-report.json ``` @@ -102,7 +102,7 @@ On **Windows PowerShell**, use PowerShell's backtick line-continuation instead o ```powershell docker run --rm -v "${PWD}:/work" -w /work ` - ghcr.io/polycentric-labs/evidentia:v0.10.18 ` + ghcr.io/polycentric-labs/evidentia:v0.11.0 ` gap analyze --inventory my-controls.yaml ` --frameworks nist-800-53-rev5-moderate --output gap-report.json ``` @@ -112,7 +112,7 @@ The image is keyless-signed via Fulcio + Rekor. Verify it before you trust it: **Bash / Linux / macOS** ```bash -cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.18 \ +cosign verify ghcr.io/polycentric-labs/evidentia:v0.11.0 \ --certificate-identity-regexp 'https://github\.com/Polycentric-Labs/evidentia/\.github/workflows/release\.yml@refs/tags/v.*' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com # → "The cosign claims were validated" @@ -121,7 +121,7 @@ cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.18 \ **PowerShell (Windows)** ```powershell -cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.18 ` +cosign verify ghcr.io/polycentric-labs/evidentia:v0.11.0 ` --certificate-identity-regexp 'https://github\.com/Polycentric-Labs/evidentia/\.github/workflows/release\.yml@refs/tags/v.*' ` --certificate-oidc-issuer https://token.actions.githubusercontent.com # → "The cosign claims were validated" diff --git a/docs/wiki/1-getting-started/quickstart.md b/docs/wiki/1-getting-started/quickstart.md index 4c8ab41f..601ad85d 100644 --- a/docs/wiki/1-getting-started/quickstart.md +++ b/docs/wiki/1-getting-started/quickstart.md @@ -17,7 +17,7 @@ Verify: ```bash evidentia version -# → Evidentia v0.10.18 / Python 3.12.x +# → Evidentia v0.11.0 / Python 3.12.x ``` ## Step 2 — Pick a framework (10 seconds) @@ -122,8 +122,8 @@ The wheel you installed has a PEP 740 attestation: pip install pypi-attestations pypi-attestations verify pypi \ --repository https://github.com/Polycentric-Labs/evidentia \ - "pypi:evidentia-0.10.18-py3-none-any.whl" -# → OK: evidentia-0.10.18-py3-none-any.whl + "pypi:evidentia-0.11.0-py3-none-any.whl" +# → OK: evidentia-0.11.0-py3-none-any.whl ``` **PowerShell (Windows)** @@ -132,8 +132,8 @@ pypi-attestations verify pypi \ pip install pypi-attestations pypi-attestations verify pypi ` --repository https://github.com/Polycentric-Labs/evidentia ` - "pypi:evidentia-0.10.18-py3-none-any.whl" -# → OK: evidentia-0.10.18-py3-none-any.whl + "pypi:evidentia-0.11.0-py3-none-any.whl" +# → OK: evidentia-0.11.0-py3-none-any.whl ``` The container image is cosign-signed (if you used the Docker install path): @@ -141,7 +141,7 @@ The container image is cosign-signed (if you used the Docker install path): **Bash / Linux / macOS** ```bash -cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.18 \ +cosign verify ghcr.io/polycentric-labs/evidentia:v0.11.0 \ --certificate-identity-regexp 'https://github\.com/Polycentric-Labs/evidentia/\.github/workflows/release\.yml@refs/tags/v.*' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com # → "The cosign claims were validated" @@ -150,7 +150,7 @@ cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.18 \ **PowerShell (Windows)** ```powershell -cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.18 ` +cosign verify ghcr.io/polycentric-labs/evidentia:v0.11.0 ` --certificate-identity-regexp 'https://github\.com/Polycentric-Labs/evidentia/\.github/workflows/release\.yml@refs/tags/v.*' ` --certificate-oidc-issuer https://token.actions.githubusercontent.com # → "The cosign claims were validated" diff --git a/docs/wiki/2-guides/air-gapped-install.md b/docs/wiki/2-guides/air-gapped-install.md index 20288dcf..f92f892e 100644 --- a/docs/wiki/2-guides/air-gapped-install.md +++ b/docs/wiki/2-guides/air-gapped-install.md @@ -38,8 +38,8 @@ Pull the cosign-signed image on the connected host, save it to a tarball, and carry the tarball across the air gap: ```bash -docker pull ghcr.io/polycentric-labs/evidentia:v0.10.18 -docker save ghcr.io/polycentric-labs/evidentia:v0.10.18 -o evidentia.tar +docker pull ghcr.io/polycentric-labs/evidentia:v0.11.0 +docker save ghcr.io/polycentric-labs/evidentia:v0.11.0 -o evidentia.tar ``` On the air-gapped host: `docker load -i evidentia.tar`. @@ -56,7 +56,7 @@ index disabled so pip never reaches for the network: python -m venv .venv && source .venv/bin/activate pip install --no-index --find-links ./evidentia-wheelhouse evidentia evidentia version -# → Evidentia v0.10.18 / Python 3.12.x +# → Evidentia v0.11.0 / Python 3.12.x ``` **PowerShell (Windows)** @@ -65,7 +65,7 @@ evidentia version python -m venv .venv ; .\.venv\Scripts\Activate.ps1 pip install --no-index --find-links ./evidentia-wheelhouse evidentia evidentia version -# → Evidentia v0.10.18 / Python 3.12.x +# → Evidentia v0.11.0 / Python 3.12.x ``` ## Step 3 — Validate the air-gap posture diff --git a/docs/wiki/6-project/changelog.md b/docs/wiki/6-project/changelog.md index 79396c37..808ead7a 100644 --- a/docs/wiki/6-project/changelog.md +++ b/docs/wiki/6-project/changelog.md @@ -10,9 +10,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +_No changes yet on the v0.11.x development branch._ + +## [0.11.0] - 2026-07-16 + +**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 emission** — `evidentia 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-16 — see [`docs/releases/plans/v0.12-plan.md`](https://github.com/Polycentric-Labs/evidentia/blob/main/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** +- **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 @@ -24,7 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 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** (pre-v0.11.0; every change +- **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, @@ -46,10 +54,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 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`** (v0.11 Wave 2; spec ratified 2026-07-14, lifecycle phases + 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 → @@ -67,7 +93,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `AI_ACQUISITION_PHASE_RECORDED` audit events. - **OMB M-25-21 minimum-practice tracking — `evidentia ai-gov set-practice`** - (v0.11 Wave 2): fills the per-practice extension point reserved at + (#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 / @@ -83,7 +109,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 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`** (v0.11 Wave 2, +- **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 diff --git a/docs/wiki/6-project/deprecation-policy.md b/docs/wiki/6-project/deprecation-policy.md index 13b7370a..7269ae5d 100644 --- a/docs/wiki/6-project/deprecation-policy.md +++ b/docs/wiki/6-project/deprecation-policy.md @@ -26,7 +26,7 @@ | `evidentia_core.models.finding.SecurityFinding` (library class name) | `evidentia_core.models.finding.Finding` (same class, new canonical name) | v0.10.1 (2026-05-23) | **v1.0.0** (earliest major bump) | The `SecurityFinding` name is kept as a backward-compatible alias for ≥ 1 minor cycle per the deprecation policy. Both names refer to the same class — no runtime difference, no behavior change, `isinstance(obj, SecurityFinding)` and `isinstance(obj, Finding)` both succeed. The rename aligns with OCSF's "Finding" terminology (Compliance Finding, Detection Finding). No `DeprecationWarning` is emitted in v0.10.1 to avoid spamming the ~50+ existing call sites — the alias is silent. Operators / integrators are encouraged to switch to `Finding` in new code; existing code keeps working unchanged. | | `evidentia ai-gov set-omb-impact` (CLI) + `OMBImpactRequest` / `POST …/omb-impact` (API) — OMB **M-24-10** impact leveling | `evidentia ai-gov set-high-impact` + `HighImpactRequest` — OMB **M-25-21** high-impact determination | v0.10.12 (2026-06-23) | **v1.0.0** | OMB M-24-10 was rescinded 2025-04-03 and superseded by M-25-21. The legacy M-24-10 surface is retained as a backward-compatible alias per the deprecation policy; new code should record the M-25-21 high-impact determination instead. | -No other surfaces are currently deprecated as of v0.10.18. +No other surfaces are currently deprecated as of v0.11.0. --- diff --git a/docs/wiki/6-project/roadmap.md b/docs/wiki/6-project/roadmap.md index a0127708..fa72b169 100644 --- a/docs/wiki/6-project/roadmap.md +++ b/docs/wiki/6-project/roadmap.md @@ -3,7 +3,7 @@ # Evidentia roadmap -**Last updated: v0.10.18 (planning, July 2026).** +**Last updated: v0.11.0 (planning, July 2026).** > **Engineering practices** — how Evidentia is built, tested, and shipped (the > PR-flow + merge-queue gate, atomic releases, supply-chain integrity, and the @@ -2041,15 +2041,41 @@ DEFER-WITH-TRIGGER verdict and a same-day setuptools 83.0.0 fix v0.11.0's boundary re-cuts to Waves 1–2. No package (`packages/*/src`) code changes. -## v0.11 — Federal-compliance theme + AI governance — PLANNED +## v0.11 — Federal-compliance theme + AI governance — SHIPPED -**The open cycle** (opened 2026-07-09). Full plan: +Opened 2026-07-09; **closed 2026-07-16 with v0.11.0** (the re-cut +Wave 1–2 scope per the 2026-07-14 boundary re-cut — Wave 0 + the +hygiene track H1–H6 had shipped early inside v0.10.18). Full plan: [`v0.11-plan.md`](https://github.com/Polycentric-Labs/evidentia/blob/main/docs/releases/plans/v0.11-plan.md) — wave sequencing, the cycle-hygiene track (the 2026-07 practice-delta adoptions + the v0.10.17 deferred queue), the medical-device row split, and the -ratification asks. Sourced from Phase B audit v3 + integration plan -§"Per-release detailed integration plan" §v0.11. Substantive minor -(~6-8 weeks): +ratification record. The remaining planned waves carry the **ratified +2026-07-16 disposition** in +[`v0.12-plan.md`](https://github.com/Polycentric-Labs/evidentia/blob/main/docs/releases/plans/v0.12-plan.md) (Wave 4 phase 3 → +v0.12-if-capacity; Wave 4 phases 1/2/4 + Wave 3 DORA + medical-device +traceability → v1.1; Waves 5–6 → post-1.0; arXiv preprint = open +decision). + +### v0.11.0 — The federal wave — SHIPPED (released 2026-07-16) + +Three verified federal firsts on machine-readable rails: **FedRAMP +CR26 SDR emission** (`evidentia conmon ksi` — the SDR +`keySecurityIndicators` block, 10 families / 46 KSIs, conformant to +the official 2026-06-24 schemas vendored at pinned SHAs and re-verified +at their 1.0.0 graduation; weekly `fedramp-schema-watch` drift +sentinel; the first production-grade OSS emitter of the format), +**OMB M-25-21 minimum-practice tracking** (`ai-gov set-practice` — +seven §4(b) practices with CAIO waiver objects carrying the annual +re-cert + 30-day OMB-report clocks), and **OMB M-25-22 +acquisition-lifecycle tracking** (`ai-gov acquisition` — the six §4 +phases with the §4(a) high-impact tie-in). Plus the ratified OSCAL +1.2.2 DEFER-WITH-TRIGGER verdict and a pre-release claim-accuracy +sweep (parity restated at the live 93.4%; first-mover registry updated +with explicit caveats). Test suite 4,939 passed. The five federal +api-only parity rows lead the v0.12 GUI pass. + +The feature bullets below are the cycle's planning record; items not +shipped in v0.11.0 carry the ratified disposition above. - **KSI (Key Security Indicators) emission** — wires as third output mode on `evidentia conmon` alongside the 7 bundled cadences shipped @@ -2240,7 +2266,7 @@ engineering-hardening batch addressed all three: maintainer — checked at PRR Row 21). P3 FIPS container variant stays gated on the federal-SI OpenPGP-interop answer. -### Medical-device GRC feature line (v0.11 → v1.1+) — PLANNED (web-grounded research 2026-06-17) +### Medical-device GRC feature line (v1.1+; re-cut 2026-07-16 from v0.11) — RESERVED (web-grounded research 2026-06-17) The medical-device-security direction the v0.10.10 FDA Section 524B catalogs opened, scanned + validated in a multi-angle web-grounded research pass. **Each feature gets a dedicated `polycentric-labcoat` research fleet at build-time** — the entries below are the high-level scan + positioning, not build specs. Effort and tier are planning-grade. The throughline: **don't rebuild commodity layers (STRIDE authoring, CBOM scanners) — ingest them; the uncontested slice is the open, signed, OSCAL/BOM-emitting evidence wrapper.** @@ -2283,6 +2309,23 @@ Items deferred from Phase B audit v3 + integration plan §"v1.1+": - Architectural Tier 3 items from Phase B audit v3 (control-chart script ships skill-side; dynamic-install eBPF scan; etc.). +## v0.12 — Pre-1.0 hardening + GUI parity — PLANNED + +**The open cycle** (ratified 2026-07-16 at the v0.11.0 release prep). +Full plan: [`v0.12-plan.md`](https://github.com/Polycentric-Labs/evidentia/blob/main/docs/releases/plans/v0.12-plan.md) — the +ratified disposition of the remaining v0.11 waves plus the LEAN v0.12 +scope: (1) the GUI parity pass for the five v0.11 federal api-only +verbs (+ the `version`/`init` exempt-reclassification decision); +(2) deprecation completions ahead of the v1.0.0 removals; +(3) api-stability freeze-prep (the surface audit the v1.0 stability +promise formalizes); (4) CR26 emitter coverage extension only if cheap +(FRR statements next); (5) the CR26-fragility watches (upstream PR #4 +delta drop, additionalProperties tightening, CR27 dated-fileset MAJOR, +the competitive-flip playbook, and the fresh-drift-probe-at-release +lesson). The v1.0 operator self-test is scheduled at v0.12 cycle-open +per [`v1.0-transition.md`](https://github.com/Polycentric-Labs/evidentia/blob/main/docs/v1.0-transition.md) so reviewer outreach can +start while v0.12 builds. + ## v1.0 — Federal compliance shipped + API stability — RESERVED See [`docs/v1.0-transition.md`](https://github.com/Polycentric-Labs/evidentia/blob/main/docs/v1.0-transition.md) for the full diff --git a/docs/wiki/6-project/security.md b/docs/wiki/6-project/security.md index 35b5e474..7f7678e0 100644 --- a/docs/wiki/6-project/security.md +++ b/docs/wiki/6-project/security.md @@ -73,7 +73,7 @@ a vulnerability in Evidentia's own code. | Version | Status | Reason | |---------|--------|--------| -| **`0.10.18`** | ✅ **Supported** | Latest patch. See the [CHANGELOG](https://github.com/Polycentric-Labs/evidentia/blob/main/CHANGELOG.md) and the latest `docs/releases/reviews/security-review-*.md` for what shipped and the CVE posture at this release. | +| **`0.11.0`** | ✅ **Supported** | Latest patch. See the [CHANGELOG](https://github.com/Polycentric-Labs/evidentia/blob/main/CHANGELOG.md) and the latest `docs/releases/reviews/security-review-*.md` for what shipped and the CVE posture at this release. | | Earlier patches | ❌ Deprecated | Pre-v1.0 single-supported-patch policy; upgrade to the latest patch. | | Legacy `controlbridge*` packages | ❌ Yanked from PyPI | Every version of every legacy package was yanked at the v0.6.0 rename. Upgrade path documented in [`RENAMED.md`](https://github.com/Polycentric-Labs/evidentia/blob/main/docs/archive/RENAMED.md). | @@ -175,7 +175,7 @@ Verify a release wheel: pip install pypi-attestations pypi-attestations verify pypi \ --repository https://github.com/Polycentric-Labs/evidentia \ - "pypi:evidentia-0.10.18-py3-none-any.whl" + "pypi:evidentia-0.11.0-py3-none-any.whl" ``` If verification fails, **stop and report immediately** via the diff --git a/docs/wiki/6-project/verification.md b/docs/wiki/6-project/verification.md index 5e94026a..cd5dc727 100644 --- a/docs/wiki/6-project/verification.md +++ b/docs/wiki/6-project/verification.md @@ -24,10 +24,10 @@ pip install pypi-attestations # Verify a single wheel pypi-attestations verify pypi \ --repository https://github.com/Polycentric-Labs/evidentia \ - pypi:evidentia_core-0.10.18-py3-none-any.whl + pypi:evidentia_core-0.11.0-py3-none-any.whl # Expected output: -# OK: evidentia_core-0.10.18-py3-none-any.whl +# OK: evidentia_core-0.11.0-py3-none-any.whl ``` **PowerShell (Windows)** @@ -39,10 +39,10 @@ pip install pypi-attestations # Verify a single wheel pypi-attestations verify pypi ` --repository https://github.com/Polycentric-Labs/evidentia ` - pypi:evidentia_core-0.10.18-py3-none-any.whl + pypi:evidentia_core-0.11.0-py3-none-any.whl # Expected output: -# OK: evidentia_core-0.10.18-py3-none-any.whl +# OK: evidentia_core-0.11.0-py3-none-any.whl ``` Per-release sweep across all 8 packages: @@ -54,7 +54,7 @@ for pkg in evidentia evidentia_ai evidentia_api evidentia_collectors \ evidentia_core evidentia_eval evidentia_integrations evidentia_mcp; do pypi-attestations verify pypi \ --repository https://github.com/Polycentric-Labs/evidentia \ - "pypi:${pkg}-0.10.18-py3-none-any.whl" + "pypi:${pkg}-0.11.0-py3-none-any.whl" done ``` @@ -65,7 +65,7 @@ foreach ($pkg in 'evidentia','evidentia_ai','evidentia_api','evidentia_collector 'evidentia_core','evidentia_eval','evidentia_integrations','evidentia_mcp') { pypi-attestations verify pypi ` --repository https://github.com/Polycentric-Labs/evidentia ` - "pypi:${pkg}-0.10.18-py3-none-any.whl" + "pypi:${pkg}-0.11.0-py3-none-any.whl" } ``` @@ -78,8 +78,8 @@ foreach ($pkg in 'evidentia','evidentia_ai','evidentia_api','evidentia_collector # https://docs.sigstore.dev/system_config/installation/ # Verify the container's keyless OIDC signature -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/v0.10.18" \ +cosign verify ghcr.io/polycentric-labs/evidentia:v0.11.0 \ + --certificate-identity-regexp "https://github.com/Polycentric-Labs/evidentia/.github/workflows/release.yml@refs/tags/v0.11.0" \ --certificate-oidc-issuer https://token.actions.githubusercontent.com # Expected output: "The cosign claims were validated" + SLSA Provenance v1 JSON. @@ -92,8 +92,8 @@ cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.18 \ # https://docs.sigstore.dev/system_config/installation/ # Verify the container's keyless OIDC signature -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/v0.10.18" ` +cosign verify ghcr.io/polycentric-labs/evidentia:v0.11.0 ` + --certificate-identity-regexp "https://github.com/Polycentric-Labs/evidentia/.github/workflows/release.yml@refs/tags/v0.11.0" ` --certificate-oidc-issuer https://token.actions.githubusercontent.com # Expected output: "The cosign claims were validated" + SLSA Provenance v1 JSON. @@ -105,7 +105,7 @@ cosign verify ghcr.io/polycentric-labs/evidentia:v0.10.18 ` ```bash # Download the SBOM -gh release download v0.10.18 --pattern 'evidentia-sbom.cdx.json' \ +gh release download v0.11.0 --pattern 'evidentia-sbom.cdx.json' \ --repo Polycentric-Labs/evidentia # Scan for vulnerabilities @@ -118,7 +118,7 @@ osv-scanner scan source -L evidentia-sbom.cdx.json ```powershell # Download the SBOM -gh release download v0.10.18 --pattern 'evidentia-sbom.cdx.json' ` +gh release download v0.11.0 --pattern 'evidentia-sbom.cdx.json' ` --repo Polycentric-Labs/evidentia # Scan for vulnerabilities @@ -135,8 +135,8 @@ attestation inline. To extract it: **Bash / Linux / macOS** ```bash -cosign verify-attestation ghcr.io/polycentric-labs/evidentia:v0.10.18 \ - --certificate-identity-regexp "https://github.com/Polycentric-Labs/evidentia/.github/workflows/release.yml@refs/tags/v0.10.18" \ +cosign verify-attestation ghcr.io/polycentric-labs/evidentia:v0.11.0 \ + --certificate-identity-regexp "https://github.com/Polycentric-Labs/evidentia/.github/workflows/release.yml@refs/tags/v0.11.0" \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ --type slsaprovenance1 ``` @@ -144,8 +144,8 @@ cosign verify-attestation ghcr.io/polycentric-labs/evidentia:v0.10.18 \ **PowerShell (Windows)** ```powershell -cosign verify-attestation ghcr.io/polycentric-labs/evidentia:v0.10.18 ` - --certificate-identity-regexp "https://github.com/Polycentric-Labs/evidentia/.github/workflows/release.yml@refs/tags/v0.10.18" ` +cosign verify-attestation ghcr.io/polycentric-labs/evidentia:v0.11.0 ` + --certificate-identity-regexp "https://github.com/Polycentric-Labs/evidentia/.github/workflows/release.yml@refs/tags/v0.11.0" ` --certificate-oidc-issuer https://token.actions.githubusercontent.com ` --type slsaprovenance1 ``` diff --git a/marketplace/grc-engineering-suite/plugins/evidentia/.claude-plugin/plugin.json b/marketplace/grc-engineering-suite/plugins/evidentia/.claude-plugin/plugin.json index 023498bd..ef0fc326 100644 --- a/marketplace/grc-engineering-suite/plugins/evidentia/.claude-plugin/plugin.json +++ b/marketplace/grc-engineering-suite/plugins/evidentia/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "evidentia", "description": "Evidentia GRC engine — OSCAL-first gap analysis, SARIF CI-gate output, OCSF ingestion. Open-source Apache-2.0 (Polycentric Labs). Wraps the evidentia-mcp server so AI clients drive the full product through one tool surface.", - "version": "0.10.18", + "version": "0.11.0", "author": { "name": "Polycentric Labs", "url": "https://github.com/Polycentric-Labs" diff --git a/packages/evidentia-ai/pyproject.toml b/packages/evidentia-ai/pyproject.toml index accecdbd..6b595bb7 100644 --- a/packages/evidentia-ai/pyproject.toml +++ b/packages/evidentia-ai/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "evidentia-ai" -version = "0.10.18" +version = "0.11.0" description = "LLM-powered risk statement generator and evidence validator for Evidentia" readme = "README.md" authors = [{name = "Allen Byrd", email = "allen@allenfbyrd.com"}] @@ -18,7 +18,7 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ - "evidentia-core>=0.10.18,<0.11.0", + "evidentia-core>=0.11.0,<0.12.0", # v0.10.5 P9: the DFAH eval harness was extracted to the # ``evidentia-eval`` workspace package so air-gap installs of # the production risk-statement runtime no longer pull the @@ -26,7 +26,7 @@ dependencies = [ # dependency here so the v0.10.5 deprecation shims (``from # evidentia_ai.eval import …``) continue to work through # v0.11.x; v0.12.0 removes both the shims and this pin. - "evidentia-eval>=0.10.18,<0.11.0", + "evidentia-eval>=0.11.0,<0.12.0", # v0.7.0 Step-3 review: pin LiteLLM above the compromised # 1.82.7 / 1.82.8 versions from the March 24, 2026 PyPI supply # chain incident (~40-min compromise window before quarantine). diff --git a/packages/evidentia-api/pyproject.toml b/packages/evidentia-api/pyproject.toml index 9caccb6e..34b01df2 100644 --- a/packages/evidentia-api/pyproject.toml +++ b/packages/evidentia-api/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "evidentia-api" -version = "0.10.18" +version = "0.11.0" description = "FastAPI REST server + bundled React web UI for Evidentia" readme = "README.md" authors = [{name = "Allen Byrd", email = "allen@allenfbyrd.com"}] @@ -20,8 +20,8 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ - "evidentia-core>=0.10.18,<0.11.0", - "evidentia-ai>=0.10.18,<0.11.0", + "evidentia-core>=0.11.0,<0.12.0", + "evidentia-ai>=0.11.0,<0.12.0", "fastapi>=0.139.0", "uvicorn[standard]>=0.51.0", # v0.7.2 supply-chain follow-up: floor bumped from >=0.0.9 to diff --git a/packages/evidentia-api/src/evidentia_api/routers/ai_gov.py b/packages/evidentia-api/src/evidentia_api/routers/ai_gov.py index 70cb6f28..ffb1402c 100644 --- a/packages/evidentia-api/src/evidentia_api/routers/ai_gov.py +++ b/packages/evidentia-api/src/evidentia_api/routers/ai_gov.py @@ -1052,11 +1052,19 @@ async def ai_gov_set_high_impact( """ entry = _load_entry_or_404(system_id) + # Carry any recorded §4(b) practice status (incl. CAIO waiver + # provenance) forward across a re-determination — the model contract + # (OMBHighImpactAssessment.practices) promises retention, and + # set-high-impact is the only verb that can amend bases/rationale on + # an already-classified system. Rebuilding without them would + # silently destroy the recorded practice + waiver evidence trail. + prior = entry.omb_high_impact try: assessment = OMBHighImpactAssessment( determination=body.determination, bases=body.bases, rationale=body.rationale, + practices=dict(prior.practices) if prior is not None else {}, ) except (ValidationError, ValueError) as exc: raise api_error(400, "invalid_body", str(exc)) from exc @@ -1221,6 +1229,7 @@ class RegisterAcquisitionRequest(BaseModel): covered_note: str | None = Field(default=None, max_length=2000) linked_system_id: str | None = Field( default=None, + max_length=256, description="AI-registry system_id this acquisition delivers.", ) diff --git a/packages/evidentia-collectors/pyproject.toml b/packages/evidentia-collectors/pyproject.toml index a02de0fb..0c9ed5e6 100644 --- a/packages/evidentia-collectors/pyproject.toml +++ b/packages/evidentia-collectors/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "evidentia-collectors" -version = "0.10.18" +version = "0.11.0" description = "Evidence collection agents for AWS, Databricks, GitHub, Okta, Snowflake, SQL databases, and vendor-risk APIs (Vanta, Drata, BitSight, SecurityScorecard)" readme = "README.md" authors = [{name = "Allen Byrd", email = "allen@allenfbyrd.com"}] @@ -18,7 +18,7 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ - "evidentia-core>=0.10.18,<0.11.0", + "evidentia-core>=0.11.0,<0.12.0", "httpx>=0.27", ] diff --git a/packages/evidentia-core/pyproject.toml b/packages/evidentia-core/pyproject.toml index b5224d05..bf4ba8c6 100644 --- a/packages/evidentia-core/pyproject.toml +++ b/packages/evidentia-core/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "evidentia-core" -version = "0.10.18" +version = "0.11.0" description = "Core data models, catalog loading, and gap analysis engine for Evidentia GRC tool" readme = "README.md" authors = [{name = "Allen Byrd", email = "allen@allenfbyrd.com"}] diff --git a/packages/evidentia-core/src/evidentia_core/ai_governance/omb_m_25_21.py b/packages/evidentia-core/src/evidentia_core/ai_governance/omb_m_25_21.py index d884fde6..f1f0b074 100644 --- a/packages/evidentia-core/src/evidentia_core/ai_governance/omb_m_25_21.py +++ b/packages/evidentia-core/src/evidentia_core/ai_governance/omb_m_25_21.py @@ -213,6 +213,7 @@ class PracticeWaiver(EvidentiaModel): description="Date the CAIO granted the waiver.", ) issued_by: str = Field( + max_length=256, description=( "The granting official (the agency CAIO — §4(a)(ii) makes " "this authority non-delegable). Recorded as provenance." diff --git a/packages/evidentia-core/src/evidentia_core/ai_governance/omb_m_25_22.py b/packages/evidentia-core/src/evidentia_core/ai_governance/omb_m_25_22.py index 8e8e2e8f..a9d8212b 100644 --- a/packages/evidentia-core/src/evidentia_core/ai_governance/omb_m_25_22.py +++ b/packages/evidentia-core/src/evidentia_core/ai_governance/omb_m_25_22.py @@ -144,6 +144,7 @@ class AIAcquisition(EvidentiaModel): ) linked_system_id: str | None = Field( default=None, + max_length=256, description=( "AI-registry system_id this acquisition delivered or will " "deliver. Optional — an acquisition may precede " diff --git a/packages/evidentia-eval/pyproject.toml b/packages/evidentia-eval/pyproject.toml index 49a209c3..2d7bb2b7 100644 --- a/packages/evidentia-eval/pyproject.toml +++ b/packages/evidentia-eval/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "evidentia-eval" -version = "0.10.18" +version = "0.11.0" description = "DFAH (Decision-Faithfulness Assessment Harness) determinism + faithfulness eval harness for Evidentia — dev-time AI-output quality gates" readme = "README.md" authors = [{name = "Allen Byrd", email = "allen@allenfbyrd.com"}] @@ -18,7 +18,7 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ - "evidentia-core>=0.10.18,<0.11.0", + "evidentia-core>=0.11.0,<0.12.0", ] [project.optional-dependencies] diff --git a/packages/evidentia-integrations/pyproject.toml b/packages/evidentia-integrations/pyproject.toml index cf51c052..f72a6b06 100644 --- a/packages/evidentia-integrations/pyproject.toml +++ b/packages/evidentia-integrations/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "evidentia-integrations" -version = "0.10.18" +version = "0.11.0" description = "Output integrations for Jira and ServiceNow" readme = "README.md" authors = [{name = "Allen Byrd", email = "allen@allenfbyrd.com"}] @@ -18,7 +18,7 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ - "evidentia-core>=0.10.18,<0.11.0", + "evidentia-core>=0.11.0,<0.12.0", "httpx>=0.27", ] diff --git a/packages/evidentia-mcp/pyproject.toml b/packages/evidentia-mcp/pyproject.toml index 579ff084..b455993b 100644 --- a/packages/evidentia-mcp/pyproject.toml +++ b/packages/evidentia-mcp/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "evidentia-mcp" -version = "0.10.18" +version = "0.11.0" description = "Model Context Protocol (MCP) server for Evidentia — exposes gap analysis, risk generation, explanation, and OSCAL emit to MCP-aware AI clients (Claude Desktop, Claude Code, ChatGPT, etc.)" readme = "README.md" authors = [{name = "Allen Byrd", email = "allen@allenfbyrd.com"}] @@ -18,9 +18,9 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ - "evidentia-core>=0.10.18,<0.11.0", - "evidentia-ai>=0.10.18,<0.11.0", - "evidentia-collectors>=0.10.18,<0.11.0", + "evidentia-core>=0.11.0,<0.12.0", + "evidentia-ai>=0.11.0,<0.12.0", + "evidentia-collectors>=0.11.0,<0.12.0", # MCP Python SDK. Includes FastMCP server scaffolding + # protocol types. Floor pinned to 1.27 (the version Evidentia # was tested against during v0.8.0 P0.3 development); diff --git a/packages/evidentia-ui/openapi.json b/packages/evidentia-ui/openapi.json index 6cca4fca..3e27d7b8 100644 --- a/packages/evidentia-ui/openapi.json +++ b/packages/evidentia-ui/openapi.json @@ -4385,6 +4385,7 @@ "properties": { "issued_by": { "description": "The granting official (the agency CAIO — §4(a)(ii) makes this authority non-delegable). Recorded as provenance.", + "maxLength": 256, "title": "Issued By", "type": "string" }, @@ -4596,6 +4597,7 @@ "linked_system_id": { "anyOf": [ { + "maxLength": 256, "type": "string" }, { @@ -6343,7 +6345,7 @@ "info": { "description": "REST API for the Evidentia GRC tool. All endpoints mirror CLI capabilities. Binds to 127.0.0.1 by default for localhost web-UI use.", "title": "Evidentia API", - "version": "0.10.18" + "version": "0.11.0" }, "openapi": "3.1.0", "paths": { diff --git a/packages/evidentia-ui/package.json b/packages/evidentia-ui/package.json index b299e050..22d249c6 100644 --- a/packages/evidentia-ui/package.json +++ b/packages/evidentia-ui/package.json @@ -1,6 +1,6 @@ { "name": "@evidentia/ui", - "version": "0.10.18", + "version": "0.11.0", "description": "Evidentia web UI — React + Vite + shadcn/ui frontend served by evidentia-api.", "private": true, "type": "module", diff --git a/packages/evidentia/pyproject.toml b/packages/evidentia/pyproject.toml index 6d7d49f5..95c9781e 100644 --- a/packages/evidentia/pyproject.toml +++ b/packages/evidentia/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "evidentia" -version = "0.10.18" +version = "0.11.0" description = "Open-source GRC tool: gap analysis, risk statements, evidence collection, web UI, and compliance automation" readme = "README.md" authors = [{name = "Allen Byrd", email = "allen@allenfbyrd.com"}] @@ -18,16 +18,16 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ - "evidentia-core>=0.10.18,<0.11.0", - "evidentia-ai>=0.10.18,<0.11.0", + "evidentia-core>=0.11.0,<0.12.0", + "evidentia-ai>=0.11.0,<0.12.0", # v0.10.5 P9: DFAH eval harness extracted from evidentia-ai. # ``evidentia eval`` CLI verbs live here, so the meta-package # depends on evidentia-eval directly (not via the evidentia-ai # transitive pin) so the verbs work even when the v0.12.0 # shim removal eventually trims evidentia-ai's runtime dep. - "evidentia-eval>=0.10.18,<0.11.0", - "evidentia-collectors>=0.10.18,<0.11.0", - "evidentia-integrations>=0.10.18,<0.11.0", + "evidentia-eval>=0.11.0,<0.12.0", + "evidentia-collectors>=0.11.0,<0.12.0", + "evidentia-integrations>=0.11.0,<0.12.0", # click 8.2 removed CliRunner's mix_stderr (stderr is now always a separate # stream) and typer 0.26 vendors its own click. The test suite and the wiki # reference generator (scripts/wiki/sync_reference.py) were updated to match @@ -43,7 +43,7 @@ dependencies = [ # Web UI — installs the FastAPI server + bundled React SPA. # Usage: `pip install "evidentia[gui]"` or `uv tool install "evidentia[gui]"`, # then `evidentia serve` to open the local web UI. -gui = ["evidentia-api>=0.10.18,<0.11.0"] +gui = ["evidentia-api>=0.11.0,<0.12.0"] # v0.7.12 P0: cloud-backed WORM storage adapters. Each extra # pulls in the cloud SDK + maps to the matching evidentia-core # extra so the WORM impl module imports cleanly. Operators @@ -57,7 +57,7 @@ worm-gcs = ["evidentia-core[worm-gcs]>=0.10.0,<0.11.0"] # Code, ChatGPT Desktop, custom clients) over stdio. # Usage: `pip install "evidentia[mcp]"`, then `evidentia mcp # serve`. -mcp = ["evidentia-mcp>=0.10.18,<0.11.0"] +mcp = ["evidentia-mcp>=0.11.0,<0.12.0"] [project.scripts] evidentia = "evidentia.cli.main:app" diff --git a/packages/evidentia/src/evidentia/cli/ai_gov.py b/packages/evidentia/src/evidentia/cli/ai_gov.py index d4b88116..27a51505 100644 --- a/packages/evidentia/src/evidentia/cli/ai_gov.py +++ b/packages/evidentia/src/evidentia/cli/ai_gov.py @@ -859,11 +859,17 @@ def ai_gov_set_high_impact( ) raise typer.Exit(code=1) from None + # Carry recorded §4(b) practice status (incl. CAIO waiver provenance) + # forward across a re-determination — set-high-impact is the only verb + # that amends bases/rationale, and the model contract promises the + # practices survive it (see OMBHighImpactAssessment.practices). + prior = entry.omb_high_impact try: assessment = OMBHighImpactAssessment( determination=determination_enum, bases=basis_enums, rationale=rationale, + practices=dict(prior.practices) if prior is not None else {}, ) except ValueError as exc: console.print(f"[red]Error:[/red] {exc}") diff --git a/packages/evidentia/src/evidentia/cli/conmon.py b/packages/evidentia/src/evidentia/cli/conmon.py index 7b280bd7..aeda7e3d 100644 --- a/packages/evidentia/src/evidentia/cli/conmon.py +++ b/packages/evidentia/src/evidentia/cli/conmon.py @@ -39,12 +39,14 @@ from __future__ import annotations import json +import os import signal import sys import threading import warnings from datetime import UTC, date, datetime from pathlib import Path +from typing import Any import typer from evidentia_core.audit import EventAction, EventOutcome, get_logger @@ -1026,8 +1028,45 @@ def conmon_ksi( from evidentia_core.models.fedramp_ksi import KsiStatusDocument from pydantic import ValidationError + # A duplicate mapping key in the status file (e.g. the same KSI ID + # listed twice) is last-wins-merged by the stock YAML loader, silently + # dropping the earlier block from the emitted federal SDR. Reject it — + # a submission artifact must not lose data to a copy-paste slip. + class _NoDupKeyLoader(yaml_mod.SafeLoader): + pass + + def _construct_no_dup( + loader: yaml_mod.SafeLoader, node: yaml_mod.MappingNode + ) -> dict[Any, Any]: + # Reject duplicate EXPLICIT keys (a copy-paste slip) before merge + # expansion — a `<<` merge override of a key is legal YAML and must + # still work, so detect dupes among the explicit key nodes only, + # then delegate to the stock construct_mapping (which flattens the + # merge keys and applies their precedence). + seen: set[Any] = set() + for key_node, _ in node.value: + if key_node.tag == "tag:yaml.org,2002:merge": + continue + key = loader.construct_object(key_node, deep=True) + if key in seen: + raise yaml_mod.constructor.ConstructorError( + "while constructing a mapping", + node.start_mark, + f"found duplicate key {key!r}", + key_node.start_mark, + ) + seen.add(key) + loader.flatten_mapping(node) + return loader.construct_mapping(node, deep=True) + + _NoDupKeyLoader.add_constructor( + "tag:yaml.org,2002:map", _construct_no_dup + ) + try: - raw = yaml_mod.safe_load(status_file.read_text(encoding="utf-8")) + raw = yaml_mod.load( + status_file.read_text(encoding="utf-8"), Loader=_NoDupKeyLoader + ) except yaml_mod.YAMLError as exc: console.print(f"[red]Error:[/red] could not parse {status_file}: {exc}") raise typer.Exit(code=2) from exc @@ -1057,6 +1096,25 @@ def conmon_ksi( _load_last_completed_map(state_file) if state_file is not None else None ) + # A state-file anchor keyed by a slug that matches no bundled cadence + # (usually a typo) never joins onto a persistence cycle, so its + # last-completed / next-due dates would silently be absent from the + # emitted SDR. Warn — the emit still succeeds, but the operator sees + # which anchors were ignored rather than shipping a quietly-incomplete + # federal artifact. + if last_completed: + unknown = sorted( + slug for slug in last_completed if get_cadence(slug) is None + ) + if unknown: + console.print( + f"[yellow]Warning:[/yellow] {state_file} has " + f"{len(unknown)} anchor(s) for unknown cadence slug(s) " + f"{', '.join(repr(s) for s in unknown)}; their dates will " + f"NOT appear in the SDR. Run `evidentia conmon list` to " + f"see valid slugs." + ) + try: document = build_sdr_document( status, @@ -1078,10 +1136,20 @@ def conmon_ksi( console.print(f" {error}") raise typer.Exit(code=1) - output.write_text( - json.dumps(document, indent=2, ensure_ascii=False) + "\n", - encoding="utf-8", - ) + payload = json.dumps(document, indent=2, ensure_ascii=False) + "\n" + # Atomic write via a sibling temp file + os.replace, and a clean + # error contract (exit 1) instead of a raw pathlib traceback when the + # target dir is missing or unwritable — an operator scripting this in + # a CONMON pipeline gets the typed exit the rest of the command keeps. + try: + tmp = output.with_name(f"{output.name}.tmp") + tmp.write_text(payload, encoding="utf-8") + os.replace(tmp, output) + except OSError as exc: + console.print( + f"[red]Error:[/red] could not write {output}: {exc.strerror or exc}" + ) + raise typer.Exit(code=1) from exc coverage = ksi_coverage(status) console.print( diff --git a/pyproject.toml b/pyproject.toml index c7227cca..238c570e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "evidentia-workspace" -version = "0.10.18" +version = "0.11.0" # Upper bound tracks the TRUE runnable ceiling of the workspace, which is set by the # tightest transitive Python cap: litellm (a hard dep of evidentia-ai, pinned # >=1.83.7,<2.0) declares requires_python "<3.14,>=3.10", so the stack cannot run on diff --git a/tests/integration/test_api/test_ai_gov.py b/tests/integration/test_api/test_ai_gov.py index bff3e556..c86cbf30 100644 --- a/tests/integration/test_api/test_ai_gov.py +++ b/tests/integration/test_api/test_ai_gov.py @@ -1022,6 +1022,51 @@ def test_bad_practice_returns_422(self, api_client: TestClient) -> None: ) assert resp.status_code == 422 + def test_set_high_impact_preserves_recorded_practices( + self, api_client: TestClient + ) -> None: + """Re-running set-high-impact must not wipe recorded practices. + + Regression: the handler rebuilt the assessment from only + determination/bases/rationale, resetting ``practices`` to {} and + silently destroying the recorded status + CAIO waiver provenance. + """ + system_id = _register_system(api_client) + self._set_high_impact(api_client, system_id) + waive = api_client.post( + f"/api/ai-gov/systems/{system_id}/set-practice", + json={ + "practice": "human_oversight", + "status": "waived", + "waiver": { + "issued_on": "2026-06-01", + "issued_by": "Agency CAIO", + "justification": "Interim necessity per §4(a)(ii).", + "reported_to_omb_on": "2026-06-15", + }, + }, + ) + assert waive.status_code == 200, waive.text + + # Amend the bases via a second set-high-impact (unrelated edit). + amend = api_client.post( + f"/api/ai-gov/systems/{system_id}/set-high-impact", + json={ + "determination": "high_impact", + "bases": ["health_and_safety", "civil_rights_liberties_privacy"], + }, + ) + assert amend.status_code == 200, amend.text + + got = api_client.get(f"/api/ai-gov/systems/{system_id}").json() + practices = got["omb_high_impact"]["practices"] + assert "human_oversight" in practices, ( + "re-determination destroyed the recorded practice" + ) + assert practices["human_oversight"]["waiver"] is not None, ( + "the CAIO waiver provenance was lost on re-determination" + ) + class TestAcquisitions: """The /ai-gov/acquisitions surface — OMB M-25-22 v0.11.""" diff --git a/tests/integration/test_cli/test_ai_gov_federal.py b/tests/integration/test_cli/test_ai_gov_federal.py index 25acaa88..b9dd168a 100644 --- a/tests/integration/test_cli/test_ai_gov_federal.py +++ b/tests/integration/test_cli/test_ai_gov_federal.py @@ -737,6 +737,72 @@ def test_practices_persist_on_the_entry( practices = entry.omb_high_impact.practices assert len(practices) == 2 + def test_re_determination_preserves_recorded_practices( + self, + runner: CliRunner, + registered_system_id: str, + isolated_registry: Path, + ) -> None: + """A later set-high-impact must NOT wipe recorded practices. + + Regression: set-high-impact is the only verb that amends + bases/rationale on an already-classified system; rebuilding the + assessment without carrying ``practices`` forward silently + destroyed the recorded status + CAIO waiver provenance. + """ + self._set_high_impact(runner, registered_system_id) + waive = runner.invoke( + app, + [ + "ai-gov", + "set-practice", + registered_system_id, + "--practice", + "human_oversight", + "--status", + "waived", + "--waiver-issued-on", + "2026-06-01", + "--waiver-issued-by", + "Agency CAIO", + "--waiver-justification", + "Interim operational necessity per §4(a)(ii).", + "--waiver-reported-on", + "2026-06-15", + ], + ) + assert waive.exit_code == 0, waive.output + + # Re-run set-high-impact to amend the bases (unrelated edit). + amend = runner.invoke( + app, + [ + "ai-gov", + "set-high-impact", + registered_system_id, + "--determination", + "high_impact", + "--basis", + "health_and_safety", + "--basis", + "civil_rights_liberties_privacy", + ], + ) + assert amend.exit_code == 0, amend.output + + from evidentia_core.ai_governance import AIRegistryStore + from evidentia_core.ai_governance.omb_m_25_21 import MinimumPractice + + entry = AIRegistryStore().load(registered_system_id) + assert entry is not None and entry.omb_high_impact is not None + practices = entry.omb_high_impact.practices + assert MinimumPractice.HUMAN_OVERSIGHT in practices, ( + "the re-determination destroyed the recorded practice" + ) + assert ( + practices[MinimumPractice.HUMAN_OVERSIGHT].waiver is not None + ), "the CAIO waiver provenance was lost on re-determination" + # ── v0.11 Wave 2: ai-gov acquisition (OMB M-25-22) ───────────────── diff --git a/tests/integration/test_cli/test_conmon.py b/tests/integration/test_cli/test_conmon.py index ad0f9463..1d72a811 100644 --- a/tests/integration/test_cli/test_conmon.py +++ b/tests/integration/test_cli/test_conmon.py @@ -975,3 +975,133 @@ def test_bad_last_updated_exits_1( ) assert result.exit_code == 1 assert "--last-updated" in _normalize(result.output) + + def test_duplicate_indicator_key_rejected( + self, runner: CliRunner, tmp_path: Path + ) -> None: + """A duplicate KSI ID must not be silently last-wins merged. + + Regression: the stock YAML loader drops the earlier block from + the emitted federal SDR; a submission artifact must not lose data + to a copy-paste slip. + """ + dup = VALID_KSI_STATUS + ( + " KSI-CED-RAT:\n" + " status: Not Implemented\n" + " implementation:\n" + ' - "Duplicate block."\n' + ) + status_file = tmp_path / "dup.yaml" + status_file.write_text(dup, encoding="utf-8") + result = runner.invoke( + app, + [ + "conmon", + "ksi", + "--status-file", + str(status_file), + "--out", + str(tmp_path / "sdr.json"), + ], + ) + assert result.exit_code == 2 + assert "duplicate key" in _normalize(result.output) + + def test_yaml_merge_keys_still_accepted( + self, runner: CliRunner, tmp_path: Path + ) -> None: + """The duplicate-key guard must not reject legal `<<` merge keys. + + Regression: a naive no-dup loader that skips flatten_mapping breaks + merge-key DRY sharing that the stock loader accepted. + """ + # Anchor the shared block on the first KSI and merge it into the + # second (the model forbids extra top-level keys, so DRY sharing + # rides real indicator anchors — the realistic merge-key use). + merged = """\ +certification_package_overview_uri: "https://provider.example/fedramp/cpo.json" +document_version: "1.0.0" +source: "merge-key test" +indicators: + KSI-CED-RAT: &shared + status: Implemented + tests: ["shared-test"] + evidence: + - evidence_type: Report + description: "shared evidence" + implementation: + - "Quarterly all-hands security training." + KSI-CMT-LMC: + <<: *shared + implementation: + - "Least-managed-change control in effect." +""" + status_file = tmp_path / "merged.yaml" + status_file.write_text(merged, encoding="utf-8") + result = runner.invoke( + app, + [ + "conmon", + "ksi", + "--status-file", + str(status_file), + "--out", + str(tmp_path / "sdr.json"), + ], + ) + assert result.exit_code == 0, result.output + assert "schema-valid" in _normalize(result.output) + + def test_unknown_state_file_slug_warns( + self, runner: CliRunner, tmp_path: Path + ) -> None: + """A state-file anchor for a non-existent cadence slug warns. + + Its dates would otherwise be silently absent from the SDR. + """ + status_file = tmp_path / "ksi-status.yaml" + status_file.write_text(VALID_KSI_STATUS, encoding="utf-8") + state_file = tmp_path / "state.yaml" + state_file.write_text( + "nist-800-53-rev5-ca7: 2026-07-01\n" + "typo-not-a-real-slug: 2026-07-02\n", + encoding="utf-8", + ) + result = runner.invoke( + app, + [ + "conmon", + "ksi", + "--status-file", + str(status_file), + "--state-file", + str(state_file), + "--out", + str(tmp_path / "sdr.json"), + ], + ) + assert result.exit_code == 0, result.output + norm = _normalize(result.output) + assert "unknown cadence slug" in norm + assert "typo-not-a-real-slug" in norm + + def test_unwritable_out_path_exits_1( + self, runner: CliRunner, tmp_path: Path + ) -> None: + """A missing --out parent dir yields a clean exit 1, not a stack + trace.""" + status_file = tmp_path / "ksi-status.yaml" + status_file.write_text(VALID_KSI_STATUS, encoding="utf-8") + result = runner.invoke( + app, + [ + "conmon", + "ksi", + "--status-file", + str(status_file), + "--out", + str(tmp_path / "no-such-dir" / "sdr.json"), + ], + ) + assert result.exit_code == 1 + assert "could not write" in _normalize(result.output) diff --git a/tests/unit/test_ai_governance/test_acquisition.py b/tests/unit/test_ai_governance/test_acquisition.py index ec26c26d..ac31e4a1 100644 --- a/tests/unit/test_ai_governance/test_acquisition.py +++ b/tests/unit/test_ai_governance/test_acquisition.py @@ -157,3 +157,13 @@ def test_malformed_file_skipped_by_list_all( rogue.write_text("{not json", encoding="utf-8") records = store.list_all() assert [a.name for a in records] == ["x"] + + +class TestAcquisitionFieldBounds: + def test_linked_system_id_is_length_bounded(self) -> None: + """linked_system_id is capped like every sibling string field.""" + from pydantic import ValidationError + + AIAcquisition(name="ok", linked_system_id="s" * 256) + with pytest.raises(ValidationError): + AIAcquisition(name="ok", linked_system_id="s" * 257) diff --git a/tests/unit/test_ai_governance/test_federal.py b/tests/unit/test_ai_governance/test_federal.py index f4a1eb01..e5a4a065 100644 --- a/tests/unit/test_ai_governance/test_federal.py +++ b/tests/unit/test_ai_governance/test_federal.py @@ -1092,3 +1092,27 @@ def test_omb_report_never_overdue_once_reported(self) -> None: reported_to_omb_on=date(2026, 3, 1), ) assert not waiver_omb_report_overdue(waiver, date(2026, 7, 14)) + + +class TestPracticeWaiverFieldBounds: + def test_issued_by_is_length_bounded(self) -> None: + """Every operator-supplied string field is capped; issued_by too. + + Regression: an unbounded issued_by is persisted verbatim into the + registry entry and re-read on every request (stored-amplification). + """ + from datetime import date + + from evidentia_core.ai_governance import PracticeWaiver + + PracticeWaiver( + issued_on=date(2026, 6, 1), + issued_by="A" * 256, + justification="x", + ) + with pytest.raises(ValidationError): + PracticeWaiver( + issued_on=date(2026, 6, 1), + issued_by="A" * 257, + justification="x", + ) diff --git a/uv.lock b/uv.lock index cf7e7ee5..ebf24f66 100644 --- a/uv.lock +++ b/uv.lock @@ -748,7 +748,7 @@ wheels = [ [[package]] name = "evidentia" -version = "0.10.18" +version = "0.11.0" source = { editable = "packages/evidentia" } dependencies = [ { name = "click" }, @@ -798,7 +798,7 @@ provides-extras = ["gui", "worm-s3", "worm-azure", "worm-gcs", "mcp"] [[package]] name = "evidentia-ai" -version = "0.10.18" +version = "0.11.0" source = { editable = "packages/evidentia-ai" } dependencies = [ { name = "evidentia-core" }, @@ -826,7 +826,7 @@ provides-extras = ["eval-faithfulness"] [[package]] name = "evidentia-api" -version = "0.10.18" +version = "0.11.0" source = { editable = "packages/evidentia-api" } dependencies = [ { name = "evidentia-ai" }, @@ -849,7 +849,7 @@ requires-dist = [ [[package]] name = "evidentia-collectors" -version = "0.10.18" +version = "0.11.0" source = { editable = "packages/evidentia-collectors" } dependencies = [ { name = "evidentia-core" }, @@ -939,7 +939,7 @@ provides-extras = ["aws", "github", "okta", "sql-postgres", "sql-mysql", "sql-sq [[package]] name = "evidentia-core" -version = "0.10.18" +version = "0.11.0" source = { editable = "packages/evidentia-core" } dependencies = [ { name = "cryptography" }, @@ -1001,7 +1001,7 @@ provides-extras = ["sigstore", "xlsx", "worm-s3", "worm-azure", "worm-gcs", "ocs [[package]] name = "evidentia-eval" -version = "0.10.18" +version = "0.11.0" source = { editable = "packages/evidentia-eval" } dependencies = [ { name = "evidentia-core" }, @@ -1023,7 +1023,7 @@ provides-extras = ["faithfulness-semantic"] [[package]] name = "evidentia-integrations" -version = "0.10.18" +version = "0.11.0" source = { editable = "packages/evidentia-integrations" } dependencies = [ { name = "evidentia-core" }, @@ -1067,7 +1067,7 @@ provides-extras = ["jira", "servicenow", "tableau", "powerbi", "all"] [[package]] name = "evidentia-mcp" -version = "0.10.18" +version = "0.11.0" source = { editable = "packages/evidentia-mcp" } dependencies = [ { name = "evidentia-ai" }, @@ -1086,7 +1086,7 @@ requires-dist = [ [[package]] name = "evidentia-workspace" -version = "0.10.18" +version = "0.11.0" source = { virtual = "." } [package.dev-dependencies]