From 82584fd9865b58ad72f91404a286a4a4cc595c22 Mon Sep 17 00:00:00 2001 From: ExatronOmega Date: Sun, 14 Jun 2026 11:14:18 +0200 Subject: [PATCH 1/3] Align docs with governed-runtime MVP truth and guard version drift. Correct stale claims across README and operator docs, extend validate_public_truth.py to catch source/PyPI and unreleased-section mismatches, and add consolidated negative regression coverage. --- CHANGELOG.md | 2 +- CONTRIBUTING.md | 1 + PUBLIC_STATUS.md | 10 ++ README.md | 16 ++- docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md | 31 +++-- docs/ROADMAP.md | 61 +++++++--- docs/RUNTIME_ADMISSION.md | 52 ++++---- docs/SCLITE_INTEGRATION.md | 11 +- scripts/validate_public_truth.py | 151 ++++++++++++++++++++++++ tests/test_public_truth_consistency.py | 68 +++++++++++ 10 files changed, 339 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 844cbbf..3e14ad3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ GovEngine follows conservative pre-1.0 versioning while the API boundary is stil without replacing existing guarded-root replay helpers from `0.12.1`. - Added receipt-to-admission binding plus validators for runner receipt bindings and admission evidence chains. -- Added `verify_evidence_review_chain()` and supporting validators for end-to-end +- Added `validate_evidence_review_chain()` and supporting validators for end-to-end evidence review chains (admission → receipt → evidence → review). - Added `AuditLedgerPort` contracts plus `JsonlAuditLedgerAdapter`, a development-only hash-chained append-only JSONL adapter without choosing a diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6d07c2f..6784a3a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,6 +14,7 @@ python -m venv .venv python -m pip install --upgrade pip python -m pip install -e '.[dev]' python -m pytest -q +python scripts/validate_public_truth.py ``` For dependency-consistency and readiness validation, run the clean installed-package gate from a new virtual environment path: diff --git a/PUBLIC_STATUS.md b/PUBLIC_STATUS.md index d78a001..9a8bda8 100644 --- a/PUBLIC_STATUS.md +++ b/PUBLIC_STATUS.md @@ -44,6 +44,16 @@ GovEngine is an **alpha governed-runtime kernel package** extracted from Ravencl decision surface. The helpers compose separate policy, ticket, trust, guarded-replay, runner, receipt-obligation, and bounded reference summaries before any live backend work. +- Receipt and evidence binding: `validate_runner_receipt_binding()` and + `validate_evidence_review_chain()` validate bounded admission/ticket/request/ + receipt and receipt/evidence/review reference chains without storing raw + evidence or replacing SCLite review verdict authority. +- Audit ledger port: `AuditLedgerPort` and development-only + `JsonlAuditLedgerAdapter` provide append/read/verify contracts without + production database, locking, or retention ownership. +- Inspect-only admission workflow: `scripts/inspect_runtime_admission.py` + validates and summarizes `RuntimeAdmissionResult` records without creating + runner requests, replay claims, audit entries, or live execution authority. - Public surface registry: tested `govengine.surfaces` metadata contains only neutral artifact-governance core, planning-contracts core, admission-policy core, evidence-review core, domain-profile SDK, runtime contract proofs, and controlled-execution core surfaces. - Security profile retirement: the published `0.12.0a0` alpha package removes the former optional Ravenclaw-derived facade and helper modules; security-domain behavior remains host-owned. - Deconfliction/state index: initial conflict/change-order helpers and lightweight artifact state summaries. diff --git a/README.md b/README.md index 47f97c2..775bff8 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ GovEngine is **not** Ravenclaw, Tecrax, Logdash, an LLM agent loop, a scanner, o - neutral admission, policy, approval, and audit contracts for host runtime gates; - explicit SCLite integration seams; - focused standalone pytest coverage and GitHub Actions CI. +- on current `main`, the governed-runtime MVP helpers also include `RuntimeAdmissionResult`, `compose_runtime_admission_result()`, `validate_runtime_admission_result()`, `normalize_admission_artifact_refs()`, `ReplayClaimStore`, `verify_guard_and_record_replay()`, `validate_runner_receipt_binding()`, `validate_evidence_review_chain()`, GovEngine-owned record digests and signed-record helpers, `AuditLedgerPort` with a development-only `JsonlAuditLedgerAdapter`, runner supervision including `LocalSubprocessRunnerReadiness`, and `scripts/inspect_runtime_admission.py` for read-only admission inspection (listed in `CHANGELOG.md` under `Unreleased` until the next PyPI alpha release). ## What it intentionally does not include yet @@ -68,15 +69,19 @@ GovEngine is **not** Ravenclaw, Tecrax, Logdash, an LLM agent loop, a scanner, o - LLM provider integrations; - Ravenclaw-specific personas, workspace state, or campaign UX; - production-readiness claims; -- PKI, CA, KMS, key storage, or production identity proof. +- PKI, CA, KMS, key storage, or production identity proof; +- a shipped `LocalSubprocessRunner` implementation (`LocalSubprocessRunnerReadiness` is a gating contract only); +- production replay or audit persistence (`ReplayClaimStore` and `JsonlAuditLedgerAdapter` are host-owned or development-only adapters). ## Current status GovEngine is an **alpha package 0.12.2a0 (`0.12.2-alpha`)**. It keeps the neutral artifact-governance, planning, admission/policy, controlled-execution, runner-supervision, runtime-shell, evidence-review, profile, and proof surfaces while removing the former optional security-profile facade and Ravenclaw-derived helper modules. The published dependency line is `sclite-core>=1.0.1,<1.1`. +Source on `main` already includes the governed-runtime MVP described below; the last PyPI publish remains `0.12.2a0`, with the MVP changes recorded under `Unreleased` in `CHANGELOG.md` until the next alpha release. + ## Current roadmap direction -The governed-runtime MVP now includes a canonical `RuntimeAdmissionResult` +The governed-runtime MVP on `main` includes a canonical `RuntimeAdmissionResult` record as the bounded admission decision surface and `compose_runtime_admission_result()` as the neutral gate-summary composition helper. The helper composes prepared execution contract status, policy @@ -87,6 +92,8 @@ references into that record. `normalize_admission_artifact_refs()` is an alpha helper for bounded review references and existing digest strings; it does not compute content digests or claim SCLite canonicalization. +`compose_runtime_admission_result()` composes host-supplied gate summaries; it does not validate SCLite tickets, verify signatures, record replay state, or execute live work. + The operator-facing MVP flow is documented in [`docs/GOVERNED_RUNTIME_MVP_RUNBOOK.md`](docs/GOVERNED_RUNTIME_MVP_RUNBOOK.md). It ties admission, trust ports, guarded SCLite verification, replay freshness, @@ -115,6 +122,7 @@ python -m venv .venv . .venv/bin/activate python -m pip install -e '.[dev]' python -m pytest -q +python scripts/validate_public_truth.py ``` ## Minimal smoke example @@ -155,12 +163,16 @@ assert receipt["status"] == "dry-run" - [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — package shape and dependency boundaries. - [`docs/SCLITE_INTEGRATION.md`](docs/SCLITE_INTEGRATION.md) — how GovEngine consumes SCLite. - [`docs/API_BOUNDARY.md`](docs/API_BOUNDARY.md) — owned vs excluded surfaces. +- [`docs/API_STABILITY_MATRIX.md`](docs/API_STABILITY_MATRIX.md) — alpha vs fixture export classification. - [`docs/RUNTIME_ADMISSION.md`](docs/RUNTIME_ADMISSION.md) — canonical runtime admission contract direction. - [`docs/GOVERNED_RUNTIME_MVP_RUNBOOK.md`](docs/GOVERNED_RUNTIME_MVP_RUNBOOK.md) — operator-facing governed-runtime MVP chain. +- [`docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md`](docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md) — read-only admission inspect workflow. +- [`docs/GUARDED_FRESH_RUNTIME_ADMISSION_EXAMPLE.md`](docs/GUARDED_FRESH_RUNTIME_ADMISSION_EXAMPLE.md) — guarded-strict plus replay-fresh example. - [`docs/ADMISSION_POLICY.md`](docs/ADMISSION_POLICY.md) — neutral admission, policy, approval, audit, and audit-ledger contracts. - [`docs/RECEIPT_BINDING.md`](docs/RECEIPT_BINDING.md) — admission/ticket/request/receipt binding design. - [`docs/EVIDENCE_REVIEW.md`](docs/EVIDENCE_REVIEW.md) — receipt-bounded evidence/review contract. - [`docs/RUNNER_SUPERVISION.md`](docs/RUNNER_SUPERVISION.md) — runner request, receipt, supervision, and live-runner safety boundaries. +- [`docs/LOCAL_SUBPROCESS_RUNNER_DECISION.md`](docs/LOCAL_SUBPROCESS_RUNNER_DECISION.md) — local subprocess runner decision record. - [`docs/GOVENGINE_KERNEL_BOUNDARY.md`](docs/GOVENGINE_KERNEL_BOUNDARY.md) — kernel/profile/runtime/SCLite ownership split. - [`docs/DOMAIN_PROFILE_CONTRACT.md`](docs/DOMAIN_PROFILE_CONTRACT.md) — domain profile contract and conformance rules. - [`docs/ORCHESTRATOR_MODEL.md`](docs/ORCHESTRATOR_MODEL.md) — deterministic orchestration boundary and runtime non-claims. diff --git a/docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md b/docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md index f0ed5a0..be7b2d7 100644 --- a/docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md +++ b/docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md @@ -1,8 +1,8 @@ # Inspect-Only Admission Workflow This document defines the operator-facing inspect workflow for -`RuntimeAdmissionResult` records. It is a design contract for GE-034 and does -not implement execution. +`RuntimeAdmissionResult` records. The workflow is read-only: it validates and +summarizes an admission record without executing work. The workflow exists so an operator or host runtime can inspect a canonical runtime-admission record before any runner request is considered. @@ -32,25 +32,24 @@ It must not execute live work, contact targets, open raw evidence, resolve credentials, call a runner backend, mutate SCLite artifacts, claim replay keys, or store audit entries. -## Proposed Operator Shape +## Operator Command -GE-035 should implement this as a small inspect-only script or CLI surface. The -preferred initial command shape is: +The inspect-only surface is implemented as: ```bash python scripts/inspect_runtime_admission.py path/to/runtime-admission.json ``` -The command should be read-only and should exit non-zero only when the input -record is malformed or unsafe to summarize. +The command is read-only and exits with code `2` when the input record is +malformed or unsafe to summarize. -Optional future flags may be added only if they remain inspect-only: +Supported inspect-only flags: -- `--format text` for compact human output; +- `--format text` for compact human output (default); - `--format json` for bounded machine-readable output; - `--show-artifact-refs` to include already-bounded references and digests. -No future flag may grant execution authority. +No flag may grant execution authority. No future flag may grant execution authority. ## Output Contract @@ -70,9 +69,9 @@ artifact_refs: 2 bounded refs execution: not performed ``` -JSON output, if implemented, should contain the same bounded fields and should -omit raw payloads, credentials, prompts, stdout, stderr, commands, targets, and -raw evidence. It should never include environment variables or secret material. +JSON output contains the same bounded fields and omits raw payloads, +credentials, prompts, stdout, stderr, commands, targets, and raw evidence. It +never includes environment variables or secret material. ## Validation Rules @@ -122,9 +121,9 @@ execution enablement. - no raw evidence loading; - no Ravenclaw, OpenClaw, MCP, A2A, scheduler, carrier, or credential adapter. -## GE-035 Implementation Acceptance +## Test Coverage -The implementation task should add tests proving: +Standalone tests in `tests/test_admission_contracts.py` prove: - an allowed dry-run admission prints compact allowed output; - a blocked admission prints blockers and required next actions; @@ -135,7 +134,7 @@ The implementation task should add tests proving: ## Implementation Status -The initial inspect-only surface is implemented as: +The inspect-only surface is implemented as: ```bash python scripts/inspect_runtime_admission.py path/to/runtime-admission.json diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index bff1027..dcd2fef 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -89,20 +89,37 @@ profile-owned tool, policy, and UX semantics remain in Ravenclaw. New neutral extraction should land in typed core/profile surfaces only when the code and a second host prove it there. -## Post-0.12.2 governed-runtime MVP direction - -The internal 2026-06-06 audit points to one highest-leverage next target: -formalize a canonical runtime admission result before adding any live runner -surface. GovEngine already has useful pieces across policy, execution tickets, -signing/trust, guarded SCLite replay, runner requests/receipts, and dry-run -gates. The public kernel shape is one bounded machine-readable decision that -composes those pieces without turning intent into execution authority; the -initial record and composition helper now exist and need focused negative -coverage plus later trust/receipt/audit hardening. - -The MVP contract is now named `RuntimeAdmissionResult`; the roadmap may still -use `GovernedExecutionAdmission` as an equivalent concept name. It should -report: +## Post-0.12.2 governed-runtime MVP + +Status: implemented on current `main` and recorded in `CHANGELOG.md` under +`Unreleased` until the next PyPI alpha release. + +GovEngine already had useful pieces across policy, execution tickets, signing/trust, +guarded SCLite replay, runner requests/receipts, and dry-run gates. The public +kernel now exposes one bounded machine-readable decision that composes those +pieces without turning intent into execution authority. + +Delivered MVP surface: + +- `RuntimeAdmissionResult`, `compose_runtime_admission_result()`, + `validate_runtime_admission_result()`, and `normalize_admission_artifact_refs()`; +- `ReplayClaimStore`, `InMemoryReplayClaimStore`, and + `verify_guard_and_record_replay()`; +- `validate_runner_receipt_binding()` and `validate_evidence_review_chain()`; +- GovEngine-owned record digests and signed-record helpers; +- `AuditLedgerPort` and development-only `JsonlAuditLedgerAdapter`; +- `LocalSubprocessRunnerReadiness` with `not_applicable` as the current local + runner posture; +- `scripts/inspect_runtime_admission.py` and operator docs under + `docs/GOVERNED_RUNTIME_MVP_RUNBOOK.md`, + `docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md`, and + `docs/GUARDED_FRESH_RUNTIME_ADMISSION_EXAMPLE.md`; +- focused negative tests for admission composition, replay claim-once behavior, + receipt/evidence binding, audit tamper cases, inspect-only workflow, and + governed-runtime smoke coverage. + +The MVP contract is named `RuntimeAdmissionResult`; `GovernedExecutionAdmission` +remains an equivalent concept name for hosts and roadmap discussion. It reports: - status and `allowed`; - deterministic reason code; @@ -119,10 +136,18 @@ report: - bounded artifact references or digests. This admission result is not a live execution backend. It is the reviewable -decision surface that later trust, receipt, ledger, replay-store, inspect-only, -and optional runner work must use. Live subprocess execution remains disabled by -default and out of scope until admission, trust, replay freshness, receipt -binding, runner safety requirements, and negative tests are complete. +decision surface that trust, receipt, ledger, replay-store, inspect-only, and +optional runner work must use. Live subprocess execution remains disabled by +default and out of scope until a future host adapter satisfies the runner safety +requirements and negative tests for any optional live backend. + +Remaining follow-up for the next alpha release line: + +- publish the `Unreleased` governed-runtime MVP through the normal PyPI alpha + gates; +- keep production replay, audit, and evidence persistence host-owned; +- keep optional `LocalSubprocessRunner` out of the kernel while readiness stays + `not_applicable`. ## Version roadmap diff --git a/docs/RUNTIME_ADMISSION.md b/docs/RUNTIME_ADMISSION.md index ecdad17..32e9eba 100644 --- a/docs/RUNTIME_ADMISSION.md +++ b/docs/RUNTIME_ADMISSION.md @@ -55,7 +55,7 @@ The admission result composes existing GovEngine and SCLite-facing signals: ## Output Shape -The implementation should expose a small immutable record with fields equivalent +The implementation exposes a small immutable record with fields equivalent to: - `status`: `allowed`, `blocked`, `dry_run_only`, `needs_review`, or @@ -88,9 +88,9 @@ execution grant. The inspect-only operator workflow is documented in [INSPECT_ONLY_ADMISSION_WORKFLOW.md](INSPECT_ONLY_ADMISSION_WORKFLOW.md). It -defines a future read-only admission-record inspection surface that validates -and summarizes `RuntimeAdmissionResult` records without creating runner -requests, receipts, replay claims, audit entries, or live execution authority. +validates and summarizes `RuntimeAdmissionResult` records through +`scripts/inspect_runtime_admission.py` without creating runner requests, +receipts, replay claims, audit entries, or live execution authority. ## Gate Semantics @@ -130,7 +130,7 @@ ports needed by host runtimes. ## Relationship To Existing Modules -The implementation should compose the existing surfaces instead of replacing +The implementation composes the existing surfaces instead of replacing them: - `govengine.admission` for policy/admission/approval/audit record shapes; @@ -147,7 +147,7 @@ them: ## Implementation Status And Next Tasks -The first implementation is additive and backward-compatible: +Delivered on current `main` (CHANGELOG `Unreleased` until the next PyPI alpha): 1. `RuntimeAdmissionResult` exists as the core record; 2. `validate_runtime_admission_result()` enforces basic status/allowed/blocker @@ -157,26 +157,36 @@ The first implementation is additive and backward-compatible: 4. `normalize_admission_artifact_refs()` is exposed as an alpha bounded-reference helper for admission review output; 5. `canonical_govengine_record()` and `govengine_record_digest()` provide a - GovEngine-owned record serialization/digest boundary for future - admission/receipt binding without canonicalizing SCLite artifacts; + GovEngine-owned record serialization/digest boundary for admission/receipt + binding without canonicalizing SCLite artifacts; 6. `SignedArtifact` binds a GovEngine-owned record digest to signer metadata and a payload reference while leaving production verification to host-provided verifier ports; 7. key-resolver and trust-store port records carry references and decisions only, not private key material, credentials, KMS, CA, or trust-anchor storage; -8. existing helpers remain unchanged. - -The next implementation tasks should: - -1. add focused negative tests for each missing or failed gate; +8. `validate_runner_receipt_binding()` and `validate_evidence_review_chain()` + validate bounded receipt and evidence/review reference chains; +9. `AuditLedgerPort` and `JsonlAuditLedgerAdapter` provide a development-only + hash-chained audit append/read/verify surface; +10. `ReplayClaimStore`, `InMemoryReplayClaimStore`, and + `verify_guard_and_record_replay()` provide replay claim-once and + guarded-strict composition helpers; +11. `scripts/inspect_runtime_admission.py` implements the inspect-only operator + workflow; +12. focused negative tests cover missing policy, ticket, trust, replay, + runner-profile, and receipt-obligation blockers in admission composition. + +Remaining work: + +1. publish the governed-runtime MVP as the next alpha PyPI line when operator + release gates pass; 2. keep live backend support disabled by default; -3. keep serialization bounded and deterministic enough for later digest/signing - work; -4. implement the inspect-only admission workflow from - [INSPECT_ONLY_ADMISSION_WORKFLOW.md](INSPECT_ONLY_ADMISSION_WORKFLOW.md); -5. document any host-owned input that GovEngine validates but does not produce. - -The result should be usable by future receipt, audit-ledger, replay-store, -inspect-only, and optional runner tasks, but it must not claim production +3. keep production replay, audit, and evidence persistence host-owned beyond the + development adapters; +4. keep optional `LocalSubprocessRunner` out of the kernel until host-owned live + profile authorization and safety gates are implemented and tested. + +The result is usable by hosts for receipt, audit-ledger, replay-store, +inspect-only, and dry-run runner workflows, but it must not claim production runtime readiness. diff --git a/docs/SCLITE_INTEGRATION.md b/docs/SCLITE_INTEGRATION.md index 9d90fde..bad01e2 100644 --- a/docs/SCLITE_INTEGRATION.md +++ b/docs/SCLITE_INTEGRATION.md @@ -38,12 +38,11 @@ intent_contract GovEngine currently provides helpers around the runtime-facing parts of that lifecycle: -- action validation and compilation before contract shaping; -- policy decision normalization/evaluation; -- execution-contract shaping and redaction; -- approved-spec and execution-ticket checks; +- approved-spec and execution-ticket validation helpers; +- execution-contract shaping and redaction through `govengine.contracts.execution`; - dry-run result assembly; -- integration seams for SCLite verification; +- host-provided policy and trust decision shape validation through `govengine.admission` and `govengine.signing` (GovEngine does not own domain policy meaning); +- integration seams for SCLite lifecycle/review verification; - guarded-root replay checks for optional SCLite `kernel_guard_hmac_v1` sidecars after SCLite has verified the HMAC guard; - `ReplayClaimStore`, a host-neutral claim-once replay freshness port, plus an @@ -51,7 +50,7 @@ GovEngine currently provides helpers around the runtime-facing parts of that lif - `verify_guard_and_record_replay()`, a high-level adapter that verifies the SCLite guarded-strict profile and then records replay freshness for one runtime-consumable decision; -- review-bundle verdict mapping through SCLite `0.8.0b2` review and guarded-strict surfaces, preserving the review-bundle contract. +- review-bundle verdict mapping through the current `sclite-core>=1.0.1,<1.1` review and guarded-strict surfaces, preserving the review-bundle contract. Host-owned artifact projection is outside GovEngine. A runtime such as Ravenclaw constructs its domain-shaped lifecycle artifacts before consuming diff --git a/scripts/validate_public_truth.py b/scripts/validate_public_truth.py index 3593357..21240e7 100644 --- a/scripts/validate_public_truth.py +++ b/scripts/validate_public_truth.py @@ -97,6 +97,144 @@ ), } +VERSION_TRUTH_FIELDS = { + 'source_version': 'pyproject.toml:project.version', + 'package_init_version': 'govengine.__init__.__version__', + 'published_pypi_version': 'PyPI install pin / README badge', + 'release_label': 'README.md / PUBLIC_STATUS.md release label', + 'sclite_dependency': 'pyproject.toml dependencies[sclite-core]', + 'changelog_unreleased_heading': 'CHANGELOG.md:## Unreleased', +} + +GOVERNED_RUNTIME_UNRELEASED_MARKERS = ( + 'RuntimeAdmissionResult', + 'compose_runtime_admission_result()', + 'validate_evidence_review_chain()', +) + +SOURCE_PYPI_GAP_DOC_MARKERS = { + 'README.md': ( + 'Unreleased', + 'last PyPI publish remains', + '`compose_runtime_admission_result()` composes host-supplied gate summaries', + ), + 'docs/ROADMAP.md': ( + 'implemented on current `main`', + 'Unreleased', + ), +} + +FORBIDDEN_CURRENT_DOC_CLAIMS = ( + ('CHANGELOG.md', 'unreleased_api_name', 'verify_evidence_review_chain()'), + ('docs/SCLITE_INTEGRATION.md', 'retired_helper_claim', 'action validation and compilation'), + ('docs/SCLITE_INTEGRATION.md', 'stale_sclite_version', '0.8.0b2'), + ('docs/SCLITE_INTEGRATION.md', 'stale_policy_helper_claim', 'policy decision normalization/evaluation'), + ('docs/RUNTIME_ADMISSION.md', 'future_inspect_claim', 'future read-only'), + ('docs/RUNTIME_ADMISSION.md', 'future_implementation_tense', 'The implementation should expose'), + ('docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md', 'stale_plan_claim', 'GE-035 should implement'), + ('docs/ROADMAP.md', 'stale_mvp_direction_claim', 'need focused negative'), +) + +README_MVP_DOC_LINK_MARKERS = ( + 'docs/API_STABILITY_MATRIX.md', + 'docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md', + 'docs/GUARDED_FRESH_RUNTIME_ADMISSION_EXAMPLE.md', + 'docs/LOCAL_SUBPROCESS_RUNNER_DECISION.md', +) + +MVP_DELIVERY_DOC_MARKERS = { + 'docs/RUNTIME_ADMISSION.md': ( + 'Delivered on current `main`', + 'scripts/inspect_runtime_admission.py', + 'The implementation exposes a small immutable record', + ), + 'docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md': ( + 'The inspect-only surface is implemented as:', + 'scripts/inspect_runtime_admission.py', + ), +} + + +def _changelog_unreleased_section(changelog: str) -> str: + if '## Unreleased' not in changelog: + return '' + start = changelog.index('## Unreleased') + len('## Unreleased') + tail = changelog[start:] + match = re.search(r'\n## \d', tail) + if match: + return tail[: match.start()] + return tail + + +def _changelog_has_unreleased_governed_runtime_mvp(changelog: str) -> bool: + section = _changelog_unreleased_section(changelog) + return all(marker in section for marker in GOVERNED_RUNTIME_UNRELEASED_MARKERS) + + +def _assert_source_pypi_gap_docs( + version: str, + readme: str, + public_status: str, + roadmap: str, + changelog: str, +) -> None: + if version != PUBLISHED_VERSION: + return + if not _changelog_has_unreleased_governed_runtime_mvp(changelog): + return + for path, markers in SOURCE_PYPI_GAP_DOC_MARKERS.items(): + text = {'README.md': readme, 'docs/ROADMAP.md': roadmap}[path] + for marker in markers: + _assert_contains(path, text, marker) + _assert_contains( + 'PUBLIC_STATUS.md', + public_status, + f'Source/package version: `{version}`.', + ) + _assert_contains( + 'PUBLIC_STATUS.md', + public_status, + f'PyPI package: `govengine=={PUBLISHED_VERSION}` is the published current alpha package.', + ) + _assert_contains('README.md', readme, f'python -m pip install govengine=={PUBLISHED_VERSION}') + + +def _assert_changelog_unreleased_api_names(changelog: str) -> None: + section = _changelog_unreleased_section(changelog) + if not section: + return + if 'verify_evidence_review_chain()' in section: + raise AssertionError('CHANGELOG.md:unreleased_stale_api_name:verify_evidence_review_chain') + if _changelog_has_unreleased_governed_runtime_mvp(changelog): + _assert_contains('CHANGELOG.md', section, 'validate_evidence_review_chain()') + + +def _assert_forbidden_current_doc_claims(docs: Mapping[str, str]) -> None: + for path, field, forbidden in FORBIDDEN_CURRENT_DOC_CLAIMS: + text = docs[path] + if forbidden in text: + raise AssertionError(f'{path}:forbidden_current_claim:{field}:{forbidden}') + + +def _assert_sclite_integration_current_dependency_truth( + sclite_integration: str, + dependency: str, +) -> None: + _assert_contains('docs/SCLITE_INTEGRATION.md', sclite_integration, dependency) + _assert_contains('docs/SCLITE_INTEGRATION.md', sclite_integration, 'approved-spec and execution-ticket validation helpers') + + +def _assert_readme_mvp_doc_links(readme: str) -> None: + for marker in README_MVP_DOC_LINK_MARKERS: + _assert_contains('README.md', readme, marker) + + +def _assert_mvp_delivery_doc_truth(markers: Mapping[str, Iterable[str]] = MVP_DELIVERY_DOC_MARKERS) -> None: + for path, expected_markers in markers.items(): + text = _read(path) + for marker in expected_markers: + _assert_contains(path, text, marker) + def _read(path: str) -> str: return (ROOT / path).read_text(encoding='utf-8') @@ -297,6 +435,19 @@ def main() -> int: _assert_validation_current_gate_precedes_history(validation, version) _assert_clean_pip_check_guidance(contributing, validation, publishing) _assert_mvp_surface_docs() + changelog = _read('CHANGELOG.md') + _assert_changelog_unreleased_api_names(changelog) + _assert_source_pypi_gap_docs(version, readme, public_status, roadmap, changelog) + _assert_forbidden_current_doc_claims({ + 'CHANGELOG.md': changelog, + 'docs/SCLITE_INTEGRATION.md': sclite_integration, + 'docs/RUNTIME_ADMISSION.md': _read('docs/RUNTIME_ADMISSION.md'), + 'docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md': _read('docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md'), + 'docs/ROADMAP.md': roadmap, + }) + _assert_sclite_integration_current_dependency_truth(sclite_integration, dependency) + _assert_readme_mvp_doc_links(readme) + _assert_mvp_delivery_doc_truth() _assert_no_published_line_candidate_drift(( 'README.md', 'CONTRIBUTING.md', diff --git a/tests/test_public_truth_consistency.py b/tests/test_public_truth_consistency.py index 07c71e7..e3f499e 100644 --- a/tests/test_public_truth_consistency.py +++ b/tests/test_public_truth_consistency.py @@ -159,3 +159,71 @@ def fake_read(path: str) -> str: 'Intent is not execution authority.', ), }) + + +def test_public_truth_version_doc_truth_negative_guards() -> None: + """Positive version/doc truth is covered by test_public_truth_validator_passes.""" + validator = _load_validator() + + assert set(validator.VERSION_TRUTH_FIELDS) == { + 'source_version', + 'package_init_version', + 'published_pypi_version', + 'release_label', + 'sclite_dependency', + 'changelog_unreleased_heading', + } + assert {field for _, field, _ in validator.FORBIDDEN_CURRENT_DOC_CLAIMS} == { + 'unreleased_api_name', + 'retired_helper_claim', + 'stale_sclite_version', + 'stale_policy_helper_claim', + 'future_inspect_claim', + 'future_implementation_tense', + 'stale_plan_claim', + 'stale_mvp_direction_claim', + } + + unreleased_mvp_changelog = ( + '## Unreleased\n' + '- Added `RuntimeAdmissionResult` and `compose_runtime_admission_result()`.\n' + '- Added `validate_evidence_review_chain()`.\n' + '## 0.12.2-alpha\n' + ) + negative_cases = ( + ( + 'missing_source_pypi_gap_readme', + 'README.md:missing:Unreleased', + lambda: validator._assert_source_pypi_gap_docs( + validator.PUBLISHED_VERSION, + 'alpha package 0.12.2a0 without the gap note', + validator._read('PUBLIC_STATUS.md'), + validator._read('docs/ROADMAP.md'), + unreleased_mvp_changelog, + ), + ), + ( + 'stale_unreleased_api_name', + 'CHANGELOG.md:unreleased_stale_api_name:verify_evidence_review_chain', + lambda: validator._assert_changelog_unreleased_api_names( + '## Unreleased\n' + '- Added `verify_evidence_review_chain()`.\n' + '## 0.12.2-alpha\n' + ), + ), + ( + 'stale_sclite_integration_version', + 'docs/SCLITE_INTEGRATION.md:forbidden_current_claim:stale_sclite_version:0.8.0b2', + lambda: validator._assert_forbidden_current_doc_claims({ + 'CHANGELOG.md': validator._read('CHANGELOG.md'), + 'docs/SCLITE_INTEGRATION.md': 'review-bundle mapping through SCLite `0.8.0b2`', + 'docs/RUNTIME_ADMISSION.md': validator._read('docs/RUNTIME_ADMISSION.md'), + 'docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md': validator._read('docs/INSPECT_ONLY_ADMISSION_WORKFLOW.md'), + 'docs/ROADMAP.md': validator._read('docs/ROADMAP.md'), + }), + ), + ) + + for case_id, matcher, invoke in negative_cases: + with pytest.raises(AssertionError, match=matcher): + invoke() From 0ab7de5bf24322b6e0b34ac46a3789a552ada8b5 Mon Sep 17 00:00:00 2001 From: ExatronOmega Date: Sun, 14 Jun 2026 11:22:50 +0200 Subject: [PATCH 2/3] Rewrite governed-runtime MVP README bullet in plain language. Replace the dense API-name list with short human-readable descriptions of what each MVP capability does and why it matters. --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 775bff8..50704af 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,16 @@ GovEngine is **not** Ravenclaw, Tecrax, Logdash, an LLM agent loop, a scanner, o - neutral admission, policy, approval, and audit contracts for host runtime gates; - explicit SCLite integration seams; - focused standalone pytest coverage and GitHub Actions CI. -- on current `main`, the governed-runtime MVP helpers also include `RuntimeAdmissionResult`, `compose_runtime_admission_result()`, `validate_runtime_admission_result()`, `normalize_admission_artifact_refs()`, `ReplayClaimStore`, `verify_guard_and_record_replay()`, `validate_runner_receipt_binding()`, `validate_evidence_review_chain()`, GovEngine-owned record digests and signed-record helpers, `AuditLedgerPort` with a development-only `JsonlAuditLedgerAdapter`, runner supervision including `LocalSubprocessRunnerReadiness`, and `scripts/inspect_runtime_admission.py` for read-only admission inspection (listed in `CHANGELOG.md` under `Unreleased` until the next PyPI alpha release). + +On current `main` (already in source, still listed under `Unreleased` in `CHANGELOG.md` until the next PyPI alpha release), the governed-runtime MVP also adds: + +- **one admission decision you can actually read** — a single `RuntimeAdmissionResult` record that summarizes whether a prepared request may proceed, what blocked it, and what to fix next; helpers compose and validate that record from separate policy, ticket, trust, guard, replay, runner, and receipt signals without running live work themselves; +- **replay freshness** — remember which verified SCLite guarded roots were already used, so the same protected bundle cannot silently count as “fresh” twice; +- **receipt and evidence chain checks** — confirm that a runner receipt still points at the right admission and ticket, and that later evidence or review references stay within the bounds of that receipt; +- **GovEngine-owned record signing for fixtures** — deterministic digests and signed-record helpers for tests and reviewer demos, not production PKI; +- **a development-only audit trail adapter** — append and verify a local hash-chained audit log during development, without claiming a production database; +- **runner safety posture** — supervision helpers that keep dry-run as the default and treat an optional local subprocess runner as not ready until explicit host safety gates exist; +- **operator inspect without executing** — `scripts/inspect_runtime_admission.py` lets you read and summarize an admission record read-only, with no runner request, replay claim, audit write, or live execution. ## What it intentionally does not include yet From 73ca4bfdb8237b64be53905f09bcab6613501702 Mon Sep 17 00:00:00 2001 From: ExatronOmega Date: Sun, 14 Jun 2026 12:19:05 +0200 Subject: [PATCH 3/3] Clarify Unreleased changelog admission and runner gate wording. Separate receipt obligation at admission compose time from concrete receipt binding validation, and state explicitly that GovEngine does not grant live execution authority. --- CHANGELOG.md | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e14ad3..576d9be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,9 +13,14 @@ GovEngine follows conservative pre-1.0 versioning while the API boundary is stil and `validate_runtime_admission_result()`. The composer assembles policy, ticket, trust, guarded replay, runner profile, receipt obligation, and bounded artifact-reference summaries into one host-consumable decision record. -- Added runner profile and receipt admission gates. Controlled execution now - requires an approved runner profile together with a matching receipt before - granting live execution authority. +- Added runner-profile and receipt-obligation admission gates. Runtime admission + now requires an allowed runner profile and a receipt obligation; concrete + runner receipts are validated separately with + `validate_runner_receipt_binding()` against admission, ticket, request, and + receipt digests. +- Added these admission gates before any host-owned controlled runner path may + proceed; GovEngine still does not grant live execution authority or ship a live + subprocess backend. - Added inspect-only admission workflow and `scripts/inspect_runtime_admission.py` for read-only operator inspection of composed admission decisions without live execution. @@ -26,8 +31,9 @@ GovEngine follows conservative pre-1.0 versioning while the API boundary is stil in-memory development adapter. The port records replay claims (root tag, chain id, ticket/run id, key id) and can reject repeat roots in require-fresh mode without replacing existing guarded-root replay helpers from `0.12.1`. -- Added receipt-to-admission binding plus validators for runner receipt bindings - and admission evidence chains. +- Added receipt-to-admission binding plus `validate_runner_receipt_binding()` + and `validate_evidence_review_chain()` for bounded admission/ticket/request/ + receipt and receipt/evidence/review reference checks. - Added `validate_evidence_review_chain()` and supporting validators for end-to-end evidence review chains (admission → receipt → evidence → review). - Added `AuditLedgerPort` contracts plus `JsonlAuditLedgerAdapter`, a @@ -40,10 +46,11 @@ GovEngine follows conservative pre-1.0 versioning while the API boundary is stil `canonical_govengine_record()`, `signed_artifact_from_record()`, `verify_signed_govengine_record()`, and supporting trust/key-resolver ports. - Refined trust ports and normalized admission artifact references and digests. -- Added local subprocess runner readiness gating: - `LocalSubprocessRunnerReadiness`, `evaluate_local_subprocess_runner_readiness()`, - and `validate_runner_receipt_binding()`. The kernel can now mark the local - runner as not applicable and enforce that decision at the admission gate. +- Added local subprocess runner readiness gating with + `LocalSubprocessRunnerReadiness` and + `evaluate_local_subprocess_runner_readiness()`. The kernel keeps the optional + local subprocess runner at `not_applicable` until explicit host safety + prerequisites exist. ### Documentation, validation, and repository hygiene