From 665bcc65a34b5a20eadf3e5c9c802993134a0d4d Mon Sep 17 00:00:00 2001 From: Yernat Yestekov <2068106+doublewhy@users.noreply.github.com> Date: Thu, 8 Oct 2026 22:12:00 -0700 Subject: [PATCH 1/9] refactor(contracts): move runtime-fact exports into their own manifest The facade manifest _exports.py is at 499 of 500 lines. Move the contiguous runtime-fact binding-plane family into _runtime_fact_exports.py and spread it in place, so PUBLIC_EXPORTS keeps identical order and membership and the next contract family fits under the cap. --- .../raes_contracts/contracts/_exports.py | 20 ++-------------- .../contracts/_runtime_fact_exports.py | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 implementations/python/packages/raes_contracts/contracts/_runtime_fact_exports.py diff --git a/implementations/python/packages/raes_contracts/contracts/_exports.py b/implementations/python/packages/raes_contracts/contracts/_exports.py index ae5c10f61..86d8a4651 100644 --- a/implementations/python/packages/raes_contracts/contracts/_exports.py +++ b/implementations/python/packages/raes_contracts/contracts/_exports.py @@ -5,6 +5,7 @@ from ._execution_policy_exports import EXECUTION_POLICY_EXPORTS from ._mixed_composition_exports import MIXED_COMPOSITION_EXPORTS from ._participant_control_exports import PARTICIPANT_CONTROL_EXPORTS +from ._runtime_fact_exports import RUNTIME_FACT_EXPORTS PUBLIC_EXPORTS = [ *EXECUTION_POLICY_EXPORTS, @@ -417,24 +418,7 @@ "ReusableAssetEvidenceRequirementModel", "ReusableAssetFamilyTrustPolicyModel", "ReusableAssetTrustPolicyModel", - "RUNTIME_FACT_BINDING_PLANE_V1_SCHEMA_VERSION", - "RuntimeFactAbsenceDisposition", - "RuntimeFactAudience", - "RuntimeFactBindingDisposition", - "RuntimeFactBindingEventModel", - "RuntimeFactBindingPlaneModel", - "RuntimeFactBindingRequestModel", - "RuntimeFactBindingSelectionModel", - "RuntimeFactDeclarationModel", - "RuntimeFactProjectionModel", - "RuntimeFactScopeKind", - "RuntimeFactScopeModel", - "RuntimeFactSensitivity", - "RuntimeFactSinkModel", - "RuntimeFactSourceKind", - "RuntimeFactValueType", - "RuntimeFactVersionModel", - "RuntimeFactVisibilityModel", + *RUNTIME_FACT_EXPORTS, "RuntimeSnapshotEnvelopeModel", "SCENARIO_INSTANTIATION_REQUEST_SCHEMA_VERSION", "SEMANTIC_PROFILE_SCHEMA_VERSION", diff --git a/implementations/python/packages/raes_contracts/contracts/_runtime_fact_exports.py b/implementations/python/packages/raes_contracts/contracts/_runtime_fact_exports.py new file mode 100644 index 000000000..5dfdd0589 --- /dev/null +++ b/implementations/python/packages/raes_contracts/contracts/_runtime_fact_exports.py @@ -0,0 +1,24 @@ +"""Public runtime-fact binding-plane contract exports.""" + +RUNTIME_FACT_EXPORTS = [ + "RUNTIME_FACT_BINDING_PLANE_V1_SCHEMA_VERSION", + "RuntimeFactAbsenceDisposition", + "RuntimeFactAudience", + "RuntimeFactBindingDisposition", + "RuntimeFactBindingEventModel", + "RuntimeFactBindingPlaneModel", + "RuntimeFactBindingRequestModel", + "RuntimeFactBindingSelectionModel", + "RuntimeFactDeclarationModel", + "RuntimeFactProjectionModel", + "RuntimeFactScopeKind", + "RuntimeFactScopeModel", + "RuntimeFactSensitivity", + "RuntimeFactSinkModel", + "RuntimeFactSourceKind", + "RuntimeFactValueType", + "RuntimeFactVersionModel", + "RuntimeFactVisibilityModel", +] + +__all__ = ["RUNTIME_FACT_EXPORTS"] From cf93eb4b863bd4444f5ca556d9e9e18f9761c67a Mon Sep 17 00:00:00 2001 From: Yernat Yestekov <2068106+doublewhy@users.noreply.github.com> Date: Sat, 10 Oct 2026 23:56:54 -0700 Subject: [PATCH 2/9] chore(research): republish evidence for the runtime-fact export split Specification-coverage release 71.0.0 and formal-validation release 72.0.0 bind the current implementation digest; outcomes and claim limits are unchanged. --- .../analysis-v72.json | 163 ++++ .../bundles/retest-v72.json | 122 +++ .../execution-snapshot-v72.json | 652 ++++++++++++++++ .../formal-semantic-validation/index.md | 8 +- .../specification-coverage/analysis-v71.json | 112 +++ ...specification-coverage-issue-1418-v71.json | 10 + .../execution-snapshot-v71.json | 704 ++++++++++++++++++ docs/research/specification-coverage/index.md | 8 +- .../tests/test_formal_semantic_validation.py | 5 +- .../test_issue_989_versioned_evidence.py | 22 +- .../tests/test_specification_coverage.py | 2 +- tools/check_specification_coverage.py | 5 +- tools/formal_semantic_validation/_baseline.py | 2 + tools/formal_semantic_validation/_loading.py | 4 +- .../_release_revisions.py | 4 +- tools/formal_semantic_validation/_releases.py | 5 +- tools/formal_semantic_validation/_retest.py | 2 +- 17 files changed, 1807 insertions(+), 23 deletions(-) create mode 100644 docs/research/formal-semantic-validation/analysis-v72.json create mode 100644 docs/research/formal-semantic-validation/bundles/retest-v72.json create mode 100644 docs/research/formal-semantic-validation/execution-snapshot-v72.json create mode 100644 docs/research/specification-coverage/analysis-v71.json create mode 100644 docs/research/specification-coverage/bundles/raes-standardized-specification-coverage-issue-1418-v71.json create mode 100644 docs/research/specification-coverage/execution-snapshot-v71.json diff --git a/docs/research/formal-semantic-validation/analysis-v72.json b/docs/research/formal-semantic-validation/analysis-v72.json new file mode 100644 index 000000000..c20f35e56 --- /dev/null +++ b/docs/research/formal-semantic-validation/analysis-v72.json @@ -0,0 +1,163 @@ +{ + "analysis_id": "issue-1418-analysis-v72", + "claim": { + "allowed_evidence": [ + "production parser and semantic-validator results", + "canonical compiled digests", + "participant contract regression tests", + "pinned protocol, corpus, and execution snapshot" + ], + "claim_id": "asr-530-formal-semantic-validation-retest", + "disallowed_evidence": [ + "schema success as semantic proof", + "workflow reachability as network or exploit reachability", + "FM labels as gate outcomes", + "attribution as counterfactual proof", + "formal prose or maintainer confidence alone" + ], + "evidence_artifacts": [ + "docs/research/formal-semantic-validation/protocol-v2.json", + "docs/research/formal-semantic-validation/corpus/manifest-v4.json", + "docs/research/formal-semantic-validation/execution-snapshot-v72.json", + "docs/research/formal-semantic-validation/evidence/finite-domain-satisfiable-v4.json", + "docs/research/formal-semantic-validation/evidence/finite-domain-unsatisfiable-v4.json", + "docs/research/formal-semantic-validation/evidence/typed-exploit-path-valid-v4.json", + "docs/research/formal-semantic-validation/evidence/typed-exploit-path-invalid-v4.json" + ], + "falsification_protocol": "Replay every retained and new case through its production entrypoint, require complete digest and evidence joins, execute participant fixtures, and derive status from the recorded outcomes.", + "objective_fail_criteria": "A supported negative passes, a positive fails, an observation drifts, a required participant case is missing, or weaker evidence is promoted to solver, exploit-path, runtime-stability, or counterfactual assurance.", + "objective_pass_criteria": "Every claim class has positive and negative cases, all supported cases reproduce the frozen outcome, every participant obligation has passing positive and negative fixtures, and unsupported classes remain untested.", + "statement": "At the recorded source-state digest, the retained RAES controls have the bounded statuses recorded here; historical releases are integrity evidence, not current replay evidence.", + "threats_to_validity": [ + "The issue-specific corpus is intentionally small and does not enumerate every validator invariant.", + "The participant fixtures exercise reference production contracts and tests, not every independent backend realization.", + "The replay gate runs on one Python reference configuration and one pinned RAES revision.", + "Unsupported solver-level classes have protocol cases but no executable observations." + ] + }, + "claim_results": [ + { + "case_count": 2, + "claim_class_id": "schema-validity", + "evidence_status": "demonstrated", + "limitations": [ + "Bounded to the named source/model structural controls." + ], + "matching_case_count": 2, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 0 + }, + { + "case_count": 4, + "claim_class_id": "semantic-consistency", + "evidence_status": "partial", + "limitations": [ + "Partial coverage of named static semantics and participant obligations, not universal consistency." + ], + "matching_case_count": 4, + "participant_obligation_count": 7, + "replayable_case_count": 4, + "unsupported_case_count": 0 + }, + { + "case_count": 2, + "claim_class_id": "graph-reachability", + "evidence_status": "partial", + "limitations": [ + "Partial workflow control-flow reachability only; not network, service, or exploit reachability." + ], + "matching_case_count": 2, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 0 + }, + { + "case_count": 4, + "claim_class_id": "constraint-satisfiability", + "evidence_status": "demonstrated", + "limitations": [ + "Demonstrated only for raes-finite-domain-satisfiability-v1 and its pinned solver configuration." + ], + "matching_case_count": 4, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 2 + }, + { + "case_count": 4, + "claim_class_id": "exploit-path-validity", + "evidence_status": "demonstrated", + "limitations": [ + "Demonstrated only for the admitted snapshot, typed graph, query, semantics, and bounded search profile." + ], + "matching_case_count": 4, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 2 + }, + { + "case_count": 2, + "claim_class_id": "determinism-stability", + "evidence_status": "partial", + "limitations": [ + "Partial parse-to-compile repeatability only; runtime and backend determinism are untested." + ], + "matching_case_count": 2, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 0 + }, + { + "case_count": 2, + "claim_class_id": "counterfactual-necessity", + "evidence_status": "untested", + "limitations": [ + "Untested because no governed intervention or ablation entrypoint ran." + ], + "matching_case_count": 2, + "participant_obligation_count": 0, + "replayable_case_count": 0, + "unsupported_case_count": 2 + } + ], + "corpus_revision": "4.0.0", + "evidence_status": "partial", + "execution_id": "issue-1418-execution-v72", + "generated_at": "2026-10-11T06:56:15.112239+00:00", + "limitations": [ + "Satisfiability is limited to raes-finite-domain-satisfiability-v1 and its exact translation, theory, and Z3 configuration.", + "The subset-minimal unsatisfiable core is not a universal proof certificate.", + "Exploit-path results are limited to the admitted snapshot, normalized graph, query, transition semantics, and bounded search profile.", + "A valid path is not backend execution and an invalid path is not real-world non-exploitability.", + "The production exploit-path JSON loader permits duplicate keys; the research loader rejects them without claiming stronger production behavior.", + "Participant replay inherits the host environment and is not described as hermetic.", + "Counterfactual necessity remains untested.", + "Scoped observation demand is not a claim class in this preregistration and is not promoted to demonstrated by this retest.", + "EXP-732 provenance joins are verified by their dedicated regression suite; this retained corpus makes no universal run, apparatus, source, or augmentation assurance claim.", + "This retained corpus does not establish native backend attestation fidelity; materialization contract checks remain separate operational provenance, not experimental observations.", + "Capture admission and evidence-proof authority are verified by issue-1237 regression tests, not promoted to a new claim class by this retained corpus.", + "Evidence-requirement refinement lineage is outside this retained formal claim set; this retest refreshes integrated source provenance without promoting that feature to a formal claim.", + "Authoring-adapter transport behavior is outside this retained formal claim set.", + "Operational recovery observation and startup reconciliation are verified by their API-404 regression suite, not promoted to a new formal claim class by this retained corpus.", + "Single-owner store admission, immutable target/run scope, and provider shutdown ordering are verified by their API-404 CP-5 regression suite, not promoted to a formal claim by this retained corpus.", + "Mixed and staged trial admission is verified by its SEM-234/SCE-002/API-407 regression suite, not promoted to a new formal claim class by this retained corpus.", + "Offline control-plane maintenance, readiness, and bounded audit behavior are verified by issue #1186 runtime tests, not promoted to a formal claim by this retained corpus.", + "Issue #1187 control-plane crash/profile conformance and HTTP security changes are covered by their dedicated regression suite, not promoted to new claims by this retained corpus.", + "Issue #1189 profile declarations and capability admission are covered by dedicated runtime tests; the retained formal corpus does not execute control-plane profile composition.", + "Issue #1016 mixed-runtime coordination is covered by dedicated runtime tests; the retained formal corpus does not establish backend-native mixed realization, multi-controller coordination, IFC, or equivalence.", + "Issue #610's reconciliation demonstration harness is covered by its dedicated processor and CLI suite, not promoted to new claims by the retained language corpus.", + "Participant identity, organization ownership, and participant assignment are separated by issue #1338. This retained offline corpus does not establish participant autonomy, execution authority, live backend fidelity, or causal attribution.", + "Issue #1389 temporal-subject admission is verified by dedicated compiler tests and adds no new formal-semantic claim to this retained corpus.", + "Issue #971 model construction is verified by its own tests; this retained corpus establishes no participant-crossing equivalence or runtime-realization claim.", + "Issue #1359 control-plane route authority, participant-view scoping, and no-store HTTP boundary are verified by their dedicated HTTP-boundary suite and add no new formal-semantic claim to this retained corpus.", + "Issue #1401 required-evidence media-type coherence is verified by its dedicated suite and adds no new formal-semantic claim to this retained corpus.", + "Issue #1361 execution and recovery requirements are verified by dedicated policy, composition, and admission tests; this retained corpus establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 maintainability repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 resource type-hint repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The combined issue #1361 execution-policy and hatchling update preserves retained outcomes and bounded claims; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1418 runtime-fact export manifest split changes no contract, schema or behavior and adds no new formal-semantic claim." + ], + "plain_language_outcome": "The retained formal controls reproduce their prior outcomes against the issue #1418 runtime-fact export manifest split; bounded claims are unchanged.", + "protocol_revision": "2.0.0" +} diff --git a/docs/research/formal-semantic-validation/bundles/retest-v72.json b/docs/research/formal-semantic-validation/bundles/retest-v72.json new file mode 100644 index 000000000..0d99997f9 --- /dev/null +++ b/docs/research/formal-semantic-validation/bundles/retest-v72.json @@ -0,0 +1,122 @@ +{ + "analysis_path": "docs/research/formal-semantic-validation/analysis-v72.json", + "analysis_sha256": "53fbd43522e022b62174f669187d20c38d46aa4a7f8a97423ff6a923e0abe9f3", + "artifacts": [ + { + "artifact_id": "finite-domain-satisfiable-v2-input", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/satisfiable-control.sdl.yaml", + "sha256": "0ca9eaba9dc47171f7a042dc6753faa6c820c65ee966538f9d65fac5342202e8" + }, + { + "artifact_id": "finite-domain-satisfiable-v2-evidence", + "kind": "production-evidence", + "path": "docs/research/formal-semantic-validation/evidence/finite-domain-satisfiable-v4.json", + "sha256": "554202313d678046958b5c028e2de26ff03c74895cfac552677eed74e8153add" + }, + { + "artifact_id": "finite-domain-unsatisfiable-v2-input", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/unsatisfiable-control.sdl.yaml", + "sha256": "cfef56a1f56d5f0db9da195377fd75694bdd0f0b92932fdb8fafcbd3f7baf6c5" + }, + { + "artifact_id": "finite-domain-unsatisfiable-v2-evidence", + "kind": "production-evidence", + "path": "docs/research/formal-semantic-validation/evidence/finite-domain-unsatisfiable-v4.json", + "sha256": "c972725ef64822a75a60380afc11f08eac25b7fe9b091d39b058b3c9f7c8031d" + }, + { + "artifact_id": "typed-exploit-path-valid-v2-input", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/exploit-path-valid-v3.json", + "sha256": "0afe635a63db5b6e6380ac70982fd61d09790745d51a10d670321304121e7c39" + }, + { + "artifact_id": "typed-exploit-path-valid-v2-evidence", + "kind": "production-evidence", + "path": "docs/research/formal-semantic-validation/evidence/typed-exploit-path-valid-v4.json", + "sha256": "1b7f55d04db172da32658187c64a88c13b5f4d565267ce2be7cb86a9d04cb70c" + }, + { + "artifact_id": "typed-exploit-path-invalid-v2-input", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/exploit-path-invalid-v3.json", + "sha256": "0b2293d4a8983515ff05c516be6e6b418a4f3f09e055250a00bf15fda861aab3" + }, + { + "artifact_id": "typed-exploit-path-invalid-v2-evidence", + "kind": "production-evidence", + "path": "docs/research/formal-semantic-validation/evidence/typed-exploit-path-invalid-v4.json", + "sha256": "244f895a64f14c10916ab0533ab462ce80a328021cd6a50c30a4aa59266d5533" + }, + { + "artifact_id": "schema-valid-control-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/schema-valid.sdl.yaml", + "sha256": "41a9adffdf9f5f2ccc2f887dcf7b15fba3b47c83a1af15f33db872c4a2449d67" + }, + { + "artifact_id": "schema-unknown-field-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/schema-invalid-unknown-field.sdl.yaml", + "sha256": "51cf62319a86c95a2517995939d1f370573051835e4b55bb6d5beaf049640481" + }, + { + "artifact_id": "semantic-resolved-objective-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/semantic-valid-participant-identity-v2.sdl.yaml", + "sha256": "75834bdc883e2003e1c473870bdf75700978955bb83095c6bd718ba6bd3908a6" + }, + { + "artifact_id": "semantic-dangling-assertion-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/semantic-invalid-dangling-ref-participant-identity-v2.sdl.yaml", + "sha256": "1d25bee5f556054e5f0a518df025e4c62e080e1964035e3c1a12e074d88d3a5d" + }, + { + "artifact_id": "semantic-ambiguous-reference-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/semantic-invalid-ambiguous-ref.sdl.yaml", + "sha256": "653cbd2fd62e220d49fb86f80133884207df5ae6752846345ae3085b93f6e4ed" + }, + { + "artifact_id": "semantic-feature-cycle-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/semantic-invalid-feature-cycle.sdl.yaml", + "sha256": "e1f66d95a9ad039687aec8cccbc8843b514072ff08e006c1b4ca6aa5cd8d4ed1" + }, + { + "artifact_id": "workflow-reachable-control-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/workflow-reachable.sdl.yaml", + "sha256": "54c40ceb98ad47247447d737973b2c55e8fb2045e209c7545c4fb20cf42dc3dc" + }, + { + "artifact_id": "workflow-unreachable-step-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/workflow-unreachable.sdl.yaml", + "sha256": "ef22ef2e260f1a7fd92d286f9b571716436b192ddfd54aea7bdfcfdda4ca52a2" + }, + { + "artifact_id": "compile-repeatability-control-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/determinism-a.sdl.yaml", + "sha256": "0bc40900d598c1af7a405d798ca19710405e53ced262d8733081abf12edf89fe" + }, + { + "artifact_id": "compile-non-vacuity-control-comparison-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/determinism-b.sdl.yaml", + "sha256": "d85338f89f20a45515b12da8640173c1a52e47eb17ca0f4f6b4f8f3306e863a1" + } + ], + "bundle_id": "raes-formal-semantic-validation", + "corpus_path": "docs/research/formal-semantic-validation/corpus/manifest-v4.json", + "corpus_sha256": "c57207af72406aa4f70882b9bbeb7cedcc79cf3854c878a95e3eb1fa59ea7a72", + "protocol_path": "docs/research/formal-semantic-validation/protocol-v2.json", + "protocol_sha256": "abf94093e344bf495dfb04e8b0c5985c0beaab8ebb17a75e15c8674fa81b1a7c", + "revision": "72.0.0", + "snapshot_path": "docs/research/formal-semantic-validation/execution-snapshot-v72.json", + "snapshot_sha256": "355ced855c9ee28dc559c505d127cbee29ec2975abdc41f2cf926d98562c92ab" +} diff --git a/docs/research/formal-semantic-validation/execution-snapshot-v72.json b/docs/research/formal-semantic-validation/execution-snapshot-v72.json new file mode 100644 index 000000000..647f418f4 --- /dev/null +++ b/docs/research/formal-semantic-validation/execution-snapshot-v72.json @@ -0,0 +1,652 @@ +{ + "baseline": { + "execution_id": "issue-1481-sonar-execution-v71", + "release_path": "docs/research/formal-semantic-validation/bundles/retest-v71.json", + "release_revision": "71.0.0", + "release_sha256": "d0ea85a0d575a4387ee38cb18328e5f1dd4ecdcc017c157844a69a9d78efe592" + }, + "captured_at": "2026-10-11T06:56:15.112239+00:00", + "commands": [ + { + "argv": [ + "implementations/python/.venv/bin/python", + "tools/check_formal_semantic_validation.py" + ], + "command_id": "bundle-replay", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/pytest", + "-q", + "implementations/python/tests/test_sem_208_participant_behavior.py::test_hidden_truth_disclosure_is_separate_from_observable_projection", + "implementations/python/tests/test_sem_208_participant_behavior.py::test_hidden_truth_cannot_be_observed_without_explicit_disclosure_rule", + "implementations/python/tests/test_sem_211_participant_action_semantics.py::test_action_contract_declares_sem_211_classes_and_compiles_them", + "implementations/python/tests/test_sem_211_participant_action_semantics.py::test_action_result_rejects_success_when_preconditions_are_unresolved", + "implementations/python/tests/test_run_308_concurrent_participant_execution.py::test_runtime_snapshot_publishes_joint_action_and_time_context_records", + "implementations/python/tests/test_run_308_concurrent_participant_execution.py::test_joint_action_record_contract_rejects_unordered_conflicting_writes", + "implementations/python/tests/test_participant_runtime_invariants.py::test_order_discipline_accepts_supported_order_claim_strengths", + "implementations/python/tests/test_participant_runtime_invariants.py::test_order_discipline_rejects_wall_clock_causality", + "implementations/python/tests/test_sem_212_participant_attribution_semantics.py::test_attribution_edge_round_trips_on_terminal_observation", + "implementations/python/tests/test_sem_212_participant_attribution_semantics.py::test_timestamp_adjacency_cannot_be_reported_as_strong_causality", + "implementations/python/tests/test_sem_215_participant_outcome_interpretation.py::test_outcome_interpretation_rule_parses_and_compiles_explicit_layers", + "implementations/python/tests/test_sem_215_participant_outcome_interpretation.py::test_local_action_success_does_not_imply_objective_success_without_rule_record", + "implementations/python/tests/test_realization_honesty_conformance.py::test_constructive_envelope_runs_positive_and_negative_honesty_probes", + "implementations/python/tests/test_realization_honesty_conformance.py::test_only_native_live_can_support_native_conformance" + ], + "command_id": "participant-fixtures", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/raes", + "processor", + "satisfiability", + "docs/research/formal-semantic-validation/corpus/satisfiable-control.sdl.yaml", + "--profile", + "raes-finite-domain-satisfiability-v1" + ], + "command_id": "finite-domain-satisfiable-v2", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/raes", + "processor", + "satisfiability", + "docs/research/formal-semantic-validation/corpus/unsatisfiable-control.sdl.yaml", + "--profile", + "raes-finite-domain-satisfiability-v1" + ], + "command_id": "finite-domain-unsatisfiable-v2", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/raes", + "processor", + "exploit-path", + "docs/research/formal-semantic-validation/corpus/exploit-path-valid-v3.json", + "--profile", + "raes-exploit-path-analysis-v1" + ], + "command_id": "typed-exploit-path-valid-v2", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/raes", + "processor", + "exploit-path", + "docs/research/formal-semantic-validation/corpus/exploit-path-invalid-v3.json", + "--profile", + "raes-exploit-path-analysis-v1" + ], + "command_id": "typed-exploit-path-invalid-v2", + "network": "disabled" + } + ], + "configuration_id": "raes-python-reference-offline-v41", + "corpus_revision": "4.0.0", + "deviations": [], + "execution_id": "issue-1418-execution-v72", + "execution_status": "complete", + "observations": [ + { + "actual_outcome": "accepted", + "analysis_profile": null, + "case_id": "schema-valid-control", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/schema-valid.sdl.yaml" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "A passing minimal source does not establish semantic correctness." + ], + "replayable": true, + "result_digest": "f7d364ef384df8a1526b489501835b635021c860793b5764f91d956710d2250c", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "schema-unknown-field", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLParseError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/schema-invalid-unknown-field.sdl.yaml" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "The observation covers one unknown-field defect only." + ], + "replayable": true, + "result_digest": "f55d834b458f8e069e1c69061b4cc0a6d61e0e052bf90c670f2e6a5ad8b5bd98", + "source_digest": null + }, + { + "actual_outcome": "accepted", + "analysis_profile": null, + "case_id": "semantic-resolved-objective", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/semantic-valid-participant-identity-v2.sdl.yaml" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "This is a positive control for one objective-reference slice." + ], + "replayable": true, + "result_digest": "652288785dc09095955ed3649f6407d616fb7c4d4f4188df4ed513ccb7537e0b", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "semantic-dangling-assertion", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLValidationError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/semantic-invalid-dangling-ref-participant-identity-v2.sdl.yaml" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "A single dangling reference does not prove complete semantic coverage." + ], + "replayable": true, + "result_digest": "0207cf616b56708ca9b8c4499d3301abe22dbe52162cf8d58d3bec429d9db024", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "semantic-ambiguous-reference", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLValidationError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/semantic-invalid-ambiguous-ref.sdl.yaml" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "One namespace collision does not enumerate every ambiguity surface." + ], + "replayable": true, + "result_digest": "9da4a87797d228e0012ab6b30459f4892e41aa6f224a9840be035fee4a2eea73", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "semantic-feature-cycle", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLValidationError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/semantic-invalid-feature-cycle.sdl.yaml" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "One static dependency cycle does not establish general constraint satisfiability." + ], + "replayable": true, + "result_digest": "d15dbcd99fb4f20b965d7031b07dd6534576302270399c3fa656d29e7de02b83", + "source_digest": null + }, + { + "actual_outcome": "accepted", + "analysis_profile": null, + "case_id": "workflow-reachable-control", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/workflow-reachable.sdl.yaml" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "The graph is workflow control flow only." + ], + "replayable": true, + "result_digest": "b1b49649b54bd59d4ef357b39cf9158da90f4eae560f8dd756acf97bd0827a06", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "workflow-unreachable-step", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLValidationError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/workflow-unreachable.sdl.yaml" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "The result does not establish network, service, participant, or exploit reachability." + ], + "replayable": true, + "result_digest": "bb931d19346ef9193408ae6c85deb4079704378fc5f00dc5f47a2817cff21943", + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "whole-scenario-satisfiable-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "No governed whole-scenario constraint theory or solver exists." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "whole-scenario-unsatisfiable-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "Local checks cannot produce a whole-scenario unsat certificate." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "valid-exploit-path-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "The issue-168 baseline had no canonical typed attack graph or path-query entrypoint." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "invalid-exploit-path-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "Vulnerability and topology declarations are not an invalid-path proof." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "stable", + "analysis_profile": null, + "case_id": "compile-repeatability-control", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/determinism-a.sdl.yaml" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "The witness ends at compiled output." + ], + "replayable": true, + "result_digest": "d7c098c5d063b8d1b0747e8df5daa90061456065cdda0bbedfa10918442f5daa", + "source_digest": null + }, + { + "actual_outcome": "distinguishable", + "analysis_profile": null, + "case_id": "compile-non-vacuity-control", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/determinism-a.sdl.yaml", + "docs/research/formal-semantic-validation/corpus/determinism-b.sdl.yaml" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "Distinct digests are a non-vacuity control, not semantic non-equivalence proof." + ], + "replayable": true, + "result_digest": "a2fcebba3341592b133af813e8bb8e5f47270418bc58bfd471a89bfbc8ba46da", + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "necessity-witness-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "No governed intervention or ablation protocol exists." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "non-necessity-control-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "Attribution and negative fixtures do not demonstrate non-necessity." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "satisfiable", + "analysis_profile": "raes-finite-domain-satisfiability-v1", + "case_id": "finite-domain-satisfiable-v2", + "configuration_digest": "sha256:1204635e17e759e9ad3bd6be2ecb28c6de05c07ead6dfdd15936ed5d3d5b81b2", + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "scenario-satisfiability-evidence/v1", + "evidence_artifact_path": "docs/research/formal-semantic-validation/evidence/finite-domain-satisfiable-v4.json", + "evidence_artifact_sha256": "554202313d678046958b5c028e2de26ff03c74895cfac552677eed74e8153add", + "evidence_digest": "sha256:23c2cae7d95d4cc83d77ca576e3911477b169ecc311c977cb45490345f633b5a", + "evidence_profile": "scenario-satisfiability-evidence/v1", + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/satisfiable-control.sdl.yaml", + "docs/research/formal-semantic-validation/evidence/finite-domain-satisfiable-v4.json", + "specs/formal/scenario-satisfiability/README.md" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "Demonstrates only the pinned finite-domain theory, translation, solver profile, and source." + ], + "replayable": true, + "result_digest": "sha256:23c2cae7d95d4cc83d77ca576e3911477b169ecc311c977cb45490345f633b5a", + "source_digest": "sha256:0ca9eaba9dc47171f7a042dc6753faa6c820c65ee966538f9d65fac5342202e8" + }, + { + "actual_outcome": "unsatisfiable", + "analysis_profile": "raes-finite-domain-satisfiability-v1", + "case_id": "finite-domain-unsatisfiable-v2", + "configuration_digest": "sha256:1204635e17e759e9ad3bd6be2ecb28c6de05c07ead6dfdd15936ed5d3d5b81b2", + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "scenario-satisfiability-evidence/v1", + "evidence_artifact_path": "docs/research/formal-semantic-validation/evidence/finite-domain-unsatisfiable-v4.json", + "evidence_artifact_sha256": "c972725ef64822a75a60380afc11f08eac25b7fe9b091d39b058b3c9f7c8031d", + "evidence_digest": "sha256:317b5cad00aa7f4f7868dca66127611ba19d40ffd86f35815502622814df54c1", + "evidence_profile": "scenario-satisfiability-evidence/v1", + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/unsatisfiable-control.sdl.yaml", + "docs/research/formal-semantic-validation/evidence/finite-domain-unsatisfiable-v4.json", + "specs/formal/scenario-satisfiability/README.md" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "The subset-minimal core is evidence for the pinned translation and solver, not a proof certificate for arbitrary SDL." + ], + "replayable": true, + "result_digest": "sha256:317b5cad00aa7f4f7868dca66127611ba19d40ffd86f35815502622814df54c1", + "source_digest": "sha256:cfef56a1f56d5f0db9da195377fd75694bdd0f0b92932fdb8fafcbd3f7baf6c5" + }, + { + "actual_outcome": "valid-path", + "analysis_profile": "raes-exploit-path-analysis-v1", + "case_id": "typed-exploit-path-valid-v2", + "configuration_digest": "sha256:7f8876d81feb77d3a3239be2fb8337de8885e2744f8786728ba23e4e6027bc0a", + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "exploit-path-analysis-evidence/v1", + "evidence_artifact_path": "docs/research/formal-semantic-validation/evidence/typed-exploit-path-valid-v4.json", + "evidence_artifact_sha256": "1b7f55d04db172da32658187c64a88c13b5f4d565267ce2be7cb86a9d04cb70c", + "evidence_digest": "sha256:2d4d1a362751abd9544beb8af7f8c6331d04dac8f4abc315fb261f81fbaf4387", + "evidence_profile": "exploit-path-analysis-evidence/v1", + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/exploit-path-valid-v3.json", + "docs/research/formal-semantic-validation/evidence/typed-exploit-path-valid-v4.json", + "specs/formal/exploit-path-analysis/README.md" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "The witness is bounded to the admitted snapshot, normalized graph, query, semantics, and search profile; it does not establish backend execution." + ], + "replayable": true, + "result_digest": "sha256:2d4d1a362751abd9544beb8af7f8c6331d04dac8f4abc315fb261f81fbaf4387", + "source_digest": "sha256:0afe635a63db5b6e6380ac70982fd61d09790745d51a10d670321304121e7c39" + }, + { + "actual_outcome": "invalid-path", + "analysis_profile": "raes-exploit-path-analysis-v1", + "case_id": "typed-exploit-path-invalid-v2", + "configuration_digest": "sha256:7f8876d81feb77d3a3239be2fb8337de8885e2744f8786728ba23e4e6027bc0a", + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "exploit-path-analysis-evidence/v1", + "evidence_artifact_path": "docs/research/formal-semantic-validation/evidence/typed-exploit-path-invalid-v4.json", + "evidence_artifact_sha256": "244f895a64f14c10916ab0533ab462ce80a328021cd6a50c30a4aa59266d5533", + "evidence_digest": "sha256:1b416bb5a4d29d57c961b769cc9d3af5d9328624e3eebf104d57f39a94c5bb97", + "evidence_profile": "exploit-path-analysis-evidence/v1", + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/exploit-path-invalid-v3.json", + "docs/research/formal-semantic-validation/evidence/typed-exploit-path-invalid-v4.json", + "specs/formal/exploit-path-analysis/README.md" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "Structured rejection proves only that this bounded graph/query cannot reach its goal; it does not establish real-world non-exploitability." + ], + "replayable": true, + "result_digest": "sha256:1b416bb5a4d29d57c961b769cc9d3af5d9328624e3eebf104d57f39a94c5bb97", + "source_digest": "sha256:0b2293d4a8983515ff05c516be6e6b418a4f3f09e055250a00bf15fda861aab3" + } + ], + "participant_observations": [ + { + "evidence_refs": [ + "implementations/python/tests/test_sem_208_participant_behavior.py::test_hidden_truth_disclosure_is_separate_from_observable_projection", + "implementations/python/tests/test_sem_208_participant_behavior.py::test_hidden_truth_cannot_be_observed_without_explicit_disclosure_rule" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "Covers the reference SDL/contract path, not every backend projection." + ], + "negative_outcome": "passed", + "obligation_id": "hidden-vs-visible-projection", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_sem_211_participant_action_semantics.py::test_action_contract_declares_sem_211_classes_and_compiles_them", + "implementations/python/tests/test_sem_211_participant_action_semantics.py::test_action_result_rejects_success_when_preconditions_are_unresolved" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "Covers declared applicability and one unresolved-precondition failure." + ], + "negative_outcome": "passed", + "obligation_id": "fail-closed-action-applicability", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_run_308_concurrent_participant_execution.py::test_runtime_snapshot_publishes_joint_action_and_time_context_records", + "implementations/python/tests/test_run_308_concurrent_participant_execution.py::test_joint_action_record_contract_rejects_unordered_conflicting_writes" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "Contract evidence does not prove every backend's live concurrency fidelity." + ], + "negative_outcome": "passed", + "obligation_id": "shared-state-effects", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_participant_runtime_invariants.py::test_order_discipline_accepts_supported_order_claim_strengths", + "implementations/python/tests/test_participant_runtime_invariants.py::test_order_discipline_rejects_wall_clock_causality" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "Rejecting timestamp-only causality does not supply counterfactual proof." + ], + "negative_outcome": "passed", + "obligation_id": "ordering-before-causality", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_sem_212_participant_attribution_semantics.py::test_attribution_edge_round_trips_on_terminal_observation", + "implementations/python/tests/test_sem_212_participant_attribution_semantics.py::test_timestamp_adjacency_cannot_be_reported_as_strong_causality" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "Attribution labels disclose basis; they do not demonstrate necessity." + ], + "negative_outcome": "passed", + "obligation_id": "evidence-labeled-attribution", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_sem_215_participant_outcome_interpretation.py::test_outcome_interpretation_rule_parses_and_compiles_explicit_layers", + "implementations/python/tests/test_sem_215_participant_outcome_interpretation.py::test_local_action_success_does_not_imply_objective_success_without_rule_record" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "The fixtures establish layer separation, not outcome validity in every realization." + ], + "negative_outcome": "passed", + "obligation_id": "participant-local-outcome-separation", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_realization_honesty_conformance.py::test_constructive_envelope_runs_positive_and_negative_honesty_probes", + "implementations/python/tests/test_realization_honesty_conformance.py::test_only_native_live_can_support_native_conformance" + ], + "execution_id": "issue-1418-execution-v72", + "limitations": [ + "Reference conformance evidence remains bounded to declared realization profiles." + ], + "negative_outcome": "passed", + "obligation_id": "realization-profile-honesty", + "positive_outcome": "passed" + } + ], + "protocol_revision": "2.0.0", + "raes_revision": "665bcc65a34b5a20eadf3e5c9c802993134a0d4d", + "source_state": { + "base_revision": "665bcc65a34b5a20eadf3e5c9c802993134a0d4d", + "checkout_state": "modified", + "implementation_digest": "0e8eb206ef7bba7d41ab2aebe4453c1f5d004b8e9855fd398559aef7b918a236", + "profile": "python-reference-source/v2" + }, + "versions": { + "python": "3.14.4", + "raes": "5.0.0", + "z3_engine": "4.16.0", + "z3_solver": "4.16.0.0" + } +} diff --git a/docs/research/formal-semantic-validation/index.md b/docs/research/formal-semantic-validation/index.md index cc927339e..a8fc612cd 100644 --- a/docs/research/formal-semantic-validation/index.md +++ b/docs/research/formal-semantic-validation/index.md @@ -336,7 +336,7 @@ outcomes and claim limits, recording the positive successor's changed result digest; the dangling-reference diagnostic remains identical. It establishes no autonomy threshold, authority grant, or realized attribution. -Current validation requires explicit release 69.0.0, rejects unsupported future +Current validation requires explicit release 72.0.0, rejects unsupported future or duplicate revisions, and never accepts an old/new output-digest pair as a substitute for replay. Historical releases (including the issue-826 supplement) undergo pin, shape, control, and internal-join checks without executing current @@ -600,3 +600,9 @@ in [`execution-snapshot-v71.json`](execution-snapshot-v71.json) and [`analysis-v71.json`](analysis-v71.json). Source identity is refreshed against immutable release 70.0.0; outcomes, compiled digests, and bounded claim limits remain unchanged, with no baseline deviations. + +Release 72.0.0 replays the retained formal cases against the issue #1418 +runtime-fact export manifest split in +[`execution-snapshot-v72.json`](execution-snapshot-v72.json) and +[`analysis-v72.json`](analysis-v72.json). Outcomes and claim limits remain +unchanged. diff --git a/docs/research/specification-coverage/analysis-v71.json b/docs/research/specification-coverage/analysis-v71.json new file mode 100644 index 000000000..e94111a02 --- /dev/null +++ b/docs/research/specification-coverage/analysis-v71.json @@ -0,0 +1,112 @@ +{ + "analysis_id": "raes-standardized-specification-coverage-issue-1418-v71", + "backend_leakage": [], + "claim": { + "allowed_evidence": [ + "pinned source metadata and bounded paraphrases", + "production parser, semantic, instantiation, admission, compiler, contract, and profile results", + "exact artifact digests and typed pointers", + "documented missing-concept and backend-specific dispositions" + ], + "claim_id": "raes-standardized-configurable-specification-coverage", + "disallowed_evidence": [ + "field-count or schema breadth alone", + "the existing scenario stress corpus as the representative request corpus", + "free-form metadata as typed coverage", + "backend-private interpretation", + "post-hoc removal or repair of falsifying concepts" + ], + "evidence_artifacts": [ + "docs/research/specification-coverage/protocol-v1.json", + "docs/research/specification-coverage/execution-snapshot-v71.json", + "docs/research/specification-coverage/analysis-v68.json" + ], + "falsification_protocol": "docs/research/specification-coverage/protocol-v1.json", + "objective_fail_criteria": "A load-bearing concept is missing or lossy, an applicable stage fails, or backend vocabulary is required in core SDL while the result claims success.", + "objective_pass_criteria": "Every load-bearing concept passes at every owning stage, backend-specific mechanics stay outside core SDL, and no requested concept is silently lost.", + "statement": "RAES provides a standardized configurable portable specification surface for the preregistered representative cyber-agent evaluation environment requirements without backend vocabulary in core SDL.", + "threats_to_validity": [ + "The representative corpus contains four source strata and sixteen atomic concepts rather than every cyber-range requirement.", + "The reference processor and repository fixtures are not independent backend implementations.", + "No live range, simulator federation, or participant execution was part of this offline specification-coverage test." + ] + }, + "classification_counts": { + "deliberately-backend-specific": 1, + "directly-expressible": 10, + "missing": 3, + "profile-or-manifest-constraint": 2 + }, + "evidence_status": "partial", + "execution_status": "complete", + "generated_at": "2026-10-11T06:56:15.112239+00:00", + "limitations": [ + "This result demonstrates bounded specification coverage, not universal cyber-range coverage, usability, adoption, backend substitution, or behavioral equivalence.", + "The three missing concepts are evidence, not implementation tasks within this snapshot.", + "The retained protocol does not test recursive realization or plan-level profile semantics; this release only re-establishes its original bounded coverage result against the current implementation.", + "The retained protocol does not test evidence-requirement refinement lineage; the dedicated EXP-731 regression suite covers that production boundary.", + "Authoring-adapter transport behavior is outside this retained protocol.", + "Reviewed OCI mirror and pre-seed admission is covered by its own regression suites and the development artifact policy gate, not a new claim in this preregistered matrix.", + "Operational recovery observation and startup reconciliation are covered by their API-404 regression suite, not a new claim in this preregistered matrix.", + "Store ownership, immutable runtime scope, and provider shutdown ordering are covered by the API-404 CP-5 regression suite, not by this retained specification-coverage protocol.", + "Mixed/staged trial compilation and admission are covered by issue #1015 regression tests, not by this retained specification-coverage corpus; no live mixed-runtime result is claimed.", + "Issue #1186 control-plane recovery operations are covered by their runtime regression suite, not by this retained specification-coverage corpus.", + "Issue #1187 control-plane crash/profile conformance and HTTP security changes are covered by their dedicated regression suite, not promoted to new claims by this retained corpus.", + "Issue #1189 control-plane profile declarations are covered by their dedicated runtime suite, not promoted to new claims by the retained language corpus.", + "Issue #610's reconciliation demonstration harness is covered by its dedicated processor and CLI suite, not promoted to new claims by the retained language corpus.", + "Participant identity, organization ownership, and participant assignment are separated by issue #1338. This retained offline corpus does not establish participant autonomy, execution authority, live backend fidelity, or causal attribution.", + "Participant-local outcome state is verified by the ACT-618 tests; this retained corpus makes no additional outcome-state claim.", + "Backend operation supervision contracts are covered by issue #1360 contract tests; this retained offline corpus establishes no live backend supervision or recovery guarantee.", + "This capture replays the merged issue #1360 and #1357 source; the protocol makes no live backend execution or supervision claim.", + "This capture replays the merged issue #1360 and #1358 source; the protocol makes no live backend execution or supervision claim.", + "Issue #1389 participant inject delivery temporal-subject admission is covered by dedicated compiler tests; this retained matrix makes no new timing or execution claim.", + "Issue #971 adds offline crossing model construction; this retained protocol establishes no crossing equivalence or runtime-realization claim.", + "Issue #1359 control-plane route authority, participant-view scoping, and no-store HTTP boundary are covered by their dedicated HTTP-boundary suite; this retained matrix makes no new exposure or execution claim.", + "Issue #1401 required-evidence media-type coherence is verified by its dedicated suite; this retained matrix makes no new admission or capture claim.", + "Issue #1361 execution and recovery requirements are verified by dedicated policy, composition, and admission tests; this retained corpus establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 maintainability repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 resource type-hint repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The combined issue #1361 execution-policy and hatchling update preserves retained outcomes and bounded claims; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1418 runtime-fact export manifest split changes no contract, schema or behavior; this retained matrix makes no new admission or coverage claim." + ], + "load_bearing_results": { + "failed": 0, + "missing": 0, + "passed": 10, + "total": 10 + }, + "plain_language_outcome": "The retained specification matrix preserves its prior classifications against the issue #1418 runtime-fact export manifest split; bounded claim limits are unchanged.", + "protocol_revision": "1.0.0", + "request_results": [ + { + "concept_count": 6, + "failed_stage_count": 0, + "missing_count": 0, + "request_id": "survey-representative-range", + "status": "demonstrated" + }, + { + "concept_count": 5, + "failed_stage_count": 1, + "missing_count": 1, + "request_id": "cyborg-participant-evaluation", + "status": "partial" + }, + { + "concept_count": 3, + "failed_stage_count": 1, + "missing_count": 1, + "request_id": "vsdl-configurable-infrastructure", + "status": "partial" + }, + { + "concept_count": 2, + "failed_stage_count": 1, + "missing_count": 1, + "request_id": "cyber-dem-federation", + "status": "partial" + } + ], + "snapshot_id": "raes-standardized-specification-coverage-issue-1418-v71", + "snapshot_sha256": "fe5d06b53b9d37773b2bda1d329147fa75fb2f821809deb2d360bc669c6e9906" +} diff --git a/docs/research/specification-coverage/bundles/raes-standardized-specification-coverage-issue-1418-v71.json b/docs/research/specification-coverage/bundles/raes-standardized-specification-coverage-issue-1418-v71.json new file mode 100644 index 000000000..18c24b925 --- /dev/null +++ b/docs/research/specification-coverage/bundles/raes-standardized-specification-coverage-issue-1418-v71.json @@ -0,0 +1,10 @@ +{ + "analysis_path": "docs/research/specification-coverage/analysis-v71.json", + "analysis_sha256": "ca48b93f47215bf87a1afcd22cc6598d52ec593af7fb743bd2ac2795b1a17aec", + "bundle_id": "raes-standardized-specification-coverage", + "protocol_path": "docs/research/specification-coverage/protocol-v1.json", + "protocol_sha256": "e97a19e643e94c9e589dca823a63c6ce49d3329fe2a3cb888ab630838ed93125", + "revision": "71.0.0", + "snapshot_path": "docs/research/specification-coverage/execution-snapshot-v71.json", + "snapshot_sha256": "5d790c32519ada0ecc316c5cffc84670a3723aa1bd11e81206ed80b68312dac7" +} diff --git a/docs/research/specification-coverage/execution-snapshot-v71.json b/docs/research/specification-coverage/execution-snapshot-v71.json new file mode 100644 index 000000000..6bafc412c --- /dev/null +++ b/docs/research/specification-coverage/execution-snapshot-v71.json @@ -0,0 +1,704 @@ +{ + "artifacts": [ + { + "artifact_id": "enterprise-participant-sdl", + "kind": "sdl", + "path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "sha256": "f7a8897beec243e188ee081975006fad32725f469f267db6e75a1e1cf5727032", + "validator": "raes parse, semantic, instantiation/admission, and compiler pipeline" + }, + { + "artifact_id": "port-range-sdl", + "kind": "sdl", + "path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "sha256": "0d5497ec946b863e6985284ec487dde7d7f6bf710a985be51401ac0e5e79dc4f", + "validator": "raes parse, semantic, instantiation/admission, and compiler pipeline" + }, + { + "artifact_id": "experiment-task-contract", + "kind": "experiment-task", + "path": "contracts/fixtures/experiment-core/experiment-task-v1/valid/reference.json", + "sha256": "f3edf713ac6af26bad609136851c6dd434bfb87ce919a2d8c4414c1035deeafc", + "validator": "raes_contracts.contracts.ExperimentTaskModel" + }, + { + "artifact_id": "apparatus-context-contract", + "kind": "experiment-apparatus-context", + "path": "contracts/fixtures/experiment-core/experiment-apparatus-context-v1/valid/reference.json", + "sha256": "e6fa559c5e961f0aab448d0f70dead24aa74fa8ba5f20e1b72f88e11473c9299", + "validator": "raes_contracts.contracts.ExperimentApparatusContextModel" + }, + { + "artifact_id": "backend-profile", + "kind": "backend-profile", + "path": "contracts/profiles/backend/orchestration-capable.json", + "sha256": "f70b8505a5c0055416db86c533e2e5bf08b11e5a514f076223b6d6c36215a092", + "validator": "raes_contracts.backend_profiles.BackendProfileModel" + }, + { + "artifact_id": "known-limitations", + "kind": "documentation", + "path": "docs/explain/sdl/limitations.md", + "sha256": "489eeab3ce682627682311581eb98af9abb9ff42a437145af266eefb71dc7fc4", + "validator": "documentation evidence only" + } + ], + "baseline": { + "release_revision": "1.1.0", + "release_sha256": "4020a1d56c7fe2831cec59ea64a12bbda9d38ccd94f93b916dd90f1a28f17fcb" + }, + "captured_at": "2026-10-11T06:56:15.112239+00:00", + "concept_results": [ + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "range-topology", + "rationale": "SDL nodes and infrastructure own host, network, link, and dependency meaning; the compiler emits canonical node deployment addresses.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed VM declaration.", + "outcome": "passed", + "pointer": "/nodes/shipping-portal", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Links and dependencies resolved.", + "outcome": "passed", + "pointer": "/infrastructure/shipping-portal", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Published instantiated shape admitted.", + "outcome": "passed", + "pointer": "/nodes/shipping-portal", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical deployment address retained.", + "outcome": "passed", + "pointer": "/node_deployments/provision.node.shipping-portal", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/nodes/shipping-portal" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "exercise-roles", + "rationale": "SDL entity roles own exercise responsibility without becoming control-plane identity or authorization.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed red role.", + "outcome": "passed", + "pointer": "/entities/enterprise-participant/role", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Entity references validated.", + "outcome": "passed", + "pointer": "/entities/enterprise-participant", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Role retained after instantiation.", + "outcome": "passed", + "pointer": "/entities/enterprise-participant/role", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Role retained in entity specification.", + "outcome": "passed", + "pointer": "/entity_specs/enterprise-participant/role", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/entities/enterprise-participant/role" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "evaluation-objectives", + "rationale": "SDL objectives own organization ownership, participant assignment, targets, windows, and assertion-based success; measures remain experiment contracts.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed objective declaration.", + "outcome": "passed", + "pointer": "/objectives/demonstrate-handoff", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Owner, participant assignment, targets, assertions, and workflow refs resolved.", + "outcome": "passed", + "pointer": "/objectives/demonstrate-handoff/success", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Objective retained in admitted artifact.", + "outcome": "passed", + "pointer": "/objectives/demonstrate-handoff", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical objective address retained.", + "outcome": "passed", + "pointer": "/objectives/evaluation.objective.demonstrate-handoff", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/objectives/demonstrate-handoff" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "control-workflows", + "rationale": "SDL workflows own the portable control graph and compile to canonical orchestration state contracts.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed control graph.", + "outcome": "passed", + "pointer": "/workflows/yard-recovery", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Step graph and objective refs validated.", + "outcome": "passed", + "pointer": "/workflows/yard-recovery/steps", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Workflow retained after instantiation.", + "outcome": "passed", + "pointer": "/workflows/yard-recovery", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical control graph retained.", + "outcome": "passed", + "pointer": "/workflows/orchestration.workflow.yard-recovery", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/workflows/yard-recovery" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "authored-evidence-expectations", + "rationale": "SDL evidence requirements own portable capture intent and remain distinct from evidence records and measures.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed capture obligation.", + "outcome": "passed", + "pointer": "/evidence_requirements/objective-truth-evidence", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Source refs and bindings validated.", + "outcome": "passed", + "pointer": "/evidence_requirements/objective-truth-evidence", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Evidence intent retained in admitted artifact.", + "outcome": "passed", + "pointer": "/evidence_requirements/objective-truth-evidence", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + } + ], + "typed_pointer": "/evidence_requirements/objective-truth-evidence" + }, + { + "backend_support": "profile-bound", + "backend_vocabulary_occurrences": [], + "classification": "profile-or-manifest-constraint", + "completeness_disposition": "implemented", + "concept_id": "apparatus-selection-constraints", + "rationale": "The experiment task contract binds processor/backend identities, manifest refs, and capabilities outside SDL.", + "stage_results": [ + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-task-v1/valid/reference.json", + "diagnostic_codes": [], + "note": "Closed ExperimentTaskModel validated.", + "outcome": "passed", + "pointer": "/apparatus_constraints/allowed_backend_refs/0", + "stage_id": "contract", + "validation_strength": "contract" + } + ], + "typed_pointer": "/apparatus_constraints/allowed_backend_refs/0" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "participant-agent", + "rationale": "SDL agents own participant entity, knowledge, actions, observation boundaries, and operating scope.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed participant declaration.", + "outcome": "passed", + "pointer": "/agents/participant-agent", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Participant refs and scope validated.", + "outcome": "passed", + "pointer": "/agents/participant-agent/observation_boundaries", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Participant retained in admitted artifact.", + "outcome": "passed", + "pointer": "/agents/participant-agent", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Compiled participant scope retained.", + "outcome": "passed", + "pointer": "/agent_specs/participant-agent", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/agents/participant-agent" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "participant-action-contract", + "rationale": "The action contract declares portable preconditions, effects, observations, evidence, and failure classes without a runner command.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed action contract.", + "outcome": "passed", + "pointer": "/action_contracts/probe-customer-portal-login", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Action refs and evidence bindings validated.", + "outcome": "passed", + "pointer": "/action_contracts/probe-customer-portal-login/effects", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Action retained in admitted artifact.", + "outcome": "passed", + "pointer": "/action_contracts/probe-customer-portal-login", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical action address retained.", + "outcome": "passed", + "pointer": "/action_contracts/participant.action-contract.probe-customer-portal-login", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/action_contracts/probe-customer-portal-login" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "participant-observation-boundary", + "rationale": "The observation boundary separately declares visible, hidden, and evidence-only information with transition rules.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed observation boundary.", + "outcome": "passed", + "pointer": "/observation_boundaries/participant-view", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Information refs and transitions validated.", + "outcome": "passed", + "pointer": "/observation_boundaries/participant-view/view_rules", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Boundary retained in admitted artifact.", + "outcome": "passed", + "pointer": "/observation_boundaries/participant-view", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical boundary address retained.", + "outcome": "passed", + "pointer": "/observation_boundaries/participant.observation-boundary.participant-view", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/observation_boundaries/participant-view" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "evaluation-measure", + "rationale": "ExperimentTaskModel owns metric construct, unit, direction, aggregation, and evidence requirements outside SDL objectives.", + "stage_results": [ + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-task-v1/valid/reference.json", + "diagnostic_codes": [], + "note": "Closed task contract validated.", + "outcome": "passed", + "pointer": "/evaluation_protocol/metric_definitions/foothold-achieved", + "stage_id": "contract", + "validation_strength": "contract" + } + ], + "typed_pointer": "/evaluation_protocol/metric_definitions/foothold-achieved" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "missing", + "completeness_disposition": "documented-gap", + "concept_id": "participant-tool-affordance", + "rationale": "This preregistered matrix has no tested carrier for participant tool affordances. The retained missing classification records missing coverage evidence, not the absence of current participant-behavior capabilities.", + "stage_results": [ + { + "artifact_path": "docs/explain/sdl/limitations.md", + "diagnostic_codes": [], + "note": "The preregistered carrier slot was not run; metadata does not substitute for a typed coverage test.", + "outcome": "not_run", + "pointer": null, + "stage_id": "authored", + "validation_strength": "not-applicable" + } + ], + "typed_pointer": null + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "resource-constrained-topology", + "rationale": "SDL node resources and infrastructure dependencies express portable resource intent without provider resource identifiers.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed CPU and memory declaration.", + "outcome": "passed", + "pointer": "/nodes/shipping-portal/resources", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Resource-bearing topology validated.", + "outcome": "passed", + "pointer": "/infrastructure/shipping-portal", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Constraints retained in admitted artifact.", + "outcome": "passed", + "pointer": "/nodes/shipping-portal/resources", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Deployment specification retains resource intent.", + "outcome": "passed", + "pointer": "/node_deployments/provision.node.shipping-portal", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/nodes/shipping-portal/resources" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "missing", + "completeness_disposition": "documented-gap", + "concept_id": "formal-constraint-satisfiability", + "rationale": "This coverage matrix did not exercise a solver-backed carrier. The separate formal-semantic-validation release demonstrates its bounded finite-domain profile; that result is not silently imported into this protocol's missing carrier slot.", + "stage_results": [ + { + "artifact_path": "docs/explain/sdl/limitations.md", + "diagnostic_codes": [], + "note": "No coverage-carrier execution was performed here; independent solver evidence does not change this preregistered denominator.", + "outcome": "not_run", + "pointer": null, + "stage_id": "semantic", + "validation_strength": "not-applicable" + } + ], + "typed_pointer": null + }, + { + "backend_support": "profile-bound", + "backend_vocabulary_occurrences": [ + { + "allowed": true, + "artifact_path": "source:vsdl-paper", + "pointer": "source sections 4-5", + "reason": "Legitimate VSDL realization vocabulary, not RAES core SDL structure.", + "term": "OpenStack/Terraform/Packer" + } + ], + "classification": "deliberately-backend-specific", + "completeness_disposition": "external", + "concept_id": "provider-specific-provisioning", + "rationale": "Provider image selection and provisioning engines are realization mechanics and therefore remain outside core SDL.", + "stage_results": [ + { + "artifact_path": "contracts/profiles/backend/orchestration-capable.json", + "diagnostic_codes": [], + "note": "The portable boundary requires backend contracts; it does not standardize a provider engine.", + "outcome": "not_applicable", + "pointer": "/required_contracts", + "stage_id": "realization-disclosure", + "validation_strength": "profile" + } + ], + "typed_pointer": null + }, + { + "backend_support": "profile-bound", + "backend_vocabulary_occurrences": [], + "classification": "profile-or-manifest-constraint", + "completeness_disposition": "implemented", + "concept_id": "apparatus-clock-context", + "rationale": "ExperimentApparatusContextModel records clock authority, time domain, and synchronization as apparatus facts outside scenario meaning.", + "stage_results": [ + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-apparatus-context-v1/valid/reference.json", + "diagnostic_codes": [], + "note": "Closed apparatus context contract validated.", + "outcome": "passed", + "pointer": "/clocks/0", + "stage_id": "contract", + "validation_strength": "contract" + } + ], + "typed_pointer": "/clocks/0" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "missing", + "completeness_disposition": "documented-gap", + "concept_id": "federated-object-event-exchange", + "rationale": "The federated cyber object/event exchange carrier was not exercised by this preregistered matrix. Runtime event internals are not treated as equivalent evidence.", + "stage_results": [ + { + "artifact_path": "docs/explain/sdl/limitations.md", + "diagnostic_codes": [], + "note": "The missing coverage-carrier test is recorded explicitly, without inferring an ecosystem-wide capability absence.", + "outcome": "not_run", + "pointer": null, + "stage_id": "contract", + "validation_strength": "not-applicable" + } + ], + "typed_pointer": null + } + ], + "deviations": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "baseline_sha256": "54ba1a60220e27a55da9cd2a407d7d3ab836fa54460d0b0c6cad87c2e744ddbb", + "rationale": "Migrate participant affiliations and explicit objective assignment, retaining organizational intent and portable action-contract declarations without granting execution authority.", + "retest_sha256": "f7a8897beec243e188ee081975006fad32725f469f267db6e75a1e1cf5727032" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "baseline_sha256": "a27c7a64e0c5c618fadaccafdf1a4e71600170a8b77b983190822b5141f00dec", + "rationale": "Migrate participant affiliations and explicit objective assignment, retaining organizational intent and portable action-contract declarations without granting execution authority.", + "retest_sha256": "0d5497ec946b863e6985284ec487dde7d7f6bf710a985be51401ac0e5e79dc4f" + }, + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-task-v1/valid/reference.json", + "baseline_sha256": "21952a752f4e8581a9fc3b872e4bc308150548170d38bcfc83dbbe35ff5e0b9f", + "rationale": "Replay the retained preregistered artifact against the current evidence-provenance validation implementation.", + "retest_sha256": "f3edf713ac6af26bad609136851c6dd434bfb87ce919a2d8c4414c1035deeafc" + }, + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-apparatus-context-v1/valid/reference.json", + "baseline_sha256": "9536d897a09cbc6920e667e4f8f9371e51307aa0b3b5ff3c7de682dd783420ab", + "rationale": "Replay the retained preregistered artifact against the current evidence-provenance validation implementation.", + "retest_sha256": "e6fa559c5e961f0aab448d0f70dead24aa74fa8ba5f20e1b72f88e11473c9299" + }, + { + "artifact_path": "docs/explain/sdl/limitations.md", + "baseline_sha256": "129cf17810aad4c51988bc872e28fe43ae95019a80053c42d800ff7e2b9cc93e", + "rationale": "Correct historical mandatory-profile guidance after issue #1207; retain the preregistered missing-concept classifications and coverage limits.", + "retest_sha256": "489eeab3ce682627682311581eb98af9abb9ff42a437145af266eefb71dc7fc4" + } + ], + "execution_status": "complete", + "implementation_surfaces": [ + { + "content_sha256": "1fdd5fcae0d5a2e8e37b5e2f570dfdeaab53b4b91ed8391c1665df3f1c123842", + "path": "implementations/python/packages/raes_contracts", + "surface_id": "contract-models" + }, + { + "content_sha256": "e947f59695e907f5af899a6bc4bde60e629620aa7c4a69a41e074ba335758c7a", + "path": "implementations/python/packages/raes_processor", + "surface_id": "processor-pipeline" + }, + { + "content_sha256": "51688dbe152fb4bbeacd7f8443a3f1fbc7a09b1b898adb134be0e5b4edec28ab", + "path": "implementations/python/packages/raes", + "surface_id": "sdl-pipeline" + } + ], + "limitations": [ + "The execution validates the pinned reference implementation and published contracts, not an independent backend.", + "Repository-owned examples are exact execution artifacts but are not themselves the literature-derived request corpus; the protocol's requests and concepts are.", + "No live range, participant, simulator federation, or provider provisioning engine was executed.", + "Missing concepts remain frozen in this snapshot and require separately scoped product work before a later rerun.", + "This capture replays the retained protocol after EXP-732 run, apparatus, measurement-channel, and augmentation-producer provenance validation; it adds no independent backend or universal provenance assurance claim.", + "Materialization attestation is covered by its dedicated regression suite, not a new claim in this preregistered matrix.", + "This capture refreshes the corrected runtime limitations prose for issue #959; the protocol, coverage classifications and implementation source are unchanged.", + "This capture replays open-by-default augmentation scope integrated with the EXP-731 evidence refinements after composition type refinement; it does not evaluate native backend scope enforcement or broaden the preregistered coverage claims.", + "This capture replays the retained protocol after merging ACT-612 participant relationships with open-by-default augmentation scope; it adds no claim of realized participant relationships or native backend scope enforcement.", + "This capture replays issue #1299 partial listener descriptions on the integrated source state; endpoint completeness and backend admission remain outside this protocol's claims.", + "This capture also binds authoring-adapter semantic conformance to the integrated source; adapter transport behavior remains outside this protocol's claims.", + "Reviewed OCI mirror and pre-seed admission is covered by its own regression suites and the development artifact policy gate, not a new claim in this preregistered matrix.", + "This capture binds issue #1297 service-manager identity, native-name, and explicitly selected systemd-state contract changes to the integrated source. It exercises no live service manager and adds no backend-execution claim.", + "This capture replays the retained specification-coverage protocol after API-404 startup reconciliation added an operational recovery-observation contract. It does not evaluate crash recovery, classify provider effects, or broaden EXP-715 experiment-observation claims.", + "This capture binds API-404 single-owner store admission and immutable target/run scope to the integrated source. The retained offline protocol does not exercise process leases, SQLite lifecycle ordering, or crash recovery.", + "This capture binds issue #1015 deterministic mixed and staged trial admission to the integrated source. The retained offline language corpus does not execute mixed runtimes, phase transitions, backend handoff, or scheduler-driven realization.", + "This replay binds issue #1186 offline control-plane maintenance, readiness, and bounded audit code to the integrated source. The retained language corpus does not execute store recovery, HTTP health behavior, or audit redaction.", + "Issue #1187 control-plane crash/profile conformance and HTTP security changes are covered by their dedicated regression suite, not promoted to new claims by this retained corpus.", + "Issue #1189 control-plane profile declarations are covered by their dedicated runtime suite, not promoted to new claims by the retained language corpus.", + "Issue #1016 mixed-runtime coordination is covered by its dedicated runtime suite. The retained language corpus does not execute mixed providers or establish backend-native realization, multi-controller coordination, IFC, or equivalence.", + "Issue #610's reconciliation demonstration harness is covered by its dedicated processor and CLI suite, not promoted to new claims by the retained language corpus.", + "Participant identity, organization ownership, and participant assignment are separated by issue #1338. This retained offline corpus does not establish participant autonomy, execution authority, live backend fidelity, or causal attribution.", + "Issue #1361 execution and recovery requirements are verified by dedicated policy, composition, and admission tests; this retained corpus establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 maintainability repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 resource type-hint repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The combined issue #1361 execution-policy and hatchling update preserves retained outcomes and bounded claims; it establishes no live recovery, continuation, or trial-allocation guarantee." + ], + "protocol_revision": "1.0.0", + "protocol_sha256": "e97a19e643e94c9e589dca823a63c6ce49d3329fe2a3cb888ab630838ed93125", + "raes_revision": "665bcc65a34b5a20eadf3e5c9c802993134a0d4d", + "snapshot_id": "raes-standardized-specification-coverage-issue-1418-v71", + "snapshot_revision": "71.0.0", + "source_state": { + "base_revision": "665bcc65a34b5a20eadf3e5c9c802993134a0d4d", + "checkout_state": "modified", + "implementation_digest": "0e8eb206ef7bba7d41ab2aebe4453c1f5d004b8e9855fd398559aef7b918a236", + "profile": "python-reference-source/v2" + } +} diff --git a/docs/research/specification-coverage/index.md b/docs/research/specification-coverage/index.md index eeaff60a8..55b1959de 100644 --- a/docs/research/specification-coverage/index.md +++ b/docs/research/specification-coverage/index.md @@ -292,7 +292,7 @@ the port scenario. Historical captures and archived example bytes are retained. The matrix classifications and untested concepts are unchanged; no execution authority, successful action, or live backend fidelity is inferred. -Current validation requires release 68.0.0 and rejects duplicate or unsupported +Current validation requires release 71.0.0 and rejects duplicate or unsupported future revisions. It executes current artifacts, requires exact source and package hashes, and checks all passing stage pointers. `source_state` discloses the base Git commit, modified checkout state, and exact implementation digest; @@ -540,3 +540,9 @@ Release 70.0.0 replays the same matrix after the issue #1481 Sonar refactor in [`execution-snapshot-v70.json`](execution-snapshot-v70.json) and [`analysis-v70.json`](analysis-v70.json). The capture refreshes source and package identities without changing classifications, outcomes, or claim limits. + +Release 71.0.0 replays the retained matrix against the issue #1418 runtime-fact +export manifest split in +[`execution-snapshot-v71.json`](execution-snapshot-v71.json) and +[`analysis-v71.json`](analysis-v71.json). Classifications and claim limits +remain unchanged. diff --git a/implementations/python/tests/test_formal_semantic_validation.py b/implementations/python/tests/test_formal_semantic_validation.py index 05a10608e..b35015af1 100644 --- a/implementations/python/tests/test_formal_semantic_validation.py +++ b/implementations/python/tests/test_formal_semantic_validation.py @@ -150,6 +150,7 @@ def test_atomic_release_index_validates_every_historical_bundle() -> None: "69.0.0", "70.0.0", "71.0.0", + "72.0.0", ] assert all(validate_release_bundle(REPO_ROOT, release) == [] for release in releases) @@ -158,10 +159,10 @@ def test_atomic_release_index_validates_every_historical_bundle() -> None: def test_current_retest_bundle_is_coherent_and_clean() -> None: release, protocol, corpus, snapshot, analysis = copy_bundle(load_retest_bundle, REPO_ROOT) - assert release.manifest["revision"] == "71.0.0" + assert release.manifest["revision"] == "72.0.0" assert protocol["revision"] == "2.0.0" assert corpus["revision"] == "4.0.0" - assert snapshot["baseline"]["release_revision"] == "70.0.0" + assert snapshot["baseline"]["release_revision"] == "71.0.0" assert snapshot["deviations"] == [] assert validate_retest_bundle(REPO_ROOT, release, protocol, corpus, snapshot, analysis) == [] diff --git a/implementations/python/tests/test_issue_989_versioned_evidence.py b/implementations/python/tests/test_issue_989_versioned_evidence.py index b54405c5d..31f182771 100644 --- a/implementations/python/tests/test_issue_989_versioned_evidence.py +++ b/implementations/python/tests/test_issue_989_versioned_evidence.py @@ -241,18 +241,18 @@ def _stub_release(revision: str, *, protocol_revision: str = "2.0.0"): [ pytest.param([], "selects no v2 retest release", id="no-release"), pytest.param( - [_stub_release("69.0.0"), _stub_release("70.0.0")], - "must be the explicit 71.0.0 retest", + [_stub_release("70.0.0"), _stub_release("71.0.0")], + "must be the explicit 72.0.0 retest", id="stale-current", ), pytest.param( - [_stub_release("70.0.0"), _stub_release("72.0.0")], - "must be the explicit 71.0.0 retest", + [_stub_release("71.0.0"), _stub_release("73.0.0")], + "must be the explicit 72.0.0 retest", id="unsupported-future", ), pytest.param( - [_stub_release("71.0.0", protocol_revision="1.0.0")], - "must be the explicit 71.0.0 retest", + [_stub_release("72.0.0", protocol_revision="1.0.0")], + "must be the explicit 72.0.0 retest", id="wrong-protocol", ), ], @@ -269,8 +269,8 @@ def test_current_formal_release_selection_is_explicit(monkeypatch, releases, mes def test_current_formal_release_selection_returns_the_explicit_retest(monkeypatch): from tools.formal_semantic_validation import _loading - current = _stub_release("71.0.0") - monkeypatch.setattr(_loading, "load_release_bundles", lambda _root: [_stub_release("70.0.0"), current]) + current = _stub_release("72.0.0") + monkeypatch.setattr(_loading, "load_release_bundles", lambda _root: [_stub_release("71.0.0"), current]) assert _loading.load_retest_bundle(ROOT)[0] is current @@ -282,7 +282,7 @@ def test_latest_current_release_is_versioned_and_strict(monkeypatch): from tools.formal_semantic_validation._releases import validate_retest_bundle release, protocol, corpus, snapshot, analysis = copy_bundle(load_retest_bundle, ROOT) - assert release.manifest["revision"] == "71.0.0" + assert release.manifest["revision"] == "72.0.0" original = _retest.replay_case def changed_result(root, case): @@ -335,7 +335,7 @@ def test_specification_current_capture_does_not_accept_old_artifact_digest(artif from tools.check_specification_coverage import load_bundle, validate_bundle manifest, protocol, snapshot, analysis = copy_bundle(load_bundle, ROOT) - assert manifest["revision"] == "70.0.0" + assert manifest["revision"] == "71.0.0" snapshot = deepcopy(snapshot) artifact = next(a for a in snapshot["artifacts"] if a["artifact_id"] == artifact_id) artifact["sha256"] = old_digest @@ -575,6 +575,7 @@ def test_no_capture_can_be_silently_dropped(monkeypatch, family, removed): "69.0.0", "70.0.0", "71.0.0", + "72.0.0", ] if family == "formal" else [ @@ -649,6 +650,7 @@ def test_no_capture_can_be_silently_dropped(monkeypatch, family, removed): "68.0.0", "69.0.0", "70.0.0", + "71.0.0", ] ) revisions.pop(-1 if removed == "current" else 0) diff --git a/implementations/python/tests/test_specification_coverage.py b/implementations/python/tests/test_specification_coverage.py index 5ed1684eb..9993be42a 100644 --- a/implementations/python/tests/test_specification_coverage.py +++ b/implementations/python/tests/test_specification_coverage.py @@ -53,7 +53,7 @@ def test_immutable_bundle_index_preserves_concurrent_captures() -> None: bundles = copy_bundle(load_bundles, REPO_ROOT) assert {manifest["revision"] for manifest, *_rest in bundles} >= {"1.0.0", "1.1.0", "19.0.0"} manifest, *_rest = copy_bundle(load_bundle, REPO_ROOT) - assert manifest["revision"] == "70.0.0" + assert manifest["revision"] == "71.0.0" def test_historical_failures_name_the_revision_specific_documents() -> None: diff --git a/tools/check_specification_coverage.py b/tools/check_specification_coverage.py index 22abd4af4..7bf2b9865 100644 --- a/tools/check_specification_coverage.py +++ b/tools/check_specification_coverage.py @@ -175,12 +175,13 @@ def _load_bundle_index(repo_root: Path) -> list[tuple[str, dict[str, object]]]: "68.0.0", "69.0.0", "70.0.0", + "71.0.0", } if ( - dict(records)[current_path].get("revision") != "70.0.0" + dict(records)[current_path].get("revision") != "71.0.0" or {record.get("revision") for _, record in records} != supported_revisions ): - raise ValueError("coverage evidence requires the explicit current 70.0.0 release and supported history") + raise ValueError("coverage evidence requires the explicit current 71.0.0 release and supported history") return records diff --git a/tools/formal_semantic_validation/_baseline.py b/tools/formal_semantic_validation/_baseline.py index b26026806..ae36ec508 100644 --- a/tools/formal_semantic_validation/_baseline.py +++ b/tools/formal_semantic_validation/_baseline.py @@ -206,6 +206,8 @@ def _selected_baseline_manifest( "68.0.0", "69.0.0", "70.0.0", + "71.0.0", + "72.0.0", }: expected_corpus_path = "docs/research/formal-semantic-validation/corpus/manifest-v4.json" elif baseline_revision in _V3_CORPUS_REVISIONS: diff --git a/tools/formal_semantic_validation/_loading.py b/tools/formal_semantic_validation/_loading.py index 94560fed2..242714714 100644 --- a/tools/formal_semantic_validation/_loading.py +++ b/tools/formal_semantic_validation/_loading.py @@ -82,6 +82,6 @@ def load_retest_bundle( if not releases: raise ValueError("the formal semantic-validation index selects no v2 retest release") release = max(releases, key=lambda item: revision_key(item.manifest.get("revision"))) - if release.manifest.get("revision") != "71.0.0" or release.protocol.get("revision") != "2.0.0": - raise ValueError("the current formal evidence release must be the explicit 71.0.0 retest") + if release.manifest.get("revision") != "72.0.0" or release.protocol.get("revision") != "2.0.0": + raise ValueError("the current formal evidence release must be the explicit 72.0.0 retest") return release, release.protocol, release.corpus, release.snapshot, release.analysis diff --git a/tools/formal_semantic_validation/_release_revisions.py b/tools/formal_semantic_validation/_release_revisions.py index b09c19e90..b17c4b61e 100644 --- a/tools/formal_semantic_validation/_release_revisions.py +++ b/tools/formal_semantic_validation/_release_revisions.py @@ -72,9 +72,10 @@ "68.0.0", "69.0.0", "70.0.0", + "71.0.0", } -_SUPPORTED_RETEST_REVISIONS = _HISTORICAL_RETEST_REVISIONS | {"71.0.0"} +_SUPPORTED_RETEST_REVISIONS = _HISTORICAL_RETEST_REVISIONS | {"72.0.0"} _SOURCE_BOUND_RETEST_REVISIONS = _SUPPORTED_RETEST_REVISIONS - {"3.0.0"} _RETEST_BASELINE_REVISIONS = { @@ -148,4 +149,5 @@ "69.0.0": "68.0.0", "70.0.0": "69.0.0", "71.0.0": "70.0.0", + "72.0.0": "71.0.0", } diff --git a/tools/formal_semantic_validation/_releases.py b/tools/formal_semantic_validation/_releases.py index 01b979147..579df51a6 100644 --- a/tools/formal_semantic_validation/_releases.py +++ b/tools/formal_semantic_validation/_releases.py @@ -160,7 +160,7 @@ def validate_release_bundle(repo_root: Path, release: EvidenceRelease) -> list[P release.corpus, release.snapshot, release.analysis, - replay_current=manifest.get("revision") == "71.0.0", + replay_current=manifest.get("revision") == "72.0.0", ) ) else: @@ -289,6 +289,7 @@ def _expected_corpus_revision(release_revision: object) -> str: "69.0.0", "70.0.0", "71.0.0", + "72.0.0", }: expected_corpus_revision = "4.0.0" return expected_corpus_revision @@ -316,7 +317,7 @@ def validate_retest_bundle( return [ _failure( "formal-validation-current-replay-required", - "only releases 3.0.0 through 66.0.0 can use integrated historical validation", + "only releases 3.0.0 through 71.0.0 can use integrated historical validation", snapshot_path, ) ] diff --git a/tools/formal_semantic_validation/_retest.py b/tools/formal_semantic_validation/_retest.py index 0a2090a96..0c62a1502 100644 --- a/tools/formal_semantic_validation/_retest.py +++ b/tools/formal_semantic_validation/_retest.py @@ -37,7 +37,7 @@ ) from tools.policy.common import PolicyFailure -_SOURCE_STATE_REVISIONS = frozenset(f"{revision}.0.0" for revision in range(4, 72)) +_SOURCE_STATE_REVISIONS = frozenset(f"{revision}.0.0" for revision in range(4, 73)) @dataclasses.dataclass(frozen=True) From c26e576d5ce61ce1e7968f54f0f000aefde9ea6d Mon Sep 17 00:00:00 2001 From: Yernat Yestekov <2068106+doublewhy@users.noreply.github.com> Date: Fri, 9 Oct 2026 01:45:00 -0700 Subject: [PATCH 3/9] feat(contracts): publish inject trigger request and occurrence contracts Publish draft inject-trigger-request-v1 and inject-occurrence-v1 carriers for ADR-112 external injects: compiled inject and binding selection, closed narrative placement, value-free input, actor-bound orchestration admission, unrebased order, and exact-retry and unique-claim helpers. Nothing executes an inject or changes the runtime. --- contracts/README.md | 5 + .../context-invalid/provisioning-kind.json | 76 +++ .../context-invalid/rebased-order.json | 76 +++ .../context-invalid/shared-identity.json | 76 +++ .../invalid/missing-admission.json | 65 +++ .../valid/participant-free-environment.json | 76 +++ .../valid/scheduled-fan-out.json | 88 +++ .../context-invalid/ambiguous-instance.json | 31 ++ .../context-invalid/event-as-inject.json | 26 + .../context-invalid/foreign-binding.json | 26 + .../invalid/no-binding.json | 20 + .../invalid/participant-binding.json | 27 + .../invalid/untyped-payload.json | 29 + .../valid/independent-binding.json | 25 + .../valid/participant-free-environment.json | 26 + .../valid/scheduled-fan-out.json | 38 ++ .../entries/inject-occurrence-v1.json | 10 + .../entries/inject-trigger-request-v1.json | 10 + .../control-plane/inject-occurrence-v1.json | 507 ++++++++++++++++++ .../inject-trigger-request-v1.json | 322 +++++++++++ .../reference/inject-occurrence-contracts.md | 95 ++++ docs/public/api/contracts.rst | 9 + .../raes_contracts/contracts/__init__.py | 1 + .../raes_contracts/contracts/_exports.py | 2 + .../contracts/_inject_occurrence_exports.py | 36 ++ .../contracts/bundle_runtime.py | 2 + .../contracts/inject_occurrence.py | 206 +++++++ .../contracts/inject_occurrence_schema.py | 44 ++ .../packages/raes_contracts/versions.py | 2 + ..._issue_1423_inject_occurrence_contracts.py | 263 +++++++++ 30 files changed, 2219 insertions(+) create mode 100644 contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/provisioning-kind.json create mode 100644 contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/rebased-order.json create mode 100644 contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/shared-identity.json create mode 100644 contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-admission.json create mode 100644 contracts/fixtures/control-plane/inject-occurrence-v1/valid/participant-free-environment.json create mode 100644 contracts/fixtures/control-plane/inject-occurrence-v1/valid/scheduled-fan-out.json create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/ambiguous-instance.json create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/event-as-inject.json create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/foreign-binding.json create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/no-binding.json create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/participant-binding.json create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/untyped-payload.json create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/valid/independent-binding.json create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/valid/participant-free-environment.json create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/valid/scheduled-fan-out.json create mode 100644 contracts/schema-publication/entries/inject-occurrence-v1.json create mode 100644 contracts/schema-publication/entries/inject-trigger-request-v1.json create mode 100644 contracts/schemas/control-plane/inject-occurrence-v1.json create mode 100644 contracts/schemas/control-plane/inject-trigger-request-v1.json create mode 100644 docs/explain/reference/inject-occurrence-contracts.md create mode 100644 implementations/python/packages/raes_contracts/contracts/_inject_occurrence_exports.py create mode 100644 implementations/python/packages/raes_contracts/contracts/inject_occurrence.py create mode 100644 implementations/python/packages/raes_contracts/contracts/inject_occurrence_schema.py create mode 100644 implementations/python/tests/test_issue_1423_inject_occurrence_contracts.py diff --git a/contracts/README.md b/contracts/README.md index 2a2ed5a39..971213b8d 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -11,6 +11,11 @@ cancellation dispositions and effect evidence. The [backend integration and migration guide](../docs/explain/reference/backend-operation-supervision.md) explains the `operation-supervision` profile and its evidence limits. +The draft [inject trigger and occurrence contracts](../docs/explain/reference/inject-occurrence-contracts.md) +carry an external inject request and its claimed occurrence under +[ADR-112](../docs/decisions/adrs/adr-112-external-inject-triggering-and-execution.md). +They grant no trigger authority and execute nothing. + `contracts/` contains the machine-readable contract side of the repository. The goal of this bucket is organizational clarity: diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/provisioning-kind.json b/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/provisioning-kind.json new file mode 100644 index 000000000..921523ff3 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/provisioning-kind.json @@ -0,0 +1,76 @@ +{ + "schema_version": "inject-occurrence/v1", + "operation_id": "operation-release-1", + "request": { + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" + }, + "admission": { + "actor_id": "researcher-1", + "authorization_scope": [ + "role:operator" + ], + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "operation_kind": "provisioning", + "request_commitment": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "parent_operation_id": null + }, + "admission_evidence": [ + { + "contract_id": "proposition-truth-result-v1", + "artifact_id": "precondition-results-1", + "digest": "sha256:3333333333333333333333333333333333333333333333333333333333333333" + } + ], + "store_revision": "store-revision-41", + "order": { + "scope": "run:environment-1", + "predecessor": "order-head-9", + "position": 10 + }, + "scenario": { + "contract_id": "instantiated-scenario-v1", + "artifact_id": "external-trigger-environment", + "digest": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "source": { + "contract_id": "associated-artifact-manifest-v1", + "artifact_id": "release-notice-source", + "digest": "sha256:5555555555555555555555555555555555555555555555555555555555555555" + }, + "realization": { + "contract_id": "backend-manifest-v2", + "artifact_id": "reference-realization", + "digest": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + }, + "evidence_requirements": [ + { + "contract_id": "runtime-snapshot-v1", + "artifact_id": "readback-requirement-1", + "digest": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + ] +} diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/rebased-order.json b/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/rebased-order.json new file mode 100644 index 000000000..dd383cc98 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/rebased-order.json @@ -0,0 +1,76 @@ +{ + "schema_version": "inject-occurrence/v1", + "operation_id": "operation-release-1", + "request": { + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" + }, + "admission": { + "actor_id": "researcher-1", + "authorization_scope": [ + "role:operator" + ], + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "operation_kind": "orchestration", + "request_commitment": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "parent_operation_id": null + }, + "admission_evidence": [ + { + "contract_id": "proposition-truth-result-v1", + "artifact_id": "precondition-results-1", + "digest": "sha256:3333333333333333333333333333333333333333333333333333333333333333" + } + ], + "store_revision": "store-revision-41", + "order": { + "scope": "run:environment-1", + "predecessor": "order-head-10", + "position": 10 + }, + "scenario": { + "contract_id": "instantiated-scenario-v1", + "artifact_id": "external-trigger-environment", + "digest": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "source": { + "contract_id": "associated-artifact-manifest-v1", + "artifact_id": "release-notice-source", + "digest": "sha256:5555555555555555555555555555555555555555555555555555555555555555" + }, + "realization": { + "contract_id": "backend-manifest-v2", + "artifact_id": "reference-realization", + "digest": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + }, + "evidence_requirements": [ + { + "contract_id": "runtime-snapshot-v1", + "artifact_id": "readback-requirement-1", + "digest": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + ] +} diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/shared-identity.json b/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/shared-identity.json new file mode 100644 index 000000000..654b900a5 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/shared-identity.json @@ -0,0 +1,76 @@ +{ + "schema_version": "inject-occurrence/v1", + "operation_id": "release-occurrence-1", + "request": { + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" + }, + "admission": { + "actor_id": "researcher-1", + "authorization_scope": [ + "role:operator" + ], + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "operation_kind": "orchestration", + "request_commitment": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "parent_operation_id": null + }, + "admission_evidence": [ + { + "contract_id": "proposition-truth-result-v1", + "artifact_id": "precondition-results-1", + "digest": "sha256:3333333333333333333333333333333333333333333333333333333333333333" + } + ], + "store_revision": "store-revision-41", + "order": { + "scope": "run:environment-1", + "predecessor": "order-head-9", + "position": 10 + }, + "scenario": { + "contract_id": "instantiated-scenario-v1", + "artifact_id": "external-trigger-environment", + "digest": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "source": { + "contract_id": "associated-artifact-manifest-v1", + "artifact_id": "release-notice-source", + "digest": "sha256:5555555555555555555555555555555555555555555555555555555555555555" + }, + "realization": { + "contract_id": "backend-manifest-v2", + "artifact_id": "reference-realization", + "digest": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + }, + "evidence_requirements": [ + { + "contract_id": "runtime-snapshot-v1", + "artifact_id": "readback-requirement-1", + "digest": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + ] +} diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-admission.json b/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-admission.json new file mode 100644 index 000000000..9988a19e3 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-admission.json @@ -0,0 +1,65 @@ +{ + "schema_version": "inject-occurrence/v1", + "operation_id": "operation-release-1", + "request": { + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" + }, + "admission_evidence": [ + { + "contract_id": "proposition-truth-result-v1", + "artifact_id": "precondition-results-1", + "digest": "sha256:3333333333333333333333333333333333333333333333333333333333333333" + } + ], + "store_revision": "store-revision-41", + "order": { + "scope": "run:environment-1", + "predecessor": "order-head-9", + "position": 10 + }, + "scenario": { + "contract_id": "instantiated-scenario-v1", + "artifact_id": "external-trigger-environment", + "digest": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "source": { + "contract_id": "associated-artifact-manifest-v1", + "artifact_id": "release-notice-source", + "digest": "sha256:5555555555555555555555555555555555555555555555555555555555555555" + }, + "realization": { + "contract_id": "backend-manifest-v2", + "artifact_id": "reference-realization", + "digest": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + }, + "evidence_requirements": [ + { + "contract_id": "runtime-snapshot-v1", + "artifact_id": "readback-requirement-1", + "digest": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + ] +} diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/valid/participant-free-environment.json b/contracts/fixtures/control-plane/inject-occurrence-v1/valid/participant-free-environment.json new file mode 100644 index 000000000..e8dd8213a --- /dev/null +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/valid/participant-free-environment.json @@ -0,0 +1,76 @@ +{ + "schema_version": "inject-occurrence/v1", + "operation_id": "operation-release-1", + "request": { + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" + }, + "admission": { + "actor_id": "researcher-1", + "authorization_scope": [ + "role:operator" + ], + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "operation_kind": "orchestration", + "request_commitment": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "parent_operation_id": null + }, + "admission_evidence": [ + { + "contract_id": "proposition-truth-result-v1", + "artifact_id": "precondition-results-1", + "digest": "sha256:3333333333333333333333333333333333333333333333333333333333333333" + } + ], + "store_revision": "store-revision-41", + "order": { + "scope": "run:environment-1", + "predecessor": "order-head-9", + "position": 10 + }, + "scenario": { + "contract_id": "instantiated-scenario-v1", + "artifact_id": "external-trigger-environment", + "digest": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "source": { + "contract_id": "associated-artifact-manifest-v1", + "artifact_id": "release-notice-source", + "digest": "sha256:5555555555555555555555555555555555555555555555555555555555555555" + }, + "realization": { + "contract_id": "backend-manifest-v2", + "artifact_id": "reference-realization", + "digest": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + }, + "evidence_requirements": [ + { + "contract_id": "runtime-snapshot-v1", + "artifact_id": "readback-requirement-1", + "digest": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + ] +} diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/valid/scheduled-fan-out.json b/contracts/fixtures/control-plane/inject-occurrence-v1/valid/scheduled-fan-out.json new file mode 100644 index 000000000..020aff24f --- /dev/null +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/valid/scheduled-fan-out.json @@ -0,0 +1,88 @@ +{ + "schema_version": "inject-occurrence/v1", + "operation_id": "operation-handover-1", + "request": { + "schema_version": "inject-trigger-request/v1", + "request_key": "slot-key-1", + "occurrence_id": "handover-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:exercise-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.handover", + "bindings": [ + { + "binding": "orchestration.inject-binding.workstation.handover", + "instance": "workstation-1", + "revision": "realization-r3" + }, + { + "binding": "orchestration.inject-binding.workstation.handover", + "instance": "workstation-2", + "revision": "realization-r3" + } + ], + "placement": { + "kind": "schedule", + "event": "orchestration.event.shift-change", + "script": "orchestration.script.day-one", + "story": "orchestration.story.exercise", + "slot": "day-one/shift-change/1" + }, + "input_ref": { + "contract_id": "handover-input-v1", + "artifact_id": "handover-input-1", + "digest": "sha256:8888888888888888888888888888888888888888888888888888888888888888" + }, + "expected_head": "order-head-19" + }, + "admission": { + "actor_id": "scheduler-1", + "authorization_scope": [ + "role:operator" + ], + "target_scope": "target:reference", + "run_scope": "run:exercise-1", + "operation_kind": "orchestration", + "request_commitment": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "parent_operation_id": null + }, + "admission_evidence": [ + { + "contract_id": "proposition-truth-result-v1", + "artifact_id": "precondition-results-1", + "digest": "sha256:3333333333333333333333333333333333333333333333333333333333333333" + } + ], + "store_revision": "store-revision-41", + "order": { + "scope": "run:exercise-1", + "predecessor": "order-head-19", + "position": 20 + }, + "scenario": { + "contract_id": "instantiated-scenario-v1", + "artifact_id": "external-trigger-environment", + "digest": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "source": { + "contract_id": "associated-artifact-manifest-v1", + "artifact_id": "release-notice-source", + "digest": "sha256:5555555555555555555555555555555555555555555555555555555555555555" + }, + "realization": { + "contract_id": "backend-manifest-v2", + "artifact_id": "reference-realization", + "digest": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + }, + "evidence_requirements": [ + { + "contract_id": "runtime-snapshot-v1", + "artifact_id": "readback-requirement-1", + "digest": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + ] +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/ambiguous-instance.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/ambiguous-instance.json new file mode 100644 index 000000000..b74c4aad7 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/ambiguous-instance.json @@ -0,0 +1,31 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "instance": "host-1", + "revision": "realization-r1" + }, + { + "binding": "orchestration.inject-binding.host.release", + "instance": "host-1", + "revision": "realization-r0" + } + ], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/event-as-inject.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/event-as-inject.json new file mode 100644 index 000000000..c0b73f663 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/event-as-inject.json @@ -0,0 +1,26 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.event.gate", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/foreign-binding.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/foreign-binding.json new file mode 100644 index 000000000..85c46a71b --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/foreign-binding.json @@ -0,0 +1,26 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.prerelease", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/no-binding.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/no-binding.json new file mode 100644 index 000000000..d9d836c0c --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/no-binding.json @@ -0,0 +1,20 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/participant-binding.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/participant-binding.json new file mode 100644 index 000000000..d95512c07 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/participant-binding.json @@ -0,0 +1,27 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9", + "participant_address": "participant.analyst" +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/untyped-payload.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/untyped-payload.json new file mode 100644 index 000000000..a7f7d0ec4 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/untyped-payload.json @@ -0,0 +1,29 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9", + "payload": { + "script": "release.sh" + } +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/independent-binding.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/independent-binding.json new file mode 100644 index 000000000..aa5458a84 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/independent-binding.json @@ -0,0 +1,25 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "operator-reset-key-1", + "occurrence_id": "reset-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.reset-badge", + "bindings": [ + { + "binding": "orchestration.inject-binding.door-controller.reset-badge", + "instance": "door-controller-1", + "revision": "realization-r2" + } + ], + "placement": { + "kind": "independent" + }, + "input_ref": null, + "expected_head": "order-head-10" +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/participant-free-environment.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/participant-free-environment.json new file mode 100644 index 000000000..0e3d0af9b --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/participant-free-environment.json @@ -0,0 +1,26 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/scheduled-fan-out.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/scheduled-fan-out.json new file mode 100644 index 000000000..fce6209e6 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/scheduled-fan-out.json @@ -0,0 +1,38 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "slot-key-1", + "occurrence_id": "handover-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:exercise-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.handover", + "bindings": [ + { + "binding": "orchestration.inject-binding.workstation.handover", + "instance": "workstation-1", + "revision": "realization-r3" + }, + { + "binding": "orchestration.inject-binding.workstation.handover", + "instance": "workstation-2", + "revision": "realization-r3" + } + ], + "placement": { + "kind": "schedule", + "event": "orchestration.event.shift-change", + "script": "orchestration.script.day-one", + "story": "orchestration.story.exercise", + "slot": "day-one/shift-change/1" + }, + "input_ref": { + "contract_id": "handover-input-v1", + "artifact_id": "handover-input-1", + "digest": "sha256:8888888888888888888888888888888888888888888888888888888888888888" + }, + "expected_head": "order-head-19" +} diff --git a/contracts/schema-publication/entries/inject-occurrence-v1.json b/contracts/schema-publication/entries/inject-occurrence-v1.json new file mode 100644 index 000000000..598f9d1bf --- /dev/null +++ b/contracts/schema-publication/entries/inject-occurrence-v1.json @@ -0,0 +1,10 @@ +{ + "contract_id": "inject-occurrence-v1", + "schema_path": "contracts/schemas/control-plane/inject-occurrence-v1.json", + "stability": "draft", + "content_hash": "016883bcaec540ed4637e3e19f9d61e10801bb58ad7c0f40af48cbad1744fb3c", + "last_change": { + "summary": "Publish the ADR-112 claimed inject occurrence with actor-bound admission, unrebased order and distinct claims (#1423, #1366).", + "content_hash": "016883bcaec540ed4637e3e19f9d61e10801bb58ad7c0f40af48cbad1744fb3c" + } +} diff --git a/contracts/schema-publication/entries/inject-trigger-request-v1.json b/contracts/schema-publication/entries/inject-trigger-request-v1.json new file mode 100644 index 000000000..d6e1dece7 --- /dev/null +++ b/contracts/schema-publication/entries/inject-trigger-request-v1.json @@ -0,0 +1,10 @@ +{ + "contract_id": "inject-trigger-request-v1", + "schema_path": "contracts/schemas/control-plane/inject-trigger-request-v1.json", + "stability": "draft", + "content_hash": "ac147226ed5e38016ab85f287c1660fbbf8bedb57e11a148fd1e8c15234002b3", + "last_change": { + "summary": "Publish the ADR-112 inject trigger request with compiled bindings, closed placement and value-free input (#1423, #1366).", + "content_hash": "ac147226ed5e38016ab85f287c1660fbbf8bedb57e11a148fd1e8c15234002b3" + } +} diff --git a/contracts/schemas/control-plane/inject-occurrence-v1.json b/contracts/schemas/control-plane/inject-occurrence-v1.json new file mode 100644 index 000000000..551d7384a --- /dev/null +++ b/contracts/schemas/control-plane/inject-occurrence-v1.json @@ -0,0 +1,507 @@ +{ + "$defs": { + "InjectEventPlacementModel": { + "additionalProperties": false, + "description": "Event-anchored request; the event's precondition assertions remain binding.", + "properties": { + "event": { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "title": "Event", + "type": "string" + }, + "kind": { + "const": "event", + "default": "event", + "title": "Kind", + "type": "string" + } + }, + "required": [ + "event" + ], + "title": "InjectEventPlacementModel", + "type": "object" + }, + "InjectIndependentPlacementModel": { + "additionalProperties": false, + "description": "Direct request through an admitted independent binding; no schedule is invented.", + "properties": { + "kind": { + "const": "independent", + "default": "independent", + "title": "Kind", + "type": "string" + } + }, + "title": "InjectIndependentPlacementModel", + "type": "object" + }, + "InjectOrderModel": { + "additionalProperties": false, + "description": "Trusted ordering-authority token; neither arrival order nor a clock tick.", + "properties": { + "position": { + "maximum": 9007199254740991, + "minimum": 1, + "title": "Position", + "type": "integer" + }, + "predecessor": { + "maxLength": 256, + "minLength": 1, + "title": "Predecessor", + "type": "string" + }, + "scope": { + "maxLength": 256, + "minLength": 1, + "title": "Scope", + "type": "string" + } + }, + "required": [ + "scope", + "predecessor", + "position" + ], + "title": "InjectOrderModel", + "type": "object" + }, + "InjectSchedulePlacementModel": { + "additionalProperties": false, + "description": "One uniquely identified schedule slot, claimable at most once in its run.", + "properties": { + "event": { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "title": "Event", + "type": "string" + }, + "kind": { + "const": "schedule", + "default": "schedule", + "title": "Kind", + "type": "string" + }, + "script": { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "title": "Script", + "type": "string" + }, + "slot": { + "maxLength": 256, + "minLength": 1, + "title": "Slot", + "type": "string" + }, + "story": { + "anyOf": [ + { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Story" + } + }, + "required": [ + "event", + "script", + "slot" + ], + "title": "InjectSchedulePlacementModel", + "type": "object" + }, + "InjectTargetBindingModel": { + "additionalProperties": false, + "description": "One selected concrete realization instance; entity names never select hosts.", + "properties": { + "binding": { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "title": "Binding", + "type": "string" + }, + "instance": { + "maxLength": 256, + "minLength": 1, + "title": "Instance", + "type": "string" + }, + "revision": { + "maxLength": 256, + "minLength": 1, + "title": "Revision", + "type": "string" + } + }, + "required": [ + "binding", + "instance", + "revision" + ], + "title": "InjectTargetBindingModel", + "type": "object" + }, + "InjectTriggerRequestModel": { + "additionalProperties": false, + "description": "A caller's selection within admitted intent; acceptance is not an effect.", + "properties": { + "bindings": { + "items": { + "$ref": "#/$defs/InjectTargetBindingModel" + }, + "maxItems": 256, + "minItems": 1, + "title": "Bindings", + "type": "array" + }, + "expected_head": { + "maxLength": 256, + "minLength": 1, + "title": "Expected Head", + "type": "string" + }, + "inject": { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "title": "Inject", + "type": "string" + }, + "input_ref": { + "anyOf": [ + { + "$ref": "#/$defs/OperationArtifactReferenceModel" + }, + { + "type": "null" + } + ], + "default": null + }, + "occurrence_id": { + "maxLength": 256, + "minLength": 1, + "title": "Occurrence Id", + "type": "string" + }, + "placement": { + "discriminator": { + "mapping": { + "event": "#/$defs/InjectEventPlacementModel", + "independent": "#/$defs/InjectIndependentPlacementModel", + "schedule": "#/$defs/InjectSchedulePlacementModel" + }, + "propertyName": "kind" + }, + "oneOf": [ + { + "$ref": "#/$defs/InjectIndependentPlacementModel" + }, + { + "$ref": "#/$defs/InjectEventPlacementModel" + }, + { + "$ref": "#/$defs/InjectSchedulePlacementModel" + } + ], + "title": "Placement" + }, + "plan": { + "$ref": "#/$defs/OperationArtifactReferenceModel" + }, + "request_key": { + "maxLength": 256, + "minLength": 1, + "title": "Request Key", + "type": "string" + }, + "run_scope": { + "maxLength": 256, + "minLength": 1, + "title": "Run Scope", + "type": "string" + }, + "schema_version": { + "const": "inject-trigger-request/v1", + "default": "inject-trigger-request/v1", + "title": "Schema Version", + "type": "string" + }, + "target_scope": { + "maxLength": 256, + "minLength": 1, + "title": "Target Scope", + "type": "string" + } + }, + "required": [ + "request_key", + "occurrence_id", + "target_scope", + "run_scope", + "plan", + "inject", + "bindings", + "placement", + "expected_head" + ], + "title": "InjectTriggerRequestModel", + "type": "object" + }, + "OperationAdmissionContext": { + "additionalProperties": false, + "description": "Immutable, value-free authority and request context fixed at admission.", + "properties": { + "actor_id": { + "maxLength": 256, + "minLength": 1, + "title": "Actor Id", + "type": "string" + }, + "authorization_scope": { + "items": { + "maxLength": 256, + "minLength": 1, + "type": "string" + }, + "maxItems": 64, + "minItems": 1, + "title": "Authorization Scope", + "type": "array" + }, + "operation_kind": { + "$ref": "#/$defs/OperationKind" + }, + "parent_operation_id": { + "anyOf": [ + { + "maxLength": 256, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Parent Operation Id" + }, + "request_commitment": { + "pattern": "^sha256:[a-f0-9]{64}$", + "title": "Request Commitment", + "type": "string" + }, + "run_scope": { + "maxLength": 256, + "minLength": 1, + "title": "Run Scope", + "type": "string" + }, + "target_scope": { + "maxLength": 256, + "minLength": 1, + "title": "Target Scope", + "type": "string" + } + }, + "required": [ + "actor_id", + "authorization_scope", + "target_scope", + "run_scope", + "operation_kind", + "request_commitment" + ], + "title": "OperationAdmissionContext", + "type": "object" + }, + "OperationArtifactReferenceModel": { + "additionalProperties": false, + "description": "Content-bound reference resolved through the owning admitted artifact authority.", + "properties": { + "artifact_id": { + "maxLength": 256, + "minLength": 1, + "title": "Artifact Id", + "type": "string" + }, + "contract_id": { + "maxLength": 128, + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*-v[0-9]+$", + "title": "Contract Id", + "type": "string" + }, + "digest": { + "pattern": "^sha256:[a-f0-9]{64}$", + "title": "Digest", + "type": "string" + } + }, + "required": [ + "contract_id", + "artifact_id", + "digest" + ], + "title": "OperationArtifactReferenceModel", + "type": "object" + }, + "OperationKind": { + "description": "Closed kinds of work admitted by the runtime control plane.", + "enum": [ + "provisioning", + "orchestration", + "evaluation", + "workflow-cancellation", + "workflow-timeout-reconciliation", + "participant-action", + "participant-control", + "participant-crossing", + "composition-phase", + "indeterminate-resolution" + ], + "title": "OperationKind", + "type": "string" + } + }, + "$id": "https://openrae.github.io/rae/schemas/inject-occurrence-v1.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "description": "Atomic claim of one occurrence under exact admitted pins; not dispatch or outcome.", + "properties": { + "admission": { + "$ref": "#/$defs/OperationAdmissionContext" + }, + "admission_evidence": { + "items": { + "$ref": "#/$defs/OperationArtifactReferenceModel" + }, + "maxItems": 64, + "minItems": 1, + "title": "Admission Evidence", + "type": "array" + }, + "evidence_requirements": { + "items": { + "$ref": "#/$defs/OperationArtifactReferenceModel" + }, + "maxItems": 64, + "minItems": 1, + "title": "Evidence Requirements", + "type": "array" + }, + "operation_id": { + "maxLength": 256, + "minLength": 1, + "title": "Operation Id", + "type": "string" + }, + "order": { + "$ref": "#/$defs/InjectOrderModel" + }, + "realization": { + "$ref": "#/$defs/OperationArtifactReferenceModel" + }, + "request": { + "$ref": "#/$defs/InjectTriggerRequestModel" + }, + "scenario": { + "$ref": "#/$defs/OperationArtifactReferenceModel" + }, + "schema_version": { + "const": "inject-occurrence/v1", + "default": "inject-occurrence/v1", + "title": "Schema Version", + "type": "string" + }, + "source": { + "$ref": "#/$defs/OperationArtifactReferenceModel" + }, + "store_revision": { + "maxLength": 256, + "minLength": 1, + "title": "Store Revision", + "type": "string" + } + }, + "required": [ + "operation_id", + "request", + "admission", + "admission_evidence", + "store_revision", + "order", + "scenario", + "source", + "realization", + "evidence_requirements" + ], + "title": "InjectOccurrenceModel", + "type": "object", + "x-raes-invariants": [ + { + "description": "Validate compiled address families, bindings of the requested inject, unique selected instances, the orchestration admission context, unrebased order and distinct claim identities; structural validity grants no trigger authority.", + "id": "inject-occurrence-local-consistency", + "inputs": [ + { + "contract_id": "inject-occurrence-v1", + "instance_path": "#" + } + ], + "level": "error", + "validator": "raes_contracts.contracts.InjectOccurrenceModel.model_validate" + }, + { + "description": "Retry keys, occurrences, operations, schedule slots and order positions are each claimed at most once in one target/run store.", + "id": "inject-occurrence-unique-claims", + "inputs": [ + { + "contract_id": "inject-occurrence-v1", + "instance_path": "#" + } + ], + "level": "error", + "validator": "raes_contracts.contracts.validate_inject_occurrence_claims" + } + ], + "x-raes-semantic-profile": { + "contract_id": "inject-occurrence-v1", + "entry_schema_contract_id": "raes-semantic-invariants-v1", + "entry_schema_pointer": "#/$defs/RaesSemanticInvariantEntryModel", + "id": "raes-semantic-invariants-v1", + "keyword": "x-raes-invariants", + "required": true, + "uri": "https://openrae.github.io/rae/schemas/semantic-invariants/v1" + } +} diff --git a/contracts/schemas/control-plane/inject-trigger-request-v1.json b/contracts/schemas/control-plane/inject-trigger-request-v1.json new file mode 100644 index 000000000..53a456ed3 --- /dev/null +++ b/contracts/schemas/control-plane/inject-trigger-request-v1.json @@ -0,0 +1,322 @@ +{ + "$defs": { + "InjectEventPlacementModel": { + "additionalProperties": false, + "description": "Event-anchored request; the event's precondition assertions remain binding.", + "properties": { + "event": { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "title": "Event", + "type": "string" + }, + "kind": { + "const": "event", + "default": "event", + "title": "Kind", + "type": "string" + } + }, + "required": [ + "event" + ], + "title": "InjectEventPlacementModel", + "type": "object" + }, + "InjectIndependentPlacementModel": { + "additionalProperties": false, + "description": "Direct request through an admitted independent binding; no schedule is invented.", + "properties": { + "kind": { + "const": "independent", + "default": "independent", + "title": "Kind", + "type": "string" + } + }, + "title": "InjectIndependentPlacementModel", + "type": "object" + }, + "InjectSchedulePlacementModel": { + "additionalProperties": false, + "description": "One uniquely identified schedule slot, claimable at most once in its run.", + "properties": { + "event": { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "title": "Event", + "type": "string" + }, + "kind": { + "const": "schedule", + "default": "schedule", + "title": "Kind", + "type": "string" + }, + "script": { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "title": "Script", + "type": "string" + }, + "slot": { + "maxLength": 256, + "minLength": 1, + "title": "Slot", + "type": "string" + }, + "story": { + "anyOf": [ + { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Story" + } + }, + "required": [ + "event", + "script", + "slot" + ], + "title": "InjectSchedulePlacementModel", + "type": "object" + }, + "InjectTargetBindingModel": { + "additionalProperties": false, + "description": "One selected concrete realization instance; entity names never select hosts.", + "properties": { + "binding": { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "title": "Binding", + "type": "string" + }, + "instance": { + "maxLength": 256, + "minLength": 1, + "title": "Instance", + "type": "string" + }, + "revision": { + "maxLength": 256, + "minLength": 1, + "title": "Revision", + "type": "string" + } + }, + "required": [ + "binding", + "instance", + "revision" + ], + "title": "InjectTargetBindingModel", + "type": "object" + }, + "OperationArtifactReferenceModel": { + "additionalProperties": false, + "description": "Content-bound reference resolved through the owning admitted artifact authority.", + "properties": { + "artifact_id": { + "maxLength": 256, + "minLength": 1, + "title": "Artifact Id", + "type": "string" + }, + "contract_id": { + "maxLength": 128, + "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*-v[0-9]+$", + "title": "Contract Id", + "type": "string" + }, + "digest": { + "pattern": "^sha256:[a-f0-9]{64}$", + "title": "Digest", + "type": "string" + } + }, + "required": [ + "contract_id", + "artifact_id", + "digest" + ], + "title": "OperationArtifactReferenceModel", + "type": "object" + } + }, + "$id": "https://openrae.github.io/rae/schemas/inject-trigger-request-v1.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "description": "A caller's selection within admitted intent; acceptance is not an effect.", + "properties": { + "bindings": { + "items": { + "$ref": "#/$defs/InjectTargetBindingModel" + }, + "maxItems": 256, + "minItems": 1, + "title": "Bindings", + "type": "array" + }, + "expected_head": { + "maxLength": 256, + "minLength": 1, + "title": "Expected Head", + "type": "string" + }, + "inject": { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "title": "Inject", + "type": "string" + }, + "input_ref": { + "anyOf": [ + { + "$ref": "#/$defs/OperationArtifactReferenceModel" + }, + { + "type": "null" + } + ], + "default": null + }, + "occurrence_id": { + "maxLength": 256, + "minLength": 1, + "title": "Occurrence Id", + "type": "string" + }, + "placement": { + "discriminator": { + "mapping": { + "event": "#/$defs/InjectEventPlacementModel", + "independent": "#/$defs/InjectIndependentPlacementModel", + "schedule": "#/$defs/InjectSchedulePlacementModel" + }, + "propertyName": "kind" + }, + "oneOf": [ + { + "$ref": "#/$defs/InjectIndependentPlacementModel" + }, + { + "$ref": "#/$defs/InjectEventPlacementModel" + }, + { + "$ref": "#/$defs/InjectSchedulePlacementModel" + } + ], + "title": "Placement" + }, + "plan": { + "$ref": "#/$defs/OperationArtifactReferenceModel" + }, + "request_key": { + "maxLength": 256, + "minLength": 1, + "title": "Request Key", + "type": "string" + }, + "run_scope": { + "maxLength": 256, + "minLength": 1, + "title": "Run Scope", + "type": "string" + }, + "schema_version": { + "const": "inject-trigger-request/v1", + "default": "inject-trigger-request/v1", + "title": "Schema Version", + "type": "string" + }, + "target_scope": { + "maxLength": 256, + "minLength": 1, + "title": "Target Scope", + "type": "string" + } + }, + "required": [ + "request_key", + "occurrence_id", + "target_scope", + "run_scope", + "plan", + "inject", + "bindings", + "placement", + "expected_head" + ], + "title": "InjectTriggerRequestModel", + "type": "object", + "x-raes-invariants": [ + { + "description": "Validate compiled address families, bindings of the requested inject, unique selected instances, the orchestration admission context, unrebased order and distinct claim identities; structural validity grants no trigger authority.", + "id": "inject-occurrence-local-consistency", + "inputs": [ + { + "contract_id": "inject-trigger-request-v1", + "instance_path": "#" + } + ], + "level": "error", + "validator": "raes_contracts.contracts.InjectTriggerRequestModel.model_validate" + }, + { + "description": "Only the original actor, key and request commitment retrieve the original claim; changed content conflicts and no retry admits, rebases or dispatches again.", + "id": "inject-trigger-exact-retry", + "inputs": [ + { + "contract_id": "inject-occurrence-v1", + "instance_path": "#" + }, + { + "contract_id": "inject-trigger-request-v1", + "instance_path": "#" + } + ], + "level": "error", + "validator": "raes_contracts.contracts.require_inject_trigger_retry" + } + ], + "x-raes-semantic-profile": { + "contract_id": "inject-trigger-request-v1", + "entry_schema_contract_id": "raes-semantic-invariants-v1", + "entry_schema_pointer": "#/$defs/RaesSemanticInvariantEntryModel", + "id": "raes-semantic-invariants-v1", + "keyword": "x-raes-invariants", + "required": true, + "uri": "https://openrae.github.io/rae/schemas/semantic-invariants/v1" + } +} diff --git a/docs/explain/reference/inject-occurrence-contracts.md b/docs/explain/reference/inject-occurrence-contracts.md new file mode 100644 index 000000000..bb97d3411 --- /dev/null +++ b/docs/explain/reference/inject-occurrence-contracts.md @@ -0,0 +1,95 @@ +# Use the inject trigger and occurrence contracts + +[ADR-112](../../decisions/adrs/adr-112-external-inject-triggering-and-execution.md) +and [EI-01–EI-06](../../../specs/sdl/external-injects.md) define how an +authorized external request instantiates one authored inject. The draft +`inject-trigger-request-v1` and `inject-occurrence-v1` contracts carry those +identities as portable data with pure validators. They add no trigger route, +store, scheduler or backend call, and the existing runtime does not accept them. + +Import the models and helpers from `raes_contracts.contracts`. The schemas are +under `contracts/schemas/control-plane/` and the examples under +`contracts/fixtures/control-plane/inject-*`. + +## Request + +`InjectTriggerRequestModel` is a caller's selection within admitted intent. + +| Field | Meaning | +| --- | --- | +| `request_key` | Client retry key. The ADR-104 store scopes it by actor and operation kind in one target/run store (EI-02). | +| `occurrence_id` | Fresh logical occurrence. A repeat needs a fresh occurrence and a fresh key. | +| `target_scope`, `run_scope` | The exact target and run. | +| `plan` | Content-bound pin of the compiled `orchestration-plan-v1`. | +| `inject` | Canonical `orchestration.inject.*` address. A request names one inject, not a whole event. | +| `bindings` | One or more selected concrete bindings: compiled binding address, realization instance and revision. An `orchestration.inject-binding.*` address must name the requested inject. Each instance appears once; nothing selects every host or the first matching name. | +| `placement` | `independent`, `event` (the event's assertions stay binding) or `schedule` (event, script, optional story and a slot that can be claimed once). | +| `input_ref` | Optional content-bound reference to an input document that the realization's input contract checks. There are no inline values, and absence means no runtime parameters. | +| `expected_head` | The ordering head the caller observed. A stale head is refused, never rebased. | + +## Occurrence + +`InjectOccurrenceModel` records the atomic claim (EI-03). It holds the exact +request, the runtime `operation_id`, the actor-bound `OperationAdmissionContext`, +admission evidence, the expected store revision, the trusted order token, and +the scenario, source, realization and required-evidence pins. Local validation +requires that: + +- the admission context is an `orchestration` operation for the requested + target and run; +- the order token's scope is the requested run and its predecessor is the + requested head; +- the request key, occurrence, operation and slot are distinct values. + +This revision admits inject occurrences only as orchestration operations. +Another operation kind needs a new contract revision with lifecycle, audit, +store and recovery agreement. + +## Retries and duplicate claims + +| Situation | Helper and result | +| --- | --- | +| Same actor, key and request commitment | `require_inject_trigger_retry` returns the original claim. Nothing is admitted or dispatched again. | +| Changed content, another actor, or another key for the same claim | `require_inject_trigger_retry` raises a conflict. Authorize receipt access before the lookup, so a conflict reveals no other actor's claim. | +| A reused retry key, occurrence, operation, schedule slot or order position in one store | `validate_inject_occurrence_claims` rejects the claim set. | +| A fresh key and fresh occurrence for the same inject | Valid; admission checks every current constraint again. | + +`inject_trigger_request_digest` and `inject_occurrence_digest` return RFC 8785 +commitments. + +## Participant-free example + +This environment declares no agents, behaviors, scripts or stories, and the +existing parser and compiler accept it: + +```yaml +name: external-trigger-environment +nodes: + host: + type: compute + resources: {ram: 1 gib, cpu: 1} + roles: + operator: ops + injects: + release: operator +injects: + release: + description: Release the staged maintenance notice. +events: + gate: + injects: [release] +``` + +Each `participant-free-environment.json` fixture triggers `release` against +`orchestration.inject-binding.host.release`, anchored to `gate`. The caller is +an authenticated operator, not a participant or controller. +`test_issue_1423_inject_occurrence_contracts.py` compiles this environment and +checks that the fixture names only its compiled identities. + +## Limits + +Fixture digests, scopes and evidence references are synthetic. Structural and +local validation grant no trigger authority and prove no effect. +Authentication, admission, ordering, claims, dispatch and outcome evidence +belong to the runtime and backend adoption that the +[compatibility contract](../sdl/external-inject-compatibility.md) describes. diff --git a/docs/public/api/contracts.rst b/docs/public/api/contracts.rst index 7f255bb2f..cb8ab5500 100644 --- a/docs/public/api/contracts.rst +++ b/docs/public/api/contracts.rst @@ -60,6 +60,15 @@ constraints. The provenance record preserves the participant implementation, selected manifest, selected configuration reference, participant contract versions, and decision-surface exposure policy used in a run. +External inject triggers and occurrences +---------------------------------------- + +Draft ADR-112 carriers for an external inject request and its claimed occurrence. +They grant no trigger authority and do not execute an inject. + +.. automodule:: raes_contracts.contracts.inject_occurrence + :members: + Backend operation supervision ----------------------------- diff --git a/implementations/python/packages/raes_contracts/contracts/__init__.py b/implementations/python/packages/raes_contracts/contracts/__init__.py index faf1d61a3..d8bc6e784 100644 --- a/implementations/python/packages/raes_contracts/contracts/__init__.py +++ b/implementations/python/packages/raes_contracts/contracts/__init__.py @@ -33,6 +33,7 @@ from ._candidate_synthesis_facade import * from ._evidence_requirement_exports import * from ._exports import PUBLIC_EXPORTS as __all__ +from ._inject_occurrence_exports import * from ._participant_control_exports import * from ._version_exports import * from .admitted_trial_plan import AdmittedApparatusBindingModel as AdmittedApparatusBindingModel diff --git a/implementations/python/packages/raes_contracts/contracts/_exports.py b/implementations/python/packages/raes_contracts/contracts/_exports.py index 86d8a4651..4fa175a43 100644 --- a/implementations/python/packages/raes_contracts/contracts/_exports.py +++ b/implementations/python/packages/raes_contracts/contracts/_exports.py @@ -3,6 +3,7 @@ from ._backend_operation_exports import BACKEND_OPERATION_EXPORTS from ._candidate_synthesis_exports import CANDIDATE_SYNTHESIS_EXPORTS from ._execution_policy_exports import EXECUTION_POLICY_EXPORTS +from ._inject_occurrence_exports import INJECT_OCCURRENCE_EXPORTS from ._mixed_composition_exports import MIXED_COMPOSITION_EXPORTS from ._participant_control_exports import PARTICIPANT_CONTROL_EXPORTS from ._runtime_fact_exports import RUNTIME_FACT_EXPORTS @@ -10,6 +11,7 @@ PUBLIC_EXPORTS = [ *EXECUTION_POLICY_EXPORTS, *BACKEND_OPERATION_EXPORTS, + *INJECT_OCCURRENCE_EXPORTS, *PARTICIPANT_CONTROL_EXPORTS, *MIXED_COMPOSITION_EXPORTS, "MaterializationArchiveRecord", diff --git a/implementations/python/packages/raes_contracts/contracts/_inject_occurrence_exports.py b/implementations/python/packages/raes_contracts/contracts/_inject_occurrence_exports.py new file mode 100644 index 000000000..e4e864138 --- /dev/null +++ b/implementations/python/packages/raes_contracts/contracts/_inject_occurrence_exports.py @@ -0,0 +1,36 @@ +"""Inject trigger and occurrence facade exports (ADR-112); claims, never execution.""" + +from ..versions import INJECT_OCCURRENCE_SCHEMA_VERSION, INJECT_TRIGGER_REQUEST_SCHEMA_VERSION +from .inject_occurrence import ( + InjectEventPlacementModel, + InjectIndependentPlacementModel, + InjectOccurrenceModel, + InjectOrderModel, + InjectSchedulePlacementModel, + InjectTargetBindingModel, + InjectTriggerRequestModel, + inject_occurrence_digest, + inject_retry_key, + inject_trigger_request_digest, + require_inject_trigger_retry, + validate_inject_occurrence_claims, +) + +__all__ = [ + "INJECT_TRIGGER_REQUEST_SCHEMA_VERSION", + "INJECT_OCCURRENCE_SCHEMA_VERSION", + "InjectEventPlacementModel", + "InjectIndependentPlacementModel", + "InjectOccurrenceModel", + "InjectOrderModel", + "InjectSchedulePlacementModel", + "InjectTargetBindingModel", + "InjectTriggerRequestModel", + "inject_occurrence_digest", + "inject_retry_key", + "inject_trigger_request_digest", + "require_inject_trigger_retry", + "validate_inject_occurrence_claims", +] + +INJECT_OCCURRENCE_EXPORTS = __all__ diff --git a/implementations/python/packages/raes_contracts/contracts/bundle_runtime.py b/implementations/python/packages/raes_contracts/contracts/bundle_runtime.py index c0cb8a142..be9fa25b4 100644 --- a/implementations/python/packages/raes_contracts/contracts/bundle_runtime.py +++ b/implementations/python/packages/raes_contracts/contracts/bundle_runtime.py @@ -8,6 +8,7 @@ from .backend_operation_schema import backend_operation_schema_bundle from .execution_state import EvaluationHistoryEventModel from .experiment_bindings import ParticipantConfigurationResultModel +from .inject_occurrence_schema import inject_occurrence_schema_bundle from .operation_carriers import OperationReceiptModel, OperationStatusModel from .participant_context import ParticipantContextViewModel from .participant_control import ParticipantControlOccurrenceModel @@ -95,6 +96,7 @@ def _participant_control_schema_bundle() -> dict[str, dict[str, Any]]: def _runtime_schema_bundle() -> dict[str, dict[str, Any]]: return { **backend_operation_schema_bundle(), + **inject_occurrence_schema_bundle(), **_participant_control_schema_bundle(), "evaluation-history-event-stream-v1": _event_stream_schema( "EvaluationHistoryEventStream", diff --git a/implementations/python/packages/raes_contracts/contracts/inject_occurrence.py b/implementations/python/packages/raes_contracts/contracts/inject_occurrence.py new file mode 100644 index 000000000..71d198b3b --- /dev/null +++ b/implementations/python/packages/raes_contracts/contracts/inject_occurrence.py @@ -0,0 +1,206 @@ +"""ADR-112 inject trigger requests and claimed occurrences; neither executes an effect.""" + +from __future__ import annotations + +from collections.abc import Sequence +from typing import Annotated, Literal, Self + +from pydantic import Field, model_validator + +from ..addressing import CompiledAddress +from ..canonical import canonical_json_digest +from ..operation_lifecycle import OperationAdmissionContext, OperationKind +from ..versions import INJECT_OCCURRENCE_SCHEMA_VERSION, INJECT_TRIGGER_REQUEST_SCHEMA_VERSION +from .backend_operation import ( + OperationArtifactReferenceModel, + OperationContractModel, + OperationIdentifier, + OperationPositive, +) + +_MAX_CLAIMS = 1024 +_CLAIM_CONFLICT = "inject trigger retry conflicts with the original claim" + + +def _require_family(address: str, family: str) -> None: + if not address.startswith(f"orchestration.{family}."): + raise ValueError(f"inject trigger requires a compiled orchestration {family} address") + + +def _require_binding_of(inject: str, binding: str) -> None: + """A compiled node binding renders as ``orchestration.inject-binding..``.""" + + prefix = "orchestration.inject-binding." + if binding.startswith(prefix) and not binding.endswith("." + inject.removeprefix("orchestration.inject.")): + raise ValueError("inject trigger bindings must belong to the requested inject") + + +class InjectTargetBindingModel(OperationContractModel): + """One selected concrete realization instance; entity names never select hosts.""" + + binding: CompiledAddress + instance: OperationIdentifier + revision: OperationIdentifier + + +class InjectIndependentPlacementModel(OperationContractModel): + """Direct request through an admitted independent binding; no schedule is invented.""" + + kind: Literal["independent"] = "independent" + + +class InjectEventPlacementModel(OperationContractModel): + """Event-anchored request; the event's precondition assertions remain binding.""" + + kind: Literal["event"] = "event" + event: CompiledAddress + + @model_validator(mode="after") + def _event(self) -> Self: + _require_family(self.event, "event") + return self + + +class InjectSchedulePlacementModel(OperationContractModel): + """One uniquely identified schedule slot, claimable at most once in its run.""" + + kind: Literal["schedule"] = "schedule" + event: CompiledAddress + script: CompiledAddress + story: CompiledAddress | None = None + slot: OperationIdentifier + + @model_validator(mode="after") + def _schedule(self) -> Self: + _require_family(self.event, "event") + _require_family(self.script, "script") + if self.story is not None: + _require_family(self.story, "story") + return self + + +InjectPlacement = Annotated[ + InjectIndependentPlacementModel | InjectEventPlacementModel | InjectSchedulePlacementModel, + Field(discriminator="kind"), +] + + +class InjectTriggerRequestModel(OperationContractModel): + """A caller's selection within admitted intent; acceptance is not an effect.""" + + schema_version: Literal[INJECT_TRIGGER_REQUEST_SCHEMA_VERSION] = INJECT_TRIGGER_REQUEST_SCHEMA_VERSION + request_key: OperationIdentifier + occurrence_id: OperationIdentifier + target_scope: OperationIdentifier + run_scope: OperationIdentifier + plan: OperationArtifactReferenceModel + inject: CompiledAddress + bindings: tuple[InjectTargetBindingModel, ...] = Field(min_length=1, max_length=256) + placement: InjectPlacement + input_ref: OperationArtifactReferenceModel | None = None + expected_head: OperationIdentifier + + @model_validator(mode="after") + def _selection(self) -> Self: + _require_family(self.inject, "inject") + if self.plan.contract_id != "orchestration-plan-v1": + raise ValueError("inject trigger must pin its compiled orchestration plan") + for binding in self.bindings: + _require_binding_of(self.inject, binding.binding) + instances = [(binding.binding, binding.instance) for binding in self.bindings] + if len(instances) != len(set(instances)): + raise ValueError("inject trigger cannot select one realization instance twice") + return self + + +class InjectOrderModel(OperationContractModel): + """Trusted ordering-authority token; neither arrival order nor a clock tick.""" + + scope: OperationIdentifier + predecessor: OperationIdentifier + position: OperationPositive + + +class InjectOccurrenceModel(OperationContractModel): + """Atomic claim of one occurrence under exact admitted pins; not dispatch or outcome.""" + + schema_version: Literal[INJECT_OCCURRENCE_SCHEMA_VERSION] = INJECT_OCCURRENCE_SCHEMA_VERSION + operation_id: OperationIdentifier + request: InjectTriggerRequestModel + admission: OperationAdmissionContext + admission_evidence: tuple[OperationArtifactReferenceModel, ...] = Field(min_length=1, max_length=64) + store_revision: OperationIdentifier + order: InjectOrderModel + scenario: OperationArtifactReferenceModel + source: OperationArtifactReferenceModel + realization: OperationArtifactReferenceModel + evidence_requirements: tuple[OperationArtifactReferenceModel, ...] = Field(min_length=1, max_length=64) + + @model_validator(mode="after") + def _claim(self) -> Self: + request, admission = self.request, self.admission + if admission.operation_kind is not OperationKind.ORCHESTRATION: + raise ValueError("inject occurrences are admitted as orchestration operations") + if (admission.target_scope, admission.run_scope) != (request.target_scope, request.run_scope): + raise ValueError("inject occurrence admission must bind the requested target and run") + if (self.order.scope, self.order.predecessor) != (request.run_scope, request.expected_head): + raise ValueError("inject order must follow the requested run head without rebasing") + identities = [request.request_key, request.occurrence_id, self.operation_id, *_slot(self)] + if len(identities) != len(set(identities)): + raise ValueError("request key, occurrence, operation and slot identities must stay distinct") + return self + + +def _slot(occurrence: InjectOccurrenceModel) -> tuple[str, ...]: + placement = occurrence.request.placement + return (placement.slot,) if isinstance(placement, InjectSchedulePlacementModel) else () + + +def inject_trigger_request_digest(request: InjectTriggerRequestModel) -> str: + return canonical_json_digest(request.model_dump(mode="json")) + + +def inject_occurrence_digest(occurrence: InjectOccurrenceModel) -> str: + return canonical_json_digest(occurrence.model_dump(mode="json")) + + +def inject_retry_key(occurrence: InjectOccurrenceModel) -> tuple[str, str, str]: + """Return the ADR-104 scoped retry identity: actor, operation kind and client key.""" + + admission = occurrence.admission + return admission.actor_id, admission.operation_kind.value, occurrence.request.request_key + + +def require_inject_trigger_retry( + occurrence: InjectOccurrenceModel, request: InjectTriggerRequestModel, *, actor_id: str +) -> InjectOccurrenceModel: + """Return the original claim for an exact retry; never admit, rebase or dispatch again. + + Callers authorize receipt access before any lookup, so a conflict reveals no + other actor's claim. Changed content under the same key is a conflict. + """ + + if (actor_id, request.request_key) != (occurrence.admission.actor_id, occurrence.request.request_key): + raise ValueError(_CLAIM_CONFLICT) + if inject_trigger_request_digest(request) != inject_trigger_request_digest(occurrence.request): + raise ValueError(_CLAIM_CONFLICT) + return occurrence + + +def validate_inject_occurrence_claims(occurrences: Sequence[InjectOccurrenceModel]) -> None: + """Reject reuse of a retry key, occurrence, operation, schedule slot or order position.""" + + if len(occurrences) > _MAX_CLAIMS: + raise ValueError("inject occurrence claim set exceeds its bound") + if len({(item.request.target_scope, item.request.run_scope) for item in occurrences}) > 1: + raise ValueError("inject occurrence claims must share one target/run store") + claims = { + "retry key": [inject_retry_key(item) for item in occurrences], + "occurrence": [item.request.occurrence_id for item in occurrences], + "operation": [item.operation_id for item in occurrences], + "order position": [item.order.position for item in occurrences], + "schedule slot": [slot for item in occurrences for slot in _slot(item)], + } + for label, values in claims.items(): + if len(values) != len(set(values)): + raise ValueError(f"inject occurrence {label} is already claimed") diff --git a/implementations/python/packages/raes_contracts/contracts/inject_occurrence_schema.py b/implementations/python/packages/raes_contracts/contracts/inject_occurrence_schema.py new file mode 100644 index 000000000..27a44dbad --- /dev/null +++ b/implementations/python/packages/raes_contracts/contracts/inject_occurrence_schema.py @@ -0,0 +1,44 @@ +"""Published inject trigger/occurrence schemas and their semantic validation bindings.""" + +from __future__ import annotations + +from typing import Any + +from .inject_occurrence import InjectOccurrenceModel, InjectTriggerRequestModel +from .schema_invariants import _add_raes_invariant + +_REQUEST = {"contract_id": "inject-trigger-request-v1", "instance_path": "#"} +_OCCURRENCE = {"contract_id": "inject-occurrence-v1", "instance_path": "#"} + + +def inject_occurrence_schema_bundle() -> dict[str, dict[str, Any]]: + schemas = {} + for inputs, model in ((_REQUEST, InjectTriggerRequestModel), (_OCCURRENCE, InjectOccurrenceModel)): + schema = model.model_json_schema() + _add_raes_invariant( + schema, + "inject-occurrence-local-consistency", + "Validate compiled address families, bindings of the requested inject, unique selected instances, the " + "orchestration admission context, unrebased order and distinct claim identities; structural validity " + "grants no trigger authority.", + validator=f"raes_contracts.contracts.{model.__name__}.model_validate", + inputs=[inputs], + ) + schemas[inputs["contract_id"]] = schema + _add_raes_invariant( + schemas["inject-trigger-request-v1"], + "inject-trigger-exact-retry", + "Only the original actor, key and request commitment retrieve the original claim; changed content conflicts " + "and no retry admits, rebases or dispatches again.", + validator="raes_contracts.contracts.require_inject_trigger_retry", + inputs=[_OCCURRENCE, _REQUEST], + ) + _add_raes_invariant( + schemas["inject-occurrence-v1"], + "inject-occurrence-unique-claims", + "Retry keys, occurrences, operations, schedule slots and order positions are each claimed at most once " + "in one target/run store.", + validator="raes_contracts.contracts.validate_inject_occurrence_claims", + inputs=[_OCCURRENCE], + ) + return schemas diff --git a/implementations/python/packages/raes_contracts/versions.py b/implementations/python/packages/raes_contracts/versions.py index 6619fbf3b..eb2587354 100644 --- a/implementations/python/packages/raes_contracts/versions.py +++ b/implementations/python/packages/raes_contracts/versions.py @@ -35,6 +35,8 @@ WORKFLOW_STATE_SCHEMA_VERSION = "workflow-step-state/v1" WORKFLOW_CANCELLATION_REQUEST_SCHEMA_VERSION = "workflow-cancellation-request/v1" RUNTIME_SNAPSHOT_SCHEMA_VERSION = "runtime-snapshot/v1" +INJECT_TRIGGER_REQUEST_SCHEMA_VERSION = "inject-trigger-request/v1" +INJECT_OCCURRENCE_SCHEMA_VERSION = "inject-occurrence/v1" OPERATION_SCHEMA_VERSION = "runtime-operation/v1" BACKEND_OPERATION_REQUEST_SCHEMA_VERSION = "backend-operation-request/v1" BACKEND_OPERATION_CAPABILITIES_SCHEMA_VERSION = "backend-operation-capabilities/v1" diff --git a/implementations/python/tests/test_issue_1423_inject_occurrence_contracts.py b/implementations/python/tests/test_issue_1423_inject_occurrence_contracts.py new file mode 100644 index 000000000..ce5847051 --- /dev/null +++ b/implementations/python/tests/test_issue_1423_inject_occurrence_contracts.py @@ -0,0 +1,263 @@ +"""ADR-112 inject trigger requests and claimed occurrences: structure, claims and retries.""" + +from __future__ import annotations + +import json +from pathlib import Path + +import pytest +from jsonschema import Draft202012Validator +from pydantic import ValidationError +from raes.parser import parse_sdl +from raes_contracts import contracts +from raes_processor.compiler import compile_runtime_model + +ROOT = Path(__file__).resolve().parents[3] +FIXTURES = ROOT / "contracts/fixtures/control-plane" +MODELS = { + "inject-trigger-request-v1": contracts.InjectTriggerRequestModel, + "inject-occurrence-v1": contracts.InjectOccurrenceModel, +} +CORPUS = [ + (contract_id, category, path.stem) + for contract_id in MODELS + for category in ("valid", "invalid", "context-invalid") + for path in sorted((FIXTURES / contract_id / category).glob("*.json")) +] +ENVIRONMENT_SDL = """name: external-trigger-environment +nodes: + host: + type: compute + resources: {ram: 1 gib, cpu: 1} + roles: + operator: ops + injects: + release: operator +injects: + release: + description: Release the staged maintenance notice. +events: + gate: + injects: [release] +""" + + +def fixture(contract_id: str, category: str, name: str) -> dict: + return json.loads((FIXTURES / contract_id / category / f"{name}.json").read_text()) + + +def schema(contract_id: str) -> dict: + return json.loads((ROOT / f"contracts/schemas/control-plane/{contract_id}.json").read_text()) + + +def occurrence(name: str = "participant-free-environment") -> contracts.InjectOccurrenceModel: + return contracts.InjectOccurrenceModel.model_validate(fixture("inject-occurrence-v1", "valid", name)) + + +def fresh( + base: contracts.InjectOccurrenceModel, *, actor: str | None = None, **claims +) -> contracts.InjectOccurrenceModel: + """Return another claim on the same authored intent with the given claim identities.""" + payload = base.model_dump(mode="json") + payload["request"]["request_key"] = claims.get("key", base.request.request_key) + payload["request"]["occurrence_id"] = claims.get("occurrence", base.request.occurrence_id) + payload["operation_id"] = claims.get("operation", base.operation_id) + payload["order"]["position"] = claims.get("position", base.order.position) + payload["admission"]["actor_id"] = actor or base.admission.actor_id + return contracts.InjectOccurrenceModel.model_validate(payload) + + +def changed(payload: dict, path: tuple[str, ...], value: object) -> dict: + target = payload + for key in path[:-1]: + target = target[key] + target[path[-1]] = value + return payload + + +@pytest.mark.parametrize(("contract_id", "category", "name"), CORPUS) +def test_fixture_corpus_separates_structure_from_contextual_claims(contract_id, category, name): + payload = fixture(contract_id, category, name) + model = MODELS[contract_id] + + assert Draft202012Validator(schema(contract_id)).is_valid(payload) is (category != "invalid") + if category == "valid": + assert model.model_validate(payload).model_dump(mode="json") == payload + else: + with pytest.raises(ValidationError): + model.model_validate(payload) + + +def test_published_schemas_are_the_reference_bundle_with_semantic_bindings(): + bundle = contracts.schema_bundle() + for contract_id in MODELS: + published = schema(contract_id) + assert published == bundle[contract_id] + assert published["x-raes-semantic-profile"]["required"] is True + validators = {item["validator"] for item in bundle["inject-occurrence-v1"]["x-raes-invariants"]} + assert "raes_contracts.contracts.validate_inject_occurrence_claims" in validators + + +def _property_names(node: object) -> set[str]: + if isinstance(node, dict): + names = set(node.get("properties", {})) + return names.union(*(_property_names(value) for value in node.values())) + if isinstance(node, list): + return set().union(*(_property_names(value) for value in node)) + return set() + + +def test_participant_free_environment_trigger_names_only_compiled_orchestration_identities(): + model = compile_runtime_model(parse_sdl(ENVIRONMENT_SDL)) + claim = occurrence() + request = claim.request + + assert not model.diagnostics + assert not (model.agent_specs or model.participant_behaviors or model.participant_inject_deliveries) + assert request.inject in model.injects + assert {binding.binding for binding in request.bindings} <= set(model.inject_bindings) + assert request.inject in model.events[request.placement.event].inject_addresses + names = _property_names(schema("inject-occurrence-v1")) + assert not [name for name in names if any(word in name for word in ("participant", "episode", "control"))] + + +def test_exact_retry_returns_the_original_claim_without_a_new_admission(): + claim = occurrence() + retry = contracts.InjectTriggerRequestModel.model_validate(claim.request.model_dump(mode="json")) + + assert contracts.require_inject_trigger_retry(claim, retry, actor_id="researcher-1") is claim + + +@pytest.mark.parametrize( + ("actor_id", "path", "value"), + [ + pytest.param("researcher-2", ("expected_head",), "order-head-9", id="another-actor"), + pytest.param("researcher-1", ("request_key",), "researcher-release-key-2", id="another-key"), + pytest.param("researcher-1", ("occurrence_id",), "release-occurrence-2", id="another-occurrence"), + pytest.param("researcher-1", ("expected_head",), "order-head-10", id="changed-cut"), + pytest.param("researcher-1", ("bindings", 0, "instance"), "host-2", id="changed-target"), + pytest.param( + "researcher-1", + ("input_ref",), + {"contract_id": "release-input-v1", "artifact_id": "input-1", "digest": "sha256:" + "9" * 64}, + id="changed-input", + ), + ], +) +def test_changed_actor_key_or_content_conflicts_with_the_original_claim(actor_id, path, value): + claim = occurrence() + retry = contracts.InjectTriggerRequestModel.model_validate( + changed(claim.request.model_dump(mode="json"), path, value) + ) + + with pytest.raises(ValueError, match="conflicts with the original claim"): + contracts.require_inject_trigger_retry(claim, retry, actor_id=actor_id) + + +def test_fresh_key_and_occurrence_may_repeat_the_same_authored_inject(): + first = occurrence() + repeat = fresh( + first, key="researcher-release-key-2", occurrence="release-occurrence-2", operation="op-2", position=11 + ) + + contracts.validate_inject_occurrence_claims([first, repeat]) + assert contracts.inject_retry_key(repeat) != contracts.inject_retry_key(first) + + +@pytest.mark.parametrize( + ("label", "actor", "claims"), + [ + ("retry key", None, {"occurrence": "release-occurrence-2", "operation": "op-2", "position": 11}), + ("occurrence", "researcher-2", {"key": "researcher-release-key-2", "operation": "op-2", "position": 11}), + ("operation", None, {"key": "researcher-release-key-2", "occurrence": "release-occurrence-2", "position": 11}), + ("order position", None, {"key": "key-2", "occurrence": "release-occurrence-2", "operation": "op-2"}), + ], +) +def test_claim_set_rejects_a_reused_claim_identity(label, actor, claims): + first = occurrence() + claim_set = [first, fresh(first, actor=actor, **claims)] + + with pytest.raises(ValueError, match=f"{label} is already claimed"): + contracts.validate_inject_occurrence_claims(claim_set) + + +def test_a_consumed_schedule_slot_cannot_be_claimed_under_fresh_names(): + first = occurrence("scheduled-fan-out") + claim_set = [ + first, + fresh(first, key="slot-key-2", occurrence="handover-occurrence-2", operation="op-2", position=21), + ] + + with pytest.raises(ValueError, match="schedule slot is already claimed"): + contracts.validate_inject_occurrence_claims(claim_set) + + +def test_claim_sets_stay_within_one_bounded_target_run_store(): + other_run = occurrence("scheduled-fan-out") + claim_set = [occurrence(), other_run] + oversized = [occurrence()] * 1025 + + with pytest.raises(ValueError, match="one target/run store"): + contracts.validate_inject_occurrence_claims(claim_set) + with pytest.raises(ValueError, match="exceeds its bound"): + contracts.validate_inject_occurrence_claims(oversized) + + +@pytest.mark.parametrize( + ("path", "value", "message"), + [ + (("plan", "contract_id"), "provisioning-plan-v1", "orchestration plan"), + (("bindings", 0, "binding"), "orchestration.inject-binding.host.prerelease", "belong to the requested inject"), + (("placement",), {"kind": "event", "event": "orchestration.script.day-one"}, "event address"), + ( + ("placement",), + {"kind": "schedule", "event": "orchestration.event.gate", "script": "orchestration.story.s", "slot": "1"}, + "script address", + ), + ( + ("placement",), + { + "kind": "schedule", + "event": "orchestration.event.gate", + "script": "orchestration.script.s", + "story": "orchestration.event.gate", + "slot": "1", + }, + "story address", + ), + ], +) +def test_request_requires_the_compiled_plan_and_narrative_address_families(path, value, message): + payload = changed(fixture("inject-trigger-request-v1", "valid", "participant-free-environment"), path, value) + + with pytest.raises(ValidationError, match=message): + contracts.InjectTriggerRequestModel.model_validate(payload) + + +@pytest.mark.parametrize( + ("path", "value", "message"), + [ + (("admission", "target_scope"), "target:other", "requested target and run"), + (("admission", "run_scope"), "run:other", "requested target and run"), + (("order", "scope"), "run:other", "without rebasing"), + (("operation_id",), "day-one/shift-change/1", "must stay distinct"), + ], +) +def test_occurrence_binds_admission_order_and_distinct_identities(path, value, message): + payload = changed(fixture("inject-occurrence-v1", "valid", "scheduled-fan-out"), path, value) + + with pytest.raises(ValidationError, match=message): + contracts.InjectOccurrenceModel.model_validate(payload) + + +def test_commitments_are_canonical_and_cover_the_selected_targets(): + claim = occurrence("scheduled-fan-out") + narrowed = contracts.InjectTriggerRequestModel.model_validate( + {**claim.request.model_dump(mode="json"), "bindings": [claim.request.bindings[0].model_dump(mode="json")]} + ) + + assert contracts.inject_trigger_request_digest(claim.request).startswith("sha256:") + assert contracts.inject_trigger_request_digest(narrowed) != contracts.inject_trigger_request_digest(claim.request) + assert contracts.inject_occurrence_digest(claim) == contracts.inject_occurrence_digest( + occurrence("scheduled-fan-out") + ) From 0521d9c5865fd2a1333a790189c0921fa6c8d605 Mon Sep 17 00:00:00 2001 From: Yernat Yestekov <2068106+doublewhy@users.noreply.github.com> Date: Fri, 9 Oct 2026 02:21:45 -0700 Subject: [PATCH 4/9] docs(contracts): append the inject API section after backend operation supervision Keep the end-of-file placement agreed with the parallel mixed-backend contracts work, which inserts its section before the backend operation supervision section. --- docs/public/api/contracts.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/public/api/contracts.rst b/docs/public/api/contracts.rst index cb8ab5500..43c6c85ba 100644 --- a/docs/public/api/contracts.rst +++ b/docs/public/api/contracts.rst @@ -60,15 +60,6 @@ constraints. The provenance record preserves the participant implementation, selected manifest, selected configuration reference, participant contract versions, and decision-surface exposure policy used in a run. -External inject triggers and occurrences ----------------------------------------- - -Draft ADR-112 carriers for an external inject request and its claimed occurrence. -They grant no trigger authority and do not execute an inject. - -.. automodule:: raes_contracts.contracts.inject_occurrence - :members: - Backend operation supervision ----------------------------- @@ -86,3 +77,12 @@ The shared runtime retains authorization, scenario execution and terminal state. .. automodule:: raes_backend_protocols.operation_supervision :members: + +External inject triggers and occurrences +---------------------------------------- + +Draft ADR-112 carriers for an external inject request and its claimed occurrence. +They grant no trigger authority and do not execute an inject. + +.. automodule:: raes_contracts.contracts.inject_occurrence + :members: From 74a4fc112fc6b98ac1d510be8f05b2d034880157 Mon Sep 17 00:00:00 2001 From: Yernat Yestekov <2068106+doublewhy@users.noreply.github.com> Date: Fri, 9 Oct 2026 02:26:14 -0700 Subject: [PATCH 5/9] test(contracts): split the participant-free composite assertion SonarCloud python:S9073 flags the combined participant-free check; assert each compiled participant family separately. --- .../tests/test_issue_1423_inject_occurrence_contracts.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/implementations/python/tests/test_issue_1423_inject_occurrence_contracts.py b/implementations/python/tests/test_issue_1423_inject_occurrence_contracts.py index ce5847051..d4091ada6 100644 --- a/implementations/python/tests/test_issue_1423_inject_occurrence_contracts.py +++ b/implementations/python/tests/test_issue_1423_inject_occurrence_contracts.py @@ -113,7 +113,9 @@ def test_participant_free_environment_trigger_names_only_compiled_orchestration_ request = claim.request assert not model.diagnostics - assert not (model.agent_specs or model.participant_behaviors or model.participant_inject_deliveries) + assert not model.agent_specs + assert not model.participant_behaviors + assert not model.participant_inject_deliveries assert request.inject in model.injects assert {binding.binding for binding in request.bindings} <= set(model.inject_bindings) assert request.inject in model.events[request.placement.event].inject_addresses From f0215beecd728c8941b6bfd520ac0c4827aaf81a Mon Sep 17 00:00:00 2001 From: Yernat Yestekov <2068106+doublewhy@users.noreply.github.com> Date: Fri, 9 Oct 2026 07:13:44 -0700 Subject: [PATCH 6/9] fix(contracts): render inject bindings from their node and claim each order head once Module namespaces put dots inside node and inject names, so an address suffix cannot show which inject a binding serves. Each selected binding now carries its compiled provision.node address, and its address must equal the compiler's rendering of that node and the requested inject. A claim set now rejects two claims that follow the same order head. The fixture corpus test asserts each context-invalid fixture's reason, and each schema states its own local-consistency invariant. --- .../context-invalid/provisioning-kind.json | 1 + .../context-invalid/rebased-order.json | 1 + .../context-invalid/shared-identity.json | 1 + .../invalid/missing-admission.json | 1 + .../valid/participant-free-environment.json | 1 + .../valid/scheduled-fan-out.json | 2 + .../context-invalid/ambiguous-instance.json | 2 + .../context-invalid/event-as-inject.json | 1 + .../context-invalid/foreign-binding.json | 1 + .../context-invalid/namespaced-binding.json | 27 +++++ .../invalid/participant-binding.json | 1 + .../invalid/untyped-payload.json | 1 + .../valid/independent-binding.json | 1 + .../valid/participant-free-environment.json | 1 + .../valid/scheduled-fan-out.json | 2 + .../entries/inject-occurrence-v1.json | 4 +- .../entries/inject-trigger-request-v1.json | 6 +- .../control-plane/inject-occurrence-v1.json | 17 +++- .../inject-trigger-request-v1.json | 17 +++- .../reference/inject-occurrence-contracts.md | 45 +++++++-- .../contracts/inject_occurrence.py | 53 ++++++---- .../contracts/inject_occurrence_schema.py | 31 ++++-- ..._issue_1423_inject_occurrence_contracts.py | 98 +++++++++++++++++-- 23 files changed, 263 insertions(+), 52 deletions(-) create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/namespaced-binding.json diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/provisioning-kind.json b/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/provisioning-kind.json index 921523ff3..f5e6abc12 100644 --- a/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/provisioning-kind.json +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/provisioning-kind.json @@ -16,6 +16,7 @@ "bindings": [ { "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", "instance": "host-1", "revision": "realization-r1" } diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/rebased-order.json b/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/rebased-order.json index dd383cc98..76b1a26f1 100644 --- a/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/rebased-order.json +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/rebased-order.json @@ -16,6 +16,7 @@ "bindings": [ { "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", "instance": "host-1", "revision": "realization-r1" } diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/shared-identity.json b/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/shared-identity.json index 654b900a5..77d12fedb 100644 --- a/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/shared-identity.json +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/context-invalid/shared-identity.json @@ -16,6 +16,7 @@ "bindings": [ { "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", "instance": "host-1", "revision": "realization-r1" } diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-admission.json b/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-admission.json index 9988a19e3..295cec10f 100644 --- a/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-admission.json +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-admission.json @@ -16,6 +16,7 @@ "bindings": [ { "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", "instance": "host-1", "revision": "realization-r1" } diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/valid/participant-free-environment.json b/contracts/fixtures/control-plane/inject-occurrence-v1/valid/participant-free-environment.json index e8dd8213a..30c8f146f 100644 --- a/contracts/fixtures/control-plane/inject-occurrence-v1/valid/participant-free-environment.json +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/valid/participant-free-environment.json @@ -16,6 +16,7 @@ "bindings": [ { "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", "instance": "host-1", "revision": "realization-r1" } diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/valid/scheduled-fan-out.json b/contracts/fixtures/control-plane/inject-occurrence-v1/valid/scheduled-fan-out.json index 020aff24f..035c1240b 100644 --- a/contracts/fixtures/control-plane/inject-occurrence-v1/valid/scheduled-fan-out.json +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/valid/scheduled-fan-out.json @@ -16,11 +16,13 @@ "bindings": [ { "binding": "orchestration.inject-binding.workstation.handover", + "node": "provision.node.workstation", "instance": "workstation-1", "revision": "realization-r3" }, { "binding": "orchestration.inject-binding.workstation.handover", + "node": "provision.node.workstation", "instance": "workstation-2", "revision": "realization-r3" } diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/ambiguous-instance.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/ambiguous-instance.json index b74c4aad7..5f5fa1a8b 100644 --- a/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/ambiguous-instance.json +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/ambiguous-instance.json @@ -13,11 +13,13 @@ "bindings": [ { "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", "instance": "host-1", "revision": "realization-r1" }, { "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", "instance": "host-1", "revision": "realization-r0" } diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/event-as-inject.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/event-as-inject.json index c0b73f663..e7b2d187d 100644 --- a/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/event-as-inject.json +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/event-as-inject.json @@ -13,6 +13,7 @@ "bindings": [ { "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", "instance": "host-1", "revision": "realization-r1" } diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/foreign-binding.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/foreign-binding.json index 85c46a71b..f7fbc0de7 100644 --- a/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/foreign-binding.json +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/foreign-binding.json @@ -13,6 +13,7 @@ "bindings": [ { "binding": "orchestration.inject-binding.host.prerelease", + "node": "provision.node.host", "instance": "host-1", "revision": "realization-r1" } diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/namespaced-binding.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/namespaced-binding.json new file mode 100644 index 000000000..f88bc6da7 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/context-invalid/namespaced-binding.json @@ -0,0 +1,27 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.mod.host.mod.release", + "node": "provision.node.mod.host", + "instance": "mod-host-1", + "revision": "realization-r1" + } + ], + "placement": { + "kind": "event", + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/participant-binding.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/participant-binding.json index d95512c07..47b4bca23 100644 --- a/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/participant-binding.json +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/participant-binding.json @@ -13,6 +13,7 @@ "bindings": [ { "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", "instance": "host-1", "revision": "realization-r1" } diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/untyped-payload.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/untyped-payload.json index a7f7d0ec4..3095cf376 100644 --- a/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/untyped-payload.json +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/untyped-payload.json @@ -13,6 +13,7 @@ "bindings": [ { "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", "instance": "host-1", "revision": "realization-r1" } diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/independent-binding.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/independent-binding.json index aa5458a84..97708eda4 100644 --- a/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/independent-binding.json +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/independent-binding.json @@ -13,6 +13,7 @@ "bindings": [ { "binding": "orchestration.inject-binding.door-controller.reset-badge", + "node": "provision.node.door-controller", "instance": "door-controller-1", "revision": "realization-r2" } diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/participant-free-environment.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/participant-free-environment.json index 0e3d0af9b..a89c4ee97 100644 --- a/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/participant-free-environment.json +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/participant-free-environment.json @@ -13,6 +13,7 @@ "bindings": [ { "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", "instance": "host-1", "revision": "realization-r1" } diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/scheduled-fan-out.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/scheduled-fan-out.json index fce6209e6..c40eea2e5 100644 --- a/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/scheduled-fan-out.json +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/valid/scheduled-fan-out.json @@ -13,11 +13,13 @@ "bindings": [ { "binding": "orchestration.inject-binding.workstation.handover", + "node": "provision.node.workstation", "instance": "workstation-1", "revision": "realization-r3" }, { "binding": "orchestration.inject-binding.workstation.handover", + "node": "provision.node.workstation", "instance": "workstation-2", "revision": "realization-r3" } diff --git a/contracts/schema-publication/entries/inject-occurrence-v1.json b/contracts/schema-publication/entries/inject-occurrence-v1.json index 598f9d1bf..fe0adf079 100644 --- a/contracts/schema-publication/entries/inject-occurrence-v1.json +++ b/contracts/schema-publication/entries/inject-occurrence-v1.json @@ -2,9 +2,9 @@ "contract_id": "inject-occurrence-v1", "schema_path": "contracts/schemas/control-plane/inject-occurrence-v1.json", "stability": "draft", - "content_hash": "016883bcaec540ed4637e3e19f9d61e10801bb58ad7c0f40af48cbad1744fb3c", + "content_hash": "019f648c5501b339a7e37997d91c06d49d879f8c15757d901a3c052bb36abc62", "last_change": { "summary": "Publish the ADR-112 claimed inject occurrence with actor-bound admission, unrebased order and distinct claims (#1423, #1366).", - "content_hash": "016883bcaec540ed4637e3e19f9d61e10801bb58ad7c0f40af48cbad1744fb3c" + "content_hash": "019f648c5501b339a7e37997d91c06d49d879f8c15757d901a3c052bb36abc62" } } diff --git a/contracts/schema-publication/entries/inject-trigger-request-v1.json b/contracts/schema-publication/entries/inject-trigger-request-v1.json index d6e1dece7..35ca8a0cd 100644 --- a/contracts/schema-publication/entries/inject-trigger-request-v1.json +++ b/contracts/schema-publication/entries/inject-trigger-request-v1.json @@ -2,9 +2,9 @@ "contract_id": "inject-trigger-request-v1", "schema_path": "contracts/schemas/control-plane/inject-trigger-request-v1.json", "stability": "draft", - "content_hash": "ac147226ed5e38016ab85f287c1660fbbf8bedb57e11a148fd1e8c15234002b3", + "content_hash": "23f5f644bc570b8224eed543a7cc1d24f6596e2425a097b540162e41ee3a330c", "last_change": { - "summary": "Publish the ADR-112 inject trigger request with compiled bindings, closed placement and value-free input (#1423, #1366).", - "content_hash": "ac147226ed5e38016ab85f287c1660fbbf8bedb57e11a148fd1e8c15234002b3" + "summary": "Publish the ADR-112 inject trigger request with compiled node bindings, closed placement and value-free input (#1423, #1366).", + "content_hash": "23f5f644bc570b8224eed543a7cc1d24f6596e2425a097b540162e41ee3a330c" } } diff --git a/contracts/schemas/control-plane/inject-occurrence-v1.json b/contracts/schemas/control-plane/inject-occurrence-v1.json index 551d7384a..e90a84eff 100644 --- a/contracts/schemas/control-plane/inject-occurrence-v1.json +++ b/contracts/schemas/control-plane/inject-occurrence-v1.json @@ -137,7 +137,7 @@ }, "InjectTargetBindingModel": { "additionalProperties": false, - "description": "One selected concrete realization instance; entity names never select hosts.", + "description": "One selected realization instance of a compiled node binding; entity names never select hosts.", "properties": { "binding": { "maxLength": 2048, @@ -155,6 +155,16 @@ "title": "Instance", "type": "string" }, + "node": { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "title": "Node", + "type": "string" + }, "revision": { "maxLength": 256, "minLength": 1, @@ -164,6 +174,7 @@ }, "required": [ "binding", + "node", "instance", "revision" ], @@ -471,7 +482,7 @@ "type": "object", "x-raes-invariants": [ { - "description": "Validate compiled address families, bindings of the requested inject, unique selected instances, the orchestration admission context, unrebased order and distinct claim identities; structural validity grants no trigger authority.", + "description": "Validate the embedded request, an orchestration admission context for its target and run, an order token whose scope is that run and whose predecessor is the requested head, and distinct request key, occurrence, operation and slot identities; structural validity grants no trigger authority.", "id": "inject-occurrence-local-consistency", "inputs": [ { @@ -483,7 +494,7 @@ "validator": "raes_contracts.contracts.InjectOccurrenceModel.model_validate" }, { - "description": "Retry keys, occurrences, operations, schedule slots and order positions are each claimed at most once in one target/run store.", + "description": "Retry keys, occurrences, operations, schedule slots, order positions and order predecessors are each claimed at most once in one target/run store, so no two claims follow the same head; head tokens are opaque, so the head chain itself is not checked.", "id": "inject-occurrence-unique-claims", "inputs": [ { diff --git a/contracts/schemas/control-plane/inject-trigger-request-v1.json b/contracts/schemas/control-plane/inject-trigger-request-v1.json index 53a456ed3..94e1b6418 100644 --- a/contracts/schemas/control-plane/inject-trigger-request-v1.json +++ b/contracts/schemas/control-plane/inject-trigger-request-v1.json @@ -106,7 +106,7 @@ }, "InjectTargetBindingModel": { "additionalProperties": false, - "description": "One selected concrete realization instance; entity names never select hosts.", + "description": "One selected realization instance of a compiled node binding; entity names never select hosts.", "properties": { "binding": { "maxLength": 2048, @@ -124,6 +124,16 @@ "title": "Instance", "type": "string" }, + "node": { + "maxLength": 2048, + "minLength": 3, + "not": { + "pattern": "[^a-z0-9_.-]" + }, + "pattern": "^(?:[a-z0-9][a-z0-9_-]{0,63}|__private)(?:\\.(?:[a-z0-9][a-z0-9_-]{0,63}|__private))+$", + "title": "Node", + "type": "string" + }, "revision": { "maxLength": 256, "minLength": 1, @@ -133,6 +143,7 @@ }, "required": [ "binding", + "node", "instance", "revision" ], @@ -282,8 +293,8 @@ "type": "object", "x-raes-invariants": [ { - "description": "Validate compiled address families, bindings of the requested inject, unique selected instances, the orchestration admission context, unrebased order and distinct claim identities; structural validity grants no trigger authority.", - "id": "inject-occurrence-local-consistency", + "description": "Validate compiled inject, node, event, script and story address families, the pinned orchestration plan, binding addresses rendered exactly from their node and the requested inject, and unique binding/instance pairs; structural validity grants no trigger authority and does not resolve bindings against the plan.", + "id": "inject-trigger-request-local-consistency", "inputs": [ { "contract_id": "inject-trigger-request-v1", diff --git a/docs/explain/reference/inject-occurrence-contracts.md b/docs/explain/reference/inject-occurrence-contracts.md index bb97d3411..4d1fb2f02 100644 --- a/docs/explain/reference/inject-occurrence-contracts.md +++ b/docs/explain/reference/inject-occurrence-contracts.md @@ -22,11 +22,31 @@ under `contracts/schemas/control-plane/` and the examples under | `target_scope`, `run_scope` | The exact target and run. | | `plan` | Content-bound pin of the compiled `orchestration-plan-v1`. | | `inject` | Canonical `orchestration.inject.*` address. A request names one inject, not a whole event. | -| `bindings` | One or more selected concrete bindings: compiled binding address, realization instance and revision. An `orchestration.inject-binding.*` address must name the requested inject. Each instance appears once; nothing selects every host or the first matching name. | +| `bindings` | One or more selected compiled node bindings. Each names its `orchestration.inject-binding.*` address, the compiled `provision.node.*` node it binds, a realization instance and its revision. Each binding/instance pair appears once; nothing selects every host or the first matching name. | | `placement` | `independent`, `event` (the event's assertions stay binding) or `schedule` (event, script, optional story and a slot that can be claimed once). | | `input_ref` | Optional content-bound reference to an input document that the realization's input contract checks. There are no inline values, and absence means no runtime parameters. | | `expected_head` | The ordering head the caller observed. A stale head is refused, never rebased. | +### Binding addresses + +The compiler renders a node binding as +`orchestration.inject-binding..`, and module namespaces put dots +inside both names. When a scenario imports a module under namespace `mod`, +`orchestration.inject-binding.mod.host.mod.release` binds node `mod.host` to +inject `mod.release`, yet it also ends in `.release`. The end of an address +therefore doesn't show which inject it binds. + +Local validation requires each binding address to equal the rendering of its +`node` and the requested inject. Carrying node `provision.node.mod.host`, that +binding can't serve a request for `release`. Local validation can't see the +plan, so it doesn't show that the node exists or that the plan records this node +for the binding. A consumer resolves both against the pinned plan's +`inject-binding` operations. + +This revision selects only `Node.injects` bindings. Under EI-01, a top-level +inject without `Node.injects` runs only through its realization's explicit target +contract, which this revision doesn't carry. + ## Occurrence `InjectOccurrenceModel` records the atomic claim (EI-03). It holds the exact @@ -51,9 +71,14 @@ store and recovery agreement. | --- | --- | | Same actor, key and request commitment | `require_inject_trigger_retry` returns the original claim. Nothing is admitted or dispatched again. | | Changed content, another actor, or another key for the same claim | `require_inject_trigger_retry` raises a conflict. Authorize receipt access before the lookup, so a conflict reveals no other actor's claim. | -| A reused retry key, occurrence, operation, schedule slot or order position in one store | `validate_inject_occurrence_claims` rejects the claim set. | +| A reused retry key, occurrence, operation, schedule slot, order position or order predecessor in one store | `validate_inject_occurrence_claims` rejects the claim set. | | A fresh key and fresh occurrence for the same inject | Valid; admission checks every current constraint again. | +Two claims that follow the same head would fork the run's order, so each +predecessor is claimed once. Head tokens are opaque, so the claim set can't +check that a predecessor is the head that the preceding claim produced. That +chain belongs to the ordering authority (EI-03). + `inject_trigger_request_digest` and `inject_occurrence_digest` return RFC 8785 commitments. @@ -81,15 +106,19 @@ events: ``` Each `participant-free-environment.json` fixture triggers `release` against -`orchestration.inject-binding.host.release`, anchored to `gate`. The caller is -an authenticated operator, not a participant or controller. -`test_issue_1423_inject_occurrence_contracts.py` compiles this environment and -checks that the fixture names only its compiled identities. +`orchestration.inject-binding.host.release` on node `provision.node.host`, +anchored to `gate`. The caller is an authenticated operator, not a participant +or controller. `test_issue_1423_inject_occurrence_contracts.py` compiles this +environment and checks that the fixture names only its compiled identities. It +also imports the same environment under namespace `mod` and checks that each +compiled binding serves only its own inject. The `namespaced-binding.json` +fixture is the refused case. ## Limits Fixture digests, scopes and evidence references are synthetic. Structural and local validation grant no trigger authority and prove no effect. -Authentication, admission, ordering, claims, dispatch and outcome evidence -belong to the runtime and backend adoption that the +Authentication, admission, binding resolution against the pinned plan, +ordering, claims, dispatch and outcome evidence belong to the runtime and +backend adoption that the [compatibility contract](../sdl/external-inject-compatibility.md) describes. diff --git a/implementations/python/packages/raes_contracts/contracts/inject_occurrence.py b/implementations/python/packages/raes_contracts/contracts/inject_occurrence.py index 71d198b3b..ec7c119a2 100644 --- a/implementations/python/packages/raes_contracts/contracts/inject_occurrence.py +++ b/implementations/python/packages/raes_contracts/contracts/inject_occurrence.py @@ -7,7 +7,7 @@ from pydantic import Field, model_validator -from ..addressing import CompiledAddress +from ..addressing import CompiledAddress, render_compiled_address from ..canonical import canonical_json_digest from ..operation_lifecycle import OperationAdmissionContext, OperationKind from ..versions import INJECT_OCCURRENCE_SCHEMA_VERSION, INJECT_TRIGGER_REQUEST_SCHEMA_VERSION @@ -22,26 +22,36 @@ _CLAIM_CONFLICT = "inject trigger retry conflicts with the original claim" -def _require_family(address: str, family: str) -> None: - if not address.startswith(f"orchestration.{family}."): - raise ValueError(f"inject trigger requires a compiled orchestration {family} address") +def _require_family(address: str, family: str, root: str = "orchestration") -> str: + """Return the compiled name after ``..``; module namespaces keep their dots.""" - -def _require_binding_of(inject: str, binding: str) -> None: - """A compiled node binding renders as ``orchestration.inject-binding..``.""" - - prefix = "orchestration.inject-binding." - if binding.startswith(prefix) and not binding.endswith("." + inject.removeprefix("orchestration.inject.")): - raise ValueError("inject trigger bindings must belong to the requested inject") + prefix = f"{root}.{family}." + if not address.startswith(prefix): + raise ValueError(f"inject trigger requires a compiled {root} {family} address") + return address.removeprefix(prefix) class InjectTargetBindingModel(OperationContractModel): - """One selected concrete realization instance; entity names never select hosts.""" + """One selected realization instance of a compiled node binding; entity names never select hosts.""" binding: CompiledAddress + node: CompiledAddress instance: OperationIdentifier revision: OperationIdentifier + @model_validator(mode="after") + def _node(self) -> Self: + _require_family(self.node, "node", "provision") + return self + + +def _require_binding_of(item: InjectTargetBindingModel, inject: str) -> None: + """Dots inside namespaced names make a suffix ambiguous; only the compiler's exact rendering counts.""" + + node = item.node.removeprefix("provision.node.") + if item.binding != render_compiled_address("orchestration", "inject-binding", node, inject): + raise ValueError("inject trigger binding must be the compiled binding of its node and the requested inject") + class InjectIndependentPlacementModel(OperationContractModel): """Direct request through an admitted independent binding; no schedule is invented.""" @@ -102,14 +112,14 @@ class InjectTriggerRequestModel(OperationContractModel): @model_validator(mode="after") def _selection(self) -> Self: - _require_family(self.inject, "inject") + inject = _require_family(self.inject, "inject") if self.plan.contract_id != "orchestration-plan-v1": raise ValueError("inject trigger must pin its compiled orchestration plan") - for binding in self.bindings: - _require_binding_of(self.inject, binding.binding) - instances = [(binding.binding, binding.instance) for binding in self.bindings] - if len(instances) != len(set(instances)): - raise ValueError("inject trigger cannot select one realization instance twice") + for item in self.bindings: + _require_binding_of(item, inject) + pairs = [(item.binding, item.instance) for item in self.bindings] + if len(pairs) != len(set(pairs)): + raise ValueError("inject trigger cannot select one binding/instance pair twice") return self @@ -188,7 +198,11 @@ def require_inject_trigger_retry( def validate_inject_occurrence_claims(occurrences: Sequence[InjectOccurrenceModel]) -> None: - """Reject reuse of a retry key, occurrence, operation, schedule slot or order position.""" + """Reject reuse of a retry key, occurrence, operation, schedule slot, order position or predecessor. + + Two claims that follow one head fork the run's order. Head tokens are opaque, so this + cannot check that a predecessor is the head that the preceding claim produced. + """ if len(occurrences) > _MAX_CLAIMS: raise ValueError("inject occurrence claim set exceeds its bound") @@ -199,6 +213,7 @@ def validate_inject_occurrence_claims(occurrences: Sequence[InjectOccurrenceMode "occurrence": [item.request.occurrence_id for item in occurrences], "operation": [item.operation_id for item in occurrences], "order position": [item.order.position for item in occurrences], + "order predecessor": [item.order.predecessor for item in occurrences], "schedule slot": [slot for item in occurrences for slot in _slot(item)], } for label, values in claims.items(): diff --git a/implementations/python/packages/raes_contracts/contracts/inject_occurrence_schema.py b/implementations/python/packages/raes_contracts/contracts/inject_occurrence_schema.py index 27a44dbad..464a15b5c 100644 --- a/implementations/python/packages/raes_contracts/contracts/inject_occurrence_schema.py +++ b/implementations/python/packages/raes_contracts/contracts/inject_occurrence_schema.py @@ -9,18 +9,34 @@ _REQUEST = {"contract_id": "inject-trigger-request-v1", "instance_path": "#"} _OCCURRENCE = {"contract_id": "inject-occurrence-v1", "instance_path": "#"} +_LOCAL = ( + ( + _REQUEST, + InjectTriggerRequestModel, + "inject-trigger-request-local-consistency", + "Validate compiled inject, node, event, script and story address families, the pinned orchestration plan, " + "binding addresses rendered exactly from their node and the requested inject, and unique binding/instance " + "pairs; structural validity grants no trigger authority and does not resolve bindings against the plan.", + ), + ( + _OCCURRENCE, + InjectOccurrenceModel, + "inject-occurrence-local-consistency", + "Validate the embedded request, an orchestration admission context for its target and run, an order token " + "whose scope is that run and whose predecessor is the requested head, and distinct request key, occurrence, " + "operation and slot identities; structural validity grants no trigger authority.", + ), +) def inject_occurrence_schema_bundle() -> dict[str, dict[str, Any]]: schemas = {} - for inputs, model in ((_REQUEST, InjectTriggerRequestModel), (_OCCURRENCE, InjectOccurrenceModel)): + for inputs, model, invariant_id, description in _LOCAL: schema = model.model_json_schema() _add_raes_invariant( schema, - "inject-occurrence-local-consistency", - "Validate compiled address families, bindings of the requested inject, unique selected instances, the " - "orchestration admission context, unrebased order and distinct claim identities; structural validity " - "grants no trigger authority.", + invariant_id, + description, validator=f"raes_contracts.contracts.{model.__name__}.model_validate", inputs=[inputs], ) @@ -36,8 +52,9 @@ def inject_occurrence_schema_bundle() -> dict[str, dict[str, Any]]: _add_raes_invariant( schemas["inject-occurrence-v1"], "inject-occurrence-unique-claims", - "Retry keys, occurrences, operations, schedule slots and order positions are each claimed at most once " - "in one target/run store.", + "Retry keys, occurrences, operations, schedule slots, order positions and order predecessors are each claimed " + "at most once in one target/run store, so no two claims follow the same head; head tokens are opaque, so the " + "head chain itself is not checked.", validator="raes_contracts.contracts.validate_inject_occurrence_claims", inputs=[_OCCURRENCE], ) diff --git a/implementations/python/tests/test_issue_1423_inject_occurrence_contracts.py b/implementations/python/tests/test_issue_1423_inject_occurrence_contracts.py index d4091ada6..d120e5ba7 100644 --- a/implementations/python/tests/test_issue_1423_inject_occurrence_contracts.py +++ b/implementations/python/tests/test_issue_1423_inject_occurrence_contracts.py @@ -3,12 +3,13 @@ from __future__ import annotations import json +from itertools import product from pathlib import Path import pytest from jsonschema import Draft202012Validator from pydantic import ValidationError -from raes.parser import parse_sdl +from raes.parser import parse_sdl, parse_sdl_file from raes_contracts import contracts from raes_processor.compiler import compile_runtime_model @@ -24,6 +25,20 @@ for category in ("valid", "invalid", "context-invalid") for path in sorted((FIXTURES / contract_id / category).glob("*.json")) ] +OWNERSHIP = "its node and the requested inject" +# Each context-invalid fixture breaks one rule, so it must be refused for that rule's reason. +CONTEXT_REASONS = { + "ambiguous-instance": "binding/instance pair twice", + "event-as-inject": "compiled orchestration inject address", + "foreign-binding": OWNERSHIP, + "namespaced-binding": OWNERSHIP, + "provisioning-kind": "admitted as orchestration operations", + "rebased-order": "without rebasing", + "shared-identity": "must stay distinct", +} +# Importing the environment below under namespace ``mod`` compiles a second binding ending in ``.release``. +MODULE_HEADER = "module: {id: acme/release, version: 1.0.0, exports: {nodes: [host], injects: [release]}}\n" +IMPORT_HEADER = "imports: [{source: 'local:module.yaml', namespace: mod}]\n" ENVIRONMENT_SDL = """name: external-trigger-environment nodes: host: @@ -57,12 +72,18 @@ def occurrence(name: str = "participant-free-environment") -> contracts.InjectOc def fresh( base: contracts.InjectOccurrenceModel, *, actor: str | None = None, **claims ) -> contracts.InjectOccurrenceModel: - """Return another claim on the same authored intent with the given claim identities.""" + """Return another claim on the same authored intent with the given claim identities. + + As in the fixtures, position N follows head ``order-head-`` unless ``head`` names another. + """ payload = base.model_dump(mode="json") + position = claims.get("position", base.order.position) + head = claims.get("head", f"order-head-{position - 1}") payload["request"]["request_key"] = claims.get("key", base.request.request_key) payload["request"]["occurrence_id"] = claims.get("occurrence", base.request.occurrence_id) + payload["request"]["expected_head"] = head payload["operation_id"] = claims.get("operation", base.operation_id) - payload["order"]["position"] = claims.get("position", base.order.position) + payload["order"].update(position=position, predecessor=head) payload["admission"]["actor_id"] = actor or base.admission.actor_id return contracts.InjectOccurrenceModel.model_validate(payload) @@ -84,7 +105,8 @@ def test_fixture_corpus_separates_structure_from_contextual_claims(contract_id, if category == "valid": assert model.model_validate(payload).model_dump(mode="json") == payload else: - with pytest.raises(ValidationError): + reason = CONTEXT_REASONS[name] if category == "context-invalid" else None + with pytest.raises(ValidationError, match=reason): model.model_validate(payload) @@ -117,12 +139,48 @@ def test_participant_free_environment_trigger_names_only_compiled_orchestration_ assert not model.participant_behaviors assert not model.participant_inject_deliveries assert request.inject in model.injects - assert {binding.binding for binding in request.bindings} <= set(model.inject_bindings) + assert {(item.binding, item.node) for item in request.bindings} <= { + (address, binding.node_address) for address, binding in model.inject_bindings.items() + } assert request.inject in model.events[request.placement.event].inject_addresses names = _property_names(schema("inject-occurrence-v1")) assert not [name for name in names if any(word in name for word in ("participant", "episode", "control"))] +def _with_header(header: str) -> str: + name, body = ENVIRONMENT_SDL.split("\n", 1) + return f"{name}\n{header}{body}" + + +def _selects(inject: str, binding) -> bool: + payload = fixture("inject-trigger-request-v1", "valid", "participant-free-environment") + payload["inject"] = inject + payload["bindings"] = [ + {"binding": binding.address, "node": binding.node_address, "instance": "host-1", "revision": "realization-r1"} + ] + try: + contracts.InjectTriggerRequestModel.model_validate(payload) + except ValidationError as error: + assert OWNERSHIP in str(error) + return False + return True + + +def test_module_namespaces_cannot_borrow_another_injects_binding(tmp_path): + (tmp_path / "module.yaml").write_text(_with_header(MODULE_HEADER)) + (tmp_path / "root.yaml").write_text(_with_header(IMPORT_HEADER)) + model = compile_runtime_model(parse_sdl_file(tmp_path / "root.yaml")) + bindings = model.inject_bindings.values() + + assert not model.diagnostics + assert sorted(model.inject_bindings) == [ + "orchestration.inject-binding.host.release", + "orchestration.inject-binding.mod.host.mod.release", + ] + selected = {(inject, item.address) for inject, item in product(model.injects, bindings) if _selects(inject, item)} + assert selected == {(item.spec["inject_address"], item.address) for item in bindings} + + def test_exact_retry_returns_the_original_claim_without_a_new_admission(): claim = occurrence() retry = contracts.InjectTriggerRequestModel.model_validate(claim.request.model_dump(mode="json")) @@ -172,7 +230,22 @@ def test_fresh_key_and_occurrence_may_repeat_the_same_authored_inject(): ("retry key", None, {"occurrence": "release-occurrence-2", "operation": "op-2", "position": 11}), ("occurrence", "researcher-2", {"key": "researcher-release-key-2", "operation": "op-2", "position": 11}), ("operation", None, {"key": "researcher-release-key-2", "occurrence": "release-occurrence-2", "position": 11}), - ("order position", None, {"key": "key-2", "occurrence": "release-occurrence-2", "operation": "op-2"}), + ( + "order position", + None, + {"key": "key-2", "occurrence": "release-occurrence-2", "operation": "op-2", "head": "order-head-forked"}, + ), + ( + "order predecessor", + None, + { + "key": "key-2", + "occurrence": "release-occurrence-2", + "operation": "op-2", + "position": 11, + "head": "order-head-9", + }, + ), ], ) def test_claim_set_rejects_a_reused_claim_identity(label, actor, claims): @@ -209,8 +282,19 @@ def test_claim_sets_stay_within_one_bounded_target_run_store(): ("path", "value", "message"), [ (("plan", "contract_id"), "provisioning-plan-v1", "orchestration plan"), - (("bindings", 0, "binding"), "orchestration.inject-binding.host.prerelease", "belong to the requested inject"), + (("bindings", 0, "binding"), "orchestration.inject-binding.release", OWNERSHIP), + (("bindings", 0, "node"), "orchestration.event.gate", "provision node address"), (("placement",), {"kind": "event", "event": "orchestration.script.day-one"}, "event address"), + ( + ("placement",), + { + "kind": "schedule", + "event": "orchestration.script.day-one", + "script": "orchestration.script.s", + "slot": "1", + }, + "event address", + ), ( ("placement",), {"kind": "schedule", "event": "orchestration.event.gate", "script": "orchestration.story.s", "slot": "1"}, From 2bf8c1ad138b51f6ce35bc762c41cf675b3e93f7 Mon Sep 17 00:00:00 2001 From: Yernat Yestekov <2068106+doublewhy@users.noreply.github.com> Date: Sun, 11 Oct 2026 00:04:43 -0700 Subject: [PATCH 7/9] chore(research): republish evidence for the inject occurrence contracts Specification-coverage release 72.0.0 and formal-validation release 73.0.0 bind the current implementation digest; outcomes and claim limits are unchanged. --- .../analysis-v73.json | 164 ++++ .../bundles/retest-v73.json | 122 +++ .../execution-snapshot-v73.json | 652 ++++++++++++++++ .../formal-semantic-validation/index.md | 8 +- .../specification-coverage/analysis-v72.json | 113 +++ ...specification-coverage-issue-1423-v72.json | 10 + .../execution-snapshot-v72.json | 704 ++++++++++++++++++ docs/research/specification-coverage/index.md | 8 +- .../tests/test_formal_semantic_validation.py | 5 +- .../test_issue_989_versioned_evidence.py | 22 +- .../tests/test_specification_coverage.py | 2 +- tools/check_specification_coverage.py | 5 +- tools/formal_semantic_validation/_baseline.py | 1 + tools/formal_semantic_validation/_loading.py | 4 +- .../_release_revisions.py | 4 +- tools/formal_semantic_validation/_releases.py | 5 +- tools/formal_semantic_validation/_retest.py | 2 +- 17 files changed, 1808 insertions(+), 23 deletions(-) create mode 100644 docs/research/formal-semantic-validation/analysis-v73.json create mode 100644 docs/research/formal-semantic-validation/bundles/retest-v73.json create mode 100644 docs/research/formal-semantic-validation/execution-snapshot-v73.json create mode 100644 docs/research/specification-coverage/analysis-v72.json create mode 100644 docs/research/specification-coverage/bundles/raes-standardized-specification-coverage-issue-1423-v72.json create mode 100644 docs/research/specification-coverage/execution-snapshot-v72.json diff --git a/docs/research/formal-semantic-validation/analysis-v73.json b/docs/research/formal-semantic-validation/analysis-v73.json new file mode 100644 index 000000000..2ce8d873f --- /dev/null +++ b/docs/research/formal-semantic-validation/analysis-v73.json @@ -0,0 +1,164 @@ +{ + "analysis_id": "issue-1423-analysis-v73", + "claim": { + "allowed_evidence": [ + "production parser and semantic-validator results", + "canonical compiled digests", + "participant contract regression tests", + "pinned protocol, corpus, and execution snapshot" + ], + "claim_id": "asr-530-formal-semantic-validation-retest", + "disallowed_evidence": [ + "schema success as semantic proof", + "workflow reachability as network or exploit reachability", + "FM labels as gate outcomes", + "attribution as counterfactual proof", + "formal prose or maintainer confidence alone" + ], + "evidence_artifacts": [ + "docs/research/formal-semantic-validation/protocol-v2.json", + "docs/research/formal-semantic-validation/corpus/manifest-v4.json", + "docs/research/formal-semantic-validation/execution-snapshot-v73.json", + "docs/research/formal-semantic-validation/evidence/finite-domain-satisfiable-v4.json", + "docs/research/formal-semantic-validation/evidence/finite-domain-unsatisfiable-v4.json", + "docs/research/formal-semantic-validation/evidence/typed-exploit-path-valid-v4.json", + "docs/research/formal-semantic-validation/evidence/typed-exploit-path-invalid-v4.json" + ], + "falsification_protocol": "Replay every retained and new case through its production entrypoint, require complete digest and evidence joins, execute participant fixtures, and derive status from the recorded outcomes.", + "objective_fail_criteria": "A supported negative passes, a positive fails, an observation drifts, a required participant case is missing, or weaker evidence is promoted to solver, exploit-path, runtime-stability, or counterfactual assurance.", + "objective_pass_criteria": "Every claim class has positive and negative cases, all supported cases reproduce the frozen outcome, every participant obligation has passing positive and negative fixtures, and unsupported classes remain untested.", + "statement": "At the recorded source-state digest, the retained RAES controls have the bounded statuses recorded here; historical releases are integrity evidence, not current replay evidence.", + "threats_to_validity": [ + "The issue-specific corpus is intentionally small and does not enumerate every validator invariant.", + "The participant fixtures exercise reference production contracts and tests, not every independent backend realization.", + "The replay gate runs on one Python reference configuration and one pinned RAES revision.", + "Unsupported solver-level classes have protocol cases but no executable observations." + ] + }, + "claim_results": [ + { + "case_count": 2, + "claim_class_id": "schema-validity", + "evidence_status": "demonstrated", + "limitations": [ + "Bounded to the named source/model structural controls." + ], + "matching_case_count": 2, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 0 + }, + { + "case_count": 4, + "claim_class_id": "semantic-consistency", + "evidence_status": "partial", + "limitations": [ + "Partial coverage of named static semantics and participant obligations, not universal consistency." + ], + "matching_case_count": 4, + "participant_obligation_count": 7, + "replayable_case_count": 4, + "unsupported_case_count": 0 + }, + { + "case_count": 2, + "claim_class_id": "graph-reachability", + "evidence_status": "partial", + "limitations": [ + "Partial workflow control-flow reachability only; not network, service, or exploit reachability." + ], + "matching_case_count": 2, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 0 + }, + { + "case_count": 4, + "claim_class_id": "constraint-satisfiability", + "evidence_status": "demonstrated", + "limitations": [ + "Demonstrated only for raes-finite-domain-satisfiability-v1 and its pinned solver configuration." + ], + "matching_case_count": 4, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 2 + }, + { + "case_count": 4, + "claim_class_id": "exploit-path-validity", + "evidence_status": "demonstrated", + "limitations": [ + "Demonstrated only for the admitted snapshot, typed graph, query, semantics, and bounded search profile." + ], + "matching_case_count": 4, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 2 + }, + { + "case_count": 2, + "claim_class_id": "determinism-stability", + "evidence_status": "partial", + "limitations": [ + "Partial parse-to-compile repeatability only; runtime and backend determinism are untested." + ], + "matching_case_count": 2, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 0 + }, + { + "case_count": 2, + "claim_class_id": "counterfactual-necessity", + "evidence_status": "untested", + "limitations": [ + "Untested because no governed intervention or ablation entrypoint ran." + ], + "matching_case_count": 2, + "participant_obligation_count": 0, + "replayable_case_count": 0, + "unsupported_case_count": 2 + } + ], + "corpus_revision": "4.0.0", + "evidence_status": "partial", + "execution_id": "issue-1423-execution-v73", + "generated_at": "2026-10-11T07:04:16.616377+00:00", + "limitations": [ + "Satisfiability is limited to raes-finite-domain-satisfiability-v1 and its exact translation, theory, and Z3 configuration.", + "The subset-minimal unsatisfiable core is not a universal proof certificate.", + "Exploit-path results are limited to the admitted snapshot, normalized graph, query, transition semantics, and bounded search profile.", + "A valid path is not backend execution and an invalid path is not real-world non-exploitability.", + "The production exploit-path JSON loader permits duplicate keys; the research loader rejects them without claiming stronger production behavior.", + "Participant replay inherits the host environment and is not described as hermetic.", + "Counterfactual necessity remains untested.", + "Scoped observation demand is not a claim class in this preregistration and is not promoted to demonstrated by this retest.", + "EXP-732 provenance joins are verified by their dedicated regression suite; this retained corpus makes no universal run, apparatus, source, or augmentation assurance claim.", + "This retained corpus does not establish native backend attestation fidelity; materialization contract checks remain separate operational provenance, not experimental observations.", + "Capture admission and evidence-proof authority are verified by issue-1237 regression tests, not promoted to a new claim class by this retained corpus.", + "Evidence-requirement refinement lineage is outside this retained formal claim set; this retest refreshes integrated source provenance without promoting that feature to a formal claim.", + "Authoring-adapter transport behavior is outside this retained formal claim set.", + "Operational recovery observation and startup reconciliation are verified by their API-404 regression suite, not promoted to a new formal claim class by this retained corpus.", + "Single-owner store admission, immutable target/run scope, and provider shutdown ordering are verified by their API-404 CP-5 regression suite, not promoted to a formal claim by this retained corpus.", + "Mixed and staged trial admission is verified by its SEM-234/SCE-002/API-407 regression suite, not promoted to a new formal claim class by this retained corpus.", + "Offline control-plane maintenance, readiness, and bounded audit behavior are verified by issue #1186 runtime tests, not promoted to a formal claim by this retained corpus.", + "Issue #1187 control-plane crash/profile conformance and HTTP security changes are covered by their dedicated regression suite, not promoted to new claims by this retained corpus.", + "Issue #1189 profile declarations and capability admission are covered by dedicated runtime tests; the retained formal corpus does not execute control-plane profile composition.", + "Issue #1016 mixed-runtime coordination is covered by dedicated runtime tests; the retained formal corpus does not establish backend-native mixed realization, multi-controller coordination, IFC, or equivalence.", + "Issue #610's reconciliation demonstration harness is covered by its dedicated processor and CLI suite, not promoted to new claims by the retained language corpus.", + "Participant identity, organization ownership, and participant assignment are separated by issue #1338. This retained offline corpus does not establish participant autonomy, execution authority, live backend fidelity, or causal attribution.", + "Issue #1389 temporal-subject admission is verified by dedicated compiler tests and adds no new formal-semantic claim to this retained corpus.", + "Issue #971 model construction is verified by its own tests; this retained corpus establishes no participant-crossing equivalence or runtime-realization claim.", + "Issue #1359 control-plane route authority, participant-view scoping, and no-store HTTP boundary are verified by their dedicated HTTP-boundary suite and add no new formal-semantic claim to this retained corpus.", + "Issue #1401 required-evidence media-type coherence is verified by its dedicated suite and adds no new formal-semantic claim to this retained corpus.", + "Issue #1361 execution and recovery requirements are verified by dedicated policy, composition, and admission tests; this retained corpus establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 maintainability repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 resource type-hint repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The combined issue #1361 execution-policy and hatchling update preserves retained outcomes and bounded claims; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1418 runtime-fact export manifest split changes no contract, schema or behavior and adds no new formal-semantic claim.", + "The issue #1423 inject trigger request and occurrence contracts are new draft carriers that no SDL construct, compiler or runtime path reads, and they add no new formal-semantic claim." + ], + "plain_language_outcome": "The retained formal controls reproduce their prior outcomes against the issue #1423 inject trigger request and occurrence contracts; bounded claims are unchanged.", + "protocol_revision": "2.0.0" +} diff --git a/docs/research/formal-semantic-validation/bundles/retest-v73.json b/docs/research/formal-semantic-validation/bundles/retest-v73.json new file mode 100644 index 000000000..38cf75040 --- /dev/null +++ b/docs/research/formal-semantic-validation/bundles/retest-v73.json @@ -0,0 +1,122 @@ +{ + "analysis_path": "docs/research/formal-semantic-validation/analysis-v73.json", + "analysis_sha256": "9d13ac904e77f8a36413d2673dad5182382c0e02f0de671948fe92c341ed3d37", + "artifacts": [ + { + "artifact_id": "finite-domain-satisfiable-v2-input", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/satisfiable-control.sdl.yaml", + "sha256": "0ca9eaba9dc47171f7a042dc6753faa6c820c65ee966538f9d65fac5342202e8" + }, + { + "artifact_id": "finite-domain-satisfiable-v2-evidence", + "kind": "production-evidence", + "path": "docs/research/formal-semantic-validation/evidence/finite-domain-satisfiable-v4.json", + "sha256": "554202313d678046958b5c028e2de26ff03c74895cfac552677eed74e8153add" + }, + { + "artifact_id": "finite-domain-unsatisfiable-v2-input", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/unsatisfiable-control.sdl.yaml", + "sha256": "cfef56a1f56d5f0db9da195377fd75694bdd0f0b92932fdb8fafcbd3f7baf6c5" + }, + { + "artifact_id": "finite-domain-unsatisfiable-v2-evidence", + "kind": "production-evidence", + "path": "docs/research/formal-semantic-validation/evidence/finite-domain-unsatisfiable-v4.json", + "sha256": "c972725ef64822a75a60380afc11f08eac25b7fe9b091d39b058b3c9f7c8031d" + }, + { + "artifact_id": "typed-exploit-path-valid-v2-input", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/exploit-path-valid-v3.json", + "sha256": "0afe635a63db5b6e6380ac70982fd61d09790745d51a10d670321304121e7c39" + }, + { + "artifact_id": "typed-exploit-path-valid-v2-evidence", + "kind": "production-evidence", + "path": "docs/research/formal-semantic-validation/evidence/typed-exploit-path-valid-v4.json", + "sha256": "1b7f55d04db172da32658187c64a88c13b5f4d565267ce2be7cb86a9d04cb70c" + }, + { + "artifact_id": "typed-exploit-path-invalid-v2-input", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/exploit-path-invalid-v3.json", + "sha256": "0b2293d4a8983515ff05c516be6e6b418a4f3f09e055250a00bf15fda861aab3" + }, + { + "artifact_id": "typed-exploit-path-invalid-v2-evidence", + "kind": "production-evidence", + "path": "docs/research/formal-semantic-validation/evidence/typed-exploit-path-invalid-v4.json", + "sha256": "244f895a64f14c10916ab0533ab462ce80a328021cd6a50c30a4aa59266d5533" + }, + { + "artifact_id": "schema-valid-control-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/schema-valid.sdl.yaml", + "sha256": "41a9adffdf9f5f2ccc2f887dcf7b15fba3b47c83a1af15f33db872c4a2449d67" + }, + { + "artifact_id": "schema-unknown-field-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/schema-invalid-unknown-field.sdl.yaml", + "sha256": "51cf62319a86c95a2517995939d1f370573051835e4b55bb6d5beaf049640481" + }, + { + "artifact_id": "semantic-resolved-objective-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/semantic-valid-participant-identity-v2.sdl.yaml", + "sha256": "75834bdc883e2003e1c473870bdf75700978955bb83095c6bd718ba6bd3908a6" + }, + { + "artifact_id": "semantic-dangling-assertion-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/semantic-invalid-dangling-ref-participant-identity-v2.sdl.yaml", + "sha256": "1d25bee5f556054e5f0a518df025e4c62e080e1964035e3c1a12e074d88d3a5d" + }, + { + "artifact_id": "semantic-ambiguous-reference-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/semantic-invalid-ambiguous-ref.sdl.yaml", + "sha256": "653cbd2fd62e220d49fb86f80133884207df5ae6752846345ae3085b93f6e4ed" + }, + { + "artifact_id": "semantic-feature-cycle-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/semantic-invalid-feature-cycle.sdl.yaml", + "sha256": "e1f66d95a9ad039687aec8cccbc8843b514072ff08e006c1b4ca6aa5cd8d4ed1" + }, + { + "artifact_id": "workflow-reachable-control-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/workflow-reachable.sdl.yaml", + "sha256": "54c40ceb98ad47247447d737973b2c55e8fb2045e209c7545c4fb20cf42dc3dc" + }, + { + "artifact_id": "workflow-unreachable-step-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/workflow-unreachable.sdl.yaml", + "sha256": "ef22ef2e260f1a7fd92d286f9b571716436b192ddfd54aea7bdfcfdda4ca52a2" + }, + { + "artifact_id": "compile-repeatability-control-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/determinism-a.sdl.yaml", + "sha256": "0bc40900d598c1af7a405d798ca19710405e53ced262d8733081abf12edf89fe" + }, + { + "artifact_id": "compile-non-vacuity-control-comparison-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/determinism-b.sdl.yaml", + "sha256": "d85338f89f20a45515b12da8640173c1a52e47eb17ca0f4f6b4f8f3306e863a1" + } + ], + "bundle_id": "raes-formal-semantic-validation", + "corpus_path": "docs/research/formal-semantic-validation/corpus/manifest-v4.json", + "corpus_sha256": "c57207af72406aa4f70882b9bbeb7cedcc79cf3854c878a95e3eb1fa59ea7a72", + "protocol_path": "docs/research/formal-semantic-validation/protocol-v2.json", + "protocol_sha256": "abf94093e344bf495dfb04e8b0c5985c0beaab8ebb17a75e15c8674fa81b1a7c", + "revision": "73.0.0", + "snapshot_path": "docs/research/formal-semantic-validation/execution-snapshot-v73.json", + "snapshot_sha256": "5e7433dc9308c4c374b395bbf9da61430e4bb4b9e7bdd0665f27c17cdedee612" +} diff --git a/docs/research/formal-semantic-validation/execution-snapshot-v73.json b/docs/research/formal-semantic-validation/execution-snapshot-v73.json new file mode 100644 index 000000000..252e7b122 --- /dev/null +++ b/docs/research/formal-semantic-validation/execution-snapshot-v73.json @@ -0,0 +1,652 @@ +{ + "baseline": { + "execution_id": "issue-1418-execution-v72", + "release_path": "docs/research/formal-semantic-validation/bundles/retest-v72.json", + "release_revision": "72.0.0", + "release_sha256": "6a4b9d510e4d1c98f45cf0275cee2563bbdbaa432914694d86e4a4fdf96a06ed" + }, + "captured_at": "2026-10-11T07:04:16.616377+00:00", + "commands": [ + { + "argv": [ + "implementations/python/.venv/bin/python", + "tools/check_formal_semantic_validation.py" + ], + "command_id": "bundle-replay", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/pytest", + "-q", + "implementations/python/tests/test_sem_208_participant_behavior.py::test_hidden_truth_disclosure_is_separate_from_observable_projection", + "implementations/python/tests/test_sem_208_participant_behavior.py::test_hidden_truth_cannot_be_observed_without_explicit_disclosure_rule", + "implementations/python/tests/test_sem_211_participant_action_semantics.py::test_action_contract_declares_sem_211_classes_and_compiles_them", + "implementations/python/tests/test_sem_211_participant_action_semantics.py::test_action_result_rejects_success_when_preconditions_are_unresolved", + "implementations/python/tests/test_run_308_concurrent_participant_execution.py::test_runtime_snapshot_publishes_joint_action_and_time_context_records", + "implementations/python/tests/test_run_308_concurrent_participant_execution.py::test_joint_action_record_contract_rejects_unordered_conflicting_writes", + "implementations/python/tests/test_participant_runtime_invariants.py::test_order_discipline_accepts_supported_order_claim_strengths", + "implementations/python/tests/test_participant_runtime_invariants.py::test_order_discipline_rejects_wall_clock_causality", + "implementations/python/tests/test_sem_212_participant_attribution_semantics.py::test_attribution_edge_round_trips_on_terminal_observation", + "implementations/python/tests/test_sem_212_participant_attribution_semantics.py::test_timestamp_adjacency_cannot_be_reported_as_strong_causality", + "implementations/python/tests/test_sem_215_participant_outcome_interpretation.py::test_outcome_interpretation_rule_parses_and_compiles_explicit_layers", + "implementations/python/tests/test_sem_215_participant_outcome_interpretation.py::test_local_action_success_does_not_imply_objective_success_without_rule_record", + "implementations/python/tests/test_realization_honesty_conformance.py::test_constructive_envelope_runs_positive_and_negative_honesty_probes", + "implementations/python/tests/test_realization_honesty_conformance.py::test_only_native_live_can_support_native_conformance" + ], + "command_id": "participant-fixtures", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/raes", + "processor", + "satisfiability", + "docs/research/formal-semantic-validation/corpus/satisfiable-control.sdl.yaml", + "--profile", + "raes-finite-domain-satisfiability-v1" + ], + "command_id": "finite-domain-satisfiable-v2", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/raes", + "processor", + "satisfiability", + "docs/research/formal-semantic-validation/corpus/unsatisfiable-control.sdl.yaml", + "--profile", + "raes-finite-domain-satisfiability-v1" + ], + "command_id": "finite-domain-unsatisfiable-v2", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/raes", + "processor", + "exploit-path", + "docs/research/formal-semantic-validation/corpus/exploit-path-valid-v3.json", + "--profile", + "raes-exploit-path-analysis-v1" + ], + "command_id": "typed-exploit-path-valid-v2", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/raes", + "processor", + "exploit-path", + "docs/research/formal-semantic-validation/corpus/exploit-path-invalid-v3.json", + "--profile", + "raes-exploit-path-analysis-v1" + ], + "command_id": "typed-exploit-path-invalid-v2", + "network": "disabled" + } + ], + "configuration_id": "raes-python-reference-offline-v41", + "corpus_revision": "4.0.0", + "deviations": [], + "execution_id": "issue-1423-execution-v73", + "execution_status": "complete", + "observations": [ + { + "actual_outcome": "accepted", + "analysis_profile": null, + "case_id": "schema-valid-control", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/schema-valid.sdl.yaml" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "A passing minimal source does not establish semantic correctness." + ], + "replayable": true, + "result_digest": "f7d364ef384df8a1526b489501835b635021c860793b5764f91d956710d2250c", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "schema-unknown-field", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLParseError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/schema-invalid-unknown-field.sdl.yaml" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "The observation covers one unknown-field defect only." + ], + "replayable": true, + "result_digest": "f55d834b458f8e069e1c69061b4cc0a6d61e0e052bf90c670f2e6a5ad8b5bd98", + "source_digest": null + }, + { + "actual_outcome": "accepted", + "analysis_profile": null, + "case_id": "semantic-resolved-objective", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/semantic-valid-participant-identity-v2.sdl.yaml" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "This is a positive control for one objective-reference slice." + ], + "replayable": true, + "result_digest": "652288785dc09095955ed3649f6407d616fb7c4d4f4188df4ed513ccb7537e0b", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "semantic-dangling-assertion", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLValidationError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/semantic-invalid-dangling-ref-participant-identity-v2.sdl.yaml" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "A single dangling reference does not prove complete semantic coverage." + ], + "replayable": true, + "result_digest": "0207cf616b56708ca9b8c4499d3301abe22dbe52162cf8d58d3bec429d9db024", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "semantic-ambiguous-reference", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLValidationError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/semantic-invalid-ambiguous-ref.sdl.yaml" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "One namespace collision does not enumerate every ambiguity surface." + ], + "replayable": true, + "result_digest": "9da4a87797d228e0012ab6b30459f4892e41aa6f224a9840be035fee4a2eea73", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "semantic-feature-cycle", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLValidationError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/semantic-invalid-feature-cycle.sdl.yaml" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "One static dependency cycle does not establish general constraint satisfiability." + ], + "replayable": true, + "result_digest": "d15dbcd99fb4f20b965d7031b07dd6534576302270399c3fa656d29e7de02b83", + "source_digest": null + }, + { + "actual_outcome": "accepted", + "analysis_profile": null, + "case_id": "workflow-reachable-control", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/workflow-reachable.sdl.yaml" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "The graph is workflow control flow only." + ], + "replayable": true, + "result_digest": "b1b49649b54bd59d4ef357b39cf9158da90f4eae560f8dd756acf97bd0827a06", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "workflow-unreachable-step", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLValidationError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/workflow-unreachable.sdl.yaml" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "The result does not establish network, service, participant, or exploit reachability." + ], + "replayable": true, + "result_digest": "bb931d19346ef9193408ae6c85deb4079704378fc5f00dc5f47a2817cff21943", + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "whole-scenario-satisfiable-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "No governed whole-scenario constraint theory or solver exists." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "whole-scenario-unsatisfiable-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "Local checks cannot produce a whole-scenario unsat certificate." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "valid-exploit-path-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "The issue-168 baseline had no canonical typed attack graph or path-query entrypoint." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "invalid-exploit-path-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "Vulnerability and topology declarations are not an invalid-path proof." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "stable", + "analysis_profile": null, + "case_id": "compile-repeatability-control", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/determinism-a.sdl.yaml" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "The witness ends at compiled output." + ], + "replayable": true, + "result_digest": "d7c098c5d063b8d1b0747e8df5daa90061456065cdda0bbedfa10918442f5daa", + "source_digest": null + }, + { + "actual_outcome": "distinguishable", + "analysis_profile": null, + "case_id": "compile-non-vacuity-control", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/determinism-a.sdl.yaml", + "docs/research/formal-semantic-validation/corpus/determinism-b.sdl.yaml" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "Distinct digests are a non-vacuity control, not semantic non-equivalence proof." + ], + "replayable": true, + "result_digest": "a2fcebba3341592b133af813e8bb8e5f47270418bc58bfd471a89bfbc8ba46da", + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "necessity-witness-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "No governed intervention or ablation protocol exists." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "non-necessity-control-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "Attribution and negative fixtures do not demonstrate non-necessity." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "satisfiable", + "analysis_profile": "raes-finite-domain-satisfiability-v1", + "case_id": "finite-domain-satisfiable-v2", + "configuration_digest": "sha256:1204635e17e759e9ad3bd6be2ecb28c6de05c07ead6dfdd15936ed5d3d5b81b2", + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "scenario-satisfiability-evidence/v1", + "evidence_artifact_path": "docs/research/formal-semantic-validation/evidence/finite-domain-satisfiable-v4.json", + "evidence_artifact_sha256": "554202313d678046958b5c028e2de26ff03c74895cfac552677eed74e8153add", + "evidence_digest": "sha256:23c2cae7d95d4cc83d77ca576e3911477b169ecc311c977cb45490345f633b5a", + "evidence_profile": "scenario-satisfiability-evidence/v1", + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/satisfiable-control.sdl.yaml", + "docs/research/formal-semantic-validation/evidence/finite-domain-satisfiable-v4.json", + "specs/formal/scenario-satisfiability/README.md" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "Demonstrates only the pinned finite-domain theory, translation, solver profile, and source." + ], + "replayable": true, + "result_digest": "sha256:23c2cae7d95d4cc83d77ca576e3911477b169ecc311c977cb45490345f633b5a", + "source_digest": "sha256:0ca9eaba9dc47171f7a042dc6753faa6c820c65ee966538f9d65fac5342202e8" + }, + { + "actual_outcome": "unsatisfiable", + "analysis_profile": "raes-finite-domain-satisfiability-v1", + "case_id": "finite-domain-unsatisfiable-v2", + "configuration_digest": "sha256:1204635e17e759e9ad3bd6be2ecb28c6de05c07ead6dfdd15936ed5d3d5b81b2", + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "scenario-satisfiability-evidence/v1", + "evidence_artifact_path": "docs/research/formal-semantic-validation/evidence/finite-domain-unsatisfiable-v4.json", + "evidence_artifact_sha256": "c972725ef64822a75a60380afc11f08eac25b7fe9b091d39b058b3c9f7c8031d", + "evidence_digest": "sha256:317b5cad00aa7f4f7868dca66127611ba19d40ffd86f35815502622814df54c1", + "evidence_profile": "scenario-satisfiability-evidence/v1", + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/unsatisfiable-control.sdl.yaml", + "docs/research/formal-semantic-validation/evidence/finite-domain-unsatisfiable-v4.json", + "specs/formal/scenario-satisfiability/README.md" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "The subset-minimal core is evidence for the pinned translation and solver, not a proof certificate for arbitrary SDL." + ], + "replayable": true, + "result_digest": "sha256:317b5cad00aa7f4f7868dca66127611ba19d40ffd86f35815502622814df54c1", + "source_digest": "sha256:cfef56a1f56d5f0db9da195377fd75694bdd0f0b92932fdb8fafcbd3f7baf6c5" + }, + { + "actual_outcome": "valid-path", + "analysis_profile": "raes-exploit-path-analysis-v1", + "case_id": "typed-exploit-path-valid-v2", + "configuration_digest": "sha256:7f8876d81feb77d3a3239be2fb8337de8885e2744f8786728ba23e4e6027bc0a", + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "exploit-path-analysis-evidence/v1", + "evidence_artifact_path": "docs/research/formal-semantic-validation/evidence/typed-exploit-path-valid-v4.json", + "evidence_artifact_sha256": "1b7f55d04db172da32658187c64a88c13b5f4d565267ce2be7cb86a9d04cb70c", + "evidence_digest": "sha256:2d4d1a362751abd9544beb8af7f8c6331d04dac8f4abc315fb261f81fbaf4387", + "evidence_profile": "exploit-path-analysis-evidence/v1", + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/exploit-path-valid-v3.json", + "docs/research/formal-semantic-validation/evidence/typed-exploit-path-valid-v4.json", + "specs/formal/exploit-path-analysis/README.md" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "The witness is bounded to the admitted snapshot, normalized graph, query, semantics, and search profile; it does not establish backend execution." + ], + "replayable": true, + "result_digest": "sha256:2d4d1a362751abd9544beb8af7f8c6331d04dac8f4abc315fb261f81fbaf4387", + "source_digest": "sha256:0afe635a63db5b6e6380ac70982fd61d09790745d51a10d670321304121e7c39" + }, + { + "actual_outcome": "invalid-path", + "analysis_profile": "raes-exploit-path-analysis-v1", + "case_id": "typed-exploit-path-invalid-v2", + "configuration_digest": "sha256:7f8876d81feb77d3a3239be2fb8337de8885e2744f8786728ba23e4e6027bc0a", + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "exploit-path-analysis-evidence/v1", + "evidence_artifact_path": "docs/research/formal-semantic-validation/evidence/typed-exploit-path-invalid-v4.json", + "evidence_artifact_sha256": "244f895a64f14c10916ab0533ab462ce80a328021cd6a50c30a4aa59266d5533", + "evidence_digest": "sha256:1b416bb5a4d29d57c961b769cc9d3af5d9328624e3eebf104d57f39a94c5bb97", + "evidence_profile": "exploit-path-analysis-evidence/v1", + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/exploit-path-invalid-v3.json", + "docs/research/formal-semantic-validation/evidence/typed-exploit-path-invalid-v4.json", + "specs/formal/exploit-path-analysis/README.md" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "Structured rejection proves only that this bounded graph/query cannot reach its goal; it does not establish real-world non-exploitability." + ], + "replayable": true, + "result_digest": "sha256:1b416bb5a4d29d57c961b769cc9d3af5d9328624e3eebf104d57f39a94c5bb97", + "source_digest": "sha256:0b2293d4a8983515ff05c516be6e6b418a4f3f09e055250a00bf15fda861aab3" + } + ], + "participant_observations": [ + { + "evidence_refs": [ + "implementations/python/tests/test_sem_208_participant_behavior.py::test_hidden_truth_disclosure_is_separate_from_observable_projection", + "implementations/python/tests/test_sem_208_participant_behavior.py::test_hidden_truth_cannot_be_observed_without_explicit_disclosure_rule" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "Covers the reference SDL/contract path, not every backend projection." + ], + "negative_outcome": "passed", + "obligation_id": "hidden-vs-visible-projection", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_sem_211_participant_action_semantics.py::test_action_contract_declares_sem_211_classes_and_compiles_them", + "implementations/python/tests/test_sem_211_participant_action_semantics.py::test_action_result_rejects_success_when_preconditions_are_unresolved" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "Covers declared applicability and one unresolved-precondition failure." + ], + "negative_outcome": "passed", + "obligation_id": "fail-closed-action-applicability", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_run_308_concurrent_participant_execution.py::test_runtime_snapshot_publishes_joint_action_and_time_context_records", + "implementations/python/tests/test_run_308_concurrent_participant_execution.py::test_joint_action_record_contract_rejects_unordered_conflicting_writes" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "Contract evidence does not prove every backend's live concurrency fidelity." + ], + "negative_outcome": "passed", + "obligation_id": "shared-state-effects", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_participant_runtime_invariants.py::test_order_discipline_accepts_supported_order_claim_strengths", + "implementations/python/tests/test_participant_runtime_invariants.py::test_order_discipline_rejects_wall_clock_causality" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "Rejecting timestamp-only causality does not supply counterfactual proof." + ], + "negative_outcome": "passed", + "obligation_id": "ordering-before-causality", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_sem_212_participant_attribution_semantics.py::test_attribution_edge_round_trips_on_terminal_observation", + "implementations/python/tests/test_sem_212_participant_attribution_semantics.py::test_timestamp_adjacency_cannot_be_reported_as_strong_causality" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "Attribution labels disclose basis; they do not demonstrate necessity." + ], + "negative_outcome": "passed", + "obligation_id": "evidence-labeled-attribution", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_sem_215_participant_outcome_interpretation.py::test_outcome_interpretation_rule_parses_and_compiles_explicit_layers", + "implementations/python/tests/test_sem_215_participant_outcome_interpretation.py::test_local_action_success_does_not_imply_objective_success_without_rule_record" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "The fixtures establish layer separation, not outcome validity in every realization." + ], + "negative_outcome": "passed", + "obligation_id": "participant-local-outcome-separation", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_realization_honesty_conformance.py::test_constructive_envelope_runs_positive_and_negative_honesty_probes", + "implementations/python/tests/test_realization_honesty_conformance.py::test_only_native_live_can_support_native_conformance" + ], + "execution_id": "issue-1423-execution-v73", + "limitations": [ + "Reference conformance evidence remains bounded to declared realization profiles." + ], + "negative_outcome": "passed", + "obligation_id": "realization-profile-honesty", + "positive_outcome": "passed" + } + ], + "protocol_revision": "2.0.0", + "raes_revision": "f0215beecd728c8941b6bfd520ac0c4827aaf81a", + "source_state": { + "base_revision": "f0215beecd728c8941b6bfd520ac0c4827aaf81a", + "checkout_state": "modified", + "implementation_digest": "e9b23d9653f2c38214c03042f4c83e3356ae0e4e4f7d111cf2fadf0ee70f4690", + "profile": "python-reference-source/v2" + }, + "versions": { + "python": "3.14.4", + "raes": "5.0.0", + "z3_engine": "4.16.0", + "z3_solver": "4.16.0.0" + } +} diff --git a/docs/research/formal-semantic-validation/index.md b/docs/research/formal-semantic-validation/index.md index a8fc612cd..62206d55a 100644 --- a/docs/research/formal-semantic-validation/index.md +++ b/docs/research/formal-semantic-validation/index.md @@ -336,7 +336,7 @@ outcomes and claim limits, recording the positive successor's changed result digest; the dangling-reference diagnostic remains identical. It establishes no autonomy threshold, authority grant, or realized attribution. -Current validation requires explicit release 72.0.0, rejects unsupported future +Current validation requires explicit release 73.0.0, rejects unsupported future or duplicate revisions, and never accepts an old/new output-digest pair as a substitute for replay. Historical releases (including the issue-826 supplement) undergo pin, shape, control, and internal-join checks without executing current @@ -606,3 +606,9 @@ runtime-fact export manifest split in [`execution-snapshot-v72.json`](execution-snapshot-v72.json) and [`analysis-v72.json`](analysis-v72.json). Outcomes and claim limits remain unchanged. + +Release 73.0.0 replays the retained formal cases against the issue #1423 inject +trigger request and occurrence contracts in +[`execution-snapshot-v73.json`](execution-snapshot-v73.json) and +[`analysis-v73.json`](analysis-v73.json). Outcomes and claim limits remain +unchanged. diff --git a/docs/research/specification-coverage/analysis-v72.json b/docs/research/specification-coverage/analysis-v72.json new file mode 100644 index 000000000..7612a68b4 --- /dev/null +++ b/docs/research/specification-coverage/analysis-v72.json @@ -0,0 +1,113 @@ +{ + "analysis_id": "raes-standardized-specification-coverage-issue-1423-v72", + "backend_leakage": [], + "claim": { + "allowed_evidence": [ + "pinned source metadata and bounded paraphrases", + "production parser, semantic, instantiation, admission, compiler, contract, and profile results", + "exact artifact digests and typed pointers", + "documented missing-concept and backend-specific dispositions" + ], + "claim_id": "raes-standardized-configurable-specification-coverage", + "disallowed_evidence": [ + "field-count or schema breadth alone", + "the existing scenario stress corpus as the representative request corpus", + "free-form metadata as typed coverage", + "backend-private interpretation", + "post-hoc removal or repair of falsifying concepts" + ], + "evidence_artifacts": [ + "docs/research/specification-coverage/protocol-v1.json", + "docs/research/specification-coverage/execution-snapshot-v72.json", + "docs/research/specification-coverage/analysis-v68.json" + ], + "falsification_protocol": "docs/research/specification-coverage/protocol-v1.json", + "objective_fail_criteria": "A load-bearing concept is missing or lossy, an applicable stage fails, or backend vocabulary is required in core SDL while the result claims success.", + "objective_pass_criteria": "Every load-bearing concept passes at every owning stage, backend-specific mechanics stay outside core SDL, and no requested concept is silently lost.", + "statement": "RAES provides a standardized configurable portable specification surface for the preregistered representative cyber-agent evaluation environment requirements without backend vocabulary in core SDL.", + "threats_to_validity": [ + "The representative corpus contains four source strata and sixteen atomic concepts rather than every cyber-range requirement.", + "The reference processor and repository fixtures are not independent backend implementations.", + "No live range, simulator federation, or participant execution was part of this offline specification-coverage test." + ] + }, + "classification_counts": { + "deliberately-backend-specific": 1, + "directly-expressible": 10, + "missing": 3, + "profile-or-manifest-constraint": 2 + }, + "evidence_status": "partial", + "execution_status": "complete", + "generated_at": "2026-10-11T07:04:16.616377+00:00", + "limitations": [ + "This result demonstrates bounded specification coverage, not universal cyber-range coverage, usability, adoption, backend substitution, or behavioral equivalence.", + "The three missing concepts are evidence, not implementation tasks within this snapshot.", + "The retained protocol does not test recursive realization or plan-level profile semantics; this release only re-establishes its original bounded coverage result against the current implementation.", + "The retained protocol does not test evidence-requirement refinement lineage; the dedicated EXP-731 regression suite covers that production boundary.", + "Authoring-adapter transport behavior is outside this retained protocol.", + "Reviewed OCI mirror and pre-seed admission is covered by its own regression suites and the development artifact policy gate, not a new claim in this preregistered matrix.", + "Operational recovery observation and startup reconciliation are covered by their API-404 regression suite, not a new claim in this preregistered matrix.", + "Store ownership, immutable runtime scope, and provider shutdown ordering are covered by the API-404 CP-5 regression suite, not by this retained specification-coverage protocol.", + "Mixed/staged trial compilation and admission are covered by issue #1015 regression tests, not by this retained specification-coverage corpus; no live mixed-runtime result is claimed.", + "Issue #1186 control-plane recovery operations are covered by their runtime regression suite, not by this retained specification-coverage corpus.", + "Issue #1187 control-plane crash/profile conformance and HTTP security changes are covered by their dedicated regression suite, not promoted to new claims by this retained corpus.", + "Issue #1189 control-plane profile declarations are covered by their dedicated runtime suite, not promoted to new claims by the retained language corpus.", + "Issue #610's reconciliation demonstration harness is covered by its dedicated processor and CLI suite, not promoted to new claims by the retained language corpus.", + "Participant identity, organization ownership, and participant assignment are separated by issue #1338. This retained offline corpus does not establish participant autonomy, execution authority, live backend fidelity, or causal attribution.", + "Participant-local outcome state is verified by the ACT-618 tests; this retained corpus makes no additional outcome-state claim.", + "Backend operation supervision contracts are covered by issue #1360 contract tests; this retained offline corpus establishes no live backend supervision or recovery guarantee.", + "This capture replays the merged issue #1360 and #1357 source; the protocol makes no live backend execution or supervision claim.", + "This capture replays the merged issue #1360 and #1358 source; the protocol makes no live backend execution or supervision claim.", + "Issue #1389 participant inject delivery temporal-subject admission is covered by dedicated compiler tests; this retained matrix makes no new timing or execution claim.", + "Issue #971 adds offline crossing model construction; this retained protocol establishes no crossing equivalence or runtime-realization claim.", + "Issue #1359 control-plane route authority, participant-view scoping, and no-store HTTP boundary are covered by their dedicated HTTP-boundary suite; this retained matrix makes no new exposure or execution claim.", + "Issue #1401 required-evidence media-type coherence is verified by its dedicated suite; this retained matrix makes no new admission or capture claim.", + "Issue #1361 execution and recovery requirements are verified by dedicated policy, composition, and admission tests; this retained corpus establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 maintainability repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 resource type-hint repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The combined issue #1361 execution-policy and hatchling update preserves retained outcomes and bounded claims; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1418 runtime-fact export manifest split changes no contract, schema or behavior; this retained matrix makes no new admission or coverage claim.", + "The issue #1423 inject trigger request and occurrence contracts are new draft carriers that no SDL construct, compiler or runtime path reads; this retained matrix makes no new admission or coverage claim." + ], + "load_bearing_results": { + "failed": 0, + "missing": 0, + "passed": 10, + "total": 10 + }, + "plain_language_outcome": "The retained specification matrix preserves its prior classifications against the issue #1423 inject trigger request and occurrence contracts; bounded claim limits are unchanged.", + "protocol_revision": "1.0.0", + "request_results": [ + { + "concept_count": 6, + "failed_stage_count": 0, + "missing_count": 0, + "request_id": "survey-representative-range", + "status": "demonstrated" + }, + { + "concept_count": 5, + "failed_stage_count": 1, + "missing_count": 1, + "request_id": "cyborg-participant-evaluation", + "status": "partial" + }, + { + "concept_count": 3, + "failed_stage_count": 1, + "missing_count": 1, + "request_id": "vsdl-configurable-infrastructure", + "status": "partial" + }, + { + "concept_count": 2, + "failed_stage_count": 1, + "missing_count": 1, + "request_id": "cyber-dem-federation", + "status": "partial" + } + ], + "snapshot_id": "raes-standardized-specification-coverage-issue-1423-v72", + "snapshot_sha256": "728c996b22dfe6e96a1d75c0ed906029c2eac9196cf4aced3541c6ab428fc074" +} diff --git a/docs/research/specification-coverage/bundles/raes-standardized-specification-coverage-issue-1423-v72.json b/docs/research/specification-coverage/bundles/raes-standardized-specification-coverage-issue-1423-v72.json new file mode 100644 index 000000000..18ffae2b0 --- /dev/null +++ b/docs/research/specification-coverage/bundles/raes-standardized-specification-coverage-issue-1423-v72.json @@ -0,0 +1,10 @@ +{ + "analysis_path": "docs/research/specification-coverage/analysis-v72.json", + "analysis_sha256": "cd5c595d3868c0997631cd2d3145cd8ee3c0693ffa1c5a6fc99fe2af01b136dd", + "bundle_id": "raes-standardized-specification-coverage", + "protocol_path": "docs/research/specification-coverage/protocol-v1.json", + "protocol_sha256": "e97a19e643e94c9e589dca823a63c6ce49d3329fe2a3cb888ab630838ed93125", + "revision": "72.0.0", + "snapshot_path": "docs/research/specification-coverage/execution-snapshot-v72.json", + "snapshot_sha256": "c1c8f8d1c768b0c8497f316f1b7daf63f68c2ba11dbdbb71c4db55d5566e6543" +} diff --git a/docs/research/specification-coverage/execution-snapshot-v72.json b/docs/research/specification-coverage/execution-snapshot-v72.json new file mode 100644 index 000000000..cda0188f7 --- /dev/null +++ b/docs/research/specification-coverage/execution-snapshot-v72.json @@ -0,0 +1,704 @@ +{ + "artifacts": [ + { + "artifact_id": "enterprise-participant-sdl", + "kind": "sdl", + "path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "sha256": "f7a8897beec243e188ee081975006fad32725f469f267db6e75a1e1cf5727032", + "validator": "raes parse, semantic, instantiation/admission, and compiler pipeline" + }, + { + "artifact_id": "port-range-sdl", + "kind": "sdl", + "path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "sha256": "0d5497ec946b863e6985284ec487dde7d7f6bf710a985be51401ac0e5e79dc4f", + "validator": "raes parse, semantic, instantiation/admission, and compiler pipeline" + }, + { + "artifact_id": "experiment-task-contract", + "kind": "experiment-task", + "path": "contracts/fixtures/experiment-core/experiment-task-v1/valid/reference.json", + "sha256": "f3edf713ac6af26bad609136851c6dd434bfb87ce919a2d8c4414c1035deeafc", + "validator": "raes_contracts.contracts.ExperimentTaskModel" + }, + { + "artifact_id": "apparatus-context-contract", + "kind": "experiment-apparatus-context", + "path": "contracts/fixtures/experiment-core/experiment-apparatus-context-v1/valid/reference.json", + "sha256": "e6fa559c5e961f0aab448d0f70dead24aa74fa8ba5f20e1b72f88e11473c9299", + "validator": "raes_contracts.contracts.ExperimentApparatusContextModel" + }, + { + "artifact_id": "backend-profile", + "kind": "backend-profile", + "path": "contracts/profiles/backend/orchestration-capable.json", + "sha256": "f70b8505a5c0055416db86c533e2e5bf08b11e5a514f076223b6d6c36215a092", + "validator": "raes_contracts.backend_profiles.BackendProfileModel" + }, + { + "artifact_id": "known-limitations", + "kind": "documentation", + "path": "docs/explain/sdl/limitations.md", + "sha256": "489eeab3ce682627682311581eb98af9abb9ff42a437145af266eefb71dc7fc4", + "validator": "documentation evidence only" + } + ], + "baseline": { + "release_revision": "1.1.0", + "release_sha256": "4020a1d56c7fe2831cec59ea64a12bbda9d38ccd94f93b916dd90f1a28f17fcb" + }, + "captured_at": "2026-10-11T07:04:16.616377+00:00", + "concept_results": [ + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "range-topology", + "rationale": "SDL nodes and infrastructure own host, network, link, and dependency meaning; the compiler emits canonical node deployment addresses.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed VM declaration.", + "outcome": "passed", + "pointer": "/nodes/shipping-portal", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Links and dependencies resolved.", + "outcome": "passed", + "pointer": "/infrastructure/shipping-portal", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Published instantiated shape admitted.", + "outcome": "passed", + "pointer": "/nodes/shipping-portal", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical deployment address retained.", + "outcome": "passed", + "pointer": "/node_deployments/provision.node.shipping-portal", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/nodes/shipping-portal" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "exercise-roles", + "rationale": "SDL entity roles own exercise responsibility without becoming control-plane identity or authorization.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed red role.", + "outcome": "passed", + "pointer": "/entities/enterprise-participant/role", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Entity references validated.", + "outcome": "passed", + "pointer": "/entities/enterprise-participant", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Role retained after instantiation.", + "outcome": "passed", + "pointer": "/entities/enterprise-participant/role", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Role retained in entity specification.", + "outcome": "passed", + "pointer": "/entity_specs/enterprise-participant/role", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/entities/enterprise-participant/role" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "evaluation-objectives", + "rationale": "SDL objectives own organization ownership, participant assignment, targets, windows, and assertion-based success; measures remain experiment contracts.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed objective declaration.", + "outcome": "passed", + "pointer": "/objectives/demonstrate-handoff", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Owner, participant assignment, targets, assertions, and workflow refs resolved.", + "outcome": "passed", + "pointer": "/objectives/demonstrate-handoff/success", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Objective retained in admitted artifact.", + "outcome": "passed", + "pointer": "/objectives/demonstrate-handoff", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical objective address retained.", + "outcome": "passed", + "pointer": "/objectives/evaluation.objective.demonstrate-handoff", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/objectives/demonstrate-handoff" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "control-workflows", + "rationale": "SDL workflows own the portable control graph and compile to canonical orchestration state contracts.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed control graph.", + "outcome": "passed", + "pointer": "/workflows/yard-recovery", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Step graph and objective refs validated.", + "outcome": "passed", + "pointer": "/workflows/yard-recovery/steps", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Workflow retained after instantiation.", + "outcome": "passed", + "pointer": "/workflows/yard-recovery", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical control graph retained.", + "outcome": "passed", + "pointer": "/workflows/orchestration.workflow.yard-recovery", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/workflows/yard-recovery" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "authored-evidence-expectations", + "rationale": "SDL evidence requirements own portable capture intent and remain distinct from evidence records and measures.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed capture obligation.", + "outcome": "passed", + "pointer": "/evidence_requirements/objective-truth-evidence", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Source refs and bindings validated.", + "outcome": "passed", + "pointer": "/evidence_requirements/objective-truth-evidence", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Evidence intent retained in admitted artifact.", + "outcome": "passed", + "pointer": "/evidence_requirements/objective-truth-evidence", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + } + ], + "typed_pointer": "/evidence_requirements/objective-truth-evidence" + }, + { + "backend_support": "profile-bound", + "backend_vocabulary_occurrences": [], + "classification": "profile-or-manifest-constraint", + "completeness_disposition": "implemented", + "concept_id": "apparatus-selection-constraints", + "rationale": "The experiment task contract binds processor/backend identities, manifest refs, and capabilities outside SDL.", + "stage_results": [ + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-task-v1/valid/reference.json", + "diagnostic_codes": [], + "note": "Closed ExperimentTaskModel validated.", + "outcome": "passed", + "pointer": "/apparatus_constraints/allowed_backend_refs/0", + "stage_id": "contract", + "validation_strength": "contract" + } + ], + "typed_pointer": "/apparatus_constraints/allowed_backend_refs/0" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "participant-agent", + "rationale": "SDL agents own participant entity, knowledge, actions, observation boundaries, and operating scope.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed participant declaration.", + "outcome": "passed", + "pointer": "/agents/participant-agent", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Participant refs and scope validated.", + "outcome": "passed", + "pointer": "/agents/participant-agent/observation_boundaries", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Participant retained in admitted artifact.", + "outcome": "passed", + "pointer": "/agents/participant-agent", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Compiled participant scope retained.", + "outcome": "passed", + "pointer": "/agent_specs/participant-agent", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/agents/participant-agent" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "participant-action-contract", + "rationale": "The action contract declares portable preconditions, effects, observations, evidence, and failure classes without a runner command.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed action contract.", + "outcome": "passed", + "pointer": "/action_contracts/probe-customer-portal-login", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Action refs and evidence bindings validated.", + "outcome": "passed", + "pointer": "/action_contracts/probe-customer-portal-login/effects", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Action retained in admitted artifact.", + "outcome": "passed", + "pointer": "/action_contracts/probe-customer-portal-login", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical action address retained.", + "outcome": "passed", + "pointer": "/action_contracts/participant.action-contract.probe-customer-portal-login", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/action_contracts/probe-customer-portal-login" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "participant-observation-boundary", + "rationale": "The observation boundary separately declares visible, hidden, and evidence-only information with transition rules.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed observation boundary.", + "outcome": "passed", + "pointer": "/observation_boundaries/participant-view", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Information refs and transitions validated.", + "outcome": "passed", + "pointer": "/observation_boundaries/participant-view/view_rules", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Boundary retained in admitted artifact.", + "outcome": "passed", + "pointer": "/observation_boundaries/participant-view", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical boundary address retained.", + "outcome": "passed", + "pointer": "/observation_boundaries/participant.observation-boundary.participant-view", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/observation_boundaries/participant-view" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "evaluation-measure", + "rationale": "ExperimentTaskModel owns metric construct, unit, direction, aggregation, and evidence requirements outside SDL objectives.", + "stage_results": [ + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-task-v1/valid/reference.json", + "diagnostic_codes": [], + "note": "Closed task contract validated.", + "outcome": "passed", + "pointer": "/evaluation_protocol/metric_definitions/foothold-achieved", + "stage_id": "contract", + "validation_strength": "contract" + } + ], + "typed_pointer": "/evaluation_protocol/metric_definitions/foothold-achieved" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "missing", + "completeness_disposition": "documented-gap", + "concept_id": "participant-tool-affordance", + "rationale": "This preregistered matrix has no tested carrier for participant tool affordances. The retained missing classification records missing coverage evidence, not the absence of current participant-behavior capabilities.", + "stage_results": [ + { + "artifact_path": "docs/explain/sdl/limitations.md", + "diagnostic_codes": [], + "note": "The preregistered carrier slot was not run; metadata does not substitute for a typed coverage test.", + "outcome": "not_run", + "pointer": null, + "stage_id": "authored", + "validation_strength": "not-applicable" + } + ], + "typed_pointer": null + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "resource-constrained-topology", + "rationale": "SDL node resources and infrastructure dependencies express portable resource intent without provider resource identifiers.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed CPU and memory declaration.", + "outcome": "passed", + "pointer": "/nodes/shipping-portal/resources", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Resource-bearing topology validated.", + "outcome": "passed", + "pointer": "/infrastructure/shipping-portal", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Constraints retained in admitted artifact.", + "outcome": "passed", + "pointer": "/nodes/shipping-portal/resources", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Deployment specification retains resource intent.", + "outcome": "passed", + "pointer": "/node_deployments/provision.node.shipping-portal", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/nodes/shipping-portal/resources" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "missing", + "completeness_disposition": "documented-gap", + "concept_id": "formal-constraint-satisfiability", + "rationale": "This coverage matrix did not exercise a solver-backed carrier. The separate formal-semantic-validation release demonstrates its bounded finite-domain profile; that result is not silently imported into this protocol's missing carrier slot.", + "stage_results": [ + { + "artifact_path": "docs/explain/sdl/limitations.md", + "diagnostic_codes": [], + "note": "No coverage-carrier execution was performed here; independent solver evidence does not change this preregistered denominator.", + "outcome": "not_run", + "pointer": null, + "stage_id": "semantic", + "validation_strength": "not-applicable" + } + ], + "typed_pointer": null + }, + { + "backend_support": "profile-bound", + "backend_vocabulary_occurrences": [ + { + "allowed": true, + "artifact_path": "source:vsdl-paper", + "pointer": "source sections 4-5", + "reason": "Legitimate VSDL realization vocabulary, not RAES core SDL structure.", + "term": "OpenStack/Terraform/Packer" + } + ], + "classification": "deliberately-backend-specific", + "completeness_disposition": "external", + "concept_id": "provider-specific-provisioning", + "rationale": "Provider image selection and provisioning engines are realization mechanics and therefore remain outside core SDL.", + "stage_results": [ + { + "artifact_path": "contracts/profiles/backend/orchestration-capable.json", + "diagnostic_codes": [], + "note": "The portable boundary requires backend contracts; it does not standardize a provider engine.", + "outcome": "not_applicable", + "pointer": "/required_contracts", + "stage_id": "realization-disclosure", + "validation_strength": "profile" + } + ], + "typed_pointer": null + }, + { + "backend_support": "profile-bound", + "backend_vocabulary_occurrences": [], + "classification": "profile-or-manifest-constraint", + "completeness_disposition": "implemented", + "concept_id": "apparatus-clock-context", + "rationale": "ExperimentApparatusContextModel records clock authority, time domain, and synchronization as apparatus facts outside scenario meaning.", + "stage_results": [ + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-apparatus-context-v1/valid/reference.json", + "diagnostic_codes": [], + "note": "Closed apparatus context contract validated.", + "outcome": "passed", + "pointer": "/clocks/0", + "stage_id": "contract", + "validation_strength": "contract" + } + ], + "typed_pointer": "/clocks/0" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "missing", + "completeness_disposition": "documented-gap", + "concept_id": "federated-object-event-exchange", + "rationale": "The federated cyber object/event exchange carrier was not exercised by this preregistered matrix. Runtime event internals are not treated as equivalent evidence.", + "stage_results": [ + { + "artifact_path": "docs/explain/sdl/limitations.md", + "diagnostic_codes": [], + "note": "The missing coverage-carrier test is recorded explicitly, without inferring an ecosystem-wide capability absence.", + "outcome": "not_run", + "pointer": null, + "stage_id": "contract", + "validation_strength": "not-applicable" + } + ], + "typed_pointer": null + } + ], + "deviations": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "baseline_sha256": "54ba1a60220e27a55da9cd2a407d7d3ab836fa54460d0b0c6cad87c2e744ddbb", + "rationale": "Migrate participant affiliations and explicit objective assignment, retaining organizational intent and portable action-contract declarations without granting execution authority.", + "retest_sha256": "f7a8897beec243e188ee081975006fad32725f469f267db6e75a1e1cf5727032" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "baseline_sha256": "a27c7a64e0c5c618fadaccafdf1a4e71600170a8b77b983190822b5141f00dec", + "rationale": "Migrate participant affiliations and explicit objective assignment, retaining organizational intent and portable action-contract declarations without granting execution authority.", + "retest_sha256": "0d5497ec946b863e6985284ec487dde7d7f6bf710a985be51401ac0e5e79dc4f" + }, + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-task-v1/valid/reference.json", + "baseline_sha256": "21952a752f4e8581a9fc3b872e4bc308150548170d38bcfc83dbbe35ff5e0b9f", + "rationale": "Replay the retained preregistered artifact against the current evidence-provenance validation implementation.", + "retest_sha256": "f3edf713ac6af26bad609136851c6dd434bfb87ce919a2d8c4414c1035deeafc" + }, + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-apparatus-context-v1/valid/reference.json", + "baseline_sha256": "9536d897a09cbc6920e667e4f8f9371e51307aa0b3b5ff3c7de682dd783420ab", + "rationale": "Replay the retained preregistered artifact against the current evidence-provenance validation implementation.", + "retest_sha256": "e6fa559c5e961f0aab448d0f70dead24aa74fa8ba5f20e1b72f88e11473c9299" + }, + { + "artifact_path": "docs/explain/sdl/limitations.md", + "baseline_sha256": "129cf17810aad4c51988bc872e28fe43ae95019a80053c42d800ff7e2b9cc93e", + "rationale": "Correct historical mandatory-profile guidance after issue #1207; retain the preregistered missing-concept classifications and coverage limits.", + "retest_sha256": "489eeab3ce682627682311581eb98af9abb9ff42a437145af266eefb71dc7fc4" + } + ], + "execution_status": "complete", + "implementation_surfaces": [ + { + "content_sha256": "004c88cd6754c7b0f2552fc965f66425d1d1b2a5c726b3d3d70816dc8abb610c", + "path": "implementations/python/packages/raes_contracts", + "surface_id": "contract-models" + }, + { + "content_sha256": "e947f59695e907f5af899a6bc4bde60e629620aa7c4a69a41e074ba335758c7a", + "path": "implementations/python/packages/raes_processor", + "surface_id": "processor-pipeline" + }, + { + "content_sha256": "51688dbe152fb4bbeacd7f8443a3f1fbc7a09b1b898adb134be0e5b4edec28ab", + "path": "implementations/python/packages/raes", + "surface_id": "sdl-pipeline" + } + ], + "limitations": [ + "The execution validates the pinned reference implementation and published contracts, not an independent backend.", + "Repository-owned examples are exact execution artifacts but are not themselves the literature-derived request corpus; the protocol's requests and concepts are.", + "No live range, participant, simulator federation, or provider provisioning engine was executed.", + "Missing concepts remain frozen in this snapshot and require separately scoped product work before a later rerun.", + "This capture replays the retained protocol after EXP-732 run, apparatus, measurement-channel, and augmentation-producer provenance validation; it adds no independent backend or universal provenance assurance claim.", + "Materialization attestation is covered by its dedicated regression suite, not a new claim in this preregistered matrix.", + "This capture refreshes the corrected runtime limitations prose for issue #959; the protocol, coverage classifications and implementation source are unchanged.", + "This capture replays open-by-default augmentation scope integrated with the EXP-731 evidence refinements after composition type refinement; it does not evaluate native backend scope enforcement or broaden the preregistered coverage claims.", + "This capture replays the retained protocol after merging ACT-612 participant relationships with open-by-default augmentation scope; it adds no claim of realized participant relationships or native backend scope enforcement.", + "This capture replays issue #1299 partial listener descriptions on the integrated source state; endpoint completeness and backend admission remain outside this protocol's claims.", + "This capture also binds authoring-adapter semantic conformance to the integrated source; adapter transport behavior remains outside this protocol's claims.", + "Reviewed OCI mirror and pre-seed admission is covered by its own regression suites and the development artifact policy gate, not a new claim in this preregistered matrix.", + "This capture binds issue #1297 service-manager identity, native-name, and explicitly selected systemd-state contract changes to the integrated source. It exercises no live service manager and adds no backend-execution claim.", + "This capture replays the retained specification-coverage protocol after API-404 startup reconciliation added an operational recovery-observation contract. It does not evaluate crash recovery, classify provider effects, or broaden EXP-715 experiment-observation claims.", + "This capture binds API-404 single-owner store admission and immutable target/run scope to the integrated source. The retained offline protocol does not exercise process leases, SQLite lifecycle ordering, or crash recovery.", + "This capture binds issue #1015 deterministic mixed and staged trial admission to the integrated source. The retained offline language corpus does not execute mixed runtimes, phase transitions, backend handoff, or scheduler-driven realization.", + "This replay binds issue #1186 offline control-plane maintenance, readiness, and bounded audit code to the integrated source. The retained language corpus does not execute store recovery, HTTP health behavior, or audit redaction.", + "Issue #1187 control-plane crash/profile conformance and HTTP security changes are covered by their dedicated regression suite, not promoted to new claims by this retained corpus.", + "Issue #1189 control-plane profile declarations are covered by their dedicated runtime suite, not promoted to new claims by the retained language corpus.", + "Issue #1016 mixed-runtime coordination is covered by its dedicated runtime suite. The retained language corpus does not execute mixed providers or establish backend-native realization, multi-controller coordination, IFC, or equivalence.", + "Issue #610's reconciliation demonstration harness is covered by its dedicated processor and CLI suite, not promoted to new claims by the retained language corpus.", + "Participant identity, organization ownership, and participant assignment are separated by issue #1338. This retained offline corpus does not establish participant autonomy, execution authority, live backend fidelity, or causal attribution.", + "Issue #1361 execution and recovery requirements are verified by dedicated policy, composition, and admission tests; this retained corpus establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 maintainability repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 resource type-hint repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The combined issue #1361 execution-policy and hatchling update preserves retained outcomes and bounded claims; it establishes no live recovery, continuation, or trial-allocation guarantee." + ], + "protocol_revision": "1.0.0", + "protocol_sha256": "e97a19e643e94c9e589dca823a63c6ce49d3329fe2a3cb888ab630838ed93125", + "raes_revision": "f0215beecd728c8941b6bfd520ac0c4827aaf81a", + "snapshot_id": "raes-standardized-specification-coverage-issue-1423-v72", + "snapshot_revision": "72.0.0", + "source_state": { + "base_revision": "f0215beecd728c8941b6bfd520ac0c4827aaf81a", + "checkout_state": "modified", + "implementation_digest": "e9b23d9653f2c38214c03042f4c83e3356ae0e4e4f7d111cf2fadf0ee70f4690", + "profile": "python-reference-source/v2" + } +} diff --git a/docs/research/specification-coverage/index.md b/docs/research/specification-coverage/index.md index 55b1959de..cdd5043ba 100644 --- a/docs/research/specification-coverage/index.md +++ b/docs/research/specification-coverage/index.md @@ -292,7 +292,7 @@ the port scenario. Historical captures and archived example bytes are retained. The matrix classifications and untested concepts are unchanged; no execution authority, successful action, or live backend fidelity is inferred. -Current validation requires release 71.0.0 and rejects duplicate or unsupported +Current validation requires release 72.0.0 and rejects duplicate or unsupported future revisions. It executes current artifacts, requires exact source and package hashes, and checks all passing stage pointers. `source_state` discloses the base Git commit, modified checkout state, and exact implementation digest; @@ -546,3 +546,9 @@ export manifest split in [`execution-snapshot-v71.json`](execution-snapshot-v71.json) and [`analysis-v71.json`](analysis-v71.json). Classifications and claim limits remain unchanged. + +Release 72.0.0 replays the retained matrix against the issue #1423 inject +trigger request and occurrence contracts in +[`execution-snapshot-v72.json`](execution-snapshot-v72.json) and +[`analysis-v72.json`](analysis-v72.json). Classifications and claim limits +remain unchanged. diff --git a/implementations/python/tests/test_formal_semantic_validation.py b/implementations/python/tests/test_formal_semantic_validation.py index b35015af1..e66fe69a1 100644 --- a/implementations/python/tests/test_formal_semantic_validation.py +++ b/implementations/python/tests/test_formal_semantic_validation.py @@ -151,6 +151,7 @@ def test_atomic_release_index_validates_every_historical_bundle() -> None: "70.0.0", "71.0.0", "72.0.0", + "73.0.0", ] assert all(validate_release_bundle(REPO_ROOT, release) == [] for release in releases) @@ -159,10 +160,10 @@ def test_atomic_release_index_validates_every_historical_bundle() -> None: def test_current_retest_bundle_is_coherent_and_clean() -> None: release, protocol, corpus, snapshot, analysis = copy_bundle(load_retest_bundle, REPO_ROOT) - assert release.manifest["revision"] == "72.0.0" + assert release.manifest["revision"] == "73.0.0" assert protocol["revision"] == "2.0.0" assert corpus["revision"] == "4.0.0" - assert snapshot["baseline"]["release_revision"] == "71.0.0" + assert snapshot["baseline"]["release_revision"] == "72.0.0" assert snapshot["deviations"] == [] assert validate_retest_bundle(REPO_ROOT, release, protocol, corpus, snapshot, analysis) == [] diff --git a/implementations/python/tests/test_issue_989_versioned_evidence.py b/implementations/python/tests/test_issue_989_versioned_evidence.py index 31f182771..11ffe7b84 100644 --- a/implementations/python/tests/test_issue_989_versioned_evidence.py +++ b/implementations/python/tests/test_issue_989_versioned_evidence.py @@ -241,18 +241,18 @@ def _stub_release(revision: str, *, protocol_revision: str = "2.0.0"): [ pytest.param([], "selects no v2 retest release", id="no-release"), pytest.param( - [_stub_release("70.0.0"), _stub_release("71.0.0")], - "must be the explicit 72.0.0 retest", + [_stub_release("71.0.0"), _stub_release("72.0.0")], + "must be the explicit 73.0.0 retest", id="stale-current", ), pytest.param( - [_stub_release("71.0.0"), _stub_release("73.0.0")], - "must be the explicit 72.0.0 retest", + [_stub_release("72.0.0"), _stub_release("74.0.0")], + "must be the explicit 73.0.0 retest", id="unsupported-future", ), pytest.param( - [_stub_release("72.0.0", protocol_revision="1.0.0")], - "must be the explicit 72.0.0 retest", + [_stub_release("73.0.0", protocol_revision="1.0.0")], + "must be the explicit 73.0.0 retest", id="wrong-protocol", ), ], @@ -269,8 +269,8 @@ def test_current_formal_release_selection_is_explicit(monkeypatch, releases, mes def test_current_formal_release_selection_returns_the_explicit_retest(monkeypatch): from tools.formal_semantic_validation import _loading - current = _stub_release("72.0.0") - monkeypatch.setattr(_loading, "load_release_bundles", lambda _root: [_stub_release("71.0.0"), current]) + current = _stub_release("73.0.0") + monkeypatch.setattr(_loading, "load_release_bundles", lambda _root: [_stub_release("72.0.0"), current]) assert _loading.load_retest_bundle(ROOT)[0] is current @@ -282,7 +282,7 @@ def test_latest_current_release_is_versioned_and_strict(monkeypatch): from tools.formal_semantic_validation._releases import validate_retest_bundle release, protocol, corpus, snapshot, analysis = copy_bundle(load_retest_bundle, ROOT) - assert release.manifest["revision"] == "72.0.0" + assert release.manifest["revision"] == "73.0.0" original = _retest.replay_case def changed_result(root, case): @@ -335,7 +335,7 @@ def test_specification_current_capture_does_not_accept_old_artifact_digest(artif from tools.check_specification_coverage import load_bundle, validate_bundle manifest, protocol, snapshot, analysis = copy_bundle(load_bundle, ROOT) - assert manifest["revision"] == "71.0.0" + assert manifest["revision"] == "72.0.0" snapshot = deepcopy(snapshot) artifact = next(a for a in snapshot["artifacts"] if a["artifact_id"] == artifact_id) artifact["sha256"] = old_digest @@ -576,6 +576,7 @@ def test_no_capture_can_be_silently_dropped(monkeypatch, family, removed): "70.0.0", "71.0.0", "72.0.0", + "73.0.0", ] if family == "formal" else [ @@ -651,6 +652,7 @@ def test_no_capture_can_be_silently_dropped(monkeypatch, family, removed): "69.0.0", "70.0.0", "71.0.0", + "72.0.0", ] ) revisions.pop(-1 if removed == "current" else 0) diff --git a/implementations/python/tests/test_specification_coverage.py b/implementations/python/tests/test_specification_coverage.py index 9993be42a..38423268d 100644 --- a/implementations/python/tests/test_specification_coverage.py +++ b/implementations/python/tests/test_specification_coverage.py @@ -53,7 +53,7 @@ def test_immutable_bundle_index_preserves_concurrent_captures() -> None: bundles = copy_bundle(load_bundles, REPO_ROOT) assert {manifest["revision"] for manifest, *_rest in bundles} >= {"1.0.0", "1.1.0", "19.0.0"} manifest, *_rest = copy_bundle(load_bundle, REPO_ROOT) - assert manifest["revision"] == "71.0.0" + assert manifest["revision"] == "72.0.0" def test_historical_failures_name_the_revision_specific_documents() -> None: diff --git a/tools/check_specification_coverage.py b/tools/check_specification_coverage.py index 7bf2b9865..4882beabb 100644 --- a/tools/check_specification_coverage.py +++ b/tools/check_specification_coverage.py @@ -176,12 +176,13 @@ def _load_bundle_index(repo_root: Path) -> list[tuple[str, dict[str, object]]]: "69.0.0", "70.0.0", "71.0.0", + "72.0.0", } if ( - dict(records)[current_path].get("revision") != "71.0.0" + dict(records)[current_path].get("revision") != "72.0.0" or {record.get("revision") for _, record in records} != supported_revisions ): - raise ValueError("coverage evidence requires the explicit current 71.0.0 release and supported history") + raise ValueError("coverage evidence requires the explicit current 72.0.0 release and supported history") return records diff --git a/tools/formal_semantic_validation/_baseline.py b/tools/formal_semantic_validation/_baseline.py index ae36ec508..8dbdbe65d 100644 --- a/tools/formal_semantic_validation/_baseline.py +++ b/tools/formal_semantic_validation/_baseline.py @@ -208,6 +208,7 @@ def _selected_baseline_manifest( "70.0.0", "71.0.0", "72.0.0", + "73.0.0", }: expected_corpus_path = "docs/research/formal-semantic-validation/corpus/manifest-v4.json" elif baseline_revision in _V3_CORPUS_REVISIONS: diff --git a/tools/formal_semantic_validation/_loading.py b/tools/formal_semantic_validation/_loading.py index 242714714..1fb2f3bab 100644 --- a/tools/formal_semantic_validation/_loading.py +++ b/tools/formal_semantic_validation/_loading.py @@ -82,6 +82,6 @@ def load_retest_bundle( if not releases: raise ValueError("the formal semantic-validation index selects no v2 retest release") release = max(releases, key=lambda item: revision_key(item.manifest.get("revision"))) - if release.manifest.get("revision") != "72.0.0" or release.protocol.get("revision") != "2.0.0": - raise ValueError("the current formal evidence release must be the explicit 72.0.0 retest") + if release.manifest.get("revision") != "73.0.0" or release.protocol.get("revision") != "2.0.0": + raise ValueError("the current formal evidence release must be the explicit 73.0.0 retest") return release, release.protocol, release.corpus, release.snapshot, release.analysis diff --git a/tools/formal_semantic_validation/_release_revisions.py b/tools/formal_semantic_validation/_release_revisions.py index b17c4b61e..d311e6bbe 100644 --- a/tools/formal_semantic_validation/_release_revisions.py +++ b/tools/formal_semantic_validation/_release_revisions.py @@ -73,9 +73,10 @@ "69.0.0", "70.0.0", "71.0.0", + "72.0.0", } -_SUPPORTED_RETEST_REVISIONS = _HISTORICAL_RETEST_REVISIONS | {"72.0.0"} +_SUPPORTED_RETEST_REVISIONS = _HISTORICAL_RETEST_REVISIONS | {"73.0.0"} _SOURCE_BOUND_RETEST_REVISIONS = _SUPPORTED_RETEST_REVISIONS - {"3.0.0"} _RETEST_BASELINE_REVISIONS = { @@ -150,4 +151,5 @@ "70.0.0": "69.0.0", "71.0.0": "70.0.0", "72.0.0": "71.0.0", + "73.0.0": "72.0.0", } diff --git a/tools/formal_semantic_validation/_releases.py b/tools/formal_semantic_validation/_releases.py index 579df51a6..21aa6de0b 100644 --- a/tools/formal_semantic_validation/_releases.py +++ b/tools/formal_semantic_validation/_releases.py @@ -160,7 +160,7 @@ def validate_release_bundle(repo_root: Path, release: EvidenceRelease) -> list[P release.corpus, release.snapshot, release.analysis, - replay_current=manifest.get("revision") == "72.0.0", + replay_current=manifest.get("revision") == "73.0.0", ) ) else: @@ -290,6 +290,7 @@ def _expected_corpus_revision(release_revision: object) -> str: "70.0.0", "71.0.0", "72.0.0", + "73.0.0", }: expected_corpus_revision = "4.0.0" return expected_corpus_revision @@ -317,7 +318,7 @@ def validate_retest_bundle( return [ _failure( "formal-validation-current-replay-required", - "only releases 3.0.0 through 71.0.0 can use integrated historical validation", + "only releases 3.0.0 through 72.0.0 can use integrated historical validation", snapshot_path, ) ] diff --git a/tools/formal_semantic_validation/_retest.py b/tools/formal_semantic_validation/_retest.py index 0c62a1502..35954a715 100644 --- a/tools/formal_semantic_validation/_retest.py +++ b/tools/formal_semantic_validation/_retest.py @@ -37,7 +37,7 @@ ) from tools.policy.common import PolicyFailure -_SOURCE_STATE_REVISIONS = frozenset(f"{revision}.0.0" for revision in range(4, 73)) +_SOURCE_STATE_REVISIONS = frozenset(f"{revision}.0.0" for revision in range(4, 74)) @dataclasses.dataclass(frozen=True) From 82cdeb62f270949f568442f2314c50fbc3e13b04 Mon Sep 17 00:00:00 2001 From: Brad Edwards Date: Mon, 12 Oct 2026 00:01:22 +0200 Subject: [PATCH 8/9] fix(contracts): require explicit inject placement discriminators --- .../invalid/missing-event-kind.json | 76 ++ .../invalid/missing-independent-kind.json | 74 ++ .../invalid/missing-schedule-kind.json | 89 +++ .../invalid/missing-event-kind.json | 26 + .../invalid/missing-independent-kind.json | 24 + .../invalid/missing-schedule-kind.json | 39 + .../entries/inject-occurrence-v1.json | 6 +- .../entries/inject-trigger-request-v1.json | 6 +- .../control-plane/inject-occurrence-v1.json | 8 +- .../inject-trigger-request-v1.json | 8 +- .../reference/inject-occurrence-contracts.md | 4 + .../analysis-v76.json | 165 ++++ .../bundles/retest-v76.json | 122 +++ .../execution-snapshot-v76.json | 652 ++++++++++++++++ .../formal-semantic-validation/index.md | 13 +- .../README.md | 5 +- .../specification-coverage/analysis-v75.json | 114 +++ ...fication-coverage-issue-1423-sync-v75.json | 10 + .../execution-snapshot-v75.json | 706 ++++++++++++++++++ docs/research/specification-coverage/index.md | 13 +- .../contracts/inject_occurrence.py | 6 +- .../tests/test_formal_semantic_validation.py | 5 +- .../test_issue_989_versioned_evidence.py | 22 +- .../tests/test_specification_coverage.py | 2 +- tools/check_specification_coverage.py | 5 +- tools/formal_semantic_validation/_baseline.py | 1 + tools/formal_semantic_validation/_loading.py | 4 +- .../_release_revisions.py | 4 +- tools/formal_semantic_validation/_releases.py | 5 +- tools/formal_semantic_validation/_retest.py | 2 +- 30 files changed, 2174 insertions(+), 42 deletions(-) create mode 100644 contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-event-kind.json create mode 100644 contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-independent-kind.json create mode 100644 contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-schedule-kind.json create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/missing-event-kind.json create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/missing-independent-kind.json create mode 100644 contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/missing-schedule-kind.json create mode 100644 docs/research/formal-semantic-validation/analysis-v76.json create mode 100644 docs/research/formal-semantic-validation/bundles/retest-v76.json create mode 100644 docs/research/formal-semantic-validation/execution-snapshot-v76.json create mode 100644 docs/research/specification-coverage/analysis-v75.json create mode 100644 docs/research/specification-coverage/bundles/raes-standardized-specification-coverage-issue-1423-sync-v75.json create mode 100644 docs/research/specification-coverage/execution-snapshot-v75.json diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-event-kind.json b/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-event-kind.json new file mode 100644 index 000000000..6f9d68771 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-event-kind.json @@ -0,0 +1,76 @@ +{ + "schema_version": "inject-occurrence/v1", + "operation_id": "operation-release-1", + "request": { + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": { + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" + }, + "admission": { + "actor_id": "researcher-1", + "authorization_scope": [ + "role:operator" + ], + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "operation_kind": "orchestration", + "request_commitment": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "parent_operation_id": null + }, + "admission_evidence": [ + { + "contract_id": "proposition-truth-result-v1", + "artifact_id": "precondition-results-1", + "digest": "sha256:3333333333333333333333333333333333333333333333333333333333333333" + } + ], + "store_revision": "store-revision-41", + "order": { + "scope": "run:environment-1", + "predecessor": "order-head-9", + "position": 10 + }, + "scenario": { + "contract_id": "instantiated-scenario-v1", + "artifact_id": "external-trigger-environment", + "digest": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "source": { + "contract_id": "associated-artifact-manifest-v1", + "artifact_id": "release-notice-source", + "digest": "sha256:5555555555555555555555555555555555555555555555555555555555555555" + }, + "realization": { + "contract_id": "backend-manifest-v2", + "artifact_id": "reference-realization", + "digest": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + }, + "evidence_requirements": [ + { + "contract_id": "runtime-snapshot-v1", + "artifact_id": "readback-requirement-1", + "digest": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + ] +} diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-independent-kind.json b/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-independent-kind.json new file mode 100644 index 000000000..45b3b2606 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-independent-kind.json @@ -0,0 +1,74 @@ +{ + "schema_version": "inject-occurrence/v1", + "operation_id": "operation-release-1", + "request": { + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": {}, + "input_ref": null, + "expected_head": "order-head-9" + }, + "admission": { + "actor_id": "researcher-1", + "authorization_scope": [ + "role:operator" + ], + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "operation_kind": "orchestration", + "request_commitment": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "parent_operation_id": null + }, + "admission_evidence": [ + { + "contract_id": "proposition-truth-result-v1", + "artifact_id": "precondition-results-1", + "digest": "sha256:3333333333333333333333333333333333333333333333333333333333333333" + } + ], + "store_revision": "store-revision-41", + "order": { + "scope": "run:environment-1", + "predecessor": "order-head-9", + "position": 10 + }, + "scenario": { + "contract_id": "instantiated-scenario-v1", + "artifact_id": "external-trigger-environment", + "digest": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "source": { + "contract_id": "associated-artifact-manifest-v1", + "artifact_id": "release-notice-source", + "digest": "sha256:5555555555555555555555555555555555555555555555555555555555555555" + }, + "realization": { + "contract_id": "backend-manifest-v2", + "artifact_id": "reference-realization", + "digest": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + }, + "evidence_requirements": [ + { + "contract_id": "runtime-snapshot-v1", + "artifact_id": "readback-requirement-1", + "digest": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + ] +} diff --git a/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-schedule-kind.json b/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-schedule-kind.json new file mode 100644 index 000000000..ba6ec5d27 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-occurrence-v1/invalid/missing-schedule-kind.json @@ -0,0 +1,89 @@ +{ + "schema_version": "inject-occurrence/v1", + "operation_id": "operation-handover-1", + "request": { + "schema_version": "inject-trigger-request/v1", + "request_key": "slot-key-1", + "occurrence_id": "handover-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:exercise-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.handover", + "bindings": [ + { + "binding": "orchestration.inject-binding.workstation.handover", + "node": "provision.node.workstation", + "instance": "workstation-1", + "revision": "realization-r3" + }, + { + "binding": "orchestration.inject-binding.workstation.handover", + "node": "provision.node.workstation", + "instance": "workstation-2", + "revision": "realization-r3" + } + ], + "placement": { + "event": "orchestration.event.shift-change", + "script": "orchestration.script.day-one", + "story": "orchestration.story.exercise", + "slot": "day-one/shift-change/1" + }, + "input_ref": { + "contract_id": "handover-input-v1", + "artifact_id": "handover-input-1", + "digest": "sha256:8888888888888888888888888888888888888888888888888888888888888888" + }, + "expected_head": "order-head-19" + }, + "admission": { + "actor_id": "scheduler-1", + "authorization_scope": [ + "role:operator" + ], + "target_scope": "target:reference", + "run_scope": "run:exercise-1", + "operation_kind": "orchestration", + "request_commitment": "sha256:2222222222222222222222222222222222222222222222222222222222222222", + "parent_operation_id": null + }, + "admission_evidence": [ + { + "contract_id": "proposition-truth-result-v1", + "artifact_id": "precondition-results-1", + "digest": "sha256:3333333333333333333333333333333333333333333333333333333333333333" + } + ], + "store_revision": "store-revision-41", + "order": { + "scope": "run:exercise-1", + "predecessor": "order-head-19", + "position": 20 + }, + "scenario": { + "contract_id": "instantiated-scenario-v1", + "artifact_id": "external-trigger-environment", + "digest": "sha256:4444444444444444444444444444444444444444444444444444444444444444" + }, + "source": { + "contract_id": "associated-artifact-manifest-v1", + "artifact_id": "release-notice-source", + "digest": "sha256:5555555555555555555555555555555555555555555555555555555555555555" + }, + "realization": { + "contract_id": "backend-manifest-v2", + "artifact_id": "reference-realization", + "digest": "sha256:6666666666666666666666666666666666666666666666666666666666666666" + }, + "evidence_requirements": [ + { + "contract_id": "runtime-snapshot-v1", + "artifact_id": "readback-requirement-1", + "digest": "sha256:7777777777777777777777777777777777777777777777777777777777777777" + } + ] +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/missing-event-kind.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/missing-event-kind.json new file mode 100644 index 000000000..1a5d908bc --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/missing-event-kind.json @@ -0,0 +1,26 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": { + "event": "orchestration.event.gate" + }, + "input_ref": null, + "expected_head": "order-head-9" +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/missing-independent-kind.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/missing-independent-kind.json new file mode 100644 index 000000000..31e980410 --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/missing-independent-kind.json @@ -0,0 +1,24 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "researcher-release-key-1", + "occurrence_id": "release-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:environment-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.release", + "bindings": [ + { + "binding": "orchestration.inject-binding.host.release", + "node": "provision.node.host", + "instance": "host-1", + "revision": "realization-r1" + } + ], + "placement": {}, + "input_ref": null, + "expected_head": "order-head-9" +} diff --git a/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/missing-schedule-kind.json b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/missing-schedule-kind.json new file mode 100644 index 000000000..5c6ae199d --- /dev/null +++ b/contracts/fixtures/control-plane/inject-trigger-request-v1/invalid/missing-schedule-kind.json @@ -0,0 +1,39 @@ +{ + "schema_version": "inject-trigger-request/v1", + "request_key": "slot-key-1", + "occurrence_id": "handover-occurrence-1", + "target_scope": "target:reference", + "run_scope": "run:exercise-1", + "plan": { + "contract_id": "orchestration-plan-v1", + "artifact_id": "orchestration-plan-1", + "digest": "sha256:1111111111111111111111111111111111111111111111111111111111111111" + }, + "inject": "orchestration.inject.handover", + "bindings": [ + { + "binding": "orchestration.inject-binding.workstation.handover", + "node": "provision.node.workstation", + "instance": "workstation-1", + "revision": "realization-r3" + }, + { + "binding": "orchestration.inject-binding.workstation.handover", + "node": "provision.node.workstation", + "instance": "workstation-2", + "revision": "realization-r3" + } + ], + "placement": { + "event": "orchestration.event.shift-change", + "script": "orchestration.script.day-one", + "story": "orchestration.story.exercise", + "slot": "day-one/shift-change/1" + }, + "input_ref": { + "contract_id": "handover-input-v1", + "artifact_id": "handover-input-1", + "digest": "sha256:8888888888888888888888888888888888888888888888888888888888888888" + }, + "expected_head": "order-head-19" +} diff --git a/contracts/schema-publication/entries/inject-occurrence-v1.json b/contracts/schema-publication/entries/inject-occurrence-v1.json index fe0adf079..24d6adeb8 100644 --- a/contracts/schema-publication/entries/inject-occurrence-v1.json +++ b/contracts/schema-publication/entries/inject-occurrence-v1.json @@ -2,9 +2,9 @@ "contract_id": "inject-occurrence-v1", "schema_path": "contracts/schemas/control-plane/inject-occurrence-v1.json", "stability": "draft", - "content_hash": "019f648c5501b339a7e37997d91c06d49d879f8c15757d901a3c052bb36abc62", + "content_hash": "05e6f50a966523de1b13844a780f7cc77d3f33836aa1d1959c1ac21f9addeb00", "last_change": { - "summary": "Publish the ADR-112 claimed inject occurrence with actor-bound admission, unrebased order and distinct claims (#1423, #1366).", - "content_hash": "019f648c5501b339a7e37997d91c06d49d879f8c15757d901a3c052bb36abc62" + "summary": "Require an explicit placement kind in the ADR-112 inject contract (#1423, #1366).", + "content_hash": "05e6f50a966523de1b13844a780f7cc77d3f33836aa1d1959c1ac21f9addeb00" } } diff --git a/contracts/schema-publication/entries/inject-trigger-request-v1.json b/contracts/schema-publication/entries/inject-trigger-request-v1.json index 35ca8a0cd..d16feb46c 100644 --- a/contracts/schema-publication/entries/inject-trigger-request-v1.json +++ b/contracts/schema-publication/entries/inject-trigger-request-v1.json @@ -2,9 +2,9 @@ "contract_id": "inject-trigger-request-v1", "schema_path": "contracts/schemas/control-plane/inject-trigger-request-v1.json", "stability": "draft", - "content_hash": "23f5f644bc570b8224eed543a7cc1d24f6596e2425a097b540162e41ee3a330c", + "content_hash": "9fdf57a62449ea4f5c2018a422023f7d72e5bc3ab501f0bbac5abae23e31cac9", "last_change": { - "summary": "Publish the ADR-112 inject trigger request with compiled node bindings, closed placement and value-free input (#1423, #1366).", - "content_hash": "23f5f644bc570b8224eed543a7cc1d24f6596e2425a097b540162e41ee3a330c" + "summary": "Require an explicit placement kind in the ADR-112 inject contract (#1423, #1366).", + "content_hash": "9fdf57a62449ea4f5c2018a422023f7d72e5bc3ab501f0bbac5abae23e31cac9" } } diff --git a/contracts/schemas/control-plane/inject-occurrence-v1.json b/contracts/schemas/control-plane/inject-occurrence-v1.json index e90a84eff..7d8f62788 100644 --- a/contracts/schemas/control-plane/inject-occurrence-v1.json +++ b/contracts/schemas/control-plane/inject-occurrence-v1.json @@ -16,12 +16,12 @@ }, "kind": { "const": "event", - "default": "event", "title": "Kind", "type": "string" } }, "required": [ + "kind", "event" ], "title": "InjectEventPlacementModel", @@ -33,11 +33,13 @@ "properties": { "kind": { "const": "independent", - "default": "independent", "title": "Kind", "type": "string" } }, + "required": [ + "kind" + ], "title": "InjectIndependentPlacementModel", "type": "object" }, @@ -88,7 +90,6 @@ }, "kind": { "const": "schedule", - "default": "schedule", "title": "Kind", "type": "string" }, @@ -128,6 +129,7 @@ } }, "required": [ + "kind", "event", "script", "slot" diff --git a/contracts/schemas/control-plane/inject-trigger-request-v1.json b/contracts/schemas/control-plane/inject-trigger-request-v1.json index 94e1b6418..16c30d6bc 100644 --- a/contracts/schemas/control-plane/inject-trigger-request-v1.json +++ b/contracts/schemas/control-plane/inject-trigger-request-v1.json @@ -16,12 +16,12 @@ }, "kind": { "const": "event", - "default": "event", "title": "Kind", "type": "string" } }, "required": [ + "kind", "event" ], "title": "InjectEventPlacementModel", @@ -33,11 +33,13 @@ "properties": { "kind": { "const": "independent", - "default": "independent", "title": "Kind", "type": "string" } }, + "required": [ + "kind" + ], "title": "InjectIndependentPlacementModel", "type": "object" }, @@ -57,7 +59,6 @@ }, "kind": { "const": "schedule", - "default": "schedule", "title": "Kind", "type": "string" }, @@ -97,6 +98,7 @@ } }, "required": [ + "kind", "event", "script", "slot" diff --git a/docs/explain/reference/inject-occurrence-contracts.md b/docs/explain/reference/inject-occurrence-contracts.md index 4d1fb2f02..c9de7337e 100644 --- a/docs/explain/reference/inject-occurrence-contracts.md +++ b/docs/explain/reference/inject-occurrence-contracts.md @@ -27,6 +27,10 @@ under `contracts/schemas/control-plane/` and the examples under | `input_ref` | Optional content-bound reference to an input document that the realization's input contract checks. There are no inline values, and absence means no runtime parameters. | | `expected_head` | The ordering head the caller observed. A stale head is refused, never rebased. | +Every placement requires an explicit `kind` discriminator, including independent +placement. Both the published schemas and the Python models refuse an omitted +discriminator. + ### Binding addresses The compiler renders a node binding as diff --git a/docs/research/formal-semantic-validation/analysis-v76.json b/docs/research/formal-semantic-validation/analysis-v76.json new file mode 100644 index 000000000..3fa35ed6f --- /dev/null +++ b/docs/research/formal-semantic-validation/analysis-v76.json @@ -0,0 +1,165 @@ +{ + "analysis_id": "issue-1423-sync-analysis-v76", + "claim": { + "allowed_evidence": [ + "production parser and semantic-validator results", + "canonical compiled digests", + "participant contract regression tests", + "pinned protocol, corpus, and execution snapshot" + ], + "claim_id": "asr-530-formal-semantic-validation-retest", + "disallowed_evidence": [ + "schema success as semantic proof", + "workflow reachability as network or exploit reachability", + "FM labels as gate outcomes", + "attribution as counterfactual proof", + "formal prose or maintainer confidence alone" + ], + "evidence_artifacts": [ + "docs/research/formal-semantic-validation/protocol-v2.json", + "docs/research/formal-semantic-validation/corpus/manifest-v4.json", + "docs/research/formal-semantic-validation/execution-snapshot-v76.json", + "docs/research/formal-semantic-validation/evidence/finite-domain-satisfiable-v4.json", + "docs/research/formal-semantic-validation/evidence/finite-domain-unsatisfiable-v4.json", + "docs/research/formal-semantic-validation/evidence/typed-exploit-path-valid-v4.json", + "docs/research/formal-semantic-validation/evidence/typed-exploit-path-invalid-v4.json" + ], + "falsification_protocol": "Replay every retained and new case through its production entrypoint, require complete digest and evidence joins, execute participant fixtures, and derive status from the recorded outcomes.", + "objective_fail_criteria": "A supported negative passes, a positive fails, an observation drifts, a required participant case is missing, or weaker evidence is promoted to solver, exploit-path, runtime-stability, or counterfactual assurance.", + "objective_pass_criteria": "Every claim class has positive and negative cases, all supported cases reproduce the frozen outcome, every participant obligation has passing positive and negative fixtures, and unsupported classes remain untested.", + "statement": "At the recorded source-state digest, the retained RAES controls have the bounded statuses recorded here; historical releases are integrity evidence, not current replay evidence.", + "threats_to_validity": [ + "The issue-specific corpus is intentionally small and does not enumerate every validator invariant.", + "The participant fixtures exercise reference production contracts and tests, not every independent backend realization.", + "The replay gate runs on one Python reference configuration and one pinned RAES revision.", + "Unsupported solver-level classes have protocol cases but no executable observations." + ] + }, + "claim_results": [ + { + "case_count": 2, + "claim_class_id": "schema-validity", + "evidence_status": "demonstrated", + "limitations": [ + "Bounded to the named source/model structural controls." + ], + "matching_case_count": 2, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 0 + }, + { + "case_count": 4, + "claim_class_id": "semantic-consistency", + "evidence_status": "partial", + "limitations": [ + "Partial coverage of named static semantics and participant obligations, not universal consistency." + ], + "matching_case_count": 4, + "participant_obligation_count": 7, + "replayable_case_count": 4, + "unsupported_case_count": 0 + }, + { + "case_count": 2, + "claim_class_id": "graph-reachability", + "evidence_status": "partial", + "limitations": [ + "Partial workflow control-flow reachability only; not network, service, or exploit reachability." + ], + "matching_case_count": 2, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 0 + }, + { + "case_count": 4, + "claim_class_id": "constraint-satisfiability", + "evidence_status": "demonstrated", + "limitations": [ + "Demonstrated only for raes-finite-domain-satisfiability-v1 and its pinned solver configuration." + ], + "matching_case_count": 4, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 2 + }, + { + "case_count": 4, + "claim_class_id": "exploit-path-validity", + "evidence_status": "demonstrated", + "limitations": [ + "Demonstrated only for the admitted snapshot, typed graph, query, semantics, and bounded search profile." + ], + "matching_case_count": 4, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 2 + }, + { + "case_count": 2, + "claim_class_id": "determinism-stability", + "evidence_status": "partial", + "limitations": [ + "Partial parse-to-compile repeatability only; runtime and backend determinism are untested." + ], + "matching_case_count": 2, + "participant_obligation_count": 0, + "replayable_case_count": 2, + "unsupported_case_count": 0 + }, + { + "case_count": 2, + "claim_class_id": "counterfactual-necessity", + "evidence_status": "untested", + "limitations": [ + "Untested because no governed intervention or ablation entrypoint ran." + ], + "matching_case_count": 2, + "participant_obligation_count": 0, + "replayable_case_count": 0, + "unsupported_case_count": 2 + } + ], + "corpus_revision": "4.0.0", + "evidence_status": "partial", + "execution_id": "issue-1423-sync-execution-v76", + "generated_at": "2026-10-11T21:58:12.665142+00:00", + "limitations": [ + "Satisfiability is limited to raes-finite-domain-satisfiability-v1 and its exact translation, theory, and Z3 configuration.", + "The subset-minimal unsatisfiable core is not a universal proof certificate.", + "Exploit-path results are limited to the admitted snapshot, normalized graph, query, transition semantics, and bounded search profile.", + "A valid path is not backend execution and an invalid path is not real-world non-exploitability.", + "The production exploit-path JSON loader permits duplicate keys; the research loader rejects them without claiming stronger production behavior.", + "Participant replay inherits the host environment and is not described as hermetic.", + "Counterfactual necessity remains untested.", + "Scoped observation demand is not a claim class in this preregistration and is not promoted to demonstrated by this retest.", + "EXP-732 provenance joins are verified by their dedicated regression suite; this retained corpus makes no universal run, apparatus, source, or augmentation assurance claim.", + "This retained corpus does not establish native backend attestation fidelity; materialization contract checks remain separate operational provenance, not experimental observations.", + "Capture admission and evidence-proof authority are verified by issue-1237 regression tests, not promoted to a new claim class by this retained corpus.", + "Evidence-requirement refinement lineage is outside this retained formal claim set; this retest refreshes integrated source provenance without promoting that feature to a formal claim.", + "Authoring-adapter transport behavior is outside this retained formal claim set.", + "Operational recovery observation and startup reconciliation are verified by their API-404 regression suite, not promoted to a new formal claim class by this retained corpus.", + "Single-owner store admission, immutable target/run scope, and provider shutdown ordering are verified by their API-404 CP-5 regression suite, not promoted to a formal claim by this retained corpus.", + "Mixed and staged trial admission is verified by its SEM-234/SCE-002/API-407 regression suite, not promoted to a new formal claim class by this retained corpus.", + "Offline control-plane maintenance, readiness, and bounded audit behavior are verified by issue #1186 runtime tests, not promoted to a formal claim by this retained corpus.", + "Issue #1187 control-plane crash/profile conformance and HTTP security changes are covered by their dedicated regression suite, not promoted to new claims by this retained corpus.", + "Issue #1189 profile declarations and capability admission are covered by dedicated runtime tests; the retained formal corpus does not execute control-plane profile composition.", + "Issue #1016 mixed-runtime coordination is covered by dedicated runtime tests; the retained formal corpus does not establish backend-native mixed realization, multi-controller coordination, IFC, or equivalence.", + "Issue #610's reconciliation demonstration harness is covered by its dedicated processor and CLI suite, not promoted to new claims by the retained language corpus.", + "Participant identity, organization ownership, and participant assignment are separated by issue #1338. This retained offline corpus does not establish participant autonomy, execution authority, live backend fidelity, or causal attribution.", + "Issue #1389 temporal-subject admission is verified by dedicated compiler tests and adds no new formal-semantic claim to this retained corpus.", + "Issue #971 model construction is verified by its own tests; this retained corpus establishes no participant-crossing equivalence or runtime-realization claim.", + "Issue #1359 control-plane route authority, participant-view scoping, and no-store HTTP boundary are verified by their dedicated HTTP-boundary suite and add no new formal-semantic claim to this retained corpus.", + "Issue #1401 required-evidence media-type coherence is verified by its dedicated suite and adds no new formal-semantic claim to this retained corpus.", + "Issue #1361 execution and recovery requirements are verified by dedicated policy, composition, and admission tests; this retained corpus establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 maintainability repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 resource type-hint repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The combined issue #1361 execution-policy and hatchling update preserves retained outcomes and bounded claims; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1418 runtime-fact export manifest split changes no contract, schema or behavior and adds no new formal-semantic claim.", + "This synchronization adds no mixed-backend runtime execution claim; the issue #1371 tests cover the composition run-scope join.", + "The issue #1423 inject contract discriminator repair is covered by its dedicated fixtures; the retained corpus adds no inject execution, authorization or world-effect claim." + ], + "plain_language_outcome": "The retained formal controls reproduce their prior outcomes after synchronizing the inject trigger and occurrence contracts with dev and requiring explicit placement discriminators. Bounded claim limits are unchanged.", + "protocol_revision": "2.0.0" +} diff --git a/docs/research/formal-semantic-validation/bundles/retest-v76.json b/docs/research/formal-semantic-validation/bundles/retest-v76.json new file mode 100644 index 000000000..5ea0fb615 --- /dev/null +++ b/docs/research/formal-semantic-validation/bundles/retest-v76.json @@ -0,0 +1,122 @@ +{ + "analysis_path": "docs/research/formal-semantic-validation/analysis-v76.json", + "analysis_sha256": "7f88bcaf4b81087c013af8efb324e2290267df055cfbbbec4995e83b69fe0e07", + "artifacts": [ + { + "artifact_id": "finite-domain-satisfiable-v2-input", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/satisfiable-control.sdl.yaml", + "sha256": "0ca9eaba9dc47171f7a042dc6753faa6c820c65ee966538f9d65fac5342202e8" + }, + { + "artifact_id": "finite-domain-satisfiable-v2-evidence", + "kind": "production-evidence", + "path": "docs/research/formal-semantic-validation/evidence/finite-domain-satisfiable-v4.json", + "sha256": "554202313d678046958b5c028e2de26ff03c74895cfac552677eed74e8153add" + }, + { + "artifact_id": "finite-domain-unsatisfiable-v2-input", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/unsatisfiable-control.sdl.yaml", + "sha256": "cfef56a1f56d5f0db9da195377fd75694bdd0f0b92932fdb8fafcbd3f7baf6c5" + }, + { + "artifact_id": "finite-domain-unsatisfiable-v2-evidence", + "kind": "production-evidence", + "path": "docs/research/formal-semantic-validation/evidence/finite-domain-unsatisfiable-v4.json", + "sha256": "c972725ef64822a75a60380afc11f08eac25b7fe9b091d39b058b3c9f7c8031d" + }, + { + "artifact_id": "typed-exploit-path-valid-v2-input", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/exploit-path-valid-v3.json", + "sha256": "0afe635a63db5b6e6380ac70982fd61d09790745d51a10d670321304121e7c39" + }, + { + "artifact_id": "typed-exploit-path-valid-v2-evidence", + "kind": "production-evidence", + "path": "docs/research/formal-semantic-validation/evidence/typed-exploit-path-valid-v4.json", + "sha256": "1b7f55d04db172da32658187c64a88c13b5f4d565267ce2be7cb86a9d04cb70c" + }, + { + "artifact_id": "typed-exploit-path-invalid-v2-input", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/exploit-path-invalid-v3.json", + "sha256": "0b2293d4a8983515ff05c516be6e6b418a4f3f09e055250a00bf15fda861aab3" + }, + { + "artifact_id": "typed-exploit-path-invalid-v2-evidence", + "kind": "production-evidence", + "path": "docs/research/formal-semantic-validation/evidence/typed-exploit-path-invalid-v4.json", + "sha256": "244f895a64f14c10916ab0533ab462ce80a328021cd6a50c30a4aa59266d5533" + }, + { + "artifact_id": "schema-valid-control-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/schema-valid.sdl.yaml", + "sha256": "41a9adffdf9f5f2ccc2f887dcf7b15fba3b47c83a1af15f33db872c4a2449d67" + }, + { + "artifact_id": "schema-unknown-field-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/schema-invalid-unknown-field.sdl.yaml", + "sha256": "51cf62319a86c95a2517995939d1f370573051835e4b55bb6d5beaf049640481" + }, + { + "artifact_id": "semantic-resolved-objective-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/semantic-valid-participant-identity-v2.sdl.yaml", + "sha256": "75834bdc883e2003e1c473870bdf75700978955bb83095c6bd718ba6bd3908a6" + }, + { + "artifact_id": "semantic-dangling-assertion-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/semantic-invalid-dangling-ref-participant-identity-v2.sdl.yaml", + "sha256": "1d25bee5f556054e5f0a518df025e4c62e080e1964035e3c1a12e074d88d3a5d" + }, + { + "artifact_id": "semantic-ambiguous-reference-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/semantic-invalid-ambiguous-ref.sdl.yaml", + "sha256": "653cbd2fd62e220d49fb86f80133884207df5ae6752846345ae3085b93f6e4ed" + }, + { + "artifact_id": "semantic-feature-cycle-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/semantic-invalid-feature-cycle.sdl.yaml", + "sha256": "e1f66d95a9ad039687aec8cccbc8843b514072ff08e006c1b4ca6aa5cd8d4ed1" + }, + { + "artifact_id": "workflow-reachable-control-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/workflow-reachable.sdl.yaml", + "sha256": "54c40ceb98ad47247447d737973b2c55e8fb2045e209c7545c4fb20cf42dc3dc" + }, + { + "artifact_id": "workflow-unreachable-step-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/workflow-unreachable.sdl.yaml", + "sha256": "ef22ef2e260f1a7fd92d286f9b571716436b192ddfd54aea7bdfcfdda4ca52a2" + }, + { + "artifact_id": "compile-repeatability-control-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/determinism-a.sdl.yaml", + "sha256": "0bc40900d598c1af7a405d798ca19710405e53ced262d8733081abf12edf89fe" + }, + { + "artifact_id": "compile-non-vacuity-control-comparison-fixture", + "kind": "corpus-input", + "path": "docs/research/formal-semantic-validation/corpus/determinism-b.sdl.yaml", + "sha256": "d85338f89f20a45515b12da8640173c1a52e47eb17ca0f4f6b4f8f3306e863a1" + } + ], + "bundle_id": "raes-formal-semantic-validation", + "corpus_path": "docs/research/formal-semantic-validation/corpus/manifest-v4.json", + "corpus_sha256": "c57207af72406aa4f70882b9bbeb7cedcc79cf3854c878a95e3eb1fa59ea7a72", + "protocol_path": "docs/research/formal-semantic-validation/protocol-v2.json", + "protocol_sha256": "abf94093e344bf495dfb04e8b0c5985c0beaab8ebb17a75e15c8674fa81b1a7c", + "revision": "76.0.0", + "snapshot_path": "docs/research/formal-semantic-validation/execution-snapshot-v76.json", + "snapshot_sha256": "b28afbe7a0ecb3f80f32ccefb30e7a2b0d7f8aa93618c5b3c306050e1096df42" +} diff --git a/docs/research/formal-semantic-validation/execution-snapshot-v76.json b/docs/research/formal-semantic-validation/execution-snapshot-v76.json new file mode 100644 index 000000000..aaaae8689 --- /dev/null +++ b/docs/research/formal-semantic-validation/execution-snapshot-v76.json @@ -0,0 +1,652 @@ +{ + "baseline": { + "execution_id": "issue-1421-sync-execution-v75", + "release_path": "docs/research/formal-semantic-validation/bundles/retest-v75.json", + "release_revision": "75.0.0", + "release_sha256": "1ad1b1aa63ca3a3d8e0499e21b49a38a2e82353d16b23961f7551804827e0b63" + }, + "captured_at": "2026-10-11T21:58:12.665142+00:00", + "commands": [ + { + "argv": [ + "implementations/python/.venv/bin/python", + "tools/check_formal_semantic_validation.py" + ], + "command_id": "bundle-replay", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/pytest", + "-q", + "implementations/python/tests/test_sem_208_participant_behavior.py::test_hidden_truth_disclosure_is_separate_from_observable_projection", + "implementations/python/tests/test_sem_208_participant_behavior.py::test_hidden_truth_cannot_be_observed_without_explicit_disclosure_rule", + "implementations/python/tests/test_sem_211_participant_action_semantics.py::test_action_contract_declares_sem_211_classes_and_compiles_them", + "implementations/python/tests/test_sem_211_participant_action_semantics.py::test_action_result_rejects_success_when_preconditions_are_unresolved", + "implementations/python/tests/test_run_308_concurrent_participant_execution.py::test_runtime_snapshot_publishes_joint_action_and_time_context_records", + "implementations/python/tests/test_run_308_concurrent_participant_execution.py::test_joint_action_record_contract_rejects_unordered_conflicting_writes", + "implementations/python/tests/test_participant_runtime_invariants.py::test_order_discipline_accepts_supported_order_claim_strengths", + "implementations/python/tests/test_participant_runtime_invariants.py::test_order_discipline_rejects_wall_clock_causality", + "implementations/python/tests/test_sem_212_participant_attribution_semantics.py::test_attribution_edge_round_trips_on_terminal_observation", + "implementations/python/tests/test_sem_212_participant_attribution_semantics.py::test_timestamp_adjacency_cannot_be_reported_as_strong_causality", + "implementations/python/tests/test_sem_215_participant_outcome_interpretation.py::test_outcome_interpretation_rule_parses_and_compiles_explicit_layers", + "implementations/python/tests/test_sem_215_participant_outcome_interpretation.py::test_local_action_success_does_not_imply_objective_success_without_rule_record", + "implementations/python/tests/test_realization_honesty_conformance.py::test_constructive_envelope_runs_positive_and_negative_honesty_probes", + "implementations/python/tests/test_realization_honesty_conformance.py::test_only_native_live_can_support_native_conformance" + ], + "command_id": "participant-fixtures", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/raes", + "processor", + "satisfiability", + "docs/research/formal-semantic-validation/corpus/satisfiable-control.sdl.yaml", + "--profile", + "raes-finite-domain-satisfiability-v1" + ], + "command_id": "finite-domain-satisfiable-v2", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/raes", + "processor", + "satisfiability", + "docs/research/formal-semantic-validation/corpus/unsatisfiable-control.sdl.yaml", + "--profile", + "raes-finite-domain-satisfiability-v1" + ], + "command_id": "finite-domain-unsatisfiable-v2", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/raes", + "processor", + "exploit-path", + "docs/research/formal-semantic-validation/corpus/exploit-path-valid-v3.json", + "--profile", + "raes-exploit-path-analysis-v1" + ], + "command_id": "typed-exploit-path-valid-v2", + "network": "disabled" + }, + { + "argv": [ + "implementations/python/.venv/bin/raes", + "processor", + "exploit-path", + "docs/research/formal-semantic-validation/corpus/exploit-path-invalid-v3.json", + "--profile", + "raes-exploit-path-analysis-v1" + ], + "command_id": "typed-exploit-path-invalid-v2", + "network": "disabled" + } + ], + "configuration_id": "raes-python-reference-offline-v41", + "corpus_revision": "4.0.0", + "deviations": [], + "execution_id": "issue-1423-sync-execution-v76", + "execution_status": "complete", + "observations": [ + { + "actual_outcome": "accepted", + "analysis_profile": null, + "case_id": "schema-valid-control", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/schema-valid.sdl.yaml" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "A passing minimal source does not establish semantic correctness." + ], + "replayable": true, + "result_digest": "f7d364ef384df8a1526b489501835b635021c860793b5764f91d956710d2250c", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "schema-unknown-field", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLParseError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/schema-invalid-unknown-field.sdl.yaml" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "The observation covers one unknown-field defect only." + ], + "replayable": true, + "result_digest": "f55d834b458f8e069e1c69061b4cc0a6d61e0e052bf90c670f2e6a5ad8b5bd98", + "source_digest": null + }, + { + "actual_outcome": "accepted", + "analysis_profile": null, + "case_id": "semantic-resolved-objective", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/semantic-valid-participant-identity-v2.sdl.yaml" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "This is a positive control for one objective-reference slice." + ], + "replayable": true, + "result_digest": "652288785dc09095955ed3649f6407d616fb7c4d4f4188df4ed513ccb7537e0b", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "semantic-dangling-assertion", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLValidationError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/semantic-invalid-dangling-ref-participant-identity-v2.sdl.yaml" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "A single dangling reference does not prove complete semantic coverage." + ], + "replayable": true, + "result_digest": "0207cf616b56708ca9b8c4499d3301abe22dbe52162cf8d58d3bec429d9db024", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "semantic-ambiguous-reference", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLValidationError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/semantic-invalid-ambiguous-ref.sdl.yaml" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "One namespace collision does not enumerate every ambiguity surface." + ], + "replayable": true, + "result_digest": "9da4a87797d228e0012ab6b30459f4892e41aa6f224a9840be035fee4a2eea73", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "semantic-feature-cycle", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLValidationError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/semantic-invalid-feature-cycle.sdl.yaml" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "One static dependency cycle does not establish general constraint satisfiability." + ], + "replayable": true, + "result_digest": "d15dbcd99fb4f20b965d7031b07dd6534576302270399c3fa656d29e7de02b83", + "source_digest": null + }, + { + "actual_outcome": "accepted", + "analysis_profile": null, + "case_id": "workflow-reachable-control", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/workflow-reachable.sdl.yaml" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "The graph is workflow control flow only." + ], + "replayable": true, + "result_digest": "b1b49649b54bd59d4ef357b39cf9158da90f4eae560f8dd756acf97bd0827a06", + "source_digest": null + }, + { + "actual_outcome": "rejected", + "analysis_profile": null, + "case_id": "workflow-unreachable-step", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "SDLValidationError", + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/workflow-unreachable.sdl.yaml" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "The result does not establish network, service, participant, or exploit reachability." + ], + "replayable": true, + "result_digest": "bb931d19346ef9193408ae6c85deb4079704378fc5f00dc5f47a2817cff21943", + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "whole-scenario-satisfiable-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "No governed whole-scenario constraint theory or solver exists." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "whole-scenario-unsatisfiable-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "Local checks cannot produce a whole-scenario unsat certificate." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "valid-exploit-path-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "The issue-168 baseline had no canonical typed attack graph or path-query entrypoint." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "invalid-exploit-path-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "Vulnerability and topology declarations are not an invalid-path proof." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "stable", + "analysis_profile": null, + "case_id": "compile-repeatability-control", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/determinism-a.sdl.yaml" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "The witness ends at compiled output." + ], + "replayable": true, + "result_digest": "d7c098c5d063b8d1b0747e8df5daa90061456065cdda0bbedfa10918442f5daa", + "source_digest": null + }, + { + "actual_outcome": "distinguishable", + "analysis_profile": null, + "case_id": "compile-non-vacuity-control", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/determinism-a.sdl.yaml", + "docs/research/formal-semantic-validation/corpus/determinism-b.sdl.yaml" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "Distinct digests are a non-vacuity control, not semantic non-equivalence proof." + ], + "replayable": true, + "result_digest": "a2fcebba3341592b133af813e8bb8e5f47270418bc58bfd471a89bfbc8ba46da", + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "necessity-witness-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "No governed intervention or ablation protocol exists." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "unsupported", + "analysis_profile": null, + "case_id": "non-necessity-control-request", + "configuration_digest": null, + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": null, + "evidence_artifact_path": null, + "evidence_artifact_sha256": null, + "evidence_digest": null, + "evidence_profile": null, + "evidence_refs": [ + "docs/decisions/issue-168-formal-semantic-validation-reachability-preflight.md" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "Attribution and negative fixtures do not demonstrate non-necessity." + ], + "replayable": false, + "result_digest": null, + "source_digest": null + }, + { + "actual_outcome": "satisfiable", + "analysis_profile": "raes-finite-domain-satisfiability-v1", + "case_id": "finite-domain-satisfiable-v2", + "configuration_digest": "sha256:1204635e17e759e9ad3bd6be2ecb28c6de05c07ead6dfdd15936ed5d3d5b81b2", + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "scenario-satisfiability-evidence/v1", + "evidence_artifact_path": "docs/research/formal-semantic-validation/evidence/finite-domain-satisfiable-v4.json", + "evidence_artifact_sha256": "554202313d678046958b5c028e2de26ff03c74895cfac552677eed74e8153add", + "evidence_digest": "sha256:23c2cae7d95d4cc83d77ca576e3911477b169ecc311c977cb45490345f633b5a", + "evidence_profile": "scenario-satisfiability-evidence/v1", + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/satisfiable-control.sdl.yaml", + "docs/research/formal-semantic-validation/evidence/finite-domain-satisfiable-v4.json", + "specs/formal/scenario-satisfiability/README.md" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "Demonstrates only the pinned finite-domain theory, translation, solver profile, and source." + ], + "replayable": true, + "result_digest": "sha256:23c2cae7d95d4cc83d77ca576e3911477b169ecc311c977cb45490345f633b5a", + "source_digest": "sha256:0ca9eaba9dc47171f7a042dc6753faa6c820c65ee966538f9d65fac5342202e8" + }, + { + "actual_outcome": "unsatisfiable", + "analysis_profile": "raes-finite-domain-satisfiability-v1", + "case_id": "finite-domain-unsatisfiable-v2", + "configuration_digest": "sha256:1204635e17e759e9ad3bd6be2ecb28c6de05c07ead6dfdd15936ed5d3d5b81b2", + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "scenario-satisfiability-evidence/v1", + "evidence_artifact_path": "docs/research/formal-semantic-validation/evidence/finite-domain-unsatisfiable-v4.json", + "evidence_artifact_sha256": "c972725ef64822a75a60380afc11f08eac25b7fe9b091d39b058b3c9f7c8031d", + "evidence_digest": "sha256:317b5cad00aa7f4f7868dca66127611ba19d40ffd86f35815502622814df54c1", + "evidence_profile": "scenario-satisfiability-evidence/v1", + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/unsatisfiable-control.sdl.yaml", + "docs/research/formal-semantic-validation/evidence/finite-domain-unsatisfiable-v4.json", + "specs/formal/scenario-satisfiability/README.md" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "The subset-minimal core is evidence for the pinned translation and solver, not a proof certificate for arbitrary SDL." + ], + "replayable": true, + "result_digest": "sha256:317b5cad00aa7f4f7868dca66127611ba19d40ffd86f35815502622814df54c1", + "source_digest": "sha256:cfef56a1f56d5f0db9da195377fd75694bdd0f0b92932fdb8fafcbd3f7baf6c5" + }, + { + "actual_outcome": "valid-path", + "analysis_profile": "raes-exploit-path-analysis-v1", + "case_id": "typed-exploit-path-valid-v2", + "configuration_digest": "sha256:7f8876d81feb77d3a3239be2fb8337de8885e2744f8786728ba23e4e6027bc0a", + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "exploit-path-analysis-evidence/v1", + "evidence_artifact_path": "docs/research/formal-semantic-validation/evidence/typed-exploit-path-valid-v4.json", + "evidence_artifact_sha256": "1b7f55d04db172da32658187c64a88c13b5f4d565267ce2be7cb86a9d04cb70c", + "evidence_digest": "sha256:2d4d1a362751abd9544beb8af7f8c6331d04dac8f4abc315fb261f81fbaf4387", + "evidence_profile": "exploit-path-analysis-evidence/v1", + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/exploit-path-valid-v3.json", + "docs/research/formal-semantic-validation/evidence/typed-exploit-path-valid-v4.json", + "specs/formal/exploit-path-analysis/README.md" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "The witness is bounded to the admitted snapshot, normalized graph, query, semantics, and search profile; it does not establish backend execution." + ], + "replayable": true, + "result_digest": "sha256:2d4d1a362751abd9544beb8af7f8c6331d04dac8f4abc315fb261f81fbaf4387", + "source_digest": "sha256:0afe635a63db5b6e6380ac70982fd61d09790745d51a10d670321304121e7c39" + }, + { + "actual_outcome": "invalid-path", + "analysis_profile": "raes-exploit-path-analysis-v1", + "case_id": "typed-exploit-path-invalid-v2", + "configuration_digest": "sha256:7f8876d81feb77d3a3239be2fb8337de8885e2744f8786728ba23e4e6027bc0a", + "configuration_id": "raes-python-reference-offline-v41", + "diagnostic_kind": "exploit-path-analysis-evidence/v1", + "evidence_artifact_path": "docs/research/formal-semantic-validation/evidence/typed-exploit-path-invalid-v4.json", + "evidence_artifact_sha256": "244f895a64f14c10916ab0533ab462ce80a328021cd6a50c30a4aa59266d5533", + "evidence_digest": "sha256:1b416bb5a4d29d57c961b769cc9d3af5d9328624e3eebf104d57f39a94c5bb97", + "evidence_profile": "exploit-path-analysis-evidence/v1", + "evidence_refs": [ + "docs/research/formal-semantic-validation/corpus/exploit-path-invalid-v3.json", + "docs/research/formal-semantic-validation/evidence/typed-exploit-path-invalid-v4.json", + "specs/formal/exploit-path-analysis/README.md" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "Structured rejection proves only that this bounded graph/query cannot reach its goal; it does not establish real-world non-exploitability." + ], + "replayable": true, + "result_digest": "sha256:1b416bb5a4d29d57c961b769cc9d3af5d9328624e3eebf104d57f39a94c5bb97", + "source_digest": "sha256:0b2293d4a8983515ff05c516be6e6b418a4f3f09e055250a00bf15fda861aab3" + } + ], + "participant_observations": [ + { + "evidence_refs": [ + "implementations/python/tests/test_sem_208_participant_behavior.py::test_hidden_truth_disclosure_is_separate_from_observable_projection", + "implementations/python/tests/test_sem_208_participant_behavior.py::test_hidden_truth_cannot_be_observed_without_explicit_disclosure_rule" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "Covers the reference SDL/contract path, not every backend projection." + ], + "negative_outcome": "passed", + "obligation_id": "hidden-vs-visible-projection", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_sem_211_participant_action_semantics.py::test_action_contract_declares_sem_211_classes_and_compiles_them", + "implementations/python/tests/test_sem_211_participant_action_semantics.py::test_action_result_rejects_success_when_preconditions_are_unresolved" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "Covers declared applicability and one unresolved-precondition failure." + ], + "negative_outcome": "passed", + "obligation_id": "fail-closed-action-applicability", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_run_308_concurrent_participant_execution.py::test_runtime_snapshot_publishes_joint_action_and_time_context_records", + "implementations/python/tests/test_run_308_concurrent_participant_execution.py::test_joint_action_record_contract_rejects_unordered_conflicting_writes" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "Contract evidence does not prove every backend's live concurrency fidelity." + ], + "negative_outcome": "passed", + "obligation_id": "shared-state-effects", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_participant_runtime_invariants.py::test_order_discipline_accepts_supported_order_claim_strengths", + "implementations/python/tests/test_participant_runtime_invariants.py::test_order_discipline_rejects_wall_clock_causality" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "Rejecting timestamp-only causality does not supply counterfactual proof." + ], + "negative_outcome": "passed", + "obligation_id": "ordering-before-causality", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_sem_212_participant_attribution_semantics.py::test_attribution_edge_round_trips_on_terminal_observation", + "implementations/python/tests/test_sem_212_participant_attribution_semantics.py::test_timestamp_adjacency_cannot_be_reported_as_strong_causality" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "Attribution labels disclose basis; they do not demonstrate necessity." + ], + "negative_outcome": "passed", + "obligation_id": "evidence-labeled-attribution", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_sem_215_participant_outcome_interpretation.py::test_outcome_interpretation_rule_parses_and_compiles_explicit_layers", + "implementations/python/tests/test_sem_215_participant_outcome_interpretation.py::test_local_action_success_does_not_imply_objective_success_without_rule_record" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "The fixtures establish layer separation, not outcome validity in every realization." + ], + "negative_outcome": "passed", + "obligation_id": "participant-local-outcome-separation", + "positive_outcome": "passed" + }, + { + "evidence_refs": [ + "implementations/python/tests/test_realization_honesty_conformance.py::test_constructive_envelope_runs_positive_and_negative_honesty_probes", + "implementations/python/tests/test_realization_honesty_conformance.py::test_only_native_live_can_support_native_conformance" + ], + "execution_id": "issue-1423-sync-execution-v76", + "limitations": [ + "Reference conformance evidence remains bounded to declared realization profiles." + ], + "negative_outcome": "passed", + "obligation_id": "realization-profile-honesty", + "positive_outcome": "passed" + } + ], + "protocol_revision": "2.0.0", + "raes_revision": "5556a6caf15d4b2fb877408b9cc4ee834f942769", + "source_state": { + "base_revision": "5556a6caf15d4b2fb877408b9cc4ee834f942769", + "checkout_state": "modified", + "implementation_digest": "4565b2699c1e2396d95ec29de5e8e99dbc9520cd0b88609c5ff099ef2e2048ec", + "profile": "python-reference-source/v2" + }, + "versions": { + "python": "3.13.13", + "raes": "5.0.0", + "z3_engine": "4.16.0", + "z3_solver": "4.16.0.0" + } +} diff --git a/docs/research/formal-semantic-validation/index.md b/docs/research/formal-semantic-validation/index.md index 837f9a2a0..bc0b41f3e 100644 --- a/docs/research/formal-semantic-validation/index.md +++ b/docs/research/formal-semantic-validation/index.md @@ -336,7 +336,7 @@ outcomes and claim limits, recording the positive successor's changed result digest; the dangling-reference diagnostic remains identical. It establishes no autonomy threshold, authority grant, or realized attribution. -Current validation requires explicit release 75.0.0, rejects unsupported future +Current validation requires explicit release 76.0.0, rejects unsupported future or duplicate revisions, and never accepts an old/new output-digest pair as a substitute for replay. Historical releases (including the issue-826 supplement) undergo pin, shape, control, and internal-join checks without executing current @@ -647,4 +647,13 @@ claim limits remain unchanged; the readback mutation cases are covered by The issue #1423 captures whose release identities collided during synchronization are preserved in the [inject occurrence archive](../inject-occurrence-pre-sync-evidence/README.md) with exact bytes, digests and source revision. Incoming published history remains -canonical. The synchronized source requires a fresh capture before publication. +canonical. + +Release 76.0.0 replays the retained corpus after synchronizing issue #1423's +inject trigger and occurrence contracts with `dev` and requiring explicit +placement discriminators. See +[`execution-snapshot-v76.json`](execution-snapshot-v76.json) and +[`analysis-v76.json`](analysis-v76.json). Retained outcomes and bounded +claim limits remain unchanged; the missing-discriminator cases are covered by +`test_issue_1423_inject_occurrence_contracts.py`. These captures establish no +inject execution, authorization or world-effect claim. diff --git a/docs/research/inject-occurrence-pre-sync-evidence/README.md b/docs/research/inject-occurrence-pre-sync-evidence/README.md index bc3508240..7399cae25 100644 --- a/docs/research/inject-occurrence-pre-sync-evidence/README.md +++ b/docs/research/inject-occurrence-pre-sync-evidence/README.md @@ -11,5 +11,6 @@ and immutable source revision. Embedded paths refer to that source revision. These historical records are outside the active indexes; no capture byte or observation has been discarded or relabeled. -Fresh captures will record the synchronized implementation and discriminator -repair without promoting the retained corpus to inject execution evidence. +Formal release 76 and specification release 75 replay the synchronized +implementation and discriminator repair. Retained outcomes and bounded claim +limits remain unchanged; the corpus makes no inject execution claim. diff --git a/docs/research/specification-coverage/analysis-v75.json b/docs/research/specification-coverage/analysis-v75.json new file mode 100644 index 000000000..6a2042fd7 --- /dev/null +++ b/docs/research/specification-coverage/analysis-v75.json @@ -0,0 +1,114 @@ +{ + "analysis_id": "raes-standardized-specification-coverage-issue-1423-sync-v75", + "backend_leakage": [], + "claim": { + "allowed_evidence": [ + "pinned source metadata and bounded paraphrases", + "production parser, semantic, instantiation, admission, compiler, contract, and profile results", + "exact artifact digests and typed pointers", + "documented missing-concept and backend-specific dispositions" + ], + "claim_id": "raes-standardized-configurable-specification-coverage", + "disallowed_evidence": [ + "field-count or schema breadth alone", + "the existing scenario stress corpus as the representative request corpus", + "free-form metadata as typed coverage", + "backend-private interpretation", + "post-hoc removal or repair of falsifying concepts" + ], + "evidence_artifacts": [ + "docs/research/specification-coverage/protocol-v1.json", + "docs/research/specification-coverage/execution-snapshot-v72.json", + "docs/research/specification-coverage/analysis-v68.json" + ], + "falsification_protocol": "docs/research/specification-coverage/protocol-v1.json", + "objective_fail_criteria": "A load-bearing concept is missing or lossy, an applicable stage fails, or backend vocabulary is required in core SDL while the result claims success.", + "objective_pass_criteria": "Every load-bearing concept passes at every owning stage, backend-specific mechanics stay outside core SDL, and no requested concept is silently lost.", + "statement": "RAES provides a standardized configurable portable specification surface for the preregistered representative cyber-agent evaluation environment requirements without backend vocabulary in core SDL.", + "threats_to_validity": [ + "The representative corpus contains four source strata and sixteen atomic concepts rather than every cyber-range requirement.", + "The reference processor and repository fixtures are not independent backend implementations.", + "No live range, simulator federation, or participant execution was part of this offline specification-coverage test." + ] + }, + "classification_counts": { + "deliberately-backend-specific": 1, + "directly-expressible": 10, + "missing": 3, + "profile-or-manifest-constraint": 2 + }, + "evidence_status": "partial", + "execution_status": "complete", + "generated_at": "2026-10-11T21:58:12.665142+00:00", + "limitations": [ + "This result demonstrates bounded specification coverage, not universal cyber-range coverage, usability, adoption, backend substitution, or behavioral equivalence.", + "The three missing concepts are evidence, not implementation tasks within this snapshot.", + "The retained protocol does not test recursive realization or plan-level profile semantics; this release only re-establishes its original bounded coverage result against the current implementation.", + "The retained protocol does not test evidence-requirement refinement lineage; the dedicated EXP-731 regression suite covers that production boundary.", + "Authoring-adapter transport behavior is outside this retained protocol.", + "Reviewed OCI mirror and pre-seed admission is covered by its own regression suites and the development artifact policy gate, not a new claim in this preregistered matrix.", + "Operational recovery observation and startup reconciliation are covered by their API-404 regression suite, not a new claim in this preregistered matrix.", + "Store ownership, immutable runtime scope, and provider shutdown ordering are covered by the API-404 CP-5 regression suite, not by this retained specification-coverage protocol.", + "Mixed/staged trial compilation and admission are covered by issue #1015 regression tests, not by this retained specification-coverage corpus; no live mixed-runtime result is claimed.", + "Issue #1186 control-plane recovery operations are covered by their runtime regression suite, not by this retained specification-coverage corpus.", + "Issue #1187 control-plane crash/profile conformance and HTTP security changes are covered by their dedicated regression suite, not promoted to new claims by this retained corpus.", + "Issue #1189 control-plane profile declarations are covered by their dedicated runtime suite, not promoted to new claims by the retained language corpus.", + "Issue #610's reconciliation demonstration harness is covered by its dedicated processor and CLI suite, not promoted to new claims by the retained language corpus.", + "Participant identity, organization ownership, and participant assignment are separated by issue #1338. This retained offline corpus does not establish participant autonomy, execution authority, live backend fidelity, or causal attribution.", + "Participant-local outcome state is verified by the ACT-618 tests; this retained corpus makes no additional outcome-state claim.", + "Backend operation supervision contracts are covered by issue #1360 contract tests; this retained offline corpus establishes no live backend supervision or recovery guarantee.", + "This capture replays the merged issue #1360 and #1357 source; the protocol makes no live backend execution or supervision claim.", + "This capture replays the merged issue #1360 and #1358 source; the protocol makes no live backend execution or supervision claim.", + "Issue #1389 participant inject delivery temporal-subject admission is covered by dedicated compiler tests; this retained matrix makes no new timing or execution claim.", + "Issue #971 adds offline crossing model construction; this retained protocol establishes no crossing equivalence or runtime-realization claim.", + "Issue #1359 control-plane route authority, participant-view scoping, and no-store HTTP boundary are covered by their dedicated HTTP-boundary suite; this retained matrix makes no new exposure or execution claim.", + "Issue #1401 required-evidence media-type coherence is verified by its dedicated suite; this retained matrix makes no new admission or capture claim.", + "Issue #1361 execution and recovery requirements are verified by dedicated policy, composition, and admission tests; this retained corpus establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 maintainability repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 resource type-hint repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The combined issue #1361 execution-policy and hatchling update preserves retained outcomes and bounded claims; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1418 runtime-fact export manifest split changes no contract, schema or behavior; this retained matrix makes no new admission or coverage claim.", + "This synchronization adds no mixed-backend runtime execution claim; the issue #1371 tests cover the composition run-scope join.", + "The issue #1423 inject contract discriminator repair is covered by its dedicated fixtures; the retained corpus adds no inject execution, authorization or world-effect claim." + ], + "load_bearing_results": { + "failed": 0, + "missing": 0, + "passed": 10, + "total": 10 + }, + "plain_language_outcome": "The retained specification matrix preserves its prior classifications after synchronizing the inject trigger and occurrence contracts with dev and requiring explicit placement discriminators. Bounded claim limits are unchanged.", + "protocol_revision": "1.0.0", + "request_results": [ + { + "concept_count": 6, + "failed_stage_count": 0, + "missing_count": 0, + "request_id": "survey-representative-range", + "status": "demonstrated" + }, + { + "concept_count": 5, + "failed_stage_count": 1, + "missing_count": 1, + "request_id": "cyborg-participant-evaluation", + "status": "partial" + }, + { + "concept_count": 3, + "failed_stage_count": 1, + "missing_count": 1, + "request_id": "vsdl-configurable-infrastructure", + "status": "partial" + }, + { + "concept_count": 2, + "failed_stage_count": 1, + "missing_count": 1, + "request_id": "cyber-dem-federation", + "status": "partial" + } + ], + "snapshot_id": "raes-standardized-specification-coverage-issue-1423-sync-v75", + "snapshot_sha256": "d173523abfea872b820e96bcc7cac05d47ef794588bdfdc9bf20d369bc2f1625" +} diff --git a/docs/research/specification-coverage/bundles/raes-standardized-specification-coverage-issue-1423-sync-v75.json b/docs/research/specification-coverage/bundles/raes-standardized-specification-coverage-issue-1423-sync-v75.json new file mode 100644 index 000000000..42a2cab35 --- /dev/null +++ b/docs/research/specification-coverage/bundles/raes-standardized-specification-coverage-issue-1423-sync-v75.json @@ -0,0 +1,10 @@ +{ + "analysis_path": "docs/research/specification-coverage/analysis-v75.json", + "analysis_sha256": "5ed6e2dd708f299747f94d15fb00776a9e4e5af6437d35553b34262dbb193680", + "bundle_id": "raes-standardized-specification-coverage", + "protocol_path": "docs/research/specification-coverage/protocol-v1.json", + "protocol_sha256": "e97a19e643e94c9e589dca823a63c6ce49d3329fe2a3cb888ab630838ed93125", + "revision": "75.0.0", + "snapshot_path": "docs/research/specification-coverage/execution-snapshot-v75.json", + "snapshot_sha256": "7deb6ca21010881b881efeff615f3991ae94c2296fa677c87c9ed1fd4e018e31" +} diff --git a/docs/research/specification-coverage/execution-snapshot-v75.json b/docs/research/specification-coverage/execution-snapshot-v75.json new file mode 100644 index 000000000..a1189bfb8 --- /dev/null +++ b/docs/research/specification-coverage/execution-snapshot-v75.json @@ -0,0 +1,706 @@ +{ + "artifacts": [ + { + "artifact_id": "enterprise-participant-sdl", + "kind": "sdl", + "path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "sha256": "f7a8897beec243e188ee081975006fad32725f469f267db6e75a1e1cf5727032", + "validator": "raes parse, semantic, instantiation/admission, and compiler pipeline" + }, + { + "artifact_id": "port-range-sdl", + "kind": "sdl", + "path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "sha256": "0d5497ec946b863e6985284ec487dde7d7f6bf710a985be51401ac0e5e79dc4f", + "validator": "raes parse, semantic, instantiation/admission, and compiler pipeline" + }, + { + "artifact_id": "experiment-task-contract", + "kind": "experiment-task", + "path": "contracts/fixtures/experiment-core/experiment-task-v1/valid/reference.json", + "sha256": "f3edf713ac6af26bad609136851c6dd434bfb87ce919a2d8c4414c1035deeafc", + "validator": "raes_contracts.contracts.ExperimentTaskModel" + }, + { + "artifact_id": "apparatus-context-contract", + "kind": "experiment-apparatus-context", + "path": "contracts/fixtures/experiment-core/experiment-apparatus-context-v1/valid/reference.json", + "sha256": "e6fa559c5e961f0aab448d0f70dead24aa74fa8ba5f20e1b72f88e11473c9299", + "validator": "raes_contracts.contracts.ExperimentApparatusContextModel" + }, + { + "artifact_id": "backend-profile", + "kind": "backend-profile", + "path": "contracts/profiles/backend/orchestration-capable.json", + "sha256": "f70b8505a5c0055416db86c533e2e5bf08b11e5a514f076223b6d6c36215a092", + "validator": "raes_contracts.backend_profiles.BackendProfileModel" + }, + { + "artifact_id": "known-limitations", + "kind": "documentation", + "path": "docs/explain/sdl/limitations.md", + "sha256": "489eeab3ce682627682311581eb98af9abb9ff42a437145af266eefb71dc7fc4", + "validator": "documentation evidence only" + } + ], + "baseline": { + "release_revision": "1.1.0", + "release_sha256": "4020a1d56c7fe2831cec59ea64a12bbda9d38ccd94f93b916dd90f1a28f17fcb" + }, + "captured_at": "2026-10-11T21:58:12.665142+00:00", + "concept_results": [ + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "range-topology", + "rationale": "SDL nodes and infrastructure own host, network, link, and dependency meaning; the compiler emits canonical node deployment addresses.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed VM declaration.", + "outcome": "passed", + "pointer": "/nodes/shipping-portal", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Links and dependencies resolved.", + "outcome": "passed", + "pointer": "/infrastructure/shipping-portal", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Published instantiated shape admitted.", + "outcome": "passed", + "pointer": "/nodes/shipping-portal", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical deployment address retained.", + "outcome": "passed", + "pointer": "/node_deployments/provision.node.shipping-portal", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/nodes/shipping-portal" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "exercise-roles", + "rationale": "SDL entity roles own exercise responsibility without becoming control-plane identity or authorization.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed red role.", + "outcome": "passed", + "pointer": "/entities/enterprise-participant/role", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Entity references validated.", + "outcome": "passed", + "pointer": "/entities/enterprise-participant", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Role retained after instantiation.", + "outcome": "passed", + "pointer": "/entities/enterprise-participant/role", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Role retained in entity specification.", + "outcome": "passed", + "pointer": "/entity_specs/enterprise-participant/role", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/entities/enterprise-participant/role" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "evaluation-objectives", + "rationale": "SDL objectives own organization ownership, participant assignment, targets, windows, and assertion-based success; measures remain experiment contracts.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed objective declaration.", + "outcome": "passed", + "pointer": "/objectives/demonstrate-handoff", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Owner, participant assignment, targets, assertions, and workflow refs resolved.", + "outcome": "passed", + "pointer": "/objectives/demonstrate-handoff/success", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Objective retained in admitted artifact.", + "outcome": "passed", + "pointer": "/objectives/demonstrate-handoff", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical objective address retained.", + "outcome": "passed", + "pointer": "/objectives/evaluation.objective.demonstrate-handoff", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/objectives/demonstrate-handoff" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "control-workflows", + "rationale": "SDL workflows own the portable control graph and compile to canonical orchestration state contracts.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed control graph.", + "outcome": "passed", + "pointer": "/workflows/yard-recovery", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Step graph and objective refs validated.", + "outcome": "passed", + "pointer": "/workflows/yard-recovery/steps", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Workflow retained after instantiation.", + "outcome": "passed", + "pointer": "/workflows/yard-recovery", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical control graph retained.", + "outcome": "passed", + "pointer": "/workflows/orchestration.workflow.yard-recovery", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/workflows/yard-recovery" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "authored-evidence-expectations", + "rationale": "SDL evidence requirements own portable capture intent and remain distinct from evidence records and measures.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed capture obligation.", + "outcome": "passed", + "pointer": "/evidence_requirements/objective-truth-evidence", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Source refs and bindings validated.", + "outcome": "passed", + "pointer": "/evidence_requirements/objective-truth-evidence", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Evidence intent retained in admitted artifact.", + "outcome": "passed", + "pointer": "/evidence_requirements/objective-truth-evidence", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + } + ], + "typed_pointer": "/evidence_requirements/objective-truth-evidence" + }, + { + "backend_support": "profile-bound", + "backend_vocabulary_occurrences": [], + "classification": "profile-or-manifest-constraint", + "completeness_disposition": "implemented", + "concept_id": "apparatus-selection-constraints", + "rationale": "The experiment task contract binds processor/backend identities, manifest refs, and capabilities outside SDL.", + "stage_results": [ + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-task-v1/valid/reference.json", + "diagnostic_codes": [], + "note": "Closed ExperimentTaskModel validated.", + "outcome": "passed", + "pointer": "/apparatus_constraints/allowed_backend_refs/0", + "stage_id": "contract", + "validation_strength": "contract" + } + ], + "typed_pointer": "/apparatus_constraints/allowed_backend_refs/0" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "participant-agent", + "rationale": "SDL agents own participant entity, knowledge, actions, observation boundaries, and operating scope.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed participant declaration.", + "outcome": "passed", + "pointer": "/agents/participant-agent", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Participant refs and scope validated.", + "outcome": "passed", + "pointer": "/agents/participant-agent/observation_boundaries", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Participant retained in admitted artifact.", + "outcome": "passed", + "pointer": "/agents/participant-agent", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Compiled participant scope retained.", + "outcome": "passed", + "pointer": "/agent_specs/participant-agent", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/agents/participant-agent" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "participant-action-contract", + "rationale": "The action contract declares portable preconditions, effects, observations, evidence, and failure classes without a runner command.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed action contract.", + "outcome": "passed", + "pointer": "/action_contracts/probe-customer-portal-login", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Action refs and evidence bindings validated.", + "outcome": "passed", + "pointer": "/action_contracts/probe-customer-portal-login/effects", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Action retained in admitted artifact.", + "outcome": "passed", + "pointer": "/action_contracts/probe-customer-portal-login", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical action address retained.", + "outcome": "passed", + "pointer": "/action_contracts/participant.action-contract.probe-customer-portal-login", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/action_contracts/probe-customer-portal-login" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "participant-observation-boundary", + "rationale": "The observation boundary separately declares visible, hidden, and evidence-only information with transition rules.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed observation boundary.", + "outcome": "passed", + "pointer": "/observation_boundaries/participant-view", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Information refs and transitions validated.", + "outcome": "passed", + "pointer": "/observation_boundaries/participant-view/view_rules", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Boundary retained in admitted artifact.", + "outcome": "passed", + "pointer": "/observation_boundaries/participant-view", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "diagnostic_codes": [], + "note": "Canonical boundary address retained.", + "outcome": "passed", + "pointer": "/observation_boundaries/participant.observation-boundary.participant-view", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/observation_boundaries/participant-view" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "evaluation-measure", + "rationale": "ExperimentTaskModel owns metric construct, unit, direction, aggregation, and evidence requirements outside SDL objectives.", + "stage_results": [ + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-task-v1/valid/reference.json", + "diagnostic_codes": [], + "note": "Closed task contract validated.", + "outcome": "passed", + "pointer": "/evaluation_protocol/metric_definitions/foothold-achieved", + "stage_id": "contract", + "validation_strength": "contract" + } + ], + "typed_pointer": "/evaluation_protocol/metric_definitions/foothold-achieved" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "missing", + "completeness_disposition": "documented-gap", + "concept_id": "participant-tool-affordance", + "rationale": "This preregistered matrix has no tested carrier for participant tool affordances. The retained missing classification records missing coverage evidence, not the absence of current participant-behavior capabilities.", + "stage_results": [ + { + "artifact_path": "docs/explain/sdl/limitations.md", + "diagnostic_codes": [], + "note": "The preregistered carrier slot was not run; metadata does not substitute for a typed coverage test.", + "outcome": "not_run", + "pointer": null, + "stage_id": "authored", + "validation_strength": "not-applicable" + } + ], + "typed_pointer": null + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "directly-expressible", + "completeness_disposition": "implemented", + "concept_id": "resource-constrained-topology", + "rationale": "SDL node resources and infrastructure dependencies express portable resource intent without provider resource identifiers.", + "stage_results": [ + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Typed CPU and memory declaration.", + "outcome": "passed", + "pointer": "/nodes/shipping-portal/resources", + "stage_id": "authored", + "validation_strength": "structural" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Resource-bearing topology validated.", + "outcome": "passed", + "pointer": "/infrastructure/shipping-portal", + "stage_id": "semantic", + "validation_strength": "semantic" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Constraints retained in admitted artifact.", + "outcome": "passed", + "pointer": "/nodes/shipping-portal/resources", + "stage_id": "instantiated", + "validation_strength": "phase-admitted" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "diagnostic_codes": [], + "note": "Deployment specification retains resource intent.", + "outcome": "passed", + "pointer": "/node_deployments/provision.node.shipping-portal", + "stage_id": "compiled", + "validation_strength": "compiled" + } + ], + "typed_pointer": "/nodes/shipping-portal/resources" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "missing", + "completeness_disposition": "documented-gap", + "concept_id": "formal-constraint-satisfiability", + "rationale": "This coverage matrix did not exercise a solver-backed carrier. The separate formal-semantic-validation release demonstrates its bounded finite-domain profile; that result is not silently imported into this protocol's missing carrier slot.", + "stage_results": [ + { + "artifact_path": "docs/explain/sdl/limitations.md", + "diagnostic_codes": [], + "note": "No coverage-carrier execution was performed here; independent solver evidence does not change this preregistered denominator.", + "outcome": "not_run", + "pointer": null, + "stage_id": "semantic", + "validation_strength": "not-applicable" + } + ], + "typed_pointer": null + }, + { + "backend_support": "profile-bound", + "backend_vocabulary_occurrences": [ + { + "allowed": true, + "artifact_path": "source:vsdl-paper", + "pointer": "source sections 4-5", + "reason": "Legitimate VSDL realization vocabulary, not RAES core SDL structure.", + "term": "OpenStack/Terraform/Packer" + } + ], + "classification": "deliberately-backend-specific", + "completeness_disposition": "external", + "concept_id": "provider-specific-provisioning", + "rationale": "Provider image selection and provisioning engines are realization mechanics and therefore remain outside core SDL.", + "stage_results": [ + { + "artifact_path": "contracts/profiles/backend/orchestration-capable.json", + "diagnostic_codes": [], + "note": "The portable boundary requires backend contracts; it does not standardize a provider engine.", + "outcome": "not_applicable", + "pointer": "/required_contracts", + "stage_id": "realization-disclosure", + "validation_strength": "profile" + } + ], + "typed_pointer": null + }, + { + "backend_support": "profile-bound", + "backend_vocabulary_occurrences": [], + "classification": "profile-or-manifest-constraint", + "completeness_disposition": "implemented", + "concept_id": "apparatus-clock-context", + "rationale": "ExperimentApparatusContextModel records clock authority, time domain, and synchronization as apparatus facts outside scenario meaning.", + "stage_results": [ + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-apparatus-context-v1/valid/reference.json", + "diagnostic_codes": [], + "note": "Closed apparatus context contract validated.", + "outcome": "passed", + "pointer": "/clocks/0", + "stage_id": "contract", + "validation_strength": "contract" + } + ], + "typed_pointer": "/clocks/0" + }, + { + "backend_support": "not-evaluated", + "backend_vocabulary_occurrences": [], + "classification": "missing", + "completeness_disposition": "documented-gap", + "concept_id": "federated-object-event-exchange", + "rationale": "The federated cyber object/event exchange carrier was not exercised by this preregistered matrix. Runtime event internals are not treated as equivalent evidence.", + "stage_results": [ + { + "artifact_path": "docs/explain/sdl/limitations.md", + "diagnostic_codes": [], + "note": "The missing coverage-carrier test is recorded explicitly, without inferring an ecosystem-wide capability absence.", + "outcome": "not_run", + "pointer": null, + "stage_id": "contract", + "validation_strength": "not-applicable" + } + ], + "typed_pointer": null + } + ], + "deviations": [ + { + "artifact_path": "examples/scenarios/enterprise-participant-evidence-loop.sdl.yaml", + "baseline_sha256": "54ba1a60220e27a55da9cd2a407d7d3ab836fa54460d0b0c6cad87c2e744ddbb", + "rationale": "Migrate participant affiliations and explicit objective assignment, retaining organizational intent and portable action-contract declarations without granting execution authority.", + "retest_sha256": "f7a8897beec243e188ee081975006fad32725f469f267db6e75a1e1cf5727032" + }, + { + "artifact_path": "examples/scenarios/port-authority-surge-response.sdl.yaml", + "baseline_sha256": "a27c7a64e0c5c618fadaccafdf1a4e71600170a8b77b983190822b5141f00dec", + "rationale": "Migrate participant affiliations and explicit objective assignment, retaining organizational intent and portable action-contract declarations without granting execution authority.", + "retest_sha256": "0d5497ec946b863e6985284ec487dde7d7f6bf710a985be51401ac0e5e79dc4f" + }, + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-task-v1/valid/reference.json", + "baseline_sha256": "21952a752f4e8581a9fc3b872e4bc308150548170d38bcfc83dbbe35ff5e0b9f", + "rationale": "Replay the retained preregistered artifact against the current evidence-provenance validation implementation.", + "retest_sha256": "f3edf713ac6af26bad609136851c6dd434bfb87ce919a2d8c4414c1035deeafc" + }, + { + "artifact_path": "contracts/fixtures/experiment-core/experiment-apparatus-context-v1/valid/reference.json", + "baseline_sha256": "9536d897a09cbc6920e667e4f8f9371e51307aa0b3b5ff3c7de682dd783420ab", + "rationale": "Replay the retained preregistered artifact against the current evidence-provenance validation implementation.", + "retest_sha256": "e6fa559c5e961f0aab448d0f70dead24aa74fa8ba5f20e1b72f88e11473c9299" + }, + { + "artifact_path": "docs/explain/sdl/limitations.md", + "baseline_sha256": "129cf17810aad4c51988bc872e28fe43ae95019a80053c42d800ff7e2b9cc93e", + "rationale": "Correct historical mandatory-profile guidance after issue #1207; retain the preregistered missing-concept classifications and coverage limits.", + "retest_sha256": "489eeab3ce682627682311581eb98af9abb9ff42a437145af266eefb71dc7fc4" + } + ], + "execution_status": "complete", + "implementation_surfaces": [ + { + "content_sha256": "7675c4f39b46d361fd17787b84b3491ad640c98b6cf4354c36dab7c78df2a7af", + "path": "implementations/python/packages/raes_contracts", + "surface_id": "contract-models" + }, + { + "content_sha256": "e947f59695e907f5af899a6bc4bde60e629620aa7c4a69a41e074ba335758c7a", + "path": "implementations/python/packages/raes_processor", + "surface_id": "processor-pipeline" + }, + { + "content_sha256": "fd19fc83b0306d5d0ff4495d97a8cc9f7c9d45300fc640cb0d246e1c6c2cdbe2", + "path": "implementations/python/packages/raes", + "surface_id": "sdl-pipeline" + } + ], + "limitations": [ + "The execution validates the pinned reference implementation and published contracts, not an independent backend.", + "Repository-owned examples are exact execution artifacts but are not themselves the literature-derived request corpus; the protocol's requests and concepts are.", + "No live range, participant, simulator federation, or provider provisioning engine was executed.", + "Missing concepts remain frozen in this snapshot and require separately scoped product work before a later rerun.", + "This capture replays the retained protocol after EXP-732 run, apparatus, measurement-channel, and augmentation-producer provenance validation; it adds no independent backend or universal provenance assurance claim.", + "Materialization attestation is covered by its dedicated regression suite, not a new claim in this preregistered matrix.", + "This capture refreshes the corrected runtime limitations prose for issue #959; the protocol, coverage classifications and implementation source are unchanged.", + "This capture replays open-by-default augmentation scope integrated with the EXP-731 evidence refinements after composition type refinement; it does not evaluate native backend scope enforcement or broaden the preregistered coverage claims.", + "This capture replays the retained protocol after merging ACT-612 participant relationships with open-by-default augmentation scope; it adds no claim of realized participant relationships or native backend scope enforcement.", + "This capture replays issue #1299 partial listener descriptions on the integrated source state; endpoint completeness and backend admission remain outside this protocol's claims.", + "This capture also binds authoring-adapter semantic conformance to the integrated source; adapter transport behavior remains outside this protocol's claims.", + "Reviewed OCI mirror and pre-seed admission is covered by its own regression suites and the development artifact policy gate, not a new claim in this preregistered matrix.", + "This capture binds issue #1297 service-manager identity, native-name, and explicitly selected systemd-state contract changes to the integrated source. It exercises no live service manager and adds no backend-execution claim.", + "This capture replays the retained specification-coverage protocol after API-404 startup reconciliation added an operational recovery-observation contract. It does not evaluate crash recovery, classify provider effects, or broaden EXP-715 experiment-observation claims.", + "This capture binds API-404 single-owner store admission and immutable target/run scope to the integrated source. The retained offline protocol does not exercise process leases, SQLite lifecycle ordering, or crash recovery.", + "This capture binds issue #1015 deterministic mixed and staged trial admission to the integrated source. The retained offline language corpus does not execute mixed runtimes, phase transitions, backend handoff, or scheduler-driven realization.", + "This replay binds issue #1186 offline control-plane maintenance, readiness, and bounded audit code to the integrated source. The retained language corpus does not execute store recovery, HTTP health behavior, or audit redaction.", + "Issue #1187 control-plane crash/profile conformance and HTTP security changes are covered by their dedicated regression suite, not promoted to new claims by this retained corpus.", + "Issue #1189 control-plane profile declarations are covered by their dedicated runtime suite, not promoted to new claims by the retained language corpus.", + "Issue #1016 mixed-runtime coordination is covered by its dedicated runtime suite. The retained language corpus does not execute mixed providers or establish backend-native realization, multi-controller coordination, IFC, or equivalence.", + "Issue #610's reconciliation demonstration harness is covered by its dedicated processor and CLI suite, not promoted to new claims by the retained language corpus.", + "Participant identity, organization ownership, and participant assignment are separated by issue #1338. This retained offline corpus does not establish participant autonomy, execution authority, live backend fidelity, or causal attribution.", + "Issue #1361 execution and recovery requirements are verified by dedicated policy, composition, and admission tests; this retained corpus establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 maintainability repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The issue #1361 resource type-hint repair preserves policy semantics and retained corpus outcomes; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "The combined issue #1361 execution-policy and hatchling update preserves retained outcomes and bounded claims; it establishes no live recovery, continuation, or trial-allocation guarantee.", + "This synchronization adds no mixed-backend runtime execution claim; the issue #1371 tests cover the composition run-scope join.", + "The issue #1423 inject contract discriminator repair is covered by its dedicated fixtures; the retained corpus adds no inject execution, authorization or world-effect claim." + ], + "protocol_revision": "1.0.0", + "protocol_sha256": "e97a19e643e94c9e589dca823a63c6ce49d3329fe2a3cb888ab630838ed93125", + "raes_revision": "5556a6caf15d4b2fb877408b9cc4ee834f942769", + "snapshot_id": "raes-standardized-specification-coverage-issue-1423-sync-v75", + "snapshot_revision": "75.0.0", + "source_state": { + "base_revision": "5556a6caf15d4b2fb877408b9cc4ee834f942769", + "checkout_state": "modified", + "implementation_digest": "4565b2699c1e2396d95ec29de5e8e99dbc9520cd0b88609c5ff099ef2e2048ec", + "profile": "python-reference-source/v2" + } +} diff --git a/docs/research/specification-coverage/index.md b/docs/research/specification-coverage/index.md index 425be1a92..b24a0e0a7 100644 --- a/docs/research/specification-coverage/index.md +++ b/docs/research/specification-coverage/index.md @@ -292,7 +292,7 @@ the port scenario. Historical captures and archived example bytes are retained. The matrix classifications and untested concepts are unchanged; no execution authority, successful action, or live backend fidelity is inferred. -Current validation requires release 74.0.0 and rejects duplicate or unsupported +Current validation requires release 75.0.0 and rejects duplicate or unsupported future revisions. It executes current artifacts, requires exact source and package hashes, and checks all passing stage pointers. `source_state` discloses the base Git commit, modified checkout state, and exact implementation digest; @@ -587,4 +587,13 @@ claim limits remain unchanged; the readback mutation cases are covered by The issue #1423 captures whose release identities collided during synchronization are preserved in the [inject occurrence archive](../inject-occurrence-pre-sync-evidence/README.md) with exact bytes, digests and source revision. Incoming published history remains -canonical. The synchronized source requires a fresh capture before publication. +canonical. + +Release 75.0.0 replays the retained corpus after synchronizing issue #1423's +inject trigger and occurrence contracts with `dev` and requiring explicit +placement discriminators. See +[`execution-snapshot-v75.json`](execution-snapshot-v75.json) and +[`analysis-v75.json`](analysis-v75.json). Retained outcomes and bounded +claim limits remain unchanged; the missing-discriminator cases are covered by +`test_issue_1423_inject_occurrence_contracts.py`. These captures establish no +inject execution, authorization or world-effect claim. diff --git a/implementations/python/packages/raes_contracts/contracts/inject_occurrence.py b/implementations/python/packages/raes_contracts/contracts/inject_occurrence.py index ec7c119a2..d93d3a05c 100644 --- a/implementations/python/packages/raes_contracts/contracts/inject_occurrence.py +++ b/implementations/python/packages/raes_contracts/contracts/inject_occurrence.py @@ -56,13 +56,13 @@ def _require_binding_of(item: InjectTargetBindingModel, inject: str) -> None: class InjectIndependentPlacementModel(OperationContractModel): """Direct request through an admitted independent binding; no schedule is invented.""" - kind: Literal["independent"] = "independent" + kind: Literal["independent"] class InjectEventPlacementModel(OperationContractModel): """Event-anchored request; the event's precondition assertions remain binding.""" - kind: Literal["event"] = "event" + kind: Literal["event"] event: CompiledAddress @model_validator(mode="after") @@ -74,7 +74,7 @@ def _event(self) -> Self: class InjectSchedulePlacementModel(OperationContractModel): """One uniquely identified schedule slot, claimable at most once in its run.""" - kind: Literal["schedule"] = "schedule" + kind: Literal["schedule"] event: CompiledAddress script: CompiledAddress story: CompiledAddress | None = None diff --git a/implementations/python/tests/test_formal_semantic_validation.py b/implementations/python/tests/test_formal_semantic_validation.py index 627a34d5c..de1f1717a 100644 --- a/implementations/python/tests/test_formal_semantic_validation.py +++ b/implementations/python/tests/test_formal_semantic_validation.py @@ -154,6 +154,7 @@ def test_atomic_release_index_validates_every_historical_bundle() -> None: "73.0.0", "74.0.0", "75.0.0", + "76.0.0", ] assert all(validate_release_bundle(REPO_ROOT, release) == [] for release in releases) @@ -162,10 +163,10 @@ def test_atomic_release_index_validates_every_historical_bundle() -> None: def test_current_retest_bundle_is_coherent_and_clean() -> None: release, protocol, corpus, snapshot, analysis = copy_bundle(load_retest_bundle, REPO_ROOT) - assert release.manifest["revision"] == "75.0.0" + assert release.manifest["revision"] == "76.0.0" assert protocol["revision"] == "2.0.0" assert corpus["revision"] == "4.0.0" - assert snapshot["baseline"]["release_revision"] == "74.0.0" + assert snapshot["baseline"]["release_revision"] == "75.0.0" assert snapshot["deviations"] == [] assert validate_retest_bundle(REPO_ROOT, release, protocol, corpus, snapshot, analysis) == [] diff --git a/implementations/python/tests/test_issue_989_versioned_evidence.py b/implementations/python/tests/test_issue_989_versioned_evidence.py index 781802d08..bcf890079 100644 --- a/implementations/python/tests/test_issue_989_versioned_evidence.py +++ b/implementations/python/tests/test_issue_989_versioned_evidence.py @@ -241,18 +241,18 @@ def _stub_release(revision: str, *, protocol_revision: str = "2.0.0"): [ pytest.param([], "selects no v2 retest release", id="no-release"), pytest.param( - [_stub_release("73.0.0"), _stub_release("74.0.0")], - "must be the explicit 75.0.0 retest", + [_stub_release("74.0.0"), _stub_release("75.0.0")], + "must be the explicit 76.0.0 retest", id="stale-current", ), pytest.param( - [_stub_release("74.0.0"), _stub_release("76.0.0")], - "must be the explicit 75.0.0 retest", + [_stub_release("75.0.0"), _stub_release("77.0.0")], + "must be the explicit 76.0.0 retest", id="unsupported-future", ), pytest.param( - [_stub_release("75.0.0", protocol_revision="1.0.0")], - "must be the explicit 75.0.0 retest", + [_stub_release("76.0.0", protocol_revision="1.0.0")], + "must be the explicit 76.0.0 retest", id="wrong-protocol", ), ], @@ -269,8 +269,8 @@ def test_current_formal_release_selection_is_explicit(monkeypatch, releases, mes def test_current_formal_release_selection_returns_the_explicit_retest(monkeypatch): from tools.formal_semantic_validation import _loading - current = _stub_release("75.0.0") - monkeypatch.setattr(_loading, "load_release_bundles", lambda _root: [_stub_release("74.0.0"), current]) + current = _stub_release("76.0.0") + monkeypatch.setattr(_loading, "load_release_bundles", lambda _root: [_stub_release("75.0.0"), current]) assert _loading.load_retest_bundle(ROOT)[0] is current @@ -282,7 +282,7 @@ def test_latest_current_release_is_versioned_and_strict(monkeypatch): from tools.formal_semantic_validation._releases import validate_retest_bundle release, protocol, corpus, snapshot, analysis = copy_bundle(load_retest_bundle, ROOT) - assert release.manifest["revision"] == "75.0.0" + assert release.manifest["revision"] == "76.0.0" original = _retest.replay_case def changed_result(root, case): @@ -335,7 +335,7 @@ def test_specification_current_capture_does_not_accept_old_artifact_digest(artif from tools.check_specification_coverage import load_bundle, validate_bundle manifest, protocol, snapshot, analysis = copy_bundle(load_bundle, ROOT) - assert manifest["revision"] == "74.0.0" + assert manifest["revision"] == "75.0.0" snapshot = deepcopy(snapshot) artifact = next(a for a in snapshot["artifacts"] if a["artifact_id"] == artifact_id) artifact["sha256"] = old_digest @@ -579,6 +579,7 @@ def test_no_capture_can_be_silently_dropped(monkeypatch, family, removed): "73.0.0", "74.0.0", "75.0.0", + "76.0.0", ] if family == "formal" else [ @@ -657,6 +658,7 @@ def test_no_capture_can_be_silently_dropped(monkeypatch, family, removed): "72.0.0", "73.0.0", "74.0.0", + "75.0.0", ] ) revisions.pop(-1 if removed == "current" else 0) diff --git a/implementations/python/tests/test_specification_coverage.py b/implementations/python/tests/test_specification_coverage.py index 498b2ddcc..4c3505f12 100644 --- a/implementations/python/tests/test_specification_coverage.py +++ b/implementations/python/tests/test_specification_coverage.py @@ -53,7 +53,7 @@ def test_immutable_bundle_index_preserves_concurrent_captures() -> None: bundles = copy_bundle(load_bundles, REPO_ROOT) assert {manifest["revision"] for manifest, *_rest in bundles} >= {"1.0.0", "1.1.0", "19.0.0"} manifest, *_rest = copy_bundle(load_bundle, REPO_ROOT) - assert manifest["revision"] == "74.0.0" + assert manifest["revision"] == "75.0.0" def test_historical_failures_name_the_revision_specific_documents() -> None: diff --git a/tools/check_specification_coverage.py b/tools/check_specification_coverage.py index 0d5b2309b..9c72bb312 100644 --- a/tools/check_specification_coverage.py +++ b/tools/check_specification_coverage.py @@ -179,12 +179,13 @@ def _load_bundle_index(repo_root: Path) -> list[tuple[str, dict[str, object]]]: "72.0.0", "73.0.0", "74.0.0", + "75.0.0", } if ( - dict(records)[current_path].get("revision") != "74.0.0" + dict(records)[current_path].get("revision") != "75.0.0" or {record.get("revision") for _, record in records} != supported_revisions ): - raise ValueError("coverage evidence requires the explicit current 74.0.0 release and supported history") + raise ValueError("coverage evidence requires the explicit current 75.0.0 release and supported history") return records diff --git a/tools/formal_semantic_validation/_baseline.py b/tools/formal_semantic_validation/_baseline.py index aad3fa029..0d529eaa0 100644 --- a/tools/formal_semantic_validation/_baseline.py +++ b/tools/formal_semantic_validation/_baseline.py @@ -211,6 +211,7 @@ def _selected_baseline_manifest( "73.0.0", "74.0.0", "75.0.0", + "76.0.0", }: expected_corpus_path = "docs/research/formal-semantic-validation/corpus/manifest-v4.json" elif baseline_revision in _V3_CORPUS_REVISIONS: diff --git a/tools/formal_semantic_validation/_loading.py b/tools/formal_semantic_validation/_loading.py index e23fc2315..61dd710df 100644 --- a/tools/formal_semantic_validation/_loading.py +++ b/tools/formal_semantic_validation/_loading.py @@ -82,6 +82,6 @@ def load_retest_bundle( if not releases: raise ValueError("the formal semantic-validation index selects no v2 retest release") release = max(releases, key=lambda item: revision_key(item.manifest.get("revision"))) - if release.manifest.get("revision") != "75.0.0" or release.protocol.get("revision") != "2.0.0": - raise ValueError("the current formal evidence release must be the explicit 75.0.0 retest") + if release.manifest.get("revision") != "76.0.0" or release.protocol.get("revision") != "2.0.0": + raise ValueError("the current formal evidence release must be the explicit 76.0.0 retest") return release, release.protocol, release.corpus, release.snapshot, release.analysis diff --git a/tools/formal_semantic_validation/_release_revisions.py b/tools/formal_semantic_validation/_release_revisions.py index bb29b30c8..5a3676fe1 100644 --- a/tools/formal_semantic_validation/_release_revisions.py +++ b/tools/formal_semantic_validation/_release_revisions.py @@ -76,9 +76,10 @@ "72.0.0", "73.0.0", "74.0.0", + "75.0.0", } -_SUPPORTED_RETEST_REVISIONS = _HISTORICAL_RETEST_REVISIONS | {"75.0.0"} +_SUPPORTED_RETEST_REVISIONS = _HISTORICAL_RETEST_REVISIONS | {"76.0.0"} _SOURCE_BOUND_RETEST_REVISIONS = _SUPPORTED_RETEST_REVISIONS - {"3.0.0"} _RETEST_BASELINE_REVISIONS = { @@ -156,4 +157,5 @@ "73.0.0": "72.0.0", "74.0.0": "73.0.0", "75.0.0": "74.0.0", + "76.0.0": "75.0.0", } diff --git a/tools/formal_semantic_validation/_releases.py b/tools/formal_semantic_validation/_releases.py index 00c1f94fc..d5ecbfc65 100644 --- a/tools/formal_semantic_validation/_releases.py +++ b/tools/formal_semantic_validation/_releases.py @@ -160,7 +160,7 @@ def validate_release_bundle(repo_root: Path, release: EvidenceRelease) -> list[P release.corpus, release.snapshot, release.analysis, - replay_current=manifest.get("revision") == "75.0.0", + replay_current=manifest.get("revision") == "76.0.0", ) ) else: @@ -293,6 +293,7 @@ def _expected_corpus_revision(release_revision: object) -> str: "73.0.0", "74.0.0", "75.0.0", + "76.0.0", }: expected_corpus_revision = "4.0.0" return expected_corpus_revision @@ -320,7 +321,7 @@ def validate_retest_bundle( return [ _failure( "formal-validation-current-replay-required", - "only releases 3.0.0 through 74.0.0 can use integrated historical validation", + "only releases 3.0.0 through 75.0.0 can use integrated historical validation", snapshot_path, ) ] diff --git a/tools/formal_semantic_validation/_retest.py b/tools/formal_semantic_validation/_retest.py index a3c444ec5..a7592ddee 100644 --- a/tools/formal_semantic_validation/_retest.py +++ b/tools/formal_semantic_validation/_retest.py @@ -37,7 +37,7 @@ ) from tools.policy.common import PolicyFailure -_SOURCE_STATE_REVISIONS = frozenset(f"{revision}.0.0" for revision in range(4, 76)) +_SOURCE_STATE_REVISIONS = frozenset(f"{revision}.0.0" for revision in range(4, 77)) @dataclasses.dataclass(frozen=True) From b0715b124cefef79cd48ec7ba209f54c71b25877 Mon Sep 17 00:00:00 2001 From: Brad Edwards Date: Tue, 13 Oct 2026 01:27:06 +0200 Subject: [PATCH 9/9] Document preserved inject evidence after dev synchronization --- .../README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/docs/research/inject-occurrence-first-sync-evidence/README.md b/docs/research/inject-occurrence-first-sync-evidence/README.md index 041aa50a0..24abdff82 100644 --- a/docs/research/inject-occurrence-first-sync-evidence/README.md +++ b/docs/research/inject-occurrence-first-sync-evidence/README.md @@ -13,7 +13,14 @@ these branch observations and record the combined implementation separately. Capture manifests: -- [capture-433c046b053bf4ff80e4ec216c2e0c1a116309cc73afd11d73532004b4cb06a4](../../../docs/research/formal-semantic-validation/captures/capture-433c046b053bf4ff80e4ec216c2e0c1a116309cc73afd11d73532004b4cb06a4/manifest.json) -- [capture-a5a57351be69b38c88e36f334855f3b15e1c158d64304427299904a352cc2299](../../../docs/research/specification-coverage/captures/capture-a5a57351be69b38c88e36f334855f3b15e1c158d64304427299904a352cc2299/manifest.json) -- [capture-1cb25772c376bf4caae8076c770469bcd5e373c9369d620fcc93460ffa859996](../../../docs/research/formal-semantic-validation/captures/capture-1cb25772c376bf4caae8076c770469bcd5e373c9369d620fcc93460ffa859996/manifest.json) -- [capture-b961393d9cbbc01916a695ae5eb09ba07ccb2d6e069fb33aa8f9a5d3de8d85fe](../../../docs/research/specification-coverage/captures/capture-b961393d9cbbc01916a695ae5eb09ba07ccb2d6e069fb33aa8f9a5d3de8d85fe/manifest.json) +- [Historical formal observations](../../../docs/research/formal-semantic-validation/captures/capture-433c046b053bf4ff80e4ec216c2e0c1a116309cc73afd11d73532004b4cb06a4/manifest.json) +- [Historical specification observations](../../../docs/research/specification-coverage/captures/capture-a5a57351be69b38c88e36f334855f3b15e1c158d64304427299904a352cc2299/manifest.json) +- [Combined formal observations](../../../docs/research/formal-semantic-validation/captures/capture-1cb25772c376bf4caae8076c770469bcd5e373c9369d620fcc93460ffa859996/manifest.json) +- [Combined specification observations](../../../docs/research/specification-coverage/captures/capture-b961393d9cbbc01916a695ae5eb09ba07ccb2d6e069fb33aa8f9a5d3de8d85fe/manifest.json) + +The historical captures preserve the branch observations under their original +source pins. The combined captures bind the synchronized implementation, replay +14 supported formal corpus cases and six specification artifacts with 38 passing +typed pointers, and retain the existing bounded claim limits. The 18 declared +participant cases and 126 inject request, occurrence and readback cases pass. +CI performs the independent integration replay before merge.