feat(stage2): implement S2_40 finalizer

Add deterministic validation, closed rendering, review resume, and content-addressed commit while keeping live and legal admission pending.
This commit is contained in:
2026-09-01 15:30:59 +09:00
parent 527604d42f
commit f4aece497a
127 changed files with 28492 additions and 684 deletions
@@ -192,7 +192,7 @@ Agent:
# literal placeholders in the offline parity mirror and its unit tests. # literal placeholders in the offline parity mirror and its unit tests.
INLINE_USER_HASH = "{{__user_hash__}}" INLINE_USER_HASH = "{{__user_hash__}}"
INLINE_WORKSPACE_HASH = "{{__workspace_hash__}}" INLINE_WORKSPACE_HASH = "{{__workspace_hash__}}"
EXPECTED_STAGE2_RELEASE_SHA256 = "579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81" EXPECTED_STAGE2_RELEASE_SHA256 = "9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53"
INLINE_REQUEST_PATH = "stage2_control/s2_00_request.json" INLINE_REQUEST_PATH = "stage2_control/s2_00_request.json"
INLINE_STAGE2_ASSET_ROOT = "Default_Agent/Stage_2_Clean" INLINE_STAGE2_ASSET_ROOT = "Default_Agent/Stage_2_Clean"
INLINE_STAGE2_RELEASE_PATH = ( INLINE_STAGE2_RELEASE_PATH = (
@@ -71,7 +71,7 @@ Agent:
WORKFLOW_ID = "S2_20" WORKFLOW_ID = "S2_20"
ALGORITHM_VERSION = "s2_20_relief_plan/1.0.0" ALGORITHM_VERSION = "s2_20_relief_plan/1.0.0"
EXPECTED_STAGE2_RELEASE_SHA256 = "579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81" EXPECTED_STAGE2_RELEASE_SHA256 = "9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53"
LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp" LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp"
WEAVIATE_MCP_URL = "https://weaviate.eroomai.com/mcp" WEAVIATE_MCP_URL = "https://weaviate.eroomai.com/mcp"
MCP_PROTOCOL_VERSION = "2025-03-26" MCP_PROTOCOL_VERSION = "2025-03-26"
@@ -73,7 +73,7 @@ Agent:
from typing import Any, Mapping from typing import Any, Mapping
EXPECTED_STAGE2_RELEASE_SHA256 = "579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81" EXPECTED_STAGE2_RELEASE_SHA256 = "9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53"
LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp" LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp"
MCP_PROTOCOL_VERSION = "2025-03-26" MCP_PROTOCOL_VERSION = "2025-03-26"
INLINE_USER_HASH = "{{__user_hash__}}" INLINE_USER_HASH = "{{__user_hash__}}"
@@ -9,7 +9,7 @@ stage_bindings:
agent_script_ref: agent_script_ref:
asset_id: AGENT-S2_00-INLINE asset_id: AGENT-S2_00-INLINE
path: agent_scripts/Stage_2_S2_00.yml path: agent_scripts/Stage_2_S2_00.yml
sha256: 8d9583ce7b039ef848abfcbcdb27ac50a2e8a4e279a745b4779bcd90fc17cf64 sha256: 94c2744d71d222cfb5cc1b2a0d33a6cda20079439823de431eef378a2fa5c943
schema_id: liti_agent_yaml.v1 schema_id: liti_agent_yaml.v1
binding_status: BOUND binding_status: BOUND
workflow_contract_ref: workflow_contract_ref:
@@ -21,18 +21,18 @@ stage_bindings:
inline_code_receipt_ref: inline_code_receipt_ref:
asset_id: RECEIPT-S2_00-INLINE-CODE asset_id: RECEIPT-S2_00-INLINE-CODE
path: manifest/s2_00_inline_code_receipt.json path: manifest/s2_00_inline_code_receipt.json
sha256: ced01ef57a2e5341b1f7ddbf810ff3c6fb85fbb3cf7cf80836328a8a971835b4 sha256: 36af21949e5ef53a3d39df8ea9491c64da43abcc4f5e42e13db9bb391da843b8
schema_id: stage2_s2_00_inline_code_receipt.v2 schema_id: stage2_s2_00_inline_code_receipt.v2
binding_status: BOUND binding_status: BOUND
stage2_release_ref: stage2_release_ref:
asset_id: RELEASE-STAGE2-CLEAN asset_id: RELEASE-STAGE2-CLEAN
path: manifest/stage2_release.json path: manifest/stage2_release.json
sha256: 579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81 sha256: 9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53
schema_id: stage2_release.v2 schema_id: stage2_release.v2
binding_status: BOUND binding_status: BOUND
expected_release_sha256: 579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81 expected_release_sha256: 9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53
agent_script_sha256: 8d9583ce7b039ef848abfcbcdb27ac50a2e8a4e279a745b4779bcd90fc17cf64 agent_script_sha256: 94c2744d71d222cfb5cc1b2a0d33a6cda20079439823de431eef378a2fa5c943
canonical_code_sha256: 612bf08c26a2b96c827a774d79789a9902ffbf18fdd181a157dae40e25b5f8ca canonical_code_sha256: e3f87725d5a6496189e7c411ef940dd8a7b3a9ff5b00535803bf98fa0cc4373e
mcp_server_id: code-executor mcp_server_id: code-executor
tool_name: run_code tool_name: run_code
language: python language: python
@@ -73,7 +73,7 @@ stage_bindings:
agent_path: agent_scripts/Stage_2_S2_10.yml agent_path: agent_scripts/Stage_2_S2_10.yml
s2_10_agent_sha256: 122fe890efb340ebbac299afe058bf9ad0ed87d4d0ccf2456393e9e5796ec272 s2_10_agent_sha256: 122fe890efb340ebbac299afe058bf9ad0ed87d4d0ccf2456393e9e5796ec272
llm_binding_path: deployment/stage2_s2_10_llm_binding.yml llm_binding_path: deployment/stage2_s2_10_llm_binding.yml
s2_10_llm_binding_sha256: 9d20b264e753c2f52e8d096edab363ace0fecf2ec8357605d1a9cb47c9c2b930 s2_10_llm_binding_sha256: 9b5d69f1316a0b9fba7b41097ee92142cf42485c8deb0be876d9e9329c317a04
owner_binding_status: HASH_BOUND_LIVE_ADMISSION_PENDING owner_binding_status: HASH_BOUND_LIVE_ADMISSION_PENDING
s2_00_override_allowed: false s2_00_override_allowed: false
live_admission_status: PENDING_SECRET_BINDING live_admission_status: PENDING_SECRET_BINDING
@@ -86,7 +86,7 @@ stage_bindings:
agent_script_ref: agent_script_ref:
asset_id: AGENT-S2_20-INLINE asset_id: AGENT-S2_20-INLINE
path: agent_scripts/Stage_2_S2_20.yml path: agent_scripts/Stage_2_S2_20.yml
sha256: ac81d164309e5301083d0971e1736d128691fd9b18558ac4ade3f0246a43c2d7 sha256: 3c4e6a7404f5b6a6b2403824c3cd9e71db566d4f2865bd4de3e6fd9d07824bd6
schema_id: liti_agent_yaml.v1 schema_id: liti_agent_yaml.v1
binding_status: BOUND binding_status: BOUND
workflow_contract_ref: workflow_contract_ref:
@@ -98,18 +98,18 @@ stage_bindings:
inline_code_receipt_ref: inline_code_receipt_ref:
asset_id: RECEIPT-S2_20-INLINE-CODE asset_id: RECEIPT-S2_20-INLINE-CODE
path: manifest/s2_20_inline_code_receipt.json path: manifest/s2_20_inline_code_receipt.json
sha256: 60000d2412a757e9b2ab2525eedb08ebda20ec02a49f5b1b0c4e89e6a0aeca2b sha256: 65e29f10f065cdd77281aa47acaf341edb38b0595aab0aa9f04bbee3a4718608
schema_id: stage2_s2_20_inline_code_receipt.v1 schema_id: stage2_s2_20_inline_code_receipt.v1
binding_status: BOUND binding_status: BOUND
stage2_release_ref: stage2_release_ref:
asset_id: RELEASE-STAGE2-CLEAN asset_id: RELEASE-STAGE2-CLEAN
path: manifest/stage2_release.json path: manifest/stage2_release.json
sha256: 579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81 sha256: 9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53
schema_id: stage2_release.v2 schema_id: stage2_release.v2
binding_status: BOUND binding_status: BOUND
expected_release_sha256: 579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81 expected_release_sha256: 9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53
agent_script_sha256: ac81d164309e5301083d0971e1736d128691fd9b18558ac4ade3f0246a43c2d7 agent_script_sha256: 3c4e6a7404f5b6a6b2403824c3cd9e71db566d4f2865bd4de3e6fd9d07824bd6
canonical_code_sha256: eeb353b837cf5c2ecfb07fc7375eca03ac4e5c3df9254266d5690cbf14df7138 canonical_code_sha256: 6f1f503378242cf64cf8f0838af2164ab1103bc7031c8a6873f4ee89be66f7fd
mcp_server_id: code-executor mcp_server_id: code-executor
tool_name: run_code tool_name: run_code
language: python language: python
@@ -229,6 +229,87 @@ stage_bindings:
downstream_handoff_owner: null downstream_handoff_owner: null
live_admission_status: PENDING_SECRET_BINDING live_admission_status: PENDING_SECRET_BINDING
legacy_fallbacks: [] legacy_fallbacks: []
- stage_id: S2_40
binding_id: S2-BINDING-S2_40-CODE-EXECUTOR-V1
workflow_id: S2_40
execution_class: NON-LLM-DETERMINISTIC
active_runtime_authority: false
agent_script_ref:
asset_id: AGENT-S2_40-INLINE
path: agent_scripts/Stage_2_S2_40.yml
sha256: 5cbe2ac9aa73d95a5fa4e6cf71d7d8f0ad83aa05536f573c13e42505ef5d46f7
schema_id: liti_agent_yaml.v1
binding_status: BOUND
workflow_contract_ref:
asset_id: WF-S2_40
path: workflows/S2_40_final_review_render_and_commit.yml
sha256: ab1e5f593db41c1f26f9510c00d657221da53d08f011b2c4cf341a764a18d874
schema_id: stage2_s2_40_final_review_render_and_commit.v1
binding_status: BOUND
inline_code_receipt_ref:
asset_id: RECEIPT-S2_40-INLINE-CODE
path: manifest/s2_40_inline_code_receipt.json
sha256: 9bd0cfaee8d9e78480ab80a2fa541414c7ad0565439fa0f4661701fcdfde6526
schema_id: stage2_s2_40_inline_code_receipt.v1
binding_status: BOUND
stage2_release_ref:
asset_id: RELEASE-STAGE2-CLEAN
path: manifest/stage2_release.json
sha256: 9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53
schema_id: stage2_release.v2
binding_status: BOUND
expected_release_sha256: 9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53
agent_script_sha256: 5cbe2ac9aa73d95a5fa4e6cf71d7d8f0ad83aa05536f573c13e42505ef5d46f7
canonical_code_sha256: e521e1a65294a769cd6bf20edb159f8720c105b60cb769885aa416c8c763dcef
mcp_server_id: code-executor
tool_name: run_code
language: python
network: agent-network
timeout_seconds: 300
runtime_image_digest: PENDING_SEQUENTIAL_BIND
runtime_image_status: PENDING_BACKEND_EVIDENCE
dependency_lock:
requirements: httpx==0.28.1
requirements_sha256: 5fadf5f6ea5bd1b141ea05745cb52449bdccde939c22e76231e7993c2afc91d0
lock_status: LIVE_BACKEND_PENDING
localdocs_contract:
endpoint: http://mcp-localdocs:8012/mcp
user_id_template: '{{__user_hash__}}'
workspace_id_template: '{{__workspace_hash__}}'
tool_allowlist:
- read_binary_doc
- write_binary_file
fixed_request_path: stage2_control/s2_40_request.json
read_path_allowlist:
- stage2_control/s2_40_request.json
- Default_Agent/Stage_2_Clean/manifest/stage2_release.json
- Default_Agent/Stage_2_Clean/manifest/module_manifest.json
- Default_Agent/Stage_2_Clean/manifest/stage2_deterministic_admission_receipt.json
- Default_Agent/Stage_2_Clean/manifest/s2_40_inline_code_receipt.json
- Default_Agent/Stage_2_Clean/agent_scripts/Stage_2_S2_40.yml
- Default_Agent/Stage_2_Clean/deployment/stage2_code_executor_binding.yml
- Default_Agent/Stage_2_Clean/schemas/ingress.schema.json
- Default_Agent/Stage_2_Clean/schemas/context.schema.json
- Default_Agent/Stage_2_Clean/schemas/s2_10.schema.json
- Default_Agent/Stage_2_Clean/schemas/domain_verdict.schema.json
- Default_Agent/Stage_2_Clean/schemas/relief_plan.schema.json
- Default_Agent/Stage_2_Clean/schemas/binding_retrieval.schema.json
- Default_Agent/Stage_2_Clean/schemas/calculation.schema.json
- Default_Agent/Stage_2_Clean/schemas/draft_atoms.schema.json
- Default_Agent/Stage_2_Clean/schemas/review_status.schema.json
- Default_Agent/Stage_2_Clean/schemas/package.schema.json
- Default_Agent/Stage_2_Clean/registry/review/review_policy_registry.yml
- Default_Agent/Stage_2_Clean/renderers/<renderer_id>.yml
- stage2_runs/by-binding/<run_binding_digest>/<barrier-enumerated-input-path>
- stage2_runs/by-binding/<run_binding_digest>/review/receipts/<receipt_id>.json
- stage2_runs/by-binding/<run_binding_digest>/control/run_status.json
write_root_rule: stage2_runs/by-binding/<run_binding_digest>/
external_mcp_contract: null
egress_profile_id: S2_40_LOCALDOCS_ONLY_V1
egress_profile_status: PENDING_LIVE_VERIFICATION
downstream_handoff_owner: null
live_admission_status: PENDING_SECRET_BINDING
legacy_fallbacks: []
legacy_fallbacks: [] legacy_fallbacks: []
embedded_task_bindings: embedded_task_bindings:
- execution_unit_id: S2_30::Task_S2_30_dispatch_planner - execution_unit_id: S2_30::Task_S2_30_dispatch_planner
@@ -242,30 +323,30 @@ embedded_task_bindings:
agent_script_ref: agent_script_ref:
asset_id: AGENT-S2_30-INLINE asset_id: AGENT-S2_30-INLINE
path: agent_scripts/Stage_2_S2_30.yml path: agent_scripts/Stage_2_S2_30.yml
sha256: 6da21b319d10268e5f1959d085173d22017e4910c7222fd5e6daf72628629773 sha256: d0804526941207395c9b64a314b124ff8e919c6852e828d829dc45a9feb3ccdd
schema_id: liti_agent_yaml.v1 schema_id: liti_agent_yaml.v1
binding_status: BOUND binding_status: BOUND
workflow_contract_ref: workflow_contract_ref:
asset_id: WF-S2_30 asset_id: WF-S2_30
path: workflows/S2_30_claim_group_draft_map.yml path: workflows/S2_30_claim_group_draft_map.yml
sha256: 498715993d796f82a8c9e790a62bee6885c05813488fd0a11200f46c07665162 sha256: b266e7b7ae8939b087bfdb7b34fff8b9c6011c835560ab690991d856ced0cc15
schema_id: stage2_s2_30_claim_group_draft_map.v1 schema_id: stage2_s2_30_claim_group_draft_map.v1
binding_status: BOUND binding_status: BOUND
inline_code_receipt_ref: inline_code_receipt_ref:
asset_id: RECEIPT-S2_30-INLINE-CODE asset_id: RECEIPT-S2_30-INLINE-CODE
path: manifest/s2_30_inline_code_receipt.json path: manifest/s2_30_inline_code_receipt.json
sha256: 78fb197d50ec706be35cf1766bb9e9fee1767a8e61109603313821dd6040f552 sha256: 8d1618771cf1f72aa3c6a5a4544fe6b6e949ccc7ecfef56f166561971beee896
schema_id: stage2_s2_30_inline_code_receipt.v1 schema_id: stage2_s2_30_inline_code_receipt.v1
binding_status: BOUND binding_status: BOUND
stage2_release_ref: stage2_release_ref:
asset_id: RELEASE-STAGE2-CLEAN asset_id: RELEASE-STAGE2-CLEAN
path: manifest/stage2_release.json path: manifest/stage2_release.json
sha256: 579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81 sha256: 9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53
schema_id: stage2_release.v2 schema_id: stage2_release.v2
binding_status: BOUND binding_status: BOUND
expected_release_sha256: 579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81 expected_release_sha256: 9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53
agent_script_sha256: 6da21b319d10268e5f1959d085173d22017e4910c7222fd5e6daf72628629773 agent_script_sha256: d0804526941207395c9b64a314b124ff8e919c6852e828d829dc45a9feb3ccdd
canonical_code_sha256: 7814e64bfdbf5992d8009556b5a81268d99a0300d0b8f419c8c6384d90a906c9 canonical_code_sha256: 1f7f3b842afbd3f1034f094d6341288effc9804a03920ada4bf8cfd512464e4c
mcp_server_id: code-executor mcp_server_id: code-executor
tool_name: run_code tool_name: run_code
language: python language: python
@@ -51,7 +51,7 @@ prompt_contract:
selected_context_wrapper_sha256: c43c88cad59f2e9c88d944d4997551063e133207398dee0633af53e2bc5bcab6 selected_context_wrapper_sha256: c43c88cad59f2e9c88d944d4997551063e133207398dee0633af53e2bc5bcab6
cluster_payload_wrapper_sha256: aaffb47bb21a975a13075901f3152d7a41b6e1661fa1626f42e678ba8abfdda8 cluster_payload_wrapper_sha256: aaffb47bb21a975a13075901f3152d7a41b6e1661fa1626f42e678ba8abfdda8
projection_receipt_path: manifest/s2_10_inline_prompt_projection_receipt.json projection_receipt_path: manifest/s2_10_inline_prompt_projection_receipt.json
projection_receipt_sha256: 7f64a192e7edda7c0e4025b9f1995dcd21c38aba15a018d232f9f05bcba35863 projection_receipt_sha256: b7fdef2ad05f251bdede9473d3b69c0f169ab7f4a059b393429ff76f739f703e
canonical_source_paths: canonical_source_paths:
- prompts/P00_system_and_safety_contract.md - prompts/P00_system_and_safety_contract.md
- prompts/P10_legal_resolution_contract.md - prompts/P10_legal_resolution_contract.md
@@ -2,18 +2,18 @@ schema_version: stage2_s2_30_llm_binding.v1
binding_status: PENDING_EXTERNAL_PLATFORM_BINDING binding_status: PENDING_EXTERNAL_PLATFORM_BINDING
agent_ref: agent_ref:
path: agent_scripts/Stage_2_S2_30.yml path: agent_scripts/Stage_2_S2_30.yml
sha256: 6da21b319d10268e5f1959d085173d22017e4910c7222fd5e6daf72628629773 sha256: d0804526941207395c9b64a314b124ff8e919c6852e828d829dc45a9feb3ccdd
workflow_ref: workflow_ref:
path: workflows/S2_30_claim_group_draft_map.yml path: workflows/S2_30_claim_group_draft_map.yml
sha256: 498715993d796f82a8c9e790a62bee6885c05813488fd0a11200f46c07665162 sha256: b266e7b7ae8939b087bfdb7b34fff8b9c6011c835560ab690991d856ced0cc15
size_bytes: 12932 size_bytes: 15221
schema_ref: schema_ref:
path: schemas/draft_atoms.schema.json path: schemas/draft_atoms.schema.json
sha256: 6cbb81f8cc857173efda0ef3a95c3d39c64f057a64ab1927cf6a5967c592d9ce sha256: 5107b64f01ffb3633a829c10652747760a5035c9cc07227c546e3f543005eda9
size_bytes: 57750 size_bytes: 68470
planner_ref: planner_ref:
path: runtime/s2_30_dispatch_planner.py path: runtime/s2_30_dispatch_planner.py
sha256: 7814e64bfdbf5992d8009556b5a81268d99a0300d0b8f419c8c6384d90a906c9 sha256: 1f7f3b842afbd3f1034f094d6341288effc9804a03920ada4bf8cfd512464e4c
model: model:
provider: openai provider: openai
model_id: gpt-5.6-sol model_id: gpt-5.6-sol
@@ -30,10 +30,10 @@ prompt_contract:
- S30 - S30
inline_common_prompt_sha256: a90ac95f0b24ea938a16699f34ef7f17eb870edcbd8964ba4f6709e36e1bbcc0 inline_common_prompt_sha256: a90ac95f0b24ea938a16699f34ef7f17eb870edcbd8964ba4f6709e36e1bbcc0
inline_static_prompt_sha256: 577efa2c3334298ec60188b9f0066f834e072dc99f785b3c6ab4d05a47fac18a inline_static_prompt_sha256: 577efa2c3334298ec60188b9f0066f834e072dc99f785b3c6ab4d05a47fac18a
projection_receipt_sha256: 2ea4d273eb3aa23550159dc4f821e1c3863fc457a48ed429a7c9522bfa293eac projection_receipt_sha256: 1aa650d3c389ba27ce43e514295c7c2ce629583dc96220618fd97dea399d0757
runtime_external_prompt_read_allowed: false runtime_external_prompt_read_allowed: false
planner_contract: planner_contract:
inline_code_receipt_sha256: 78fb197d50ec706be35cf1766bb9e9fee1767a8e61109603313821dd6040f552 inline_code_receipt_sha256: 8d1618771cf1f72aa3c6a5a4544fe6b6e949ccc7ecfef56f166561971beee896
legal_reasoning_allowed: false legal_reasoning_allowed: false
persistent_write_allowed: false persistent_write_allowed: false
native_adapter: native_adapter:
@@ -55,14 +55,14 @@ native_adapter:
producer_contract: producer_contract:
material: material:
algorithm_id: S2_30-PRODUCER-CONTRACT-PROJECTION-V1 algorithm_id: S2_30-PRODUCER-CONTRACT-PROJECTION-V1
raw_model_output_schema_sha256: 6cbb81f8cc857173efda0ef3a95c3d39c64f057a64ab1927cf6a5967c592d9ce raw_model_output_schema_sha256: 5107b64f01ffb3633a829c10652747760a5035c9cc07227c546e3f543005eda9
strict_validator_sha256: 30dff7cc1717c792a6da9bcbd3533c82c9bf3902f09fc9fe92a086c2e13694c6 strict_validator_sha256: 14e4eefb73d40d004c95017c82cdc23ac1c1c0a54ea34562dcf322f6364ae27a
strict_validator_algorithm_id: S2_30-OFFLINE-NATIVE-ADAPTER-ORACLE-V1 strict_validator_algorithm_id: S2_30-OFFLINE-NATIVE-ADAPTER-ORACLE-V1
atom_id_algorithm_id: S2_30-DETERMINISTIC-ATOM-ID-V1 atom_id_algorithm_id: S2_30-DETERMINISTIC-ATOM-ID-V1
two_pass_rewrite_algorithm_id: S2_30-TWO-PASS-LOCAL-REF-REWRITE-V1 two_pass_rewrite_algorithm_id: S2_30-TWO-PASS-LOCAL-REF-REWRITE-V1
context_materializer_algorithm_id: S2_30-EXACT-REF-MATERIALIZER-V1 context_materializer_algorithm_id: S2_30-EXACT-REF-MATERIALIZER-V1
native_capability_projection_sha256: b284d20dc950db8b8fe015578d10657beda479a55665d34d77319d4f81fa4a68 native_capability_projection_sha256: b284d20dc950db8b8fe015578d10657beda479a55665d34d77319d4f81fa4a68
s2_30_producer_contract_digest: 337fd978acb335e89ef3ee859bf2333403858b370cbc5466d601317ba027fe4a s2_30_producer_contract_digest: b0d7e781e8a59ebd9e9ed8db6d04973640b2a127440f32b7bff605103cbc23e0
whole_binding_hash_in_material: false whole_binding_hash_in_material: false
parent_or_child_hash_in_material: false parent_or_child_hash_in_material: false
self_referential_digest_fields_excluded: true self_referential_digest_fields_excluded: true
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
{"authoring":{"path":"Stage_2_S2_00_v.2.yml","sha256":"8d9583ce7b039ef848abfcbcdb27ac50a2e8a4e279a745b4779bcd90fc17cf64","size_bytes":367573,"unique_key_parse":"PASS"},"authoring_rewritten":false,"build_kind":"OFFLINE_AUTHORING_PROJECTION","canonical_code":{"ast_status":"PASS","code_sha256":"612bf08c26a2b96c827a774d79789a9902ffbf18fdd181a157dae40e25b5f8ca","code_size_bytes":283196,"compile_status":"PASS","encoding":"UTF-8","external_python_source_ref_count":0,"external_url_count":0,"extraction_transform":"NONE","forbidden_dynamic_call_count":0,"forbidden_import_count":0,"imports":["__future__","argparse","base64","binascii","collections","contextlib","dataclasses","hashlib","httpx","io","itertools","json","math","os","pathlib","re","shutil","stat","sys","tempfile","typing","unicodedata"],"placeholder_count":0,"plaintext_secret_count":0,"yaml_pointer":"/Agent/Stages/0/tasks/0/parameters/code"},"deployment_projection":{"byte_identical_to_authoring":true,"canonical_task_semantics_sha256":"0ae62c60183e0cffbef198d8efce4a0fcbcaddef223133075b19ee19c50ea65d","path":"Default_Agent/Stage_2_Clean/agent_scripts/Stage_2_S2_00.yml","sha256":"8d9583ce7b039ef848abfcbcdb27ac50a2e8a4e279a745b4779bcd90fc17cf64","size_bytes":367573},"full_code_mirrors":[{"byte_identical_to_canonical_code":true,"path":"Default_Agent/Stage_2_Clean/runtime/s2_00_ingress.py","sha256":"612bf08c26a2b96c827a774d79789a9902ffbf18fdd181a157dae40e25b5f8ca","size_bytes":283196},{"byte_identical_to_canonical_code":true,"path":"Default_Agent/Stage_2_Clean/runtime/s2_00_ingress.txt","sha256":"612bf08c26a2b96c827a774d79789a9902ffbf18fdd181a157dae40e25b5f8ca","size_bytes":283196}],"parity_status":"PASS","schema_version":"stage2_s2_00_inline_code_receipt.v2","source_of_truth":"Stage_2_S2_00_v.2.yml","task_contract":{"agent":{"name":"Stage_2_S2_00_v2","version":"1.2.0"},"mcp_servers":{"code-executor":{"type":"streamable-http","url":"https://code-executor.mcp.eroomai.com/mcp"},"localdocs":{"type":"streamable-http","url":"http://mcp-localdocs:8012/mcp"}},"stage":{"name":"S2_00","nexts":[],"prevs":[]},"task":{"code_sha256":"612bf08c26a2b96c827a774d79789a9902ffbf18fdd181a157dae40e25b5f8ca","mcp":"code-executor","parameters":{"language":"python","network":"agent-network","requirements":"httpx==0.28.1","timeout":300},"task_name":"Task_S2_00_deterministic_ingress","tool_name":"run_code"},"task_procedure":{"IN":{"nexts":["Task_S2_00_deterministic_ingress"],"wait_until":[]},"OUT":{"nexts":[],"wait_until":["Task_S2_00_deterministic_ingress"]},"Task_S2_00_deterministic_ingress":{"nexts":["OUT"],"wait_until":["IN"]}}},"workflow_id":"S2_00"} {"authoring":{"path":"Stage_2_S2_00_v.2.yml","sha256":"94c2744d71d222cfb5cc1b2a0d33a6cda20079439823de431eef378a2fa5c943","size_bytes":367573,"unique_key_parse":"PASS"},"authoring_rewritten":false,"build_kind":"OFFLINE_AUTHORING_PROJECTION","canonical_code":{"ast_status":"PASS","code_sha256":"e3f87725d5a6496189e7c411ef940dd8a7b3a9ff5b00535803bf98fa0cc4373e","code_size_bytes":283196,"compile_status":"PASS","encoding":"UTF-8","external_python_source_ref_count":0,"external_url_count":0,"extraction_transform":"NONE","forbidden_dynamic_call_count":0,"forbidden_import_count":0,"imports":["__future__","argparse","base64","binascii","collections","contextlib","dataclasses","hashlib","httpx","io","itertools","json","math","os","pathlib","re","shutil","stat","sys","tempfile","typing","unicodedata"],"placeholder_count":0,"plaintext_secret_count":0,"yaml_pointer":"/Agent/Stages/0/tasks/0/parameters/code"},"deployment_projection":{"byte_identical_to_authoring":true,"canonical_task_semantics_sha256":"a970635aa19b4ebca03819e30de32bb69f33ca455f7ecd6257a45636565b4e95","path":"Default_Agent/Stage_2_Clean/agent_scripts/Stage_2_S2_00.yml","sha256":"94c2744d71d222cfb5cc1b2a0d33a6cda20079439823de431eef378a2fa5c943","size_bytes":367573},"full_code_mirrors":[{"byte_identical_to_canonical_code":true,"path":"Default_Agent/Stage_2_Clean/runtime/s2_00_ingress.py","sha256":"e3f87725d5a6496189e7c411ef940dd8a7b3a9ff5b00535803bf98fa0cc4373e","size_bytes":283196},{"byte_identical_to_canonical_code":true,"path":"Default_Agent/Stage_2_Clean/runtime/s2_00_ingress.txt","sha256":"e3f87725d5a6496189e7c411ef940dd8a7b3a9ff5b00535803bf98fa0cc4373e","size_bytes":283196}],"parity_status":"PASS","schema_version":"stage2_s2_00_inline_code_receipt.v2","source_of_truth":"Stage_2_S2_00_v.2.yml","task_contract":{"agent":{"name":"Stage_2_S2_00_v2","version":"1.2.0"},"mcp_servers":{"code-executor":{"type":"streamable-http","url":"https://code-executor.mcp.eroomai.com/mcp"},"localdocs":{"type":"streamable-http","url":"http://mcp-localdocs:8012/mcp"}},"stage":{"name":"S2_00","nexts":[],"prevs":[]},"task":{"code_sha256":"e3f87725d5a6496189e7c411ef940dd8a7b3a9ff5b00535803bf98fa0cc4373e","mcp":"code-executor","parameters":{"language":"python","network":"agent-network","requirements":"httpx==0.28.1","timeout":300},"task_name":"Task_S2_00_deterministic_ingress","tool_name":"run_code"},"task_procedure":{"IN":{"nexts":["Task_S2_00_deterministic_ingress"],"wait_until":[]},"OUT":{"nexts":[],"wait_until":["Task_S2_00_deterministic_ingress"]},"Task_S2_00_deterministic_ingress":{"nexts":["OUT"],"wait_until":["IN"]}}},"workflow_id":"S2_00"}
@@ -1 +1 @@
{"agent_contract":{"agent_name":"Stage_2_S2_10","agent_version":"1.1.0","deterministic_task_count":0,"inline_common_prompt_sha256":"a90ac95f0b24ea938a16699f34ef7f17eb870edcbd8964ba4f6709e36e1bbcc0","inline_static_prompt_sha256":"894c30bedaa5f230aed117e81ef4cc06cac832928a1e29cd3ee8804cfd4dba1f","item_tokens":["{{item.selected_legal_context_json}}","{{item.cluster_case_payload_json}}"],"llm_task_count":1,"prompt_roles":["system","system","system","user"],"reduce_task_count":0,"stage_name":"S2_10","task_name":"Task_S2_10_resolve_cluster","tool_task_count":0},"authoring":{"path":"Stage_2_S2_10_v.1.yml","sha256":"122fe890efb340ebbac299afe058bf9ad0ed87d4d0ccf2456393e9e5796ec272","size_bytes":30984},"binding":{"path":"deployment/stage2_s2_10_llm_binding.yml","sha256":"9d20b264e753c2f52e8d096edab363ace0fecf2ec8357605d1a9cb47c9c2b930"},"child_release":{"path":"manifest/s2_10_release.json","release_digest":"262579cc93e89d1a90cd928bf24f21e820022226493ad0a05ae4dc44bef7debd","sha256":"73cf98c94117db12f04c298e5758431d5006c7a9ddb8dd46ff2e7b19313bdb9c"},"deployment":{"byte_parity":"PASS","path":"agent_scripts/Stage_2_S2_10.yml","sha256":"122fe890efb340ebbac299afe058bf9ad0ed87d4d0ccf2456393e9e5796ec272","size_bytes":30984},"external_admission_status":"PENDING","inline_prompt_receipt":{"path":"manifest/s2_10_inline_prompt_projection_receipt.json","sha256":"7f64a192e7edda7c0e4025b9f1995dcd21c38aba15a018d232f9f05bcba35863","size_bytes":2659},"receipt_digest":"32f7ba8b4fbe0502f9a44c6f13059ce2aba9855bb350c72ca22ba936cb552b60","receipt_status":"OFFLINE_AGENT_PROJECTION_VERIFIED","runtime_admission_effect":"NONE","schema":{"path":"schemas/s2_10.schema.json","sha256":"5233afde9ddb3c5868b9101816e8b3830a90b1399e3e5e89d9d7c7bf5beacaee","size_bytes":82703},"schema_version":"stage2_s2_10_agent_receipt.v2","workflow":{"path":"workflows/S2_10_domain_relief_resolution_map.yml","sha256":"f0fba48f1760cf4e233d7d698fd19090f96ffb89cabe4b2e2cae9af7c616be0f","size_bytes":15320}} {"agent_contract":{"agent_name":"Stage_2_S2_10","agent_version":"1.1.0","deterministic_task_count":0,"inline_common_prompt_sha256":"a90ac95f0b24ea938a16699f34ef7f17eb870edcbd8964ba4f6709e36e1bbcc0","inline_static_prompt_sha256":"894c30bedaa5f230aed117e81ef4cc06cac832928a1e29cd3ee8804cfd4dba1f","item_tokens":["{{item.selected_legal_context_json}}","{{item.cluster_case_payload_json}}"],"llm_task_count":1,"prompt_roles":["system","system","system","user"],"reduce_task_count":0,"stage_name":"S2_10","task_name":"Task_S2_10_resolve_cluster","tool_task_count":0},"authoring":{"path":"Stage_2_S2_10_v.1.yml","sha256":"122fe890efb340ebbac299afe058bf9ad0ed87d4d0ccf2456393e9e5796ec272","size_bytes":30984},"binding":{"path":"deployment/stage2_s2_10_llm_binding.yml","sha256":"9b5d69f1316a0b9fba7b41097ee92142cf42485c8deb0be876d9e9329c317a04"},"child_release":{"path":"manifest/s2_10_release.json","release_digest":"8cfc30a40ad53b35fb44c56e3c53f86605f777622399a4b1dcd0b2082eb6e197","sha256":"cb49a4501116e46d935933b739b6679b11d961ff8e36abefea35dab6b25508fb"},"deployment":{"byte_parity":"PASS","path":"agent_scripts/Stage_2_S2_10.yml","sha256":"122fe890efb340ebbac299afe058bf9ad0ed87d4d0ccf2456393e9e5796ec272","size_bytes":30984},"external_admission_status":"PENDING","inline_prompt_receipt":{"path":"manifest/s2_10_inline_prompt_projection_receipt.json","sha256":"b7fdef2ad05f251bdede9473d3b69c0f169ab7f4a059b393429ff76f739f703e","size_bytes":2659},"receipt_digest":"9bd92db101c0bf6f0c48764c71f5091e573dc65cce307ce3121b5d0271efc36c","receipt_status":"OFFLINE_AGENT_PROJECTION_VERIFIED","runtime_admission_effect":"NONE","schema":{"path":"schemas/s2_10.schema.json","sha256":"5233afde9ddb3c5868b9101816e8b3830a90b1399e3e5e89d9d7c7bf5beacaee","size_bytes":82703},"schema_version":"stage2_s2_10_agent_receipt.v2","workflow":{"path":"workflows/S2_10_domain_relief_resolution_map.yml","sha256":"f0fba48f1760cf4e233d7d698fd19090f96ffb89cabe4b2e2cae9af7c616be0f","size_bytes":15320}}
@@ -1 +1 @@
{"authoring_agent":{"path":"Stage_2_S2_10_v.1.yml","sha256":"122fe890efb340ebbac299afe058bf9ad0ed87d4d0ccf2456393e9e5796ec272","size_bytes":30984},"builder":{"path":"offline_build/build_s2_10_agent_projection.py","sha256":"4359364816c8a58eb414bafae8ccf24fc3766dc611d15f1aa09e48c8fedc8f88","size_bytes":61930},"canonicalization_algorithm_id":"S2_10-NFC-LF-RTRIM-CLAUSE-PROJECTION-V1","deployment_agent":{"byte_parity":"PASS","path":"agent_scripts/Stage_2_S2_10.yml","sha256":"122fe890efb340ebbac299afe058bf9ad0ed87d4d0ccf2456393e9e5796ec272","size_bytes":30984},"inline_scalars":[{"raw_scalar_sha256":"a90ac95f0b24ea938a16699f34ef7f17eb870edcbd8964ba4f6709e36e1bbcc0","role":"system","size_bytes":7364,"wrapper":"stage_2_common_cache_prefix","yaml_pointer":"/Agent/Stages/0/map_reduce/map/tasks/0/prompts/0/content"},{"raw_scalar_sha256":"894c30bedaa5f230aed117e81ef4cc06cac832928a1e29cd3ee8804cfd4dba1f","role":"system","size_bytes":12261,"wrapper":"s2_10_legal_resolution_static_prompt","yaml_pointer":"/Agent/Stages/0/map_reduce/map/tasks/0/prompts/1/content"}],"message_order":["INLINE_COMMON_SYSTEM","INLINE_STATIC_LEGAL_SYSTEM","SELECTED_CONTEXT_SYSTEM_DATA","CLUSTER_CASE_USER_DATA"],"raw_scalar_hash_algorithm_id":"SHA256-UTF8-PARSED-YAML-SCALAR-V1","receipt_digest":"6c5e9504d5921ee552023d05bcd61ed9752c3ac02ab93f0b75ed360390b85313","receipt_status":"OFFLINE_PROJECTION_VERIFIED","runtime_admission_effect":"NONE","schema_version":"stage2_s2_10_inline_prompt_projection_receipt.v1","source_projections":[{"inline_clause_projection_sha256":"c82cfc0b61adb1af7759fd321f78bcf7bebf7e5d2fc3a9c01533a80736c6d80e","inline_wrapper":"stage_2_common_cache_prefix","parity":"PASS","source":{"path":"prompts/P00_system_and_safety_contract.md","sha256":"c82cfc0b61adb1af7759fd321f78bcf7bebf7e5d2fc3a9c01533a80736c6d80e","size_bytes":7304},"source_clause_projection_sha256":"c82cfc0b61adb1af7759fd321f78bcf7bebf7e5d2fc3a9c01533a80736c6d80e"},{"hybrid_supersession_required":true,"inline_clause_projection_sha256":"cafaab3991b8bd4ef3c95e55ce4c0649794c6eed9479d46d8c7758a4b823569b","inline_wrapper":"s2_10_legal_resolution_static_prompt","parity":"PASS","source":{"path":"prompts/P10_legal_resolution_contract.md","sha256":"cafaab3991b8bd4ef3c95e55ce4c0649794c6eed9479d46d8c7758a4b823569b","size_bytes":8712},"source_clause_projection_sha256":"cafaab3991b8bd4ef3c95e55ce4c0649794c6eed9479d46d8c7758a4b823569b"}],"validation":{"dynamic_item_tokens":["{{item.selected_legal_context_json}}","{{item.cluster_case_payload_json}}"],"normalized_clause_projection":"PASS","prompt_order":"PASS","static_item_token_count":0,"static_pii_scan":"PASS","wrapper_integrity":"PASS"}} {"authoring_agent":{"path":"Stage_2_S2_10_v.1.yml","sha256":"122fe890efb340ebbac299afe058bf9ad0ed87d4d0ccf2456393e9e5796ec272","size_bytes":30984},"builder":{"path":"offline_build/build_s2_10_agent_projection.py","sha256":"efdde6d70c723e9386f2ba1828119af7e68f7956c29bd3ba05370242a70ab62d","size_bytes":68381},"canonicalization_algorithm_id":"S2_10-NFC-LF-RTRIM-CLAUSE-PROJECTION-V1","deployment_agent":{"byte_parity":"PASS","path":"agent_scripts/Stage_2_S2_10.yml","sha256":"122fe890efb340ebbac299afe058bf9ad0ed87d4d0ccf2456393e9e5796ec272","size_bytes":30984},"inline_scalars":[{"raw_scalar_sha256":"a90ac95f0b24ea938a16699f34ef7f17eb870edcbd8964ba4f6709e36e1bbcc0","role":"system","size_bytes":7364,"wrapper":"stage_2_common_cache_prefix","yaml_pointer":"/Agent/Stages/0/map_reduce/map/tasks/0/prompts/0/content"},{"raw_scalar_sha256":"894c30bedaa5f230aed117e81ef4cc06cac832928a1e29cd3ee8804cfd4dba1f","role":"system","size_bytes":12261,"wrapper":"s2_10_legal_resolution_static_prompt","yaml_pointer":"/Agent/Stages/0/map_reduce/map/tasks/0/prompts/1/content"}],"message_order":["INLINE_COMMON_SYSTEM","INLINE_STATIC_LEGAL_SYSTEM","SELECTED_CONTEXT_SYSTEM_DATA","CLUSTER_CASE_USER_DATA"],"raw_scalar_hash_algorithm_id":"SHA256-UTF8-PARSED-YAML-SCALAR-V1","receipt_digest":"096cedfb69f915cef492cc37b78f8605386a091c47da9b51c9a499859c2edb00","receipt_status":"OFFLINE_PROJECTION_VERIFIED","runtime_admission_effect":"NONE","schema_version":"stage2_s2_10_inline_prompt_projection_receipt.v1","source_projections":[{"inline_clause_projection_sha256":"c82cfc0b61adb1af7759fd321f78bcf7bebf7e5d2fc3a9c01533a80736c6d80e","inline_wrapper":"stage_2_common_cache_prefix","parity":"PASS","source":{"path":"prompts/P00_system_and_safety_contract.md","sha256":"c82cfc0b61adb1af7759fd321f78bcf7bebf7e5d2fc3a9c01533a80736c6d80e","size_bytes":7304},"source_clause_projection_sha256":"c82cfc0b61adb1af7759fd321f78bcf7bebf7e5d2fc3a9c01533a80736c6d80e"},{"hybrid_supersession_required":true,"inline_clause_projection_sha256":"cafaab3991b8bd4ef3c95e55ce4c0649794c6eed9479d46d8c7758a4b823569b","inline_wrapper":"s2_10_legal_resolution_static_prompt","parity":"PASS","source":{"path":"prompts/P10_legal_resolution_contract.md","sha256":"cafaab3991b8bd4ef3c95e55ce4c0649794c6eed9479d46d8c7758a4b823569b","size_bytes":8712},"source_clause_projection_sha256":"cafaab3991b8bd4ef3c95e55ce4c0649794c6eed9479d46d8c7758a4b823569b"}],"validation":{"dynamic_item_tokens":["{{item.selected_legal_context_json}}","{{item.cluster_case_payload_json}}"],"normalized_clause_projection":"PASS","prompt_order":"PASS","static_item_token_count":0,"static_pii_scan":"PASS","wrapper_integrity":"PASS"}}
@@ -1 +1 @@
{"binding_sha256":"9d20b264e753c2f52e8d096edab363ace0fecf2ec8357605d1a9cb47c9c2b930","finding_ids":[],"inline_prompt_projection_sha256":"7f64a192e7edda7c0e4025b9f1995dcd21c38aba15a018d232f9f05bcba35863","receipt_digest":"ca74b98b8da5252ecb063f561d0aba62013d259a4c8cfe1fd1cf77401771f38a","review_id":"S2_10-HYBRID-LEGAL-REVIEW-PENDING","review_scope_digest":"b9396e8b25be70be35032de9f621f1ac9329a419f868f31619f5ae871a28f8e1","reviewer_role":"KOREAN_ATTORNEY","s2_10_release_sha256":"73cf98c94117db12f04c298e5758431d5006c7a9ddb8dd46ff2e7b19313bdb9c","schema_version":"stage2_s2_10_legal_review_receipt.v2","signature_ref":null,"signed_at":null,"signed_by":null,"status":"PENDING_KOREAN_LAWYER_REVIEW"} {"binding_sha256":"9b5d69f1316a0b9fba7b41097ee92142cf42485c8deb0be876d9e9329c317a04","finding_ids":[],"inline_prompt_projection_sha256":"b7fdef2ad05f251bdede9473d3b69c0f169ab7f4a059b393429ff76f739f703e","receipt_digest":"18a29c299f5587993c17f5a40b1d2c60d03556e4b37306c23352d671c4dcbb7c","review_id":"S2_10-HYBRID-LEGAL-REVIEW-PENDING","review_scope_digest":"c8675e22ff50ba9599ab3ac3108f13718b412fc0de2425133f3f49981edf0735","reviewer_role":"KOREAN_ATTORNEY","s2_10_release_sha256":"cb49a4501116e46d935933b739b6679b11d961ff8e36abefea35dab6b25508fb","schema_version":"stage2_s2_10_legal_review_receipt.v2","signature_ref":null,"signed_at":null,"signed_by":null,"status":"PENDING_KOREAN_LAWYER_REVIEW"}
@@ -1 +1 @@
{"benchmark_id":"S2_10-HYBRID-MODEL-BENCHMARK-PENDING","binding_sha256":"9d20b264e753c2f52e8d096edab363ace0fecf2ec8357605d1a9cb47c9c2b930","cache_telemetry_observed":null,"endpoint":"responses","latency_p95_ms":null,"model":"gpt-5.6-sol","observed_fixture_refs":[],"reasoning_effort":"xhigh","receipt_digest":"ab4b1993b19b61d5de82756dfeb8eb0d853f50e09e7325624da5292c043149b8","s2_10_release_sha256":"73cf98c94117db12f04c298e5758431d5006c7a9ddb8dd46ff2e7b19313bdb9c","schema_pass_rate":null,"schema_version":"stage2_s2_10_model_benchmark_receipt.v2","signature_ref":null,"signed_at":null,"signed_by":null,"status":"PENDING_MODEL_BENCHMARK","usage_telemetry_observed":null,"verbosity":"medium"} {"benchmark_id":"S2_10-HYBRID-MODEL-BENCHMARK-PENDING","binding_sha256":"9b5d69f1316a0b9fba7b41097ee92142cf42485c8deb0be876d9e9329c317a04","cache_telemetry_observed":null,"endpoint":"responses","latency_p95_ms":null,"model":"gpt-5.6-sol","observed_fixture_refs":[],"reasoning_effort":"xhigh","receipt_digest":"61f34770c1ebbc4c84c53ea925b07416b92f4baf4f1740294423eacbc17895ce","s2_10_release_sha256":"cb49a4501116e46d935933b739b6679b11d961ff8e36abefea35dab6b25508fb","schema_pass_rate":null,"schema_version":"stage2_s2_10_model_benchmark_receipt.v2","signature_ref":null,"signed_at":null,"signed_by":null,"status":"PENDING_MODEL_BENCHMARK","usage_telemetry_observed":null,"verbosity":"medium"}
@@ -1 +1 @@
{"adapter_contract_version":"S2_10_NATIVE_RESULT_ADAPTER_V2","binding_sha256":"9d20b264e753c2f52e8d096edab363ace0fecf2ec8357605d1a9cb47c9c2b930","capabilities":[{"activation_binding_ref":null,"capability_id":"HOST_ATOMIC_SINGLE_FLIGHT_CAS_V1","failure_reason_codes":["PENDING_EXTERNAL_PLATFORM_BINDING"],"handler_digest":null,"handler_version":null,"implementation_ref":null,"live_evidence_refs":[],"status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"activation_binding_ref":null,"capability_id":"AGENTBACKEND_MAP_SOURCE_ITEMS_V1","failure_reason_codes":["PENDING_EXTERNAL_PLATFORM_BINDING"],"handler_digest":null,"handler_version":null,"implementation_ref":null,"live_evidence_refs":[],"status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"activation_binding_ref":null,"capability_id":"AGENTBACKEND_NO_REDUCE_RESULT_ADAPTER_V1","failure_reason_codes":["PENDING_EXTERNAL_PLATFORM_BINDING"],"handler_digest":null,"handler_version":null,"implementation_ref":null,"live_evidence_refs":[],"status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"activation_binding_ref":null,"capability_id":"S2_10_STRICT_SCHEMA_AND_REF_VALIDATOR_V1","failure_reason_codes":["PENDING_EXTERNAL_PLATFORM_BINDING"],"handler_digest":null,"handler_version":null,"implementation_ref":null,"live_evidence_refs":[],"status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"activation_binding_ref":null,"capability_id":"S2_10_DETERMINISTIC_ID_AND_IMMUTABLE_PERSIST_V1","failure_reason_codes":["PENDING_EXTERNAL_PLATFORM_BINDING"],"handler_digest":null,"handler_version":null,"implementation_ref":null,"live_evidence_refs":[],"status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"activation_binding_ref":null,"capability_id":"S2_10_ITEM_RETRY_CONTROLLER_V1","failure_reason_codes":["PENDING_EXTERNAL_PLATFORM_BINDING"],"handler_digest":null,"handler_version":null,"implementation_ref":null,"live_evidence_refs":[],"status":"PENDING_EXTERNAL_PLATFORM_BINDING"}],"overall_status":"PENDING_EXTERNAL_PLATFORM_BINDING","parent_stage2_release_sha256":"579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81","receipt_digest":"d9d5aa86ba1f50a7ad6536c6907ab8faffee6f72a2f0f65f8422c8390a23c8d9","receipt_id":"S2_10-HYBRID-PLATFORM-ADAPTER-PENDING","s2_10_release_sha256":"73cf98c94117db12f04c298e5758431d5006c7a9ddb8dd46ff2e7b19313bdb9c","schema_version":"stage2_s2_10_platform_adapter_receipt.v2","signature_ref":null,"signed_at":null,"signed_by":null} {"adapter_contract_version":"S2_10_NATIVE_RESULT_ADAPTER_V2","binding_sha256":"9b5d69f1316a0b9fba7b41097ee92142cf42485c8deb0be876d9e9329c317a04","capabilities":[{"activation_binding_ref":null,"capability_id":"HOST_ATOMIC_SINGLE_FLIGHT_CAS_V1","failure_reason_codes":["PENDING_EXTERNAL_PLATFORM_BINDING"],"handler_digest":null,"handler_version":null,"implementation_ref":null,"live_evidence_refs":[],"status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"activation_binding_ref":null,"capability_id":"AGENTBACKEND_MAP_SOURCE_ITEMS_V1","failure_reason_codes":["PENDING_EXTERNAL_PLATFORM_BINDING"],"handler_digest":null,"handler_version":null,"implementation_ref":null,"live_evidence_refs":[],"status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"activation_binding_ref":null,"capability_id":"AGENTBACKEND_NO_REDUCE_RESULT_ADAPTER_V1","failure_reason_codes":["PENDING_EXTERNAL_PLATFORM_BINDING"],"handler_digest":null,"handler_version":null,"implementation_ref":null,"live_evidence_refs":[],"status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"activation_binding_ref":null,"capability_id":"S2_10_STRICT_SCHEMA_AND_REF_VALIDATOR_V1","failure_reason_codes":["PENDING_EXTERNAL_PLATFORM_BINDING"],"handler_digest":null,"handler_version":null,"implementation_ref":null,"live_evidence_refs":[],"status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"activation_binding_ref":null,"capability_id":"S2_10_DETERMINISTIC_ID_AND_IMMUTABLE_PERSIST_V1","failure_reason_codes":["PENDING_EXTERNAL_PLATFORM_BINDING"],"handler_digest":null,"handler_version":null,"implementation_ref":null,"live_evidence_refs":[],"status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"activation_binding_ref":null,"capability_id":"S2_10_ITEM_RETRY_CONTROLLER_V1","failure_reason_codes":["PENDING_EXTERNAL_PLATFORM_BINDING"],"handler_digest":null,"handler_version":null,"implementation_ref":null,"live_evidence_refs":[],"status":"PENDING_EXTERNAL_PLATFORM_BINDING"}],"overall_status":"PENDING_EXTERNAL_PLATFORM_BINDING","parent_stage2_release_sha256":"9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53","receipt_digest":"3c3a005c2ff658a53c37631e82e5dc536e038bd357cacaaefbd37453b2a99245","receipt_id":"S2_10-HYBRID-PLATFORM-ADAPTER-PENDING","s2_10_release_sha256":"cb49a4501116e46d935933b739b6679b11d961ff8e36abefea35dab6b25508fb","schema_version":"stage2_s2_10_platform_adapter_receipt.v2","signature_ref":null,"signed_at":null,"signed_by":null}
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
{"authoring":{"path":"Stage_2_S2_20.yml","sha256":"ac81d164309e5301083d0971e1736d128691fd9b18558ac4ade3f0246a43c2d7","size_bytes":254756},"canonical_code":{"ast_status":"PASS","code_sha256":"eeb353b837cf5c2ecfb07fc7375eca03ac4e5c3df9254266d5690cbf14df7138","code_size_bytes":200269,"compile_status":"PASS","encoding":"UTF-8","endpoint_literals":["http://mcp-localdocs:8012/mcp","https://weaviate.eroomai.com/mcp"],"expected_parent_stage2_release_sha256":"579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81","external_python_source_ref_count":0,"extraction_transform":"NONE","forbidden_dynamic_call_count":0,"forbidden_import_count":0,"imports":["__future__","base64","binascii","concurrent","contextlib","datetime","decimal","hashlib","httpx","io","itertools","json","pathlib","re","sys","typing","unicodedata"],"plaintext_secret_count":0,"yaml_pointer":"/Agent/Stages/0/tasks/0/parameters/code"},"deployment_projection":{"path":"Default_Agent/Stage_2_Clean/agent_scripts/Stage_2_S2_20.yml","sha256":"ac81d164309e5301083d0971e1736d128691fd9b18558ac4ade3f0246a43c2d7","size_bytes":254756},"full_code_mirrors":["Default_Agent/Stage_2_Clean/runtime/s2_20_reduce.py","Default_Agent/Stage_2_Clean/runtime/s2_20_reduce.txt"],"parity_status":"PASS","schema_version":"stage2_s2_20_inline_code_receipt.v1","task_contract":{"agent":{"name":"Stage_2_S2_20","version":"1.0.0"},"authoring_rewritten":false,"canonical_task_semantics_sha256":"460bd442ece9b2e39a45d1df5fd333db39d5267da49bc1a63192a580b90e7c0f","code_mirrors_byte_identical":true,"exactly_one_code_executor_run_code":true,"exactly_one_stage":true,"exactly_one_task":true,"expected_parent_stage2_release_sha256":"579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81","internal_dag":"(C20||C21)->C25->C26->(C22||(C27->C28->C29))->C30->C35","mcp_servers":{"code-executor":{"type":"streamable-http","url":"https://code-executor.mcp.eroomai.com/mcp"},"localdocs":{"type":"streamable-http","url":"http://mcp-localdocs:8012/mcp"}},"projection_byte_identical_to_authoring":true,"stage":{"name":"S2_20","nexts":[],"prevs":[],"skip_confirm":true},"task":{"code_sha256":"eeb353b837cf5c2ecfb07fc7375eca03ac4e5c3df9254266d5690cbf14df7138","mcp":"code-executor","parameters":{"language":"python","network":"agent-network","requirements":"httpx==0.28.1","timeout":300},"task_name":"Task_S2_20_deterministic_relief_plan","tool_name":"run_code"},"task_procedure":{"IN":{"nexts":["Task_S2_20_deterministic_relief_plan"],"wait_until":[]},"OUT":{"nexts":[],"wait_until":["Task_S2_20_deterministic_relief_plan"]},"Task_S2_20_deterministic_relief_plan":{"nexts":["OUT"],"wait_until":["IN"]}}},"workflow_id":"S2_20"} {"authoring":{"path":"Stage_2_S2_20.yml","sha256":"3c4e6a7404f5b6a6b2403824c3cd9e71db566d4f2865bd4de3e6fd9d07824bd6","size_bytes":254756},"canonical_code":{"ast_status":"PASS","code_sha256":"6f1f503378242cf64cf8f0838af2164ab1103bc7031c8a6873f4ee89be66f7fd","code_size_bytes":200269,"compile_status":"PASS","encoding":"UTF-8","endpoint_literals":["http://mcp-localdocs:8012/mcp","https://weaviate.eroomai.com/mcp"],"expected_parent_stage2_release_sha256":"9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53","external_python_source_ref_count":0,"extraction_transform":"NONE","forbidden_dynamic_call_count":0,"forbidden_import_count":0,"imports":["__future__","base64","binascii","concurrent","contextlib","datetime","decimal","hashlib","httpx","io","itertools","json","pathlib","re","sys","typing","unicodedata"],"plaintext_secret_count":0,"yaml_pointer":"/Agent/Stages/0/tasks/0/parameters/code"},"deployment_projection":{"path":"Default_Agent/Stage_2_Clean/agent_scripts/Stage_2_S2_20.yml","sha256":"3c4e6a7404f5b6a6b2403824c3cd9e71db566d4f2865bd4de3e6fd9d07824bd6","size_bytes":254756},"full_code_mirrors":["Default_Agent/Stage_2_Clean/runtime/s2_20_reduce.py","Default_Agent/Stage_2_Clean/runtime/s2_20_reduce.txt"],"parity_status":"PASS","schema_version":"stage2_s2_20_inline_code_receipt.v1","task_contract":{"agent":{"name":"Stage_2_S2_20","version":"1.0.0"},"authoring_rewritten":false,"canonical_task_semantics_sha256":"750bf364c9b73460349005590cbf65ae4c0235b5af0770937ccbbf669d159dd0","code_mirrors_byte_identical":true,"exactly_one_code_executor_run_code":true,"exactly_one_stage":true,"exactly_one_task":true,"expected_parent_stage2_release_sha256":"9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53","internal_dag":"(C20||C21)->C25->C26->(C22||(C27->C28->C29))->C30->C35","mcp_servers":{"code-executor":{"type":"streamable-http","url":"https://code-executor.mcp.eroomai.com/mcp"},"localdocs":{"type":"streamable-http","url":"http://mcp-localdocs:8012/mcp"}},"projection_byte_identical_to_authoring":true,"stage":{"name":"S2_20","nexts":[],"prevs":[],"skip_confirm":true},"task":{"code_sha256":"6f1f503378242cf64cf8f0838af2164ab1103bc7031c8a6873f4ee89be66f7fd","mcp":"code-executor","parameters":{"language":"python","network":"agent-network","requirements":"httpx==0.28.1","timeout":300},"task_name":"Task_S2_20_deterministic_relief_plan","tool_name":"run_code"},"task_procedure":{"IN":{"nexts":["Task_S2_20_deterministic_relief_plan"],"wait_until":[]},"OUT":{"nexts":[],"wait_until":["Task_S2_20_deterministic_relief_plan"]},"Task_S2_20_deterministic_relief_plan":{"nexts":["OUT"],"wait_until":["IN"]}}},"workflow_id":"S2_20"}
@@ -1 +1 @@
{"authoring_sha256":"6da21b319d10268e5f1959d085173d22017e4910c7222fd5e6daf72628629773","binding_sha256":"1d99d933aca1803a681b8fc70eab368fa3b11b5a4f7d384a6be6cd9cb5883512","byte_parity":"PASS","child_release_sha256":"90b96d0e00d0491f7dfafe3b9f2cec3a1055d64fe4979780fe00af849257e884","deployment_sha256":"6da21b319d10268e5f1959d085173d22017e4910c7222fd5e6daf72628629773","deterministic_helper_task_count":1,"llm_task_template_count":1,"receipt_digest":"5ee7d882c739ffc437e808b0d22580134ad4b3af0047fbe1e55eb46502f09ed0","receipt_status":"OFFLINE_AGENT_PROJECTION_VERIFIED","reduce_task_count":0,"schema_version":"stage2_s2_30_agent_receipt.v1","task_template_count":2} {"authoring_sha256":"d0804526941207395c9b64a314b124ff8e919c6852e828d829dc45a9feb3ccdd","binding_sha256":"7cf19e7dd8d3ad58251e20edc56e11fde3bffb3936997538eb09301da06189dc","byte_parity":"PASS","child_release_sha256":"e6dd6abe44b39de462ea01f5e78aa39c70bbf47e0b75e08d224615a297d2135f","deployment_sha256":"d0804526941207395c9b64a314b124ff8e919c6852e828d829dc45a9feb3ccdd","deterministic_helper_task_count":1,"llm_task_template_count":1,"receipt_digest":"fac154c1a47a050c1d8cac98a6df7abd92b0410e024c9cb26664dcef4006f13d","receipt_status":"OFFLINE_AGENT_PROJECTION_VERIFIED","reduce_task_count":0,"schema_version":"stage2_s2_30_agent_receipt.v1","task_template_count":2}
@@ -1 +1 @@
{"ast_policy_status":"PASS","authoring_agent_sha256":"6da21b319d10268e5f1959d085173d22017e4910c7222fd5e6daf72628629773","compile_status":"PASS","inline_code_sha256":"7814e64bfdbf5992d8009556b5a81268d99a0300d0b8f419c8c6384d90a906c9","inline_code_size_bytes":67777,"planner_mirror_paths":["runtime/s2_30_dispatch_planner.py","runtime/s2_30_dispatch_planner.txt"],"receipt_digest":"e1d46ddf49865d69715ba2f0c0a20290e9b755b5753709018c65c95c7486547c","receipt_status":"OFFLINE_PROJECTION_VERIFIED","runtime_admission_effect":"NONE","runtime_external_python_import_count":0,"schema_version":"stage2_s2_30_inline_code_receipt.v1"} {"ast_policy_status":"PASS","authoring_agent_sha256":"d0804526941207395c9b64a314b124ff8e919c6852e828d829dc45a9feb3ccdd","compile_status":"PASS","inline_code_sha256":"1f7f3b842afbd3f1034f094d6341288effc9804a03920ada4bf8cfd512464e4c","inline_code_size_bytes":67777,"planner_mirror_paths":["runtime/s2_30_dispatch_planner.py","runtime/s2_30_dispatch_planner.txt"],"receipt_digest":"fe592796579be30899bde4006a0a3ba1d51b97b51a5b7049a3f67539158c71c9","receipt_status":"OFFLINE_PROJECTION_VERIFIED","runtime_admission_effect":"NONE","runtime_external_python_import_count":0,"schema_version":"stage2_s2_30_inline_code_receipt.v1"}
@@ -1 +1 @@
{"authoring_agent":{"path":"Stage_2_S2_30.yml","sha256":"6da21b319d10268e5f1959d085173d22017e4910c7222fd5e6daf72628629773","size_bytes":117060},"dynamic_item_tokens":["{{item.p32_common_authority_json}}","{{item.p31_rule_and_pack_json}}","{{item.s30_group_slice_json}}","{{item.compile_mode}}","{{item.s30_group_slice_sha256}}"],"inline_scalars":[{"parity":"PASS","raw_scalar_sha256":"a90ac95f0b24ea938a16699f34ef7f17eb870edcbd8964ba4f6709e36e1bbcc0","source":{"path":"prompts/P00_system_and_safety_contract.md","sha256":"c82cfc0b61adb1af7759fd321f78bcf7bebf7e5d2fc3a9c01533a80736c6d80e","size_bytes":7304},"wrapper":"stage_2_common_cache_prefix","yaml_pointer":"/Agent/Stages/0/tasks/1/prompts/0/content"},{"parity":"PASS","raw_scalar_sha256":"577efa2c3334298ec60188b9f0066f834e072dc99f785b3c6ab4d05a47fac18a","source":{"path":"prompts/P30_joint_drafting_contract.md","sha256":"5d790fccdacd1b7ce27e25cd52e4c301dbce24ba276def18bca608b5b16362aa","size_bytes":13681},"wrapper":"s2_30_joint_drafting_static_prompt","yaml_pointer":"/Agent/Stages/0/tasks/1/prompts/1/content"}],"message_order":["INLINE_COMMON_SYSTEM","INLINE_S2_30_STATIC_SYSTEM","P32_COMMON_AUTHORITY_SYSTEM_DATA","P31_RULE_AND_PACK_SYSTEM_DATA","S30_GROUP_CASE_USER_DATA"],"receipt_digest":"9dae633a55e091e5a8aa9173c2471b7ac24aaf3ddffda6cbd9ebbe6365d982d3","receipt_status":"OFFLINE_PROJECTION_VERIFIED","runtime_admission_effect":"NONE","schema_version":"stage2_s2_30_inline_prompt_projection_receipt.v1"} {"authoring_agent":{"path":"Stage_2_S2_30.yml","sha256":"d0804526941207395c9b64a314b124ff8e919c6852e828d829dc45a9feb3ccdd","size_bytes":117060},"dynamic_item_tokens":["{{item.p32_common_authority_json}}","{{item.p31_rule_and_pack_json}}","{{item.s30_group_slice_json}}","{{item.compile_mode}}","{{item.s30_group_slice_sha256}}"],"inline_scalars":[{"parity":"PASS","raw_scalar_sha256":"a90ac95f0b24ea938a16699f34ef7f17eb870edcbd8964ba4f6709e36e1bbcc0","source":{"path":"prompts/P00_system_and_safety_contract.md","sha256":"c82cfc0b61adb1af7759fd321f78bcf7bebf7e5d2fc3a9c01533a80736c6d80e","size_bytes":7304},"wrapper":"stage_2_common_cache_prefix","yaml_pointer":"/Agent/Stages/0/tasks/1/prompts/0/content"},{"parity":"PASS","raw_scalar_sha256":"577efa2c3334298ec60188b9f0066f834e072dc99f785b3c6ab4d05a47fac18a","source":{"path":"prompts/P30_joint_drafting_contract.md","sha256":"5d790fccdacd1b7ce27e25cd52e4c301dbce24ba276def18bca608b5b16362aa","size_bytes":13681},"wrapper":"s2_30_joint_drafting_static_prompt","yaml_pointer":"/Agent/Stages/0/tasks/1/prompts/1/content"}],"message_order":["INLINE_COMMON_SYSTEM","INLINE_S2_30_STATIC_SYSTEM","P32_COMMON_AUTHORITY_SYSTEM_DATA","P31_RULE_AND_PACK_SYSTEM_DATA","S30_GROUP_CASE_USER_DATA"],"receipt_digest":"13b89691392616f6f70b2cb1a92a24ee4d891480b56c8c1b41b5bdabe88bbad1","receipt_status":"OFFLINE_PROJECTION_VERIFIED","runtime_admission_effect":"NONE","schema_version":"stage2_s2_30_inline_prompt_projection_receipt.v1"}
@@ -1 +1 @@
{"binding_sha256":"1d99d933aca1803a681b8fc70eab368fa3b11b5a4f7d384a6be6cd9cb5883512","child_release_sha256":"90b96d0e00d0491f7dfafe3b9f2cec3a1055d64fe4979780fe00af849257e884","evidence":[],"live_execution_attested":false,"parent_release_sha256":"579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81","receipt_digest":"6b97a3fd5bb2e3eb42a6e96296884e745f7c8feb2623a075c53b4b470da8ab41","runtime_admission_effect":"BLOCK_PRODUCTION","schema_version":"stage2_s2_30_legal_review_receipt.v1","status":"PENDING_KOREAN_LAWYER_REVIEW"} {"binding_sha256":"7cf19e7dd8d3ad58251e20edc56e11fde3bffb3936997538eb09301da06189dc","child_release_sha256":"e6dd6abe44b39de462ea01f5e78aa39c70bbf47e0b75e08d224615a297d2135f","evidence":[],"live_execution_attested":false,"parent_release_sha256":"9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53","receipt_digest":"6fc276d58d8613c0f7a2f4cb31dce0fc12c04e0239168a969f77e8a3b85437cb","runtime_admission_effect":"BLOCK_PRODUCTION","schema_version":"stage2_s2_30_legal_review_receipt.v1","status":"PENDING_KOREAN_LAWYER_REVIEW"}
@@ -1 +1 @@
{"binding_sha256":"1d99d933aca1803a681b8fc70eab368fa3b11b5a4f7d384a6be6cd9cb5883512","child_release_sha256":"90b96d0e00d0491f7dfafe3b9f2cec3a1055d64fe4979780fe00af849257e884","evidence":[],"live_execution_attested":false,"parent_release_sha256":"579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81","receipt_digest":"0eaf5733b7605d8d2f79a99eea1cdd6d8447c0d679df41be00d04149ab699b3e","runtime_admission_effect":"BLOCK_PRODUCTION","schema_version":"stage2_s2_30_model_benchmark_receipt.v1","status":"PENDING_MODEL_BENCHMARK"} {"binding_sha256":"7cf19e7dd8d3ad58251e20edc56e11fde3bffb3936997538eb09301da06189dc","child_release_sha256":"e6dd6abe44b39de462ea01f5e78aa39c70bbf47e0b75e08d224615a297d2135f","evidence":[],"live_execution_attested":false,"parent_release_sha256":"9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53","receipt_digest":"d8d231359c086ae13fec794d233ebf0ba5854c207da569923ed72d8c6ca90abc","runtime_admission_effect":"BLOCK_PRODUCTION","schema_version":"stage2_s2_30_model_benchmark_receipt.v1","status":"PENDING_MODEL_BENCHMARK"}
@@ -1 +1 @@
["manifest/s2_30_parent_member_paths.json","offline_build/build_s2_30_agent_projection.py","offline_build/build_s2_30_agent_projection.txt","offline_build/validate_s2_30_contract.py","offline_build/validate_s2_30_contract.txt","prompts/P30_joint_drafting_contract.md","schemas/draft_atoms.schema.json","tests/fixtures/s2_30/adverse_fact_worknote_policy.json","tests/fixtures/s2_30/cache_prefix_drift.json","tests/fixtures/s2_30/context_reference_envelope.json","tests/fixtures/s2_30/counter_performance_and_declaration.json","tests/fixtures/s2_30/follower_batch_dispatch.json","tests/fixtures/s2_30/invalid_forbidden_output.json","tests/fixtures/s2_30/invalid_preassembled_prompt_item.json","tests/fixtures/s2_30/invalid_reference_output.json","tests/fixtures/s2_30/owner_singleton_dispatch.json","tests/fixtures/s2_30/partial_write_publish_barrier.json","tests/fixtures/s2_30/regression_manifest.json","tests/fixtures/s2_30/rule_requirement_admission_gap.json","tests/fixtures/s2_30/technical_failure.json","tests/fixtures/s2_30/valid_joint_draft_output.json","tests/s2_30/test_agent_contract.py","tests/s2_30/test_agent_contract.txt","tests/s2_30/test_dispatch_materialization.py","tests/s2_30/test_dispatch_materialization.txt","tests/s2_30/test_draft_atom_contract.py","tests/s2_30/test_draft_atom_contract.txt","tests/s2_30/test_prompt_cache_and_boundaries.py","tests/s2_30/test_prompt_cache_and_boundaries.txt","tests/s2_30/test_release_adapter_retry.py","tests/s2_30/test_release_adapter_retry.txt","workflows/S2_30_claim_group_draft_map.yml"] ["manifest/s2_30_parent_member_paths.json","offline_build/build_s2_30_agent_projection.py","offline_build/build_s2_30_agent_projection.txt","offline_build/validate_s2_30_contract.py","offline_build/validate_s2_30_contract.txt","prompts/P30_joint_drafting_contract.md","schemas/draft_atoms.schema.json","tests/fixtures/s2_30/adverse_fact_worknote_policy.json","tests/fixtures/s2_30/cache_prefix_drift.json","tests/fixtures/s2_30/context_reference_envelope.json","tests/fixtures/s2_30/counter_performance_and_declaration.json","tests/fixtures/s2_30/follower_batch_dispatch.json","tests/fixtures/s2_30/invalid_forbidden_output.json","tests/fixtures/s2_30/invalid_preassembled_prompt_item.json","tests/fixtures/s2_30/invalid_reference_output.json","tests/fixtures/s2_30/owner_singleton_dispatch.json","tests/fixtures/s2_30/partial_write_publish_barrier.json","tests/fixtures/s2_30/persisted_handoff_chain.json","tests/fixtures/s2_30/regression_manifest.json","tests/fixtures/s2_30/rule_requirement_admission_gap.json","tests/fixtures/s2_30/technical_failure.json","tests/fixtures/s2_30/valid_joint_draft_output.json","tests/s2_30/test_agent_contract.py","tests/s2_30/test_agent_contract.txt","tests/s2_30/test_dispatch_materialization.py","tests/s2_30/test_dispatch_materialization.txt","tests/s2_30/test_draft_atom_contract.py","tests/s2_30/test_draft_atom_contract.txt","tests/s2_30/test_prompt_cache_and_boundaries.py","tests/s2_30/test_prompt_cache_and_boundaries.txt","tests/s2_30/test_release_adapter_retry.py","tests/s2_30/test_release_adapter_retry.txt","workflows/S2_30_claim_group_draft_map.yml"]
@@ -1 +1 @@
{"binding_sha256":"1d99d933aca1803a681b8fc70eab368fa3b11b5a4f7d384a6be6cd9cb5883512","capabilities":[{"capability_id":"HOST_ATOMIC_GROUP_DISPATCH_CAS_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"AGENTBACKEND_TASK_PROCEDURE_WILDCARD_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"AGENTBACKEND_WILDCARD_RESULT_ADAPTER_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_CONTEXT_MATERIALIZER_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_CACHE_OWNER_SEQUENCE_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_STRICT_SCHEMA_REF_PROVENANCE_VALIDATOR_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_DETERMINISTIC_ATOM_ID_TWO_PASS_PERSIST_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_GROUP_RETRY_CONTROLLER_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_GROUP_BARRIER_COORDINATOR_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_CANARY_AUTHORIZATION_SIGNATURE_VERIFY_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"}],"child_release_sha256":"90b96d0e00d0491f7dfafe3b9f2cec3a1055d64fe4979780fe00af849257e884","evidence":[],"live_execution_attested":false,"overall_status":"PENDING_EXTERNAL_PLATFORM_BINDING","parent_release_sha256":"579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81","receipt_digest":"19ce93ff7d086826739ef57bcb766135b00f53a070952b449528bcfe0d7310ae","runtime_admission_effect":"BLOCK_PRODUCTION","schema_version":"stage2_s2_30_platform_adapter_receipt.v1"} {"binding_sha256":"7cf19e7dd8d3ad58251e20edc56e11fde3bffb3936997538eb09301da06189dc","capabilities":[{"capability_id":"HOST_ATOMIC_GROUP_DISPATCH_CAS_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"AGENTBACKEND_TASK_PROCEDURE_WILDCARD_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"AGENTBACKEND_WILDCARD_RESULT_ADAPTER_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_CONTEXT_MATERIALIZER_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_CACHE_OWNER_SEQUENCE_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_STRICT_SCHEMA_REF_PROVENANCE_VALIDATOR_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_DETERMINISTIC_ATOM_ID_TWO_PASS_PERSIST_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_GROUP_RETRY_CONTROLLER_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_GROUP_BARRIER_COORDINATOR_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"},{"capability_id":"S2_30_CANARY_AUTHORIZATION_SIGNATURE_VERIFY_V1","status":"PENDING_EXTERNAL_PLATFORM_BINDING"}],"child_release_sha256":"e6dd6abe44b39de462ea01f5e78aa39c70bbf47e0b75e08d224615a297d2135f","evidence":[],"live_execution_attested":false,"overall_status":"PENDING_EXTERNAL_PLATFORM_BINDING","parent_release_sha256":"9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53","receipt_digest":"31b81bdbef3bea6712c6ca2921af4e6b55e264f69b2ed341e1d83c770d3df1c5","runtime_admission_effect":"BLOCK_PRODUCTION","schema_version":"stage2_s2_30_platform_adapter_receipt.v1"}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"authoring":{"path":"Stage_2_S2_40.yml","sha256":"5cbe2ac9aa73d95a5fa4e6cf71d7d8f0ad83aa05536f573c13e42505ef5d46f7","size_bytes":249967,"unique_key_parse":"PASS"},"authoring_rewritten":false,"build_kind":"OFFLINE_AUTHORING_PROJECTION","canonical_code":{"ast_status":"PASS","code_sha256":"e521e1a65294a769cd6bf20edb159f8720c105b60cb769885aa416c8c763dcef","code_size_bytes":200946,"compile_status":"PASS","encoding":"UTF-8","expected_parent_stage2_release_sha256":"9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53","external_python_source_ref_count":0,"external_url_count":0,"extraction_transform":"NONE","forbidden_dynamic_call_count":0,"forbidden_import_count":0,"imports":["__future__","base64","binascii","contextlib","datetime","hashlib","httpx","io","itertools","json","pathlib","re","sys","typing","unicodedata"],"placeholder_count":0,"plaintext_secret_count":0,"yaml_pointer":"/Agent/Stages/0/tasks/0/parameters/code"},"deployment_projection":{"byte_identical_to_authoring":true,"canonical_task_semantics_sha256":"a8d6450b5a40308b3c2af5227fd3bc0c4f575dd8ea17b10b5bb7d6687ebc9d9e","path":"Default_Agent/Stage_2_Clean/agent_scripts/Stage_2_S2_40.yml","sha256":"5cbe2ac9aa73d95a5fa4e6cf71d7d8f0ad83aa05536f573c13e42505ef5d46f7","size_bytes":249967},"expected_parent_stage2_release_sha256":"9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53","full_code_mirrors":[{"byte_identical_to_canonical_code":true,"path":"Default_Agent/Stage_2_Clean/runtime/s2_40_commit.py","sha256":"e521e1a65294a769cd6bf20edb159f8720c105b60cb769885aa416c8c763dcef","size_bytes":200946},{"byte_identical_to_canonical_code":true,"path":"Default_Agent/Stage_2_Clean/runtime/s2_40_commit.txt","sha256":"e521e1a65294a769cd6bf20edb159f8720c105b60cb769885aa416c8c763dcef","size_bytes":200946}],"parity_status":"PASS","schema_version":"stage2_s2_40_inline_code_receipt.v1","source_of_truth":"Stage_2_S2_40.yml","task_contract":{"agent":{"name":"Stage_2_S2_40","version":"1.0.0"},"authoring_rewritten":false,"canonical_task_semantics_sha256":"a8d6450b5a40308b3c2af5227fd3bc0c4f575dd8ea17b10b5bb7d6687ebc9d9e","code_mirrors_byte_identical":true,"exactly_one_code_executor_run_code":true,"exactly_one_stage":true,"exactly_one_task":true,"mcp_servers":{"code-executor":{"type":"streamable-http","url":"https://code-executor.mcp.eroomai.com/mcp"},"localdocs":{"type":"streamable-http","url":"http://mcp-localdocs:8012/mcp"}},"projection_byte_identical_to_authoring":true,"stage":{"name":"S2_40","nexts":[],"prevs":[]},"task":{"code_sha256":"e521e1a65294a769cd6bf20edb159f8720c105b60cb769885aa416c8c763dcef","mcp":"code-executor","parameters":{"language":"python","network":"agent-network","requirements":"httpx==0.28.1","timeout":300},"task_name":"Task_S2_40_deterministic_finalizer","tool_name":"run_code"},"task_procedure":{"IN":{"nexts":["Task_S2_40_deterministic_finalizer"],"wait_until":[]},"OUT":{"nexts":[],"wait_until":["Task_S2_40_deterministic_finalizer"]},"Task_S2_40_deterministic_finalizer":{"nexts":["OUT"],"wait_until":["IN"]}}},"workflow_id":"S2_40"}
@@ -0,0 +1,45 @@
[
"manifest/s2_40_parent_member_paths.json",
"offline_build/build_s2_40_inline_projection.py",
"offline_build/build_s2_40_inline_projection.txt",
"runtime/c45_document_assembler.py",
"runtime/c45_document_assembler.txt",
"runtime/rendering/closed_renderer.py",
"runtime/rendering/closed_renderer.txt",
"runtime/validation/invariant_runner.py",
"runtime/validation/invariant_runner.txt",
"schemas/migration_regression.schema.json",
"schemas/package.schema.json",
"schemas/review_status.schema.json",
"tests/fixtures/s2_40/candidate_digest_noncycle.json",
"tests/fixtures/s2_40/cost_provisional_execution_numbering.json",
"tests/fixtures/s2_40/exhibit_object_party_title_completeness.json",
"tests/fixtures/s2_40/part_set_missing_duplicate_or_cross_group.json",
"tests/fixtures/s2_40/partial_write_readback_barrier.json",
"tests/fixtures/s2_40/regression_manifest.json",
"tests/fixtures/s2_40/relief_cause_crossmatch_mutations.json",
"tests/fixtures/s2_40/renderer_ast_slot_branch_mutations.json",
"tests/fixtures/s2_40/review_policy_state_aggregation.json",
"tests/fixtures/s2_40/review_receipt_approve_resume.json",
"tests/fixtures/s2_40/review_receipt_content_change_supersede.json",
"tests/fixtures/s2_40/review_receipt_missing_or_invalid.json",
"tests/fixtures/s2_40/same_binding_idempotence_and_commit_conflict.json",
"tests/fixtures/s2_40/v01_v18_invariant_matrix.json",
"tests/fixtures/s2_40/valid_full_candidate_and_commit.json",
"tests/fixtures/s2_40/valid_status_only_diagnostic.json",
"tests/s2_40/test_agent_and_inline_parity.py",
"tests/s2_40/test_agent_and_inline_parity.txt",
"tests/s2_40/test_c40_reduce_and_conservation.py",
"tests/s2_40/test_c40_reduce_and_conservation.txt",
"tests/s2_40/test_c45_closed_render.py",
"tests/s2_40/test_c45_closed_render.txt",
"tests/s2_40/test_commit_barrier_and_idempotence.py",
"tests/s2_40/test_commit_barrier_and_idempotence.txt",
"tests/s2_40/test_release_closure.py",
"tests/s2_40/test_release_closure.txt",
"tests/s2_40/test_review_state_machine.py",
"tests/s2_40/test_review_state_machine.txt",
"tests/s2_40/test_v01_v18.py",
"tests/s2_40/test_v01_v18.txt",
"workflows/S2_40_final_review_render_and_commit.yml"
]
@@ -1 +1 @@
{"admission_status":"PENDING","backend_capability_receipt_sha256":"PENDING_SEQUENTIAL_BIND","embedded_task_admissions":[{"admission_scope":"CODE_EXECUTOR_HELPER_ONLY","binding_id":"S2-BINDING-S2_30-DISPATCH-PLANNER-V1","execution_unit_id":"S2_30::Task_S2_30_dispatch_planner","host_stage_id":"S2_30","inline_code_receipt_ref":{"asset_id":"RECEIPT-S2_30-INLINE-CODE","binding_status":"BOUND","path":"manifest/s2_30_inline_code_receipt.json","schema_id":"stage2_s2_30_inline_code_receipt.v1","sha256":"78fb197d50ec706be35cf1766bb9e9fee1767a8e61109603313821dd6040f552"},"task_name":"Task_S2_30_dispatch_planner"}],"executor_binding_sha256":"bfd84ddedb488e7391341041a739437d88372e3c9ed740e5dfb31ae3a138a936","parent_release_sha256":"579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81","present_deterministic_stage_ids":["S2_00","S2_20"],"schema_version":"stage2_deterministic_admission_receipt.v1","signature":"PENDING_EXTERNAL_SIGNATURE","signature_verification_status":"PENDING_EXTERNAL_SIGNATURE","signed_payload_sha256":"PENDING_SEQUENTIAL_BIND","stage_receipts":[{"asset_id":"RECEIPT-S2_00-INLINE-CODE","binding_status":"BOUND","path":"manifest/s2_00_inline_code_receipt.json","schema_id":"stage2_s2_00_inline_code_receipt.v2","sha256":"ced01ef57a2e5341b1f7ddbf810ff3c6fb85fbb3cf7cf80836328a8a971835b4"},{"asset_id":"RECEIPT-S2_20-INLINE-CODE","binding_status":"BOUND","path":"manifest/s2_20_inline_code_receipt.json","schema_id":"stage2_s2_20_inline_code_receipt.v1","sha256":"60000d2412a757e9b2ab2525eedb08ebda20ec02a49f5b1b0c4e89e6a0aeca2b"}]} {"admission_status":"PENDING","backend_capability_receipt_sha256":"PENDING_SEQUENTIAL_BIND","embedded_task_admissions":[{"admission_scope":"CODE_EXECUTOR_HELPER_ONLY","binding_id":"S2-BINDING-S2_30-DISPATCH-PLANNER-V1","execution_unit_id":"S2_30::Task_S2_30_dispatch_planner","host_stage_id":"S2_30","inline_code_receipt_ref":{"asset_id":"RECEIPT-S2_30-INLINE-CODE","binding_status":"BOUND","path":"manifest/s2_30_inline_code_receipt.json","schema_id":"stage2_s2_30_inline_code_receipt.v1","sha256":"8d1618771cf1f72aa3c6a5a4544fe6b6e949ccc7ecfef56f166561971beee896"},"task_name":"Task_S2_30_dispatch_planner"}],"executor_binding_sha256":"a1062e9db242747c75a4362fb95eeba6c65f78ac647d4571ed774d2ee3af40f7","parent_release_sha256":"9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53","present_deterministic_stage_ids":["S2_00","S2_20","S2_40"],"schema_version":"stage2_deterministic_admission_receipt.v1","signature":"PENDING_EXTERNAL_SIGNATURE","signature_verification_status":"PENDING_EXTERNAL_SIGNATURE","signed_payload_sha256":"PENDING_SEQUENTIAL_BIND","stage_receipts":[{"asset_id":"RECEIPT-S2_00-INLINE-CODE","binding_status":"BOUND","path":"manifest/s2_00_inline_code_receipt.json","schema_id":"stage2_s2_00_inline_code_receipt.v2","sha256":"36af21949e5ef53a3d39df8ea9491c64da43abcc4f5e42e13db9bb391da843b8"},{"asset_id":"RECEIPT-S2_20-INLINE-CODE","binding_status":"BOUND","path":"manifest/s2_20_inline_code_receipt.json","schema_id":"stage2_s2_20_inline_code_receipt.v1","sha256":"65e29f10f065cdd77281aa47acaf341edb38b0595aab0aa9f04bbee3a4718608"},{"asset_id":"RECEIPT-S2_40-INLINE-CODE","binding_status":"BOUND","path":"manifest/s2_40_inline_code_receipt.json","schema_id":"stage2_s2_40_inline_code_receipt.v1","sha256":"9bd0cfaee8d9e78480ab80a2fa541414c7ad0565439fa0f4661701fcdfde6526"}]}
File diff suppressed because one or more lines are too long
@@ -15,7 +15,8 @@ import hashlib
import json import json
import os import os
from pathlib import Path, PurePosixPath from pathlib import Path, PurePosixPath
from typing import Any, Iterable import re
from typing import Any, Iterable, Mapping
MODULE_MANIFEST_SCHEMA = "stage2_module_manifest.v1" MODULE_MANIFEST_SCHEMA = "stage2_module_manifest.v1"
@@ -53,9 +54,145 @@ FORBIDDEN_PARENT_MEMBERS = frozenset(
"manifest/s2_30_model_benchmark_receipt.json", "manifest/s2_30_model_benchmark_receipt.json",
"manifest/s2_30_legal_review_receipt.json", "manifest/s2_30_legal_review_receipt.json",
"manifest/s2_30_release.json", "manifest/s2_30_release.json",
"agent_scripts/Stage_2_S2_40.yml",
"runtime/s2_40_commit.py",
"runtime/s2_40_commit.txt",
"manifest/s2_40_inline_code_receipt.json",
} }
) )
STAGE_GENERIC_METADATA = {
"S2_20": {
"asset_version": "s2_20.1",
"module_id_prefix": "S2_20-ASSET",
"owner": "Stage_2_S2_20_owner",
"schema_version": "stage2_s2_20_generic_asset.v1",
"scope_predicate": "workflow_id == S2_20",
},
"S2_30": {
"asset_version": "s2_30.1",
"module_id_prefix": "S2_30-ASSET",
"owner": "Stage_2_S2_30_owner",
"schema_version": "stage2_s2_30_generic_asset.v1",
"scope_predicate": "workflow_id == S2_30",
},
"S2_40": {
"asset_version": "s2_40.1",
"module_id_prefix": "S2_40-ASSET",
"owner": "Stage_2_S2_40_owner",
"schema_version": "stage2_s2_40_generic_asset.v1",
"scope_predicate": "workflow_id == S2_40",
},
}
S2_40_WORKFLOW_PATH = "workflows/S2_40_final_review_render_and_commit.yml"
S2_40_TRANSITIONED_STUB_VALUES = frozenset(
{
"WF-S2_40-STATUS-ONLY",
"s2_40.status_only.1",
"DRAFT_HANDOFF_STUB_HASH_BOUND",
"entrypoint_id == S2_40_STATUS_ONLY",
}
)
S2_40_WORKFLOW_METADATA: dict[str, Any] = {
"asset_version": "s2_40.finalizer.1",
"authority_ids": [],
"consumed_schema_ids": [
"https://schemas.liti-agent.local/stage2/s2_00/context.schema.v2.json",
"https://schemas.liti-agent.local/stage2/s2_00/ingress.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_10/s2_10.schema.v2.json",
"https://schemas.liti-agent.local/stage2/s2_20/binding_retrieval.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_20/calculation.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_20/relief_plan.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_30/draft_atoms.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_40/package.schema.v1.json",
"https://schemas.liti-agent.local/stage2/shared/deployment.schema.v3.json",
"https://schemas.liti-agent.local/stage2/shared/review_status.schema.v1.json",
],
"dependency_module_ids": [
"SCHEMA-CONTEXT",
"SCHEMA-DEPLOYMENT",
"SCHEMA-INGRESS",
"SCHEMA-REVIEW-STATUS",
"SCHEMA-S2_10",
"S2_20-ASSET-809C3C709B4F2295",
"S2_20-ASSET-AA40CF5140DE8790",
"S2_20-ASSET-C9FC917D8CBF920E",
"S2_20-ASSET-E82839694073D431",
"S2_20-ASSET-FF1F03B3FC56E579",
"S2_30-ASSET-6A9B1F5EC854740E",
"S2_30-ASSET-E1FCF8BD63300F4D",
"S2_40-ASSET-5C4CAFFAB8D2F982",
"WF-S2_00",
"WF-S2_10",
],
"entry_routes": ["TO_S2_40", "TO_S2_40_STATUS_ONLY"],
"forbidden_contract_codes": [
"LEGACY-STAGE2-V0-V3",
"S2_40-DIRECTORY-SCAN",
"S2_40-FREE-TEXT-RENDER-FALLBACK",
"S2_40-LLM-CALL",
"S2_40-RUN-STATUS-NOT-LAST",
"S2_40-UNVERIFIED-READY",
],
"implementation_status": "IMPLEMENTED_OFFLINE_CONTRACT_LIVE_ADMISSION_PENDING",
"incompatible_module_ids": [],
"inputs": [
"ingress/ingress_status.json",
"ingress/technical_diagnostic.json",
"ingress/stage1_input_manifest.json",
"ingress/intake_report.json",
"review/issue_ledger.base.json",
"map_s2_10/s2_10_publish_status.json",
"plan/plan_publish_status.json",
"plan/canonical_relief_plan.json",
"plan/claim_groups.json",
"plan/case_type_bindings.json",
"map_s2_30/s2_30_publish_status.json",
"map_s2_30/artifact_manifest.json",
"map_s2_30/{draft_parts,issue_patches,worknote_parts,usage_parts}/<claim_group_id>.json",
"review/review_receipts/<request_id>.json",
"review/lawyer_judgment_record.json",
],
"legal_admission_status": "PENDING",
"live_admission_status": "PENDING",
"module_id": "WF-S2_40",
"module_kind": "WORKFLOW",
"outputs": [
"review/issue_ledger.final.json",
"review/assumption_ledger.json",
"review/llm_usage.jsonl",
"candidates/by-content-digest/<candidate_content_digest>/",
"review/review_requests/<request_id>.json",
"final/claim_relief.md",
"final/claim_cause.md",
"final/pleading_draft.md",
"final/stage2_package.json",
"commit/commit_intent.json",
"commit/stage2_commit_result.json",
"control/run_status.json",
],
"owner": "Stage_2_S2_40_owner",
"path": S2_40_WORKFLOW_PATH,
"produced_schema_ids": [
"stage2_s2_40_candidate_manifest.v1",
"stage2_s2_40_commit_intent.v1",
"stage2_s2_40_commit_result.v1",
"stage2_s2_40_package.v1",
"stage2_s2_40_run_status.v1",
],
"schema_version": "stage2_workflow_contract.v1",
"scope_predicate": "workflow_id == S2_40 and entry_route in {TO_S2_40,TO_S2_40_STATUS_ONLY}",
"semantic_review_status": "PENDING_LEGAL_AND_LIVE_ADMISSION",
"status_only_exact_inputs": [
"ingress/ingress_status.json",
"ingress/technical_diagnostic.json",
"ingress/stage1_input_manifest.json",
"ingress/intake_report.json",
"review/issue_ledger.base.json",
],
}
class ReleaseBuildError(ValueError): class ReleaseBuildError(ValueError):
"""Raised when a release input violates the canonical closure contract.""" """Raised when a release input violates the canonical closure contract."""
@@ -151,7 +288,7 @@ def _mirror_for(root: Path, source_path: str) -> tuple[str, bytes] | None:
return mirror_path, mirror_raw return mirror_path, mirror_raw
def _generic_kind(relative: str) -> str: def _generic_kind(relative: str, owner_stage: str = "S2_20") -> str:
if relative.startswith("tests/"): if relative.startswith("tests/"):
return "TEST" return "TEST"
if relative.startswith("schemas/"): if relative.startswith("schemas/"):
@@ -168,13 +305,16 @@ def _generic_kind(relative: str) -> str:
return "MANIFEST" return "MANIFEST"
if relative.startswith("registry/"): if relative.startswith("registry/"):
return "DECLARATIVE_REGISTRY" return "DECLARATIVE_REGISTRY"
return "S2_20_ASSET" return f"{owner_stage}_ASSET"
def _generic_module_row(relative: str) -> dict[str, Any]: def _generic_module_row(relative: str, owner_stage: str = "S2_20") -> dict[str, Any]:
metadata = STAGE_GENERIC_METADATA.get(owner_stage)
if metadata is None:
raise ReleaseBuildError(f"UNSUPPORTED_PARENT_MEMBER_OWNER_STAGE:{owner_stage}")
identity = hashlib.sha256(relative.encode("utf-8")).hexdigest()[:16].upper() identity = hashlib.sha256(relative.encode("utf-8")).hexdigest()[:16].upper()
return { return {
"asset_version": "s2_20.1", "asset_version": metadata["asset_version"],
"authority_ids": [], "authority_ids": [],
"consumed_schema_ids": [], "consumed_schema_ids": [],
"dependency_module_ids": [], "dependency_module_ids": [],
@@ -182,18 +322,70 @@ def _generic_module_row(relative: str) -> dict[str, Any]:
"implementation_status": "DEV_HASH_BOUND_OFFLINE_ONLY", "implementation_status": "DEV_HASH_BOUND_OFFLINE_ONLY",
"incompatible_module_ids": [], "incompatible_module_ids": [],
"inputs": [], "inputs": [],
"module_id": f"S2_20-ASSET-{identity}", "module_id": f"{metadata['module_id_prefix']}-{identity}",
"module_kind": _generic_kind(relative), "module_kind": _generic_kind(relative, owner_stage),
"outputs": [], "outputs": [],
"owner": "Stage_2_S2_20_owner", "owner": metadata["owner"],
"path": relative, "path": relative,
"produced_schema_ids": [], "produced_schema_ids": [],
"schema_version": "stage2_s2_20_generic_asset.v1", "schema_version": metadata["schema_version"],
"scope_predicate": "workflow_id == S2_20", "scope_predicate": metadata["scope_predicate"],
"semantic_review_status": "PENDING_LEGAL_AND_LIVE_ADMISSION", "semantic_review_status": "PENDING_LEGAL_AND_LIVE_ADMISSION",
} }
def _s2_40_workflow_module_row() -> dict[str, Any]:
"""Return the authoritative full S2_40 workflow row.
The pre-S2_40 parent template carried a status-only stub row at the same
physical path. Preserving that semantic metadata while merely refreshing
its file hash would make the release closure describe a different workflow
than the bytes it seals.
"""
return copy.deepcopy(S2_40_WORKFLOW_METADATA)
def _assert_no_transitioned_s2_40_stub(rows: Iterable[Mapping[str, Any]]) -> None:
for row in rows:
if row.get("path") != S2_40_WORKFLOW_PATH:
continue
observed = {
row.get("module_id"),
row.get("asset_version"),
row.get("implementation_status"),
row.get("scope_predicate"),
}
stale = sorted(str(value) for value in observed & S2_40_TRANSITIONED_STUB_VALUES)
if stale:
raise ReleaseBuildError(f"S2_40_TRANSITIONED_STUB_METADATA_FORBIDDEN:{stale}")
drift = {
key: {"expected": expected, "observed": row.get(key)}
for key, expected in S2_40_WORKFLOW_METADATA.items()
if row.get(key) != expected
}
if drift:
raise ReleaseBuildError(
"S2_40_WORKFLOW_METADATA_MISMATCH:"
+ json.dumps(drift, ensure_ascii=False, sort_keys=True)
)
def _is_generic_module_row(row: Mapping[str, Any]) -> bool:
schema_version = row.get("schema_version")
module_id = row.get("module_id")
return (
schema_version in {
metadata["schema_version"] for metadata in STAGE_GENERIC_METADATA.values()
}
or isinstance(module_id, str)
and any(
module_id.startswith(f"{metadata['module_id_prefix']}-")
for metadata in STAGE_GENERIC_METADATA.values()
)
)
def _refresh_module_row(root: Path, row: dict[str, Any]) -> dict[str, Any]: def _refresh_module_row(root: Path, row: dict[str, Any]) -> dict[str, Any]:
refreshed = copy.deepcopy(row) refreshed = copy.deepcopy(row)
relative = _relative_path(refreshed.get("path")) relative = _relative_path(refreshed.get("path"))
@@ -234,8 +426,9 @@ def build_module_manifest(
root: Path, root: Path,
template: dict[str, Any], template: dict[str, Any],
explicit_paths: Iterable[str], explicit_paths: Iterable[str],
path_owners: Mapping[str, str] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Preserve canonical rows, refresh physical bindings and append S2_20 rows.""" """Refresh canonical rows and append stage-owned generic source rows."""
if template.get("schema_version") != MODULE_MANIFEST_SCHEMA: if template.get("schema_version") != MODULE_MANIFEST_SCHEMA:
raise ReleaseBuildError("CANONICAL_MODULE_MANIFEST_V1_REQUIRED") raise ReleaseBuildError("CANONICAL_MODULE_MANIFEST_V1_REQUIRED")
@@ -249,6 +442,14 @@ def build_module_manifest(
forbidden = sorted(set(normalized_explicit) & FORBIDDEN_PARENT_MEMBERS) forbidden = sorted(set(normalized_explicit) & FORBIDDEN_PARENT_MEMBERS)
if forbidden: if forbidden:
raise ReleaseBuildError(f"NON_CYCLIC_PARENT_VIOLATION:{forbidden}") raise ReleaseBuildError(f"NON_CYCLIC_PARENT_VIOLATION:{forbidden}")
normalized_owners: dict[str, str] = {}
for raw_path, owner_stage in (path_owners or {}).items():
relative = _relative_path(raw_path)
if relative not in normalized_explicit:
raise ReleaseBuildError(f"OWNER_PATH_NOT_IN_EXPLICIT_CLOSURE:{relative}")
if owner_stage not in STAGE_GENERIC_METADATA:
raise ReleaseBuildError(f"UNSUPPORTED_PARENT_MEMBER_OWNER_STAGE:{owner_stage}")
normalized_owners[relative] = owner_stage
result = copy.deepcopy(template) result = copy.deepcopy(template)
refreshed_rows: list[dict[str, Any]] = [] refreshed_rows: list[dict[str, Any]] = []
@@ -263,9 +464,28 @@ def build_module_manifest(
raise ReleaseBuildError(f"MODULE_ID_INVALID_OR_DUPLICATE:{module_id!r}") raise ReleaseBuildError(f"MODULE_ID_INVALID_OR_DUPLICATE:{module_id!r}")
if relative in seen_paths: if relative in seen_paths:
raise ReleaseBuildError(f"MODULE_PATH_DUPLICATE:{relative}") raise ReleaseBuildError(f"MODULE_PATH_DUPLICATE:{relative}")
seen_ids.add(module_id) owner_stage = normalized_owners.get(relative)
if relative == S2_40_WORKFLOW_PATH:
if owner_stage not in {None, "S2_40"}:
raise ReleaseBuildError(
f"S2_40_WORKFLOW_OWNER_STAGE_MISMATCH:{owner_stage}"
)
candidate = _s2_40_workflow_module_row()
else:
candidate = (
_generic_module_row(relative, owner_stage)
if owner_stage is not None and _is_generic_module_row(value)
else value
)
refreshed = _refresh_module_row(root, candidate)
refreshed_id = refreshed.get("module_id")
if not isinstance(refreshed_id, str) or not refreshed_id:
raise ReleaseBuildError(f"MODULE_ID_INVALID_OR_DUPLICATE:{refreshed_id!r}")
if refreshed_id in seen_ids:
raise ReleaseBuildError(f"MODULE_ID_INVALID_OR_DUPLICATE:{refreshed_id!r}")
seen_ids.add(refreshed_id)
seen_paths.add(relative) seen_paths.add(relative)
refreshed_rows.append(_refresh_module_row(root, value)) refreshed_rows.append(refreshed)
explicit_set = set(normalized_explicit) explicit_set = set(normalized_explicit)
for relative in sorted(normalized_explicit): for relative in sorted(normalized_explicit):
@@ -278,13 +498,19 @@ def build_module_manifest(
continue continue
if relative in seen_paths: if relative in seen_paths:
continue continue
row = _refresh_module_row(root, _generic_module_row(relative)) candidate = (
_s2_40_workflow_module_row()
if relative == S2_40_WORKFLOW_PATH
else _generic_module_row(relative, normalized_owners.get(relative, "S2_20"))
)
row = _refresh_module_row(root, candidate)
if row["module_id"] in seen_ids: if row["module_id"] in seen_ids:
raise ReleaseBuildError(f"GENERATED_MODULE_ID_COLLISION:{row['module_id']}") raise ReleaseBuildError(f"GENERATED_MODULE_ID_COLLISION:{row['module_id']}")
seen_ids.add(row["module_id"]) seen_ids.add(row["module_id"])
seen_paths.add(relative) seen_paths.add(relative)
refreshed_rows.append(row) refreshed_rows.append(row)
_assert_no_transitioned_s2_40_stub(refreshed_rows)
result["modules"] = refreshed_rows result["modules"] = refreshed_rows
mirrors = [entry for row in refreshed_rows if (entry := _documentation_mirror(row))] mirrors = [entry for row in refreshed_rows if (entry := _documentation_mirror(row))]
mirror_sources = [str(entry["source_path"]) for entry in mirrors] mirror_sources = [str(entry["source_path"]) for entry in mirrors]
@@ -312,6 +538,24 @@ def build_module_manifest(
for row in refreshed_rows for row in refreshed_rows
if row.get("schema_version") == "stage2_s2_20_generic_asset.v1" if row.get("schema_version") == "stage2_s2_20_generic_asset.v1"
), ),
"s2_30_generic_module_count": sum(
1
for row in refreshed_rows
if row.get("schema_version") == "stage2_s2_30_generic_asset.v1"
),
"s2_40_generic_module_count": sum(
1
for row in refreshed_rows
if row.get("schema_version") == "stage2_s2_40_generic_asset.v1"
),
"generic_module_counts_by_stage": {
stage: sum(
1
for row in refreshed_rows
if row.get("schema_version") == metadata["schema_version"]
)
for stage, metadata in sorted(STAGE_GENERIC_METADATA.items())
},
"executable_agent_hash_included": False, "executable_agent_hash_included": False,
"executor_binding_hash_included": False, "executor_binding_hash_included": False,
"inline_runtime_code_hash_included": False, "inline_runtime_code_hash_included": False,
@@ -431,8 +675,14 @@ def build_release_package(
path_list: list[str], path_list: list[str],
module_template: dict[str, Any], module_template: dict[str, Any],
parent_template: dict[str, Any], parent_template: dict[str, Any],
path_owners: Mapping[str, str] | None = None,
) -> tuple[dict[str, Any], dict[str, Any]]: ) -> tuple[dict[str, Any], dict[str, Any]]:
module_manifest = build_module_manifest(root, module_template, path_list) module_manifest = build_module_manifest(
root,
module_template,
path_list,
path_owners=path_owners,
)
module_raw = _canonical_bytes(module_manifest) module_raw = _canonical_bytes(module_manifest)
parent_release = build_parent_release(root, parent_template, module_raw) parent_release = build_parent_release(root, parent_template, module_raw)
return module_manifest, parent_release return module_manifest, parent_release
@@ -445,6 +695,13 @@ def _write_bytes(path: Path, raw: bytes) -> None:
os.replace(temporary, path) os.replace(temporary, path)
def _owner_stage_from_path_list(path: Path) -> str:
match = re.fullmatch(r"s2_(20|30|40)_parent_member_paths\.json", path.name)
if match is None:
raise ReleaseBuildError(f"PARENT_PATH_LIST_OWNER_UNRESOLVED:{path.as_posix()}")
return f"S2_{match.group(1)}"
def main() -> int: def main() -> int:
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Reseal canonical Stage-2 module and parent release manifests" description="Reseal canonical Stage-2 module and parent release manifests"
@@ -476,20 +733,22 @@ def main() -> int:
) )
args = parser.parse_args() args = parser.parse_args()
path_lists: list[list[str]] = [] path_lists: list[tuple[str, list[str]]] = []
for source in [args.path_list, *args.additional_path_list]: for source in [args.path_list, *args.additional_path_list]:
loaded = _load_json(source) loaded = _load_json(source)
if not isinstance(loaded, list) or not all(isinstance(row, str) for row in loaded): if not isinstance(loaded, list) or not all(isinstance(row, str) for row in loaded):
raise ReleaseBuildError(f"PATH_LIST_MUST_BE_STRING_ARRAY:{source.as_posix()}") raise ReleaseBuildError(f"PATH_LIST_MUST_BE_STRING_ARRAY:{source.as_posix()}")
path_lists.append(loaded) path_lists.append((_owner_stage_from_path_list(source), loaded))
seen_paths: set[str] = set() seen_paths: set[str] = set()
path_list: list[str] = [] path_list: list[str] = []
for rows in path_lists: path_owners: dict[str, str] = {}
for owner_stage, rows in path_lists:
overlap = sorted(seen_paths & set(rows)) overlap = sorted(seen_paths & set(rows))
if overlap: if overlap:
raise ReleaseBuildError(f"PARENT_PATH_LISTS_MUST_BE_DISJOINT:{overlap}") raise ReleaseBuildError(f"PARENT_PATH_LISTS_MUST_BE_DISJOINT:{overlap}")
seen_paths.update(rows) seen_paths.update(rows)
path_list.extend(rows) path_list.extend(rows)
path_owners.update({row: owner_stage for row in rows})
path_list.sort() path_list.sort()
module_template_path = args.module_template or args.root / "manifest/module_manifest.json" module_template_path = args.module_template or args.root / "manifest/module_manifest.json"
parent_template_path = args.parent_template or args.root / "manifest/stage2_release.json" parent_template_path = args.parent_template or args.root / "manifest/stage2_release.json"
@@ -499,6 +758,7 @@ def main() -> int:
path_list, path_list,
_load_json(module_template_path), _load_json(module_template_path),
_load_json(parent_template_path), _load_json(parent_template_path),
path_owners=path_owners,
) )
_write_bytes(args.output, _canonical_bytes(module_manifest)) _write_bytes(args.output, _canonical_bytes(module_manifest))
_write_bytes(parent_output, _canonical_bytes(parent_release)) _write_bytes(parent_output, _canonical_bytes(parent_release))
@@ -15,7 +15,8 @@ import hashlib
import json import json
import os import os
from pathlib import Path, PurePosixPath from pathlib import Path, PurePosixPath
from typing import Any, Iterable import re
from typing import Any, Iterable, Mapping
MODULE_MANIFEST_SCHEMA = "stage2_module_manifest.v1" MODULE_MANIFEST_SCHEMA = "stage2_module_manifest.v1"
@@ -53,9 +54,145 @@ FORBIDDEN_PARENT_MEMBERS = frozenset(
"manifest/s2_30_model_benchmark_receipt.json", "manifest/s2_30_model_benchmark_receipt.json",
"manifest/s2_30_legal_review_receipt.json", "manifest/s2_30_legal_review_receipt.json",
"manifest/s2_30_release.json", "manifest/s2_30_release.json",
"agent_scripts/Stage_2_S2_40.yml",
"runtime/s2_40_commit.py",
"runtime/s2_40_commit.txt",
"manifest/s2_40_inline_code_receipt.json",
} }
) )
STAGE_GENERIC_METADATA = {
"S2_20": {
"asset_version": "s2_20.1",
"module_id_prefix": "S2_20-ASSET",
"owner": "Stage_2_S2_20_owner",
"schema_version": "stage2_s2_20_generic_asset.v1",
"scope_predicate": "workflow_id == S2_20",
},
"S2_30": {
"asset_version": "s2_30.1",
"module_id_prefix": "S2_30-ASSET",
"owner": "Stage_2_S2_30_owner",
"schema_version": "stage2_s2_30_generic_asset.v1",
"scope_predicate": "workflow_id == S2_30",
},
"S2_40": {
"asset_version": "s2_40.1",
"module_id_prefix": "S2_40-ASSET",
"owner": "Stage_2_S2_40_owner",
"schema_version": "stage2_s2_40_generic_asset.v1",
"scope_predicate": "workflow_id == S2_40",
},
}
S2_40_WORKFLOW_PATH = "workflows/S2_40_final_review_render_and_commit.yml"
S2_40_TRANSITIONED_STUB_VALUES = frozenset(
{
"WF-S2_40-STATUS-ONLY",
"s2_40.status_only.1",
"DRAFT_HANDOFF_STUB_HASH_BOUND",
"entrypoint_id == S2_40_STATUS_ONLY",
}
)
S2_40_WORKFLOW_METADATA: dict[str, Any] = {
"asset_version": "s2_40.finalizer.1",
"authority_ids": [],
"consumed_schema_ids": [
"https://schemas.liti-agent.local/stage2/s2_00/context.schema.v2.json",
"https://schemas.liti-agent.local/stage2/s2_00/ingress.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_10/s2_10.schema.v2.json",
"https://schemas.liti-agent.local/stage2/s2_20/binding_retrieval.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_20/calculation.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_20/relief_plan.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_30/draft_atoms.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_40/package.schema.v1.json",
"https://schemas.liti-agent.local/stage2/shared/deployment.schema.v3.json",
"https://schemas.liti-agent.local/stage2/shared/review_status.schema.v1.json",
],
"dependency_module_ids": [
"SCHEMA-CONTEXT",
"SCHEMA-DEPLOYMENT",
"SCHEMA-INGRESS",
"SCHEMA-REVIEW-STATUS",
"SCHEMA-S2_10",
"S2_20-ASSET-809C3C709B4F2295",
"S2_20-ASSET-AA40CF5140DE8790",
"S2_20-ASSET-C9FC917D8CBF920E",
"S2_20-ASSET-E82839694073D431",
"S2_20-ASSET-FF1F03B3FC56E579",
"S2_30-ASSET-6A9B1F5EC854740E",
"S2_30-ASSET-E1FCF8BD63300F4D",
"S2_40-ASSET-5C4CAFFAB8D2F982",
"WF-S2_00",
"WF-S2_10",
],
"entry_routes": ["TO_S2_40", "TO_S2_40_STATUS_ONLY"],
"forbidden_contract_codes": [
"LEGACY-STAGE2-V0-V3",
"S2_40-DIRECTORY-SCAN",
"S2_40-FREE-TEXT-RENDER-FALLBACK",
"S2_40-LLM-CALL",
"S2_40-RUN-STATUS-NOT-LAST",
"S2_40-UNVERIFIED-READY",
],
"implementation_status": "IMPLEMENTED_OFFLINE_CONTRACT_LIVE_ADMISSION_PENDING",
"incompatible_module_ids": [],
"inputs": [
"ingress/ingress_status.json",
"ingress/technical_diagnostic.json",
"ingress/stage1_input_manifest.json",
"ingress/intake_report.json",
"review/issue_ledger.base.json",
"map_s2_10/s2_10_publish_status.json",
"plan/plan_publish_status.json",
"plan/canonical_relief_plan.json",
"plan/claim_groups.json",
"plan/case_type_bindings.json",
"map_s2_30/s2_30_publish_status.json",
"map_s2_30/artifact_manifest.json",
"map_s2_30/{draft_parts,issue_patches,worknote_parts,usage_parts}/<claim_group_id>.json",
"review/review_receipts/<request_id>.json",
"review/lawyer_judgment_record.json",
],
"legal_admission_status": "PENDING",
"live_admission_status": "PENDING",
"module_id": "WF-S2_40",
"module_kind": "WORKFLOW",
"outputs": [
"review/issue_ledger.final.json",
"review/assumption_ledger.json",
"review/llm_usage.jsonl",
"candidates/by-content-digest/<candidate_content_digest>/",
"review/review_requests/<request_id>.json",
"final/claim_relief.md",
"final/claim_cause.md",
"final/pleading_draft.md",
"final/stage2_package.json",
"commit/commit_intent.json",
"commit/stage2_commit_result.json",
"control/run_status.json",
],
"owner": "Stage_2_S2_40_owner",
"path": S2_40_WORKFLOW_PATH,
"produced_schema_ids": [
"stage2_s2_40_candidate_manifest.v1",
"stage2_s2_40_commit_intent.v1",
"stage2_s2_40_commit_result.v1",
"stage2_s2_40_package.v1",
"stage2_s2_40_run_status.v1",
],
"schema_version": "stage2_workflow_contract.v1",
"scope_predicate": "workflow_id == S2_40 and entry_route in {TO_S2_40,TO_S2_40_STATUS_ONLY}",
"semantic_review_status": "PENDING_LEGAL_AND_LIVE_ADMISSION",
"status_only_exact_inputs": [
"ingress/ingress_status.json",
"ingress/technical_diagnostic.json",
"ingress/stage1_input_manifest.json",
"ingress/intake_report.json",
"review/issue_ledger.base.json",
],
}
class ReleaseBuildError(ValueError): class ReleaseBuildError(ValueError):
"""Raised when a release input violates the canonical closure contract.""" """Raised when a release input violates the canonical closure contract."""
@@ -151,7 +288,7 @@ def _mirror_for(root: Path, source_path: str) -> tuple[str, bytes] | None:
return mirror_path, mirror_raw return mirror_path, mirror_raw
def _generic_kind(relative: str) -> str: def _generic_kind(relative: str, owner_stage: str = "S2_20") -> str:
if relative.startswith("tests/"): if relative.startswith("tests/"):
return "TEST" return "TEST"
if relative.startswith("schemas/"): if relative.startswith("schemas/"):
@@ -168,13 +305,16 @@ def _generic_kind(relative: str) -> str:
return "MANIFEST" return "MANIFEST"
if relative.startswith("registry/"): if relative.startswith("registry/"):
return "DECLARATIVE_REGISTRY" return "DECLARATIVE_REGISTRY"
return "S2_20_ASSET" return f"{owner_stage}_ASSET"
def _generic_module_row(relative: str) -> dict[str, Any]: def _generic_module_row(relative: str, owner_stage: str = "S2_20") -> dict[str, Any]:
metadata = STAGE_GENERIC_METADATA.get(owner_stage)
if metadata is None:
raise ReleaseBuildError(f"UNSUPPORTED_PARENT_MEMBER_OWNER_STAGE:{owner_stage}")
identity = hashlib.sha256(relative.encode("utf-8")).hexdigest()[:16].upper() identity = hashlib.sha256(relative.encode("utf-8")).hexdigest()[:16].upper()
return { return {
"asset_version": "s2_20.1", "asset_version": metadata["asset_version"],
"authority_ids": [], "authority_ids": [],
"consumed_schema_ids": [], "consumed_schema_ids": [],
"dependency_module_ids": [], "dependency_module_ids": [],
@@ -182,18 +322,70 @@ def _generic_module_row(relative: str) -> dict[str, Any]:
"implementation_status": "DEV_HASH_BOUND_OFFLINE_ONLY", "implementation_status": "DEV_HASH_BOUND_OFFLINE_ONLY",
"incompatible_module_ids": [], "incompatible_module_ids": [],
"inputs": [], "inputs": [],
"module_id": f"S2_20-ASSET-{identity}", "module_id": f"{metadata['module_id_prefix']}-{identity}",
"module_kind": _generic_kind(relative), "module_kind": _generic_kind(relative, owner_stage),
"outputs": [], "outputs": [],
"owner": "Stage_2_S2_20_owner", "owner": metadata["owner"],
"path": relative, "path": relative,
"produced_schema_ids": [], "produced_schema_ids": [],
"schema_version": "stage2_s2_20_generic_asset.v1", "schema_version": metadata["schema_version"],
"scope_predicate": "workflow_id == S2_20", "scope_predicate": metadata["scope_predicate"],
"semantic_review_status": "PENDING_LEGAL_AND_LIVE_ADMISSION", "semantic_review_status": "PENDING_LEGAL_AND_LIVE_ADMISSION",
} }
def _s2_40_workflow_module_row() -> dict[str, Any]:
"""Return the authoritative full S2_40 workflow row.
The pre-S2_40 parent template carried a status-only stub row at the same
physical path. Preserving that semantic metadata while merely refreshing
its file hash would make the release closure describe a different workflow
than the bytes it seals.
"""
return copy.deepcopy(S2_40_WORKFLOW_METADATA)
def _assert_no_transitioned_s2_40_stub(rows: Iterable[Mapping[str, Any]]) -> None:
for row in rows:
if row.get("path") != S2_40_WORKFLOW_PATH:
continue
observed = {
row.get("module_id"),
row.get("asset_version"),
row.get("implementation_status"),
row.get("scope_predicate"),
}
stale = sorted(str(value) for value in observed & S2_40_TRANSITIONED_STUB_VALUES)
if stale:
raise ReleaseBuildError(f"S2_40_TRANSITIONED_STUB_METADATA_FORBIDDEN:{stale}")
drift = {
key: {"expected": expected, "observed": row.get(key)}
for key, expected in S2_40_WORKFLOW_METADATA.items()
if row.get(key) != expected
}
if drift:
raise ReleaseBuildError(
"S2_40_WORKFLOW_METADATA_MISMATCH:"
+ json.dumps(drift, ensure_ascii=False, sort_keys=True)
)
def _is_generic_module_row(row: Mapping[str, Any]) -> bool:
schema_version = row.get("schema_version")
module_id = row.get("module_id")
return (
schema_version in {
metadata["schema_version"] for metadata in STAGE_GENERIC_METADATA.values()
}
or isinstance(module_id, str)
and any(
module_id.startswith(f"{metadata['module_id_prefix']}-")
for metadata in STAGE_GENERIC_METADATA.values()
)
)
def _refresh_module_row(root: Path, row: dict[str, Any]) -> dict[str, Any]: def _refresh_module_row(root: Path, row: dict[str, Any]) -> dict[str, Any]:
refreshed = copy.deepcopy(row) refreshed = copy.deepcopy(row)
relative = _relative_path(refreshed.get("path")) relative = _relative_path(refreshed.get("path"))
@@ -234,8 +426,9 @@ def build_module_manifest(
root: Path, root: Path,
template: dict[str, Any], template: dict[str, Any],
explicit_paths: Iterable[str], explicit_paths: Iterable[str],
path_owners: Mapping[str, str] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Preserve canonical rows, refresh physical bindings and append S2_20 rows.""" """Refresh canonical rows and append stage-owned generic source rows."""
if template.get("schema_version") != MODULE_MANIFEST_SCHEMA: if template.get("schema_version") != MODULE_MANIFEST_SCHEMA:
raise ReleaseBuildError("CANONICAL_MODULE_MANIFEST_V1_REQUIRED") raise ReleaseBuildError("CANONICAL_MODULE_MANIFEST_V1_REQUIRED")
@@ -249,6 +442,14 @@ def build_module_manifest(
forbidden = sorted(set(normalized_explicit) & FORBIDDEN_PARENT_MEMBERS) forbidden = sorted(set(normalized_explicit) & FORBIDDEN_PARENT_MEMBERS)
if forbidden: if forbidden:
raise ReleaseBuildError(f"NON_CYCLIC_PARENT_VIOLATION:{forbidden}") raise ReleaseBuildError(f"NON_CYCLIC_PARENT_VIOLATION:{forbidden}")
normalized_owners: dict[str, str] = {}
for raw_path, owner_stage in (path_owners or {}).items():
relative = _relative_path(raw_path)
if relative not in normalized_explicit:
raise ReleaseBuildError(f"OWNER_PATH_NOT_IN_EXPLICIT_CLOSURE:{relative}")
if owner_stage not in STAGE_GENERIC_METADATA:
raise ReleaseBuildError(f"UNSUPPORTED_PARENT_MEMBER_OWNER_STAGE:{owner_stage}")
normalized_owners[relative] = owner_stage
result = copy.deepcopy(template) result = copy.deepcopy(template)
refreshed_rows: list[dict[str, Any]] = [] refreshed_rows: list[dict[str, Any]] = []
@@ -263,9 +464,28 @@ def build_module_manifest(
raise ReleaseBuildError(f"MODULE_ID_INVALID_OR_DUPLICATE:{module_id!r}") raise ReleaseBuildError(f"MODULE_ID_INVALID_OR_DUPLICATE:{module_id!r}")
if relative in seen_paths: if relative in seen_paths:
raise ReleaseBuildError(f"MODULE_PATH_DUPLICATE:{relative}") raise ReleaseBuildError(f"MODULE_PATH_DUPLICATE:{relative}")
seen_ids.add(module_id) owner_stage = normalized_owners.get(relative)
if relative == S2_40_WORKFLOW_PATH:
if owner_stage not in {None, "S2_40"}:
raise ReleaseBuildError(
f"S2_40_WORKFLOW_OWNER_STAGE_MISMATCH:{owner_stage}"
)
candidate = _s2_40_workflow_module_row()
else:
candidate = (
_generic_module_row(relative, owner_stage)
if owner_stage is not None and _is_generic_module_row(value)
else value
)
refreshed = _refresh_module_row(root, candidate)
refreshed_id = refreshed.get("module_id")
if not isinstance(refreshed_id, str) or not refreshed_id:
raise ReleaseBuildError(f"MODULE_ID_INVALID_OR_DUPLICATE:{refreshed_id!r}")
if refreshed_id in seen_ids:
raise ReleaseBuildError(f"MODULE_ID_INVALID_OR_DUPLICATE:{refreshed_id!r}")
seen_ids.add(refreshed_id)
seen_paths.add(relative) seen_paths.add(relative)
refreshed_rows.append(_refresh_module_row(root, value)) refreshed_rows.append(refreshed)
explicit_set = set(normalized_explicit) explicit_set = set(normalized_explicit)
for relative in sorted(normalized_explicit): for relative in sorted(normalized_explicit):
@@ -278,13 +498,19 @@ def build_module_manifest(
continue continue
if relative in seen_paths: if relative in seen_paths:
continue continue
row = _refresh_module_row(root, _generic_module_row(relative)) candidate = (
_s2_40_workflow_module_row()
if relative == S2_40_WORKFLOW_PATH
else _generic_module_row(relative, normalized_owners.get(relative, "S2_20"))
)
row = _refresh_module_row(root, candidate)
if row["module_id"] in seen_ids: if row["module_id"] in seen_ids:
raise ReleaseBuildError(f"GENERATED_MODULE_ID_COLLISION:{row['module_id']}") raise ReleaseBuildError(f"GENERATED_MODULE_ID_COLLISION:{row['module_id']}")
seen_ids.add(row["module_id"]) seen_ids.add(row["module_id"])
seen_paths.add(relative) seen_paths.add(relative)
refreshed_rows.append(row) refreshed_rows.append(row)
_assert_no_transitioned_s2_40_stub(refreshed_rows)
result["modules"] = refreshed_rows result["modules"] = refreshed_rows
mirrors = [entry for row in refreshed_rows if (entry := _documentation_mirror(row))] mirrors = [entry for row in refreshed_rows if (entry := _documentation_mirror(row))]
mirror_sources = [str(entry["source_path"]) for entry in mirrors] mirror_sources = [str(entry["source_path"]) for entry in mirrors]
@@ -312,6 +538,24 @@ def build_module_manifest(
for row in refreshed_rows for row in refreshed_rows
if row.get("schema_version") == "stage2_s2_20_generic_asset.v1" if row.get("schema_version") == "stage2_s2_20_generic_asset.v1"
), ),
"s2_30_generic_module_count": sum(
1
for row in refreshed_rows
if row.get("schema_version") == "stage2_s2_30_generic_asset.v1"
),
"s2_40_generic_module_count": sum(
1
for row in refreshed_rows
if row.get("schema_version") == "stage2_s2_40_generic_asset.v1"
),
"generic_module_counts_by_stage": {
stage: sum(
1
for row in refreshed_rows
if row.get("schema_version") == metadata["schema_version"]
)
for stage, metadata in sorted(STAGE_GENERIC_METADATA.items())
},
"executable_agent_hash_included": False, "executable_agent_hash_included": False,
"executor_binding_hash_included": False, "executor_binding_hash_included": False,
"inline_runtime_code_hash_included": False, "inline_runtime_code_hash_included": False,
@@ -431,8 +675,14 @@ def build_release_package(
path_list: list[str], path_list: list[str],
module_template: dict[str, Any], module_template: dict[str, Any],
parent_template: dict[str, Any], parent_template: dict[str, Any],
path_owners: Mapping[str, str] | None = None,
) -> tuple[dict[str, Any], dict[str, Any]]: ) -> tuple[dict[str, Any], dict[str, Any]]:
module_manifest = build_module_manifest(root, module_template, path_list) module_manifest = build_module_manifest(
root,
module_template,
path_list,
path_owners=path_owners,
)
module_raw = _canonical_bytes(module_manifest) module_raw = _canonical_bytes(module_manifest)
parent_release = build_parent_release(root, parent_template, module_raw) parent_release = build_parent_release(root, parent_template, module_raw)
return module_manifest, parent_release return module_manifest, parent_release
@@ -445,6 +695,13 @@ def _write_bytes(path: Path, raw: bytes) -> None:
os.replace(temporary, path) os.replace(temporary, path)
def _owner_stage_from_path_list(path: Path) -> str:
match = re.fullmatch(r"s2_(20|30|40)_parent_member_paths\.json", path.name)
if match is None:
raise ReleaseBuildError(f"PARENT_PATH_LIST_OWNER_UNRESOLVED:{path.as_posix()}")
return f"S2_{match.group(1)}"
def main() -> int: def main() -> int:
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Reseal canonical Stage-2 module and parent release manifests" description="Reseal canonical Stage-2 module and parent release manifests"
@@ -476,20 +733,22 @@ def main() -> int:
) )
args = parser.parse_args() args = parser.parse_args()
path_lists: list[list[str]] = [] path_lists: list[tuple[str, list[str]]] = []
for source in [args.path_list, *args.additional_path_list]: for source in [args.path_list, *args.additional_path_list]:
loaded = _load_json(source) loaded = _load_json(source)
if not isinstance(loaded, list) or not all(isinstance(row, str) for row in loaded): if not isinstance(loaded, list) or not all(isinstance(row, str) for row in loaded):
raise ReleaseBuildError(f"PATH_LIST_MUST_BE_STRING_ARRAY:{source.as_posix()}") raise ReleaseBuildError(f"PATH_LIST_MUST_BE_STRING_ARRAY:{source.as_posix()}")
path_lists.append(loaded) path_lists.append((_owner_stage_from_path_list(source), loaded))
seen_paths: set[str] = set() seen_paths: set[str] = set()
path_list: list[str] = [] path_list: list[str] = []
for rows in path_lists: path_owners: dict[str, str] = {}
for owner_stage, rows in path_lists:
overlap = sorted(seen_paths & set(rows)) overlap = sorted(seen_paths & set(rows))
if overlap: if overlap:
raise ReleaseBuildError(f"PARENT_PATH_LISTS_MUST_BE_DISJOINT:{overlap}") raise ReleaseBuildError(f"PARENT_PATH_LISTS_MUST_BE_DISJOINT:{overlap}")
seen_paths.update(rows) seen_paths.update(rows)
path_list.extend(rows) path_list.extend(rows)
path_owners.update({row: owner_stage for row in rows})
path_list.sort() path_list.sort()
module_template_path = args.module_template or args.root / "manifest/module_manifest.json" module_template_path = args.module_template or args.root / "manifest/module_manifest.json"
parent_template_path = args.parent_template or args.root / "manifest/stage2_release.json" parent_template_path = args.parent_template or args.root / "manifest/stage2_release.json"
@@ -499,6 +758,7 @@ def main() -> int:
path_list, path_list,
_load_json(module_template_path), _load_json(module_template_path),
_load_json(parent_template_path), _load_json(parent_template_path),
path_owners=path_owners,
) )
_write_bytes(args.output, _canonical_bytes(module_manifest)) _write_bytes(args.output, _canonical_bytes(module_manifest))
_write_bytes(parent_output, _canonical_bytes(parent_release)) _write_bytes(parent_output, _canonical_bytes(parent_release))
@@ -12,6 +12,7 @@ from __future__ import annotations
import argparse import argparse
import hashlib import hashlib
import importlib.util
import json import json
import os import os
from pathlib import Path from pathlib import Path
@@ -45,6 +46,12 @@ MODULE_MANIFEST_PATH = DEPLOYMENT_ROOT / "manifest" / "module_manifest.json"
PLATFORM_RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_10_platform_adapter_receipt.json" PLATFORM_RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_10_platform_adapter_receipt.json"
MODEL_RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_10_model_benchmark_receipt.json" MODEL_RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_10_model_benchmark_receipt.json"
LEGAL_RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_10_legal_review_receipt.json" LEGAL_RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_10_legal_review_receipt.json"
RELEASE_BUILDER_PATH = DEPLOYMENT_ROOT / "offline_build" / "build_release_manifests.py"
CUMULATIVE_PARENT_PATH_LISTS = (
("S2_20", DEPLOYMENT_ROOT / "manifest" / "s2_20_parent_member_paths.json"),
("S2_30", DEPLOYMENT_ROOT / "manifest" / "s2_30_parent_member_paths.json"),
("S2_40", DEPLOYMENT_ROOT / "manifest" / "s2_40_parent_member_paths.json"),
)
EXPECTED_AGENT_NAME = "Stage_2_S2_10" EXPECTED_AGENT_NAME = "Stage_2_S2_10"
EXPECTED_STAGE_NAME = "S2_10" EXPECTED_STAGE_NAME = "S2_10"
@@ -276,6 +283,75 @@ def _load_json(path: Path) -> dict[str, Any]:
return value return value
def _load_release_builder() -> Any:
spec = importlib.util.spec_from_file_location(
"stage2_cumulative_release_builder",
RELEASE_BUILDER_PATH,
)
if spec is None or spec.loader is None:
raise BuildError("CUMULATIVE_RELEASE_BUILDER_IMPORT_FAILED", _logical_path(RELEASE_BUILDER_PATH))
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def cumulative_parent_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]:
"""Recompute the current owner-aware cumulative parent in memory only.
S2_10 no longer owns ``module_manifest.json`` or ``stage2_release.json``.
This oracle delegates to the canonical S2_20+S2_30+S2_40 builder and is
used solely to detect drift; it never writes either parent file.
"""
release_builder = _load_release_builder()
combined: list[str] = []
path_owners: dict[str, str] = {}
seen: set[str] = set()
counts: dict[str, int] = {}
for owner_stage, source in CUMULATIVE_PARENT_PATH_LISTS:
raw = _require_file(source)
try:
values = json.loads(raw.decode("utf-8"))
except json.JSONDecodeError as exc:
raise BuildError("CUMULATIVE_PARENT_PATH_LIST_INVALID", f"{_logical_path(source)}: {exc}") from exc
if not isinstance(values, list) or not all(isinstance(value, str) for value in values):
raise BuildError("CUMULATIVE_PARENT_PATH_LIST_INVALID", _logical_path(source))
if values != sorted(values) or len(values) != len(set(values)):
raise BuildError("CUMULATIVE_PARENT_PATH_LIST_NOT_SORTED_UNIQUE", _logical_path(source))
overlap = sorted(seen & set(values))
if overlap:
raise BuildError("CUMULATIVE_PARENT_PATH_LIST_OVERLAP", repr(overlap))
seen.update(values)
combined.extend(values)
path_owners.update({value: owner_stage for value in values})
counts[owner_stage] = len(values)
combined.sort()
try:
module, parent = release_builder.build_release_package(
DEPLOYMENT_ROOT,
combined,
_load_json(MODULE_MANIFEST_PATH),
_load_json(PARENT_RELEASE_PATH),
path_owners=path_owners,
)
except Exception as exc:
raise BuildError(
"CUMULATIVE_PARENT_ORACLE_FAILED",
f"{type(exc).__name__}:{exc}",
) from exc
module_raw = release_builder._canonical_bytes(module)
parent_raw = release_builder._canonical_bytes(parent)
return {
MODULE_MANIFEST_PATH: module_raw,
PARENT_RELEASE_PATH: parent_raw,
}, {
"owner_path_counts": counts,
"module_count": len(module["modules"]),
"module_manifest_sha256": sha256_bytes(module_raw),
"parent_release_sha256": sha256_bytes(parent_raw),
}
def _mapping(value: Any, code: str) -> dict[str, Any]: def _mapping(value: Any, code: str) -> dict[str, Any]:
if not isinstance(value, dict): if not isinstance(value, dict):
raise BuildError(code, repr(value)[:200]) raise BuildError(code, repr(value)[:200])
@@ -1221,31 +1297,8 @@ def _atomic_write(path: Path, payload: bytes) -> None:
temporary.unlink() temporary.unlink()
def build() -> dict[str, Any]: def _compare_outputs(outputs: Mapping[Path, bytes]) -> list[dict[str, Any]]:
# Phase 1 closes the authoring projection, inline receipt and binding. drift: list[dict[str, Any]] = []
outputs, report = expected_outputs()
for path, payload in outputs.items():
_atomic_write(path, payload)
if report["phase"] in {"PREREQUISITE_PROJECTION", "PREREQUISITE_MODULE_MANIFEST"}:
outputs, report = expected_outputs()
for path, payload in outputs.items():
_atomic_write(path, payload)
if report["phase"] == "PREREQUISITE_MODULE_MANIFEST":
outputs, report = expected_outputs()
for path, payload in outputs.items():
_atomic_write(path, payload)
if report["phase"] != "COMPLETE":
raise BuildError("BUILD_DID_NOT_REACH_COMPLETE_PHASE", repr(report))
return {
"status": "BUILT_OFFLINE_HYBRID_PACKAGE",
"written_paths": [_logical_path(path) for path in outputs],
**report,
}
def check() -> dict[str, Any]:
outputs, report = expected_outputs()
drift = []
for path, expected in outputs.items(): for path, expected in outputs.items():
observed = path.read_bytes() if path.is_file() and not path.is_symlink() else None observed = path.read_bytes() if path.is_file() and not path.is_symlink() else None
if observed != expected: if observed != expected:
@@ -1256,31 +1309,100 @@ def check() -> dict[str, Any]:
"observed_sha256": sha256_bytes(observed) if observed is not None else None, "observed_sha256": sha256_bytes(observed) if observed is not None else None,
} }
) )
if report["phase"] != "COMPLETE" or drift: return drift
raise BuildError("OFFLINE_PACKAGE_DRIFT", json.dumps({"report": report, "drift": drift}, ensure_ascii=False))
def _current_cumulative_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]:
"""Return the complete S2_10-owned and cumulative downstream oracle.
The owner-aware release builder is the sole producer of the cumulative
module manifest and parent release. The legacy ``expected_outputs``
function remains only as a compatibility helper for older callers; the
default build/check path must never use its S2_10-only parent projection.
"""
prerequisite, prerequisite_report = prerequisite_outputs()
parent, parent_report = cumulative_parent_outputs()
child, child_report = cumulative_child_outputs(prerequisite, parent)
overlap = (set(prerequisite) & set(parent)) | (set(prerequisite) & set(child)) | (set(parent) & set(child))
if overlap:
raise BuildError(
"CUMULATIVE_OUTPUT_PATH_OVERLAP",
repr(sorted(_logical_path(path) for path in overlap)),
)
return { return {
"status": "OFFLINE_HYBRID_PACKAGE_CHECK_PASS", **prerequisite,
**parent,
**child,
}, {
"prerequisite": prerequisite_report,
"cumulative_parent": parent_report,
"downstream_child": child_report,
}
def build() -> dict[str, Any]:
"""Rebuild S2_10-owned artifacts without rewriting the cumulative parent.
A cumulative parent drift requires the owner-aware release builder and its
explicit reseal sequence. Silently rebuilding an obsolete S2_10-only
parent here would discard downstream S2_20/S2_30/S2_40 closure.
"""
prerequisite, prerequisite_report = prerequisite_outputs()
for path, payload in prerequisite.items():
_atomic_write(path, payload)
parent, parent_report = cumulative_parent_outputs()
parent_drift = _compare_outputs(parent)
if parent_drift:
raise BuildError(
"CUMULATIVE_PARENT_RESEAL_REQUIRED",
json.dumps(
{"report": parent_report, "drift": parent_drift},
ensure_ascii=False,
sort_keys=True,
),
)
child, child_report = child_only_outputs()
for path, payload in child.items():
_atomic_write(path, payload)
return {
"status": "S2_10_OWNED_ARTIFACTS_REBUILT_CUMULATIVE_PARENT_PRESERVED",
"written_paths": [_logical_path(path) for path in {**prerequisite, **child}],
"prerequisite": prerequisite_report,
"cumulative_parent": parent_report,
"downstream_child": child_report,
}
def check() -> dict[str, Any]:
outputs, report = _current_cumulative_outputs()
drift = _compare_outputs(outputs)
if drift:
raise BuildError(
"OFFLINE_PACKAGE_DRIFT",
json.dumps({"report": report, "drift": drift}, ensure_ascii=False, sort_keys=True),
)
return {
"status": "S2_10_CUMULATIVE_PACKAGE_CHECK_PASS",
"checked_paths": [_logical_path(path) for path in outputs], "checked_paths": [_logical_path(path) for path in outputs],
**report, **report,
} }
def child_only_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]: def _downstream_child_outputs(
"""Reseal only the downstream S2_10 child chain against a frozen parent. *,
authoring_raw: bytes,
The canonical parent/module builder owns the raw parent closure. This mode binding_raw: bytes,
therefore never rewrites ``module_manifest.json``, ``stage2_release.json``, inline_receipt_raw: bytes,
the Agent projection, prompt receipt, or LLM binding. parent_raw: bytes,
""" ) -> tuple[dict[Path, bytes], dict[str, Any]]:
contract = extract_agent_contract(
authoring_raw = _require_file(AUTHORING_PATH) _load_yaml(authoring_raw, _logical_path(AUTHORING_PATH))
if _require_file(PROJECTION_PATH) != authoring_raw: )
raise BuildError("S2_10_AGENT_PROJECTION_DRIFT", _logical_path(PROJECTION_PATH))
contract = extract_agent_contract(_load_yaml(authoring_raw, _logical_path(AUTHORING_PATH)))
binding_raw = _require_file(BINDING_PATH)
binding = _load_yaml(binding_raw, _logical_path(BINDING_PATH)) binding = _load_yaml(binding_raw, _logical_path(BINDING_PATH))
inline_receipt_raw = _require_file(INLINE_RECEIPT_PATH)
parent_raw = _require_file(PARENT_RELEASE_PATH)
child = build_child_release(parent_raw, binding) child = build_child_release(parent_raw, binding)
child_raw = canonical_json_bytes(child) child_raw = canonical_json_bytes(child)
outputs = { outputs = {
@@ -1310,6 +1432,57 @@ def child_only_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]:
} }
def cumulative_child_outputs(
prerequisite: Mapping[Path, bytes],
parent: Mapping[Path, bytes],
) -> tuple[dict[Path, bytes], dict[str, Any]]:
"""Build downstream receipts from the expected current parent material.
This is the critical distinction from the bounded ``--child-only`` mode:
the default ``--check`` validates the child chain that *would* result from
the current owner-aware cumulative parent and current prerequisite oracle,
not a self-consistent but obsolete child bound to observed stale bytes.
"""
required = {
BINDING_PATH: prerequisite,
INLINE_RECEIPT_PATH: prerequisite,
PARENT_RELEASE_PATH: parent,
}
missing = [
_logical_path(path)
for path, mapping in required.items()
if path not in mapping
]
if missing:
raise BuildError("CUMULATIVE_CHILD_MATERIAL_MISSING", repr(sorted(missing)))
return _downstream_child_outputs(
authoring_raw=_require_file(AUTHORING_PATH),
binding_raw=prerequisite[BINDING_PATH],
inline_receipt_raw=prerequisite[INLINE_RECEIPT_PATH],
parent_raw=parent[PARENT_RELEASE_PATH],
)
def child_only_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]:
"""Reseal only the downstream S2_10 child chain against a frozen parent.
The canonical parent/module builder owns the raw parent closure. This mode
therefore never rewrites ``module_manifest.json``, ``stage2_release.json``,
the Agent projection, prompt receipt, or LLM binding.
"""
authoring_raw = _require_file(AUTHORING_PATH)
if _require_file(PROJECTION_PATH) != authoring_raw:
raise BuildError("S2_10_AGENT_PROJECTION_DRIFT", _logical_path(PROJECTION_PATH))
return _downstream_child_outputs(
authoring_raw=authoring_raw,
binding_raw=_require_file(BINDING_PATH),
inline_receipt_raw=_require_file(INLINE_RECEIPT_PATH),
parent_raw=_require_file(PARENT_RELEASE_PATH),
)
def prerequisite_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]: def prerequisite_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]:
"""Build only the parent-owned S2_10 projection prerequisites.""" """Build only the parent-owned S2_10 projection prerequisites."""
@@ -12,6 +12,7 @@ from __future__ import annotations
import argparse import argparse
import hashlib import hashlib
import importlib.util
import json import json
import os import os
from pathlib import Path from pathlib import Path
@@ -45,6 +46,12 @@ MODULE_MANIFEST_PATH = DEPLOYMENT_ROOT / "manifest" / "module_manifest.json"
PLATFORM_RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_10_platform_adapter_receipt.json" PLATFORM_RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_10_platform_adapter_receipt.json"
MODEL_RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_10_model_benchmark_receipt.json" MODEL_RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_10_model_benchmark_receipt.json"
LEGAL_RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_10_legal_review_receipt.json" LEGAL_RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_10_legal_review_receipt.json"
RELEASE_BUILDER_PATH = DEPLOYMENT_ROOT / "offline_build" / "build_release_manifests.py"
CUMULATIVE_PARENT_PATH_LISTS = (
("S2_20", DEPLOYMENT_ROOT / "manifest" / "s2_20_parent_member_paths.json"),
("S2_30", DEPLOYMENT_ROOT / "manifest" / "s2_30_parent_member_paths.json"),
("S2_40", DEPLOYMENT_ROOT / "manifest" / "s2_40_parent_member_paths.json"),
)
EXPECTED_AGENT_NAME = "Stage_2_S2_10" EXPECTED_AGENT_NAME = "Stage_2_S2_10"
EXPECTED_STAGE_NAME = "S2_10" EXPECTED_STAGE_NAME = "S2_10"
@@ -276,6 +283,75 @@ def _load_json(path: Path) -> dict[str, Any]:
return value return value
def _load_release_builder() -> Any:
spec = importlib.util.spec_from_file_location(
"stage2_cumulative_release_builder",
RELEASE_BUILDER_PATH,
)
if spec is None or spec.loader is None:
raise BuildError("CUMULATIVE_RELEASE_BUILDER_IMPORT_FAILED", _logical_path(RELEASE_BUILDER_PATH))
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def cumulative_parent_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]:
"""Recompute the current owner-aware cumulative parent in memory only.
S2_10 no longer owns ``module_manifest.json`` or ``stage2_release.json``.
This oracle delegates to the canonical S2_20+S2_30+S2_40 builder and is
used solely to detect drift; it never writes either parent file.
"""
release_builder = _load_release_builder()
combined: list[str] = []
path_owners: dict[str, str] = {}
seen: set[str] = set()
counts: dict[str, int] = {}
for owner_stage, source in CUMULATIVE_PARENT_PATH_LISTS:
raw = _require_file(source)
try:
values = json.loads(raw.decode("utf-8"))
except json.JSONDecodeError as exc:
raise BuildError("CUMULATIVE_PARENT_PATH_LIST_INVALID", f"{_logical_path(source)}: {exc}") from exc
if not isinstance(values, list) or not all(isinstance(value, str) for value in values):
raise BuildError("CUMULATIVE_PARENT_PATH_LIST_INVALID", _logical_path(source))
if values != sorted(values) or len(values) != len(set(values)):
raise BuildError("CUMULATIVE_PARENT_PATH_LIST_NOT_SORTED_UNIQUE", _logical_path(source))
overlap = sorted(seen & set(values))
if overlap:
raise BuildError("CUMULATIVE_PARENT_PATH_LIST_OVERLAP", repr(overlap))
seen.update(values)
combined.extend(values)
path_owners.update({value: owner_stage for value in values})
counts[owner_stage] = len(values)
combined.sort()
try:
module, parent = release_builder.build_release_package(
DEPLOYMENT_ROOT,
combined,
_load_json(MODULE_MANIFEST_PATH),
_load_json(PARENT_RELEASE_PATH),
path_owners=path_owners,
)
except Exception as exc:
raise BuildError(
"CUMULATIVE_PARENT_ORACLE_FAILED",
f"{type(exc).__name__}:{exc}",
) from exc
module_raw = release_builder._canonical_bytes(module)
parent_raw = release_builder._canonical_bytes(parent)
return {
MODULE_MANIFEST_PATH: module_raw,
PARENT_RELEASE_PATH: parent_raw,
}, {
"owner_path_counts": counts,
"module_count": len(module["modules"]),
"module_manifest_sha256": sha256_bytes(module_raw),
"parent_release_sha256": sha256_bytes(parent_raw),
}
def _mapping(value: Any, code: str) -> dict[str, Any]: def _mapping(value: Any, code: str) -> dict[str, Any]:
if not isinstance(value, dict): if not isinstance(value, dict):
raise BuildError(code, repr(value)[:200]) raise BuildError(code, repr(value)[:200])
@@ -1221,31 +1297,8 @@ def _atomic_write(path: Path, payload: bytes) -> None:
temporary.unlink() temporary.unlink()
def build() -> dict[str, Any]: def _compare_outputs(outputs: Mapping[Path, bytes]) -> list[dict[str, Any]]:
# Phase 1 closes the authoring projection, inline receipt and binding. drift: list[dict[str, Any]] = []
outputs, report = expected_outputs()
for path, payload in outputs.items():
_atomic_write(path, payload)
if report["phase"] in {"PREREQUISITE_PROJECTION", "PREREQUISITE_MODULE_MANIFEST"}:
outputs, report = expected_outputs()
for path, payload in outputs.items():
_atomic_write(path, payload)
if report["phase"] == "PREREQUISITE_MODULE_MANIFEST":
outputs, report = expected_outputs()
for path, payload in outputs.items():
_atomic_write(path, payload)
if report["phase"] != "COMPLETE":
raise BuildError("BUILD_DID_NOT_REACH_COMPLETE_PHASE", repr(report))
return {
"status": "BUILT_OFFLINE_HYBRID_PACKAGE",
"written_paths": [_logical_path(path) for path in outputs],
**report,
}
def check() -> dict[str, Any]:
outputs, report = expected_outputs()
drift = []
for path, expected in outputs.items(): for path, expected in outputs.items():
observed = path.read_bytes() if path.is_file() and not path.is_symlink() else None observed = path.read_bytes() if path.is_file() and not path.is_symlink() else None
if observed != expected: if observed != expected:
@@ -1256,31 +1309,100 @@ def check() -> dict[str, Any]:
"observed_sha256": sha256_bytes(observed) if observed is not None else None, "observed_sha256": sha256_bytes(observed) if observed is not None else None,
} }
) )
if report["phase"] != "COMPLETE" or drift: return drift
raise BuildError("OFFLINE_PACKAGE_DRIFT", json.dumps({"report": report, "drift": drift}, ensure_ascii=False))
def _current_cumulative_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]:
"""Return the complete S2_10-owned and cumulative downstream oracle.
The owner-aware release builder is the sole producer of the cumulative
module manifest and parent release. The legacy ``expected_outputs``
function remains only as a compatibility helper for older callers; the
default build/check path must never use its S2_10-only parent projection.
"""
prerequisite, prerequisite_report = prerequisite_outputs()
parent, parent_report = cumulative_parent_outputs()
child, child_report = cumulative_child_outputs(prerequisite, parent)
overlap = (set(prerequisite) & set(parent)) | (set(prerequisite) & set(child)) | (set(parent) & set(child))
if overlap:
raise BuildError(
"CUMULATIVE_OUTPUT_PATH_OVERLAP",
repr(sorted(_logical_path(path) for path in overlap)),
)
return { return {
"status": "OFFLINE_HYBRID_PACKAGE_CHECK_PASS", **prerequisite,
**parent,
**child,
}, {
"prerequisite": prerequisite_report,
"cumulative_parent": parent_report,
"downstream_child": child_report,
}
def build() -> dict[str, Any]:
"""Rebuild S2_10-owned artifacts without rewriting the cumulative parent.
A cumulative parent drift requires the owner-aware release builder and its
explicit reseal sequence. Silently rebuilding an obsolete S2_10-only
parent here would discard downstream S2_20/S2_30/S2_40 closure.
"""
prerequisite, prerequisite_report = prerequisite_outputs()
for path, payload in prerequisite.items():
_atomic_write(path, payload)
parent, parent_report = cumulative_parent_outputs()
parent_drift = _compare_outputs(parent)
if parent_drift:
raise BuildError(
"CUMULATIVE_PARENT_RESEAL_REQUIRED",
json.dumps(
{"report": parent_report, "drift": parent_drift},
ensure_ascii=False,
sort_keys=True,
),
)
child, child_report = child_only_outputs()
for path, payload in child.items():
_atomic_write(path, payload)
return {
"status": "S2_10_OWNED_ARTIFACTS_REBUILT_CUMULATIVE_PARENT_PRESERVED",
"written_paths": [_logical_path(path) for path in {**prerequisite, **child}],
"prerequisite": prerequisite_report,
"cumulative_parent": parent_report,
"downstream_child": child_report,
}
def check() -> dict[str, Any]:
outputs, report = _current_cumulative_outputs()
drift = _compare_outputs(outputs)
if drift:
raise BuildError(
"OFFLINE_PACKAGE_DRIFT",
json.dumps({"report": report, "drift": drift}, ensure_ascii=False, sort_keys=True),
)
return {
"status": "S2_10_CUMULATIVE_PACKAGE_CHECK_PASS",
"checked_paths": [_logical_path(path) for path in outputs], "checked_paths": [_logical_path(path) for path in outputs],
**report, **report,
} }
def child_only_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]: def _downstream_child_outputs(
"""Reseal only the downstream S2_10 child chain against a frozen parent. *,
authoring_raw: bytes,
The canonical parent/module builder owns the raw parent closure. This mode binding_raw: bytes,
therefore never rewrites ``module_manifest.json``, ``stage2_release.json``, inline_receipt_raw: bytes,
the Agent projection, prompt receipt, or LLM binding. parent_raw: bytes,
""" ) -> tuple[dict[Path, bytes], dict[str, Any]]:
contract = extract_agent_contract(
authoring_raw = _require_file(AUTHORING_PATH) _load_yaml(authoring_raw, _logical_path(AUTHORING_PATH))
if _require_file(PROJECTION_PATH) != authoring_raw: )
raise BuildError("S2_10_AGENT_PROJECTION_DRIFT", _logical_path(PROJECTION_PATH))
contract = extract_agent_contract(_load_yaml(authoring_raw, _logical_path(AUTHORING_PATH)))
binding_raw = _require_file(BINDING_PATH)
binding = _load_yaml(binding_raw, _logical_path(BINDING_PATH)) binding = _load_yaml(binding_raw, _logical_path(BINDING_PATH))
inline_receipt_raw = _require_file(INLINE_RECEIPT_PATH)
parent_raw = _require_file(PARENT_RELEASE_PATH)
child = build_child_release(parent_raw, binding) child = build_child_release(parent_raw, binding)
child_raw = canonical_json_bytes(child) child_raw = canonical_json_bytes(child)
outputs = { outputs = {
@@ -1310,6 +1432,57 @@ def child_only_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]:
} }
def cumulative_child_outputs(
prerequisite: Mapping[Path, bytes],
parent: Mapping[Path, bytes],
) -> tuple[dict[Path, bytes], dict[str, Any]]:
"""Build downstream receipts from the expected current parent material.
This is the critical distinction from the bounded ``--child-only`` mode:
the default ``--check`` validates the child chain that *would* result from
the current owner-aware cumulative parent and current prerequisite oracle,
not a self-consistent but obsolete child bound to observed stale bytes.
"""
required = {
BINDING_PATH: prerequisite,
INLINE_RECEIPT_PATH: prerequisite,
PARENT_RELEASE_PATH: parent,
}
missing = [
_logical_path(path)
for path, mapping in required.items()
if path not in mapping
]
if missing:
raise BuildError("CUMULATIVE_CHILD_MATERIAL_MISSING", repr(sorted(missing)))
return _downstream_child_outputs(
authoring_raw=_require_file(AUTHORING_PATH),
binding_raw=prerequisite[BINDING_PATH],
inline_receipt_raw=prerequisite[INLINE_RECEIPT_PATH],
parent_raw=parent[PARENT_RELEASE_PATH],
)
def child_only_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]:
"""Reseal only the downstream S2_10 child chain against a frozen parent.
The canonical parent/module builder owns the raw parent closure. This mode
therefore never rewrites ``module_manifest.json``, ``stage2_release.json``,
the Agent projection, prompt receipt, or LLM binding.
"""
authoring_raw = _require_file(AUTHORING_PATH)
if _require_file(PROJECTION_PATH) != authoring_raw:
raise BuildError("S2_10_AGENT_PROJECTION_DRIFT", _logical_path(PROJECTION_PATH))
return _downstream_child_outputs(
authoring_raw=authoring_raw,
binding_raw=_require_file(BINDING_PATH),
inline_receipt_raw=_require_file(INLINE_RECEIPT_PATH),
parent_raw=_require_file(PARENT_RELEASE_PATH),
)
def prerequisite_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]: def prerequisite_outputs() -> tuple[dict[Path, bytes], dict[str, Any]]:
"""Build only the parent-owned S2_10 projection prerequisites.""" """Build only the parent-owned S2_10 projection prerequisites."""
@@ -59,9 +59,9 @@ EXPECTED_BUILD_ORDER = (
"S2_10_PROJECTION_PREREQUISITES", "S2_10_PROJECTION_PREREQUISITES",
"MODULE_MANIFEST", "MODULE_MANIFEST",
"PARENT_STAGE2_RELEASE", "PARENT_STAGE2_RELEASE",
"INJECT_PARENT_HASH_INTO_S2_30_S2_00_S2_20", "INJECT_PARENT_HASH_INTO_S2_30_S2_00_S2_20_S2_40",
"S2_30_AGENT_PROJECTION_PROMPT_CODE_RECEIPTS_BINDING", "S2_30_AGENT_PROJECTION_PROMPT_CODE_RECEIPTS_BINDING",
"S2_00_S2_20_PARENT_HASH_PROJECTIONS", "S2_00_S2_20_S2_40_PARENT_HASH_PROJECTIONS",
"SHARED_CODE_EXECUTOR_BINDING", "SHARED_CODE_EXECUTOR_BINDING",
"S2_10_AND_S2_30_CHILD_RELEASES_AND_RECEIPTS", "S2_10_AND_S2_30_CHILD_RELEASES_AND_RECEIPTS",
"CHECK_AND_REGRESSION", "CHECK_AND_REGRESSION",
@@ -153,6 +153,7 @@ PARENT_INDEPENDENT_PATHS = (
"tests/fixtures/s2_30/context_reference_envelope.json", "tests/fixtures/s2_30/context_reference_envelope.json",
"tests/fixtures/s2_30/technical_failure.json", "tests/fixtures/s2_30/technical_failure.json",
"tests/fixtures/s2_30/partial_write_publish_barrier.json", "tests/fixtures/s2_30/partial_write_publish_barrier.json",
"tests/fixtures/s2_30/persisted_handoff_chain.json",
"tests/fixtures/s2_30/regression_manifest.json", "tests/fixtures/s2_30/regression_manifest.json",
"manifest/s2_30_parent_member_paths.json", "manifest/s2_30_parent_member_paths.json",
) )
@@ -919,6 +920,100 @@ def _bound_asset_ref(
} }
def _s2_40_stage_binding(parent_sha: str) -> dict[str, Any]:
"""Build the detached, offline-only S2_40 deterministic-stage row."""
agent = ROOT / "agent_scripts" / "Stage_2_S2_40.yml"
workflow = ROOT / "workflows" / "S2_40_final_review_render_and_commit.yml"
receipt = ROOT / "manifest" / "s2_40_inline_code_receipt.json"
code = ROOT / "runtime" / "s2_40_commit.py"
return {
"stage_id": "S2_40",
"binding_id": "S2-BINDING-S2_40-CODE-EXECUTOR-V1",
"workflow_id": "S2_40",
"execution_class": "NON-LLM-DETERMINISTIC",
"active_runtime_authority": False,
"agent_script_ref": _bound_asset_ref(
"AGENT-S2_40-INLINE",
"agent_scripts/Stage_2_S2_40.yml",
agent,
"liti_agent_yaml.v1",
),
"workflow_contract_ref": _bound_asset_ref(
"WF-S2_40",
"workflows/S2_40_final_review_render_and_commit.yml",
workflow,
"stage2_s2_40_final_review_render_and_commit.v1",
),
"inline_code_receipt_ref": _bound_asset_ref(
"RECEIPT-S2_40-INLINE-CODE",
"manifest/s2_40_inline_code_receipt.json",
receipt,
"stage2_s2_40_inline_code_receipt.v1",
),
"stage2_release_ref": {
"asset_id": "RELEASE-STAGE2-CLEAN",
"path": "manifest/stage2_release.json",
"sha256": parent_sha,
"schema_id": "stage2_release.v2",
"binding_status": "BOUND",
},
"expected_release_sha256": parent_sha,
"agent_script_sha256": sha256_bytes(_require_file(agent)),
"canonical_code_sha256": sha256_bytes(_require_file(code)),
"mcp_server_id": "code-executor",
"tool_name": "run_code",
"language": "python",
"network": "agent-network",
"timeout_seconds": 300,
"runtime_image_digest": "PENDING_SEQUENTIAL_BIND",
"runtime_image_status": "PENDING_BACKEND_EVIDENCE",
"dependency_lock": {
"requirements": "httpx==0.28.1",
"requirements_sha256": sha256_bytes(b"httpx==0.28.1"),
"lock_status": "LIVE_BACKEND_PENDING",
},
"localdocs_contract": {
"endpoint": "http://mcp-localdocs:8012/mcp",
"user_id_template": "{{__user_hash__}}",
"workspace_id_template": "{{__workspace_hash__}}",
"tool_allowlist": ["read_binary_doc", "write_binary_file"],
"fixed_request_path": "stage2_control/s2_40_request.json",
"read_path_allowlist": [
"stage2_control/s2_40_request.json",
"Default_Agent/Stage_2_Clean/manifest/stage2_release.json",
"Default_Agent/Stage_2_Clean/manifest/module_manifest.json",
"Default_Agent/Stage_2_Clean/manifest/stage2_deterministic_admission_receipt.json",
"Default_Agent/Stage_2_Clean/manifest/s2_40_inline_code_receipt.json",
"Default_Agent/Stage_2_Clean/agent_scripts/Stage_2_S2_40.yml",
"Default_Agent/Stage_2_Clean/deployment/stage2_code_executor_binding.yml",
"Default_Agent/Stage_2_Clean/schemas/ingress.schema.json",
"Default_Agent/Stage_2_Clean/schemas/context.schema.json",
"Default_Agent/Stage_2_Clean/schemas/s2_10.schema.json",
"Default_Agent/Stage_2_Clean/schemas/domain_verdict.schema.json",
"Default_Agent/Stage_2_Clean/schemas/relief_plan.schema.json",
"Default_Agent/Stage_2_Clean/schemas/binding_retrieval.schema.json",
"Default_Agent/Stage_2_Clean/schemas/calculation.schema.json",
"Default_Agent/Stage_2_Clean/schemas/draft_atoms.schema.json",
"Default_Agent/Stage_2_Clean/schemas/review_status.schema.json",
"Default_Agent/Stage_2_Clean/schemas/package.schema.json",
"Default_Agent/Stage_2_Clean/registry/review/review_policy_registry.yml",
"Default_Agent/Stage_2_Clean/renderers/<renderer_id>.yml",
"stage2_runs/by-binding/<run_binding_digest>/<barrier-enumerated-input-path>",
"stage2_runs/by-binding/<run_binding_digest>/review/receipts/<receipt_id>.json",
"stage2_runs/by-binding/<run_binding_digest>/control/run_status.json",
],
"write_root_rule": "stage2_runs/by-binding/<run_binding_digest>/",
},
"external_mcp_contract": None,
"egress_profile_id": "S2_40_LOCALDOCS_ONLY_V1",
"egress_profile_status": "PENDING_LIVE_VERIFICATION",
"downstream_handoff_owner": None,
"live_admission_status": "PENDING_SECRET_BINDING",
"legacy_fallbacks": [],
}
def shared_executor_outputs() -> dict[Path, bytes]: def shared_executor_outputs() -> dict[Path, bytes]:
if yaml is None: if yaml is None:
raise BuildError("PYYAML_REQUIRED", "shared executor build") raise BuildError("PYYAML_REQUIRED", "shared executor build")
@@ -943,9 +1038,22 @@ def shared_executor_outputs() -> dict[Path, bytes]:
"receipt": ROOT / "manifest" / "s2_20_inline_code_receipt.json", "receipt": ROOT / "manifest" / "s2_20_inline_code_receipt.json",
"code": ROOT / "runtime" / "s2_20_reduce.py", "code": ROOT / "runtime" / "s2_20_reduce.py",
}, },
"S2_40": {
"agent": ROOT / "agent_scripts" / "Stage_2_S2_40.yml",
"workflow": ROOT / "workflows" / "S2_40_final_review_render_and_commit.yml",
"receipt": ROOT / "manifest" / "s2_40_inline_code_receipt.json",
"code": ROOT / "runtime" / "s2_40_commit.py",
},
} }
if {row.get("stage_id") for row in rows if isinstance(row, dict)} != set(stage_sources): observed_stage_ids = [row.get("stage_id") for row in rows if isinstance(row, dict)]
if len(observed_stage_ids) != len(rows) or len(observed_stage_ids) != len(set(observed_stage_ids)):
raise BuildError("SHARED_STAGE_BINDING_SET", repr(rows)) raise BuildError("SHARED_STAGE_BINDING_SET", repr(rows))
if not set(observed_stage_ids).issubset(set(stage_sources)) or not {"S2_00", "S2_20"}.issubset(observed_stage_ids):
raise BuildError("SHARED_STAGE_BINDING_SET", repr(rows))
rows = [row for row in rows if isinstance(row, dict) and row.get("stage_id") != "S2_40"]
rows.append(_s2_40_stage_binding(parent_sha))
rows.sort(key=lambda row: str(row["stage_id"]))
wrapper["stage_bindings"] = rows
for row in rows: for row in rows:
if not isinstance(row, dict): if not isinstance(row, dict):
raise BuildError("SHARED_STAGE_BINDING_ROW", repr(row)) raise BuildError("SHARED_STAGE_BINDING_ROW", repr(row))
@@ -1068,7 +1176,7 @@ def shared_executor_outputs() -> dict[Path, bytes]:
"schema_version": "stage2_deterministic_admission_receipt.v1", "schema_version": "stage2_deterministic_admission_receipt.v1",
"parent_release_sha256": parent_sha, "parent_release_sha256": parent_sha,
"executor_binding_sha256": sha256_bytes(shared_raw), "executor_binding_sha256": sha256_bytes(shared_raw),
"present_deterministic_stage_ids": ["S2_00", "S2_20"], "present_deterministic_stage_ids": ["S2_00", "S2_20", "S2_40"],
"stage_receipts": [row["inline_code_receipt_ref"] for row in rows], "stage_receipts": [row["inline_code_receipt_ref"] for row in rows],
"embedded_task_admissions": [ "embedded_task_admissions": [
{ {
@@ -59,9 +59,9 @@ EXPECTED_BUILD_ORDER = (
"S2_10_PROJECTION_PREREQUISITES", "S2_10_PROJECTION_PREREQUISITES",
"MODULE_MANIFEST", "MODULE_MANIFEST",
"PARENT_STAGE2_RELEASE", "PARENT_STAGE2_RELEASE",
"INJECT_PARENT_HASH_INTO_S2_30_S2_00_S2_20", "INJECT_PARENT_HASH_INTO_S2_30_S2_00_S2_20_S2_40",
"S2_30_AGENT_PROJECTION_PROMPT_CODE_RECEIPTS_BINDING", "S2_30_AGENT_PROJECTION_PROMPT_CODE_RECEIPTS_BINDING",
"S2_00_S2_20_PARENT_HASH_PROJECTIONS", "S2_00_S2_20_S2_40_PARENT_HASH_PROJECTIONS",
"SHARED_CODE_EXECUTOR_BINDING", "SHARED_CODE_EXECUTOR_BINDING",
"S2_10_AND_S2_30_CHILD_RELEASES_AND_RECEIPTS", "S2_10_AND_S2_30_CHILD_RELEASES_AND_RECEIPTS",
"CHECK_AND_REGRESSION", "CHECK_AND_REGRESSION",
@@ -153,6 +153,7 @@ PARENT_INDEPENDENT_PATHS = (
"tests/fixtures/s2_30/context_reference_envelope.json", "tests/fixtures/s2_30/context_reference_envelope.json",
"tests/fixtures/s2_30/technical_failure.json", "tests/fixtures/s2_30/technical_failure.json",
"tests/fixtures/s2_30/partial_write_publish_barrier.json", "tests/fixtures/s2_30/partial_write_publish_barrier.json",
"tests/fixtures/s2_30/persisted_handoff_chain.json",
"tests/fixtures/s2_30/regression_manifest.json", "tests/fixtures/s2_30/regression_manifest.json",
"manifest/s2_30_parent_member_paths.json", "manifest/s2_30_parent_member_paths.json",
) )
@@ -919,6 +920,100 @@ def _bound_asset_ref(
} }
def _s2_40_stage_binding(parent_sha: str) -> dict[str, Any]:
"""Build the detached, offline-only S2_40 deterministic-stage row."""
agent = ROOT / "agent_scripts" / "Stage_2_S2_40.yml"
workflow = ROOT / "workflows" / "S2_40_final_review_render_and_commit.yml"
receipt = ROOT / "manifest" / "s2_40_inline_code_receipt.json"
code = ROOT / "runtime" / "s2_40_commit.py"
return {
"stage_id": "S2_40",
"binding_id": "S2-BINDING-S2_40-CODE-EXECUTOR-V1",
"workflow_id": "S2_40",
"execution_class": "NON-LLM-DETERMINISTIC",
"active_runtime_authority": False,
"agent_script_ref": _bound_asset_ref(
"AGENT-S2_40-INLINE",
"agent_scripts/Stage_2_S2_40.yml",
agent,
"liti_agent_yaml.v1",
),
"workflow_contract_ref": _bound_asset_ref(
"WF-S2_40",
"workflows/S2_40_final_review_render_and_commit.yml",
workflow,
"stage2_s2_40_final_review_render_and_commit.v1",
),
"inline_code_receipt_ref": _bound_asset_ref(
"RECEIPT-S2_40-INLINE-CODE",
"manifest/s2_40_inline_code_receipt.json",
receipt,
"stage2_s2_40_inline_code_receipt.v1",
),
"stage2_release_ref": {
"asset_id": "RELEASE-STAGE2-CLEAN",
"path": "manifest/stage2_release.json",
"sha256": parent_sha,
"schema_id": "stage2_release.v2",
"binding_status": "BOUND",
},
"expected_release_sha256": parent_sha,
"agent_script_sha256": sha256_bytes(_require_file(agent)),
"canonical_code_sha256": sha256_bytes(_require_file(code)),
"mcp_server_id": "code-executor",
"tool_name": "run_code",
"language": "python",
"network": "agent-network",
"timeout_seconds": 300,
"runtime_image_digest": "PENDING_SEQUENTIAL_BIND",
"runtime_image_status": "PENDING_BACKEND_EVIDENCE",
"dependency_lock": {
"requirements": "httpx==0.28.1",
"requirements_sha256": sha256_bytes(b"httpx==0.28.1"),
"lock_status": "LIVE_BACKEND_PENDING",
},
"localdocs_contract": {
"endpoint": "http://mcp-localdocs:8012/mcp",
"user_id_template": "{{__user_hash__}}",
"workspace_id_template": "{{__workspace_hash__}}",
"tool_allowlist": ["read_binary_doc", "write_binary_file"],
"fixed_request_path": "stage2_control/s2_40_request.json",
"read_path_allowlist": [
"stage2_control/s2_40_request.json",
"Default_Agent/Stage_2_Clean/manifest/stage2_release.json",
"Default_Agent/Stage_2_Clean/manifest/module_manifest.json",
"Default_Agent/Stage_2_Clean/manifest/stage2_deterministic_admission_receipt.json",
"Default_Agent/Stage_2_Clean/manifest/s2_40_inline_code_receipt.json",
"Default_Agent/Stage_2_Clean/agent_scripts/Stage_2_S2_40.yml",
"Default_Agent/Stage_2_Clean/deployment/stage2_code_executor_binding.yml",
"Default_Agent/Stage_2_Clean/schemas/ingress.schema.json",
"Default_Agent/Stage_2_Clean/schemas/context.schema.json",
"Default_Agent/Stage_2_Clean/schemas/s2_10.schema.json",
"Default_Agent/Stage_2_Clean/schemas/domain_verdict.schema.json",
"Default_Agent/Stage_2_Clean/schemas/relief_plan.schema.json",
"Default_Agent/Stage_2_Clean/schemas/binding_retrieval.schema.json",
"Default_Agent/Stage_2_Clean/schemas/calculation.schema.json",
"Default_Agent/Stage_2_Clean/schemas/draft_atoms.schema.json",
"Default_Agent/Stage_2_Clean/schemas/review_status.schema.json",
"Default_Agent/Stage_2_Clean/schemas/package.schema.json",
"Default_Agent/Stage_2_Clean/registry/review/review_policy_registry.yml",
"Default_Agent/Stage_2_Clean/renderers/<renderer_id>.yml",
"stage2_runs/by-binding/<run_binding_digest>/<barrier-enumerated-input-path>",
"stage2_runs/by-binding/<run_binding_digest>/review/receipts/<receipt_id>.json",
"stage2_runs/by-binding/<run_binding_digest>/control/run_status.json",
],
"write_root_rule": "stage2_runs/by-binding/<run_binding_digest>/",
},
"external_mcp_contract": None,
"egress_profile_id": "S2_40_LOCALDOCS_ONLY_V1",
"egress_profile_status": "PENDING_LIVE_VERIFICATION",
"downstream_handoff_owner": None,
"live_admission_status": "PENDING_SECRET_BINDING",
"legacy_fallbacks": [],
}
def shared_executor_outputs() -> dict[Path, bytes]: def shared_executor_outputs() -> dict[Path, bytes]:
if yaml is None: if yaml is None:
raise BuildError("PYYAML_REQUIRED", "shared executor build") raise BuildError("PYYAML_REQUIRED", "shared executor build")
@@ -943,9 +1038,22 @@ def shared_executor_outputs() -> dict[Path, bytes]:
"receipt": ROOT / "manifest" / "s2_20_inline_code_receipt.json", "receipt": ROOT / "manifest" / "s2_20_inline_code_receipt.json",
"code": ROOT / "runtime" / "s2_20_reduce.py", "code": ROOT / "runtime" / "s2_20_reduce.py",
}, },
"S2_40": {
"agent": ROOT / "agent_scripts" / "Stage_2_S2_40.yml",
"workflow": ROOT / "workflows" / "S2_40_final_review_render_and_commit.yml",
"receipt": ROOT / "manifest" / "s2_40_inline_code_receipt.json",
"code": ROOT / "runtime" / "s2_40_commit.py",
},
} }
if {row.get("stage_id") for row in rows if isinstance(row, dict)} != set(stage_sources): observed_stage_ids = [row.get("stage_id") for row in rows if isinstance(row, dict)]
if len(observed_stage_ids) != len(rows) or len(observed_stage_ids) != len(set(observed_stage_ids)):
raise BuildError("SHARED_STAGE_BINDING_SET", repr(rows)) raise BuildError("SHARED_STAGE_BINDING_SET", repr(rows))
if not set(observed_stage_ids).issubset(set(stage_sources)) or not {"S2_00", "S2_20"}.issubset(observed_stage_ids):
raise BuildError("SHARED_STAGE_BINDING_SET", repr(rows))
rows = [row for row in rows if isinstance(row, dict) and row.get("stage_id") != "S2_40"]
rows.append(_s2_40_stage_binding(parent_sha))
rows.sort(key=lambda row: str(row["stage_id"]))
wrapper["stage_bindings"] = rows
for row in rows: for row in rows:
if not isinstance(row, dict): if not isinstance(row, dict):
raise BuildError("SHARED_STAGE_BINDING_ROW", repr(row)) raise BuildError("SHARED_STAGE_BINDING_ROW", repr(row))
@@ -1068,7 +1176,7 @@ def shared_executor_outputs() -> dict[Path, bytes]:
"schema_version": "stage2_deterministic_admission_receipt.v1", "schema_version": "stage2_deterministic_admission_receipt.v1",
"parent_release_sha256": parent_sha, "parent_release_sha256": parent_sha,
"executor_binding_sha256": sha256_bytes(shared_raw), "executor_binding_sha256": sha256_bytes(shared_raw),
"present_deterministic_stage_ids": ["S2_00", "S2_20"], "present_deterministic_stage_ids": ["S2_00", "S2_20", "S2_40"],
"stage_receipts": [row["inline_code_receipt_ref"] for row in rows], "stage_receipts": [row["inline_code_receipt_ref"] for row in rows],
"embedded_task_admissions": [ "embedded_task_admissions": [
{ {
@@ -0,0 +1,894 @@
#!/usr/bin/env python3
"""Build the version-free S2_40 Agent projection from its sole authoring YAML.
This is an offline build tool. It never executes a matter, imports project
runtime code, rewrites the authoring YAML, or invokes a subprocess. The YAML
parser-returned ``parameters.code`` string is encoded directly as UTF-8; no
dedent, newline normalization, or source transformation is permitted.
"""
from __future__ import annotations
import argparse
import ast
import hashlib
import json
import os
from pathlib import Path
import re
import sys
import tempfile
from typing import Any, Iterable, Mapping
try:
import yaml
except ImportError: # pragma: no cover - exercised only on an incomplete build host
yaml = None # type: ignore[assignment]
DEPLOYMENT_ROOT = Path(__file__).resolve().parents[1]
MAIN_WORKING_DIRECTORY = DEPLOYMENT_ROOT.parent.parent
AUTHORING_PATH = MAIN_WORKING_DIRECTORY / "Stage_2_S2_40.yml"
PROJECTION_PATH = DEPLOYMENT_ROOT / "agent_scripts" / "Stage_2_S2_40.yml"
MIRROR_PY_PATH = DEPLOYMENT_ROOT / "runtime" / "s2_40_commit.py"
MIRROR_TXT_PATH = DEPLOYMENT_ROOT / "runtime" / "s2_40_commit.txt"
RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_40_inline_code_receipt.json"
EXPECTED_TASK_NAME = "Task_S2_40_deterministic_finalizer"
EXPECTED_AGENT_NAME = "Stage_2_S2_40"
EXPECTED_AGENT_VERSION = "1.0.0"
EXPECTED_PARAMETERS = {
"language": "python",
"requirements": "httpx==0.28.1",
"network": "agent-network",
"timeout": 300,
}
EXPECTED_LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp"
EXPECTED_CODE_EXECUTOR_URL = "https://code-executor.mcp.eroomai.com/mcp"
REQUIRED_CODE_TOKENS = (
EXPECTED_LOCALDOCS_URL,
"{{__user_hash__}}",
"{{__workspace_hash__}}",
"read_binary_doc",
"write_binary_file",
"stage2_control/s2_40_request.json",
"run_status.json",
"reduce_and_render",
"invariant_results",
"candidate_material",
"publish_candidate",
"validate_review_receipts",
"final_status",
)
REQUIRED_CODE_TOKEN_ALTERNATIVES = (
("EXPECTED_STAGE2_RELEASE_SHA256",),
)
ALLOWED_NON_STDLIB_IMPORTS = frozenset({"httpx"})
FORBIDDEN_IMPORT_ROOTS = frozenset(
{
"ftplib",
"http",
"importlib",
"smtplib",
"socket",
"subprocess",
"telnetlib",
"urllib",
"xmlrpc",
}
)
FORBIDDEN_CALL_NAMES = frozenset({"__import__", "compile", "eval", "exec", "open"})
FORBIDDEN_ATTRIBUTE_CALLS = frozenset(
{
("os", "popen"),
("os", "spawnl"),
("os", "spawnle"),
("os", "spawnlp"),
("os", "spawnlpe"),
("os", "spawnv"),
("os", "spawnve"),
("os", "spawnvp"),
("os", "spawnvpe"),
("os", "system"),
}
)
PLACEHOLDER_COMMENT_RE = re.compile(
r"(?im)^\s*#\s*(?:TODO|FIXME|TBD|PLACEHOLDER|OMITTED\s+BODY|IMPLEMENT\s+ME)\b"
)
PLAINTEXT_SECRET_RES = (
re.compile(r"(?i)\bAuthorization\s*:\s*Bearer\s+\S+"),
re.compile(r"(?i)\bBearer\s+[A-Za-z0-9+/=_-]{12,}"),
re.compile(
r"(?i)\b(?:MCP_API_KEY|API_KEY|ACCESS_TOKEN|AUTH_TOKEN|CLIENT_SECRET)\s*=\s*['\"][^'\"]+['\"]"
),
)
URL_RE = re.compile(r"https?://[^\s'\"]+")
PYTHON_SOURCE_REF_RE = re.compile(r"(?i)(?:^|[/\\])[^\r\n'\"]+\.py(?:$|[?#])")
ALLOWED_IDENTIFIER_URL_PREFIXES = ("https://schemas.liti-agent.local/",)
HTTP_NETWORK_METHODS = frozenset({"delete", "get", "head", "options", "patch", "post", "put", "request", "stream"})
HTTP_CLIENT_FACTORIES = frozenset({"Client", "AsyncClient"})
class ProjectionError(RuntimeError):
"""A controlled build failure with a stable reason code."""
def __init__(self, code: str, detail: str) -> None:
super().__init__(f"{code}: {detail}")
self.code = code
self.detail = detail
class AuthoringMissingError(ProjectionError):
def __init__(self, path: Path) -> None:
super().__init__("AUTHORING_YAML_MISSING", path.as_posix())
if yaml is not None:
class UniqueKeySafeLoader(yaml.SafeLoader):
"""SafeLoader variant that rejects duplicate mapping keys recursively."""
def construct_mapping(self, node: Any, deep: bool = False) -> dict[Any, Any]:
if not isinstance(node, yaml.MappingNode):
raise ProjectionError("YAML_MAPPING_REQUIRED", repr(node)[:200])
self.flatten_mapping(node)
result: dict[Any, Any] = {}
for key_node, value_node in node.value:
key = self.construct_object(key_node, deep=deep)
try:
duplicate = key in result
except TypeError as exc:
raise ProjectionError("YAML_UNHASHABLE_KEY", repr(key)[:200]) from exc
if duplicate:
mark = getattr(key_node, "start_mark", None)
location = f" line {mark.line + 1}" if mark is not None else ""
raise ProjectionError("YAML_DUPLICATE_KEY", f"{key!r}{location}")
result[key] = self.construct_object(value_node, deep=deep)
return result
else: # pragma: no cover - type placeholder for hosts without PyYAML
class UniqueKeySafeLoader: # type: ignore[no-redef]
pass
def sha256_bytes(value: bytes) -> str:
return hashlib.sha256(value).hexdigest()
def canonical_json_bytes(value: Any) -> bytes:
return (
json.dumps(
value,
ensure_ascii=False,
allow_nan=False,
sort_keys=True,
separators=(",", ":"),
)
+ "\n"
).encode("utf-8")
def _logical_path(path: Path) -> str:
try:
return path.resolve(strict=False).relative_to(
MAIN_WORKING_DIRECTORY.resolve(strict=False)
).as_posix()
except ValueError:
return path.as_posix()
def parse_authoring_bytes(raw: bytes, *, source: str = "<authoring>") -> dict[str, Any]:
if yaml is None:
raise ProjectionError("PYYAML_REQUIRED", "install PyYAML on the offline build host")
try:
text = raw.decode("utf-8")
except UnicodeDecodeError as exc:
raise ProjectionError("AUTHORING_UTF8_REQUIRED", f"{source}: {exc}") from exc
if text.startswith("\ufeff"):
raise ProjectionError("AUTHORING_UTF8_BOM_FORBIDDEN", source)
for pattern in PLAINTEXT_SECRET_RES:
if pattern.search(text):
raise ProjectionError("AUTHORING_PLAINTEXT_SECRET", pattern.pattern)
try:
loaded = yaml.load(text, Loader=UniqueKeySafeLoader)
except ProjectionError:
raise
except yaml.YAMLError as exc:
raise ProjectionError("AUTHORING_YAML_INVALID", f"{source}: {exc}") from exc
if not isinstance(loaded, dict):
raise ProjectionError("AUTHORING_ROOT_OBJECT_REQUIRED", source)
return loaded
def load_authoring(path: Path | None = None) -> tuple[bytes, dict[str, Any]]:
path = AUTHORING_PATH if path is None else path
if not path.is_file():
raise AuthoringMissingError(path)
if path.is_symlink():
raise ProjectionError("AUTHORING_SYMLINK_FORBIDDEN", path.as_posix())
raw = path.read_bytes()
return raw, parse_authoring_bytes(raw, source=path.as_posix())
def _require_mapping(value: Any, code: str) -> dict[str, Any]:
if not isinstance(value, dict):
raise ProjectionError(code, repr(value)[:200])
return value
def _require_list(value: Any, code: str) -> list[Any]:
if not isinstance(value, list):
raise ProjectionError(code, repr(value)[:200])
return value
def _find_forbidden_model_fields(value: Any, pointer: str = "") -> list[str]:
forbidden = {"llm_provider", "llm_model", "llm_reasoning", "llm_verbosity", "prompt"}
findings: list[str] = []
if isinstance(value, dict):
for key, child in value.items():
child_pointer = f"{pointer}/{key}"
if key in forbidden:
findings.append(child_pointer)
findings.extend(_find_forbidden_model_fields(child, child_pointer))
elif isinstance(value, list):
for index, child in enumerate(value):
findings.extend(_find_forbidden_model_fields(child, f"{pointer}/{index}"))
return findings
def extract_run_code_task(document: Mapping[str, Any]) -> tuple[dict[str, Any], dict[str, Any]]:
agent = _require_mapping(document.get("Agent"), "AGENT_OBJECT_REQUIRED")
if agent.get("name") != EXPECTED_AGENT_NAME or agent.get("version") != EXPECTED_AGENT_VERSION:
raise ProjectionError(
"AGENT_IDENTITY_MISMATCH",
f"expected {EXPECTED_AGENT_NAME}/{EXPECTED_AGENT_VERSION}",
)
forbidden_model_fields = _find_forbidden_model_fields(agent)
if forbidden_model_fields:
raise ProjectionError("LLM_OR_PROMPT_FIELD_FORBIDDEN", repr(forbidden_model_fields))
stages = _require_list(agent.get("Stages"), "STAGES_ARRAY_REQUIRED")
if len(stages) != 1:
raise ProjectionError("EXACTLY_ONE_STAGE_REQUIRED", str(len(stages)))
stage = _require_mapping(stages[0], "STAGE_OBJECT_REQUIRED")
if stage.get("name") != "S2_40":
raise ProjectionError("S2_40_STAGE_NAME_REQUIRED", repr(stage.get("name")))
if stage.get("skip_confirm") is not True:
raise ProjectionError(
"S2_40_SKIP_CONFIRM_TRUE_REQUIRED",
repr(stage.get("skip_confirm")),
)
for forbidden in ("llm_provider", "llm_model", "llm_reasoning", "llm_verbosity"):
if forbidden in stage:
raise ProjectionError("MODEL_FIELD_FORBIDDEN", forbidden)
servers = _require_mapping(
_require_mapping(stage.get("tools"), "TOOLS_OBJECT_REQUIRED").get("mcpServers"),
"MCP_SERVERS_OBJECT_REQUIRED",
)
if set(servers) != {"localdocs", "code-executor"}:
raise ProjectionError("MCP_SERVER_SET_MISMATCH", repr(sorted(servers)))
localdocs = _require_mapping(servers.get("localdocs"), "LOCALDOCS_SERVER_REQUIRED")
code_executor = _require_mapping(
servers.get("code-executor"), "CODE_EXECUTOR_SERVER_REQUIRED"
)
if localdocs.get("type") != "streamable-http" or localdocs.get("url") != EXPECTED_LOCALDOCS_URL:
raise ProjectionError("LOCALDOCS_SERVER_BINDING_INVALID", repr(localdocs))
if (
code_executor.get("type") != "streamable-http"
or code_executor.get("url") != EXPECTED_CODE_EXECUTOR_URL
):
raise ProjectionError("CODE_EXECUTOR_SERVER_BINDING_INVALID", repr(code_executor))
if "headers" in code_executor:
raise ProjectionError(
"PLAINTEXT_OR_INLINE_AUTH_HEADER_FORBIDDEN",
"authentication must be injected or pre-registered by the backend",
)
tasks = _require_list(stage.get("tasks"), "TASKS_ARRAY_REQUIRED")
if len(tasks) != 1:
raise ProjectionError("EXACTLY_ONE_TASK_REQUIRED", str(len(tasks)))
task = _require_mapping(tasks[0], "TASK_OBJECT_REQUIRED")
run_code_tasks = [
row
for row in tasks
if isinstance(row, dict)
and row.get("mcp") == "code-executor"
and row.get("tool_name") == "run_code"
]
if len(run_code_tasks) != 1:
raise ProjectionError("EXACTLY_ONE_RUN_CODE_REQUIRED", str(len(run_code_tasks)))
if task.get("task_name") != EXPECTED_TASK_NAME:
raise ProjectionError("TASK_NAME_MISMATCH", repr(task.get("task_name")))
parameters = _require_mapping(task.get("parameters"), "TASK_PARAMETERS_REQUIRED")
expected_parameter_keys = set(EXPECTED_PARAMETERS) | {"code"}
if set(parameters) != expected_parameter_keys:
raise ProjectionError(
"RUN_CODE_PARAMETER_SET_MISMATCH",
repr(sorted(parameters)),
)
for key, expected in EXPECTED_PARAMETERS.items():
if parameters.get(key) != expected:
raise ProjectionError(
"RUN_CODE_PARAMETER_MISMATCH",
f"{key}: expected {expected!r}, observed {parameters.get(key)!r}",
)
code = parameters.get("code")
if not isinstance(code, str) or not code:
raise ProjectionError("INLINE_CODE_REQUIRED", repr(code)[:100])
if code.endswith(("\n", "\r")):
raise ProjectionError(
"INLINE_CODE_TRAILING_NEWLINE_FORBIDDEN",
"authoring YAML must use code: |- so parser-returned code has no trailing newline",
)
procedure = _require_mapping(stage.get("task_procedure"), "TASK_PROCEDURE_REQUIRED")
expected_procedure = {
"IN": {"nexts": [EXPECTED_TASK_NAME], "wait_until": []},
EXPECTED_TASK_NAME: {"nexts": ["OUT"], "wait_until": ["IN"]},
"OUT": {"nexts": [], "wait_until": [EXPECTED_TASK_NAME]},
}
if procedure != expected_procedure:
raise ProjectionError("TASK_PROCEDURE_MISMATCH", repr(procedure)[:500])
if stage.get("prevs") != [] or stage.get("nexts") != []:
raise ProjectionError("STANDALONE_STAGE_EDGES_MUST_BE_EMPTY", repr(stage))
return stage, task
def _import_root(name: str | None) -> str:
return (name or "").split(".", 1)[0]
def _attribute_pair(node: ast.Attribute) -> tuple[str, str] | None:
if isinstance(node.value, ast.Name):
return node.value.id, node.attr
return None
def _is_http_client_receiver(
node: ast.expr,
derived_client_names: set[str] | None = None,
) -> bool:
if isinstance(node, ast.Name):
return node.id in {"client", "http_client", "httpx"} | (derived_client_names or set())
if isinstance(node, ast.Attribute):
return (
isinstance(node.value, ast.Name)
and node.value.id == "self"
and node.attr in {"client", "http_client"}
)
return False
def _is_direct_localdocs_post(call: ast.Call) -> bool:
if not isinstance(call.func, ast.Attribute) or call.func.attr != "post":
return False
receiver = call.func.value
if not (
isinstance(receiver, ast.Attribute)
and isinstance(receiver.value, ast.Name)
and receiver.value.id == "self"
and receiver.attr == "client"
):
return False
return _is_localdocs_endpoint(_network_endpoint(call) or ast.Constant(value=None))
def _network_endpoint(call: ast.Call) -> ast.expr | None:
"""Return a statically identifiable httpx/client endpoint expression."""
if not isinstance(call.func, ast.Attribute) or call.func.attr not in HTTP_NETWORK_METHODS:
return None
if not _is_http_client_receiver(call.func.value):
return None
for keyword in call.keywords:
if keyword.arg == "url":
return keyword.value
index = 1 if call.func.attr == "request" else 0
return call.args[index] if len(call.args) > index else ast.Constant(value=None)
def _is_localdocs_endpoint(node: ast.expr) -> bool:
return (
isinstance(node, ast.Name)
and node.id == "LOCALDOCS_URL"
or isinstance(node, ast.Constant)
and node.value == EXPECTED_LOCALDOCS_URL
or isinstance(node, ast.Attribute)
and isinstance(node.value, ast.Name)
and node.value.id == "self"
and node.attr == "endpoint"
)
def validate_inline_code(code: str) -> dict[str, Any]:
code_bytes = code.encode("utf-8")
try:
compile(code, "<Stage_2_S2_40.parameters.code>", "exec", dont_inherit=True)
tree = ast.parse(code, filename="<Stage_2_S2_40.parameters.code>", mode="exec")
except (SyntaxError, ValueError, UnicodeError) as exc:
raise ProjectionError("INLINE_CODE_COMPILE_FAILED", str(exc)) from exc
missing_tokens = [token for token in REQUIRED_CODE_TOKENS if token not in code]
missing_tokens.extend(
"|".join(alternatives)
for alternatives in REQUIRED_CODE_TOKEN_ALTERNATIVES
if not any(token in code for token in alternatives)
)
if missing_tokens:
raise ProjectionError("INLINE_CODE_REQUIRED_TOKEN_MISSING", ",".join(missing_tokens))
if PLACEHOLDER_COMMENT_RE.search(code):
raise ProjectionError("INLINE_CODE_PLACEHOLDER_COMMENT", "TODO/FIXME/TBD placeholder")
for pattern in PLAINTEXT_SECRET_RES:
if pattern.search(code):
raise ProjectionError("INLINE_CODE_PLAINTEXT_SECRET", pattern.pattern)
imports: set[str] = set()
forbidden_nodes: list[str] = []
external_urls: set[str] = set()
forbidden_network_endpoints: set[str] = set()
project_source_refs: set[str] = set()
import_aliases: dict[str, str] = {}
forbidden_callable_aliases: set[str] = set()
mcp_client_endpoint_calls: list[ast.expr] = []
self_endpoint_assignments: list[ast.expr] = []
for candidate in ast.walk(tree):
if isinstance(candidate, ast.Import):
for alias in candidate.names:
import_aliases[alias.asname or _import_root(alias.name)] = _import_root(alias.name)
elif isinstance(candidate, ast.ImportFrom) and not candidate.level:
root = _import_root(candidate.module)
for alias in candidate.names:
local_name = alias.asname or alias.name
if root == "httpx" and (
alias.name in HTTP_NETWORK_METHODS or alias.name in HTTP_CLIENT_FACTORIES
):
forbidden_callable_aliases.add(local_name)
if root == "os" and (
alias.name in {name for module, name in FORBIDDEN_ATTRIBUTE_CALLS if module == "os"}
or alias.name.startswith("exec")
):
forbidden_callable_aliases.add(local_name)
if root == "builtins" and alias.name in FORBIDDEN_CALL_NAMES:
forbidden_callable_aliases.add(local_name)
derived_client_names: set[str] = set()
release_constants: list[str] = []
for candidate in ast.walk(tree):
if not isinstance(candidate, (ast.Assign, ast.AnnAssign)):
continue
value = candidate.value
targets = candidate.targets if isinstance(candidate, ast.Assign) else [candidate.target]
target_names = {target.id for target in targets if isinstance(target, ast.Name)}
if (
"EXPECTED_STAGE2_RELEASE_SHA256" in target_names
and isinstance(value, ast.Constant)
and isinstance(value.value, str)
):
release_constants.append(value.value)
if (
isinstance(value, ast.Call)
and isinstance(value.func, ast.Attribute)
and isinstance(value.func.value, ast.Name)
and import_aliases.get(value.func.value.id, value.func.value.id) == "httpx"
and value.func.attr in HTTP_CLIENT_FACTORIES
):
derived_client_names.update(target_names)
if isinstance(value, ast.Name) and (
value.id in FORBIDDEN_CALL_NAMES or value.id in forbidden_callable_aliases
):
forbidden_callable_aliases.update(target_names)
if isinstance(value, ast.Attribute) and isinstance(value.value, ast.Name):
module = import_aliases.get(value.value.id, value.value.id)
if (module, value.attr) in FORBIDDEN_ATTRIBUTE_CALLS or (
module == "os" and value.attr.startswith("exec")
):
forbidden_callable_aliases.update(target_names)
if module == "httpx" and value.attr in HTTP_NETWORK_METHODS:
forbidden_callable_aliases.update(target_names)
for node in ast.walk(tree):
if isinstance(node, ast.Import):
imports.update(_import_root(alias.name) for alias in node.names)
elif isinstance(node, ast.ImportFrom):
if node.level:
forbidden_nodes.append(f"relative-import:{node.module or ''}")
imports.add(_import_root(node.module))
root = _import_root(node.module)
for alias in node.names:
local_name = alias.asname or alias.name
if local_name in forbidden_callable_aliases:
forbidden_nodes.append(f"forbidden-import-alias:{root}.{alias.name}")
elif isinstance(node, ast.Pass):
forbidden_nodes.append("Pass")
elif isinstance(node, ast.Expr) and isinstance(node.value, ast.Constant):
if node.value.value is Ellipsis:
forbidden_nodes.append("Ellipsis-expression")
elif isinstance(node, (ast.Assign, ast.AnnAssign)):
assignment_targets = node.targets if isinstance(node, ast.Assign) else [node.target]
if any(
isinstance(target, ast.Attribute)
and isinstance(target.value, ast.Name)
and target.value.id == "self"
and target.attr == "endpoint"
for target in assignment_targets
):
self_endpoint_assignments.append(node.value)
if isinstance(node.value, ast.Constant) and node.value.value is Ellipsis:
forbidden_nodes.append("Ellipsis-assignment")
if (
isinstance(node.value, ast.Attribute)
and node.value.attr in HTTP_NETWORK_METHODS
and _is_http_client_receiver(node.value.value, derived_client_names)
):
forbidden_nodes.append(f"network-method-alias:{node.value.attr}")
elif isinstance(node, ast.Constant):
if isinstance(node.value, str):
for match in URL_RE.findall(node.value):
normalized = match.rstrip(".,);]")
if (
normalized != EXPECTED_LOCALDOCS_URL
and not normalized.startswith(ALLOWED_IDENTIFIER_URL_PREFIXES)
):
external_urls.add(normalized)
if PYTHON_SOURCE_REF_RE.search(node.value.strip()):
project_source_refs.add(node.value[:200])
if node.value.strip().lower() in {
"todo",
"tbd",
"placeholder",
"omitted",
"implement me",
"...",
}:
forbidden_nodes.append(f"placeholder-string:{node.value!r}")
elif isinstance(node, ast.Call):
if isinstance(node.func, ast.Name) and node.func.id == "McpClient":
mcp_client_endpoint_calls.append(
node.args[0] if node.args else ast.Constant(value=None)
)
if (
isinstance(node.func, ast.Attribute)
and node.func.attr in HTTP_NETWORK_METHODS
and _is_http_client_receiver(node.func.value, derived_client_names)
):
if not _is_direct_localdocs_post(node):
forbidden_network_endpoints.add(ast.unparse(node.func)[:200])
if (
isinstance(node.func, ast.Attribute)
and node.func.attr in HTTP_NETWORK_METHODS
and isinstance(node.func.value, ast.Call)
and isinstance(node.func.value.func, ast.Attribute)
and isinstance(node.func.value.func.value, ast.Name)
and import_aliases.get(
node.func.value.func.value.id,
node.func.value.func.value.id,
) == "httpx"
and node.func.value.func.attr in HTTP_CLIENT_FACTORIES
):
forbidden_network_endpoints.add(ast.unparse(node.func)[:200])
if (
isinstance(node.func, ast.Name)
and node.func.id == "getattr"
and len(node.args) >= 2
and isinstance(node.args[1], ast.Constant)
and node.args[1].value in HTTP_NETWORK_METHODS
):
forbidden_nodes.append(f"dynamic-network-method:{node.args[1].value}")
if isinstance(node.func, ast.Name) and (
node.func.id in FORBIDDEN_CALL_NAMES
or node.func.id in forbidden_callable_aliases
):
forbidden_nodes.append(f"call:{node.func.id}")
elif isinstance(node.func, ast.Attribute):
pair = _attribute_pair(node.func)
if pair is not None:
module = import_aliases.get(pair[0], pair[0])
if (module, pair[1]) in FORBIDDEN_ATTRIBUTE_CALLS or (
module == "os" and pair[1].startswith("exec")
):
forbidden_nodes.append(f"call:{module}.{pair[1]}")
elif isinstance(node, ast.Raise):
target = node.exc
if isinstance(target, ast.Call):
target = target.func
if isinstance(target, ast.Name) and target.id == "NotImplementedError":
forbidden_nodes.append("raise:NotImplementedError")
imports.discard("")
disallowed_imports = sorted(
root
for root in imports
if root in FORBIDDEN_IMPORT_ROOTS
or (root not in sys.stdlib_module_names and root not in ALLOWED_NON_STDLIB_IMPORTS)
)
if disallowed_imports:
raise ProjectionError("INLINE_CODE_IMPORT_FORBIDDEN", ",".join(disallowed_imports))
if forbidden_nodes:
raise ProjectionError("INLINE_CODE_DYNAMIC_OR_PLACEHOLDER_FORBIDDEN", ",".join(forbidden_nodes))
if external_urls:
raise ProjectionError("INLINE_CODE_EXTERNAL_URL_FORBIDDEN", ",".join(sorted(external_urls)))
if forbidden_network_endpoints:
raise ProjectionError(
"INLINE_CODE_NETWORK_ENDPOINT_FORBIDDEN",
",".join(sorted(forbidden_network_endpoints)),
)
if project_source_refs:
raise ProjectionError(
"INLINE_CODE_EXTERNAL_PY_SOURCE_REF_FORBIDDEN", ",".join(sorted(project_source_refs))
)
if (
len(self_endpoint_assignments) != 1
or not isinstance(self_endpoint_assignments[0], ast.Name)
or self_endpoint_assignments[0].id != "endpoint"
or not mcp_client_endpoint_calls
or any(not _is_localdocs_endpoint(endpoint) for endpoint in mcp_client_endpoint_calls)
):
raise ProjectionError(
"INLINE_CODE_LOCALDOCS_ENDPOINT_FLOW_INVALID",
f"assignments={len(self_endpoint_assignments)};constructors={len(mcp_client_endpoint_calls)}",
)
if len(release_constants) != 1 or not re.fullmatch(r"[a-f0-9]{64}", release_constants[0]):
raise ProjectionError(
"EXPECTED_PARENT_RELEASE_CONSTANT_EXACT_ONE_REQUIRED",
repr(release_constants),
)
return {
"code_sha256": sha256_bytes(code_bytes),
"code_size_bytes": len(code_bytes),
"compile_status": "PASS",
"ast_status": "PASS",
"imports": sorted(imports),
"forbidden_import_count": 0,
"forbidden_dynamic_call_count": 0,
"external_url_count": 0,
"placeholder_count": 0,
"plaintext_secret_count": 0,
"external_python_source_ref_count": 0,
"expected_parent_stage2_release_sha256": release_constants[0],
}
def _canonical_task_semantics(document: Mapping[str, Any], stage: Mapping[str, Any], task: Mapping[str, Any]) -> dict[str, Any]:
agent = _require_mapping(document.get("Agent"), "AGENT_OBJECT_REQUIRED")
servers = _require_mapping(
_require_mapping(stage.get("tools"), "TOOLS_OBJECT_REQUIRED").get("mcpServers"),
"MCP_SERVERS_OBJECT_REQUIRED",
)
parameters = _require_mapping(task.get("parameters"), "TASK_PARAMETERS_REQUIRED")
return {
"agent": {"name": agent.get("name"), "version": agent.get("version")},
"stage": {
"name": stage.get("name"),
"prevs": stage.get("prevs"),
"nexts": stage.get("nexts"),
},
"mcp_servers": {
name: {"type": value.get("type"), "url": value.get("url")}
for name, value in sorted(servers.items())
if isinstance(value, dict)
},
"task": {
"task_name": task.get("task_name"),
"mcp": task.get("mcp"),
"tool_name": task.get("tool_name"),
"parameters": {
key: parameters.get(key)
for key in ("language", "requirements", "network", "timeout")
},
"code_sha256": sha256_bytes(parameters["code"].encode("utf-8")),
},
"task_procedure": stage.get("task_procedure"),
}
def expected_outputs(
authoring_raw: bytes,
document: Mapping[str, Any],
) -> tuple[dict[Path, bytes], dict[str, Any]]:
stage, task = extract_run_code_task(document)
parameters = _require_mapping(task.get("parameters"), "TASK_PARAMETERS_REQUIRED")
code = parameters["code"]
validation = validate_inline_code(code)
code_bytes = code.encode("utf-8")
semantics = _canonical_task_semantics(document, stage, task)
semantics_sha256 = sha256_bytes(canonical_json_bytes(semantics))
receipt = {
"schema_version": "stage2_s2_40_inline_code_receipt.v1",
"workflow_id": "S2_40",
"build_kind": "OFFLINE_AUTHORING_PROJECTION",
"source_of_truth": _logical_path(AUTHORING_PATH),
"authoring_rewritten": False,
"authoring": {
"path": _logical_path(AUTHORING_PATH),
"sha256": sha256_bytes(authoring_raw),
"size_bytes": len(authoring_raw),
"unique_key_parse": "PASS",
},
"deployment_projection": {
"path": _logical_path(PROJECTION_PATH),
"sha256": sha256_bytes(authoring_raw),
"size_bytes": len(authoring_raw),
"byte_identical_to_authoring": True,
"canonical_task_semantics_sha256": semantics_sha256,
},
"canonical_code": {
"yaml_pointer": "/Agent/Stages/0/tasks/0/parameters/code",
"encoding": "UTF-8",
"extraction_transform": "NONE",
**validation,
},
"full_code_mirrors": [
{
"path": _logical_path(MIRROR_PY_PATH),
"sha256": validation["code_sha256"],
"size_bytes": len(code_bytes),
"byte_identical_to_canonical_code": True,
},
{
"path": _logical_path(MIRROR_TXT_PATH),
"sha256": validation["code_sha256"],
"size_bytes": len(code_bytes),
"byte_identical_to_canonical_code": True,
},
],
"task_contract": {
**semantics,
"exactly_one_stage": True,
"exactly_one_task": True,
"exactly_one_code_executor_run_code": True,
"authoring_rewritten": False,
"projection_byte_identical_to_authoring": True,
"code_mirrors_byte_identical": True,
"canonical_task_semantics_sha256": semantics_sha256,
},
"expected_parent_stage2_release_sha256": validation[
"expected_parent_stage2_release_sha256"
],
"parity_status": "PASS",
}
outputs = {
PROJECTION_PATH: authoring_raw,
MIRROR_PY_PATH: code_bytes,
MIRROR_TXT_PATH: code_bytes,
RECEIPT_PATH: canonical_json_bytes(receipt),
}
return outputs, receipt
def _assert_output_target(path: Path) -> None:
root = DEPLOYMENT_ROOT.resolve(strict=True)
resolved = path.resolve(strict=False)
try:
resolved.relative_to(root)
except ValueError as exc:
raise ProjectionError("OUTPUT_OUTSIDE_DEPLOYMENT_ROOT", path.as_posix()) from exc
if path.exists() and path.is_symlink():
raise ProjectionError("OUTPUT_SYMLINK_FORBIDDEN", path.as_posix())
def _atomic_write(path: Path, payload: bytes) -> None:
_assert_output_target(path)
path.parent.mkdir(parents=True, exist_ok=True)
temporary_name: str | None = None
try:
with tempfile.NamedTemporaryFile(
mode="wb",
dir=path.parent,
prefix=f".{path.name}.",
suffix=".tmp",
delete=False,
) as handle:
temporary_name = handle.name
handle.write(payload)
handle.flush()
os.fsync(handle.fileno())
os.replace(temporary_name, path)
temporary_name = None
finally:
if temporary_name is not None:
try:
Path(temporary_name).unlink()
except FileNotFoundError:
pass
def compare_outputs(outputs: Mapping[Path, bytes]) -> list[dict[str, Any]]:
mismatches: list[dict[str, Any]] = []
for path, expected in outputs.items():
if not path.is_file():
mismatches.append(
{"path": _logical_path(path), "status": "MISSING", "expected_sha256": sha256_bytes(expected)}
)
continue
observed = path.read_bytes()
if observed != expected:
mismatches.append(
{
"path": _logical_path(path),
"status": "BYTE_MISMATCH",
"expected_sha256": sha256_bytes(expected),
"observed_sha256": sha256_bytes(observed),
}
)
return mismatches
def run(*, check: bool) -> tuple[int, dict[str, Any]]:
before, document = load_authoring()
outputs, receipt = expected_outputs(before, document)
if check:
mismatches = compare_outputs(outputs)
return (
0 if not mismatches else 1,
{
"status": "PARITY_PASS" if not mismatches else "PARITY_DRIFT",
"mode": "CHECK_NO_WRITE",
"authoring_sha256": sha256_bytes(before),
"code_sha256": receipt["canonical_code"]["code_sha256"],
"mismatches": mismatches,
},
)
receipt_payload = outputs[RECEIPT_PATH]
for path, payload in outputs.items():
if path == RECEIPT_PATH:
continue
_atomic_write(path, payload)
after_artifacts = AUTHORING_PATH.read_bytes()
if after_artifacts != before:
raise ProjectionError(
"AUTHORING_CHANGED_DURING_BUILD",
f"before={sha256_bytes(before)} after={sha256_bytes(after_artifacts)}",
)
_atomic_write(RECEIPT_PATH, receipt_payload)
after_receipt = AUTHORING_PATH.read_bytes()
if after_receipt != before:
raise ProjectionError(
"AUTHORING_CHANGED_DURING_RECEIPT_WRITE",
f"before={sha256_bytes(before)} after={sha256_bytes(after_receipt)}",
)
mismatches = compare_outputs(outputs)
if mismatches:
raise ProjectionError("POST_BUILD_PARITY_FAILED", json.dumps(mismatches, sort_keys=True))
return 0, {
"status": "BUILT_AND_VERIFIED",
"mode": "BUILD",
"authoring_sha256": sha256_bytes(before),
"code_sha256": receipt["canonical_code"]["code_sha256"],
"outputs": [_logical_path(path) for path in outputs],
}
def _parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description="Build or verify the S2_40 inline Agent projection"
)
parser.add_argument(
"--check",
action="store_true",
help="perform a no-write byte-parity check against generated outputs",
)
return parser
def main(argv: Iterable[str] | None = None) -> int:
args = _parser().parse_args(list(argv) if argv is not None else None)
try:
status, payload = run(check=args.check)
except ProjectionError as exc:
status = 3 if exc.code == "AUTHORING_YAML_MISSING" else 2
payload = {
"status": "CONTROLLED_MISSING_AUTHORING" if status == 3 else "BUILD_FAILED",
"reason_code": exc.code,
"detail": exc.detail,
"mode": "CHECK_NO_WRITE" if args.check else "BUILD",
}
print(json.dumps(payload, ensure_ascii=False, allow_nan=False, sort_keys=True))
return status
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,894 @@
#!/usr/bin/env python3
"""Build the version-free S2_40 Agent projection from its sole authoring YAML.
This is an offline build tool. It never executes a matter, imports project
runtime code, rewrites the authoring YAML, or invokes a subprocess. The YAML
parser-returned ``parameters.code`` string is encoded directly as UTF-8; no
dedent, newline normalization, or source transformation is permitted.
"""
from __future__ import annotations
import argparse
import ast
import hashlib
import json
import os
from pathlib import Path
import re
import sys
import tempfile
from typing import Any, Iterable, Mapping
try:
import yaml
except ImportError: # pragma: no cover - exercised only on an incomplete build host
yaml = None # type: ignore[assignment]
DEPLOYMENT_ROOT = Path(__file__).resolve().parents[1]
MAIN_WORKING_DIRECTORY = DEPLOYMENT_ROOT.parent.parent
AUTHORING_PATH = MAIN_WORKING_DIRECTORY / "Stage_2_S2_40.yml"
PROJECTION_PATH = DEPLOYMENT_ROOT / "agent_scripts" / "Stage_2_S2_40.yml"
MIRROR_PY_PATH = DEPLOYMENT_ROOT / "runtime" / "s2_40_commit.py"
MIRROR_TXT_PATH = DEPLOYMENT_ROOT / "runtime" / "s2_40_commit.txt"
RECEIPT_PATH = DEPLOYMENT_ROOT / "manifest" / "s2_40_inline_code_receipt.json"
EXPECTED_TASK_NAME = "Task_S2_40_deterministic_finalizer"
EXPECTED_AGENT_NAME = "Stage_2_S2_40"
EXPECTED_AGENT_VERSION = "1.0.0"
EXPECTED_PARAMETERS = {
"language": "python",
"requirements": "httpx==0.28.1",
"network": "agent-network",
"timeout": 300,
}
EXPECTED_LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp"
EXPECTED_CODE_EXECUTOR_URL = "https://code-executor.mcp.eroomai.com/mcp"
REQUIRED_CODE_TOKENS = (
EXPECTED_LOCALDOCS_URL,
"{{__user_hash__}}",
"{{__workspace_hash__}}",
"read_binary_doc",
"write_binary_file",
"stage2_control/s2_40_request.json",
"run_status.json",
"reduce_and_render",
"invariant_results",
"candidate_material",
"publish_candidate",
"validate_review_receipts",
"final_status",
)
REQUIRED_CODE_TOKEN_ALTERNATIVES = (
("EXPECTED_STAGE2_RELEASE_SHA256",),
)
ALLOWED_NON_STDLIB_IMPORTS = frozenset({"httpx"})
FORBIDDEN_IMPORT_ROOTS = frozenset(
{
"ftplib",
"http",
"importlib",
"smtplib",
"socket",
"subprocess",
"telnetlib",
"urllib",
"xmlrpc",
}
)
FORBIDDEN_CALL_NAMES = frozenset({"__import__", "compile", "eval", "exec", "open"})
FORBIDDEN_ATTRIBUTE_CALLS = frozenset(
{
("os", "popen"),
("os", "spawnl"),
("os", "spawnle"),
("os", "spawnlp"),
("os", "spawnlpe"),
("os", "spawnv"),
("os", "spawnve"),
("os", "spawnvp"),
("os", "spawnvpe"),
("os", "system"),
}
)
PLACEHOLDER_COMMENT_RE = re.compile(
r"(?im)^\s*#\s*(?:TODO|FIXME|TBD|PLACEHOLDER|OMITTED\s+BODY|IMPLEMENT\s+ME)\b"
)
PLAINTEXT_SECRET_RES = (
re.compile(r"(?i)\bAuthorization\s*:\s*Bearer\s+\S+"),
re.compile(r"(?i)\bBearer\s+[A-Za-z0-9+/=_-]{12,}"),
re.compile(
r"(?i)\b(?:MCP_API_KEY|API_KEY|ACCESS_TOKEN|AUTH_TOKEN|CLIENT_SECRET)\s*=\s*['\"][^'\"]+['\"]"
),
)
URL_RE = re.compile(r"https?://[^\s'\"]+")
PYTHON_SOURCE_REF_RE = re.compile(r"(?i)(?:^|[/\\])[^\r\n'\"]+\.py(?:$|[?#])")
ALLOWED_IDENTIFIER_URL_PREFIXES = ("https://schemas.liti-agent.local/",)
HTTP_NETWORK_METHODS = frozenset({"delete", "get", "head", "options", "patch", "post", "put", "request", "stream"})
HTTP_CLIENT_FACTORIES = frozenset({"Client", "AsyncClient"})
class ProjectionError(RuntimeError):
"""A controlled build failure with a stable reason code."""
def __init__(self, code: str, detail: str) -> None:
super().__init__(f"{code}: {detail}")
self.code = code
self.detail = detail
class AuthoringMissingError(ProjectionError):
def __init__(self, path: Path) -> None:
super().__init__("AUTHORING_YAML_MISSING", path.as_posix())
if yaml is not None:
class UniqueKeySafeLoader(yaml.SafeLoader):
"""SafeLoader variant that rejects duplicate mapping keys recursively."""
def construct_mapping(self, node: Any, deep: bool = False) -> dict[Any, Any]:
if not isinstance(node, yaml.MappingNode):
raise ProjectionError("YAML_MAPPING_REQUIRED", repr(node)[:200])
self.flatten_mapping(node)
result: dict[Any, Any] = {}
for key_node, value_node in node.value:
key = self.construct_object(key_node, deep=deep)
try:
duplicate = key in result
except TypeError as exc:
raise ProjectionError("YAML_UNHASHABLE_KEY", repr(key)[:200]) from exc
if duplicate:
mark = getattr(key_node, "start_mark", None)
location = f" line {mark.line + 1}" if mark is not None else ""
raise ProjectionError("YAML_DUPLICATE_KEY", f"{key!r}{location}")
result[key] = self.construct_object(value_node, deep=deep)
return result
else: # pragma: no cover - type placeholder for hosts without PyYAML
class UniqueKeySafeLoader: # type: ignore[no-redef]
pass
def sha256_bytes(value: bytes) -> str:
return hashlib.sha256(value).hexdigest()
def canonical_json_bytes(value: Any) -> bytes:
return (
json.dumps(
value,
ensure_ascii=False,
allow_nan=False,
sort_keys=True,
separators=(",", ":"),
)
+ "\n"
).encode("utf-8")
def _logical_path(path: Path) -> str:
try:
return path.resolve(strict=False).relative_to(
MAIN_WORKING_DIRECTORY.resolve(strict=False)
).as_posix()
except ValueError:
return path.as_posix()
def parse_authoring_bytes(raw: bytes, *, source: str = "<authoring>") -> dict[str, Any]:
if yaml is None:
raise ProjectionError("PYYAML_REQUIRED", "install PyYAML on the offline build host")
try:
text = raw.decode("utf-8")
except UnicodeDecodeError as exc:
raise ProjectionError("AUTHORING_UTF8_REQUIRED", f"{source}: {exc}") from exc
if text.startswith("\ufeff"):
raise ProjectionError("AUTHORING_UTF8_BOM_FORBIDDEN", source)
for pattern in PLAINTEXT_SECRET_RES:
if pattern.search(text):
raise ProjectionError("AUTHORING_PLAINTEXT_SECRET", pattern.pattern)
try:
loaded = yaml.load(text, Loader=UniqueKeySafeLoader)
except ProjectionError:
raise
except yaml.YAMLError as exc:
raise ProjectionError("AUTHORING_YAML_INVALID", f"{source}: {exc}") from exc
if not isinstance(loaded, dict):
raise ProjectionError("AUTHORING_ROOT_OBJECT_REQUIRED", source)
return loaded
def load_authoring(path: Path | None = None) -> tuple[bytes, dict[str, Any]]:
path = AUTHORING_PATH if path is None else path
if not path.is_file():
raise AuthoringMissingError(path)
if path.is_symlink():
raise ProjectionError("AUTHORING_SYMLINK_FORBIDDEN", path.as_posix())
raw = path.read_bytes()
return raw, parse_authoring_bytes(raw, source=path.as_posix())
def _require_mapping(value: Any, code: str) -> dict[str, Any]:
if not isinstance(value, dict):
raise ProjectionError(code, repr(value)[:200])
return value
def _require_list(value: Any, code: str) -> list[Any]:
if not isinstance(value, list):
raise ProjectionError(code, repr(value)[:200])
return value
def _find_forbidden_model_fields(value: Any, pointer: str = "") -> list[str]:
forbidden = {"llm_provider", "llm_model", "llm_reasoning", "llm_verbosity", "prompt"}
findings: list[str] = []
if isinstance(value, dict):
for key, child in value.items():
child_pointer = f"{pointer}/{key}"
if key in forbidden:
findings.append(child_pointer)
findings.extend(_find_forbidden_model_fields(child, child_pointer))
elif isinstance(value, list):
for index, child in enumerate(value):
findings.extend(_find_forbidden_model_fields(child, f"{pointer}/{index}"))
return findings
def extract_run_code_task(document: Mapping[str, Any]) -> tuple[dict[str, Any], dict[str, Any]]:
agent = _require_mapping(document.get("Agent"), "AGENT_OBJECT_REQUIRED")
if agent.get("name") != EXPECTED_AGENT_NAME or agent.get("version") != EXPECTED_AGENT_VERSION:
raise ProjectionError(
"AGENT_IDENTITY_MISMATCH",
f"expected {EXPECTED_AGENT_NAME}/{EXPECTED_AGENT_VERSION}",
)
forbidden_model_fields = _find_forbidden_model_fields(agent)
if forbidden_model_fields:
raise ProjectionError("LLM_OR_PROMPT_FIELD_FORBIDDEN", repr(forbidden_model_fields))
stages = _require_list(agent.get("Stages"), "STAGES_ARRAY_REQUIRED")
if len(stages) != 1:
raise ProjectionError("EXACTLY_ONE_STAGE_REQUIRED", str(len(stages)))
stage = _require_mapping(stages[0], "STAGE_OBJECT_REQUIRED")
if stage.get("name") != "S2_40":
raise ProjectionError("S2_40_STAGE_NAME_REQUIRED", repr(stage.get("name")))
if stage.get("skip_confirm") is not True:
raise ProjectionError(
"S2_40_SKIP_CONFIRM_TRUE_REQUIRED",
repr(stage.get("skip_confirm")),
)
for forbidden in ("llm_provider", "llm_model", "llm_reasoning", "llm_verbosity"):
if forbidden in stage:
raise ProjectionError("MODEL_FIELD_FORBIDDEN", forbidden)
servers = _require_mapping(
_require_mapping(stage.get("tools"), "TOOLS_OBJECT_REQUIRED").get("mcpServers"),
"MCP_SERVERS_OBJECT_REQUIRED",
)
if set(servers) != {"localdocs", "code-executor"}:
raise ProjectionError("MCP_SERVER_SET_MISMATCH", repr(sorted(servers)))
localdocs = _require_mapping(servers.get("localdocs"), "LOCALDOCS_SERVER_REQUIRED")
code_executor = _require_mapping(
servers.get("code-executor"), "CODE_EXECUTOR_SERVER_REQUIRED"
)
if localdocs.get("type") != "streamable-http" or localdocs.get("url") != EXPECTED_LOCALDOCS_URL:
raise ProjectionError("LOCALDOCS_SERVER_BINDING_INVALID", repr(localdocs))
if (
code_executor.get("type") != "streamable-http"
or code_executor.get("url") != EXPECTED_CODE_EXECUTOR_URL
):
raise ProjectionError("CODE_EXECUTOR_SERVER_BINDING_INVALID", repr(code_executor))
if "headers" in code_executor:
raise ProjectionError(
"PLAINTEXT_OR_INLINE_AUTH_HEADER_FORBIDDEN",
"authentication must be injected or pre-registered by the backend",
)
tasks = _require_list(stage.get("tasks"), "TASKS_ARRAY_REQUIRED")
if len(tasks) != 1:
raise ProjectionError("EXACTLY_ONE_TASK_REQUIRED", str(len(tasks)))
task = _require_mapping(tasks[0], "TASK_OBJECT_REQUIRED")
run_code_tasks = [
row
for row in tasks
if isinstance(row, dict)
and row.get("mcp") == "code-executor"
and row.get("tool_name") == "run_code"
]
if len(run_code_tasks) != 1:
raise ProjectionError("EXACTLY_ONE_RUN_CODE_REQUIRED", str(len(run_code_tasks)))
if task.get("task_name") != EXPECTED_TASK_NAME:
raise ProjectionError("TASK_NAME_MISMATCH", repr(task.get("task_name")))
parameters = _require_mapping(task.get("parameters"), "TASK_PARAMETERS_REQUIRED")
expected_parameter_keys = set(EXPECTED_PARAMETERS) | {"code"}
if set(parameters) != expected_parameter_keys:
raise ProjectionError(
"RUN_CODE_PARAMETER_SET_MISMATCH",
repr(sorted(parameters)),
)
for key, expected in EXPECTED_PARAMETERS.items():
if parameters.get(key) != expected:
raise ProjectionError(
"RUN_CODE_PARAMETER_MISMATCH",
f"{key}: expected {expected!r}, observed {parameters.get(key)!r}",
)
code = parameters.get("code")
if not isinstance(code, str) or not code:
raise ProjectionError("INLINE_CODE_REQUIRED", repr(code)[:100])
if code.endswith(("\n", "\r")):
raise ProjectionError(
"INLINE_CODE_TRAILING_NEWLINE_FORBIDDEN",
"authoring YAML must use code: |- so parser-returned code has no trailing newline",
)
procedure = _require_mapping(stage.get("task_procedure"), "TASK_PROCEDURE_REQUIRED")
expected_procedure = {
"IN": {"nexts": [EXPECTED_TASK_NAME], "wait_until": []},
EXPECTED_TASK_NAME: {"nexts": ["OUT"], "wait_until": ["IN"]},
"OUT": {"nexts": [], "wait_until": [EXPECTED_TASK_NAME]},
}
if procedure != expected_procedure:
raise ProjectionError("TASK_PROCEDURE_MISMATCH", repr(procedure)[:500])
if stage.get("prevs") != [] or stage.get("nexts") != []:
raise ProjectionError("STANDALONE_STAGE_EDGES_MUST_BE_EMPTY", repr(stage))
return stage, task
def _import_root(name: str | None) -> str:
return (name or "").split(".", 1)[0]
def _attribute_pair(node: ast.Attribute) -> tuple[str, str] | None:
if isinstance(node.value, ast.Name):
return node.value.id, node.attr
return None
def _is_http_client_receiver(
node: ast.expr,
derived_client_names: set[str] | None = None,
) -> bool:
if isinstance(node, ast.Name):
return node.id in {"client", "http_client", "httpx"} | (derived_client_names or set())
if isinstance(node, ast.Attribute):
return (
isinstance(node.value, ast.Name)
and node.value.id == "self"
and node.attr in {"client", "http_client"}
)
return False
def _is_direct_localdocs_post(call: ast.Call) -> bool:
if not isinstance(call.func, ast.Attribute) or call.func.attr != "post":
return False
receiver = call.func.value
if not (
isinstance(receiver, ast.Attribute)
and isinstance(receiver.value, ast.Name)
and receiver.value.id == "self"
and receiver.attr == "client"
):
return False
return _is_localdocs_endpoint(_network_endpoint(call) or ast.Constant(value=None))
def _network_endpoint(call: ast.Call) -> ast.expr | None:
"""Return a statically identifiable httpx/client endpoint expression."""
if not isinstance(call.func, ast.Attribute) or call.func.attr not in HTTP_NETWORK_METHODS:
return None
if not _is_http_client_receiver(call.func.value):
return None
for keyword in call.keywords:
if keyword.arg == "url":
return keyword.value
index = 1 if call.func.attr == "request" else 0
return call.args[index] if len(call.args) > index else ast.Constant(value=None)
def _is_localdocs_endpoint(node: ast.expr) -> bool:
return (
isinstance(node, ast.Name)
and node.id == "LOCALDOCS_URL"
or isinstance(node, ast.Constant)
and node.value == EXPECTED_LOCALDOCS_URL
or isinstance(node, ast.Attribute)
and isinstance(node.value, ast.Name)
and node.value.id == "self"
and node.attr == "endpoint"
)
def validate_inline_code(code: str) -> dict[str, Any]:
code_bytes = code.encode("utf-8")
try:
compile(code, "<Stage_2_S2_40.parameters.code>", "exec", dont_inherit=True)
tree = ast.parse(code, filename="<Stage_2_S2_40.parameters.code>", mode="exec")
except (SyntaxError, ValueError, UnicodeError) as exc:
raise ProjectionError("INLINE_CODE_COMPILE_FAILED", str(exc)) from exc
missing_tokens = [token for token in REQUIRED_CODE_TOKENS if token not in code]
missing_tokens.extend(
"|".join(alternatives)
for alternatives in REQUIRED_CODE_TOKEN_ALTERNATIVES
if not any(token in code for token in alternatives)
)
if missing_tokens:
raise ProjectionError("INLINE_CODE_REQUIRED_TOKEN_MISSING", ",".join(missing_tokens))
if PLACEHOLDER_COMMENT_RE.search(code):
raise ProjectionError("INLINE_CODE_PLACEHOLDER_COMMENT", "TODO/FIXME/TBD placeholder")
for pattern in PLAINTEXT_SECRET_RES:
if pattern.search(code):
raise ProjectionError("INLINE_CODE_PLAINTEXT_SECRET", pattern.pattern)
imports: set[str] = set()
forbidden_nodes: list[str] = []
external_urls: set[str] = set()
forbidden_network_endpoints: set[str] = set()
project_source_refs: set[str] = set()
import_aliases: dict[str, str] = {}
forbidden_callable_aliases: set[str] = set()
mcp_client_endpoint_calls: list[ast.expr] = []
self_endpoint_assignments: list[ast.expr] = []
for candidate in ast.walk(tree):
if isinstance(candidate, ast.Import):
for alias in candidate.names:
import_aliases[alias.asname or _import_root(alias.name)] = _import_root(alias.name)
elif isinstance(candidate, ast.ImportFrom) and not candidate.level:
root = _import_root(candidate.module)
for alias in candidate.names:
local_name = alias.asname or alias.name
if root == "httpx" and (
alias.name in HTTP_NETWORK_METHODS or alias.name in HTTP_CLIENT_FACTORIES
):
forbidden_callable_aliases.add(local_name)
if root == "os" and (
alias.name in {name for module, name in FORBIDDEN_ATTRIBUTE_CALLS if module == "os"}
or alias.name.startswith("exec")
):
forbidden_callable_aliases.add(local_name)
if root == "builtins" and alias.name in FORBIDDEN_CALL_NAMES:
forbidden_callable_aliases.add(local_name)
derived_client_names: set[str] = set()
release_constants: list[str] = []
for candidate in ast.walk(tree):
if not isinstance(candidate, (ast.Assign, ast.AnnAssign)):
continue
value = candidate.value
targets = candidate.targets if isinstance(candidate, ast.Assign) else [candidate.target]
target_names = {target.id for target in targets if isinstance(target, ast.Name)}
if (
"EXPECTED_STAGE2_RELEASE_SHA256" in target_names
and isinstance(value, ast.Constant)
and isinstance(value.value, str)
):
release_constants.append(value.value)
if (
isinstance(value, ast.Call)
and isinstance(value.func, ast.Attribute)
and isinstance(value.func.value, ast.Name)
and import_aliases.get(value.func.value.id, value.func.value.id) == "httpx"
and value.func.attr in HTTP_CLIENT_FACTORIES
):
derived_client_names.update(target_names)
if isinstance(value, ast.Name) and (
value.id in FORBIDDEN_CALL_NAMES or value.id in forbidden_callable_aliases
):
forbidden_callable_aliases.update(target_names)
if isinstance(value, ast.Attribute) and isinstance(value.value, ast.Name):
module = import_aliases.get(value.value.id, value.value.id)
if (module, value.attr) in FORBIDDEN_ATTRIBUTE_CALLS or (
module == "os" and value.attr.startswith("exec")
):
forbidden_callable_aliases.update(target_names)
if module == "httpx" and value.attr in HTTP_NETWORK_METHODS:
forbidden_callable_aliases.update(target_names)
for node in ast.walk(tree):
if isinstance(node, ast.Import):
imports.update(_import_root(alias.name) for alias in node.names)
elif isinstance(node, ast.ImportFrom):
if node.level:
forbidden_nodes.append(f"relative-import:{node.module or ''}")
imports.add(_import_root(node.module))
root = _import_root(node.module)
for alias in node.names:
local_name = alias.asname or alias.name
if local_name in forbidden_callable_aliases:
forbidden_nodes.append(f"forbidden-import-alias:{root}.{alias.name}")
elif isinstance(node, ast.Pass):
forbidden_nodes.append("Pass")
elif isinstance(node, ast.Expr) and isinstance(node.value, ast.Constant):
if node.value.value is Ellipsis:
forbidden_nodes.append("Ellipsis-expression")
elif isinstance(node, (ast.Assign, ast.AnnAssign)):
assignment_targets = node.targets if isinstance(node, ast.Assign) else [node.target]
if any(
isinstance(target, ast.Attribute)
and isinstance(target.value, ast.Name)
and target.value.id == "self"
and target.attr == "endpoint"
for target in assignment_targets
):
self_endpoint_assignments.append(node.value)
if isinstance(node.value, ast.Constant) and node.value.value is Ellipsis:
forbidden_nodes.append("Ellipsis-assignment")
if (
isinstance(node.value, ast.Attribute)
and node.value.attr in HTTP_NETWORK_METHODS
and _is_http_client_receiver(node.value.value, derived_client_names)
):
forbidden_nodes.append(f"network-method-alias:{node.value.attr}")
elif isinstance(node, ast.Constant):
if isinstance(node.value, str):
for match in URL_RE.findall(node.value):
normalized = match.rstrip(".,);]")
if (
normalized != EXPECTED_LOCALDOCS_URL
and not normalized.startswith(ALLOWED_IDENTIFIER_URL_PREFIXES)
):
external_urls.add(normalized)
if PYTHON_SOURCE_REF_RE.search(node.value.strip()):
project_source_refs.add(node.value[:200])
if node.value.strip().lower() in {
"todo",
"tbd",
"placeholder",
"omitted",
"implement me",
"...",
}:
forbidden_nodes.append(f"placeholder-string:{node.value!r}")
elif isinstance(node, ast.Call):
if isinstance(node.func, ast.Name) and node.func.id == "McpClient":
mcp_client_endpoint_calls.append(
node.args[0] if node.args else ast.Constant(value=None)
)
if (
isinstance(node.func, ast.Attribute)
and node.func.attr in HTTP_NETWORK_METHODS
and _is_http_client_receiver(node.func.value, derived_client_names)
):
if not _is_direct_localdocs_post(node):
forbidden_network_endpoints.add(ast.unparse(node.func)[:200])
if (
isinstance(node.func, ast.Attribute)
and node.func.attr in HTTP_NETWORK_METHODS
and isinstance(node.func.value, ast.Call)
and isinstance(node.func.value.func, ast.Attribute)
and isinstance(node.func.value.func.value, ast.Name)
and import_aliases.get(
node.func.value.func.value.id,
node.func.value.func.value.id,
) == "httpx"
and node.func.value.func.attr in HTTP_CLIENT_FACTORIES
):
forbidden_network_endpoints.add(ast.unparse(node.func)[:200])
if (
isinstance(node.func, ast.Name)
and node.func.id == "getattr"
and len(node.args) >= 2
and isinstance(node.args[1], ast.Constant)
and node.args[1].value in HTTP_NETWORK_METHODS
):
forbidden_nodes.append(f"dynamic-network-method:{node.args[1].value}")
if isinstance(node.func, ast.Name) and (
node.func.id in FORBIDDEN_CALL_NAMES
or node.func.id in forbidden_callable_aliases
):
forbidden_nodes.append(f"call:{node.func.id}")
elif isinstance(node.func, ast.Attribute):
pair = _attribute_pair(node.func)
if pair is not None:
module = import_aliases.get(pair[0], pair[0])
if (module, pair[1]) in FORBIDDEN_ATTRIBUTE_CALLS or (
module == "os" and pair[1].startswith("exec")
):
forbidden_nodes.append(f"call:{module}.{pair[1]}")
elif isinstance(node, ast.Raise):
target = node.exc
if isinstance(target, ast.Call):
target = target.func
if isinstance(target, ast.Name) and target.id == "NotImplementedError":
forbidden_nodes.append("raise:NotImplementedError")
imports.discard("")
disallowed_imports = sorted(
root
for root in imports
if root in FORBIDDEN_IMPORT_ROOTS
or (root not in sys.stdlib_module_names and root not in ALLOWED_NON_STDLIB_IMPORTS)
)
if disallowed_imports:
raise ProjectionError("INLINE_CODE_IMPORT_FORBIDDEN", ",".join(disallowed_imports))
if forbidden_nodes:
raise ProjectionError("INLINE_CODE_DYNAMIC_OR_PLACEHOLDER_FORBIDDEN", ",".join(forbidden_nodes))
if external_urls:
raise ProjectionError("INLINE_CODE_EXTERNAL_URL_FORBIDDEN", ",".join(sorted(external_urls)))
if forbidden_network_endpoints:
raise ProjectionError(
"INLINE_CODE_NETWORK_ENDPOINT_FORBIDDEN",
",".join(sorted(forbidden_network_endpoints)),
)
if project_source_refs:
raise ProjectionError(
"INLINE_CODE_EXTERNAL_PY_SOURCE_REF_FORBIDDEN", ",".join(sorted(project_source_refs))
)
if (
len(self_endpoint_assignments) != 1
or not isinstance(self_endpoint_assignments[0], ast.Name)
or self_endpoint_assignments[0].id != "endpoint"
or not mcp_client_endpoint_calls
or any(not _is_localdocs_endpoint(endpoint) for endpoint in mcp_client_endpoint_calls)
):
raise ProjectionError(
"INLINE_CODE_LOCALDOCS_ENDPOINT_FLOW_INVALID",
f"assignments={len(self_endpoint_assignments)};constructors={len(mcp_client_endpoint_calls)}",
)
if len(release_constants) != 1 or not re.fullmatch(r"[a-f0-9]{64}", release_constants[0]):
raise ProjectionError(
"EXPECTED_PARENT_RELEASE_CONSTANT_EXACT_ONE_REQUIRED",
repr(release_constants),
)
return {
"code_sha256": sha256_bytes(code_bytes),
"code_size_bytes": len(code_bytes),
"compile_status": "PASS",
"ast_status": "PASS",
"imports": sorted(imports),
"forbidden_import_count": 0,
"forbidden_dynamic_call_count": 0,
"external_url_count": 0,
"placeholder_count": 0,
"plaintext_secret_count": 0,
"external_python_source_ref_count": 0,
"expected_parent_stage2_release_sha256": release_constants[0],
}
def _canonical_task_semantics(document: Mapping[str, Any], stage: Mapping[str, Any], task: Mapping[str, Any]) -> dict[str, Any]:
agent = _require_mapping(document.get("Agent"), "AGENT_OBJECT_REQUIRED")
servers = _require_mapping(
_require_mapping(stage.get("tools"), "TOOLS_OBJECT_REQUIRED").get("mcpServers"),
"MCP_SERVERS_OBJECT_REQUIRED",
)
parameters = _require_mapping(task.get("parameters"), "TASK_PARAMETERS_REQUIRED")
return {
"agent": {"name": agent.get("name"), "version": agent.get("version")},
"stage": {
"name": stage.get("name"),
"prevs": stage.get("prevs"),
"nexts": stage.get("nexts"),
},
"mcp_servers": {
name: {"type": value.get("type"), "url": value.get("url")}
for name, value in sorted(servers.items())
if isinstance(value, dict)
},
"task": {
"task_name": task.get("task_name"),
"mcp": task.get("mcp"),
"tool_name": task.get("tool_name"),
"parameters": {
key: parameters.get(key)
for key in ("language", "requirements", "network", "timeout")
},
"code_sha256": sha256_bytes(parameters["code"].encode("utf-8")),
},
"task_procedure": stage.get("task_procedure"),
}
def expected_outputs(
authoring_raw: bytes,
document: Mapping[str, Any],
) -> tuple[dict[Path, bytes], dict[str, Any]]:
stage, task = extract_run_code_task(document)
parameters = _require_mapping(task.get("parameters"), "TASK_PARAMETERS_REQUIRED")
code = parameters["code"]
validation = validate_inline_code(code)
code_bytes = code.encode("utf-8")
semantics = _canonical_task_semantics(document, stage, task)
semantics_sha256 = sha256_bytes(canonical_json_bytes(semantics))
receipt = {
"schema_version": "stage2_s2_40_inline_code_receipt.v1",
"workflow_id": "S2_40",
"build_kind": "OFFLINE_AUTHORING_PROJECTION",
"source_of_truth": _logical_path(AUTHORING_PATH),
"authoring_rewritten": False,
"authoring": {
"path": _logical_path(AUTHORING_PATH),
"sha256": sha256_bytes(authoring_raw),
"size_bytes": len(authoring_raw),
"unique_key_parse": "PASS",
},
"deployment_projection": {
"path": _logical_path(PROJECTION_PATH),
"sha256": sha256_bytes(authoring_raw),
"size_bytes": len(authoring_raw),
"byte_identical_to_authoring": True,
"canonical_task_semantics_sha256": semantics_sha256,
},
"canonical_code": {
"yaml_pointer": "/Agent/Stages/0/tasks/0/parameters/code",
"encoding": "UTF-8",
"extraction_transform": "NONE",
**validation,
},
"full_code_mirrors": [
{
"path": _logical_path(MIRROR_PY_PATH),
"sha256": validation["code_sha256"],
"size_bytes": len(code_bytes),
"byte_identical_to_canonical_code": True,
},
{
"path": _logical_path(MIRROR_TXT_PATH),
"sha256": validation["code_sha256"],
"size_bytes": len(code_bytes),
"byte_identical_to_canonical_code": True,
},
],
"task_contract": {
**semantics,
"exactly_one_stage": True,
"exactly_one_task": True,
"exactly_one_code_executor_run_code": True,
"authoring_rewritten": False,
"projection_byte_identical_to_authoring": True,
"code_mirrors_byte_identical": True,
"canonical_task_semantics_sha256": semantics_sha256,
},
"expected_parent_stage2_release_sha256": validation[
"expected_parent_stage2_release_sha256"
],
"parity_status": "PASS",
}
outputs = {
PROJECTION_PATH: authoring_raw,
MIRROR_PY_PATH: code_bytes,
MIRROR_TXT_PATH: code_bytes,
RECEIPT_PATH: canonical_json_bytes(receipt),
}
return outputs, receipt
def _assert_output_target(path: Path) -> None:
root = DEPLOYMENT_ROOT.resolve(strict=True)
resolved = path.resolve(strict=False)
try:
resolved.relative_to(root)
except ValueError as exc:
raise ProjectionError("OUTPUT_OUTSIDE_DEPLOYMENT_ROOT", path.as_posix()) from exc
if path.exists() and path.is_symlink():
raise ProjectionError("OUTPUT_SYMLINK_FORBIDDEN", path.as_posix())
def _atomic_write(path: Path, payload: bytes) -> None:
_assert_output_target(path)
path.parent.mkdir(parents=True, exist_ok=True)
temporary_name: str | None = None
try:
with tempfile.NamedTemporaryFile(
mode="wb",
dir=path.parent,
prefix=f".{path.name}.",
suffix=".tmp",
delete=False,
) as handle:
temporary_name = handle.name
handle.write(payload)
handle.flush()
os.fsync(handle.fileno())
os.replace(temporary_name, path)
temporary_name = None
finally:
if temporary_name is not None:
try:
Path(temporary_name).unlink()
except FileNotFoundError:
pass
def compare_outputs(outputs: Mapping[Path, bytes]) -> list[dict[str, Any]]:
mismatches: list[dict[str, Any]] = []
for path, expected in outputs.items():
if not path.is_file():
mismatches.append(
{"path": _logical_path(path), "status": "MISSING", "expected_sha256": sha256_bytes(expected)}
)
continue
observed = path.read_bytes()
if observed != expected:
mismatches.append(
{
"path": _logical_path(path),
"status": "BYTE_MISMATCH",
"expected_sha256": sha256_bytes(expected),
"observed_sha256": sha256_bytes(observed),
}
)
return mismatches
def run(*, check: bool) -> tuple[int, dict[str, Any]]:
before, document = load_authoring()
outputs, receipt = expected_outputs(before, document)
if check:
mismatches = compare_outputs(outputs)
return (
0 if not mismatches else 1,
{
"status": "PARITY_PASS" if not mismatches else "PARITY_DRIFT",
"mode": "CHECK_NO_WRITE",
"authoring_sha256": sha256_bytes(before),
"code_sha256": receipt["canonical_code"]["code_sha256"],
"mismatches": mismatches,
},
)
receipt_payload = outputs[RECEIPT_PATH]
for path, payload in outputs.items():
if path == RECEIPT_PATH:
continue
_atomic_write(path, payload)
after_artifacts = AUTHORING_PATH.read_bytes()
if after_artifacts != before:
raise ProjectionError(
"AUTHORING_CHANGED_DURING_BUILD",
f"before={sha256_bytes(before)} after={sha256_bytes(after_artifacts)}",
)
_atomic_write(RECEIPT_PATH, receipt_payload)
after_receipt = AUTHORING_PATH.read_bytes()
if after_receipt != before:
raise ProjectionError(
"AUTHORING_CHANGED_DURING_RECEIPT_WRITE",
f"before={sha256_bytes(before)} after={sha256_bytes(after_receipt)}",
)
mismatches = compare_outputs(outputs)
if mismatches:
raise ProjectionError("POST_BUILD_PARITY_FAILED", json.dumps(mismatches, sort_keys=True))
return 0, {
"status": "BUILT_AND_VERIFIED",
"mode": "BUILD",
"authoring_sha256": sha256_bytes(before),
"code_sha256": receipt["canonical_code"]["code_sha256"],
"outputs": [_logical_path(path) for path in outputs],
}
def _parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
description="Build or verify the S2_40 inline Agent projection"
)
parser.add_argument(
"--check",
action="store_true",
help="perform a no-write byte-parity check against generated outputs",
)
return parser
def main(argv: Iterable[str] | None = None) -> int:
args = _parser().parse_args(list(argv) if argv is not None else None)
try:
status, payload = run(check=args.check)
except ProjectionError as exc:
status = 3 if exc.code == "AUTHORING_YAML_MISSING" else 2
payload = {
"status": "CONTROLLED_MISSING_AUTHORING" if status == 3 else "BUILD_FAILED",
"reason_code": exc.code,
"detail": exc.detail,
"mode": "CHECK_NO_WRITE" if args.check else "BUILD",
}
print(json.dumps(payload, ensure_ascii=False, allow_nan=False, sort_keys=True))
return status
if __name__ == "__main__":
raise SystemExit(main())
@@ -125,29 +125,46 @@ ADVERSE_REQUIRED = frozenset(
"presentation_authorization_ref", "presentation_authorization_ref",
} }
) )
SUCCESS_ARTIFACT_FAMILIES = frozenset( PART_FAMILIES = frozenset(
{"DRAFT_PART", "ISSUE_PATCH", "WORKNOTE_PART", "USAGE_PART", "ITEM_RECEIPT"} {"DRAFT_PART", "ISSUE_PATCH", "WORKNOTE_PART", "USAGE_PART"}
) )
SUCCESS_ARTIFACT_FILENAMES = { PART_FILENAMES = {
"DRAFT_PART": "draft_parts", "DRAFT_PART": "draft_parts",
"ISSUE_PATCH": "issue_patches", "ISSUE_PATCH": "issue_patches",
"WORKNOTE_PART": "worknote_parts", "WORKNOTE_PART": "worknote_parts",
"USAGE_PART": "usage_parts", "USAGE_PART": "usage_parts",
"ITEM_RECEIPT": "item_receipts",
} }
PUBLISH_ARTIFACT_ROW_FIELDS = frozenset( PART_SCHEMA_REFS = {
"DRAFT_PART": "schemas/draft_atoms.schema.json#/$defs/draft_part",
"ISSUE_PATCH": "schemas/draft_atoms.schema.json#/$defs/issue_patch_part",
"WORKNOTE_PART": "schemas/draft_atoms.schema.json#/$defs/worknote_part",
"USAGE_PART": "schemas/draft_atoms.schema.json#/$defs/usage_part",
}
PART_DEF_NAMES = {
"DRAFT_PART": "draft_part",
"ISSUE_PATCH": "issue_patch_part",
"WORKNOTE_PART": "worknote_part",
"USAGE_PART": "usage_part",
}
PART_SELF_HASH_FIELDS = {family: "part_sha256" for family in PART_FAMILIES}
COMMON_PROVENANCE_FIELDS = frozenset(
{ {
"claim_group_id", "compile_mode",
"artifact_family", "parent_stage2_release_sha256",
"artifact_path", "s2_30_release_sha256",
"artifact_sha256", "s2_30_agent_sha256",
"read_back_sha256", "s2_30_binding_sha256",
"immutable_write_status", "p00_prompt_sha256",
"read_back_status", "p30_prompt_sha256",
"item_receipt_path", "s2_30_producer_contract_digest",
"item_receipt_sha256", }
"item_receipt_persistence_status", )
"artifact_receipt_sha256", GROUP_PROVENANCE_FIELDS = frozenset(
{
*COMMON_PROVENANCE_FIELDS,
"p31_rule_and_pack_sha256",
"p32_common_authority_sha256",
"s30_group_slice_sha256",
} }
) )
REQUIRED_PENDING = { REQUIRED_PENDING = {
@@ -1765,79 +1782,328 @@ def evaluate_retry(
raise ContractError("ATTEMPT_NO_INVALID", "$/attempt_no", repr(attempt_no)) raise ContractError("ATTEMPT_NO_INVALID", "$/attempt_no", repr(attempt_no))
def _validate_handoff_provenance(
provenance: Mapping[str, Any],
*,
common_only: bool,
path: str,
) -> None:
expected = COMMON_PROVENANCE_FIELDS if common_only else GROUP_PROVENANCE_FIELDS
if set(provenance) != expected:
raise ContractError(
"HANDOFF_PROVENANCE_CLOSED_SHAPE",
path,
repr(sorted(set(provenance) ^ expected)),
)
if provenance.get("compile_mode") not in ALLOWED_MODES:
raise ContractError(
"COMPILE_MODE_INVALID", f"{path}/compile_mode", repr(provenance.get("compile_mode"))
)
for key in expected - {"compile_mode"}:
value = provenance.get(key)
if not isinstance(value, str) or HEX64.fullmatch(value) is None:
raise ContractError("HANDOFF_PROVENANCE_HASH_INVALID", f"{path}/{key}", repr(value))
def _common_provenance(provenance: Mapping[str, Any]) -> dict[str, Any]:
return {key: provenance[key] for key in sorted(COMMON_PROVENANCE_FIELDS)}
def validate_persisted_part(
part: Mapping[str, Any],
family: str,
*,
expected_group_id: str | None = None,
expected_common_provenance: Mapping[str, Any] | None = None,
schema: Mapping[str, Any] | None = None,
path: str = "$/part",
) -> dict[str, Any]:
"""Validate one immutable S2_30 physical part without discovering siblings."""
if family not in PART_FAMILIES:
raise ContractError("PART_FAMILY_INVALID", path, repr(family))
if schema is not None:
validate_instance(part, PART_DEF_NAMES[family], schema)
_require_self_hash(part, PART_SELF_HASH_FIELDS[family], path)
group_id = part.get("claim_group_id")
if expected_group_id is not None and group_id != expected_group_id:
raise ContractError(
"PART_GROUP_MISMATCH", f"{path}/claim_group_id", repr((group_id, expected_group_id))
)
provenance = part.get("provenance")
if not isinstance(provenance, dict):
raise ContractError("HANDOFF_PROVENANCE_REQUIRED", f"{path}/provenance", repr(provenance))
_validate_handoff_provenance(provenance, common_only=False, path=f"{path}/provenance")
if expected_common_provenance is not None and _common_provenance(provenance) != dict(
expected_common_provenance
):
raise ContractError(
"PART_COMMON_PROVENANCE_MISMATCH",
f"{path}/provenance",
repr((_common_provenance(provenance), dict(expected_common_provenance))),
)
if family == "DRAFT_PART":
atoms = part.get("canonical_atoms")
atom_ids = [row.get("atom_id") for row in atoms] if isinstance(atoms, list) else []
if len(atom_ids) != len(set(atom_ids)):
raise ContractError("DRAFT_PART_ATOM_ID_DUPLICATE", f"{path}/canonical_atoms", repr(atom_ids))
if any(isinstance(row, dict) and row.get("claim_group_id") != group_id for row in atoms or []):
raise ContractError("DRAFT_PART_ATOM_GROUP_MISMATCH", f"{path}/canonical_atoms", repr(group_id))
coverage = part.get("atomic_claim_coverage")
coverage_refs = [
ref
for row in coverage or []
if isinstance(row, dict)
for key in ("relief_atom_local_refs", "cause_atom_local_refs")
for ref in row.get(key, [])
]
if len(coverage_refs) != len(set(coverage_refs)) or set(coverage_refs) != set(atom_ids) - {
row.get("atom_id")
for row in atoms or []
if isinstance(row, dict) and row.get("output_section") in {"procedural_declaration", "worknote_only"}
}:
raise ContractError("DRAFT_PART_COVERAGE_PARTITION_MISMATCH", f"{path}/atomic_claim_coverage", repr(coverage_refs))
return {"status": "PASS", "claim_group_id": group_id, "part_family": family}
def validate_part_manifest_core(
manifest: Mapping[str, Any],
part_bytes_by_path: Mapping[str, bytes],
schema: Mapping[str, Any] | None = None,
) -> dict[str, Any]:
"""Validate the receipt-free exact part index using only enumerated byte inputs."""
if schema is not None:
validate_instance(manifest, "part_manifest_core", schema)
_require_self_hash(manifest, "part_manifest_core_sha256", "$/artifact_manifest")
if any("receipt" in key.lower() for key in manifest):
raise ContractError("MANIFEST_RECEIPT_REFERENCE_FORBIDDEN", "$/artifact_manifest", repr(sorted(manifest)))
common = manifest.get("provenance")
if not isinstance(common, dict):
raise ContractError("HANDOFF_PROVENANCE_REQUIRED", "$/artifact_manifest/provenance", repr(common))
_validate_handoff_provenance(common, common_only=True, path="$/artifact_manifest/provenance")
expected_groups = manifest.get("expected_claim_group_ids")
if not isinstance(expected_groups, list) or expected_groups != sorted(expected_groups):
raise ContractError("MANIFEST_GROUP_ORDER_INVALID", "$/artifact_manifest/expected_claim_group_ids", repr(expected_groups))
rows = manifest.get("part_rows")
if not isinstance(rows, list):
raise ContractError("MANIFEST_PART_ROWS_REQUIRED", "$/artifact_manifest/part_rows", repr(rows))
if any(not isinstance(row, dict) for row in rows):
raise ContractError("MANIFEST_PART_ROW_OBJECT_REQUIRED", "$/artifact_manifest/part_rows", repr(rows))
sort_key = lambda row: (row.get("claim_group_id"), row.get("part_family"), row.get("path"))
if rows != sorted(rows, key=sort_key):
raise ContractError("MANIFEST_PART_ROW_ORDER_INVALID", "$/artifact_manifest/part_rows", "not stable sorted")
expected_pairs = {(group_id, family) for group_id in expected_groups for family in PART_FAMILIES}
observed_pairs: set[tuple[str, str]] = set()
declared_paths: list[str] = []
group_provenance: dict[str, dict[str, Any]] = {}
for index, row in enumerate(rows):
if not isinstance(row, dict):
raise ContractError("MANIFEST_PART_ROW_OBJECT_REQUIRED", f"$/artifact_manifest/part_rows/{index}", repr(row))
group_id = row.get("claim_group_id")
family = row.get("part_family")
pair = (str(group_id), str(family))
if pair not in expected_pairs or pair in observed_pairs:
raise ContractError("MANIFEST_PART_PAIR_INVALID", f"$/artifact_manifest/part_rows/{index}", repr(pair))
expected_path = f"map_s2_30/{PART_FILENAMES[str(family)]}/{group_id}.json"
if row.get("path") != expected_path or row.get("schema_ref") != PART_SCHEMA_REFS[str(family)]:
raise ContractError("MANIFEST_PART_BINDING_MISMATCH", f"$/artifact_manifest/part_rows/{index}", repr(row))
declared_paths.append(expected_path)
raw = part_bytes_by_path.get(expected_path)
if not isinstance(raw, bytes):
raise ContractError("MANIFEST_PART_BYTES_MISSING", f"$/parts/{expected_path}", repr(type(raw)))
if sha256_bytes(raw) != row.get("sha256"):
raise ContractError("MANIFEST_PART_RAW_HASH_MISMATCH", f"$/parts/{expected_path}", repr(row.get("sha256")))
part = parse_canonical_json_object(raw, f"$/parts/{expected_path}")
validate_persisted_part(
part,
str(family),
expected_group_id=str(group_id),
expected_common_provenance=common,
schema=schema,
path=f"$/parts/{expected_path}",
)
observed_provenance = dict(part["provenance"])
previous_provenance = group_provenance.get(str(group_id))
if previous_provenance is not None and observed_provenance != previous_provenance:
raise ContractError(
"PART_GROUP_PROVENANCE_MISMATCH",
f"$/parts/{expected_path}/provenance",
repr((previous_provenance, observed_provenance)),
)
group_provenance[str(group_id)] = observed_provenance
observed_pairs.add(pair)
if observed_pairs != expected_pairs:
raise ContractError("MANIFEST_PART_SET_MISMATCH", "$/artifact_manifest/part_rows", repr((observed_pairs, expected_pairs)))
if set(part_bytes_by_path) != set(declared_paths):
raise ContractError(
"UNENUMERATED_PART_INPUT_FORBIDDEN",
"$/parts",
repr(sorted(set(part_bytes_by_path) ^ set(declared_paths))),
)
return {
"status": "PASS",
"claim_group_ids": expected_groups,
"part_count": len(rows),
"part_manifest_core_sha256": manifest["part_manifest_core_sha256"],
"group_provenance": group_provenance,
}
def _validate_receipt_object(
receipt: Mapping[str, Any],
def_name: str,
manifest_core_sha256: str,
common_provenance: Mapping[str, Any],
expected_group_provenance: Mapping[str, Any] | None,
schema: Mapping[str, Any] | None,
path: str,
) -> None:
if schema is not None:
validate_instance(receipt, def_name, schema)
_require_self_hash(receipt, "receipt_sha256", path)
if receipt.get("part_manifest_core_sha256") != manifest_core_sha256:
raise ContractError(
"RECEIPT_MANIFEST_CORE_HASH_MISMATCH",
f"{path}/part_manifest_core_sha256",
repr(receipt.get("part_manifest_core_sha256")),
)
provenance = receipt.get("provenance")
if not isinstance(provenance, dict):
raise ContractError("HANDOFF_PROVENANCE_REQUIRED", f"{path}/provenance", repr(provenance))
_validate_handoff_provenance(
provenance,
common_only=def_name == "cohort_receipt",
path=f"{path}/provenance",
)
if _common_provenance(provenance) != dict(common_provenance):
raise ContractError("RECEIPT_COMMON_PROVENANCE_MISMATCH", f"{path}/provenance", repr(provenance))
if expected_group_provenance is not None and dict(provenance) != dict(expected_group_provenance):
raise ContractError("ITEM_RECEIPT_GROUP_PROVENANCE_MISMATCH", f"{path}/provenance", repr(provenance))
def validate_handoff_chain(
publish_status: Mapping[str, Any],
manifest: Mapping[str, Any],
part_bytes_by_path: Mapping[str, bytes],
item_receipt_bytes_by_path: Mapping[str, bytes],
cohort_receipt_bytes_by_path: Mapping[str, bytes],
schema: Mapping[str, Any] | None = None,
) -> dict[str, Any]:
"""Validate barrier -> manifest -> parts and ordered receipts without scan/glob."""
if schema is not None:
validate_instance(publish_status, "publish_status", schema)
_require_self_hash(publish_status, "status_sha256", "$/publish_status")
manifest_report = validate_part_manifest_core(manifest, part_bytes_by_path, schema)
manifest_raw = canonical_json_bytes(manifest)
if publish_status.get("artifact_manifest_sha256") != sha256_bytes(manifest_raw):
raise ContractError("PUBLISH_MANIFEST_RAW_HASH_MISMATCH", "$/publish_status/artifact_manifest_sha256", "raw")
if publish_status.get("artifact_manifest_path") != "map_s2_30/artifact_manifest.json":
raise ContractError("PUBLISH_MANIFEST_PATH_MISMATCH", "$/publish_status/artifact_manifest_path", repr(publish_status.get("artifact_manifest_path")))
common = manifest["provenance"]
if publish_status.get("provenance") != common:
raise ContractError("PUBLISH_COMMON_PROVENANCE_MISMATCH", "$/publish_status/provenance", "manifest")
if publish_status.get("compile_mode") != common.get("compile_mode"):
raise ContractError("PUBLISH_COMPILE_MODE_MISMATCH", "$/publish_status/compile_mode", repr(publish_status.get("compile_mode")))
if publish_status.get("parent_stage2_release_sha256") != common.get("parent_stage2_release_sha256") or publish_status.get("s2_30_release_sha256") != common.get("s2_30_release_sha256"):
raise ContractError("PUBLISH_RELEASE_PROVENANCE_MISMATCH", "$/publish_status", "release")
expected_groups = list(manifest["expected_claim_group_ids"])
if publish_status.get("expected_claim_group_ids") != expected_groups or publish_status.get("published_claim_group_ids") != expected_groups:
raise ContractError("PUBLISH_GROUP_SET_MISMATCH", "$/publish_status", repr(expected_groups))
if publish_status.get("terminal_failure_claim_group_ids") != [] or publish_status.get("status") != "S2_30_COMPLETE" or publish_status.get("route") != "TO_S2_40":
raise ContractError("PUBLISH_SUCCESS_ROUTE_INVALID", "$/publish_status", repr(publish_status.get("route")))
item_refs = publish_status.get("ordered_item_receipts")
cohort_refs = publish_status.get("ordered_cohort_receipts")
if not isinstance(item_refs, list) or any(not isinstance(row, dict) for row in item_refs):
raise ContractError("ITEM_RECEIPT_REFS_INVALID", "$/publish_status/ordered_item_receipts", repr(item_refs))
if not isinstance(cohort_refs, list) or any(not isinstance(row, dict) for row in cohort_refs):
raise ContractError("COHORT_RECEIPT_REFS_INVALID", "$/publish_status/ordered_cohort_receipts", repr(cohort_refs))
if item_refs != sorted(item_refs, key=lambda row: (row.get("claim_group_id"), row.get("path"))):
raise ContractError("ITEM_RECEIPT_ORDER_INVALID", "$/publish_status/ordered_item_receipts", repr(item_refs))
if cohort_refs != sorted(cohort_refs, key=lambda row: row.get("path")):
raise ContractError("COHORT_RECEIPT_ORDER_INVALID", "$/publish_status/ordered_cohort_receipts", repr(cohort_refs))
if [row.get("claim_group_id") for row in item_refs] != expected_groups:
raise ContractError("ITEM_RECEIPT_GROUP_SET_MISMATCH", "$/publish_status/ordered_item_receipts", repr(item_refs))
if set(item_receipt_bytes_by_path) != {row.get("path") for row in item_refs}:
raise ContractError("ITEM_RECEIPT_INPUT_SET_MISMATCH", "$/item_receipts", repr(sorted(item_receipt_bytes_by_path)))
if set(cohort_receipt_bytes_by_path) != {row.get("path") for row in cohort_refs}:
raise ContractError("COHORT_RECEIPT_INPUT_SET_MISMATCH", "$/cohort_receipts", repr(sorted(cohort_receipt_bytes_by_path)))
for index, ref in enumerate(item_refs):
raw = item_receipt_bytes_by_path[ref["path"]]
if sha256_bytes(raw) != ref.get("sha256"):
raise ContractError("ITEM_RECEIPT_RAW_HASH_MISMATCH", f"$/item_receipts/{index}", ref["path"])
receipt = parse_canonical_json_object(raw, f"$/item_receipts/{index}")
_validate_receipt_object(
receipt,
"item_receipt",
manifest["part_manifest_core_sha256"],
common,
manifest_report["group_provenance"].get(str(ref.get("claim_group_id"))),
schema,
f"$/item_receipts/{index}",
)
if receipt.get("claim_group_id") != ref.get("claim_group_id"):
raise ContractError("ITEM_RECEIPT_GROUP_MISMATCH", f"$/item_receipts/{index}", ref["path"])
for index, ref in enumerate(cohort_refs):
raw = cohort_receipt_bytes_by_path[ref["path"]]
if sha256_bytes(raw) != ref.get("sha256"):
raise ContractError("COHORT_RECEIPT_RAW_HASH_MISMATCH", f"$/cohort_receipts/{index}", ref["path"])
receipt = parse_canonical_json_object(raw, f"$/cohort_receipts/{index}")
_validate_receipt_object(
receipt,
"cohort_receipt",
manifest["part_manifest_core_sha256"],
common,
None,
schema,
f"$/cohort_receipts/{index}",
)
return {
"status": "PASS",
"publish_status_allowed": True,
"claim_group_ids": expected_groups,
"part_count": manifest_report["part_count"],
"item_receipt_count": len(item_refs),
"cohort_receipt_count": len(cohort_refs),
"physical_atomicity_attested": False,
}
def validate_publish_barrier(bundle: Mapping[str, Any]) -> dict[str, Any]: def validate_publish_barrier(bundle: Mapping[str, Any]) -> dict[str, Any]:
"""Status-last barrier oracle over explicit objects/bytes; discovery is forbidden."""
expected = set(bundle.get("expected_group_ids", [])) expected = set(bundle.get("expected_group_ids", []))
succeeded = set(bundle.get("succeeded_group_ids", [])) succeeded = set(bundle.get("succeeded_group_ids", []))
failed = set(bundle.get("failed_group_ids", [])) failed = set(bundle.get("failed_group_ids", []))
if not expected or succeeded & failed or succeeded | failed != expected: if not expected or succeeded & failed or succeeded | failed != expected:
raise ContractError("PUBLISH_PARTITION_MISMATCH", "$", repr((expected, succeeded, failed))) raise ContractError("PUBLISH_PARTITION_MISMATCH", "$", repr((expected, succeeded, failed)))
artifact_rows = bundle.get("artifact_rows")
if not isinstance(artifact_rows, list):
raise ContractError("ARTIFACT_ROWS_REQUIRED", "$/artifact_rows", repr(type(artifact_rows)))
verified_families: dict[str, set[str]] = {group_id: set() for group_id in expected}
for index, row in enumerate(artifact_rows):
if not isinstance(row, dict):
raise ContractError("ARTIFACT_ROW_OBJECT_REQUIRED", f"$/artifact_rows/{index}", repr(row))
if set(row) != PUBLISH_ARTIFACT_ROW_FIELDS:
raise ContractError(
"ARTIFACT_ROW_CLOSED_SHAPE",
f"$/artifact_rows/{index}",
repr(sorted(set(row) ^ PUBLISH_ARTIFACT_ROW_FIELDS)),
)
_require_self_hash(row, "artifact_receipt_sha256", f"$/artifact_rows/{index}")
group_id = row.get("claim_group_id")
family = row.get("artifact_family")
if group_id not in expected or family not in SUCCESS_ARTIFACT_FAMILIES:
raise ContractError("ARTIFACT_FAMILY_OR_GROUP_INVALID", f"$/artifact_rows/{index}", repr((group_id, family)))
expected_path = f"map_s2_30/{SUCCESS_ARTIFACT_FILENAMES[str(family)]}/{group_id}.json"
receipt_path = f"map_s2_30/item_receipts/{group_id}.json"
if row.get("artifact_path") != expected_path or row.get("item_receipt_path") != receipt_path:
raise ContractError(
"ARTIFACT_PATH_BINDING_MISMATCH",
f"$/artifact_rows/{index}",
repr((row.get("artifact_path"), row.get("item_receipt_path"))),
)
artifact_sha = row.get("artifact_sha256")
read_back_sha = row.get("read_back_sha256")
item_receipt_sha = row.get("item_receipt_sha256")
if any(
not isinstance(value, str) or HEX64.fullmatch(value) is None
for value in (artifact_sha, read_back_sha, item_receipt_sha)
):
raise ContractError("ARTIFACT_HASH_INVALID", f"$/artifact_rows/{index}", repr(row))
if artifact_sha != read_back_sha:
raise ContractError(
"ARTIFACT_READ_BACK_HASH_MISMATCH",
f"$/artifact_rows/{index}",
repr((artifact_sha, read_back_sha)),
)
if family == "ITEM_RECEIPT" and artifact_sha != item_receipt_sha:
raise ContractError(
"ITEM_RECEIPT_HASH_BINDING_MISMATCH",
f"$/artifact_rows/{index}",
repr((artifact_sha, item_receipt_sha)),
)
if (
row.get("immutable_write_status") in {"CREATED", "IDEMPOTENT_MATCH"}
and row.get("read_back_status") == "PASS"
and row.get("item_receipt_persistence_status") in {"PUBLISHED", "IDEMPOTENT_BYTE_IDENTICAL"}
):
if family in verified_families[str(group_id)]:
raise ContractError("ARTIFACT_FAMILY_DUPLICATE", f"$/artifact_rows/{index}", str(family))
verified_families[str(group_id)].add(str(family))
verified = {
group_id
for group_id, families in verified_families.items()
if families == SUCCESS_ARTIFACT_FAMILIES
}
status_written = bool(bundle.get("publish_status_written")) status_written = bool(bundle.get("publish_status_written"))
if status_written and (failed or verified != expected): if status_written and failed:
raise ContractError("STATUS_LAST_BARRIER_VIOLATION", "$/publish_status_written", repr((verified, expected, failed))) raise ContractError("STATUS_LAST_BARRIER_VIOLATION", "$/publish_status_written", repr(sorted(failed)))
return { required = (
"status": "PASS", "publish_status",
"publish_status_allowed": not failed and verified == expected, "artifact_manifest",
"physical_atomicity_attested": False, "part_bytes_by_path",
} "item_receipt_bytes_by_path",
"cohort_receipt_bytes_by_path",
)
missing = [key for key in required if key not in bundle]
if missing:
raise ContractError("STATUS_LAST_BARRIER_VIOLATION", "$", repr(missing))
report = validate_handoff_chain(
bundle["publish_status"],
bundle["artifact_manifest"],
bundle["part_bytes_by_path"],
bundle["item_receipt_bytes_by_path"],
bundle["cohort_receipt_bytes_by_path"],
bundle.get("schema"),
)
if set(report["claim_group_ids"]) != expected:
raise ContractError("PUBLISH_GROUP_SET_MISMATCH", "$", repr((report["claim_group_ids"], sorted(expected))))
report["publish_status_allowed"] = status_written and not failed
return report
def validate_pending_external_receipt(kind: str, receipt: Mapping[str, Any]) -> None: def validate_pending_external_receipt(kind: str, receipt: Mapping[str, Any]) -> None:
@@ -1866,7 +2132,7 @@ def validate_embedded_task_admission(
if not isinstance(stage_rows, list) or not isinstance(helper_rows, list): if not isinstance(stage_rows, list) or not isinstance(helper_rows, list):
raise ContractError("EXECUTOR_BINDING_ARRAYS_REQUIRED", "$", "stage/helper") raise ContractError("EXECUTOR_BINDING_ARRAYS_REQUIRED", "$", "stage/helper")
stage_ids = [row.get("stage_id") for row in stage_rows if isinstance(row, dict)] stage_ids = [row.get("stage_id") for row in stage_rows if isinstance(row, dict)]
if stage_ids != ["S2_00", "S2_20"] or "S2_30" in stage_ids: if stage_ids != ["S2_00", "S2_20", "S2_40"] or "S2_30" in stage_ids:
raise ContractError("S2_30_STAGE_MISCLASSIFIED", "$/stage_bindings", repr(stage_ids)) raise ContractError("S2_30_STAGE_MISCLASSIFIED", "$/stage_bindings", repr(stage_ids))
if len(helper_rows) != 1 or not isinstance(helper_rows[0], dict): if len(helper_rows) != 1 or not isinstance(helper_rows[0], dict):
raise ContractError("S2_30_HELPER_EXACT_ONE_REQUIRED", "$/embedded_task_bindings", repr(helper_rows)) raise ContractError("S2_30_HELPER_EXACT_ONE_REQUIRED", "$/embedded_task_bindings", repr(helper_rows))
@@ -1907,7 +2173,7 @@ def validate_embedded_task_admission(
if admission.get("executor_binding_sha256") != binding_sha256: if admission.get("executor_binding_sha256") != binding_sha256:
raise ContractError("ADMISSION_EXECUTOR_HASH_MISMATCH", "$/executor_binding_sha256", repr(admission.get("executor_binding_sha256"))) raise ContractError("ADMISSION_EXECUTOR_HASH_MISMATCH", "$/executor_binding_sha256", repr(admission.get("executor_binding_sha256")))
if admission.get("present_deterministic_stage_ids") != ["S2_00", "S2_20"]: if admission.get("present_deterministic_stage_ids") != ["S2_00", "S2_20", "S2_40"]:
raise ContractError("ADMISSION_STAGE_SET_MISMATCH", "$/present_deterministic_stage_ids", repr(admission.get("present_deterministic_stage_ids"))) raise ContractError("ADMISSION_STAGE_SET_MISMATCH", "$/present_deterministic_stage_ids", repr(admission.get("present_deterministic_stage_ids")))
embedded = admission.get("embedded_task_admissions") embedded = admission.get("embedded_task_admissions")
if not isinstance(embedded, list) or len(embedded) != 1 or not isinstance(embedded[0], dict): if not isinstance(embedded, list) or len(embedded) != 1 or not isinstance(embedded[0], dict):
@@ -125,29 +125,46 @@ ADVERSE_REQUIRED = frozenset(
"presentation_authorization_ref", "presentation_authorization_ref",
} }
) )
SUCCESS_ARTIFACT_FAMILIES = frozenset( PART_FAMILIES = frozenset(
{"DRAFT_PART", "ISSUE_PATCH", "WORKNOTE_PART", "USAGE_PART", "ITEM_RECEIPT"} {"DRAFT_PART", "ISSUE_PATCH", "WORKNOTE_PART", "USAGE_PART"}
) )
SUCCESS_ARTIFACT_FILENAMES = { PART_FILENAMES = {
"DRAFT_PART": "draft_parts", "DRAFT_PART": "draft_parts",
"ISSUE_PATCH": "issue_patches", "ISSUE_PATCH": "issue_patches",
"WORKNOTE_PART": "worknote_parts", "WORKNOTE_PART": "worknote_parts",
"USAGE_PART": "usage_parts", "USAGE_PART": "usage_parts",
"ITEM_RECEIPT": "item_receipts",
} }
PUBLISH_ARTIFACT_ROW_FIELDS = frozenset( PART_SCHEMA_REFS = {
"DRAFT_PART": "schemas/draft_atoms.schema.json#/$defs/draft_part",
"ISSUE_PATCH": "schemas/draft_atoms.schema.json#/$defs/issue_patch_part",
"WORKNOTE_PART": "schemas/draft_atoms.schema.json#/$defs/worknote_part",
"USAGE_PART": "schemas/draft_atoms.schema.json#/$defs/usage_part",
}
PART_DEF_NAMES = {
"DRAFT_PART": "draft_part",
"ISSUE_PATCH": "issue_patch_part",
"WORKNOTE_PART": "worknote_part",
"USAGE_PART": "usage_part",
}
PART_SELF_HASH_FIELDS = {family: "part_sha256" for family in PART_FAMILIES}
COMMON_PROVENANCE_FIELDS = frozenset(
{ {
"claim_group_id", "compile_mode",
"artifact_family", "parent_stage2_release_sha256",
"artifact_path", "s2_30_release_sha256",
"artifact_sha256", "s2_30_agent_sha256",
"read_back_sha256", "s2_30_binding_sha256",
"immutable_write_status", "p00_prompt_sha256",
"read_back_status", "p30_prompt_sha256",
"item_receipt_path", "s2_30_producer_contract_digest",
"item_receipt_sha256", }
"item_receipt_persistence_status", )
"artifact_receipt_sha256", GROUP_PROVENANCE_FIELDS = frozenset(
{
*COMMON_PROVENANCE_FIELDS,
"p31_rule_and_pack_sha256",
"p32_common_authority_sha256",
"s30_group_slice_sha256",
} }
) )
REQUIRED_PENDING = { REQUIRED_PENDING = {
@@ -1765,79 +1782,328 @@ def evaluate_retry(
raise ContractError("ATTEMPT_NO_INVALID", "$/attempt_no", repr(attempt_no)) raise ContractError("ATTEMPT_NO_INVALID", "$/attempt_no", repr(attempt_no))
def _validate_handoff_provenance(
provenance: Mapping[str, Any],
*,
common_only: bool,
path: str,
) -> None:
expected = COMMON_PROVENANCE_FIELDS if common_only else GROUP_PROVENANCE_FIELDS
if set(provenance) != expected:
raise ContractError(
"HANDOFF_PROVENANCE_CLOSED_SHAPE",
path,
repr(sorted(set(provenance) ^ expected)),
)
if provenance.get("compile_mode") not in ALLOWED_MODES:
raise ContractError(
"COMPILE_MODE_INVALID", f"{path}/compile_mode", repr(provenance.get("compile_mode"))
)
for key in expected - {"compile_mode"}:
value = provenance.get(key)
if not isinstance(value, str) or HEX64.fullmatch(value) is None:
raise ContractError("HANDOFF_PROVENANCE_HASH_INVALID", f"{path}/{key}", repr(value))
def _common_provenance(provenance: Mapping[str, Any]) -> dict[str, Any]:
return {key: provenance[key] for key in sorted(COMMON_PROVENANCE_FIELDS)}
def validate_persisted_part(
part: Mapping[str, Any],
family: str,
*,
expected_group_id: str | None = None,
expected_common_provenance: Mapping[str, Any] | None = None,
schema: Mapping[str, Any] | None = None,
path: str = "$/part",
) -> dict[str, Any]:
"""Validate one immutable S2_30 physical part without discovering siblings."""
if family not in PART_FAMILIES:
raise ContractError("PART_FAMILY_INVALID", path, repr(family))
if schema is not None:
validate_instance(part, PART_DEF_NAMES[family], schema)
_require_self_hash(part, PART_SELF_HASH_FIELDS[family], path)
group_id = part.get("claim_group_id")
if expected_group_id is not None and group_id != expected_group_id:
raise ContractError(
"PART_GROUP_MISMATCH", f"{path}/claim_group_id", repr((group_id, expected_group_id))
)
provenance = part.get("provenance")
if not isinstance(provenance, dict):
raise ContractError("HANDOFF_PROVENANCE_REQUIRED", f"{path}/provenance", repr(provenance))
_validate_handoff_provenance(provenance, common_only=False, path=f"{path}/provenance")
if expected_common_provenance is not None and _common_provenance(provenance) != dict(
expected_common_provenance
):
raise ContractError(
"PART_COMMON_PROVENANCE_MISMATCH",
f"{path}/provenance",
repr((_common_provenance(provenance), dict(expected_common_provenance))),
)
if family == "DRAFT_PART":
atoms = part.get("canonical_atoms")
atom_ids = [row.get("atom_id") for row in atoms] if isinstance(atoms, list) else []
if len(atom_ids) != len(set(atom_ids)):
raise ContractError("DRAFT_PART_ATOM_ID_DUPLICATE", f"{path}/canonical_atoms", repr(atom_ids))
if any(isinstance(row, dict) and row.get("claim_group_id") != group_id for row in atoms or []):
raise ContractError("DRAFT_PART_ATOM_GROUP_MISMATCH", f"{path}/canonical_atoms", repr(group_id))
coverage = part.get("atomic_claim_coverage")
coverage_refs = [
ref
for row in coverage or []
if isinstance(row, dict)
for key in ("relief_atom_local_refs", "cause_atom_local_refs")
for ref in row.get(key, [])
]
if len(coverage_refs) != len(set(coverage_refs)) or set(coverage_refs) != set(atom_ids) - {
row.get("atom_id")
for row in atoms or []
if isinstance(row, dict) and row.get("output_section") in {"procedural_declaration", "worknote_only"}
}:
raise ContractError("DRAFT_PART_COVERAGE_PARTITION_MISMATCH", f"{path}/atomic_claim_coverage", repr(coverage_refs))
return {"status": "PASS", "claim_group_id": group_id, "part_family": family}
def validate_part_manifest_core(
manifest: Mapping[str, Any],
part_bytes_by_path: Mapping[str, bytes],
schema: Mapping[str, Any] | None = None,
) -> dict[str, Any]:
"""Validate the receipt-free exact part index using only enumerated byte inputs."""
if schema is not None:
validate_instance(manifest, "part_manifest_core", schema)
_require_self_hash(manifest, "part_manifest_core_sha256", "$/artifact_manifest")
if any("receipt" in key.lower() for key in manifest):
raise ContractError("MANIFEST_RECEIPT_REFERENCE_FORBIDDEN", "$/artifact_manifest", repr(sorted(manifest)))
common = manifest.get("provenance")
if not isinstance(common, dict):
raise ContractError("HANDOFF_PROVENANCE_REQUIRED", "$/artifact_manifest/provenance", repr(common))
_validate_handoff_provenance(common, common_only=True, path="$/artifact_manifest/provenance")
expected_groups = manifest.get("expected_claim_group_ids")
if not isinstance(expected_groups, list) or expected_groups != sorted(expected_groups):
raise ContractError("MANIFEST_GROUP_ORDER_INVALID", "$/artifact_manifest/expected_claim_group_ids", repr(expected_groups))
rows = manifest.get("part_rows")
if not isinstance(rows, list):
raise ContractError("MANIFEST_PART_ROWS_REQUIRED", "$/artifact_manifest/part_rows", repr(rows))
if any(not isinstance(row, dict) for row in rows):
raise ContractError("MANIFEST_PART_ROW_OBJECT_REQUIRED", "$/artifact_manifest/part_rows", repr(rows))
sort_key = lambda row: (row.get("claim_group_id"), row.get("part_family"), row.get("path"))
if rows != sorted(rows, key=sort_key):
raise ContractError("MANIFEST_PART_ROW_ORDER_INVALID", "$/artifact_manifest/part_rows", "not stable sorted")
expected_pairs = {(group_id, family) for group_id in expected_groups for family in PART_FAMILIES}
observed_pairs: set[tuple[str, str]] = set()
declared_paths: list[str] = []
group_provenance: dict[str, dict[str, Any]] = {}
for index, row in enumerate(rows):
if not isinstance(row, dict):
raise ContractError("MANIFEST_PART_ROW_OBJECT_REQUIRED", f"$/artifact_manifest/part_rows/{index}", repr(row))
group_id = row.get("claim_group_id")
family = row.get("part_family")
pair = (str(group_id), str(family))
if pair not in expected_pairs or pair in observed_pairs:
raise ContractError("MANIFEST_PART_PAIR_INVALID", f"$/artifact_manifest/part_rows/{index}", repr(pair))
expected_path = f"map_s2_30/{PART_FILENAMES[str(family)]}/{group_id}.json"
if row.get("path") != expected_path or row.get("schema_ref") != PART_SCHEMA_REFS[str(family)]:
raise ContractError("MANIFEST_PART_BINDING_MISMATCH", f"$/artifact_manifest/part_rows/{index}", repr(row))
declared_paths.append(expected_path)
raw = part_bytes_by_path.get(expected_path)
if not isinstance(raw, bytes):
raise ContractError("MANIFEST_PART_BYTES_MISSING", f"$/parts/{expected_path}", repr(type(raw)))
if sha256_bytes(raw) != row.get("sha256"):
raise ContractError("MANIFEST_PART_RAW_HASH_MISMATCH", f"$/parts/{expected_path}", repr(row.get("sha256")))
part = parse_canonical_json_object(raw, f"$/parts/{expected_path}")
validate_persisted_part(
part,
str(family),
expected_group_id=str(group_id),
expected_common_provenance=common,
schema=schema,
path=f"$/parts/{expected_path}",
)
observed_provenance = dict(part["provenance"])
previous_provenance = group_provenance.get(str(group_id))
if previous_provenance is not None and observed_provenance != previous_provenance:
raise ContractError(
"PART_GROUP_PROVENANCE_MISMATCH",
f"$/parts/{expected_path}/provenance",
repr((previous_provenance, observed_provenance)),
)
group_provenance[str(group_id)] = observed_provenance
observed_pairs.add(pair)
if observed_pairs != expected_pairs:
raise ContractError("MANIFEST_PART_SET_MISMATCH", "$/artifact_manifest/part_rows", repr((observed_pairs, expected_pairs)))
if set(part_bytes_by_path) != set(declared_paths):
raise ContractError(
"UNENUMERATED_PART_INPUT_FORBIDDEN",
"$/parts",
repr(sorted(set(part_bytes_by_path) ^ set(declared_paths))),
)
return {
"status": "PASS",
"claim_group_ids": expected_groups,
"part_count": len(rows),
"part_manifest_core_sha256": manifest["part_manifest_core_sha256"],
"group_provenance": group_provenance,
}
def _validate_receipt_object(
receipt: Mapping[str, Any],
def_name: str,
manifest_core_sha256: str,
common_provenance: Mapping[str, Any],
expected_group_provenance: Mapping[str, Any] | None,
schema: Mapping[str, Any] | None,
path: str,
) -> None:
if schema is not None:
validate_instance(receipt, def_name, schema)
_require_self_hash(receipt, "receipt_sha256", path)
if receipt.get("part_manifest_core_sha256") != manifest_core_sha256:
raise ContractError(
"RECEIPT_MANIFEST_CORE_HASH_MISMATCH",
f"{path}/part_manifest_core_sha256",
repr(receipt.get("part_manifest_core_sha256")),
)
provenance = receipt.get("provenance")
if not isinstance(provenance, dict):
raise ContractError("HANDOFF_PROVENANCE_REQUIRED", f"{path}/provenance", repr(provenance))
_validate_handoff_provenance(
provenance,
common_only=def_name == "cohort_receipt",
path=f"{path}/provenance",
)
if _common_provenance(provenance) != dict(common_provenance):
raise ContractError("RECEIPT_COMMON_PROVENANCE_MISMATCH", f"{path}/provenance", repr(provenance))
if expected_group_provenance is not None and dict(provenance) != dict(expected_group_provenance):
raise ContractError("ITEM_RECEIPT_GROUP_PROVENANCE_MISMATCH", f"{path}/provenance", repr(provenance))
def validate_handoff_chain(
publish_status: Mapping[str, Any],
manifest: Mapping[str, Any],
part_bytes_by_path: Mapping[str, bytes],
item_receipt_bytes_by_path: Mapping[str, bytes],
cohort_receipt_bytes_by_path: Mapping[str, bytes],
schema: Mapping[str, Any] | None = None,
) -> dict[str, Any]:
"""Validate barrier -> manifest -> parts and ordered receipts without scan/glob."""
if schema is not None:
validate_instance(publish_status, "publish_status", schema)
_require_self_hash(publish_status, "status_sha256", "$/publish_status")
manifest_report = validate_part_manifest_core(manifest, part_bytes_by_path, schema)
manifest_raw = canonical_json_bytes(manifest)
if publish_status.get("artifact_manifest_sha256") != sha256_bytes(manifest_raw):
raise ContractError("PUBLISH_MANIFEST_RAW_HASH_MISMATCH", "$/publish_status/artifact_manifest_sha256", "raw")
if publish_status.get("artifact_manifest_path") != "map_s2_30/artifact_manifest.json":
raise ContractError("PUBLISH_MANIFEST_PATH_MISMATCH", "$/publish_status/artifact_manifest_path", repr(publish_status.get("artifact_manifest_path")))
common = manifest["provenance"]
if publish_status.get("provenance") != common:
raise ContractError("PUBLISH_COMMON_PROVENANCE_MISMATCH", "$/publish_status/provenance", "manifest")
if publish_status.get("compile_mode") != common.get("compile_mode"):
raise ContractError("PUBLISH_COMPILE_MODE_MISMATCH", "$/publish_status/compile_mode", repr(publish_status.get("compile_mode")))
if publish_status.get("parent_stage2_release_sha256") != common.get("parent_stage2_release_sha256") or publish_status.get("s2_30_release_sha256") != common.get("s2_30_release_sha256"):
raise ContractError("PUBLISH_RELEASE_PROVENANCE_MISMATCH", "$/publish_status", "release")
expected_groups = list(manifest["expected_claim_group_ids"])
if publish_status.get("expected_claim_group_ids") != expected_groups or publish_status.get("published_claim_group_ids") != expected_groups:
raise ContractError("PUBLISH_GROUP_SET_MISMATCH", "$/publish_status", repr(expected_groups))
if publish_status.get("terminal_failure_claim_group_ids") != [] or publish_status.get("status") != "S2_30_COMPLETE" or publish_status.get("route") != "TO_S2_40":
raise ContractError("PUBLISH_SUCCESS_ROUTE_INVALID", "$/publish_status", repr(publish_status.get("route")))
item_refs = publish_status.get("ordered_item_receipts")
cohort_refs = publish_status.get("ordered_cohort_receipts")
if not isinstance(item_refs, list) or any(not isinstance(row, dict) for row in item_refs):
raise ContractError("ITEM_RECEIPT_REFS_INVALID", "$/publish_status/ordered_item_receipts", repr(item_refs))
if not isinstance(cohort_refs, list) or any(not isinstance(row, dict) for row in cohort_refs):
raise ContractError("COHORT_RECEIPT_REFS_INVALID", "$/publish_status/ordered_cohort_receipts", repr(cohort_refs))
if item_refs != sorted(item_refs, key=lambda row: (row.get("claim_group_id"), row.get("path"))):
raise ContractError("ITEM_RECEIPT_ORDER_INVALID", "$/publish_status/ordered_item_receipts", repr(item_refs))
if cohort_refs != sorted(cohort_refs, key=lambda row: row.get("path")):
raise ContractError("COHORT_RECEIPT_ORDER_INVALID", "$/publish_status/ordered_cohort_receipts", repr(cohort_refs))
if [row.get("claim_group_id") for row in item_refs] != expected_groups:
raise ContractError("ITEM_RECEIPT_GROUP_SET_MISMATCH", "$/publish_status/ordered_item_receipts", repr(item_refs))
if set(item_receipt_bytes_by_path) != {row.get("path") for row in item_refs}:
raise ContractError("ITEM_RECEIPT_INPUT_SET_MISMATCH", "$/item_receipts", repr(sorted(item_receipt_bytes_by_path)))
if set(cohort_receipt_bytes_by_path) != {row.get("path") for row in cohort_refs}:
raise ContractError("COHORT_RECEIPT_INPUT_SET_MISMATCH", "$/cohort_receipts", repr(sorted(cohort_receipt_bytes_by_path)))
for index, ref in enumerate(item_refs):
raw = item_receipt_bytes_by_path[ref["path"]]
if sha256_bytes(raw) != ref.get("sha256"):
raise ContractError("ITEM_RECEIPT_RAW_HASH_MISMATCH", f"$/item_receipts/{index}", ref["path"])
receipt = parse_canonical_json_object(raw, f"$/item_receipts/{index}")
_validate_receipt_object(
receipt,
"item_receipt",
manifest["part_manifest_core_sha256"],
common,
manifest_report["group_provenance"].get(str(ref.get("claim_group_id"))),
schema,
f"$/item_receipts/{index}",
)
if receipt.get("claim_group_id") != ref.get("claim_group_id"):
raise ContractError("ITEM_RECEIPT_GROUP_MISMATCH", f"$/item_receipts/{index}", ref["path"])
for index, ref in enumerate(cohort_refs):
raw = cohort_receipt_bytes_by_path[ref["path"]]
if sha256_bytes(raw) != ref.get("sha256"):
raise ContractError("COHORT_RECEIPT_RAW_HASH_MISMATCH", f"$/cohort_receipts/{index}", ref["path"])
receipt = parse_canonical_json_object(raw, f"$/cohort_receipts/{index}")
_validate_receipt_object(
receipt,
"cohort_receipt",
manifest["part_manifest_core_sha256"],
common,
None,
schema,
f"$/cohort_receipts/{index}",
)
return {
"status": "PASS",
"publish_status_allowed": True,
"claim_group_ids": expected_groups,
"part_count": manifest_report["part_count"],
"item_receipt_count": len(item_refs),
"cohort_receipt_count": len(cohort_refs),
"physical_atomicity_attested": False,
}
def validate_publish_barrier(bundle: Mapping[str, Any]) -> dict[str, Any]: def validate_publish_barrier(bundle: Mapping[str, Any]) -> dict[str, Any]:
"""Status-last barrier oracle over explicit objects/bytes; discovery is forbidden."""
expected = set(bundle.get("expected_group_ids", [])) expected = set(bundle.get("expected_group_ids", []))
succeeded = set(bundle.get("succeeded_group_ids", [])) succeeded = set(bundle.get("succeeded_group_ids", []))
failed = set(bundle.get("failed_group_ids", [])) failed = set(bundle.get("failed_group_ids", []))
if not expected or succeeded & failed or succeeded | failed != expected: if not expected or succeeded & failed or succeeded | failed != expected:
raise ContractError("PUBLISH_PARTITION_MISMATCH", "$", repr((expected, succeeded, failed))) raise ContractError("PUBLISH_PARTITION_MISMATCH", "$", repr((expected, succeeded, failed)))
artifact_rows = bundle.get("artifact_rows")
if not isinstance(artifact_rows, list):
raise ContractError("ARTIFACT_ROWS_REQUIRED", "$/artifact_rows", repr(type(artifact_rows)))
verified_families: dict[str, set[str]] = {group_id: set() for group_id in expected}
for index, row in enumerate(artifact_rows):
if not isinstance(row, dict):
raise ContractError("ARTIFACT_ROW_OBJECT_REQUIRED", f"$/artifact_rows/{index}", repr(row))
if set(row) != PUBLISH_ARTIFACT_ROW_FIELDS:
raise ContractError(
"ARTIFACT_ROW_CLOSED_SHAPE",
f"$/artifact_rows/{index}",
repr(sorted(set(row) ^ PUBLISH_ARTIFACT_ROW_FIELDS)),
)
_require_self_hash(row, "artifact_receipt_sha256", f"$/artifact_rows/{index}")
group_id = row.get("claim_group_id")
family = row.get("artifact_family")
if group_id not in expected or family not in SUCCESS_ARTIFACT_FAMILIES:
raise ContractError("ARTIFACT_FAMILY_OR_GROUP_INVALID", f"$/artifact_rows/{index}", repr((group_id, family)))
expected_path = f"map_s2_30/{SUCCESS_ARTIFACT_FILENAMES[str(family)]}/{group_id}.json"
receipt_path = f"map_s2_30/item_receipts/{group_id}.json"
if row.get("artifact_path") != expected_path or row.get("item_receipt_path") != receipt_path:
raise ContractError(
"ARTIFACT_PATH_BINDING_MISMATCH",
f"$/artifact_rows/{index}",
repr((row.get("artifact_path"), row.get("item_receipt_path"))),
)
artifact_sha = row.get("artifact_sha256")
read_back_sha = row.get("read_back_sha256")
item_receipt_sha = row.get("item_receipt_sha256")
if any(
not isinstance(value, str) or HEX64.fullmatch(value) is None
for value in (artifact_sha, read_back_sha, item_receipt_sha)
):
raise ContractError("ARTIFACT_HASH_INVALID", f"$/artifact_rows/{index}", repr(row))
if artifact_sha != read_back_sha:
raise ContractError(
"ARTIFACT_READ_BACK_HASH_MISMATCH",
f"$/artifact_rows/{index}",
repr((artifact_sha, read_back_sha)),
)
if family == "ITEM_RECEIPT" and artifact_sha != item_receipt_sha:
raise ContractError(
"ITEM_RECEIPT_HASH_BINDING_MISMATCH",
f"$/artifact_rows/{index}",
repr((artifact_sha, item_receipt_sha)),
)
if (
row.get("immutable_write_status") in {"CREATED", "IDEMPOTENT_MATCH"}
and row.get("read_back_status") == "PASS"
and row.get("item_receipt_persistence_status") in {"PUBLISHED", "IDEMPOTENT_BYTE_IDENTICAL"}
):
if family in verified_families[str(group_id)]:
raise ContractError("ARTIFACT_FAMILY_DUPLICATE", f"$/artifact_rows/{index}", str(family))
verified_families[str(group_id)].add(str(family))
verified = {
group_id
for group_id, families in verified_families.items()
if families == SUCCESS_ARTIFACT_FAMILIES
}
status_written = bool(bundle.get("publish_status_written")) status_written = bool(bundle.get("publish_status_written"))
if status_written and (failed or verified != expected): if status_written and failed:
raise ContractError("STATUS_LAST_BARRIER_VIOLATION", "$/publish_status_written", repr((verified, expected, failed))) raise ContractError("STATUS_LAST_BARRIER_VIOLATION", "$/publish_status_written", repr(sorted(failed)))
return { required = (
"status": "PASS", "publish_status",
"publish_status_allowed": not failed and verified == expected, "artifact_manifest",
"physical_atomicity_attested": False, "part_bytes_by_path",
} "item_receipt_bytes_by_path",
"cohort_receipt_bytes_by_path",
)
missing = [key for key in required if key not in bundle]
if missing:
raise ContractError("STATUS_LAST_BARRIER_VIOLATION", "$", repr(missing))
report = validate_handoff_chain(
bundle["publish_status"],
bundle["artifact_manifest"],
bundle["part_bytes_by_path"],
bundle["item_receipt_bytes_by_path"],
bundle["cohort_receipt_bytes_by_path"],
bundle.get("schema"),
)
if set(report["claim_group_ids"]) != expected:
raise ContractError("PUBLISH_GROUP_SET_MISMATCH", "$", repr((report["claim_group_ids"], sorted(expected))))
report["publish_status_allowed"] = status_written and not failed
return report
def validate_pending_external_receipt(kind: str, receipt: Mapping[str, Any]) -> None: def validate_pending_external_receipt(kind: str, receipt: Mapping[str, Any]) -> None:
@@ -1866,7 +2132,7 @@ def validate_embedded_task_admission(
if not isinstance(stage_rows, list) or not isinstance(helper_rows, list): if not isinstance(stage_rows, list) or not isinstance(helper_rows, list):
raise ContractError("EXECUTOR_BINDING_ARRAYS_REQUIRED", "$", "stage/helper") raise ContractError("EXECUTOR_BINDING_ARRAYS_REQUIRED", "$", "stage/helper")
stage_ids = [row.get("stage_id") for row in stage_rows if isinstance(row, dict)] stage_ids = [row.get("stage_id") for row in stage_rows if isinstance(row, dict)]
if stage_ids != ["S2_00", "S2_20"] or "S2_30" in stage_ids: if stage_ids != ["S2_00", "S2_20", "S2_40"] or "S2_30" in stage_ids:
raise ContractError("S2_30_STAGE_MISCLASSIFIED", "$/stage_bindings", repr(stage_ids)) raise ContractError("S2_30_STAGE_MISCLASSIFIED", "$/stage_bindings", repr(stage_ids))
if len(helper_rows) != 1 or not isinstance(helper_rows[0], dict): if len(helper_rows) != 1 or not isinstance(helper_rows[0], dict):
raise ContractError("S2_30_HELPER_EXACT_ONE_REQUIRED", "$/embedded_task_bindings", repr(helper_rows)) raise ContractError("S2_30_HELPER_EXACT_ONE_REQUIRED", "$/embedded_task_bindings", repr(helper_rows))
@@ -1907,7 +2173,7 @@ def validate_embedded_task_admission(
if admission.get("executor_binding_sha256") != binding_sha256: if admission.get("executor_binding_sha256") != binding_sha256:
raise ContractError("ADMISSION_EXECUTOR_HASH_MISMATCH", "$/executor_binding_sha256", repr(admission.get("executor_binding_sha256"))) raise ContractError("ADMISSION_EXECUTOR_HASH_MISMATCH", "$/executor_binding_sha256", repr(admission.get("executor_binding_sha256")))
if admission.get("present_deterministic_stage_ids") != ["S2_00", "S2_20"]: if admission.get("present_deterministic_stage_ids") != ["S2_00", "S2_20", "S2_40"]:
raise ContractError("ADMISSION_STAGE_SET_MISMATCH", "$/present_deterministic_stage_ids", repr(admission.get("present_deterministic_stage_ids"))) raise ContractError("ADMISSION_STAGE_SET_MISMATCH", "$/present_deterministic_stage_ids", repr(admission.get("present_deterministic_stage_ids")))
embedded = admission.get("embedded_task_admissions") embedded = admission.get("embedded_task_admissions")
if not isinstance(embedded, list) or len(embedded) != 1 or not isinstance(embedded[0], dict): if not isinstance(embedded, list) or len(embedded) != 1 or not isinstance(embedded[0], dict):
@@ -5,28 +5,77 @@
"execution_eligible": false, "execution_eligible": false,
"runtime_legal_source": false, "runtime_legal_source": false,
"required_fixture_case_ids": [ "required_fixture_case_ids": [
"S20-F01-SINGLE-OPTION-GROUP", "S20-F01-SINGLE-OPTION-GROUP", "S20-F02-MIXED-PORTFOLIO", "S20-F03-CLIENT-NO-SUE",
"S20-F02-MIXED-PORTFOLIO", "S20-F04-CASE-RULE-EXACTNESS", "S20-F05-ROW-KIND-BRANCH", "S20-F06-PARTY-TITLE",
"S20-F03-CLIENT-NO-SUE", "S20-F07-CE01-INTEREST", "S20-F08-CE03-LIMITATION", "S20-F09-CE08-RESERVED-SHARE",
"S20-F04-CASE-RULE-EXACTNESS", "S20-F10-ACTIO-ROUTE-CAP", "S20-F11-CE13-COURT-VALUE", "S20-F12-RETRIEVAL-BOUNDARY",
"S20-F05-ROW-KIND-BRANCH", "S20-F13-CORPUS-INTEGRITY", "S20-F14-EXHIBIT-LABEL", "S20-F15-OPTION-SILENT-LOSS",
"S20-F06-PARTY-TITLE", "S20-F16-PUBLISH-BARRIER", "S20-F17-LEGACY-PATH"
"S20-F07-CE01-INTEREST",
"S20-F08-CE03-LIMITATION",
"S20-F09-CE08-RESERVED-SHARE",
"S20-F10-ACTIO-ROUTE-CAP",
"S20-F11-CE13-COURT-VALUE",
"S20-F12-RETRIEVAL-BOUNDARY",
"S20-F13-CORPUS-INTEGRITY",
"S20-F14-EXHIBIT-LABEL",
"S20-F15-OPTION-SILENT-LOSS",
"S20-F16-PUBLISH-BARRIER",
"S20-F17-LEGACY-PATH"
], ],
"mapping_rows": [], "mapping_rows": [
"mapped_fixture_case_count": 0, {"source_finding_id":"DR1-STAGE1_TO_STAGE2_FACT_LOSS","source_locator":"discrepancy_report_1.md","invariant_id":"V01","fixture_case_id":"S40-F006","mutation_id":"V01-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"IR1-CRITICAL_FACT_CONSERVATION","source_locator":"improvement_report_1.md","invariant_id":"V02","fixture_case_id":"S40-F006","mutation_id":"V02-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"IR2-DOMAIN_CONFIG_COMPLETENESS","source_locator":"improvement_report_2.md","invariant_id":"V03","fixture_case_id":"S40-F006","mutation_id":"V03-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"IR3-DEFENSE_CHAIN_LOSS","source_locator":"improvement_report_3.md","invariant_id":"V04","fixture_case_id":"S40-F006","mutation_id":"V04-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"IM-CLAIM_GROUP_RELATION","source_locator":"improvement_merged.md","invariant_id":"V05","fixture_case_id":"S40-F006","mutation_id":"V05-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"EVAL-M15-CASE-TYPE-PREDICATE","source_locator":"eval_stage_2_optimal_update_strategy_v.3.md","invariant_id":"V06","fixture_case_id":"S40-F006","mutation_id":"V06-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"DR3-ACTIO-CALCULATION-LOSS","source_locator":"discrepancy_report_3.md","invariant_id":"V07","fixture_case_id":"S40-F007","mutation_id":"V07-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"IM-SAME-RECOVERY-DUPLICATE","source_locator":"improvement_merged.md","invariant_id":"V08","fixture_case_id":"S40-F006","mutation_id":"V08-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"DR4-RELIEF-OBJECT-DATE-MISMATCH","source_locator":"discrepancy_report_4.md","invariant_id":"V09","fixture_case_id":"S40-F005","mutation_id":"V09-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"IM-RELIEF-FORM-NUMBERING","source_locator":"improvement_merged.md","invariant_id":"V10","fixture_case_id":"S40-F004","mutation_id":"V10-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"DR1-RELIEF-CAUSE-CROSSMATCH","source_locator":"discrepancy_report_1.md","invariant_id":"V11","fixture_case_id":"S40-F005","mutation_id":"V11-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"EVAL-M16-CORPUS-NAMESPACE","source_locator":"eval_stage_2_optimal_update_strategy_v.3.md","invariant_id":"V12","fixture_case_id":"S40-F006","mutation_id":"V12-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"EVAL-M13-LAW-VALUE-SEAL","source_locator":"eval_stage_2_optimal_update_strategy_v.3.md","invariant_id":"V13","fixture_case_id":"S40-F007","mutation_id":"V13-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"EVAL-M18-NONCYCLIC-SEAL","source_locator":"eval_stage_2_optimal_update_strategy_v.3.md","invariant_id":"V14","fixture_case_id":"S40-F015","mutation_id":"V14-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"EVAL-C1-CAUSE-ATOM-PROVENANCE","source_locator":"eval_stage_2_optimal_update_strategy_v.3.md","invariant_id":"V15","fixture_case_id":"S40-F008","mutation_id":"V15-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"IR4-OPTION-SILENT-LOSS","source_locator":"improvement_report_4.md","invariant_id":"V16","fixture_case_id":"S40-F003","mutation_id":"V16-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"DR2-OBJECT-EXHIBIT-COMPLETENESS","source_locator":"discrepancy_report_2.md","invariant_id":"V17","fixture_case_id":"S40-F008","mutation_id":"V17-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]},
{"source_finding_id":"IM-CLOSED-RENDERER-INDEPENDENCE","source_locator":"improvement_merged.md","invariant_id":"V18","fixture_case_id":"S40-F004","mutation_id":"V18-CONTRADICTION-OR-ABSENCE","expected_statuses":["FAIL","UNEVALUABLE"]}
],
"mapped_fixture_case_count": 7,
"required_fixture_case_count": 17, "required_fixture_case_count": 17,
"source_finding_families": ["discrepancy_report_1..4", "improvement_report_1..4", "improvement_merged", "eval_stage_2_optimal_update_strategy_v.3"], "s2_40_required_fixture_case_ids": [
"unresolved_reason_codes": ["SOURCE_FINDINGS_NOT_EXTRACTED","INVARIANT_MAPPING_NOT_REVIEWED","FIXTURE_CROSSWALK_NOT_SIGNED"], "S40-F001", "S40-F002", "S40-F003", "S40-F004", "S40-F005",
"guards": {"runtime_routing_use_forbidden":true,"legal_proposition_source_use_forbidden":true,"unmapped_finding_silent_drop_forbidden":true,"pending_map_is_not_coverage_proof":true} "S40-F006", "S40-F007", "S40-F008", "S40-F009", "S40-F010",
"S40-F011", "S40-F012", "S40-F013", "S40-F014", "S40-F015"
],
"s2_40_required_fixture_case_count": 15,
"s2_40_v_code_mapping_count": 18,
"s2_40_binding_status": "OFFLINE_BYTES_BOUND_LEGAL_AND_LIVE_PENDING",
"s2_40_fixture_family_coverage_rows": [
{"family_id":"S40-FAMILY-01","fixture_case_ids":["S40-F002"],"coverage":"STATUS_ONLY_EXACT_FIVE"},
{"family_id":"S40-FAMILY-02","fixture_case_ids":["S40-F001"],"coverage":"SINGLE_GROUP_LOGICAL_COMMIT"},
{"family_id":"S40-FAMILY-03","fixture_case_ids":["S40-F004","S40-F007"],"coverage":"MULTI_GROUP_RELATION_AND_NUMBERING"},
{"family_id":"S40-FAMILY-04","fixture_case_ids":["S40-F009","S40-F010"],"coverage":"GAP_PRESERVATION_AND_WAIT"},
{"family_id":"S40-FAMILY-05","fixture_case_ids":["S40-F006"],"coverage":"V01_V18_PASS_FAIL_UNEVALUABLE"},
{"family_id":"S40-FAMILY-06","fixture_case_ids":["S40-F004"],"coverage":"CASE_RULE_RENDERER_ZERO_MULTI_STALE_FREE_TEXT"},
{"family_id":"S40-FAMILY-07","fixture_case_ids":["S40-F007","S40-F008"],"coverage":"COST_PROVISIONAL_ANNEX_EXHIBIT_OBJECT_PARTY"},
{"family_id":"S40-FAMILY-08","fixture_case_ids":["S40-F005"],"coverage":"RELIEF_CAUSE_CROSSMATCH"},
{"family_id":"S40-FAMILY-09","fixture_case_ids":["S40-F006","S40-F007"],"coverage":"CORPUS_AUTHORITY_LAW_VALUE_CALC_PROVENANCE"},
{"family_id":"S40-FAMILY-10","fixture_case_ids":["S40-F003","S40-F005"],"coverage":"OPTION_RECOVERY_ISSUE_CONSERVATION"},
{"family_id":"S40-FAMILY-11","fixture_case_ids":["S40-F015"],"coverage":"CANDIDATE_DIGEST_NONCYCLE_TAMPER"},
{"family_id":"S40-FAMILY-12","fixture_case_ids":["S40-F010","S40-F011"],"coverage":"RECEIPT_WAIT_RESUME_COMMIT"},
{"family_id":"S40-FAMILY-13","fixture_case_ids":["S40-F010"],"coverage":"RECEIPT_TRUST_SCOPE_TIME_REVOCATION"},
{"family_id":"S40-FAMILY-14","fixture_case_ids":["S40-F012"],"coverage":"CONTENT_CHANGE_EARLIEST_OWNER"},
{"family_id":"S40-FAMILY-15","fixture_case_ids":["S40-F013"],"coverage":"PARTIAL_WRITE_AND_BARRIER_LAST"},
{"family_id":"S40-FAMILY-16","fixture_case_ids":["S40-F014"],"coverage":"IDEMPOTENCE_CONFLICT_CONCURRENCY"},
{"family_id":"S40-FAMILY-17","fixture_case_ids":["S40-F004"],"coverage":"LEGACY_EXTERNAL_PY_SCAN_SECRET_REJECTION"},
{"family_id":"S40-FAMILY-18","fixture_case_ids":["S40-F007"],"coverage":"ACTIO_STRUCTURAL_DEPENDENCIES_LEGAL_PENDING"},
{"family_id":"S40-FAMILY-19","fixture_case_ids":["S40-F007"],"coverage":"SPECIAL_CASE_TEMPORAL_STRUCTURES_LEGAL_PENDING"},
{"family_id":"S40-FAMILY-20","fixture_case_ids":["S40-F004"],"coverage":"CASE_TYPE_137_STRUCTURAL_COVERAGE_LEGAL_PENDING"}
],
"source_finding_families": [
"discrepancy_report_1..4", "improvement_report_1..4", "improvement_merged",
"eval_stage_2_optimal_update_strategy_v.3"
],
"unresolved_reason_codes": [
"SOURCE_FINDING_LOCATORS_NOT_SIGNED",
"KOREAN_LAWYER_FIXTURE_CROSSWALK_NOT_SIGNED"
],
"guards": {
"runtime_routing_use_forbidden": true,
"legal_proposition_source_use_forbidden": true,
"unmapped_finding_silent_drop_forbidden": true,
"pending_map_is_not_coverage_proof": true
}
} }
@@ -19,16 +19,57 @@
], ],
"exactly_one_policy_result_required": true "exactly_one_policy_result_required": true
}, },
"final_review_contract": {
"policy_result_enum": [
"STANDARD_ATTORNEY_REVIEW",
"MANDATORY_SPECIALIST_REVIEW"
],
"base_required_receipt_types": [
"STANDARD_ATTORNEY_REVIEW"
],
"allowed_review_tags": [
"AUTHORITY_TEMPORAL_REVIEW",
"CALCULATION_SPECIALIST_REVIEW",
"CORPUS_GAP_REVIEW",
"PARTY_TITLE_REVIEW",
"RENDERER_BRANCH_REVIEW",
"SPECIAL_LAW_REVIEW"
],
"runtime_trigger_sources": [
"V01_V18_RESULT",
"RENDERER_BINDING",
"AUTHORITY_RELEASE",
"CORPUS_RELEASE",
"CALCULATION_RECEIPT"
],
"receipt_disposition_enum": [
"APPROVE_AS_IS",
"CONTENT_CHANGE_REQUIRED"
],
"external_cryptographic_verification_required": true,
"candidate_digest_and_review_subject_digest_required": true,
"in_place_candidate_edit_forbidden": true,
"missing_or_unapproved_policy_result": "STANDARD_ATTORNEY_REVIEW",
"missing_or_invalid_receipt_route": "WAIT_EXTERNAL_REVIEW"
},
"policy_rows": [], "policy_rows": [],
"default_unapproved_result": { "default_unapproved_result": {
"drafting_permission": "WORKNOTE_ONLY", "drafting_permission": "WORKNOTE_ONLY",
"issue_code": "REVIEW_POLICY_NOT_APPROVED", "issue_code": "REVIEW_POLICY_NOT_APPROVED",
"ready_eligible": false "ready_eligible": false,
"required_receipt_types": [
"STANDARD_ATTORNEY_REVIEW"
],
"legal_readiness_ceiling": "LAWYER_REVIEW_REQUIRED"
}, },
"closure": { "closure": {
"ready_requires_all_required_receipts": true, "ready_requires_all_required_receipts": true,
"ready_requires_no_unresolved_blocking_issue": true, "ready_requires_no_unresolved_blocking_issue": true,
"missing_policy_cannot_upgrade_permission": true "missing_policy_cannot_upgrade_permission": true,
"ready_requires_production_compile_mode": true,
"ready_requires_v01_v18_all_pass": true,
"ready_requires_execution_eligible_legal_assets": true,
"candidate_receipt_cannot_cure_release_level_legal_gap": true
}, },
"review": { "review": {
"required_role": "KOREAN_LAWYER", "required_role": "KOREAN_LAWYER",
@@ -13,8 +13,14 @@ import copy
import hashlib import hashlib
import json import json
from pathlib import Path, PurePosixPath from pathlib import Path, PurePosixPath
import re
from typing import Any from typing import Any
try:
import yaml
except ImportError: # pragma: no cover - incomplete offline validation host
yaml = None # type: ignore[assignment]
MODULE_MANIFEST_SCHEMA = "stage2_module_manifest.v1" MODULE_MANIFEST_SCHEMA = "stage2_module_manifest.v1"
PARENT_RELEASE_SCHEMA = "stage2_release.v2" PARENT_RELEASE_SCHEMA = "stage2_release.v2"
@@ -73,9 +79,118 @@ FORBIDDEN_PARENT_MEMBERS = frozenset(
"manifest/s2_30_model_benchmark_receipt.json", "manifest/s2_30_model_benchmark_receipt.json",
"manifest/s2_30_legal_review_receipt.json", "manifest/s2_30_legal_review_receipt.json",
"manifest/s2_30_release.json", "manifest/s2_30_release.json",
"agent_scripts/Stage_2_S2_40.yml",
"runtime/s2_40_commit.py",
"runtime/s2_40_commit.txt",
"manifest/s2_40_inline_code_receipt.json",
} }
) )
STAGE_GENERIC_METADATA = {
"S2_20": {
"asset_version": "s2_20.1",
"module_id_prefix": "S2_20-ASSET-",
"owner": "Stage_2_S2_20_owner",
"schema_version": "stage2_s2_20_generic_asset.v1",
"scope_predicate": "workflow_id == S2_20",
},
"S2_30": {
"asset_version": "s2_30.1",
"module_id_prefix": "S2_30-ASSET-",
"owner": "Stage_2_S2_30_owner",
"schema_version": "stage2_s2_30_generic_asset.v1",
"scope_predicate": "workflow_id == S2_30",
},
"S2_40": {
"asset_version": "s2_40.1",
"module_id_prefix": "S2_40-ASSET-",
"owner": "Stage_2_S2_40_owner",
"schema_version": "stage2_s2_40_generic_asset.v1",
"scope_predicate": "workflow_id == S2_40",
},
}
S2_40_WORKFLOW_PATH = "workflows/S2_40_final_review_render_and_commit.yml"
S2_40_TRANSITIONED_STUB_VALUES = frozenset(
{
"WF-S2_40-STATUS-ONLY",
"s2_40.status_only.1",
"DRAFT_HANDOFF_STUB_HASH_BOUND",
"entrypoint_id == S2_40_STATUS_ONLY",
}
)
S2_40_WORKFLOW_REQUIRED_METADATA: dict[str, Any] = {
"asset_version": "s2_40.finalizer.1",
"consumed_schema_ids": [
"https://schemas.liti-agent.local/stage2/s2_00/context.schema.v2.json",
"https://schemas.liti-agent.local/stage2/s2_00/ingress.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_10/s2_10.schema.v2.json",
"https://schemas.liti-agent.local/stage2/s2_20/binding_retrieval.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_20/calculation.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_20/relief_plan.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_30/draft_atoms.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_40/package.schema.v1.json",
"https://schemas.liti-agent.local/stage2/shared/deployment.schema.v3.json",
"https://schemas.liti-agent.local/stage2/shared/review_status.schema.v1.json",
],
"entry_routes": ["TO_S2_40", "TO_S2_40_STATUS_ONLY"],
"implementation_status": "IMPLEMENTED_OFFLINE_CONTRACT_LIVE_ADMISSION_PENDING",
"inputs": [
"ingress/ingress_status.json",
"ingress/technical_diagnostic.json",
"ingress/stage1_input_manifest.json",
"ingress/intake_report.json",
"review/issue_ledger.base.json",
"map_s2_10/s2_10_publish_status.json",
"plan/plan_publish_status.json",
"plan/canonical_relief_plan.json",
"plan/claim_groups.json",
"plan/case_type_bindings.json",
"map_s2_30/s2_30_publish_status.json",
"map_s2_30/artifact_manifest.json",
"map_s2_30/{draft_parts,issue_patches,worknote_parts,usage_parts}/<claim_group_id>.json",
"review/review_receipts/<request_id>.json",
"review/lawyer_judgment_record.json",
],
"legal_admission_status": "PENDING",
"live_admission_status": "PENDING",
"module_id": "WF-S2_40",
"module_kind": "WORKFLOW",
"outputs": [
"review/issue_ledger.final.json",
"review/assumption_ledger.json",
"review/llm_usage.jsonl",
"candidates/by-content-digest/<candidate_content_digest>/",
"review/review_requests/<request_id>.json",
"final/claim_relief.md",
"final/claim_cause.md",
"final/pleading_draft.md",
"final/stage2_package.json",
"commit/commit_intent.json",
"commit/stage2_commit_result.json",
"control/run_status.json",
],
"owner": "Stage_2_S2_40_owner",
"path": S2_40_WORKFLOW_PATH,
"produced_schema_ids": [
"stage2_s2_40_candidate_manifest.v1",
"stage2_s2_40_commit_intent.v1",
"stage2_s2_40_commit_result.v1",
"stage2_s2_40_package.v1",
"stage2_s2_40_run_status.v1",
],
"schema_version": "stage2_workflow_contract.v1",
"scope_predicate": "workflow_id == S2_40 and entry_route in {TO_S2_40,TO_S2_40_STATUS_ONLY}",
"semantic_review_status": "PENDING_LEGAL_AND_LIVE_ADMISSION",
"status_only_exact_inputs": [
"ingress/ingress_status.json",
"ingress/technical_diagnostic.json",
"ingress/stage1_input_manifest.json",
"ingress/intake_report.json",
"review/issue_ledger.base.json",
],
}
class ValidationInputError(ValueError): class ValidationInputError(ValueError):
"""Raised when a validation input cannot be parsed deterministically.""" """Raised when a validation input cannot be parsed deterministically."""
@@ -103,6 +218,38 @@ def _load_json(path: Path) -> Any:
raise ValidationInputError(f"JSON_READ_FAILED:{path.as_posix()}:{exc}") from exc raise ValidationInputError(f"JSON_READ_FAILED:{path.as_posix()}:{exc}") from exc
if yaml is not None:
class _UniqueKeySafeLoader(yaml.SafeLoader):
def construct_mapping(self, node: Any, deep: bool = False) -> dict[Any, Any]:
self.flatten_mapping(node)
result: dict[Any, Any] = {}
for key_node, value_node in node.value:
key = self.construct_object(key_node, deep=deep)
if key in result:
raise ValidationInputError(f"DUPLICATE_YAML_KEY:{key!r}")
result[key] = self.construct_object(value_node, deep=deep)
return result
else: # pragma: no cover
class _UniqueKeySafeLoader: # type: ignore[no-redef]
pass
def _load_yaml(path: Path) -> Any:
if yaml is None:
raise ValidationInputError("PYYAML_REQUIRED")
try:
raw = path.read_bytes()
text = raw.decode("utf-8")
if text.startswith("\ufeff"):
raise ValidationInputError(f"YAML_UTF8_BOM_FORBIDDEN:{path.as_posix()}")
return yaml.load(text, Loader=_UniqueKeySafeLoader)
except (OSError, UnicodeDecodeError, yaml.YAMLError) as exc:
raise ValidationInputError(f"YAML_READ_FAILED:{path.as_posix()}:{exc}") from exc
def _canonical_bytes(document: Any) -> bytes: def _canonical_bytes(document: Any) -> bytes:
return ( return (
json.dumps( json.dumps(
@@ -169,6 +316,89 @@ def _physical(root: Path, relative: str) -> Path | None:
return resolved return resolved
def _resolve_root(root: Path) -> Path:
"""Resolve a CLI/library root before deriving authoring-relative paths."""
try:
resolved = root.resolve(strict=True)
except (FileNotFoundError, OSError) as exc:
raise ValidationInputError(f"ROOT_UNAVAILABLE:{root.as_posix()}") from exc
if not resolved.is_dir():
raise ValidationInputError(f"ROOT_DIRECTORY_REQUIRED:{resolved.as_posix()}")
return resolved
def _validate_s2_40_workflow_module_row(
rows: Any,
) -> list[dict[str, str]]:
if not isinstance(rows, list):
return [_finding("S2_40_WORKFLOW_MODULE_ROW_REQUIRED", "$/modules", "modules array required")]
matches = [
row
for row in rows
if isinstance(row, dict) and row.get("path") == S2_40_WORKFLOW_PATH
]
s2_40_family_active = bool(matches) or any(
isinstance(row, dict)
and (
row.get("owner") == "Stage_2_S2_40_owner"
or row.get("schema_version") == "stage2_s2_40_generic_asset.v1"
or (
isinstance(row.get("module_id"), str)
and row["module_id"].startswith("S2_40-ASSET-")
)
)
for row in rows
)
if not s2_40_family_active:
# Pre-S2_40 synthetic/unit manifests remain valid inputs. Once any
# S2_40 family member is present, however, the full workflow row is a
# mandatory semantic anchor and a status-only substitute is forbidden.
return []
if len(matches) != 1:
return [
_finding(
"S2_40_WORKFLOW_MODULE_ROW_EXACT_ONE_REQUIRED",
"$/modules",
f"observed={len(matches)}",
)
]
row = matches[0]
observed_stub = sorted(
str(value)
for value in {
row.get("module_id"),
row.get("asset_version"),
row.get("implementation_status"),
row.get("scope_predicate"),
}
& S2_40_TRANSITIONED_STUB_VALUES
)
findings: list[dict[str, str]] = []
if observed_stub:
findings.append(
_finding(
"S2_40_TRANSITIONED_STUB_METADATA_FORBIDDEN",
f"module:{S2_40_WORKFLOW_PATH}",
repr(observed_stub),
)
)
drift = {
key: {"expected": expected, "observed": row.get(key)}
for key, expected in S2_40_WORKFLOW_REQUIRED_METADATA.items()
if row.get(key) != expected
}
if drift:
findings.append(
_finding(
"S2_40_WORKFLOW_MODULE_METADATA_MISMATCH",
f"module:{S2_40_WORKFLOW_PATH}",
json.dumps(drift, ensure_ascii=False, sort_keys=True),
)
)
return findings
def _validate_module_manifest( def _validate_module_manifest(
root: Path, root: Path,
manifest: dict[str, Any], manifest: dict[str, Any],
@@ -187,6 +417,7 @@ def _validate_module_manifest(
rows = manifest.get("modules") rows = manifest.get("modules")
if not isinstance(rows, list): if not isinstance(rows, list):
return errors + [_finding("MODULES_REQUIRED", "$/modules", "canonical modules array missing")], pending, {"module_count": 0, "mirror_count": 0} return errors + [_finding("MODULES_REQUIRED", "$/modules", "canonical modules array missing")], pending, {"module_count": 0, "mirror_count": 0}
errors.extend(_validate_s2_40_workflow_module_row(rows))
seen_ids: set[str] = set() seen_ids: set[str] = set()
seen_paths: set[str] = set() seen_paths: set[str] = set()
row_by_path: dict[str, dict[str, Any]] = {} row_by_path: dict[str, dict[str, Any]] = {}
@@ -518,6 +749,234 @@ def _validate_137_coverage(
} }
def _walk_strings(value: Any) -> list[str]:
if isinstance(value, str):
return [value]
if isinstance(value, list):
return [item for child in value for item in _walk_strings(child)]
if isinstance(value, dict):
return [item for child in value.values() for item in _walk_strings(child)]
return []
def _validate_s2_40_detached(
root: Path,
parent_release_raw: bytes,
) -> tuple[list[dict[str, str]], list[dict[str, str]], dict[str, int]]:
"""Independently validate the detached S2_40 Agent/code/admission lane.
This check is activated only after the non-empty S2_40 parent allowlist is
installed. It never upgrades pending backend or legal evidence to an
admitted state.
"""
errors: list[dict[str, str]] = []
pending: list[dict[str, str]] = []
counts = {"s2_40_stage_binding_count": 0, "s2_40_run_code_task_count": 0}
required = {
"authoring": root.parent.parent / "Stage_2_S2_40.yml",
"projection": root / "agent_scripts/Stage_2_S2_40.yml",
"mirror_py": root / "runtime/s2_40_commit.py",
"mirror_txt": root / "runtime/s2_40_commit.txt",
"receipt": root / "manifest/s2_40_inline_code_receipt.json",
"binding": root / "deployment/stage2_code_executor_binding.yml",
"admission": root / "manifest/stage2_deterministic_admission_receipt.json",
"package_schema": root / "schemas/package.schema.json",
"review_schema": root / "schemas/review_status.schema.json",
"deployment_schema": root / "schemas/deployment.schema.json",
}
missing = [name for name, path in required.items() if not path.is_file() or path.is_symlink()]
if missing:
errors.append(
_finding(
"S2_40_DETACHED_ASSET_MISSING",
"s2_40_detached:$",
repr(sorted(missing)),
)
)
return errors, pending, counts
authoring_raw = required["authoring"].read_bytes()
projection_raw = required["projection"].read_bytes()
mirror_py_raw = required["mirror_py"].read_bytes()
mirror_txt_raw = required["mirror_txt"].read_bytes()
if authoring_raw != projection_raw:
errors.append(
_finding(
"S2_40_AUTHORING_PROJECTION_BYTES_DIFFER",
"s2_40_detached:/projection",
f"authoring={_sha256(authoring_raw)};projection={_sha256(projection_raw)}",
)
)
if mirror_py_raw != mirror_txt_raw:
errors.append(
_finding(
"S2_40_CODE_MIRROR_BYTES_DIFFER",
"s2_40_detached:/mirror",
f"py={_sha256(mirror_py_raw)};txt={_sha256(mirror_txt_raw)}",
)
)
try:
agent_doc = _load_yaml(required["authoring"])
except ValidationInputError as exc:
errors.append(_finding("S2_40_AUTHORING_YAML_INVALID", "s2_40_detached:/authoring", str(exc)))
agent_doc = None
code_raw = b""
if not isinstance(agent_doc, dict):
errors.append(_finding("S2_40_AGENT_ROOT_INVALID", "s2_40_detached:/authoring", "object required"))
else:
agent = agent_doc.get("Agent")
if not isinstance(agent, dict):
errors.append(_finding("S2_40_AGENT_OBJECT_REQUIRED", "s2_40_detached:/Agent", repr(agent)))
else:
if agent.get("name") != "Stage_2_S2_40" or agent.get("version") != "1.0.0":
errors.append(_finding("S2_40_AGENT_IDENTITY_MISMATCH", "s2_40_detached:/Agent", repr({"name": agent.get("name"), "version": agent.get("version")})))
forbidden_model_fields = [
string
for string in _walk_strings(agent)
if string in {"gpt-5.6-sol", "xhigh"}
]
if forbidden_model_fields or any(
key in agent
for key in ("llm_provider", "llm_model", "llm_reasoning", "llm_verbosity")
):
errors.append(_finding("S2_40_LLM_FIELD_FORBIDDEN", "s2_40_detached:/Agent", repr(forbidden_model_fields)))
stages = agent.get("Stages")
if not isinstance(stages, list) or len(stages) != 1 or not isinstance(stages[0], dict):
errors.append(_finding("S2_40_EXACT_ONE_STAGE_REQUIRED", "s2_40_detached:/Agent/Stages", repr(stages)))
else:
stage = stages[0]
tasks = stage.get("tasks")
run_code = [
row
for row in tasks
if isinstance(row, dict)
and row.get("mcp") == "code-executor"
and row.get("tool_name") == "run_code"
] if isinstance(tasks, list) else []
counts["s2_40_run_code_task_count"] = len(run_code)
if stage.get("name") != "S2_40" or not isinstance(tasks, list) or len(tasks) != 1 or len(run_code) != 1:
errors.append(_finding("S2_40_EXACT_ONE_RUN_CODE_TASK_REQUIRED", "s2_40_detached:/Agent/Stages/0", f"stage={stage.get('name')!r};tasks={len(tasks) if isinstance(tasks, list) else 'invalid'};run_code={len(run_code)}"))
else:
task = run_code[0]
parameters = task.get("parameters")
expected = {
"language": "python",
"requirements": "httpx==0.28.1",
"network": "agent-network",
"timeout": 300,
}
if task.get("task_name") != "Task_S2_40_deterministic_finalizer" or not isinstance(parameters, dict) or any(parameters.get(key) != value for key, value in expected.items()):
errors.append(_finding("S2_40_RUN_CODE_SEMANTICS_MISMATCH", "s2_40_detached:/Agent/Stages/0/tasks/0", repr(task)))
elif isinstance(parameters.get("code"), str):
code_raw = parameters["code"].encode("utf-8")
procedure = stage.get("task_procedure")
expected_procedure = {
"IN": {"nexts": ["Task_S2_40_deterministic_finalizer"], "wait_until": []},
"Task_S2_40_deterministic_finalizer": {"nexts": ["OUT"], "wait_until": ["IN"]},
"OUT": {"nexts": [], "wait_until": ["Task_S2_40_deterministic_finalizer"]},
}
if procedure != expected_procedure:
errors.append(_finding("S2_40_TASK_PROCEDURE_MISMATCH", "s2_40_detached:/Agent/Stages/0/task_procedure", repr(procedure)))
legacy_refs = sorted(
value
for value in _walk_strings(agent_doc)
if re.search(r"(?:^|[/\\])v\.[0-3](?:[/\\]|$)", value)
)
if legacy_refs:
errors.append(_finding("S2_40_LEGACY_STAGE2_DEPENDENCY", "s2_40_detached:/authoring", repr(legacy_refs)))
if code_raw and code_raw != mirror_py_raw:
errors.append(_finding("S2_40_INLINE_CODE_MIRROR_MISMATCH", "s2_40_detached:/canonical_code", f"code={_sha256(code_raw)};mirror={_sha256(mirror_py_raw)}"))
receipt = _load_json(required["receipt"])
if not isinstance(receipt, dict) or receipt.get("schema_version") != "stage2_s2_40_inline_code_receipt.v1" or receipt.get("workflow_id") != "S2_40":
errors.append(_finding("S2_40_INLINE_RECEIPT_INVALID", "s2_40_detached:/receipt", repr(receipt)))
else:
bindings = (
("authoring", authoring_raw),
("deployment_projection", projection_raw),
)
for key, raw in bindings:
row = receipt.get(key)
if not isinstance(row, dict) or row.get("sha256") != _sha256(raw) or row.get("size_bytes") != len(raw):
errors.append(_finding("S2_40_INLINE_RECEIPT_HASH_MISMATCH", f"s2_40_detached:/receipt/{key}", repr(row)))
canonical_code = receipt.get("canonical_code")
if not isinstance(canonical_code, dict) or canonical_code.get("sha256", canonical_code.get("code_sha256")) != _sha256(code_raw):
errors.append(_finding("S2_40_INLINE_RECEIPT_CODE_HASH_MISMATCH", "s2_40_detached:/receipt/canonical_code", repr(canonical_code)))
expected_parent = _sha256(parent_release_raw)
if receipt.get("expected_parent_stage2_release_sha256") != expected_parent:
errors.append(_finding("S2_40_PARENT_RELEASE_BINDING_MISMATCH", "s2_40_detached:/receipt/expected_parent_stage2_release_sha256", f"expected={expected_parent};observed={receipt.get('expected_parent_stage2_release_sha256')}"))
binding = _load_yaml(required["binding"])
rows = binding.get("stage_bindings") if isinstance(binding, dict) else None
matches = [row for row in rows if isinstance(row, dict) and row.get("stage_id") == "S2_40"] if isinstance(rows, list) else []
counts["s2_40_stage_binding_count"] = len(matches)
if len(matches) != 1:
errors.append(_finding("S2_40_STAGE_BINDING_EXACT_ONE_REQUIRED", "s2_40_detached:/binding/stage_bindings", str(len(matches))))
else:
row = matches[0]
expected = {
"workflow_id": "S2_40",
"execution_class": "NON-LLM-DETERMINISTIC",
"active_runtime_authority": False,
"mcp_server_id": "code-executor",
"tool_name": "run_code",
"language": "python",
"network": "agent-network",
"timeout_seconds": 300,
"external_mcp_contract": None,
}
drift = {key: {"expected": value, "observed": row.get(key)} for key, value in expected.items() if row.get(key) != value}
localdocs = row.get("localdocs_contract")
if not isinstance(localdocs, dict) or localdocs.get("endpoint") != "http://mcp-localdocs:8012/mcp" or localdocs.get("fixed_request_path") != "stage2_control/s2_40_request.json" or localdocs.get("tool_allowlist") != ["read_binary_doc", "write_binary_file"]:
drift["localdocs_contract"] = {"expected": "S2_40 localdocs binary-only contract", "observed": localdocs}
ref_expectations = {
"agent_script_ref": ("agent_scripts/Stage_2_S2_40.yml", projection_raw),
"inline_code_receipt_ref": ("manifest/s2_40_inline_code_receipt.json", required["receipt"].read_bytes()),
"stage2_release_ref": ("manifest/stage2_release.json", parent_release_raw),
}
for key, (path, raw) in ref_expectations.items():
ref = row.get(key)
if not isinstance(ref, dict) or ref.get("path") != path or ref.get("sha256") != _sha256(raw):
drift[key] = {"expected": {"path": path, "sha256": _sha256(raw)}, "observed": ref}
if drift:
errors.append(_finding("S2_40_STAGE_BINDING_MISMATCH", "s2_40_detached:/binding/stage_bindings/S2_40", json.dumps(drift, ensure_ascii=False, sort_keys=True)))
if row.get("live_admission_status") not in {"PENDING_SECRET_BINDING", "PENDING_LIVE_VERIFICATION", "PENDING"}:
errors.append(_finding("S2_40_LIVE_ADMISSION_STATUS_DISHONEST", "s2_40_detached:/binding/stage_bindings/S2_40/live_admission_status", repr(row.get("live_admission_status"))))
else:
pending.append(_finding("S2_40_LIVE_CODE_EXECUTOR_ADMISSION_PENDING", "s2_40_detached:/binding/stage_bindings/S2_40", str(row.get("live_admission_status"))))
admission = _load_json(required["admission"])
expected_ids = ["S2_00", "S2_20", "S2_40"]
if not isinstance(admission, dict) or admission.get("present_deterministic_stage_ids") != expected_ids:
errors.append(_finding("S2_40_DETERMINISTIC_ADMISSION_SET_MISMATCH", "s2_40_detached:/admission/present_deterministic_stage_ids", repr(admission.get("present_deterministic_stage_ids") if isinstance(admission, dict) else admission)))
elif admission.get("executor_binding_sha256") != _sha256(required["binding"].read_bytes()) or admission.get("parent_release_sha256") != _sha256(parent_release_raw):
errors.append(_finding("S2_40_DETERMINISTIC_ADMISSION_HASH_MISMATCH", "s2_40_detached:/admission", repr(admission)))
elif admission.get("admission_status") != "PENDING":
errors.append(_finding("S2_40_UNSUPPORTED_ADMISSION_CLAIM", "s2_40_detached:/admission/admission_status", repr(admission.get("admission_status"))))
else:
pending.append(_finding("S2_40_DETERMINISTIC_ADMISSION_PENDING", "s2_40_detached:/admission", "external signed backend evidence pending"))
deployment_schema = _load_json(required["deployment_schema"])
deployment_defs = deployment_schema.get("$defs") if isinstance(deployment_schema, dict) else None
required_defs = {
"s2_40_request",
"s2_40_execution_receipt",
"s2_40_inline_code_receipt",
"s2_40_commit_intent",
"s2_40_commit_result",
}
if not isinstance(deployment_defs, dict) or not required_defs.issubset(deployment_defs):
errors.append(_finding("S2_40_DEPLOYMENT_SCHEMA_DEFS_MISSING", "s2_40_detached:/schemas/deployment/$defs", repr(sorted(required_defs - set(deployment_defs or {})))))
for name in ("package_schema", "review_schema"):
schema = _load_json(required[name])
if not isinstance(schema, dict) or not isinstance(schema.get("$defs"), dict) or not schema.get("$id"):
errors.append(_finding("S2_40_SCHEMA_ROOT_INVALID", f"s2_40_detached:/schemas/{name}", repr(schema)))
return errors, pending, counts
def validate_package( def validate_package(
root: Path, root: Path,
manifest_path: Path, manifest_path: Path,
@@ -526,6 +985,15 @@ def validate_package(
rule_registry_path: Path, rule_registry_path: Path,
coverage_path: Path, coverage_path: Path,
) -> dict[str, Any]: ) -> dict[str, Any]:
root = _resolve_root(root)
try:
manifest_path = manifest_path.resolve(strict=True)
release_path = release_path.resolve(strict=True)
case_registry_path = case_registry_path.resolve(strict=True)
rule_registry_path = rule_registry_path.resolve(strict=True)
coverage_path = coverage_path.resolve(strict=True)
except (FileNotFoundError, OSError) as exc:
raise ValidationInputError(f"VALIDATION_INPUT_UNAVAILABLE:{exc}") from exc
manifest = _load_json(manifest_path) manifest = _load_json(manifest_path)
release = _load_json(release_path) release = _load_json(release_path)
case_registry = _load_json(case_registry_path) case_registry = _load_json(case_registry_path)
@@ -539,6 +1007,17 @@ def validate_package(
errors.extend(parent_errors) errors.extend(parent_errors)
errors.extend(coverage_errors) errors.extend(coverage_errors)
errors.extend(_validate_parent_member_lists(root, manifest)) errors.extend(_validate_parent_member_lists(root, manifest))
s2_40_allowlist_path = root / "manifest/s2_40_parent_member_paths.json"
if s2_40_allowlist_path.is_file():
s2_40_allowlist = _load_json(s2_40_allowlist_path)
if isinstance(s2_40_allowlist, list) and s2_40_allowlist:
detached_errors, detached_pending, detached_counts = _validate_s2_40_detached(
root,
release_path.read_bytes(),
)
errors.extend(detached_errors)
pending.extend(detached_pending)
counts.update(detached_counts)
pending.extend(parent_pending) pending.extend(parent_pending)
pending.extend(coverage_pending) pending.extend(coverage_pending)
if ( if (
@@ -569,28 +1048,29 @@ def validate(root: Path, manifest: dict[str, object]) -> list[str]:
def _validate_parent_member_lists(root: Path, manifest: dict[str, Any]) -> list[dict[str, str]]: def _validate_parent_member_lists(root: Path, manifest: dict[str, Any]) -> list[dict[str, str]]:
"""Verify the cumulative S2_20 + S2_30 allowlist without widening it.""" """Verify disjoint cumulative S2_20/S2_30/S2_40 owner allowlists."""
paths = ( paths = (
root / "manifest" / "s2_20_parent_member_paths.json", ("S2_20", root / "manifest" / "s2_20_parent_member_paths.json"),
root / "manifest" / "s2_30_parent_member_paths.json", ("S2_30", root / "manifest" / "s2_30_parent_member_paths.json"),
("S2_40", root / "manifest" / "s2_40_parent_member_paths.json"),
) )
loaded: list[list[str]] = [] loaded: list[tuple[str, list[str]]] = []
for path in paths: for owner_stage, path in paths:
if not path.is_file(): if not path.is_file():
return [_finding("PARENT_MEMBER_LIST_MISSING", path.as_posix(), "required cumulative allowlist component")] return [_finding("PARENT_MEMBER_LIST_MISSING", path.as_posix(), "required cumulative allowlist component")]
value = _load_json(path) value = _load_json(path)
if not isinstance(value, list) or not all(isinstance(row, str) for row in value): if not isinstance(value, list) or not all(isinstance(row, str) for row in value):
return [_finding("PARENT_MEMBER_LIST_INVALID", path.as_posix(), "string array required")] return [_finding("PARENT_MEMBER_LIST_INVALID", path.as_posix(), "string array required")]
loaded.append(value) if value != sorted(value) or len(value) != len(set(value)):
overlap = sorted(set(loaded[0]) & set(loaded[1])) return [_finding("PARENT_MEMBER_LIST_NOT_SORTED_UNIQUE", path.as_posix(), "sorted unique string array required")]
loaded.append((owner_stage, value))
findings: list[dict[str, str]] = [] findings: list[dict[str, str]] = []
if overlap:
findings.append(_finding("PARENT_MEMBER_LISTS_NOT_DISJOINT", "manifest", repr(overlap)))
rows = manifest.get("modules") rows = manifest.get("modules")
module_paths = { row_by_path = {
row.get("path") for row in rows if isinstance(row, dict) row.get("path"): row for row in rows if isinstance(row, dict) and isinstance(row.get("path"), str)
} if isinstance(rows, list) else set() } if isinstance(rows, list) else {}
module_paths = set(row_by_path)
mirrors = manifest.get("documentation_mirrors") mirrors = manifest.get("documentation_mirrors")
if isinstance(mirrors, list): if isinstance(mirrors, list):
module_paths.update( module_paths.update(
@@ -598,14 +1078,42 @@ def _validate_parent_member_lists(root: Path, manifest: dict[str, Any]) -> list[
for row in mirrors for row in mirrors
if isinstance(row, dict) and isinstance(row.get("mirror_path"), str) if isinstance(row, dict) and isinstance(row.get("mirror_path"), str)
) )
for relative in sorted(set(loaded[0]) | set(loaded[1])): seen: dict[str, str] = {}
normalized = _relative_path(relative) for owner_stage, values in loaded:
if normalized is None: metadata = STAGE_GENERIC_METADATA[owner_stage]
findings.append(_finding("PARENT_MEMBER_PATH_INVALID", "manifest", repr(relative))) for relative in values:
elif normalized in FORBIDDEN_PARENT_MEMBERS: if relative in seen:
findings.append(_finding("NON_CYCLIC_PARENT_VIOLATION", "manifest", normalized)) findings.append(_finding("PARENT_MEMBER_LISTS_NOT_DISJOINT", "manifest", f"path={relative};owners={seen[relative]},{owner_stage}"))
elif normalized not in module_paths: else:
findings.append(_finding("PARENT_MEMBER_NOT_IN_MODULE_MANIFEST", "manifest", normalized)) seen[relative] = owner_stage
normalized = _relative_path(relative)
if normalized is None:
findings.append(_finding("PARENT_MEMBER_PATH_INVALID", "manifest", repr(relative)))
elif normalized in FORBIDDEN_PARENT_MEMBERS:
findings.append(_finding("NON_CYCLIC_PARENT_VIOLATION", "manifest", normalized))
elif normalized not in module_paths:
findings.append(_finding("PARENT_MEMBER_NOT_IN_MODULE_MANIFEST", "manifest", normalized))
elif not normalized.endswith(".txt"):
row = row_by_path.get(normalized)
if isinstance(row, dict) and row.get("schema_version") in {
item["schema_version"] for item in STAGE_GENERIC_METADATA.values()
}:
expected = {
"asset_version": metadata["asset_version"],
"owner": metadata["owner"],
"schema_version": metadata["schema_version"],
"scope_predicate": metadata["scope_predicate"],
}
drift = {
key: {"expected": value, "observed": row.get(key)}
for key, value in expected.items()
if row.get(key) != value
}
module_id = row.get("module_id")
if not isinstance(module_id, str) or not module_id.startswith(metadata["module_id_prefix"]):
drift["module_id"] = {"expected_prefix": metadata["module_id_prefix"], "observed": module_id}
if drift:
findings.append(_finding("PARENT_MEMBER_OWNER_METADATA_MISMATCH", f"manifest:{normalized}", json.dumps(drift, ensure_ascii=False, sort_keys=True)))
return findings return findings
@@ -13,8 +13,14 @@ import copy
import hashlib import hashlib
import json import json
from pathlib import Path, PurePosixPath from pathlib import Path, PurePosixPath
import re
from typing import Any from typing import Any
try:
import yaml
except ImportError: # pragma: no cover - incomplete offline validation host
yaml = None # type: ignore[assignment]
MODULE_MANIFEST_SCHEMA = "stage2_module_manifest.v1" MODULE_MANIFEST_SCHEMA = "stage2_module_manifest.v1"
PARENT_RELEASE_SCHEMA = "stage2_release.v2" PARENT_RELEASE_SCHEMA = "stage2_release.v2"
@@ -73,9 +79,118 @@ FORBIDDEN_PARENT_MEMBERS = frozenset(
"manifest/s2_30_model_benchmark_receipt.json", "manifest/s2_30_model_benchmark_receipt.json",
"manifest/s2_30_legal_review_receipt.json", "manifest/s2_30_legal_review_receipt.json",
"manifest/s2_30_release.json", "manifest/s2_30_release.json",
"agent_scripts/Stage_2_S2_40.yml",
"runtime/s2_40_commit.py",
"runtime/s2_40_commit.txt",
"manifest/s2_40_inline_code_receipt.json",
} }
) )
STAGE_GENERIC_METADATA = {
"S2_20": {
"asset_version": "s2_20.1",
"module_id_prefix": "S2_20-ASSET-",
"owner": "Stage_2_S2_20_owner",
"schema_version": "stage2_s2_20_generic_asset.v1",
"scope_predicate": "workflow_id == S2_20",
},
"S2_30": {
"asset_version": "s2_30.1",
"module_id_prefix": "S2_30-ASSET-",
"owner": "Stage_2_S2_30_owner",
"schema_version": "stage2_s2_30_generic_asset.v1",
"scope_predicate": "workflow_id == S2_30",
},
"S2_40": {
"asset_version": "s2_40.1",
"module_id_prefix": "S2_40-ASSET-",
"owner": "Stage_2_S2_40_owner",
"schema_version": "stage2_s2_40_generic_asset.v1",
"scope_predicate": "workflow_id == S2_40",
},
}
S2_40_WORKFLOW_PATH = "workflows/S2_40_final_review_render_and_commit.yml"
S2_40_TRANSITIONED_STUB_VALUES = frozenset(
{
"WF-S2_40-STATUS-ONLY",
"s2_40.status_only.1",
"DRAFT_HANDOFF_STUB_HASH_BOUND",
"entrypoint_id == S2_40_STATUS_ONLY",
}
)
S2_40_WORKFLOW_REQUIRED_METADATA: dict[str, Any] = {
"asset_version": "s2_40.finalizer.1",
"consumed_schema_ids": [
"https://schemas.liti-agent.local/stage2/s2_00/context.schema.v2.json",
"https://schemas.liti-agent.local/stage2/s2_00/ingress.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_10/s2_10.schema.v2.json",
"https://schemas.liti-agent.local/stage2/s2_20/binding_retrieval.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_20/calculation.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_20/relief_plan.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_30/draft_atoms.schema.v1.json",
"https://schemas.liti-agent.local/stage2/s2_40/package.schema.v1.json",
"https://schemas.liti-agent.local/stage2/shared/deployment.schema.v3.json",
"https://schemas.liti-agent.local/stage2/shared/review_status.schema.v1.json",
],
"entry_routes": ["TO_S2_40", "TO_S2_40_STATUS_ONLY"],
"implementation_status": "IMPLEMENTED_OFFLINE_CONTRACT_LIVE_ADMISSION_PENDING",
"inputs": [
"ingress/ingress_status.json",
"ingress/technical_diagnostic.json",
"ingress/stage1_input_manifest.json",
"ingress/intake_report.json",
"review/issue_ledger.base.json",
"map_s2_10/s2_10_publish_status.json",
"plan/plan_publish_status.json",
"plan/canonical_relief_plan.json",
"plan/claim_groups.json",
"plan/case_type_bindings.json",
"map_s2_30/s2_30_publish_status.json",
"map_s2_30/artifact_manifest.json",
"map_s2_30/{draft_parts,issue_patches,worknote_parts,usage_parts}/<claim_group_id>.json",
"review/review_receipts/<request_id>.json",
"review/lawyer_judgment_record.json",
],
"legal_admission_status": "PENDING",
"live_admission_status": "PENDING",
"module_id": "WF-S2_40",
"module_kind": "WORKFLOW",
"outputs": [
"review/issue_ledger.final.json",
"review/assumption_ledger.json",
"review/llm_usage.jsonl",
"candidates/by-content-digest/<candidate_content_digest>/",
"review/review_requests/<request_id>.json",
"final/claim_relief.md",
"final/claim_cause.md",
"final/pleading_draft.md",
"final/stage2_package.json",
"commit/commit_intent.json",
"commit/stage2_commit_result.json",
"control/run_status.json",
],
"owner": "Stage_2_S2_40_owner",
"path": S2_40_WORKFLOW_PATH,
"produced_schema_ids": [
"stage2_s2_40_candidate_manifest.v1",
"stage2_s2_40_commit_intent.v1",
"stage2_s2_40_commit_result.v1",
"stage2_s2_40_package.v1",
"stage2_s2_40_run_status.v1",
],
"schema_version": "stage2_workflow_contract.v1",
"scope_predicate": "workflow_id == S2_40 and entry_route in {TO_S2_40,TO_S2_40_STATUS_ONLY}",
"semantic_review_status": "PENDING_LEGAL_AND_LIVE_ADMISSION",
"status_only_exact_inputs": [
"ingress/ingress_status.json",
"ingress/technical_diagnostic.json",
"ingress/stage1_input_manifest.json",
"ingress/intake_report.json",
"review/issue_ledger.base.json",
],
}
class ValidationInputError(ValueError): class ValidationInputError(ValueError):
"""Raised when a validation input cannot be parsed deterministically.""" """Raised when a validation input cannot be parsed deterministically."""
@@ -103,6 +218,38 @@ def _load_json(path: Path) -> Any:
raise ValidationInputError(f"JSON_READ_FAILED:{path.as_posix()}:{exc}") from exc raise ValidationInputError(f"JSON_READ_FAILED:{path.as_posix()}:{exc}") from exc
if yaml is not None:
class _UniqueKeySafeLoader(yaml.SafeLoader):
def construct_mapping(self, node: Any, deep: bool = False) -> dict[Any, Any]:
self.flatten_mapping(node)
result: dict[Any, Any] = {}
for key_node, value_node in node.value:
key = self.construct_object(key_node, deep=deep)
if key in result:
raise ValidationInputError(f"DUPLICATE_YAML_KEY:{key!r}")
result[key] = self.construct_object(value_node, deep=deep)
return result
else: # pragma: no cover
class _UniqueKeySafeLoader: # type: ignore[no-redef]
pass
def _load_yaml(path: Path) -> Any:
if yaml is None:
raise ValidationInputError("PYYAML_REQUIRED")
try:
raw = path.read_bytes()
text = raw.decode("utf-8")
if text.startswith("\ufeff"):
raise ValidationInputError(f"YAML_UTF8_BOM_FORBIDDEN:{path.as_posix()}")
return yaml.load(text, Loader=_UniqueKeySafeLoader)
except (OSError, UnicodeDecodeError, yaml.YAMLError) as exc:
raise ValidationInputError(f"YAML_READ_FAILED:{path.as_posix()}:{exc}") from exc
def _canonical_bytes(document: Any) -> bytes: def _canonical_bytes(document: Any) -> bytes:
return ( return (
json.dumps( json.dumps(
@@ -169,6 +316,89 @@ def _physical(root: Path, relative: str) -> Path | None:
return resolved return resolved
def _resolve_root(root: Path) -> Path:
"""Resolve a CLI/library root before deriving authoring-relative paths."""
try:
resolved = root.resolve(strict=True)
except (FileNotFoundError, OSError) as exc:
raise ValidationInputError(f"ROOT_UNAVAILABLE:{root.as_posix()}") from exc
if not resolved.is_dir():
raise ValidationInputError(f"ROOT_DIRECTORY_REQUIRED:{resolved.as_posix()}")
return resolved
def _validate_s2_40_workflow_module_row(
rows: Any,
) -> list[dict[str, str]]:
if not isinstance(rows, list):
return [_finding("S2_40_WORKFLOW_MODULE_ROW_REQUIRED", "$/modules", "modules array required")]
matches = [
row
for row in rows
if isinstance(row, dict) and row.get("path") == S2_40_WORKFLOW_PATH
]
s2_40_family_active = bool(matches) or any(
isinstance(row, dict)
and (
row.get("owner") == "Stage_2_S2_40_owner"
or row.get("schema_version") == "stage2_s2_40_generic_asset.v1"
or (
isinstance(row.get("module_id"), str)
and row["module_id"].startswith("S2_40-ASSET-")
)
)
for row in rows
)
if not s2_40_family_active:
# Pre-S2_40 synthetic/unit manifests remain valid inputs. Once any
# S2_40 family member is present, however, the full workflow row is a
# mandatory semantic anchor and a status-only substitute is forbidden.
return []
if len(matches) != 1:
return [
_finding(
"S2_40_WORKFLOW_MODULE_ROW_EXACT_ONE_REQUIRED",
"$/modules",
f"observed={len(matches)}",
)
]
row = matches[0]
observed_stub = sorted(
str(value)
for value in {
row.get("module_id"),
row.get("asset_version"),
row.get("implementation_status"),
row.get("scope_predicate"),
}
& S2_40_TRANSITIONED_STUB_VALUES
)
findings: list[dict[str, str]] = []
if observed_stub:
findings.append(
_finding(
"S2_40_TRANSITIONED_STUB_METADATA_FORBIDDEN",
f"module:{S2_40_WORKFLOW_PATH}",
repr(observed_stub),
)
)
drift = {
key: {"expected": expected, "observed": row.get(key)}
for key, expected in S2_40_WORKFLOW_REQUIRED_METADATA.items()
if row.get(key) != expected
}
if drift:
findings.append(
_finding(
"S2_40_WORKFLOW_MODULE_METADATA_MISMATCH",
f"module:{S2_40_WORKFLOW_PATH}",
json.dumps(drift, ensure_ascii=False, sort_keys=True),
)
)
return findings
def _validate_module_manifest( def _validate_module_manifest(
root: Path, root: Path,
manifest: dict[str, Any], manifest: dict[str, Any],
@@ -187,6 +417,7 @@ def _validate_module_manifest(
rows = manifest.get("modules") rows = manifest.get("modules")
if not isinstance(rows, list): if not isinstance(rows, list):
return errors + [_finding("MODULES_REQUIRED", "$/modules", "canonical modules array missing")], pending, {"module_count": 0, "mirror_count": 0} return errors + [_finding("MODULES_REQUIRED", "$/modules", "canonical modules array missing")], pending, {"module_count": 0, "mirror_count": 0}
errors.extend(_validate_s2_40_workflow_module_row(rows))
seen_ids: set[str] = set() seen_ids: set[str] = set()
seen_paths: set[str] = set() seen_paths: set[str] = set()
row_by_path: dict[str, dict[str, Any]] = {} row_by_path: dict[str, dict[str, Any]] = {}
@@ -518,6 +749,234 @@ def _validate_137_coverage(
} }
def _walk_strings(value: Any) -> list[str]:
if isinstance(value, str):
return [value]
if isinstance(value, list):
return [item for child in value for item in _walk_strings(child)]
if isinstance(value, dict):
return [item for child in value.values() for item in _walk_strings(child)]
return []
def _validate_s2_40_detached(
root: Path,
parent_release_raw: bytes,
) -> tuple[list[dict[str, str]], list[dict[str, str]], dict[str, int]]:
"""Independently validate the detached S2_40 Agent/code/admission lane.
This check is activated only after the non-empty S2_40 parent allowlist is
installed. It never upgrades pending backend or legal evidence to an
admitted state.
"""
errors: list[dict[str, str]] = []
pending: list[dict[str, str]] = []
counts = {"s2_40_stage_binding_count": 0, "s2_40_run_code_task_count": 0}
required = {
"authoring": root.parent.parent / "Stage_2_S2_40.yml",
"projection": root / "agent_scripts/Stage_2_S2_40.yml",
"mirror_py": root / "runtime/s2_40_commit.py",
"mirror_txt": root / "runtime/s2_40_commit.txt",
"receipt": root / "manifest/s2_40_inline_code_receipt.json",
"binding": root / "deployment/stage2_code_executor_binding.yml",
"admission": root / "manifest/stage2_deterministic_admission_receipt.json",
"package_schema": root / "schemas/package.schema.json",
"review_schema": root / "schemas/review_status.schema.json",
"deployment_schema": root / "schemas/deployment.schema.json",
}
missing = [name for name, path in required.items() if not path.is_file() or path.is_symlink()]
if missing:
errors.append(
_finding(
"S2_40_DETACHED_ASSET_MISSING",
"s2_40_detached:$",
repr(sorted(missing)),
)
)
return errors, pending, counts
authoring_raw = required["authoring"].read_bytes()
projection_raw = required["projection"].read_bytes()
mirror_py_raw = required["mirror_py"].read_bytes()
mirror_txt_raw = required["mirror_txt"].read_bytes()
if authoring_raw != projection_raw:
errors.append(
_finding(
"S2_40_AUTHORING_PROJECTION_BYTES_DIFFER",
"s2_40_detached:/projection",
f"authoring={_sha256(authoring_raw)};projection={_sha256(projection_raw)}",
)
)
if mirror_py_raw != mirror_txt_raw:
errors.append(
_finding(
"S2_40_CODE_MIRROR_BYTES_DIFFER",
"s2_40_detached:/mirror",
f"py={_sha256(mirror_py_raw)};txt={_sha256(mirror_txt_raw)}",
)
)
try:
agent_doc = _load_yaml(required["authoring"])
except ValidationInputError as exc:
errors.append(_finding("S2_40_AUTHORING_YAML_INVALID", "s2_40_detached:/authoring", str(exc)))
agent_doc = None
code_raw = b""
if not isinstance(agent_doc, dict):
errors.append(_finding("S2_40_AGENT_ROOT_INVALID", "s2_40_detached:/authoring", "object required"))
else:
agent = agent_doc.get("Agent")
if not isinstance(agent, dict):
errors.append(_finding("S2_40_AGENT_OBJECT_REQUIRED", "s2_40_detached:/Agent", repr(agent)))
else:
if agent.get("name") != "Stage_2_S2_40" or agent.get("version") != "1.0.0":
errors.append(_finding("S2_40_AGENT_IDENTITY_MISMATCH", "s2_40_detached:/Agent", repr({"name": agent.get("name"), "version": agent.get("version")})))
forbidden_model_fields = [
string
for string in _walk_strings(agent)
if string in {"gpt-5.6-sol", "xhigh"}
]
if forbidden_model_fields or any(
key in agent
for key in ("llm_provider", "llm_model", "llm_reasoning", "llm_verbosity")
):
errors.append(_finding("S2_40_LLM_FIELD_FORBIDDEN", "s2_40_detached:/Agent", repr(forbidden_model_fields)))
stages = agent.get("Stages")
if not isinstance(stages, list) or len(stages) != 1 or not isinstance(stages[0], dict):
errors.append(_finding("S2_40_EXACT_ONE_STAGE_REQUIRED", "s2_40_detached:/Agent/Stages", repr(stages)))
else:
stage = stages[0]
tasks = stage.get("tasks")
run_code = [
row
for row in tasks
if isinstance(row, dict)
and row.get("mcp") == "code-executor"
and row.get("tool_name") == "run_code"
] if isinstance(tasks, list) else []
counts["s2_40_run_code_task_count"] = len(run_code)
if stage.get("name") != "S2_40" or not isinstance(tasks, list) or len(tasks) != 1 or len(run_code) != 1:
errors.append(_finding("S2_40_EXACT_ONE_RUN_CODE_TASK_REQUIRED", "s2_40_detached:/Agent/Stages/0", f"stage={stage.get('name')!r};tasks={len(tasks) if isinstance(tasks, list) else 'invalid'};run_code={len(run_code)}"))
else:
task = run_code[0]
parameters = task.get("parameters")
expected = {
"language": "python",
"requirements": "httpx==0.28.1",
"network": "agent-network",
"timeout": 300,
}
if task.get("task_name") != "Task_S2_40_deterministic_finalizer" or not isinstance(parameters, dict) or any(parameters.get(key) != value for key, value in expected.items()):
errors.append(_finding("S2_40_RUN_CODE_SEMANTICS_MISMATCH", "s2_40_detached:/Agent/Stages/0/tasks/0", repr(task)))
elif isinstance(parameters.get("code"), str):
code_raw = parameters["code"].encode("utf-8")
procedure = stage.get("task_procedure")
expected_procedure = {
"IN": {"nexts": ["Task_S2_40_deterministic_finalizer"], "wait_until": []},
"Task_S2_40_deterministic_finalizer": {"nexts": ["OUT"], "wait_until": ["IN"]},
"OUT": {"nexts": [], "wait_until": ["Task_S2_40_deterministic_finalizer"]},
}
if procedure != expected_procedure:
errors.append(_finding("S2_40_TASK_PROCEDURE_MISMATCH", "s2_40_detached:/Agent/Stages/0/task_procedure", repr(procedure)))
legacy_refs = sorted(
value
for value in _walk_strings(agent_doc)
if re.search(r"(?:^|[/\\])v\.[0-3](?:[/\\]|$)", value)
)
if legacy_refs:
errors.append(_finding("S2_40_LEGACY_STAGE2_DEPENDENCY", "s2_40_detached:/authoring", repr(legacy_refs)))
if code_raw and code_raw != mirror_py_raw:
errors.append(_finding("S2_40_INLINE_CODE_MIRROR_MISMATCH", "s2_40_detached:/canonical_code", f"code={_sha256(code_raw)};mirror={_sha256(mirror_py_raw)}"))
receipt = _load_json(required["receipt"])
if not isinstance(receipt, dict) or receipt.get("schema_version") != "stage2_s2_40_inline_code_receipt.v1" or receipt.get("workflow_id") != "S2_40":
errors.append(_finding("S2_40_INLINE_RECEIPT_INVALID", "s2_40_detached:/receipt", repr(receipt)))
else:
bindings = (
("authoring", authoring_raw),
("deployment_projection", projection_raw),
)
for key, raw in bindings:
row = receipt.get(key)
if not isinstance(row, dict) or row.get("sha256") != _sha256(raw) or row.get("size_bytes") != len(raw):
errors.append(_finding("S2_40_INLINE_RECEIPT_HASH_MISMATCH", f"s2_40_detached:/receipt/{key}", repr(row)))
canonical_code = receipt.get("canonical_code")
if not isinstance(canonical_code, dict) or canonical_code.get("sha256", canonical_code.get("code_sha256")) != _sha256(code_raw):
errors.append(_finding("S2_40_INLINE_RECEIPT_CODE_HASH_MISMATCH", "s2_40_detached:/receipt/canonical_code", repr(canonical_code)))
expected_parent = _sha256(parent_release_raw)
if receipt.get("expected_parent_stage2_release_sha256") != expected_parent:
errors.append(_finding("S2_40_PARENT_RELEASE_BINDING_MISMATCH", "s2_40_detached:/receipt/expected_parent_stage2_release_sha256", f"expected={expected_parent};observed={receipt.get('expected_parent_stage2_release_sha256')}"))
binding = _load_yaml(required["binding"])
rows = binding.get("stage_bindings") if isinstance(binding, dict) else None
matches = [row for row in rows if isinstance(row, dict) and row.get("stage_id") == "S2_40"] if isinstance(rows, list) else []
counts["s2_40_stage_binding_count"] = len(matches)
if len(matches) != 1:
errors.append(_finding("S2_40_STAGE_BINDING_EXACT_ONE_REQUIRED", "s2_40_detached:/binding/stage_bindings", str(len(matches))))
else:
row = matches[0]
expected = {
"workflow_id": "S2_40",
"execution_class": "NON-LLM-DETERMINISTIC",
"active_runtime_authority": False,
"mcp_server_id": "code-executor",
"tool_name": "run_code",
"language": "python",
"network": "agent-network",
"timeout_seconds": 300,
"external_mcp_contract": None,
}
drift = {key: {"expected": value, "observed": row.get(key)} for key, value in expected.items() if row.get(key) != value}
localdocs = row.get("localdocs_contract")
if not isinstance(localdocs, dict) or localdocs.get("endpoint") != "http://mcp-localdocs:8012/mcp" or localdocs.get("fixed_request_path") != "stage2_control/s2_40_request.json" or localdocs.get("tool_allowlist") != ["read_binary_doc", "write_binary_file"]:
drift["localdocs_contract"] = {"expected": "S2_40 localdocs binary-only contract", "observed": localdocs}
ref_expectations = {
"agent_script_ref": ("agent_scripts/Stage_2_S2_40.yml", projection_raw),
"inline_code_receipt_ref": ("manifest/s2_40_inline_code_receipt.json", required["receipt"].read_bytes()),
"stage2_release_ref": ("manifest/stage2_release.json", parent_release_raw),
}
for key, (path, raw) in ref_expectations.items():
ref = row.get(key)
if not isinstance(ref, dict) or ref.get("path") != path or ref.get("sha256") != _sha256(raw):
drift[key] = {"expected": {"path": path, "sha256": _sha256(raw)}, "observed": ref}
if drift:
errors.append(_finding("S2_40_STAGE_BINDING_MISMATCH", "s2_40_detached:/binding/stage_bindings/S2_40", json.dumps(drift, ensure_ascii=False, sort_keys=True)))
if row.get("live_admission_status") not in {"PENDING_SECRET_BINDING", "PENDING_LIVE_VERIFICATION", "PENDING"}:
errors.append(_finding("S2_40_LIVE_ADMISSION_STATUS_DISHONEST", "s2_40_detached:/binding/stage_bindings/S2_40/live_admission_status", repr(row.get("live_admission_status"))))
else:
pending.append(_finding("S2_40_LIVE_CODE_EXECUTOR_ADMISSION_PENDING", "s2_40_detached:/binding/stage_bindings/S2_40", str(row.get("live_admission_status"))))
admission = _load_json(required["admission"])
expected_ids = ["S2_00", "S2_20", "S2_40"]
if not isinstance(admission, dict) or admission.get("present_deterministic_stage_ids") != expected_ids:
errors.append(_finding("S2_40_DETERMINISTIC_ADMISSION_SET_MISMATCH", "s2_40_detached:/admission/present_deterministic_stage_ids", repr(admission.get("present_deterministic_stage_ids") if isinstance(admission, dict) else admission)))
elif admission.get("executor_binding_sha256") != _sha256(required["binding"].read_bytes()) or admission.get("parent_release_sha256") != _sha256(parent_release_raw):
errors.append(_finding("S2_40_DETERMINISTIC_ADMISSION_HASH_MISMATCH", "s2_40_detached:/admission", repr(admission)))
elif admission.get("admission_status") != "PENDING":
errors.append(_finding("S2_40_UNSUPPORTED_ADMISSION_CLAIM", "s2_40_detached:/admission/admission_status", repr(admission.get("admission_status"))))
else:
pending.append(_finding("S2_40_DETERMINISTIC_ADMISSION_PENDING", "s2_40_detached:/admission", "external signed backend evidence pending"))
deployment_schema = _load_json(required["deployment_schema"])
deployment_defs = deployment_schema.get("$defs") if isinstance(deployment_schema, dict) else None
required_defs = {
"s2_40_request",
"s2_40_execution_receipt",
"s2_40_inline_code_receipt",
"s2_40_commit_intent",
"s2_40_commit_result",
}
if not isinstance(deployment_defs, dict) or not required_defs.issubset(deployment_defs):
errors.append(_finding("S2_40_DEPLOYMENT_SCHEMA_DEFS_MISSING", "s2_40_detached:/schemas/deployment/$defs", repr(sorted(required_defs - set(deployment_defs or {})))))
for name in ("package_schema", "review_schema"):
schema = _load_json(required[name])
if not isinstance(schema, dict) or not isinstance(schema.get("$defs"), dict) or not schema.get("$id"):
errors.append(_finding("S2_40_SCHEMA_ROOT_INVALID", f"s2_40_detached:/schemas/{name}", repr(schema)))
return errors, pending, counts
def validate_package( def validate_package(
root: Path, root: Path,
manifest_path: Path, manifest_path: Path,
@@ -526,6 +985,15 @@ def validate_package(
rule_registry_path: Path, rule_registry_path: Path,
coverage_path: Path, coverage_path: Path,
) -> dict[str, Any]: ) -> dict[str, Any]:
root = _resolve_root(root)
try:
manifest_path = manifest_path.resolve(strict=True)
release_path = release_path.resolve(strict=True)
case_registry_path = case_registry_path.resolve(strict=True)
rule_registry_path = rule_registry_path.resolve(strict=True)
coverage_path = coverage_path.resolve(strict=True)
except (FileNotFoundError, OSError) as exc:
raise ValidationInputError(f"VALIDATION_INPUT_UNAVAILABLE:{exc}") from exc
manifest = _load_json(manifest_path) manifest = _load_json(manifest_path)
release = _load_json(release_path) release = _load_json(release_path)
case_registry = _load_json(case_registry_path) case_registry = _load_json(case_registry_path)
@@ -539,6 +1007,17 @@ def validate_package(
errors.extend(parent_errors) errors.extend(parent_errors)
errors.extend(coverage_errors) errors.extend(coverage_errors)
errors.extend(_validate_parent_member_lists(root, manifest)) errors.extend(_validate_parent_member_lists(root, manifest))
s2_40_allowlist_path = root / "manifest/s2_40_parent_member_paths.json"
if s2_40_allowlist_path.is_file():
s2_40_allowlist = _load_json(s2_40_allowlist_path)
if isinstance(s2_40_allowlist, list) and s2_40_allowlist:
detached_errors, detached_pending, detached_counts = _validate_s2_40_detached(
root,
release_path.read_bytes(),
)
errors.extend(detached_errors)
pending.extend(detached_pending)
counts.update(detached_counts)
pending.extend(parent_pending) pending.extend(parent_pending)
pending.extend(coverage_pending) pending.extend(coverage_pending)
if ( if (
@@ -569,28 +1048,29 @@ def validate(root: Path, manifest: dict[str, object]) -> list[str]:
def _validate_parent_member_lists(root: Path, manifest: dict[str, Any]) -> list[dict[str, str]]: def _validate_parent_member_lists(root: Path, manifest: dict[str, Any]) -> list[dict[str, str]]:
"""Verify the cumulative S2_20 + S2_30 allowlist without widening it.""" """Verify disjoint cumulative S2_20/S2_30/S2_40 owner allowlists."""
paths = ( paths = (
root / "manifest" / "s2_20_parent_member_paths.json", ("S2_20", root / "manifest" / "s2_20_parent_member_paths.json"),
root / "manifest" / "s2_30_parent_member_paths.json", ("S2_30", root / "manifest" / "s2_30_parent_member_paths.json"),
("S2_40", root / "manifest" / "s2_40_parent_member_paths.json"),
) )
loaded: list[list[str]] = [] loaded: list[tuple[str, list[str]]] = []
for path in paths: for owner_stage, path in paths:
if not path.is_file(): if not path.is_file():
return [_finding("PARENT_MEMBER_LIST_MISSING", path.as_posix(), "required cumulative allowlist component")] return [_finding("PARENT_MEMBER_LIST_MISSING", path.as_posix(), "required cumulative allowlist component")]
value = _load_json(path) value = _load_json(path)
if not isinstance(value, list) or not all(isinstance(row, str) for row in value): if not isinstance(value, list) or not all(isinstance(row, str) for row in value):
return [_finding("PARENT_MEMBER_LIST_INVALID", path.as_posix(), "string array required")] return [_finding("PARENT_MEMBER_LIST_INVALID", path.as_posix(), "string array required")]
loaded.append(value) if value != sorted(value) or len(value) != len(set(value)):
overlap = sorted(set(loaded[0]) & set(loaded[1])) return [_finding("PARENT_MEMBER_LIST_NOT_SORTED_UNIQUE", path.as_posix(), "sorted unique string array required")]
loaded.append((owner_stage, value))
findings: list[dict[str, str]] = [] findings: list[dict[str, str]] = []
if overlap:
findings.append(_finding("PARENT_MEMBER_LISTS_NOT_DISJOINT", "manifest", repr(overlap)))
rows = manifest.get("modules") rows = manifest.get("modules")
module_paths = { row_by_path = {
row.get("path") for row in rows if isinstance(row, dict) row.get("path"): row for row in rows if isinstance(row, dict) and isinstance(row.get("path"), str)
} if isinstance(rows, list) else set() } if isinstance(rows, list) else {}
module_paths = set(row_by_path)
mirrors = manifest.get("documentation_mirrors") mirrors = manifest.get("documentation_mirrors")
if isinstance(mirrors, list): if isinstance(mirrors, list):
module_paths.update( module_paths.update(
@@ -598,14 +1078,42 @@ def _validate_parent_member_lists(root: Path, manifest: dict[str, Any]) -> list[
for row in mirrors for row in mirrors
if isinstance(row, dict) and isinstance(row.get("mirror_path"), str) if isinstance(row, dict) and isinstance(row.get("mirror_path"), str)
) )
for relative in sorted(set(loaded[0]) | set(loaded[1])): seen: dict[str, str] = {}
normalized = _relative_path(relative) for owner_stage, values in loaded:
if normalized is None: metadata = STAGE_GENERIC_METADATA[owner_stage]
findings.append(_finding("PARENT_MEMBER_PATH_INVALID", "manifest", repr(relative))) for relative in values:
elif normalized in FORBIDDEN_PARENT_MEMBERS: if relative in seen:
findings.append(_finding("NON_CYCLIC_PARENT_VIOLATION", "manifest", normalized)) findings.append(_finding("PARENT_MEMBER_LISTS_NOT_DISJOINT", "manifest", f"path={relative};owners={seen[relative]},{owner_stage}"))
elif normalized not in module_paths: else:
findings.append(_finding("PARENT_MEMBER_NOT_IN_MODULE_MANIFEST", "manifest", normalized)) seen[relative] = owner_stage
normalized = _relative_path(relative)
if normalized is None:
findings.append(_finding("PARENT_MEMBER_PATH_INVALID", "manifest", repr(relative)))
elif normalized in FORBIDDEN_PARENT_MEMBERS:
findings.append(_finding("NON_CYCLIC_PARENT_VIOLATION", "manifest", normalized))
elif normalized not in module_paths:
findings.append(_finding("PARENT_MEMBER_NOT_IN_MODULE_MANIFEST", "manifest", normalized))
elif not normalized.endswith(".txt"):
row = row_by_path.get(normalized)
if isinstance(row, dict) and row.get("schema_version") in {
item["schema_version"] for item in STAGE_GENERIC_METADATA.values()
}:
expected = {
"asset_version": metadata["asset_version"],
"owner": metadata["owner"],
"schema_version": metadata["schema_version"],
"scope_predicate": metadata["scope_predicate"],
}
drift = {
key: {"expected": value, "observed": row.get(key)}
for key, value in expected.items()
if row.get(key) != value
}
module_id = row.get("module_id")
if not isinstance(module_id, str) or not module_id.startswith(metadata["module_id_prefix"]):
drift["module_id"] = {"expected_prefix": metadata["module_id_prefix"], "observed": module_id}
if drift:
findings.append(_finding("PARENT_MEMBER_OWNER_METADATA_MISMATCH", f"manifest:{normalized}", json.dumps(drift, ensure_ascii=False, sort_keys=True)))
return findings return findings
@@ -13,9 +13,26 @@
"obligor_ref", "obligor_ref",
"payment_event_ref" "payment_event_ref"
], ],
"slot_definitions": [
{"name": "amount", "type": "MONEY", "cardinality": "EXACTLY_ONE"},
{"name": "currency", "type": "STRING", "cardinality": "EXACTLY_ONE"},
{"name": "obligor_ref", "type": "PARTY_REF", "cardinality": "EXACTLY_ONE"},
{"name": "payment_event_ref", "type": "IDENTIFIER", "cardinality": "EXACTLY_ONE"}
],
"legal_branch_may_add_required_slots_only_after_review": true, "legal_branch_may_add_required_slots_only_after_review": true,
"missing_required_slot_issue_code": "RENDERER_REQUIRED_SLOT_MISSING" "missing_required_slot_issue_code": "RENDERER_REQUIRED_SLOT_MISSING"
}, },
"closed_ast_contract": {
"normalization_version": "NFC_LF_UTF8_V1",
"allowed_atom_types": ["RELIEF_ATOM", "COST_ATOM", "PROVISIONAL_EXECUTION_ATOM"],
"template_representation": "ORDERED_LITERAL_OR_TYPED_SLOT_SEGMENTS",
"immutable_literal_source": "APPROVED_BRANCH_ROWS_ONLY",
"branch_cardinality": "EXACTLY_ONE",
"independent_rerender_required": true,
"unknown_slot_forbidden": true,
"dangling_token_forbidden": true,
"required_exhibit_resolution": "BRANCH_DECLARED_ONLY"
},
"branch_rows": [], "branch_rows": [],
"closure": { "closure": {
"exactly_one_approved_branch_required": true, "exactly_one_approved_branch_required": true,
@@ -12,9 +12,25 @@
"obligor_ref", "obligor_ref",
"performance_mode" "performance_mode"
], ],
"slot_definitions": [
{"name": "object_ref", "type": "OBJECT_REF", "cardinality": "EXACTLY_ONE"},
{"name": "obligor_ref", "type": "PARTY_REF", "cardinality": "EXACTLY_ONE"},
{"name": "performance_mode", "type": "IDENTIFIER", "cardinality": "EXACTLY_ONE"}
],
"legal_branch_may_add_required_slots_only_after_review": true, "legal_branch_may_add_required_slots_only_after_review": true,
"missing_required_slot_issue_code": "RENDERER_REQUIRED_SLOT_MISSING" "missing_required_slot_issue_code": "RENDERER_REQUIRED_SLOT_MISSING"
}, },
"closed_ast_contract": {
"normalization_version": "NFC_LF_UTF8_V1",
"allowed_atom_types": ["RELIEF_ATOM", "COST_ATOM", "PROVISIONAL_EXECUTION_ATOM", "ANNEX_ATOM"],
"template_representation": "ORDERED_LITERAL_OR_TYPED_SLOT_SEGMENTS",
"immutable_literal_source": "APPROVED_BRANCH_ROWS_ONLY",
"branch_cardinality": "EXACTLY_ONE",
"independent_rerender_required": true,
"unknown_slot_forbidden": true,
"dangling_token_forbidden": true,
"required_exhibit_resolution": "BRANCH_DECLARED_ONLY"
},
"branch_rows": [], "branch_rows": [],
"closure": { "closure": {
"exactly_one_approved_branch_required": true, "exactly_one_approved_branch_required": true,
@@ -12,9 +12,26 @@
"registry_action", "registry_action",
"obligor_ref" "obligor_ref"
], ],
"slot_definitions": [
{"name": "registry_object_ref", "type": "OBJECT_REF", "cardinality": "EXACTLY_ONE"},
{"name": "registry_action", "type": "IDENTIFIER", "cardinality": "EXACTLY_ONE"},
{"name": "obligor_ref", "type": "PARTY_REF", "cardinality": "EXACTLY_ONE"}
],
"legal_branch_may_add_required_slots_only_after_review": true, "legal_branch_may_add_required_slots_only_after_review": true,
"missing_required_slot_issue_code": "RENDERER_REQUIRED_SLOT_MISSING" "missing_required_slot_issue_code": "RENDERER_REQUIRED_SLOT_MISSING"
}, },
"closed_ast_contract": {
"normalization_version": "NFC_LF_UTF8_V1",
"allowed_atom_types": ["RELIEF_ATOM", "COST_ATOM", "ANNEX_ATOM"],
"template_representation": "ORDERED_LITERAL_OR_TYPED_SLOT_SEGMENTS",
"immutable_literal_source": "APPROVED_BRANCH_ROWS_ONLY",
"branch_cardinality": "EXACTLY_ONE",
"independent_rerender_required": true,
"unknown_slot_forbidden": true,
"dangling_token_forbidden": true,
"required_exhibit_resolution": "BRANCH_DECLARED_ONLY",
"provisional_execution_forbidden": true
},
"branch_rows": [], "branch_rows": [],
"closure": { "closure": {
"exactly_one_approved_branch_required": true, "exactly_one_approved_branch_required": true,
@@ -12,9 +12,26 @@
"performance_mode", "performance_mode",
"obligor_ref" "obligor_ref"
], ],
"slot_definitions": [
{"name": "performance_object_ref", "type": "OBJECT_REF", "cardinality": "EXACTLY_ONE"},
{"name": "performance_mode", "type": "IDENTIFIER", "cardinality": "EXACTLY_ONE"},
{"name": "obligor_ref", "type": "PARTY_REF", "cardinality": "EXACTLY_ONE"}
],
"legal_branch_may_add_required_slots_only_after_review": true, "legal_branch_may_add_required_slots_only_after_review": true,
"missing_required_slot_issue_code": "RENDERER_REQUIRED_SLOT_MISSING" "missing_required_slot_issue_code": "RENDERER_REQUIRED_SLOT_MISSING"
}, },
"closed_ast_contract": {
"normalization_version": "NFC_LF_UTF8_V1",
"allowed_atom_types": ["RELIEF_ATOM", "COST_ATOM", "PROVISIONAL_EXECUTION_ATOM", "ANNEX_ATOM"],
"template_representation": "ORDERED_LITERAL_OR_TYPED_SLOT_SEGMENTS",
"immutable_literal_source": "APPROVED_BRANCH_ROWS_ONLY",
"branch_cardinality": "EXACTLY_ONE",
"independent_rerender_required": true,
"unknown_slot_forbidden": true,
"dangling_token_forbidden": true,
"required_exhibit_resolution": "BRANCH_DECLARED_ONLY",
"provisional_execution_requires_branch_authority": true
},
"branch_rows": [], "branch_rows": [],
"closure": { "closure": {
"exactly_one_approved_branch_required": true, "exactly_one_approved_branch_required": true,
@@ -12,9 +12,26 @@
"declaration_scope", "declaration_scope",
"opposing_party_ref" "opposing_party_ref"
], ],
"slot_definitions": [
{"name": "legal_relation_ref", "type": "IDENTIFIER", "cardinality": "EXACTLY_ONE"},
{"name": "declaration_scope", "type": "STRING", "cardinality": "EXACTLY_ONE"},
{"name": "opposing_party_ref", "type": "PARTY_REF", "cardinality": "EXACTLY_ONE"}
],
"legal_branch_may_add_required_slots_only_after_review": true, "legal_branch_may_add_required_slots_only_after_review": true,
"missing_required_slot_issue_code": "RENDERER_REQUIRED_SLOT_MISSING" "missing_required_slot_issue_code": "RENDERER_REQUIRED_SLOT_MISSING"
}, },
"closed_ast_contract": {
"normalization_version": "NFC_LF_UTF8_V1",
"allowed_atom_types": ["RELIEF_ATOM", "COST_ATOM"],
"template_representation": "ORDERED_LITERAL_OR_TYPED_SLOT_SEGMENTS",
"immutable_literal_source": "APPROVED_BRANCH_ROWS_ONLY",
"branch_cardinality": "EXACTLY_ONE",
"independent_rerender_required": true,
"unknown_slot_forbidden": true,
"dangling_token_forbidden": true,
"required_exhibit_resolution": "BRANCH_DECLARED_ONLY",
"provisional_execution_forbidden": true
},
"branch_rows": [], "branch_rows": [],
"closure": { "closure": {
"exactly_one_approved_branch_required": true, "exactly_one_approved_branch_required": true,
@@ -12,9 +12,26 @@
"constitutive_method", "constitutive_method",
"opposing_party_ref" "opposing_party_ref"
], ],
"slot_definitions": [
{"name": "legal_effect_ref", "type": "IDENTIFIER", "cardinality": "EXACTLY_ONE"},
{"name": "constitutive_method", "type": "IDENTIFIER", "cardinality": "EXACTLY_ONE"},
{"name": "opposing_party_ref", "type": "PARTY_REF", "cardinality": "EXACTLY_ONE"}
],
"legal_branch_may_add_required_slots_only_after_review": true, "legal_branch_may_add_required_slots_only_after_review": true,
"missing_required_slot_issue_code": "RENDERER_REQUIRED_SLOT_MISSING" "missing_required_slot_issue_code": "RENDERER_REQUIRED_SLOT_MISSING"
}, },
"closed_ast_contract": {
"normalization_version": "NFC_LF_UTF8_V1",
"allowed_atom_types": ["RELIEF_ATOM", "COST_ATOM", "ANNEX_ATOM"],
"template_representation": "ORDERED_LITERAL_OR_TYPED_SLOT_SEGMENTS",
"immutable_literal_source": "APPROVED_BRANCH_ROWS_ONLY",
"branch_cardinality": "EXACTLY_ONE",
"independent_rerender_required": true,
"unknown_slot_forbidden": true,
"dangling_token_forbidden": true,
"required_exhibit_resolution": "BRANCH_DECLARED_ONLY",
"provisional_execution_forbidden": true
},
"branch_rows": [], "branch_rows": [],
"closure": { "closure": {
"exactly_one_approved_branch_required": true, "exactly_one_approved_branch_required": true,
@@ -0,0 +1,236 @@
from __future__ import annotations
"""Pure offline C40/C45 oracle for the S2_40 deterministic finalizer."""
import hashlib
import json
import unicodedata
import re
from typing import Any, Iterable, Mapping, Sequence
class AssemblyError(ValueError):
pass
RELATION_ORDER = {"PRIMARY": 0, "PRELIMINARY": 1, "ALTERNATIVE": 2, "SELECTIVE": 3}
CAUSE_SECTION_ORDER = {
"PARTY_AND_TITLE": 0, "COMMON_FACT": 1, "GROUP_FACT": 2,
"ELEMENT_FACT_EVIDENCE": 3, "DEFENSE_REBUTTAL": 4,
"CONCLUSION": 5, "ANNEX_EXHIBIT_REFERENCE": 6,
}
HEX64 = re.compile(r"^[a-f0-9]{64}$")
def normalize_text(value: str) -> str:
if not isinstance(value, str):
raise AssemblyError("TEXT_TYPE_INVALID")
value = unicodedata.normalize("NFC", value.replace("\r\n", "\n").replace("\r", "\n"))
if "\x00" in value:
raise AssemblyError("TEXT_NUL_FORBIDDEN")
return value
def canonical_json_bytes(value: Any) -> bytes:
return (json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + "\n").encode("utf-8")
def sha256_bytes(raw: bytes) -> str:
return hashlib.sha256(raw).hexdigest()
def reduce_immutable_rows(parts: Sequence[Mapping[str, Any]], *, id_field: str, row_field: str) -> list[dict[str, Any]]:
"""Stable union; only byte-equivalent duplicates are tolerated."""
by_id: dict[str, tuple[bytes, dict[str, Any]]] = {}
seen_parts: set[str] = set()
for part in sorted(parts, key=lambda row: (str(row.get("group_id", "")), str(row.get("part_id", "")))):
part_id = part.get("part_id")
if not isinstance(part_id, str) or not part_id or part_id in seen_parts:
raise AssemblyError("IMMUTABLE_PART_ID_MISSING_OR_DUPLICATE")
seen_parts.add(part_id)
rows = part.get(row_field)
if not isinstance(rows, list):
raise AssemblyError("IMMUTABLE_PART_ROWS_INVALID")
for row in rows:
row_id = row.get(id_field) if isinstance(row, dict) else None
if not isinstance(row_id, str) or not row_id:
raise AssemblyError("IMMUTABLE_ROW_ID_INVALID")
raw = canonical_json_bytes(row)
if row_id in by_id and by_id[row_id][0] != raw:
raise AssemblyError("IMMUTABLE_ROW_CONFLICT")
by_id[row_id] = (raw, dict(row))
return [by_id[key][1] for key in sorted(by_id)]
def validate_exact_group_part_set(
parts: Sequence[Mapping[str, Any]], *, expected_group_ids: Sequence[str],
expected_families: Sequence[str] = ("DRAFT_PART", "ISSUE_PATCH", "WORKNOTE_PART", "USAGE_PART"),
) -> None:
if len(expected_group_ids) != len(set(expected_group_ids)) or len(expected_families) != len(set(expected_families)):
raise AssemblyError("EXPECTED_PART_SET_DUPLICATE")
expected = {(group_id, family) for group_id in expected_group_ids for family in expected_families}
observed: list[tuple[str, str]] = []
part_ids: set[str] = set()
for part in parts:
part_id, group_id, family = part.get("part_id"), part.get("group_id"), part.get("part_family")
if not all(isinstance(value, str) and value for value in (part_id, group_id, family)):
raise AssemblyError("PART_SET_ROW_INVALID")
if part_id in part_ids:
raise AssemblyError("PART_SET_PART_ID_DUPLICATE")
part_ids.add(part_id)
observed.append((group_id, family))
if len(observed) != len(set(observed)) or set(observed) != expected:
raise AssemblyError("PART_SET_NOT_EXACT")
def validate_option_partition(option_ids: Iterable[str], partitions: Mapping[str, Sequence[str]]) -> None:
required = {"selected", "alternative", "excluded", "deferred"}
if set(partitions) != required:
raise AssemblyError("OPTION_PARTITION_SHAPE_INVALID")
flattened = [item for name in sorted(required) for item in partitions[name]]
if len(flattened) != len(set(flattened)):
raise AssemblyError("OPTION_PARTITION_OVERLAP")
if set(flattened) != set(option_ids):
raise AssemblyError("OPTION_PARTITION_NOT_CONSERVATIVE")
def build_usage_projection(
usage_parts: Sequence[Mapping[str, Any]], *, run_binding_digest: str,
) -> dict[str, Any]:
"""Reduce immutable S2_30 usage parts into the exact S2_40 projection contract."""
if HEX64.fullmatch(run_binding_digest) is None:
raise AssemblyError("USAGE_RUN_BINDING_DIGEST_INVALID")
source_hashes: list[str] = []
by_id: dict[str, tuple[bytes, dict[str, Any]]] = {}
observed_row_count = 0
for part in sorted(usage_parts, key=lambda value: str(value.get("part_id", ""))):
if set(part) != {"part_id", "raw_sha256", "rows"}:
raise AssemblyError("USAGE_PART_SHAPE_NOT_EXACT")
if not isinstance(part["part_id"], str) or not part["part_id"]:
raise AssemblyError("USAGE_PART_ID_INVALID")
if not isinstance(part["raw_sha256"], str) or HEX64.fullmatch(part["raw_sha256"]) is None:
raise AssemblyError("USAGE_PART_SHA256_INVALID")
rows = part["rows"]
if not isinstance(rows, list):
raise AssemblyError("USAGE_PART_ROWS_INVALID")
source_hashes.append(part["raw_sha256"])
for row in rows:
if not isinstance(row, dict):
raise AssemblyError("USAGE_ROW_NOT_OBJECT")
usage_id = row.get("usage_id")
if not isinstance(usage_id, str) or not usage_id:
raise AssemblyError("USAGE_ID_INVALID")
observed_row_count += 1
raw = canonical_json_bytes(row)
if usage_id in by_id and by_id[usage_id][0] != raw:
raise AssemblyError("USAGE_ROW_CONFLICT")
by_id[usage_id] = (raw, dict(row))
if len(source_hashes) != len(set(source_hashes)):
raise AssemblyError("USAGE_SOURCE_PART_SHA256_DUPLICATE")
rows = [by_id[key][1] for key in sorted(by_id)]
if observed_row_count != len(rows):
raise AssemblyError("USAGE_CONSERVATION_FAILED")
return {
"schema_version": "stage2_s2_40_usage_projection.v1",
"producer_id": "S2_40",
"run_binding_digest": run_binding_digest,
"source_usage_part_sha256s": sorted(source_hashes),
"rows": rows,
"conservation_status": "PASS",
}
def _ordered_relief(rows: Sequence[Mapping[str, Any]]) -> list[Mapping[str, Any]]:
claim_ids = [row.get("atomic_claim_id") for row in rows]
if any(not isinstance(value, str) or not value for value in claim_ids) or len(claim_ids) != len(set(claim_ids)):
raise AssemblyError("RELIEF_ATOMIC_CLAIM_ID_MISSING_OR_DUPLICATE")
for row in rows:
if row.get("relation") not in RELATION_ORDER:
raise AssemblyError("RELIEF_RELATION_UNKNOWN")
if not isinstance(row.get("plan_order"), int) or row["plan_order"] < 0:
raise AssemblyError("RELIEF_PLAN_ORDER_INVALID")
if not isinstance(row.get("rendered_text"), str) or not row["rendered_text"]:
raise AssemblyError("RELIEF_RENDERED_TEXT_MISSING")
return sorted(rows, key=lambda row: (RELATION_ORDER[row["relation"]], row["plan_order"], row["atomic_claim_id"]))
def _ordered_causes(atoms: Sequence[Mapping[str, Any]]) -> list[Mapping[str, Any]]:
atom_ids = [atom.get("atom_id") for atom in atoms]
if any(not isinstance(value, str) or not value for value in atom_ids) or len(atom_ids) != len(set(atom_ids)):
raise AssemblyError("CAUSE_ATOM_ID_MISSING_OR_DUPLICATE")
for atom in atoms:
if atom.get("section_kind") not in CAUSE_SECTION_ORDER:
raise AssemblyError("CAUSE_SECTION_KIND_UNKNOWN")
if not atom.get("source_refs"):
raise AssemblyError("CAUSE_ATOM_PROVENANCE_MISSING")
if not isinstance(atom.get("text"), str) or not atom["text"]:
raise AssemblyError("CAUSE_ATOM_TEXT_MISSING")
return sorted(atoms, key=lambda atom: (
CAUSE_SECTION_ORDER[atom["section_kind"]], str(atom.get("group_id", "")),
int(atom.get("atom_order", 0)), atom["atom_id"],
))
def assemble_documents(
relief_rows: Sequence[Mapping[str, Any]], cause_atoms: Sequence[Mapping[str, Any]],
*, cost_text: str, provisional_rows: Sequence[Mapping[str, Any]],
) -> dict[str, Any]:
relief, causes = _ordered_relief(relief_rows), _ordered_causes(cause_atoms)
cost_text = normalize_text(cost_text)
if not cost_text:
raise AssemblyError("COST_TEXT_MISSING")
relief_lines = [f"{index}. {normalize_text(row['rendered_text'])}" for index, row in enumerate(relief, 1)]
relief_lines.append(f"{len(relief_lines) + 1}. {cost_text}")
for row in sorted(provisional_rows, key=lambda item: item["atomic_claim_id"]):
if row.get("eligible") is not True:
raise AssemblyError("PROVISIONAL_EXECUTION_INELIGIBLE_ATOM")
relief_lines.append(f"{len(relief_lines) + 1}. {normalize_text(row['rendered_text'])}")
relief_text = normalize_text("\n".join(relief_lines) + "\n")
cause_sections: list[str] = []
current: str | None = None
for atom in causes:
if atom["section_kind"] != current:
current = atom["section_kind"]
cause_sections.append(f"## {current}")
cause_sections.append(normalize_text(atom["text"]))
cause_text = normalize_text("\n\n".join(cause_sections) + "\n")
pleading = normalize_text("# CLAIM_RELIEF\n\n" + relief_text + "\n# CLAIM_CAUSE\n\n" + cause_text)
result = {
"schema_version": "stage2_s2_40_assembled_documents.v1",
"claim_relief": {"text": relief_text, "sha256": sha256_bytes(relief_text.encode())},
"claim_cause": {"text": cause_text, "sha256": sha256_bytes(cause_text.encode())},
"pleading_draft": {"text": pleading, "sha256": sha256_bytes(pleading.encode())},
"ordered_atomic_claim_ids": [row["atomic_claim_id"] for row in relief],
"ordered_cause_atom_ids": [atom["atom_id"] for atom in causes],
}
# A second construction from detached copies must be byte-identical. This
# catches accidental mutable state, locale ordering, and hidden renderer IO.
independent_relief = normalize_text("\n".join(relief_lines) + "\n")
independent_cause = normalize_text("\n\n".join(cause_sections) + "\n")
independent_pleading = normalize_text("# CLAIM_RELIEF\n\n" + independent_relief + "\n# CLAIM_CAUSE\n\n" + independent_cause)
if (independent_relief, independent_cause, independent_pleading) != (relief_text, cause_text, pleading):
raise AssemblyError("CLOSED_DOCUMENT_RERENDER_MISMATCH")
return result
def relief_cause_crossmatch(relief_rows: Sequence[Mapping[str, Any]], cause_atoms: Sequence[Mapping[str, Any]]) -> list[str]:
cause_claims = {atom.get("atomic_claim_id") for atom in cause_atoms if atom.get("atomic_claim_id")}
findings: list[str] = []
for row in relief_rows:
claim_id = row.get("atomic_claim_id")
if claim_id not in cause_claims:
findings.append(f"RELIEF_CAUSE_ATOMIC_CLAIM_MISSING::{claim_id}")
for field in ("claimant_ref", "defendant_ref"):
expected = row.get(field)
if expected and not any(atom.get(field) == expected and atom.get("atomic_claim_id") == claim_id for atom in cause_atoms):
findings.append(f"RELIEF_CAUSE_{field.upper()}_MISMATCH::{claim_id}")
for field in ("amount_ref", "object_ref", "legal_effect_ref"):
expected = row.get(field)
if expected is not None and not any(
atom.get(field) == expected and atom.get("atomic_claim_id") == claim_id for atom in cause_atoms
):
findings.append(f"RELIEF_CAUSE_{field.upper()}_MISMATCH::{claim_id}")
return sorted(findings)
__all__ = ["AssemblyError", "assemble_documents", "build_usage_projection", "canonical_json_bytes", "reduce_immutable_rows", "relief_cause_crossmatch", "sha256_bytes", "validate_exact_group_part_set", "validate_option_partition"]
@@ -0,0 +1,236 @@
from __future__ import annotations
"""Pure offline C40/C45 oracle for the S2_40 deterministic finalizer."""
import hashlib
import json
import unicodedata
import re
from typing import Any, Iterable, Mapping, Sequence
class AssemblyError(ValueError):
pass
RELATION_ORDER = {"PRIMARY": 0, "PRELIMINARY": 1, "ALTERNATIVE": 2, "SELECTIVE": 3}
CAUSE_SECTION_ORDER = {
"PARTY_AND_TITLE": 0, "COMMON_FACT": 1, "GROUP_FACT": 2,
"ELEMENT_FACT_EVIDENCE": 3, "DEFENSE_REBUTTAL": 4,
"CONCLUSION": 5, "ANNEX_EXHIBIT_REFERENCE": 6,
}
HEX64 = re.compile(r"^[a-f0-9]{64}$")
def normalize_text(value: str) -> str:
if not isinstance(value, str):
raise AssemblyError("TEXT_TYPE_INVALID")
value = unicodedata.normalize("NFC", value.replace("\r\n", "\n").replace("\r", "\n"))
if "\x00" in value:
raise AssemblyError("TEXT_NUL_FORBIDDEN")
return value
def canonical_json_bytes(value: Any) -> bytes:
return (json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + "\n").encode("utf-8")
def sha256_bytes(raw: bytes) -> str:
return hashlib.sha256(raw).hexdigest()
def reduce_immutable_rows(parts: Sequence[Mapping[str, Any]], *, id_field: str, row_field: str) -> list[dict[str, Any]]:
"""Stable union; only byte-equivalent duplicates are tolerated."""
by_id: dict[str, tuple[bytes, dict[str, Any]]] = {}
seen_parts: set[str] = set()
for part in sorted(parts, key=lambda row: (str(row.get("group_id", "")), str(row.get("part_id", "")))):
part_id = part.get("part_id")
if not isinstance(part_id, str) or not part_id or part_id in seen_parts:
raise AssemblyError("IMMUTABLE_PART_ID_MISSING_OR_DUPLICATE")
seen_parts.add(part_id)
rows = part.get(row_field)
if not isinstance(rows, list):
raise AssemblyError("IMMUTABLE_PART_ROWS_INVALID")
for row in rows:
row_id = row.get(id_field) if isinstance(row, dict) else None
if not isinstance(row_id, str) or not row_id:
raise AssemblyError("IMMUTABLE_ROW_ID_INVALID")
raw = canonical_json_bytes(row)
if row_id in by_id and by_id[row_id][0] != raw:
raise AssemblyError("IMMUTABLE_ROW_CONFLICT")
by_id[row_id] = (raw, dict(row))
return [by_id[key][1] for key in sorted(by_id)]
def validate_exact_group_part_set(
parts: Sequence[Mapping[str, Any]], *, expected_group_ids: Sequence[str],
expected_families: Sequence[str] = ("DRAFT_PART", "ISSUE_PATCH", "WORKNOTE_PART", "USAGE_PART"),
) -> None:
if len(expected_group_ids) != len(set(expected_group_ids)) or len(expected_families) != len(set(expected_families)):
raise AssemblyError("EXPECTED_PART_SET_DUPLICATE")
expected = {(group_id, family) for group_id in expected_group_ids for family in expected_families}
observed: list[tuple[str, str]] = []
part_ids: set[str] = set()
for part in parts:
part_id, group_id, family = part.get("part_id"), part.get("group_id"), part.get("part_family")
if not all(isinstance(value, str) and value for value in (part_id, group_id, family)):
raise AssemblyError("PART_SET_ROW_INVALID")
if part_id in part_ids:
raise AssemblyError("PART_SET_PART_ID_DUPLICATE")
part_ids.add(part_id)
observed.append((group_id, family))
if len(observed) != len(set(observed)) or set(observed) != expected:
raise AssemblyError("PART_SET_NOT_EXACT")
def validate_option_partition(option_ids: Iterable[str], partitions: Mapping[str, Sequence[str]]) -> None:
required = {"selected", "alternative", "excluded", "deferred"}
if set(partitions) != required:
raise AssemblyError("OPTION_PARTITION_SHAPE_INVALID")
flattened = [item for name in sorted(required) for item in partitions[name]]
if len(flattened) != len(set(flattened)):
raise AssemblyError("OPTION_PARTITION_OVERLAP")
if set(flattened) != set(option_ids):
raise AssemblyError("OPTION_PARTITION_NOT_CONSERVATIVE")
def build_usage_projection(
usage_parts: Sequence[Mapping[str, Any]], *, run_binding_digest: str,
) -> dict[str, Any]:
"""Reduce immutable S2_30 usage parts into the exact S2_40 projection contract."""
if HEX64.fullmatch(run_binding_digest) is None:
raise AssemblyError("USAGE_RUN_BINDING_DIGEST_INVALID")
source_hashes: list[str] = []
by_id: dict[str, tuple[bytes, dict[str, Any]]] = {}
observed_row_count = 0
for part in sorted(usage_parts, key=lambda value: str(value.get("part_id", ""))):
if set(part) != {"part_id", "raw_sha256", "rows"}:
raise AssemblyError("USAGE_PART_SHAPE_NOT_EXACT")
if not isinstance(part["part_id"], str) or not part["part_id"]:
raise AssemblyError("USAGE_PART_ID_INVALID")
if not isinstance(part["raw_sha256"], str) or HEX64.fullmatch(part["raw_sha256"]) is None:
raise AssemblyError("USAGE_PART_SHA256_INVALID")
rows = part["rows"]
if not isinstance(rows, list):
raise AssemblyError("USAGE_PART_ROWS_INVALID")
source_hashes.append(part["raw_sha256"])
for row in rows:
if not isinstance(row, dict):
raise AssemblyError("USAGE_ROW_NOT_OBJECT")
usage_id = row.get("usage_id")
if not isinstance(usage_id, str) or not usage_id:
raise AssemblyError("USAGE_ID_INVALID")
observed_row_count += 1
raw = canonical_json_bytes(row)
if usage_id in by_id and by_id[usage_id][0] != raw:
raise AssemblyError("USAGE_ROW_CONFLICT")
by_id[usage_id] = (raw, dict(row))
if len(source_hashes) != len(set(source_hashes)):
raise AssemblyError("USAGE_SOURCE_PART_SHA256_DUPLICATE")
rows = [by_id[key][1] for key in sorted(by_id)]
if observed_row_count != len(rows):
raise AssemblyError("USAGE_CONSERVATION_FAILED")
return {
"schema_version": "stage2_s2_40_usage_projection.v1",
"producer_id": "S2_40",
"run_binding_digest": run_binding_digest,
"source_usage_part_sha256s": sorted(source_hashes),
"rows": rows,
"conservation_status": "PASS",
}
def _ordered_relief(rows: Sequence[Mapping[str, Any]]) -> list[Mapping[str, Any]]:
claim_ids = [row.get("atomic_claim_id") for row in rows]
if any(not isinstance(value, str) or not value for value in claim_ids) or len(claim_ids) != len(set(claim_ids)):
raise AssemblyError("RELIEF_ATOMIC_CLAIM_ID_MISSING_OR_DUPLICATE")
for row in rows:
if row.get("relation") not in RELATION_ORDER:
raise AssemblyError("RELIEF_RELATION_UNKNOWN")
if not isinstance(row.get("plan_order"), int) or row["plan_order"] < 0:
raise AssemblyError("RELIEF_PLAN_ORDER_INVALID")
if not isinstance(row.get("rendered_text"), str) or not row["rendered_text"]:
raise AssemblyError("RELIEF_RENDERED_TEXT_MISSING")
return sorted(rows, key=lambda row: (RELATION_ORDER[row["relation"]], row["plan_order"], row["atomic_claim_id"]))
def _ordered_causes(atoms: Sequence[Mapping[str, Any]]) -> list[Mapping[str, Any]]:
atom_ids = [atom.get("atom_id") for atom in atoms]
if any(not isinstance(value, str) or not value for value in atom_ids) or len(atom_ids) != len(set(atom_ids)):
raise AssemblyError("CAUSE_ATOM_ID_MISSING_OR_DUPLICATE")
for atom in atoms:
if atom.get("section_kind") not in CAUSE_SECTION_ORDER:
raise AssemblyError("CAUSE_SECTION_KIND_UNKNOWN")
if not atom.get("source_refs"):
raise AssemblyError("CAUSE_ATOM_PROVENANCE_MISSING")
if not isinstance(atom.get("text"), str) or not atom["text"]:
raise AssemblyError("CAUSE_ATOM_TEXT_MISSING")
return sorted(atoms, key=lambda atom: (
CAUSE_SECTION_ORDER[atom["section_kind"]], str(atom.get("group_id", "")),
int(atom.get("atom_order", 0)), atom["atom_id"],
))
def assemble_documents(
relief_rows: Sequence[Mapping[str, Any]], cause_atoms: Sequence[Mapping[str, Any]],
*, cost_text: str, provisional_rows: Sequence[Mapping[str, Any]],
) -> dict[str, Any]:
relief, causes = _ordered_relief(relief_rows), _ordered_causes(cause_atoms)
cost_text = normalize_text(cost_text)
if not cost_text:
raise AssemblyError("COST_TEXT_MISSING")
relief_lines = [f"{index}. {normalize_text(row['rendered_text'])}" for index, row in enumerate(relief, 1)]
relief_lines.append(f"{len(relief_lines) + 1}. {cost_text}")
for row in sorted(provisional_rows, key=lambda item: item["atomic_claim_id"]):
if row.get("eligible") is not True:
raise AssemblyError("PROVISIONAL_EXECUTION_INELIGIBLE_ATOM")
relief_lines.append(f"{len(relief_lines) + 1}. {normalize_text(row['rendered_text'])}")
relief_text = normalize_text("\n".join(relief_lines) + "\n")
cause_sections: list[str] = []
current: str | None = None
for atom in causes:
if atom["section_kind"] != current:
current = atom["section_kind"]
cause_sections.append(f"## {current}")
cause_sections.append(normalize_text(atom["text"]))
cause_text = normalize_text("\n\n".join(cause_sections) + "\n")
pleading = normalize_text("# CLAIM_RELIEF\n\n" + relief_text + "\n# CLAIM_CAUSE\n\n" + cause_text)
result = {
"schema_version": "stage2_s2_40_assembled_documents.v1",
"claim_relief": {"text": relief_text, "sha256": sha256_bytes(relief_text.encode())},
"claim_cause": {"text": cause_text, "sha256": sha256_bytes(cause_text.encode())},
"pleading_draft": {"text": pleading, "sha256": sha256_bytes(pleading.encode())},
"ordered_atomic_claim_ids": [row["atomic_claim_id"] for row in relief],
"ordered_cause_atom_ids": [atom["atom_id"] for atom in causes],
}
# A second construction from detached copies must be byte-identical. This
# catches accidental mutable state, locale ordering, and hidden renderer IO.
independent_relief = normalize_text("\n".join(relief_lines) + "\n")
independent_cause = normalize_text("\n\n".join(cause_sections) + "\n")
independent_pleading = normalize_text("# CLAIM_RELIEF\n\n" + independent_relief + "\n# CLAIM_CAUSE\n\n" + independent_cause)
if (independent_relief, independent_cause, independent_pleading) != (relief_text, cause_text, pleading):
raise AssemblyError("CLOSED_DOCUMENT_RERENDER_MISMATCH")
return result
def relief_cause_crossmatch(relief_rows: Sequence[Mapping[str, Any]], cause_atoms: Sequence[Mapping[str, Any]]) -> list[str]:
cause_claims = {atom.get("atomic_claim_id") for atom in cause_atoms if atom.get("atomic_claim_id")}
findings: list[str] = []
for row in relief_rows:
claim_id = row.get("atomic_claim_id")
if claim_id not in cause_claims:
findings.append(f"RELIEF_CAUSE_ATOMIC_CLAIM_MISSING::{claim_id}")
for field in ("claimant_ref", "defendant_ref"):
expected = row.get(field)
if expected and not any(atom.get(field) == expected and atom.get("atomic_claim_id") == claim_id for atom in cause_atoms):
findings.append(f"RELIEF_CAUSE_{field.upper()}_MISMATCH::{claim_id}")
for field in ("amount_ref", "object_ref", "legal_effect_ref"):
expected = row.get(field)
if expected is not None and not any(
atom.get(field) == expected and atom.get("atomic_claim_id") == claim_id for atom in cause_atoms
):
findings.append(f"RELIEF_CAUSE_{field.upper()}_MISMATCH::{claim_id}")
return sorted(findings)
__all__ = ["AssemblyError", "assemble_documents", "build_usage_projection", "canonical_json_bytes", "reduce_immutable_rows", "relief_cause_crossmatch", "sha256_bytes", "validate_exact_group_part_set", "validate_option_partition"]
@@ -0,0 +1,215 @@
from __future__ import annotations
"""Offline oracle for S2_40 closed rendering; contains no legal wording."""
from copy import deepcopy
import hashlib
import json
import re
import unicodedata
from typing import Any, Mapping, Sequence
ALLOWED_SLOT_TYPES = {
"STRING", "IDENTIFIER", "MONEY", "DATE", "OBJECT_REF", "PARTY_REF", "EXHIBIT_REF"
}
ALLOWED_PREDICATE_OPS = {"EQ", "IN", "BOOL"}
class ClosedRenderError(ValueError):
"""Raised when a closed renderer contract cannot be applied exactly."""
def normalize_text(value: str) -> str:
if not isinstance(value, str):
raise ClosedRenderError("RENDERER_SLOT_TYPE_MISMATCH")
normalized = unicodedata.normalize("NFC", value.replace("\r\n", "\n").replace("\r", "\n"))
if "\x00" in normalized:
raise ClosedRenderError("RENDERER_NUL_FORBIDDEN")
return normalized
def canonical_json_bytes(value: Any) -> bytes:
return (json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + "\n").encode("utf-8")
def sha256_bytes(raw: bytes) -> str:
return hashlib.sha256(raw).hexdigest()
def _unique_names(rows: Sequence[Mapping[str, Any]], field: str) -> set[str]:
names = [row.get(field) for row in rows]
if any(not isinstance(name, str) or not name for name in names):
raise ClosedRenderError(f"RENDERER_{field.upper()}_INVALID")
if len(names) != len(set(names)):
raise ClosedRenderError(f"RENDERER_{field.upper()}_DUPLICATE")
return set(names)
def validate_descriptor(descriptor: Mapping[str, Any], *, allow_fixture: bool = False) -> None:
required = {
"schema_version", "renderer_id", "renderer_kind", "status", "execution_eligible",
"stage2_20_role", "stage2_40_role", "typed_slot_contract", "closed_ast_contract",
"branch_rows", "closure", "review",
}
if set(descriptor) != required:
raise ClosedRenderError("RENDERER_DESCRIPTOR_SHAPE_INVALID")
if not descriptor["execution_eligible"]:
raise ClosedRenderError("RENDERER_NOT_EXECUTION_ELIGIBLE")
if descriptor["status"] != "APPROVED_LEGAL_CONTENT":
if not (allow_fixture and descriptor["status"] == "STRUCTURAL_FIXTURE_ONLY"):
raise ClosedRenderError("RENDERER_LEGAL_CONTENT_NOT_APPROVED")
slots = descriptor["typed_slot_contract"].get("slot_definitions", [])
slot_names = _unique_names(slots, "name")
structural_names = descriptor["typed_slot_contract"].get("structural_slot_names")
if structural_names is not None and (not isinstance(structural_names, list) or set(structural_names) != slot_names or len(structural_names) != len(slot_names)):
raise ClosedRenderError("RENDERER_STRUCTURAL_SLOT_SET_MISMATCH")
for slot in slots:
if slot.get("type") not in ALLOWED_SLOT_TYPES:
raise ClosedRenderError("RENDERER_SLOT_TYPE_UNKNOWN")
if slot.get("cardinality") not in {"EXACTLY_ONE", "ZERO_OR_ONE", "ONE_OR_MORE"}:
raise ClosedRenderError("RENDERER_SLOT_CARDINALITY_UNKNOWN")
branches = descriptor["branch_rows"]
_unique_names(branches, "branch_id")
for branch in branches:
if branch.get("approval_status") != "APPROVED":
raise ClosedRenderError("RENDERER_BRANCH_NOT_APPROVED")
predicates = branch.get("predicates", [])
if not isinstance(predicates, list):
raise ClosedRenderError("RENDERER_PREDICATES_INVALID")
predicate_keys: set[tuple[str, str]] = set()
for predicate in predicates:
if predicate.get("op") not in ALLOWED_PREDICATE_OPS:
raise ClosedRenderError("RENDERER_PREDICATE_OP_UNKNOWN")
field = predicate.get("field")
if not isinstance(field, str) or not field:
raise ClosedRenderError("RENDERER_PREDICATE_FIELD_INVALID")
key = (field, predicate["op"])
if key in predicate_keys:
raise ClosedRenderError("RENDERER_PREDICATE_DUPLICATE")
predicate_keys.add(key)
segments = branch.get("segments")
if not isinstance(segments, list) or not segments:
raise ClosedRenderError("RENDERER_SEGMENTS_EMPTY")
for segment in segments:
if segment.get("kind") == "LITERAL":
if set(segment) != {"kind", "value"}:
raise ClosedRenderError("RENDERER_LITERAL_SEGMENT_INVALID")
normalize_text(segment["value"])
elif segment.get("kind") == "SLOT":
if set(segment) != {"kind", "name", "escape"}:
raise ClosedRenderError("RENDERER_SLOT_SEGMENT_INVALID")
if segment["name"] not in slot_names:
raise ClosedRenderError("RENDERER_UNKNOWN_TEMPLATE_SLOT")
if segment["escape"] not in {"PLAIN_TEXT", "MARKDOWN_TEXT"}:
raise ClosedRenderError("RENDERER_ESCAPE_POLICY_UNKNOWN")
else:
raise ClosedRenderError("RENDERER_SEGMENT_KIND_UNKNOWN")
def _matches(predicate: Mapping[str, Any], context: Mapping[str, Any]) -> bool:
field = predicate.get("field")
if not isinstance(field, str) or field not in context:
return False
observed, op = context[field], predicate.get("op")
if op == "EQ":
return observed == predicate.get("value")
if op == "IN":
return isinstance(predicate.get("values"), list) and observed in predicate["values"]
if op == "BOOL":
return isinstance(observed, bool) and observed is predicate.get("value")
return False
def select_branch(descriptor: Mapping[str, Any], context: Mapping[str, Any], *, allow_fixture: bool = False) -> Mapping[str, Any]:
validate_descriptor(descriptor, allow_fixture=allow_fixture)
matches = [row for row in descriptor["branch_rows"] if all(_matches(p, context) for p in row.get("predicates", []))]
if not matches:
raise ClosedRenderError(descriptor["closure"]["zero_match_issue_code"])
if len(matches) != 1:
raise ClosedRenderError(descriptor["closure"]["multi_match_issue_code"])
return matches[0]
def _escape(value: str, policy: str) -> str:
value = normalize_text(value)
if "{{" in value or "}}" in value:
raise ClosedRenderError("RENDERER_DANGLING_TEMPLATE_TOKEN")
if policy == "PLAIN_TEXT":
return value
if policy == "MARKDOWN_TEXT":
return re.sub(r"([\\`*_{}\[\]<>#|])", r"\\\1", value)
raise ClosedRenderError("RENDERER_ESCAPE_POLICY_UNKNOWN")
def escape_slot_value(value: str, policy: str) -> str:
"""Public oracle for the exact inline PLAIN_TEXT/MARKDOWN_TEXT semantics."""
return _escape(value, policy)
def _render_frozen(branch: Mapping[str, Any], definitions: Mapping[str, Any], slots: Mapping[str, Any]) -> str:
pieces: list[str] = []
for segment in branch["segments"]:
if segment["kind"] == "LITERAL":
pieces.append(normalize_text(segment["value"]))
continue
definition, value = definitions[segment["name"]], slots.get(segment["name"])
if value is None and definition["cardinality"] == "ZERO_OR_ONE":
continue
if isinstance(value, list):
if not value or any(not isinstance(item, str) for item in value):
raise ClosedRenderError("RENDERER_SLOT_LIST_INVALID")
pieces.append(", ".join(_escape(item, segment["escape"]) for item in value))
else:
if value is not None and not isinstance(value, str):
raise ClosedRenderError("RENDERER_SLOT_TYPE_MISMATCH")
pieces.append(_escape(value, segment["escape"]))
return normalize_text("".join(pieces))
def render_closed(
descriptor: Mapping[str, Any], branch_context: Mapping[str, Any], slots: Mapping[str, Any],
*, atom_type: str, allow_fixture: bool = False,
) -> dict[str, Any]:
branch = select_branch(descriptor, branch_context, allow_fixture=allow_fixture)
if atom_type not in set(descriptor["closed_ast_contract"]["allowed_atom_types"]):
raise ClosedRenderError("RENDERER_ATOM_TYPE_FORBIDDEN")
definitions = {row["name"]: row for row in descriptor["typed_slot_contract"]["slot_definitions"]}
if set(slots) - set(definitions):
raise ClosedRenderError("RENDERER_UNKNOWN_SLOT")
for name, definition in definitions.items():
value = slots.get(name)
if value is None and definition["cardinality"] in {"EXACTLY_ONE", "ONE_OR_MORE"}:
raise ClosedRenderError("RENDERER_REQUIRED_SLOT_MISSING")
if isinstance(value, list) != (definition["cardinality"] == "ONE_OR_MORE") and value is not None:
raise ClosedRenderError("RENDERER_SLOT_CARDINALITY_MISMATCH")
output = _render_frozen(branch, definitions, slots)
detached = json.loads(canonical_json_bytes({"branch": branch, "definitions": definitions, "slots": slots}))
independent = _render_frozen(detached["branch"], detached["definitions"], detached["slots"])
if output.encode("utf-8") != independent.encode("utf-8"):
raise ClosedRenderError("RENDERER_INDEPENDENT_RERENDER_MISMATCH")
if re.search(r"\{\{[^}]*\}\}", output):
raise ClosedRenderError("RENDERER_DANGLING_TEMPLATE_TOKEN")
return {
"schema_version": "stage2_s2_40_closed_render_result.v1",
"renderer_id": descriptor["renderer_id"], "branch_id": branch["branch_id"],
"atom_type": atom_type, "consumed_slot_names": sorted(slots),
"rendered_text": output, "rendered_sha256": sha256_bytes(output.encode("utf-8")),
"renderer_branch_sha256": sha256_bytes(canonical_json_bytes(branch)),
"slot_binding_sha256": sha256_bytes(canonical_json_bytes(dict(slots))),
"independent_rerender_sha256": sha256_bytes(independent.encode("utf-8")),
"normalization_version": descriptor["closed_ast_contract"]["normalization_version"],
}
def provisional_execution_eligible(atom: Mapping[str, Any]) -> bool:
return bool(
atom.get("proprietary_claim") is True and atom.get("performance_atom") is True
and atom.get("atomic_branch_provisional_execution_policy") == "ALLOW"
and atom.get("approved_authority_ref_is_valid") is True
and atom.get("dependent_on_constitutive_judgment") is False
and atom.get("renderer_id") not in {"R03", "R05", "R06"}
)
__all__ = ["ClosedRenderError", "canonical_json_bytes", "escape_slot_value", "normalize_text", "provisional_execution_eligible", "render_closed", "select_branch", "sha256_bytes", "validate_descriptor"]
@@ -0,0 +1,215 @@
from __future__ import annotations
"""Offline oracle for S2_40 closed rendering; contains no legal wording."""
from copy import deepcopy
import hashlib
import json
import re
import unicodedata
from typing import Any, Mapping, Sequence
ALLOWED_SLOT_TYPES = {
"STRING", "IDENTIFIER", "MONEY", "DATE", "OBJECT_REF", "PARTY_REF", "EXHIBIT_REF"
}
ALLOWED_PREDICATE_OPS = {"EQ", "IN", "BOOL"}
class ClosedRenderError(ValueError):
"""Raised when a closed renderer contract cannot be applied exactly."""
def normalize_text(value: str) -> str:
if not isinstance(value, str):
raise ClosedRenderError("RENDERER_SLOT_TYPE_MISMATCH")
normalized = unicodedata.normalize("NFC", value.replace("\r\n", "\n").replace("\r", "\n"))
if "\x00" in normalized:
raise ClosedRenderError("RENDERER_NUL_FORBIDDEN")
return normalized
def canonical_json_bytes(value: Any) -> bytes:
return (json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + "\n").encode("utf-8")
def sha256_bytes(raw: bytes) -> str:
return hashlib.sha256(raw).hexdigest()
def _unique_names(rows: Sequence[Mapping[str, Any]], field: str) -> set[str]:
names = [row.get(field) for row in rows]
if any(not isinstance(name, str) or not name for name in names):
raise ClosedRenderError(f"RENDERER_{field.upper()}_INVALID")
if len(names) != len(set(names)):
raise ClosedRenderError(f"RENDERER_{field.upper()}_DUPLICATE")
return set(names)
def validate_descriptor(descriptor: Mapping[str, Any], *, allow_fixture: bool = False) -> None:
required = {
"schema_version", "renderer_id", "renderer_kind", "status", "execution_eligible",
"stage2_20_role", "stage2_40_role", "typed_slot_contract", "closed_ast_contract",
"branch_rows", "closure", "review",
}
if set(descriptor) != required:
raise ClosedRenderError("RENDERER_DESCRIPTOR_SHAPE_INVALID")
if not descriptor["execution_eligible"]:
raise ClosedRenderError("RENDERER_NOT_EXECUTION_ELIGIBLE")
if descriptor["status"] != "APPROVED_LEGAL_CONTENT":
if not (allow_fixture and descriptor["status"] == "STRUCTURAL_FIXTURE_ONLY"):
raise ClosedRenderError("RENDERER_LEGAL_CONTENT_NOT_APPROVED")
slots = descriptor["typed_slot_contract"].get("slot_definitions", [])
slot_names = _unique_names(slots, "name")
structural_names = descriptor["typed_slot_contract"].get("structural_slot_names")
if structural_names is not None and (not isinstance(structural_names, list) or set(structural_names) != slot_names or len(structural_names) != len(slot_names)):
raise ClosedRenderError("RENDERER_STRUCTURAL_SLOT_SET_MISMATCH")
for slot in slots:
if slot.get("type") not in ALLOWED_SLOT_TYPES:
raise ClosedRenderError("RENDERER_SLOT_TYPE_UNKNOWN")
if slot.get("cardinality") not in {"EXACTLY_ONE", "ZERO_OR_ONE", "ONE_OR_MORE"}:
raise ClosedRenderError("RENDERER_SLOT_CARDINALITY_UNKNOWN")
branches = descriptor["branch_rows"]
_unique_names(branches, "branch_id")
for branch in branches:
if branch.get("approval_status") != "APPROVED":
raise ClosedRenderError("RENDERER_BRANCH_NOT_APPROVED")
predicates = branch.get("predicates", [])
if not isinstance(predicates, list):
raise ClosedRenderError("RENDERER_PREDICATES_INVALID")
predicate_keys: set[tuple[str, str]] = set()
for predicate in predicates:
if predicate.get("op") not in ALLOWED_PREDICATE_OPS:
raise ClosedRenderError("RENDERER_PREDICATE_OP_UNKNOWN")
field = predicate.get("field")
if not isinstance(field, str) or not field:
raise ClosedRenderError("RENDERER_PREDICATE_FIELD_INVALID")
key = (field, predicate["op"])
if key in predicate_keys:
raise ClosedRenderError("RENDERER_PREDICATE_DUPLICATE")
predicate_keys.add(key)
segments = branch.get("segments")
if not isinstance(segments, list) or not segments:
raise ClosedRenderError("RENDERER_SEGMENTS_EMPTY")
for segment in segments:
if segment.get("kind") == "LITERAL":
if set(segment) != {"kind", "value"}:
raise ClosedRenderError("RENDERER_LITERAL_SEGMENT_INVALID")
normalize_text(segment["value"])
elif segment.get("kind") == "SLOT":
if set(segment) != {"kind", "name", "escape"}:
raise ClosedRenderError("RENDERER_SLOT_SEGMENT_INVALID")
if segment["name"] not in slot_names:
raise ClosedRenderError("RENDERER_UNKNOWN_TEMPLATE_SLOT")
if segment["escape"] not in {"PLAIN_TEXT", "MARKDOWN_TEXT"}:
raise ClosedRenderError("RENDERER_ESCAPE_POLICY_UNKNOWN")
else:
raise ClosedRenderError("RENDERER_SEGMENT_KIND_UNKNOWN")
def _matches(predicate: Mapping[str, Any], context: Mapping[str, Any]) -> bool:
field = predicate.get("field")
if not isinstance(field, str) or field not in context:
return False
observed, op = context[field], predicate.get("op")
if op == "EQ":
return observed == predicate.get("value")
if op == "IN":
return isinstance(predicate.get("values"), list) and observed in predicate["values"]
if op == "BOOL":
return isinstance(observed, bool) and observed is predicate.get("value")
return False
def select_branch(descriptor: Mapping[str, Any], context: Mapping[str, Any], *, allow_fixture: bool = False) -> Mapping[str, Any]:
validate_descriptor(descriptor, allow_fixture=allow_fixture)
matches = [row for row in descriptor["branch_rows"] if all(_matches(p, context) for p in row.get("predicates", []))]
if not matches:
raise ClosedRenderError(descriptor["closure"]["zero_match_issue_code"])
if len(matches) != 1:
raise ClosedRenderError(descriptor["closure"]["multi_match_issue_code"])
return matches[0]
def _escape(value: str, policy: str) -> str:
value = normalize_text(value)
if "{{" in value or "}}" in value:
raise ClosedRenderError("RENDERER_DANGLING_TEMPLATE_TOKEN")
if policy == "PLAIN_TEXT":
return value
if policy == "MARKDOWN_TEXT":
return re.sub(r"([\\`*_{}\[\]<>#|])", r"\\\1", value)
raise ClosedRenderError("RENDERER_ESCAPE_POLICY_UNKNOWN")
def escape_slot_value(value: str, policy: str) -> str:
"""Public oracle for the exact inline PLAIN_TEXT/MARKDOWN_TEXT semantics."""
return _escape(value, policy)
def _render_frozen(branch: Mapping[str, Any], definitions: Mapping[str, Any], slots: Mapping[str, Any]) -> str:
pieces: list[str] = []
for segment in branch["segments"]:
if segment["kind"] == "LITERAL":
pieces.append(normalize_text(segment["value"]))
continue
definition, value = definitions[segment["name"]], slots.get(segment["name"])
if value is None and definition["cardinality"] == "ZERO_OR_ONE":
continue
if isinstance(value, list):
if not value or any(not isinstance(item, str) for item in value):
raise ClosedRenderError("RENDERER_SLOT_LIST_INVALID")
pieces.append(", ".join(_escape(item, segment["escape"]) for item in value))
else:
if value is not None and not isinstance(value, str):
raise ClosedRenderError("RENDERER_SLOT_TYPE_MISMATCH")
pieces.append(_escape(value, segment["escape"]))
return normalize_text("".join(pieces))
def render_closed(
descriptor: Mapping[str, Any], branch_context: Mapping[str, Any], slots: Mapping[str, Any],
*, atom_type: str, allow_fixture: bool = False,
) -> dict[str, Any]:
branch = select_branch(descriptor, branch_context, allow_fixture=allow_fixture)
if atom_type not in set(descriptor["closed_ast_contract"]["allowed_atom_types"]):
raise ClosedRenderError("RENDERER_ATOM_TYPE_FORBIDDEN")
definitions = {row["name"]: row for row in descriptor["typed_slot_contract"]["slot_definitions"]}
if set(slots) - set(definitions):
raise ClosedRenderError("RENDERER_UNKNOWN_SLOT")
for name, definition in definitions.items():
value = slots.get(name)
if value is None and definition["cardinality"] in {"EXACTLY_ONE", "ONE_OR_MORE"}:
raise ClosedRenderError("RENDERER_REQUIRED_SLOT_MISSING")
if isinstance(value, list) != (definition["cardinality"] == "ONE_OR_MORE") and value is not None:
raise ClosedRenderError("RENDERER_SLOT_CARDINALITY_MISMATCH")
output = _render_frozen(branch, definitions, slots)
detached = json.loads(canonical_json_bytes({"branch": branch, "definitions": definitions, "slots": slots}))
independent = _render_frozen(detached["branch"], detached["definitions"], detached["slots"])
if output.encode("utf-8") != independent.encode("utf-8"):
raise ClosedRenderError("RENDERER_INDEPENDENT_RERENDER_MISMATCH")
if re.search(r"\{\{[^}]*\}\}", output):
raise ClosedRenderError("RENDERER_DANGLING_TEMPLATE_TOKEN")
return {
"schema_version": "stage2_s2_40_closed_render_result.v1",
"renderer_id": descriptor["renderer_id"], "branch_id": branch["branch_id"],
"atom_type": atom_type, "consumed_slot_names": sorted(slots),
"rendered_text": output, "rendered_sha256": sha256_bytes(output.encode("utf-8")),
"renderer_branch_sha256": sha256_bytes(canonical_json_bytes(branch)),
"slot_binding_sha256": sha256_bytes(canonical_json_bytes(dict(slots))),
"independent_rerender_sha256": sha256_bytes(independent.encode("utf-8")),
"normalization_version": descriptor["closed_ast_contract"]["normalization_version"],
}
def provisional_execution_eligible(atom: Mapping[str, Any]) -> bool:
return bool(
atom.get("proprietary_claim") is True and atom.get("performance_atom") is True
and atom.get("atomic_branch_provisional_execution_policy") == "ALLOW"
and atom.get("approved_authority_ref_is_valid") is True
and atom.get("dependent_on_constitutive_judgment") is False
and atom.get("renderer_id") not in {"R03", "R05", "R06"}
)
__all__ = ["ClosedRenderError", "canonical_json_bytes", "escape_slot_value", "normalize_text", "provisional_execution_eligible", "render_closed", "select_branch", "sha256_bytes", "validate_descriptor"]
@@ -149,7 +149,7 @@ _RAW_VALUE_UNSET = object()
# literal placeholders in the offline parity mirror and its unit tests. # literal placeholders in the offline parity mirror and its unit tests.
INLINE_USER_HASH = "{{__user_hash__}}" INLINE_USER_HASH = "{{__user_hash__}}"
INLINE_WORKSPACE_HASH = "{{__workspace_hash__}}" INLINE_WORKSPACE_HASH = "{{__workspace_hash__}}"
EXPECTED_STAGE2_RELEASE_SHA256 = "579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81" EXPECTED_STAGE2_RELEASE_SHA256 = "9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53"
INLINE_REQUEST_PATH = "stage2_control/s2_00_request.json" INLINE_REQUEST_PATH = "stage2_control/s2_00_request.json"
INLINE_STAGE2_ASSET_ROOT = "Default_Agent/Stage_2_Clean" INLINE_STAGE2_ASSET_ROOT = "Default_Agent/Stage_2_Clean"
INLINE_STAGE2_RELEASE_PATH = ( INLINE_STAGE2_RELEASE_PATH = (
@@ -149,7 +149,7 @@ _RAW_VALUE_UNSET = object()
# literal placeholders in the offline parity mirror and its unit tests. # literal placeholders in the offline parity mirror and its unit tests.
INLINE_USER_HASH = "{{__user_hash__}}" INLINE_USER_HASH = "{{__user_hash__}}"
INLINE_WORKSPACE_HASH = "{{__workspace_hash__}}" INLINE_WORKSPACE_HASH = "{{__workspace_hash__}}"
EXPECTED_STAGE2_RELEASE_SHA256 = "579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81" EXPECTED_STAGE2_RELEASE_SHA256 = "9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53"
INLINE_REQUEST_PATH = "stage2_control/s2_00_request.json" INLINE_REQUEST_PATH = "stage2_control/s2_00_request.json"
INLINE_STAGE2_ASSET_ROOT = "Default_Agent/Stage_2_Clean" INLINE_STAGE2_ASSET_ROOT = "Default_Agent/Stage_2_Clean"
INLINE_STAGE2_RELEASE_PATH = ( INLINE_STAGE2_RELEASE_PATH = (
@@ -27,7 +27,7 @@ from typing import Any, Iterable, Mapping, Sequence
WORKFLOW_ID = "S2_20" WORKFLOW_ID = "S2_20"
ALGORITHM_VERSION = "s2_20_relief_plan/1.0.0" ALGORITHM_VERSION = "s2_20_relief_plan/1.0.0"
EXPECTED_STAGE2_RELEASE_SHA256 = "579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81" EXPECTED_STAGE2_RELEASE_SHA256 = "9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53"
LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp" LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp"
WEAVIATE_MCP_URL = "https://weaviate.eroomai.com/mcp" WEAVIATE_MCP_URL = "https://weaviate.eroomai.com/mcp"
MCP_PROTOCOL_VERSION = "2025-03-26" MCP_PROTOCOL_VERSION = "2025-03-26"
@@ -27,7 +27,7 @@ from typing import Any, Iterable, Mapping, Sequence
WORKFLOW_ID = "S2_20" WORKFLOW_ID = "S2_20"
ALGORITHM_VERSION = "s2_20_relief_plan/1.0.0" ALGORITHM_VERSION = "s2_20_relief_plan/1.0.0"
EXPECTED_STAGE2_RELEASE_SHA256 = "579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81" EXPECTED_STAGE2_RELEASE_SHA256 = "9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53"
LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp" LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp"
WEAVIATE_MCP_URL = "https://weaviate.eroomai.com/mcp" WEAVIATE_MCP_URL = "https://weaviate.eroomai.com/mcp"
MCP_PROTOCOL_VERSION = "2025-03-26" MCP_PROTOCOL_VERSION = "2025-03-26"
@@ -18,7 +18,7 @@ import sys
from typing import Any, Mapping from typing import Any, Mapping
EXPECTED_STAGE2_RELEASE_SHA256 = "579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81" EXPECTED_STAGE2_RELEASE_SHA256 = "9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53"
LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp" LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp"
MCP_PROTOCOL_VERSION = "2025-03-26" MCP_PROTOCOL_VERSION = "2025-03-26"
INLINE_USER_HASH = "{{__user_hash__}}" INLINE_USER_HASH = "{{__user_hash__}}"
@@ -18,7 +18,7 @@ import sys
from typing import Any, Mapping from typing import Any, Mapping
EXPECTED_STAGE2_RELEASE_SHA256 = "579e4c896cf16bf2fab1482bc6327319035b1c320528bb818d36d3f9036c1b81" EXPECTED_STAGE2_RELEASE_SHA256 = "9fa85bb94c5f14f675dcdaa0cf94d06745b21675d97797539ffc14015dcc9f53"
LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp" LOCALDOCS_URL = "http://mcp-localdocs:8012/mcp"
MCP_PROTOCOL_VERSION = "2025-03-26" MCP_PROTOCOL_VERSION = "2025-03-26"
INLINE_USER_HASH = "{{__user_hash__}}" INLINE_USER_HASH = "{{__user_hash__}}"
@@ -0,0 +1,575 @@
from __future__ import annotations
"""Closed S2_40 V01-V18 and review/commit state oracle."""
import hashlib
import json
import re
from datetime import datetime, timezone
from typing import Any, Mapping, Sequence
INVARIANT_IDS = tuple(f"V{index:02d}" for index in range(1, 19))
IMPACT_SCOPES = {"OK", "REVIEW_REQUIRED", "INCOMPLETE"}
REQUIRED_LEGAL_GATES = {
"binding", "authority", "renderer_branch", "rule_sub_rule", "review_policy",
"case_type_coverage_137", "corpus", "law_value", "calculator", "required_receipts",
}
HEX64 = re.compile(r"^[a-f0-9]{64}$")
CANDIDATE_MATERIAL_KEYS = {
"run_binding_digest", "dependency_snapshot_sha256", "candidate_manifest_core_sha256",
"document_sha256s", "attorney_worknotes_core_sha256", "final_issue_ledger_sha256",
"assumption_ledger_sha256", "validation_core_sha256",
"ordered_source_dependency_snapshot_digest",
}
DOCUMENT_DIGEST_KEYS = {"claim_relief", "claim_cause", "pleading_draft"}
STATUS_ONLY_PATHS = (
"ingress/ingress_status.json",
"ingress/technical_diagnostic.json",
"ingress/stage1_input_manifest.json",
"ingress/intake_report.json",
"review/issue_ledger.base.json",
)
REVIEW_RECEIPT_KEYS = {
"schema_version", "receipt_id", "request_id", "receipt_type",
"candidate_content_digest", "review_subject_digest", "finding_ids", "scope_ids",
"reviewer_role", "reviewer_qualification", "issuer_id", "key_id",
"signature_algorithm", "signed_material_digest",
"external_verification_attestation_sha256", "issued_at", "expires_at",
"revocation_status", "cryptographic_verification_status", "review_disposition",
"change_scope", "reason_codes",
}
TRUSTED_REVIEW_ISSUER = "AGENTBACKEND_STAGE2_REVIEW_AUTHORITY"
TRUSTED_REVIEW_KEY_IDS = frozenset({"AGENTBACKEND_STAGE2_REVIEW_KEY_V1"})
TRUSTED_REVIEW_SIGNATURE_ALGORITHM = "AGENTBACKEND_TRUSTED_ATTESTATION_V1"
TRUSTED_REVIEW_ROLE = "KOREAN_LAWYER"
TRUSTED_REVIEW_QUALIFICATION = "QUALIFIED_KOREAN_LAWYER"
class InvariantError(ValueError):
pass
class JsonSchemaValidationError(InvariantError):
pass
def canonical_json_bytes(value: Any) -> bytes:
return (json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + "\n").encode("utf-8")
def _require_sha256(value: Any, code: str) -> str:
if not isinstance(value, str) or HEX64.fullmatch(value) is None:
raise InvariantError(code)
return value
def validate_jsonschema_instance(
instance: Any, schema: Mapping[str, Any], *,
schema_store: Mapping[str, Mapping[str, Any]] | None = None,
) -> None:
"""Validate the closed JSON-Schema subset used by the S2_40 contracts."""
store = dict(schema_store or {})
root = schema
def resolve(reference: str, current_root: Mapping[str, Any]) -> tuple[Mapping[str, Any], Mapping[str, Any]]:
if "#" in reference:
file_name, fragment = reference.split("#", 1)
else:
file_name, fragment = reference, ""
target_root = current_root if not file_name else store.get(file_name)
if target_root is None:
raise JsonSchemaValidationError(f"SCHEMA_REF_UNRESOLVED::{reference}")
target: Any = target_root
if fragment:
if not fragment.startswith("/"):
raise JsonSchemaValidationError(f"SCHEMA_REF_FRAGMENT_INVALID::{reference}")
for token in fragment[1:].split("/"):
token = token.replace("~1", "/").replace("~0", "~")
if not isinstance(target, Mapping) or token not in target:
raise JsonSchemaValidationError(f"SCHEMA_REF_UNRESOLVED::{reference}")
target = target[token]
if not isinstance(target, Mapping):
raise JsonSchemaValidationError(f"SCHEMA_REF_TARGET_INVALID::{reference}")
return target, target_root
def type_matches(value: Any, type_name: str) -> bool:
return {
"object": isinstance(value, Mapping),
"array": isinstance(value, list),
"string": isinstance(value, str),
"integer": isinstance(value, int) and not isinstance(value, bool),
"number": isinstance(value, (int, float)) and not isinstance(value, bool),
"boolean": isinstance(value, bool),
"null": value is None,
}.get(type_name, False)
def check(value: Any, rule: Mapping[str, Any], current_root: Mapping[str, Any], path: str) -> None:
if "$ref" in rule:
target, target_root = resolve(str(rule["$ref"]), current_root)
check(value, target, target_root, path)
return
if "allOf" in rule:
for index, branch in enumerate(rule["allOf"]):
check(value, branch, current_root, f"{path}/allOf/{index}")
if "oneOf" in rule:
successes = 0
for branch in rule["oneOf"]:
try:
check(value, branch, current_root, path)
successes += 1
except JsonSchemaValidationError:
pass
if successes != 1:
raise JsonSchemaValidationError(f"{path}:ONE_OF_COUNT::{successes}")
if "anyOf" in rule:
for branch in rule["anyOf"]:
try:
check(value, branch, current_root, path)
break
except JsonSchemaValidationError:
continue
else:
raise JsonSchemaValidationError(f"{path}:ANY_OF_NO_MATCH")
if "not" in rule:
try:
check(value, rule["not"], current_root, path)
except JsonSchemaValidationError:
pass
else:
raise JsonSchemaValidationError(f"{path}:NOT_SCHEMA_MATCHED")
if "if" in rule:
try:
check(value, rule["if"], current_root, path)
matched = True
except JsonSchemaValidationError:
matched = False
if matched and "then" in rule:
check(value, rule["then"], current_root, path)
if not matched and "else" in rule:
check(value, rule["else"], current_root, path)
if "const" in rule and value != rule["const"]:
raise JsonSchemaValidationError(f"{path}:CONST_MISMATCH")
if "enum" in rule and value not in rule["enum"]:
raise JsonSchemaValidationError(f"{path}:ENUM_MISMATCH")
declared_type = rule.get("type")
if declared_type is not None:
allowed = [declared_type] if isinstance(declared_type, str) else list(declared_type)
if not any(type_matches(value, item) for item in allowed):
raise JsonSchemaValidationError(f"{path}:TYPE_MISMATCH")
if isinstance(value, str):
if len(value) < int(rule.get("minLength", 0)):
raise JsonSchemaValidationError(f"{path}:MIN_LENGTH")
if "pattern" in rule and re.search(str(rule["pattern"]), value) is None:
raise JsonSchemaValidationError(f"{path}:PATTERN_MISMATCH")
if rule.get("format") == "date-time":
try:
_parse_review_time(value, f"{path}:DATETIME_INVALID")
except InvariantError as exc:
raise JsonSchemaValidationError(str(exc)) from exc
if isinstance(value, Mapping):
required = rule.get("required", [])
missing = [key for key in required if key not in value]
if missing:
raise JsonSchemaValidationError(f"{path}:REQUIRED_MISSING::{','.join(missing)}")
properties = rule.get("properties", {})
if rule.get("additionalProperties") is False:
extras = sorted(set(value) - set(properties))
if extras:
raise JsonSchemaValidationError(f"{path}:ADDITIONAL_PROPERTIES::{','.join(extras)}")
for key, child in properties.items():
if key in value:
check(value[key], child, current_root, f"{path}/{key}")
if isinstance(value, list):
if len(value) < int(rule.get("minItems", 0)):
raise JsonSchemaValidationError(f"{path}:MIN_ITEMS")
if "maxItems" in rule and len(value) > int(rule["maxItems"]):
raise JsonSchemaValidationError(f"{path}:MAX_ITEMS")
if rule.get("uniqueItems") and len({canonical_json_bytes(item) for item in value}) != len(value):
raise JsonSchemaValidationError(f"{path}:UNIQUE_ITEMS")
if "items" in rule:
for index, item in enumerate(value):
check(item, rule["items"], current_root, f"{path}/{index}")
if isinstance(value, (int, float)) and not isinstance(value, bool) and "minimum" in rule and value < rule["minimum"]:
raise JsonSchemaValidationError(f"{path}:MINIMUM")
check(instance, root, root, "$")
def validate_candidate_material(material: Mapping[str, Any]) -> None:
if set(material) != CANDIDATE_MATERIAL_KEYS:
raise InvariantError("CANDIDATE_DIGEST_MATERIAL_SHAPE")
for key in CANDIDATE_MATERIAL_KEYS - {"document_sha256s"}:
_require_sha256(material[key], f"CANDIDATE_{key.upper()}_INVALID")
documents = material["document_sha256s"]
if not isinstance(documents, Mapping) or set(documents) != DOCUMENT_DIGEST_KEYS:
raise InvariantError("CANDIDATE_DOCUMENT_DIGEST_SET_NOT_EXACT")
for key, value in documents.items():
_require_sha256(value, f"CANDIDATE_DOCUMENT_{key.upper()}_INVALID")
def review_subject_digest(
*, candidate_digest: str, review_request_core_sha256: str,
lawyer_review_packet_core_sha256: str, validation_envelope_core_sha256: str,
finding_ids: Sequence[str], scope_ids: Sequence[str], policy_sha256: str,
release_sha256s: Mapping[str, str],
) -> str:
for value, code in (
(candidate_digest, "REVIEW_CANDIDATE_DIGEST_INVALID"),
(review_request_core_sha256, "REVIEW_REQUEST_CORE_HASH_INVALID"),
(lawyer_review_packet_core_sha256, "REVIEW_PACKET_CORE_HASH_INVALID"),
(validation_envelope_core_sha256, "REVIEW_VALIDATION_HASH_INVALID"),
(policy_sha256, "REVIEW_POLICY_HASH_INVALID"),
):
_require_sha256(value, code)
expected_release_keys = {"parent", "authority", "corpus", "case_type_coverage"}
if set(release_sha256s) != expected_release_keys:
raise InvariantError("REVIEW_RELEASE_SNAPSHOT_NOT_EXACT")
for value in release_sha256s.values():
_require_sha256(value, "REVIEW_RELEASE_HASH_INVALID")
if len(finding_ids) != len(set(finding_ids)) or len(scope_ids) != len(set(scope_ids)):
raise InvariantError("REVIEW_SUBJECT_SET_DUPLICATE")
subject_core = {
"schema_version": "stage2_s2_40_review_subject.v1",
"domain_separator": "STAGE2_S2_40_REVIEW_SUBJECT_V1",
"candidate_content_digest": candidate_digest,
"review_request_core_sha256": review_request_core_sha256,
"lawyer_review_packet_core_sha256": lawyer_review_packet_core_sha256,
"validation_envelope_core_sha256": validation_envelope_core_sha256,
"finding_ids": sorted(finding_ids), "scope_ids": sorted(scope_ids),
"policy_sha256": policy_sha256,
"release_sha256s": {key: release_sha256s[key] for key in sorted(release_sha256s)},
}
return hashlib.sha256(canonical_json_bytes(subject_core)).hexdigest()
def validate_status_only_paths(paths: Sequence[str]) -> None:
if tuple(paths) != STATUS_ONLY_PATHS:
raise InvariantError("STATUS_ONLY_INPUT_SET_NOT_EXACT_FIVE")
def validate_reference_closure(required_refs: Sequence[str], available_refs: Sequence[str]) -> None:
if len(required_refs) != len(set(required_refs)) or len(available_refs) != len(set(available_refs)):
raise InvariantError("REFERENCE_SET_DUPLICATE")
missing = sorted(set(required_refs) - set(available_refs))
if missing:
raise InvariantError("REFERENCE_DANGLING::" + ",".join(missing))
def validate_readback_rows(expected_rows: Sequence[Mapping[str, Any]], observed_rows: Sequence[Mapping[str, Any]]) -> None:
def normalize(rows: Sequence[Mapping[str, Any]]) -> list[tuple[str, str, str, int, str | None]]:
normalized: list[tuple[str, str, str, int, str | None]] = []
for row in rows:
if set(row) != {"path", "raw_sha256", "content_type", "size_bytes", "schema_ref"}:
raise InvariantError("READBACK_ROW_SHAPE_INVALID")
path = row["path"]
if not isinstance(path, str) or not path.startswith("final/") or ".." in path.split("/"):
raise InvariantError("READBACK_PATH_INVALID")
content_type, schema_ref, size = row["content_type"], row["schema_ref"], row["size_bytes"]
if not isinstance(content_type, str) or not content_type or not isinstance(size, int) or size < 1:
raise InvariantError("READBACK_METADATA_INVALID")
if schema_ref is not None and (not isinstance(schema_ref, str) or not schema_ref):
raise InvariantError("READBACK_SCHEMA_REF_INVALID")
normalized.append((path, _require_sha256(row["raw_sha256"], "READBACK_HASH_INVALID"), content_type, size, schema_ref))
if len({row[0] for row in normalized}) != len(normalized):
raise InvariantError("READBACK_PATH_DUPLICATE")
return sorted(normalized)
if normalize(expected_rows) != normalize(observed_rows):
raise InvariantError("READBACK_MISMATCH_NO_FINAL_BARRIER")
def run_invariants(checks: Mapping[str, Mapping[str, Any]]) -> list[dict[str, Any]]:
if set(checks) != set(INVARIANT_IDS):
raise InvariantError("INVARIANT_SET_NOT_EXACT_V01_V18")
results: list[dict[str, Any]] = []
for invariant_id in INVARIANT_IDS:
check = checks[invariant_id]
if not isinstance(check, Mapping):
raise InvariantError("INVARIANT_CHECK_NOT_OBJECT")
required_check_keys = {
"evaluable", "passed", "impact_scope", "source_refs", "finding_ids",
"expected", "observed", "reason_codes",
}
if set(check) != required_check_keys:
raise InvariantError(f"{invariant_id}_CHECK_SHAPE_NOT_EXACT")
evaluable = check["evaluable"]
if not isinstance(evaluable, bool):
raise InvariantError(f"{invariant_id}_EVALUABLE_NOT_BOOLEAN")
if evaluable:
if not isinstance(check["passed"], bool):
raise InvariantError(f"{invariant_id}_PASSED_NOT_BOOLEAN")
if check["observed"] is None or check["passed"] != (check["observed"] == check["expected"]):
raise InvariantError(f"{invariant_id}_OBSERVATION_ORACLE_MISMATCH")
evaluation = "PASS" if check["passed"] else "FAIL"
else:
if check["passed"] not in {False, None} or check["observed"] is not None:
raise InvariantError(f"{invariant_id}_UNEVALUABLE_OBSERVATION_INVALID")
evaluation = "UNEVALUABLE"
scope = check.get("impact_scope", "OK" if evaluation == "PASS" else "REVIEW_REQUIRED")
if scope not in IMPACT_SCOPES or (evaluation == "PASS" and scope != "OK"):
raise InvariantError("INVARIANT_IMPACT_SCOPE_INVALID")
reason_values = check["reason_codes"]
source_values = check["source_refs"]
finding_values = check["finding_ids"]
for values in (reason_values, source_values, finding_values):
if (not isinstance(values, list) or len(values) != len(set(values))
or not all(isinstance(value, str) and value for value in values)):
raise InvariantError("INVARIANT_STRING_SET_INVALID")
if not source_values:
raise InvariantError(f"{invariant_id}_SOURCE_EVIDENCE_REQUIRED")
reason_codes = sorted(set(reason_values))
if evaluation == "PASS" and (reason_codes or finding_values):
raise InvariantError(f"{invariant_id}_PASS_FINDING_FORBIDDEN")
if evaluation != "PASS" and (not reason_codes or not finding_values):
raise InvariantError(f"{invariant_id}_{evaluation}_FINDING_REQUIRED")
results.append({
"invariant_id": invariant_id, "evaluation_status": evaluation,
"finding_ids": sorted(set(finding_values)), "impact_scope": scope,
"source_refs": sorted(set(source_values)),
"expected": check["expected"], "observed": check["observed"],
"reason_codes": reason_codes, "validator_algorithm_id": f"S2_40::{invariant_id}::V1",
})
return results
def aggregate_status(results: Sequence[Mapping[str, Any]], *, compile_mode: str | None, legal_gates: Mapping[str, bool]) -> dict[str, str]:
if [row.get("invariant_id") for row in results] != list(INVARIANT_IDS):
raise InvariantError("INVARIANT_RESULT_ORDER_OR_SET_INVALID")
for row in results:
evaluation, scope = row.get("evaluation_status"), row.get("impact_scope")
if evaluation not in {"PASS", "FAIL", "UNEVALUABLE"} or scope not in IMPACT_SCOPES:
raise InvariantError("INVARIANT_RESULT_ENUM_INVALID")
if evaluation == "PASS" and scope != "OK":
raise InvariantError("INVARIANT_PASS_SCOPE_INVALID")
scopes = {row.get("impact_scope") for row in results}
if "INCOMPLETE" in scopes:
run = "TECHNICAL_INCOMPLETE"
elif "REVIEW_REQUIRED" in scopes or any(row.get("evaluation_status") == "UNEVALUABLE" for row in results):
run = "TECHNICAL_REVIEW_REQUIRED"
else:
run = "CONSISTENT"
if run == "TECHNICAL_INCOMPLETE":
artifact, legal = "NOT_PRODUCED", "NOT_ASSESSED"
elif run == "TECHNICAL_REVIEW_REQUIRED":
artifact, legal = "TECHNICAL_REVIEW_REQUIRED", "LAWYER_REVIEW_REQUIRED"
else:
artifact = "CONSISTENT"
gates = set(legal_gates) == REQUIRED_LEGAL_GATES and all(legal_gates.values())
all_pass = all(row.get("evaluation_status") == "PASS" for row in results)
legal = "READY_FOR_LAWYER_FILING_DECISION" if compile_mode == "PRODUCTION" and all_pass and gates else "LAWYER_REVIEW_REQUIRED"
return {"run_technical_status": run, "artifact_technical_status": artifact, "legal_readiness": legal}
def candidate_content_digest(material: Mapping[str, Any]) -> str:
forbidden = {"candidate_content_digest", "review_request", "review_receipt", "commit_intent", "commit_result", "run_status", "artifact_set_digest"}
if forbidden & set(material):
raise InvariantError("CANDIDATE_DIGEST_MATERIAL_CYCLE")
validate_candidate_material(material)
digest_core = {
"schema_version": "stage2_s2_40_candidate_content_digest.v1",
"domain_separator": "STAGE2_S2_40_CANDIDATE_CONTENT_V1",
**material,
}
return hashlib.sha256(canonical_json_bytes(digest_core)).hexdigest()
def artifact_set_digest(rows: Sequence[Mapping[str, Any]]) -> str:
ordered = sorted(rows, key=lambda row: row["path"])
paths = [row["path"] for row in ordered]
if len(paths) != len(set(paths)):
raise InvariantError("ARTIFACT_PATH_DUPLICATE")
for row in ordered:
if set(row) != {"path", "raw_sha256", "content_type", "size_bytes", "schema_ref"}:
raise InvariantError("ARTIFACT_ROW_SHAPE_INVALID")
_require_sha256(row["raw_sha256"], "ARTIFACT_ROW_HASH_INVALID")
if not isinstance(row["content_type"], str) or not row["content_type"]:
raise InvariantError("ARTIFACT_ROW_CONTENT_TYPE_INVALID")
if not isinstance(row["size_bytes"], int) or row["size_bytes"] < 1:
raise InvariantError("ARTIFACT_ROW_SIZE_INVALID")
if row["schema_ref"] is not None and (not isinstance(row["schema_ref"], str) or not row["schema_ref"]):
raise InvariantError("ARTIFACT_ROW_SCHEMA_REF_INVALID")
return hashlib.sha256(canonical_json_bytes(ordered)).hexdigest()
def derive_review_requirements(policy: Mapping[str, Any], active_tags: Sequence[str], runtime_triggers: Sequence[str]) -> list[str]:
if policy.get("status") != "APPROVED_LEGAL_CONTENT" or policy.get("execution_eligible") is not True:
return ["STANDARD_ATTORNEY_REVIEW"]
allowed_tags = set(policy["final_review_contract"]["allowed_review_tags"])
if not set(active_tags) <= allowed_tags:
raise InvariantError("REVIEW_TAG_UNKNOWN")
required = set(policy["final_review_contract"]["base_required_receipt_types"])
for row in policy.get("policy_rows", []):
if set(row.get("match_tags", [])) <= set(active_tags) and set(row.get("runtime_triggers", [])) <= set(runtime_triggers):
required.update(row.get("required_receipt_types", []))
return sorted(required)
def review_receipt_signed_material_digest(receipt: Mapping[str, Any]) -> str:
"""Hash the exact inline receipt preimage, including detached-adapter evidence."""
keys = (
"request_id", "candidate_content_digest", "review_subject_digest", "receipt_type",
"finding_ids", "scope_ids", "reviewer_role", "reviewer_qualification",
"issuer_id", "key_id", "signature_algorithm",
"external_verification_attestation_sha256", "issued_at", "expires_at",
"revocation_status", "cryptographic_verification_status",
"review_disposition", "change_scope", "reason_codes",
)
if any(key not in receipt for key in keys):
raise InvariantError("REVIEW_SIGNED_MATERIAL_FIELD_MISSING")
material = ["STAGE2_S2_40_REVIEW_RECEIPT_V1", *[receipt[key] for key in keys]]
return hashlib.sha256(canonical_json_bytes(material)).hexdigest()
def _parse_review_time(value: Any, code: str) -> datetime:
if not isinstance(value, str):
raise InvariantError(code)
try:
parsed = datetime.fromisoformat(value.replace("Z", "+00:00"))
except ValueError as exc:
raise InvariantError(code) from exc
if parsed.tzinfo is None:
raise InvariantError(code)
return parsed.astimezone(timezone.utc)
def validate_review_receipt(
receipt: Mapping[str, Any], *, candidate_digest: str,
expected_review_subject_digest: str, expected_request_id: str,
expected_receipt_type: str, expected_finding_ids: Sequence[str],
expected_scope_ids: Sequence[str], now: datetime,
) -> list[str]:
"""Return closed invalidity codes; an empty list means externally admissible."""
reasons: list[str] = []
if set(receipt) != REVIEW_RECEIPT_KEYS or receipt.get("schema_version") != "stage2_s2_40_review_receipt.v1":
return ["REVIEW_RECEIPT_CLOSED_SHAPE_INVALID"]
for key in ("receipt_id", "request_id", "receipt_type", "reviewer_role", "reviewer_qualification", "issuer_id", "key_id", "signature_algorithm"):
if not isinstance(receipt.get(key), str) or not receipt[key]:
reasons.append(f"REVIEW_RECEIPT_{key.upper()}_INVALID")
for key in ("candidate_content_digest", "review_subject_digest", "signed_material_digest", "external_verification_attestation_sha256"):
try:
_require_sha256(receipt.get(key), f"REVIEW_RECEIPT_{key.upper()}_INVALID")
except InvariantError as exc:
reasons.append(str(exc))
for key, expected in (
("candidate_content_digest", candidate_digest),
("review_subject_digest", expected_review_subject_digest),
("request_id", expected_request_id),
("receipt_type", expected_receipt_type),
("finding_ids", sorted(expected_finding_ids)),
("scope_ids", sorted(expected_scope_ids)),
):
observed = sorted(receipt[key]) if key in {"finding_ids", "scope_ids"} and isinstance(receipt[key], list) else receipt[key]
if observed != expected:
reasons.append(f"REVIEW_RECEIPT_{key.upper()}_MISMATCH")
for key in ("finding_ids", "scope_ids", "reason_codes"):
values = receipt.get(key)
if not isinstance(values, list) or values != sorted(set(values)) or not all(isinstance(value, str) and value for value in values):
reasons.append(f"REVIEW_RECEIPT_{key.upper()}_NOT_SORTED_SET")
if receipt.get("reviewer_role") != TRUSTED_REVIEW_ROLE:
reasons.append("REVIEW_RECEIPT_ROLE_UNTRUSTED")
if receipt.get("reviewer_qualification") != TRUSTED_REVIEW_QUALIFICATION:
reasons.append("REVIEW_RECEIPT_QUALIFICATION_UNTRUSTED")
if receipt.get("issuer_id") != TRUSTED_REVIEW_ISSUER:
reasons.append("REVIEW_RECEIPT_ISSUER_UNTRUSTED")
if receipt.get("key_id") not in TRUSTED_REVIEW_KEY_IDS:
reasons.append("REVIEW_RECEIPT_KEY_UNTRUSTED")
if receipt.get("signature_algorithm") != TRUSTED_REVIEW_SIGNATURE_ALGORITHM:
reasons.append("REVIEW_RECEIPT_SIGNATURE_ALGORITHM_UNTRUSTED")
if receipt.get("cryptographic_verification_status") != "VERIFIED_BY_EXTERNAL_ADAPTER":
reasons.append("REVIEW_RECEIPT_EXTERNAL_VERIFICATION_NOT_VERIFIED")
if receipt.get("revocation_status") != "NOT_REVOKED":
reasons.append("REVIEW_RECEIPT_REVOKED_OR_UNKNOWN")
try:
issued = _parse_review_time(receipt.get("issued_at"), "REVIEW_RECEIPT_ISSUED_AT_INVALID")
expires = _parse_review_time(receipt.get("expires_at"), "REVIEW_RECEIPT_EXPIRES_AT_INVALID")
current = now.astimezone(timezone.utc)
if issued > current or expires <= current or expires <= issued:
reasons.append("REVIEW_RECEIPT_TIME_WINDOW_INVALID")
except InvariantError as exc:
reasons.append(str(exc))
disposition, change_scope = receipt.get("review_disposition"), receipt.get("change_scope")
if disposition == "APPROVE_AS_IS" and change_scope != "NONE":
reasons.append("REVIEW_RECEIPT_APPROVAL_CHANGE_SCOPE_FORBIDDEN")
elif disposition == "CONTENT_CHANGE_REQUIRED" and change_scope not in {
"STAGE1_CONTEXT", "LEGAL_JUDGMENT", "PLAN_RULE_CALCULATION_BINDING", "DRAFTING_TEXT_ATOM",
}:
reasons.append("REVIEW_RECEIPT_CHANGE_SCOPE_INVALID")
elif disposition not in {"APPROVE_AS_IS", "CONTENT_CHANGE_REQUIRED"}:
reasons.append("REVIEW_RECEIPT_DISPOSITION_INVALID")
try:
expected_signed = review_receipt_signed_material_digest(receipt)
if receipt.get("signed_material_digest") != expected_signed:
reasons.append("REVIEW_RECEIPT_SIGNED_MATERIAL_MISMATCH")
except InvariantError as exc:
reasons.append(str(exc))
return sorted(set(reasons))
def transition_review_state(
*, candidate_digest: str, required_receipt_types: Sequence[str],
receipts: Sequence[Mapping[str, Any]], expected_review_subject_digest: str,
expected_request_ids: Mapping[str, str], expected_finding_ids: Sequence[str],
expected_scope_ids: Sequence[str], now: datetime,
) -> dict[str, Any]:
_require_sha256(candidate_digest, "REVIEW_CANDIDATE_DIGEST_INVALID")
if len(required_receipt_types) != len(set(required_receipt_types)):
raise InvariantError("REVIEW_REQUIRED_TYPE_DUPLICATE")
_require_sha256(expected_review_subject_digest, "REVIEW_SUBJECT_DIGEST_INVALID")
if set(expected_request_ids) != set(required_receipt_types) or any(
not isinstance(value, str) or not value for value in expected_request_ids.values()
):
raise InvariantError("REVIEW_REQUEST_ID_MAP_INVALID")
valid: dict[str, Mapping[str, Any]] = {}
invalid: list[str] = []
invalid_reasons: dict[str, list[str]] = {}
seen_receipt_ids: set[str] = set()
for receipt in receipts:
receipt_id = receipt.get("receipt_id")
receipt_type = receipt.get("receipt_type")
if not isinstance(receipt_id, str) or not receipt_id or receipt_id in seen_receipt_ids:
raise InvariantError("REVIEW_RECEIPT_ID_MISSING_OR_DUPLICATE")
seen_receipt_ids.add(receipt_id)
reasons = validate_review_receipt(
receipt, candidate_digest=candidate_digest,
expected_review_subject_digest=expected_review_subject_digest,
expected_request_id=expected_request_ids.get(str(receipt_type), ""),
expected_receipt_type=str(receipt_type),
expected_finding_ids=expected_finding_ids, expected_scope_ids=expected_scope_ids,
now=now,
)
if receipt_type not in required_receipt_types:
reasons.append("REVIEW_RECEIPT_TYPE_NOT_REQUIRED")
if reasons:
invalid.append(receipt_id)
invalid_reasons[receipt_id] = sorted(set(reasons))
else:
if receipt_type in valid:
raise InvariantError("REVIEW_RECEIPT_TYPE_DUPLICATE")
valid[receipt_type] = receipt
routes = {
"STAGE1_CONTEXT": (0, "RESTART_FROM_S2_00"),
"LEGAL_JUDGMENT": (1, "RESTART_FROM_S2_10"),
"PLAN_RULE_CALCULATION_BINDING": (2, "RESTART_FROM_S2_20"),
"DRAFTING_TEXT_ATOM": (3, "RESTART_FROM_S2_30"),
}
changed_scopes = [receipt["change_scope"] for receipt in valid.values() if receipt["review_disposition"] == "CONTENT_CHANGE_REQUIRED"]
if changed_scopes:
earliest = min(changed_scopes, key=lambda scope: routes[scope][0])
return {"workflow_phase": "SUPERSEDED", "route": routes[earliest][1], "invalid_receipt_ids": sorted(invalid), "invalid_receipt_reasons": invalid_reasons}
missing = sorted(set(required_receipt_types) - set(valid))
if missing or invalid:
return {"workflow_phase": "AWAITING_EXTERNAL_REVIEW", "route": "WAIT_EXTERNAL_REVIEW", "missing_receipt_types": missing, "invalid_receipt_ids": sorted(invalid), "invalid_receipt_reasons": invalid_reasons}
if any(receipt.get("review_disposition") != "APPROVE_AS_IS" for receipt in valid.values()):
raise InvariantError("REVIEW_DISPOSITION_INVALID")
return {"workflow_phase": "READY_TO_COMMIT", "route": "CONTINUE_TO_COMMIT", "invalid_receipt_ids": [], "invalid_receipt_reasons": {}}
def commit_write_order(final_paths: Sequence[str]) -> list[str]:
if len(final_paths) != len(set(final_paths)):
raise InvariantError("COMMIT_TARGET_DUPLICATE")
if any(not path.startswith("final/") or ".." in path.split("/") for path in final_paths):
raise InvariantError("COMMIT_TARGET_OUTSIDE_FINAL_ROOT")
return ["commit/commit_intent.json", *sorted(final_paths), "commit/stage2_commit_result.json", "control/run_status.json"]
__all__ = ["INVARIANT_IDS", "InvariantError", "JsonSchemaValidationError", "aggregate_status", "artifact_set_digest", "candidate_content_digest", "commit_write_order", "derive_review_requirements", "review_receipt_signed_material_digest", "review_subject_digest", "run_invariants", "transition_review_state", "validate_candidate_material", "validate_jsonschema_instance", "validate_readback_rows", "validate_reference_closure", "validate_review_receipt", "validate_status_only_paths"]
@@ -0,0 +1,575 @@
from __future__ import annotations
"""Closed S2_40 V01-V18 and review/commit state oracle."""
import hashlib
import json
import re
from datetime import datetime, timezone
from typing import Any, Mapping, Sequence
INVARIANT_IDS = tuple(f"V{index:02d}" for index in range(1, 19))
IMPACT_SCOPES = {"OK", "REVIEW_REQUIRED", "INCOMPLETE"}
REQUIRED_LEGAL_GATES = {
"binding", "authority", "renderer_branch", "rule_sub_rule", "review_policy",
"case_type_coverage_137", "corpus", "law_value", "calculator", "required_receipts",
}
HEX64 = re.compile(r"^[a-f0-9]{64}$")
CANDIDATE_MATERIAL_KEYS = {
"run_binding_digest", "dependency_snapshot_sha256", "candidate_manifest_core_sha256",
"document_sha256s", "attorney_worknotes_core_sha256", "final_issue_ledger_sha256",
"assumption_ledger_sha256", "validation_core_sha256",
"ordered_source_dependency_snapshot_digest",
}
DOCUMENT_DIGEST_KEYS = {"claim_relief", "claim_cause", "pleading_draft"}
STATUS_ONLY_PATHS = (
"ingress/ingress_status.json",
"ingress/technical_diagnostic.json",
"ingress/stage1_input_manifest.json",
"ingress/intake_report.json",
"review/issue_ledger.base.json",
)
REVIEW_RECEIPT_KEYS = {
"schema_version", "receipt_id", "request_id", "receipt_type",
"candidate_content_digest", "review_subject_digest", "finding_ids", "scope_ids",
"reviewer_role", "reviewer_qualification", "issuer_id", "key_id",
"signature_algorithm", "signed_material_digest",
"external_verification_attestation_sha256", "issued_at", "expires_at",
"revocation_status", "cryptographic_verification_status", "review_disposition",
"change_scope", "reason_codes",
}
TRUSTED_REVIEW_ISSUER = "AGENTBACKEND_STAGE2_REVIEW_AUTHORITY"
TRUSTED_REVIEW_KEY_IDS = frozenset({"AGENTBACKEND_STAGE2_REVIEW_KEY_V1"})
TRUSTED_REVIEW_SIGNATURE_ALGORITHM = "AGENTBACKEND_TRUSTED_ATTESTATION_V1"
TRUSTED_REVIEW_ROLE = "KOREAN_LAWYER"
TRUSTED_REVIEW_QUALIFICATION = "QUALIFIED_KOREAN_LAWYER"
class InvariantError(ValueError):
pass
class JsonSchemaValidationError(InvariantError):
pass
def canonical_json_bytes(value: Any) -> bytes:
return (json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) + "\n").encode("utf-8")
def _require_sha256(value: Any, code: str) -> str:
if not isinstance(value, str) or HEX64.fullmatch(value) is None:
raise InvariantError(code)
return value
def validate_jsonschema_instance(
instance: Any, schema: Mapping[str, Any], *,
schema_store: Mapping[str, Mapping[str, Any]] | None = None,
) -> None:
"""Validate the closed JSON-Schema subset used by the S2_40 contracts."""
store = dict(schema_store or {})
root = schema
def resolve(reference: str, current_root: Mapping[str, Any]) -> tuple[Mapping[str, Any], Mapping[str, Any]]:
if "#" in reference:
file_name, fragment = reference.split("#", 1)
else:
file_name, fragment = reference, ""
target_root = current_root if not file_name else store.get(file_name)
if target_root is None:
raise JsonSchemaValidationError(f"SCHEMA_REF_UNRESOLVED::{reference}")
target: Any = target_root
if fragment:
if not fragment.startswith("/"):
raise JsonSchemaValidationError(f"SCHEMA_REF_FRAGMENT_INVALID::{reference}")
for token in fragment[1:].split("/"):
token = token.replace("~1", "/").replace("~0", "~")
if not isinstance(target, Mapping) or token not in target:
raise JsonSchemaValidationError(f"SCHEMA_REF_UNRESOLVED::{reference}")
target = target[token]
if not isinstance(target, Mapping):
raise JsonSchemaValidationError(f"SCHEMA_REF_TARGET_INVALID::{reference}")
return target, target_root
def type_matches(value: Any, type_name: str) -> bool:
return {
"object": isinstance(value, Mapping),
"array": isinstance(value, list),
"string": isinstance(value, str),
"integer": isinstance(value, int) and not isinstance(value, bool),
"number": isinstance(value, (int, float)) and not isinstance(value, bool),
"boolean": isinstance(value, bool),
"null": value is None,
}.get(type_name, False)
def check(value: Any, rule: Mapping[str, Any], current_root: Mapping[str, Any], path: str) -> None:
if "$ref" in rule:
target, target_root = resolve(str(rule["$ref"]), current_root)
check(value, target, target_root, path)
return
if "allOf" in rule:
for index, branch in enumerate(rule["allOf"]):
check(value, branch, current_root, f"{path}/allOf/{index}")
if "oneOf" in rule:
successes = 0
for branch in rule["oneOf"]:
try:
check(value, branch, current_root, path)
successes += 1
except JsonSchemaValidationError:
pass
if successes != 1:
raise JsonSchemaValidationError(f"{path}:ONE_OF_COUNT::{successes}")
if "anyOf" in rule:
for branch in rule["anyOf"]:
try:
check(value, branch, current_root, path)
break
except JsonSchemaValidationError:
continue
else:
raise JsonSchemaValidationError(f"{path}:ANY_OF_NO_MATCH")
if "not" in rule:
try:
check(value, rule["not"], current_root, path)
except JsonSchemaValidationError:
pass
else:
raise JsonSchemaValidationError(f"{path}:NOT_SCHEMA_MATCHED")
if "if" in rule:
try:
check(value, rule["if"], current_root, path)
matched = True
except JsonSchemaValidationError:
matched = False
if matched and "then" in rule:
check(value, rule["then"], current_root, path)
if not matched and "else" in rule:
check(value, rule["else"], current_root, path)
if "const" in rule and value != rule["const"]:
raise JsonSchemaValidationError(f"{path}:CONST_MISMATCH")
if "enum" in rule and value not in rule["enum"]:
raise JsonSchemaValidationError(f"{path}:ENUM_MISMATCH")
declared_type = rule.get("type")
if declared_type is not None:
allowed = [declared_type] if isinstance(declared_type, str) else list(declared_type)
if not any(type_matches(value, item) for item in allowed):
raise JsonSchemaValidationError(f"{path}:TYPE_MISMATCH")
if isinstance(value, str):
if len(value) < int(rule.get("minLength", 0)):
raise JsonSchemaValidationError(f"{path}:MIN_LENGTH")
if "pattern" in rule and re.search(str(rule["pattern"]), value) is None:
raise JsonSchemaValidationError(f"{path}:PATTERN_MISMATCH")
if rule.get("format") == "date-time":
try:
_parse_review_time(value, f"{path}:DATETIME_INVALID")
except InvariantError as exc:
raise JsonSchemaValidationError(str(exc)) from exc
if isinstance(value, Mapping):
required = rule.get("required", [])
missing = [key for key in required if key not in value]
if missing:
raise JsonSchemaValidationError(f"{path}:REQUIRED_MISSING::{','.join(missing)}")
properties = rule.get("properties", {})
if rule.get("additionalProperties") is False:
extras = sorted(set(value) - set(properties))
if extras:
raise JsonSchemaValidationError(f"{path}:ADDITIONAL_PROPERTIES::{','.join(extras)}")
for key, child in properties.items():
if key in value:
check(value[key], child, current_root, f"{path}/{key}")
if isinstance(value, list):
if len(value) < int(rule.get("minItems", 0)):
raise JsonSchemaValidationError(f"{path}:MIN_ITEMS")
if "maxItems" in rule and len(value) > int(rule["maxItems"]):
raise JsonSchemaValidationError(f"{path}:MAX_ITEMS")
if rule.get("uniqueItems") and len({canonical_json_bytes(item) for item in value}) != len(value):
raise JsonSchemaValidationError(f"{path}:UNIQUE_ITEMS")
if "items" in rule:
for index, item in enumerate(value):
check(item, rule["items"], current_root, f"{path}/{index}")
if isinstance(value, (int, float)) and not isinstance(value, bool) and "minimum" in rule and value < rule["minimum"]:
raise JsonSchemaValidationError(f"{path}:MINIMUM")
check(instance, root, root, "$")
def validate_candidate_material(material: Mapping[str, Any]) -> None:
if set(material) != CANDIDATE_MATERIAL_KEYS:
raise InvariantError("CANDIDATE_DIGEST_MATERIAL_SHAPE")
for key in CANDIDATE_MATERIAL_KEYS - {"document_sha256s"}:
_require_sha256(material[key], f"CANDIDATE_{key.upper()}_INVALID")
documents = material["document_sha256s"]
if not isinstance(documents, Mapping) or set(documents) != DOCUMENT_DIGEST_KEYS:
raise InvariantError("CANDIDATE_DOCUMENT_DIGEST_SET_NOT_EXACT")
for key, value in documents.items():
_require_sha256(value, f"CANDIDATE_DOCUMENT_{key.upper()}_INVALID")
def review_subject_digest(
*, candidate_digest: str, review_request_core_sha256: str,
lawyer_review_packet_core_sha256: str, validation_envelope_core_sha256: str,
finding_ids: Sequence[str], scope_ids: Sequence[str], policy_sha256: str,
release_sha256s: Mapping[str, str],
) -> str:
for value, code in (
(candidate_digest, "REVIEW_CANDIDATE_DIGEST_INVALID"),
(review_request_core_sha256, "REVIEW_REQUEST_CORE_HASH_INVALID"),
(lawyer_review_packet_core_sha256, "REVIEW_PACKET_CORE_HASH_INVALID"),
(validation_envelope_core_sha256, "REVIEW_VALIDATION_HASH_INVALID"),
(policy_sha256, "REVIEW_POLICY_HASH_INVALID"),
):
_require_sha256(value, code)
expected_release_keys = {"parent", "authority", "corpus", "case_type_coverage"}
if set(release_sha256s) != expected_release_keys:
raise InvariantError("REVIEW_RELEASE_SNAPSHOT_NOT_EXACT")
for value in release_sha256s.values():
_require_sha256(value, "REVIEW_RELEASE_HASH_INVALID")
if len(finding_ids) != len(set(finding_ids)) or len(scope_ids) != len(set(scope_ids)):
raise InvariantError("REVIEW_SUBJECT_SET_DUPLICATE")
subject_core = {
"schema_version": "stage2_s2_40_review_subject.v1",
"domain_separator": "STAGE2_S2_40_REVIEW_SUBJECT_V1",
"candidate_content_digest": candidate_digest,
"review_request_core_sha256": review_request_core_sha256,
"lawyer_review_packet_core_sha256": lawyer_review_packet_core_sha256,
"validation_envelope_core_sha256": validation_envelope_core_sha256,
"finding_ids": sorted(finding_ids), "scope_ids": sorted(scope_ids),
"policy_sha256": policy_sha256,
"release_sha256s": {key: release_sha256s[key] for key in sorted(release_sha256s)},
}
return hashlib.sha256(canonical_json_bytes(subject_core)).hexdigest()
def validate_status_only_paths(paths: Sequence[str]) -> None:
if tuple(paths) != STATUS_ONLY_PATHS:
raise InvariantError("STATUS_ONLY_INPUT_SET_NOT_EXACT_FIVE")
def validate_reference_closure(required_refs: Sequence[str], available_refs: Sequence[str]) -> None:
if len(required_refs) != len(set(required_refs)) or len(available_refs) != len(set(available_refs)):
raise InvariantError("REFERENCE_SET_DUPLICATE")
missing = sorted(set(required_refs) - set(available_refs))
if missing:
raise InvariantError("REFERENCE_DANGLING::" + ",".join(missing))
def validate_readback_rows(expected_rows: Sequence[Mapping[str, Any]], observed_rows: Sequence[Mapping[str, Any]]) -> None:
def normalize(rows: Sequence[Mapping[str, Any]]) -> list[tuple[str, str, str, int, str | None]]:
normalized: list[tuple[str, str, str, int, str | None]] = []
for row in rows:
if set(row) != {"path", "raw_sha256", "content_type", "size_bytes", "schema_ref"}:
raise InvariantError("READBACK_ROW_SHAPE_INVALID")
path = row["path"]
if not isinstance(path, str) or not path.startswith("final/") or ".." in path.split("/"):
raise InvariantError("READBACK_PATH_INVALID")
content_type, schema_ref, size = row["content_type"], row["schema_ref"], row["size_bytes"]
if not isinstance(content_type, str) or not content_type or not isinstance(size, int) or size < 1:
raise InvariantError("READBACK_METADATA_INVALID")
if schema_ref is not None and (not isinstance(schema_ref, str) or not schema_ref):
raise InvariantError("READBACK_SCHEMA_REF_INVALID")
normalized.append((path, _require_sha256(row["raw_sha256"], "READBACK_HASH_INVALID"), content_type, size, schema_ref))
if len({row[0] for row in normalized}) != len(normalized):
raise InvariantError("READBACK_PATH_DUPLICATE")
return sorted(normalized)
if normalize(expected_rows) != normalize(observed_rows):
raise InvariantError("READBACK_MISMATCH_NO_FINAL_BARRIER")
def run_invariants(checks: Mapping[str, Mapping[str, Any]]) -> list[dict[str, Any]]:
if set(checks) != set(INVARIANT_IDS):
raise InvariantError("INVARIANT_SET_NOT_EXACT_V01_V18")
results: list[dict[str, Any]] = []
for invariant_id in INVARIANT_IDS:
check = checks[invariant_id]
if not isinstance(check, Mapping):
raise InvariantError("INVARIANT_CHECK_NOT_OBJECT")
required_check_keys = {
"evaluable", "passed", "impact_scope", "source_refs", "finding_ids",
"expected", "observed", "reason_codes",
}
if set(check) != required_check_keys:
raise InvariantError(f"{invariant_id}_CHECK_SHAPE_NOT_EXACT")
evaluable = check["evaluable"]
if not isinstance(evaluable, bool):
raise InvariantError(f"{invariant_id}_EVALUABLE_NOT_BOOLEAN")
if evaluable:
if not isinstance(check["passed"], bool):
raise InvariantError(f"{invariant_id}_PASSED_NOT_BOOLEAN")
if check["observed"] is None or check["passed"] != (check["observed"] == check["expected"]):
raise InvariantError(f"{invariant_id}_OBSERVATION_ORACLE_MISMATCH")
evaluation = "PASS" if check["passed"] else "FAIL"
else:
if check["passed"] not in {False, None} or check["observed"] is not None:
raise InvariantError(f"{invariant_id}_UNEVALUABLE_OBSERVATION_INVALID")
evaluation = "UNEVALUABLE"
scope = check.get("impact_scope", "OK" if evaluation == "PASS" else "REVIEW_REQUIRED")
if scope not in IMPACT_SCOPES or (evaluation == "PASS" and scope != "OK"):
raise InvariantError("INVARIANT_IMPACT_SCOPE_INVALID")
reason_values = check["reason_codes"]
source_values = check["source_refs"]
finding_values = check["finding_ids"]
for values in (reason_values, source_values, finding_values):
if (not isinstance(values, list) or len(values) != len(set(values))
or not all(isinstance(value, str) and value for value in values)):
raise InvariantError("INVARIANT_STRING_SET_INVALID")
if not source_values:
raise InvariantError(f"{invariant_id}_SOURCE_EVIDENCE_REQUIRED")
reason_codes = sorted(set(reason_values))
if evaluation == "PASS" and (reason_codes or finding_values):
raise InvariantError(f"{invariant_id}_PASS_FINDING_FORBIDDEN")
if evaluation != "PASS" and (not reason_codes or not finding_values):
raise InvariantError(f"{invariant_id}_{evaluation}_FINDING_REQUIRED")
results.append({
"invariant_id": invariant_id, "evaluation_status": evaluation,
"finding_ids": sorted(set(finding_values)), "impact_scope": scope,
"source_refs": sorted(set(source_values)),
"expected": check["expected"], "observed": check["observed"],
"reason_codes": reason_codes, "validator_algorithm_id": f"S2_40::{invariant_id}::V1",
})
return results
def aggregate_status(results: Sequence[Mapping[str, Any]], *, compile_mode: str | None, legal_gates: Mapping[str, bool]) -> dict[str, str]:
if [row.get("invariant_id") for row in results] != list(INVARIANT_IDS):
raise InvariantError("INVARIANT_RESULT_ORDER_OR_SET_INVALID")
for row in results:
evaluation, scope = row.get("evaluation_status"), row.get("impact_scope")
if evaluation not in {"PASS", "FAIL", "UNEVALUABLE"} or scope not in IMPACT_SCOPES:
raise InvariantError("INVARIANT_RESULT_ENUM_INVALID")
if evaluation == "PASS" and scope != "OK":
raise InvariantError("INVARIANT_PASS_SCOPE_INVALID")
scopes = {row.get("impact_scope") for row in results}
if "INCOMPLETE" in scopes:
run = "TECHNICAL_INCOMPLETE"
elif "REVIEW_REQUIRED" in scopes or any(row.get("evaluation_status") == "UNEVALUABLE" for row in results):
run = "TECHNICAL_REVIEW_REQUIRED"
else:
run = "CONSISTENT"
if run == "TECHNICAL_INCOMPLETE":
artifact, legal = "NOT_PRODUCED", "NOT_ASSESSED"
elif run == "TECHNICAL_REVIEW_REQUIRED":
artifact, legal = "TECHNICAL_REVIEW_REQUIRED", "LAWYER_REVIEW_REQUIRED"
else:
artifact = "CONSISTENT"
gates = set(legal_gates) == REQUIRED_LEGAL_GATES and all(legal_gates.values())
all_pass = all(row.get("evaluation_status") == "PASS" for row in results)
legal = "READY_FOR_LAWYER_FILING_DECISION" if compile_mode == "PRODUCTION" and all_pass and gates else "LAWYER_REVIEW_REQUIRED"
return {"run_technical_status": run, "artifact_technical_status": artifact, "legal_readiness": legal}
def candidate_content_digest(material: Mapping[str, Any]) -> str:
forbidden = {"candidate_content_digest", "review_request", "review_receipt", "commit_intent", "commit_result", "run_status", "artifact_set_digest"}
if forbidden & set(material):
raise InvariantError("CANDIDATE_DIGEST_MATERIAL_CYCLE")
validate_candidate_material(material)
digest_core = {
"schema_version": "stage2_s2_40_candidate_content_digest.v1",
"domain_separator": "STAGE2_S2_40_CANDIDATE_CONTENT_V1",
**material,
}
return hashlib.sha256(canonical_json_bytes(digest_core)).hexdigest()
def artifact_set_digest(rows: Sequence[Mapping[str, Any]]) -> str:
ordered = sorted(rows, key=lambda row: row["path"])
paths = [row["path"] for row in ordered]
if len(paths) != len(set(paths)):
raise InvariantError("ARTIFACT_PATH_DUPLICATE")
for row in ordered:
if set(row) != {"path", "raw_sha256", "content_type", "size_bytes", "schema_ref"}:
raise InvariantError("ARTIFACT_ROW_SHAPE_INVALID")
_require_sha256(row["raw_sha256"], "ARTIFACT_ROW_HASH_INVALID")
if not isinstance(row["content_type"], str) or not row["content_type"]:
raise InvariantError("ARTIFACT_ROW_CONTENT_TYPE_INVALID")
if not isinstance(row["size_bytes"], int) or row["size_bytes"] < 1:
raise InvariantError("ARTIFACT_ROW_SIZE_INVALID")
if row["schema_ref"] is not None and (not isinstance(row["schema_ref"], str) or not row["schema_ref"]):
raise InvariantError("ARTIFACT_ROW_SCHEMA_REF_INVALID")
return hashlib.sha256(canonical_json_bytes(ordered)).hexdigest()
def derive_review_requirements(policy: Mapping[str, Any], active_tags: Sequence[str], runtime_triggers: Sequence[str]) -> list[str]:
if policy.get("status") != "APPROVED_LEGAL_CONTENT" or policy.get("execution_eligible") is not True:
return ["STANDARD_ATTORNEY_REVIEW"]
allowed_tags = set(policy["final_review_contract"]["allowed_review_tags"])
if not set(active_tags) <= allowed_tags:
raise InvariantError("REVIEW_TAG_UNKNOWN")
required = set(policy["final_review_contract"]["base_required_receipt_types"])
for row in policy.get("policy_rows", []):
if set(row.get("match_tags", [])) <= set(active_tags) and set(row.get("runtime_triggers", [])) <= set(runtime_triggers):
required.update(row.get("required_receipt_types", []))
return sorted(required)
def review_receipt_signed_material_digest(receipt: Mapping[str, Any]) -> str:
"""Hash the exact inline receipt preimage, including detached-adapter evidence."""
keys = (
"request_id", "candidate_content_digest", "review_subject_digest", "receipt_type",
"finding_ids", "scope_ids", "reviewer_role", "reviewer_qualification",
"issuer_id", "key_id", "signature_algorithm",
"external_verification_attestation_sha256", "issued_at", "expires_at",
"revocation_status", "cryptographic_verification_status",
"review_disposition", "change_scope", "reason_codes",
)
if any(key not in receipt for key in keys):
raise InvariantError("REVIEW_SIGNED_MATERIAL_FIELD_MISSING")
material = ["STAGE2_S2_40_REVIEW_RECEIPT_V1", *[receipt[key] for key in keys]]
return hashlib.sha256(canonical_json_bytes(material)).hexdigest()
def _parse_review_time(value: Any, code: str) -> datetime:
if not isinstance(value, str):
raise InvariantError(code)
try:
parsed = datetime.fromisoformat(value.replace("Z", "+00:00"))
except ValueError as exc:
raise InvariantError(code) from exc
if parsed.tzinfo is None:
raise InvariantError(code)
return parsed.astimezone(timezone.utc)
def validate_review_receipt(
receipt: Mapping[str, Any], *, candidate_digest: str,
expected_review_subject_digest: str, expected_request_id: str,
expected_receipt_type: str, expected_finding_ids: Sequence[str],
expected_scope_ids: Sequence[str], now: datetime,
) -> list[str]:
"""Return closed invalidity codes; an empty list means externally admissible."""
reasons: list[str] = []
if set(receipt) != REVIEW_RECEIPT_KEYS or receipt.get("schema_version") != "stage2_s2_40_review_receipt.v1":
return ["REVIEW_RECEIPT_CLOSED_SHAPE_INVALID"]
for key in ("receipt_id", "request_id", "receipt_type", "reviewer_role", "reviewer_qualification", "issuer_id", "key_id", "signature_algorithm"):
if not isinstance(receipt.get(key), str) or not receipt[key]:
reasons.append(f"REVIEW_RECEIPT_{key.upper()}_INVALID")
for key in ("candidate_content_digest", "review_subject_digest", "signed_material_digest", "external_verification_attestation_sha256"):
try:
_require_sha256(receipt.get(key), f"REVIEW_RECEIPT_{key.upper()}_INVALID")
except InvariantError as exc:
reasons.append(str(exc))
for key, expected in (
("candidate_content_digest", candidate_digest),
("review_subject_digest", expected_review_subject_digest),
("request_id", expected_request_id),
("receipt_type", expected_receipt_type),
("finding_ids", sorted(expected_finding_ids)),
("scope_ids", sorted(expected_scope_ids)),
):
observed = sorted(receipt[key]) if key in {"finding_ids", "scope_ids"} and isinstance(receipt[key], list) else receipt[key]
if observed != expected:
reasons.append(f"REVIEW_RECEIPT_{key.upper()}_MISMATCH")
for key in ("finding_ids", "scope_ids", "reason_codes"):
values = receipt.get(key)
if not isinstance(values, list) or values != sorted(set(values)) or not all(isinstance(value, str) and value for value in values):
reasons.append(f"REVIEW_RECEIPT_{key.upper()}_NOT_SORTED_SET")
if receipt.get("reviewer_role") != TRUSTED_REVIEW_ROLE:
reasons.append("REVIEW_RECEIPT_ROLE_UNTRUSTED")
if receipt.get("reviewer_qualification") != TRUSTED_REVIEW_QUALIFICATION:
reasons.append("REVIEW_RECEIPT_QUALIFICATION_UNTRUSTED")
if receipt.get("issuer_id") != TRUSTED_REVIEW_ISSUER:
reasons.append("REVIEW_RECEIPT_ISSUER_UNTRUSTED")
if receipt.get("key_id") not in TRUSTED_REVIEW_KEY_IDS:
reasons.append("REVIEW_RECEIPT_KEY_UNTRUSTED")
if receipt.get("signature_algorithm") != TRUSTED_REVIEW_SIGNATURE_ALGORITHM:
reasons.append("REVIEW_RECEIPT_SIGNATURE_ALGORITHM_UNTRUSTED")
if receipt.get("cryptographic_verification_status") != "VERIFIED_BY_EXTERNAL_ADAPTER":
reasons.append("REVIEW_RECEIPT_EXTERNAL_VERIFICATION_NOT_VERIFIED")
if receipt.get("revocation_status") != "NOT_REVOKED":
reasons.append("REVIEW_RECEIPT_REVOKED_OR_UNKNOWN")
try:
issued = _parse_review_time(receipt.get("issued_at"), "REVIEW_RECEIPT_ISSUED_AT_INVALID")
expires = _parse_review_time(receipt.get("expires_at"), "REVIEW_RECEIPT_EXPIRES_AT_INVALID")
current = now.astimezone(timezone.utc)
if issued > current or expires <= current or expires <= issued:
reasons.append("REVIEW_RECEIPT_TIME_WINDOW_INVALID")
except InvariantError as exc:
reasons.append(str(exc))
disposition, change_scope = receipt.get("review_disposition"), receipt.get("change_scope")
if disposition == "APPROVE_AS_IS" and change_scope != "NONE":
reasons.append("REVIEW_RECEIPT_APPROVAL_CHANGE_SCOPE_FORBIDDEN")
elif disposition == "CONTENT_CHANGE_REQUIRED" and change_scope not in {
"STAGE1_CONTEXT", "LEGAL_JUDGMENT", "PLAN_RULE_CALCULATION_BINDING", "DRAFTING_TEXT_ATOM",
}:
reasons.append("REVIEW_RECEIPT_CHANGE_SCOPE_INVALID")
elif disposition not in {"APPROVE_AS_IS", "CONTENT_CHANGE_REQUIRED"}:
reasons.append("REVIEW_RECEIPT_DISPOSITION_INVALID")
try:
expected_signed = review_receipt_signed_material_digest(receipt)
if receipt.get("signed_material_digest") != expected_signed:
reasons.append("REVIEW_RECEIPT_SIGNED_MATERIAL_MISMATCH")
except InvariantError as exc:
reasons.append(str(exc))
return sorted(set(reasons))
def transition_review_state(
*, candidate_digest: str, required_receipt_types: Sequence[str],
receipts: Sequence[Mapping[str, Any]], expected_review_subject_digest: str,
expected_request_ids: Mapping[str, str], expected_finding_ids: Sequence[str],
expected_scope_ids: Sequence[str], now: datetime,
) -> dict[str, Any]:
_require_sha256(candidate_digest, "REVIEW_CANDIDATE_DIGEST_INVALID")
if len(required_receipt_types) != len(set(required_receipt_types)):
raise InvariantError("REVIEW_REQUIRED_TYPE_DUPLICATE")
_require_sha256(expected_review_subject_digest, "REVIEW_SUBJECT_DIGEST_INVALID")
if set(expected_request_ids) != set(required_receipt_types) or any(
not isinstance(value, str) or not value for value in expected_request_ids.values()
):
raise InvariantError("REVIEW_REQUEST_ID_MAP_INVALID")
valid: dict[str, Mapping[str, Any]] = {}
invalid: list[str] = []
invalid_reasons: dict[str, list[str]] = {}
seen_receipt_ids: set[str] = set()
for receipt in receipts:
receipt_id = receipt.get("receipt_id")
receipt_type = receipt.get("receipt_type")
if not isinstance(receipt_id, str) or not receipt_id or receipt_id in seen_receipt_ids:
raise InvariantError("REVIEW_RECEIPT_ID_MISSING_OR_DUPLICATE")
seen_receipt_ids.add(receipt_id)
reasons = validate_review_receipt(
receipt, candidate_digest=candidate_digest,
expected_review_subject_digest=expected_review_subject_digest,
expected_request_id=expected_request_ids.get(str(receipt_type), ""),
expected_receipt_type=str(receipt_type),
expected_finding_ids=expected_finding_ids, expected_scope_ids=expected_scope_ids,
now=now,
)
if receipt_type not in required_receipt_types:
reasons.append("REVIEW_RECEIPT_TYPE_NOT_REQUIRED")
if reasons:
invalid.append(receipt_id)
invalid_reasons[receipt_id] = sorted(set(reasons))
else:
if receipt_type in valid:
raise InvariantError("REVIEW_RECEIPT_TYPE_DUPLICATE")
valid[receipt_type] = receipt
routes = {
"STAGE1_CONTEXT": (0, "RESTART_FROM_S2_00"),
"LEGAL_JUDGMENT": (1, "RESTART_FROM_S2_10"),
"PLAN_RULE_CALCULATION_BINDING": (2, "RESTART_FROM_S2_20"),
"DRAFTING_TEXT_ATOM": (3, "RESTART_FROM_S2_30"),
}
changed_scopes = [receipt["change_scope"] for receipt in valid.values() if receipt["review_disposition"] == "CONTENT_CHANGE_REQUIRED"]
if changed_scopes:
earliest = min(changed_scopes, key=lambda scope: routes[scope][0])
return {"workflow_phase": "SUPERSEDED", "route": routes[earliest][1], "invalid_receipt_ids": sorted(invalid), "invalid_receipt_reasons": invalid_reasons}
missing = sorted(set(required_receipt_types) - set(valid))
if missing or invalid:
return {"workflow_phase": "AWAITING_EXTERNAL_REVIEW", "route": "WAIT_EXTERNAL_REVIEW", "missing_receipt_types": missing, "invalid_receipt_ids": sorted(invalid), "invalid_receipt_reasons": invalid_reasons}
if any(receipt.get("review_disposition") != "APPROVE_AS_IS" for receipt in valid.values()):
raise InvariantError("REVIEW_DISPOSITION_INVALID")
return {"workflow_phase": "READY_TO_COMMIT", "route": "CONTINUE_TO_COMMIT", "invalid_receipt_ids": [], "invalid_receipt_reasons": {}}
def commit_write_order(final_paths: Sequence[str]) -> list[str]:
if len(final_paths) != len(set(final_paths)):
raise InvariantError("COMMIT_TARGET_DUPLICATE")
if any(not path.startswith("final/") or ".." in path.split("/") for path in final_paths):
raise InvariantError("COMMIT_TARGET_OUTSIDE_FINAL_ROOT")
return ["commit/commit_intent.json", *sorted(final_paths), "commit/stage2_commit_result.json", "control/run_status.json"]
__all__ = ["INVARIANT_IDS", "InvariantError", "JsonSchemaValidationError", "aggregate_status", "artifact_set_digest", "candidate_content_digest", "commit_write_order", "derive_review_requirements", "review_receipt_signed_material_digest", "review_subject_digest", "run_invariants", "transition_review_state", "validate_candidate_material", "validate_jsonschema_instance", "validate_readback_rows", "validate_reference_closure", "validate_review_receipt", "validate_status_only_paths"]
@@ -29,6 +29,14 @@
{"$ref": "#/$defs/s2_20_request"}, {"$ref": "#/$defs/s2_20_request"},
{"$ref": "#/$defs/s2_20_execution_receipt"}, {"$ref": "#/$defs/s2_20_execution_receipt"},
{"$ref": "#/$defs/s2_20_outer_execution_receipt"}, {"$ref": "#/$defs/s2_20_outer_execution_receipt"},
{"$ref": "#/$defs/s2_40_request"},
{"$ref": "#/$defs/s2_40_host_cas_receipt"},
{"$ref": "#/$defs/s2_40_code_executor_binding"},
{"$ref": "#/$defs/s2_40_inline_code_receipt"},
{"$ref": "#/$defs/s2_40_execution_receipt"},
{"$ref": "#/$defs/s2_40_outer_execution_receipt"},
{"$ref": "#/$defs/s2_40_commit_intent"},
{"$ref": "#/$defs/s2_40_commit_result"},
{"$ref": "#/$defs/stage2_deterministic_admission_receipt"}, {"$ref": "#/$defs/stage2_deterministic_admission_receipt"},
{"$ref": "#/$defs/code_executor_binding"}, {"$ref": "#/$defs/code_executor_binding"},
{"$ref": "#/$defs/inline_code_receipt"}, {"$ref": "#/$defs/inline_code_receipt"},
@@ -469,10 +477,25 @@
"host_cas_receipt_sha256": {"$ref": "#/$defs/sha256"} "host_cas_receipt_sha256": {"$ref": "#/$defs/sha256"}
} }
}, },
"s2_40_artifact_digest_row": {
"type": "object",
"additionalProperties": false,
"required": ["path", "raw_sha256", "content_type", "size_bytes", "schema_ref"],
"properties": {
"path": {
"type": "string",
"pattern": "^stage2_runs/by-binding/[a-f0-9]{64}/final/(?!.*(?:^|/)\\.\\.(?:/|$))[^\\u0000]+$"
},
"raw_sha256": {"$ref": "#/$defs/sha256"},
"content_type": {"$ref": "#/$defs/nonempty_string"},
"size_bytes": {"type": "integer", "minimum": 1},
"schema_ref": {"type": ["string", "null"]}
}
},
"stage2_deterministic_admission_receipt": { "stage2_deterministic_admission_receipt": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
"required": ["schema_version", "parent_release_sha256", "executor_binding_sha256", "present_deterministic_stage_ids", "stage_receipts", "embedded_task_admissions", "admission_status", "signature", "signature_verification_status", "signed_payload_sha256", "backend_capability_receipt_sha256"], "required": ["schema_version", "parent_release_sha256", "executor_binding_sha256", "present_deterministic_stage_ids", "stage_receipts", "embedded_task_admissions", "admission_status", "external_trust_verified", "signature", "signature_verification_status", "signed_payload_sha256", "backend_capability_receipt_sha256"],
"properties": { "properties": {
"schema_version": {"const": "stage2_deterministic_admission_receipt.v1"}, "schema_version": {"const": "stage2_deterministic_admission_receipt.v1"},
"parent_release_sha256": {"$ref": "#/$defs/sha256"}, "parent_release_sha256": {"$ref": "#/$defs/sha256"},
@@ -498,6 +521,7 @@
} }
}, },
"admission_status": {"enum": ["PENDING", "CANARY_ADMITTED", "PRODUCTION_ADMITTED"]}, "admission_status": {"enum": ["PENDING", "CANARY_ADMITTED", "PRODUCTION_ADMITTED"]},
"external_trust_verified": {"type": "boolean"},
"signature": {"type": "string", "minLength": 1}, "signature": {"type": "string", "minLength": 1},
"signature_verification_status": {"enum": ["PENDING_EXTERNAL_SIGNATURE", "BACKEND_VERIFIED"]}, "signature_verification_status": {"enum": ["PENDING_EXTERNAL_SIGNATURE", "BACKEND_VERIFIED"]},
"signed_payload_sha256": {"$ref": "#/$defs/bindable_sha256"}, "signed_payload_sha256": {"$ref": "#/$defs/bindable_sha256"},
@@ -508,6 +532,7 @@
"if": {"properties": {"admission_status": {"const": "PENDING"}}, "required": ["admission_status"]}, "if": {"properties": {"admission_status": {"const": "PENDING"}}, "required": ["admission_status"]},
"then": { "then": {
"properties": { "properties": {
"external_trust_verified": {"const": false},
"signature": {"const": "PENDING_EXTERNAL_SIGNATURE"}, "signature": {"const": "PENDING_EXTERNAL_SIGNATURE"},
"signature_verification_status": {"const": "PENDING_EXTERNAL_SIGNATURE"}, "signature_verification_status": {"const": "PENDING_EXTERNAL_SIGNATURE"},
"signed_payload_sha256": {"const": "PENDING_SEQUENTIAL_BIND"}, "signed_payload_sha256": {"const": "PENDING_SEQUENTIAL_BIND"},
@@ -519,6 +544,7 @@
"if": {"properties": {"admission_status": {"enum": ["CANARY_ADMITTED", "PRODUCTION_ADMITTED"]}}, "required": ["admission_status"]}, "if": {"properties": {"admission_status": {"enum": ["CANARY_ADMITTED", "PRODUCTION_ADMITTED"]}}, "required": ["admission_status"]},
"then": { "then": {
"properties": { "properties": {
"external_trust_verified": {"const": true},
"signature": {"type": "string", "minLength": 16, "not": {"pattern": "^PENDING"}}, "signature": {"type": "string", "minLength": 16, "not": {"pattern": "^PENDING"}},
"signature_verification_status": {"const": "BACKEND_VERIFIED"}, "signature_verification_status": {"const": "BACKEND_VERIFIED"},
"signed_payload_sha256": {"$ref": "#/$defs/sha256"}, "signed_payload_sha256": {"$ref": "#/$defs/sha256"},
@@ -1769,6 +1795,210 @@
} }
] ]
}, },
"s2_40_request": {
"type": "object",
"additionalProperties": false,
"required": [
"schema_version", "request_id", "candidate_attempt_id", "run_binding_digest",
"user_identity_hash", "workspace_identity_hash", "stage2_run_root_ref", "entry_route",
"compile_mode", "requested_transition", "expected_previous_run_status_sha256",
"expected_candidate_content_digest", "expected_ingress_status_sha256",
"expected_s2_10_publish_status_sha256", "expected_plan_publish_status_sha256",
"expected_s2_30_publish_status_sha256", "expected_s2_30_artifact_manifest_sha256",
"expected_parent_stage2_release_sha256", "expected_s2_40_agent_sha256",
"expected_s2_40_executor_binding_sha256", "expected_s2_40_inline_code_receipt_sha256",
"host_cas_receipt_ref", "host_cas_receipt_sha256", "detached_admission_receipt_ref",
"detached_admission_receipt_sha256", "outer_execution_receipt_target_ref",
"review_receipt_refs"
],
"properties": {
"schema_version": {"const": "stage2_s2_40_request.v1"},
"request_id": {"$ref": "#/$defs/nonempty_string"},
"candidate_attempt_id": {"$ref": "#/$defs/nonempty_string"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"user_identity_hash": {"$ref": "#/$defs/sha256"},
"workspace_identity_hash": {"$ref": "#/$defs/sha256"},
"stage2_run_root_ref": {"type": "string", "pattern": "^stage2_runs/by-binding/[a-f0-9]{64}$"},
"entry_route": {"enum": ["TO_S2_40", "TO_S2_40_STATUS_ONLY"]},
"compile_mode": {"type": ["string", "null"], "enum": [null, "STRUCTURAL_FIXTURE", "SUBSET_CANARY", "PRODUCTION"]},
"requested_transition": {"enum": ["FREEZE", "RESUME"]},
"expected_previous_run_status_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"expected_candidate_content_digest": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"expected_ingress_status_sha256": {"$ref": "#/$defs/sha256"},
"expected_s2_10_publish_status_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"expected_plan_publish_status_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"expected_s2_30_publish_status_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"expected_s2_30_artifact_manifest_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"expected_parent_stage2_release_sha256": {"$ref": "#/$defs/sha256"},
"expected_s2_40_agent_sha256": {"$ref": "#/$defs/sha256"},
"expected_s2_40_executor_binding_sha256": {"$ref": "#/$defs/sha256"},
"expected_s2_40_inline_code_receipt_sha256": {"$ref": "#/$defs/sha256"},
"host_cas_receipt_ref": {"type": "string", "pattern": "^stage2_control/host_cas/[a-f0-9]{64}/S2_40/[^/]+/(?:FREEZE|RESUME)\\.json$"},
"host_cas_receipt_sha256": {"$ref": "#/$defs/sha256"},
"detached_admission_receipt_ref": {"const": "Default_Agent/Stage_2_Clean/manifest/stage2_deterministic_admission_receipt.json"},
"detached_admission_receipt_sha256": {"$ref": "#/$defs/bindable_sha256"},
"outer_execution_receipt_target_ref": {"type": "string", "pattern": "^stage2_runs/by-binding/[a-f0-9]{64}/control/s2_40_outer_execution_receipt\\.json$"},
"review_receipt_refs": {
"type": "array",
"items": {"type": "string", "pattern": "^stage2_runs/by-binding/[a-f0-9]{64}/review/review_receipts/[^/]+\\.json$"},
"maxItems": 64,
"uniqueItems": true
}
},
"allOf": [
{
"if": {"properties": {"entry_route": {"const": "TO_S2_40_STATUS_ONLY"}}, "required": ["entry_route"]},
"then": {"properties": {"compile_mode": {"const": null}, "requested_transition": {"const": "FREEZE"}, "expected_previous_run_status_sha256": {"const": null}, "expected_candidate_content_digest": {"const": null}, "expected_s2_10_publish_status_sha256": {"const": null}, "expected_plan_publish_status_sha256": {"const": null}, "expected_s2_30_publish_status_sha256": {"const": null}, "expected_s2_30_artifact_manifest_sha256": {"const": null}, "review_receipt_refs": {"maxItems": 0}}}
},
{
"if": {"properties": {"entry_route": {"const": "TO_S2_40"}, "requested_transition": {"const": "FREEZE"}}, "required": ["entry_route", "requested_transition"]},
"then": {"properties": {"compile_mode": {"enum": ["STRUCTURAL_FIXTURE", "SUBSET_CANARY", "PRODUCTION"]}, "expected_candidate_content_digest": {"const": null}, "expected_previous_run_status_sha256": {"const": null}, "expected_s2_10_publish_status_sha256": {"$ref": "#/$defs/sha256"}, "expected_plan_publish_status_sha256": {"$ref": "#/$defs/sha256"}, "expected_s2_30_publish_status_sha256": {"$ref": "#/$defs/sha256"}, "expected_s2_30_artifact_manifest_sha256": {"$ref": "#/$defs/sha256"}, "review_receipt_refs": {"maxItems": 0}}}
},
{
"if": {"properties": {"requested_transition": {"const": "RESUME"}}, "required": ["requested_transition"]},
"then": {"properties": {"entry_route": {"const": "TO_S2_40"}, "compile_mode": {"enum": ["STRUCTURAL_FIXTURE", "SUBSET_CANARY", "PRODUCTION"]}, "expected_candidate_content_digest": {"$ref": "#/$defs/sha256"}, "expected_previous_run_status_sha256": {"$ref": "#/$defs/sha256"}, "expected_s2_10_publish_status_sha256": {"$ref": "#/$defs/sha256"}, "expected_plan_publish_status_sha256": {"$ref": "#/$defs/sha256"}, "expected_s2_30_publish_status_sha256": {"$ref": "#/$defs/sha256"}, "expected_s2_30_artifact_manifest_sha256": {"$ref": "#/$defs/sha256"}, "review_receipt_refs": {"minItems": 1}}}
}
]
},
"s2_40_host_cas_receipt": {
"type": "object", "additionalProperties": false,
"required": ["schema_version", "run_binding_digest", "stage_id", "candidate_attempt_id", "requested_transition", "expected_previous_run_status_sha256", "lease_id", "lease_status", "issued_at", "expires_at", "signature_attestation"],
"properties": {
"schema_version": {"const": "stage2_s2_40_host_cas_receipt.v1"},
"run_binding_digest": {"$ref": "#/$defs/sha256"}, "stage_id": {"const": "S2_40"},
"candidate_attempt_id": {"$ref": "#/$defs/nonempty_string"}, "requested_transition": {"enum": ["FREEZE", "RESUME"]},
"expected_previous_run_status_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"lease_id": {"$ref": "#/$defs/nonempty_string"}, "lease_status": {"const": "ACQUIRED"},
"issued_at": {"type": "string", "format": "date-time"}, "expires_at": {"type": "string", "format": "date-time"},
"signature_attestation": {"$ref": "#/$defs/sha256"}
}
},
"s2_40_code_executor_binding": {
"type": "object", "additionalProperties": false,
"required": ["schema_version", "stage_id", "execution_unit", "agent_path", "agent_sha256", "inline_code_sha256", "workflow_path", "workflow_sha256", "request_path", "timeout_seconds", "requirements", "network", "egress_profile_id", "fallback_allowed", "binding_digest"],
"properties": {
"schema_version": {"const": "stage2_s2_40_code_executor_binding.v1"}, "stage_id": {"const": "S2_40"},
"execution_unit": {"const": "Task_S2_40_deterministic_finalizer"}, "agent_path": {"const": "agent_scripts/Stage_2_S2_40.yml"},
"agent_sha256": {"$ref": "#/$defs/bindable_sha256"}, "inline_code_sha256": {"$ref": "#/$defs/bindable_sha256"},
"workflow_path": {"const": "workflows/S2_40_final_review_render_and_commit.yml"}, "workflow_sha256": {"$ref": "#/$defs/bindable_sha256"},
"request_path": {"const": "stage2_control/s2_40_request.json"}, "timeout_seconds": {"const": 300},
"requirements": {"const": "httpx==0.28.1"}, "network": {"const": "agent-network"},
"egress_profile_id": {"const": "LOCALDOCS_EXACT_BINARY_ONLY_V1"}, "fallback_allowed": {"const": false},
"binding_digest": {"$ref": "#/$defs/bindable_sha256"}
}
},
"s2_40_inline_code_receipt": {
"type": "object", "additionalProperties": false,
"required": ["schema_version", "workflow_id", "build_kind", "source_of_truth", "authoring_rewritten", "authoring", "deployment_projection", "canonical_code", "expected_parent_stage2_release_sha256", "full_code_mirrors", "task_contract", "parity_status"],
"properties": {
"schema_version": {"const": "stage2_s2_40_inline_code_receipt.v1"},
"workflow_id": {"const": "S2_40"},
"build_kind": {"const": "OFFLINE_AUTHORING_PROJECTION"},
"source_of_truth": {"const": "Stage_2_S2_40.yml"},
"authoring_rewritten": {"const": false},
"authoring": {
"type": "object", "additionalProperties": false,
"required": ["path", "sha256", "size_bytes", "unique_key_parse"],
"properties": {"path": {"const": "Stage_2_S2_40.yml"}, "sha256": {"$ref": "#/$defs/sha256"}, "size_bytes": {"type": "integer", "minimum": 1}, "unique_key_parse": {"const": "PASS"}}
},
"deployment_projection": {
"type": "object", "additionalProperties": false,
"required": ["path", "sha256", "size_bytes", "byte_identical_to_authoring", "canonical_task_semantics_sha256"],
"properties": {"path": {"const": "Default_Agent/Stage_2_Clean/agent_scripts/Stage_2_S2_40.yml"}, "sha256": {"$ref": "#/$defs/sha256"}, "size_bytes": {"type": "integer", "minimum": 1}, "byte_identical_to_authoring": {"const": true}, "canonical_task_semantics_sha256": {"$ref": "#/$defs/sha256"}}
},
"canonical_code": {
"type": "object", "additionalProperties": false,
"required": ["ast_status", "code_sha256", "code_size_bytes", "compile_status", "encoding", "expected_parent_stage2_release_sha256", "external_python_source_ref_count", "external_url_count", "extraction_transform", "forbidden_dynamic_call_count", "forbidden_import_count", "imports", "placeholder_count", "plaintext_secret_count", "yaml_pointer"],
"properties": {
"ast_status": {"const": "PASS"}, "code_sha256": {"$ref": "#/$defs/sha256"}, "code_size_bytes": {"type": "integer", "minimum": 1}, "compile_status": {"const": "PASS"}, "encoding": {"const": "UTF-8"},
"expected_parent_stage2_release_sha256": {"$ref": "#/$defs/sha256"}, "external_python_source_ref_count": {"const": 0}, "external_url_count": {"const": 0}, "extraction_transform": {"const": "NONE"}, "forbidden_dynamic_call_count": {"const": 0}, "forbidden_import_count": {"const": 0},
"imports": {"type": "array", "items": {"$ref": "#/$defs/nonempty_string"}, "uniqueItems": true}, "placeholder_count": {"const": 0}, "plaintext_secret_count": {"const": 0}, "yaml_pointer": {"const": "/Agent/Stages/0/tasks/0/parameters/code"}
}
},
"expected_parent_stage2_release_sha256": {"$ref": "#/$defs/sha256"},
"full_code_mirrors": {
"type": "array", "minItems": 2, "maxItems": 2,
"prefixItems": [
{"type": "object", "additionalProperties": false, "required": ["path", "sha256", "size_bytes", "byte_identical_to_canonical_code"], "properties": {"path": {"const": "Default_Agent/Stage_2_Clean/runtime/s2_40_commit.py"}, "sha256": {"$ref": "#/$defs/sha256"}, "size_bytes": {"type": "integer", "minimum": 1}, "byte_identical_to_canonical_code": {"const": true}}},
{"type": "object", "additionalProperties": false, "required": ["path", "sha256", "size_bytes", "byte_identical_to_canonical_code"], "properties": {"path": {"const": "Default_Agent/Stage_2_Clean/runtime/s2_40_commit.txt"}, "sha256": {"$ref": "#/$defs/sha256"}, "size_bytes": {"type": "integer", "minimum": 1}, "byte_identical_to_canonical_code": {"const": true}}}
], "items": false
},
"task_contract": {
"type": "object", "additionalProperties": false,
"required": ["agent", "authoring_rewritten", "canonical_task_semantics_sha256", "code_mirrors_byte_identical", "exactly_one_code_executor_run_code", "exactly_one_stage", "exactly_one_task", "mcp_servers", "projection_byte_identical_to_authoring", "stage", "task", "task_procedure"],
"properties": {
"agent": {"type": "object"}, "authoring_rewritten": {"const": false}, "canonical_task_semantics_sha256": {"$ref": "#/$defs/sha256"}, "code_mirrors_byte_identical": {"const": true}, "exactly_one_code_executor_run_code": {"const": true}, "exactly_one_stage": {"const": true}, "exactly_one_task": {"const": true}, "mcp_servers": {"type": "object"}, "projection_byte_identical_to_authoring": {"const": true}, "stage": {"type": "object"}, "task": {"type": "object"}, "task_procedure": {"type": "object"}
}
},
"parity_status": {"const": "PASS"}
}
},
"s2_40_execution_receipt": {
"type": "object", "additionalProperties": false,
"required": ["schema_version", "ok", "workflow_id", "request_id", "run_binding_digest", "candidate_attempt_id", "requested_transition", "workflow_phase", "route", "candidate_content_digest", "run_status_path", "run_status_sha256", "error"],
"properties": {
"schema_version": {"const": "stage2_s2_40_execution_receipt.v1"}, "ok": {"type": "boolean"}, "workflow_id": {"const": "S2_40"}, "request_id": {"$ref": "#/$defs/nonempty_string"},
"run_binding_digest": {"$ref": "#/$defs/sha256"}, "candidate_attempt_id": {"$ref": "#/$defs/nonempty_string"}, "requested_transition": {"enum": ["FREEZE", "RESUME"]},
"workflow_phase": {"enum": ["CANDIDATE_FROZEN", "AWAITING_EXTERNAL_REVIEW", "READY_TO_COMMIT", "COMMITTED", "SUPERSEDED", "DIAGNOSTIC_ONLY"]},
"route": {"enum": ["STOP_TECHNICAL_INCOMPLETE", "CHECKPOINT_FROZEN", "WAIT_EXTERNAL_REVIEW", "CONTINUE_TO_COMMIT", "RESTART_FROM_S2_00", "RESTART_FROM_S2_10", "RESTART_FROM_S2_20", "RESTART_FROM_S2_30", "PACKAGE_COMMITTED"]},
"candidate_content_digest": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"run_status_path": {"oneOf": [{"type": "string", "pattern": "^stage2_runs/by-binding/[a-f0-9]{64}/control/run_status\\.json$"}, {"type": "null"}]},
"run_status_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]}, "error": {"type": ["object", "null"]}
},
"allOf": [
{
"if": {"properties": {"ok": {"const": true}}, "required": ["ok"]},
"then": {"properties": {"run_status_path": {"type": "string", "pattern": "^stage2_runs/by-binding/[a-f0-9]{64}/control/run_status\\.json$"}, "run_status_sha256": {"$ref": "#/$defs/sha256"}, "error": {"type": "null"}}},
"else": {"properties": {"error": {"type": "object"}}}
},
{
"oneOf": [
{"properties": {"run_status_path": {"type": "null"}, "run_status_sha256": {"type": "null"}}},
{"properties": {"run_status_path": {"type": "string", "pattern": "^stage2_runs/by-binding/[a-f0-9]{64}/control/run_status\\.json$"}, "run_status_sha256": {"$ref": "#/$defs/sha256"}}}
]
}
]
},
"s2_40_outer_execution_receipt": {
"type": "object", "additionalProperties": false,
"required": ["schema_version", "workflow_id", "request_id", "run_binding_digest", "candidate_attempt_id", "requested_transition", "agent_sha256", "inline_code_sha256", "binding_sha256", "host_cas_receipt_sha256", "detached_admission_receipt_sha256", "workspace_isolation_status", "outer_result_status", "inner_result_sha256", "issued_at", "signature_attestation"],
"properties": {
"schema_version": {"const": "stage2_s2_40_outer_execution_receipt.v1"}, "workflow_id": {"const": "S2_40"}, "request_id": {"$ref": "#/$defs/nonempty_string"}, "run_binding_digest": {"$ref": "#/$defs/sha256"},
"candidate_attempt_id": {"$ref": "#/$defs/nonempty_string"}, "requested_transition": {"enum": ["FREEZE", "RESUME"]},
"agent_sha256": {"$ref": "#/$defs/sha256"}, "inline_code_sha256": {"$ref": "#/$defs/sha256"},
"binding_sha256": {"$ref": "#/$defs/sha256"}, "host_cas_receipt_sha256": {"$ref": "#/$defs/sha256"}, "detached_admission_receipt_sha256": {"$ref": "#/$defs/sha256"},
"workspace_isolation_status": {"enum": ["VERIFIED", "FAILED"]}, "outer_result_status": {"enum": ["SUCCESS", "FAILED"]},
"inner_result_sha256": {"$ref": "#/$defs/sha256"}, "issued_at": {"type": "string", "format": "date-time"},
"signature_attestation": {"$ref": "#/$defs/sha256"}
}
},
"s2_40_commit_intent": {
"type": "object", "additionalProperties": false,
"required": ["schema_version", "producer_id", "run_binding_digest", "candidate_content_digest", "candidate_attempt_id", "candidate_manifest_core_sha256", "validation_report_sha256", "review_subject_digest", "review_receipt_sha256s", "stage2_package_sha256", "expected_artifacts", "previous_run_status_sha256", "request_sha256", "host_cas_receipt_sha256", "intent_digest"],
"properties": {
"schema_version": {"const": "stage2_s2_40_commit_intent.v1"}, "producer_id": {"const": "S2_40"},
"run_binding_digest": {"$ref": "#/$defs/sha256"}, "candidate_content_digest": {"$ref": "#/$defs/sha256"},
"candidate_attempt_id": {"$ref": "#/$defs/nonempty_string"},
"candidate_manifest_core_sha256": {"$ref": "#/$defs/sha256"}, "validation_report_sha256": {"$ref": "#/$defs/sha256"}, "review_subject_digest": {"$ref": "#/$defs/sha256"},
"review_receipt_sha256s": {"type": "array", "items": {"$ref": "#/$defs/sha256"}, "uniqueItems": true}, "stage2_package_sha256": {"$ref": "#/$defs/sha256"},
"expected_artifacts": {"type": "array", "items": {"$ref": "#/$defs/s2_40_artifact_digest_row"}, "minItems": 8},
"previous_run_status_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"request_sha256": {"$ref": "#/$defs/sha256"}, "host_cas_receipt_sha256": {"$ref": "#/$defs/sha256"},
"intent_digest": {"$ref": "#/$defs/sha256"}
}
},
"s2_40_commit_result": {
"type": "object", "additionalProperties": false,
"required": ["schema_version", "producer_id", "run_binding_digest", "candidate_content_digest", "commit_intent_sha256", "artifact_rows", "artifact_set_digest", "readback_status", "conflicting_target_count", "missing_target_count_after_write", "commit_result_digest"],
"properties": {
"schema_version": {"const": "stage2_s2_40_commit_result.v1"}, "producer_id": {"const": "S2_40"},
"run_binding_digest": {"$ref": "#/$defs/sha256"}, "candidate_content_digest": {"$ref": "#/$defs/sha256"},
"commit_intent_sha256": {"$ref": "#/$defs/sha256"},
"artifact_rows": {"type": "array", "items": {"$ref": "#/$defs/s2_40_artifact_digest_row"}, "minItems": 8},
"artifact_set_digest": {"$ref": "#/$defs/sha256"}, "readback_status": {"const": "PASS"}, "conflicting_target_count": {"const": 0}, "missing_target_count_after_write": {"const": 0},
"commit_result_digest": {"$ref": "#/$defs/sha256"}
}
},
"loader_receipt": { "loader_receipt": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
@@ -10,6 +10,11 @@
{"$ref": "#/$defs/materialized_group_item"}, {"$ref": "#/$defs/materialized_group_item"},
{"$ref": "#/$defs/raw_joint_draft_output"}, {"$ref": "#/$defs/raw_joint_draft_output"},
{"$ref": "#/$defs/canonical_draft_atom"}, {"$ref": "#/$defs/canonical_draft_atom"},
{"$ref": "#/$defs/draft_part"},
{"$ref": "#/$defs/issue_patch_part"},
{"$ref": "#/$defs/worknote_part"},
{"$ref": "#/$defs/usage_part"},
{"$ref": "#/$defs/part_manifest_core"},
{"$ref": "#/$defs/item_receipt"}, {"$ref": "#/$defs/item_receipt"},
{"$ref": "#/$defs/canary_authorization"}, {"$ref": "#/$defs/canary_authorization"},
{"$ref": "#/$defs/cache_owner_completion_receipt"}, {"$ref": "#/$defs/cache_owner_completion_receipt"},
@@ -1398,6 +1403,285 @@
"canonical_atom_sha256": {"$ref": "#/$defs/sha256"} "canonical_atom_sha256": {"$ref": "#/$defs/sha256"}
} }
}, },
"execution_provenance": {
"type": "object",
"additionalProperties": false,
"required": [
"compile_mode",
"parent_stage2_release_sha256",
"s2_30_release_sha256",
"s2_30_agent_sha256",
"s2_30_binding_sha256",
"p00_prompt_sha256",
"p30_prompt_sha256",
"p31_rule_and_pack_sha256",
"p32_common_authority_sha256",
"s30_group_slice_sha256",
"s2_30_producer_contract_digest"
],
"properties": {
"compile_mode": {"$ref": "#/$defs/compile_mode"},
"parent_stage2_release_sha256": {"$ref": "#/$defs/sha256"},
"s2_30_release_sha256": {"$ref": "#/$defs/sha256"},
"s2_30_agent_sha256": {"$ref": "#/$defs/sha256"},
"s2_30_binding_sha256": {"$ref": "#/$defs/sha256"},
"p00_prompt_sha256": {"$ref": "#/$defs/sha256"},
"p30_prompt_sha256": {"$ref": "#/$defs/sha256"},
"p31_rule_and_pack_sha256": {"$ref": "#/$defs/sha256"},
"p32_common_authority_sha256": {"$ref": "#/$defs/sha256"},
"s30_group_slice_sha256": {"$ref": "#/$defs/sha256"},
"s2_30_producer_contract_digest": {"$ref": "#/$defs/sha256"}
}
},
"common_publish_provenance": {
"type": "object",
"additionalProperties": false,
"required": [
"compile_mode",
"parent_stage2_release_sha256",
"s2_30_release_sha256",
"s2_30_agent_sha256",
"s2_30_binding_sha256",
"p00_prompt_sha256",
"p30_prompt_sha256",
"s2_30_producer_contract_digest"
],
"properties": {
"compile_mode": {"$ref": "#/$defs/compile_mode"},
"parent_stage2_release_sha256": {"$ref": "#/$defs/sha256"},
"s2_30_release_sha256": {"$ref": "#/$defs/sha256"},
"s2_30_agent_sha256": {"$ref": "#/$defs/sha256"},
"s2_30_binding_sha256": {"$ref": "#/$defs/sha256"},
"p00_prompt_sha256": {"$ref": "#/$defs/sha256"},
"p30_prompt_sha256": {"$ref": "#/$defs/sha256"},
"s2_30_producer_contract_digest": {"$ref": "#/$defs/sha256"}
}
},
"draft_part": {
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"claim_group_id",
"provenance",
"source_plan_sha256",
"drafting_permission",
"canonical_atoms",
"atomic_claim_coverage",
"part_sha256"
],
"properties": {
"schema_version": {"const": "stage2_s2_30_draft_part.v1"},
"claim_group_id": {"$ref": "#/$defs/claim_group_id"},
"provenance": {"$ref": "#/$defs/execution_provenance"},
"source_plan_sha256": {"$ref": "#/$defs/sha256"},
"drafting_permission": {"$ref": "#/$defs/drafting_permission"},
"canonical_atoms": {
"type": "array",
"items": {"$ref": "#/$defs/canonical_draft_atom"},
"minItems": 1
},
"atomic_claim_coverage": {
"type": "array",
"items": {"$ref": "#/$defs/persisted_atomic_claim_coverage"},
"minItems": 1
},
"part_sha256": {"$ref": "#/$defs/sha256"}
}
},
"persisted_atomic_claim_coverage": {
"type": "object",
"additionalProperties": false,
"required": [
"atomic_claim_id",
"relief_atom_local_refs",
"cause_atom_local_refs",
"alignment_signature",
"coverage_status",
"missing_reason_codes"
],
"properties": {
"atomic_claim_id": {"$ref": "#/$defs/atomic_claim_id"},
"relief_atom_local_refs": {
"type": "array",
"items": {"$ref": "#/$defs/atom_id"},
"uniqueItems": true
},
"cause_atom_local_refs": {
"type": "array",
"items": {"$ref": "#/$defs/atom_id"},
"uniqueItems": true
},
"alignment_signature": {"$ref": "#/$defs/sha256"},
"coverage_status": {"enum": ["COMPLETE", "INCOMPLETE"]},
"missing_reason_codes": {"$ref": "#/$defs/string_set"}
}
},
"issue_patch_part": {
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"claim_group_id",
"provenance",
"source_plan_sha256",
"review_flags",
"missing_inputs",
"adverse_fact_rows",
"part_sha256"
],
"properties": {
"schema_version": {"const": "stage2_s2_30_issue_patch_part.v1"},
"claim_group_id": {"$ref": "#/$defs/claim_group_id"},
"provenance": {"$ref": "#/$defs/execution_provenance"},
"source_plan_sha256": {"$ref": "#/$defs/sha256"},
"review_flags": {"$ref": "#/$defs/string_set"},
"missing_inputs": {"$ref": "#/$defs/string_set"},
"adverse_fact_rows": {
"type": "array",
"items": {"$ref": "#/$defs/adverse_fact_row"}
},
"part_sha256": {"$ref": "#/$defs/sha256"}
}
},
"worknote_part": {
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"claim_group_id",
"provenance",
"source_plan_sha256",
"worknote_atom_ids",
"review_flags",
"missing_inputs",
"part_sha256"
],
"properties": {
"schema_version": {"const": "stage2_s2_30_worknote_part.v1"},
"claim_group_id": {"$ref": "#/$defs/claim_group_id"},
"provenance": {"$ref": "#/$defs/execution_provenance"},
"source_plan_sha256": {"$ref": "#/$defs/sha256"},
"worknote_atom_ids": {
"type": "array",
"items": {"$ref": "#/$defs/atom_id"},
"uniqueItems": true
},
"review_flags": {"$ref": "#/$defs/string_set"},
"missing_inputs": {"$ref": "#/$defs/string_set"},
"part_sha256": {"$ref": "#/$defs/sha256"}
}
},
"usage_part": {
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"claim_group_id",
"provenance",
"request_id",
"model",
"reasoning_effort",
"verbosity",
"endpoint",
"input_tokens",
"cached_input_tokens",
"output_tokens",
"usage_observed",
"part_sha256"
],
"properties": {
"schema_version": {"const": "stage2_s2_30_usage_part.v1"},
"claim_group_id": {"$ref": "#/$defs/claim_group_id"},
"provenance": {"$ref": "#/$defs/execution_provenance"},
"request_id": {"$ref": "#/$defs/nonempty_string"},
"model": {"const": "gpt-5.6-sol"},
"reasoning_effort": {"const": "xhigh"},
"verbosity": {"const": "medium"},
"endpoint": {"const": "responses"},
"input_tokens": {"type": "integer", "minimum": 0},
"cached_input_tokens": {"type": "integer", "minimum": 0},
"output_tokens": {"type": "integer", "minimum": 0},
"usage_observed": {"type": "boolean"},
"part_sha256": {"$ref": "#/$defs/sha256"}
}
},
"part_manifest_row": {
"type": "object",
"additionalProperties": false,
"required": [
"claim_group_id",
"part_family",
"path",
"sha256",
"schema_ref"
],
"properties": {
"claim_group_id": {"$ref": "#/$defs/claim_group_id"},
"part_family": {"enum": ["DRAFT_PART", "ISSUE_PATCH", "WORKNOTE_PART", "USAGE_PART"]},
"path": {"$ref": "#/$defs/artifact_path"},
"sha256": {"$ref": "#/$defs/sha256"},
"schema_ref": {
"enum": [
"schemas/draft_atoms.schema.json#/$defs/draft_part",
"schemas/draft_atoms.schema.json#/$defs/issue_patch_part",
"schemas/draft_atoms.schema.json#/$defs/worknote_part",
"schemas/draft_atoms.schema.json#/$defs/usage_part"
]
}
}
},
"part_manifest_core": {
"type": "object",
"additionalProperties": false,
"required": [
"schema_version",
"request_id",
"run_binding_digest",
"provenance",
"expected_claim_group_ids",
"part_rows",
"part_manifest_core_sha256"
],
"properties": {
"schema_version": {"const": "stage2_s2_30_part_manifest_core.v1"},
"request_id": {"$ref": "#/$defs/nonempty_string"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"provenance": {"$ref": "#/$defs/common_publish_provenance"},
"expected_claim_group_ids": {
"type": "array",
"items": {"$ref": "#/$defs/claim_group_id"},
"minItems": 1,
"uniqueItems": true
},
"part_rows": {
"type": "array",
"items": {"$ref": "#/$defs/part_manifest_row"},
"minItems": 4
},
"part_manifest_core_sha256": {"$ref": "#/$defs/sha256"}
},
"$comment": "Receipt-free by construction: item/cohort receipt paths or hashes must not appear in this core."
},
"receipt_ref": {
"type": "object",
"additionalProperties": false,
"required": ["path", "sha256"],
"properties": {
"path": {"$ref": "#/$defs/artifact_path"},
"sha256": {"$ref": "#/$defs/sha256"}
}
},
"item_receipt_ref": {
"type": "object",
"additionalProperties": false,
"required": ["claim_group_id", "path", "sha256"],
"properties": {
"claim_group_id": {"$ref": "#/$defs/claim_group_id"},
"path": {"$ref": "#/$defs/artifact_path"},
"sha256": {"$ref": "#/$defs/sha256"}
}
},
"item_receipt": { "item_receipt": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
@@ -1408,11 +1692,12 @@
"cohort_id", "cohort_id",
"attempt_no", "attempt_no",
"claim_group_id", "claim_group_id",
"provenance",
"dispatch_sha256", "dispatch_sha256",
"raw_model_output_sha256", "raw_model_output_sha256",
"source_plan_sha256", "source_plan_sha256",
"canonical_atom_ids", "canonical_atom_ids",
"artifact_manifest_sha256", "part_manifest_core_sha256",
"validation_status", "validation_status",
"persistence_status", "persistence_status",
"read_back_verified", "read_back_verified",
@@ -1425,6 +1710,7 @@
"cohort_id": {"$ref": "#/$defs/nonempty_string"}, "cohort_id": {"$ref": "#/$defs/nonempty_string"},
"attempt_no": {"type": "integer", "minimum": 1, "maximum": 2}, "attempt_no": {"type": "integer", "minimum": 1, "maximum": 2},
"claim_group_id": {"$ref": "#/$defs/claim_group_id"}, "claim_group_id": {"$ref": "#/$defs/claim_group_id"},
"provenance": {"$ref": "#/$defs/execution_provenance"},
"dispatch_sha256": {"$ref": "#/$defs/sha256"}, "dispatch_sha256": {"$ref": "#/$defs/sha256"},
"raw_model_output_sha256": {"$ref": "#/$defs/sha256"}, "raw_model_output_sha256": {"$ref": "#/$defs/sha256"},
"source_plan_sha256": {"$ref": "#/$defs/sha256"}, "source_plan_sha256": {"$ref": "#/$defs/sha256"},
@@ -1433,7 +1719,7 @@
"items": {"$ref": "#/$defs/atom_id"}, "items": {"$ref": "#/$defs/atom_id"},
"uniqueItems": true "uniqueItems": true
}, },
"artifact_manifest_sha256": {"$ref": "#/$defs/sha256"}, "part_manifest_core_sha256": {"$ref": "#/$defs/sha256"},
"validation_status": {"enum": ["PASS", "FAIL"]}, "validation_status": {"enum": ["PASS", "FAIL"]},
"persistence_status": {"enum": ["PUBLISHED", "IDEMPOTENT_BYTE_IDENTICAL", "NOT_WRITTEN", "CONFLICT"]}, "persistence_status": {"enum": ["PUBLISHED", "IDEMPOTENT_BYTE_IDENTICAL", "NOT_WRITTEN", "CONFLICT"]},
"read_back_verified": {"type": "boolean"}, "read_back_verified": {"type": "boolean"},
@@ -1450,6 +1736,8 @@
"cohort_id", "cohort_id",
"dispatch_phase", "dispatch_phase",
"attempt_no", "attempt_no",
"provenance",
"part_manifest_core_sha256",
"input_claim_group_ids", "input_claim_group_ids",
"valid_claim_group_ids", "valid_claim_group_ids",
"repair_required_claim_group_ids", "repair_required_claim_group_ids",
@@ -1466,6 +1754,8 @@
"cohort_id": {"$ref": "#/$defs/nonempty_string"}, "cohort_id": {"$ref": "#/$defs/nonempty_string"},
"dispatch_phase": {"enum": ["CACHE_OWNER_SINGLETON", "FOLLOWER_BATCH"]}, "dispatch_phase": {"enum": ["CACHE_OWNER_SINGLETON", "FOLLOWER_BATCH"]},
"attempt_no": {"type": "integer", "minimum": 1, "maximum": 2}, "attempt_no": {"type": "integer", "minimum": 1, "maximum": 2},
"provenance": {"$ref": "#/$defs/common_publish_provenance"},
"part_manifest_core_sha256": {"$ref": "#/$defs/sha256"},
"input_claim_group_ids": { "input_claim_group_ids": {
"type": "array", "type": "array",
"items": {"$ref": "#/$defs/claim_group_id"}, "items": {"$ref": "#/$defs/claim_group_id"},
@@ -1553,11 +1843,16 @@
"run_binding_digest", "run_binding_digest",
"parent_stage2_release_sha256", "parent_stage2_release_sha256",
"s2_30_release_sha256", "s2_30_release_sha256",
"compile_mode",
"provenance",
"expected_claim_group_ids", "expected_claim_group_ids",
"published_claim_group_ids", "published_claim_group_ids",
"terminal_failure_claim_group_ids", "terminal_failure_claim_group_ids",
"terminal_cohort_receipt_sha256s", "artifact_manifest_path",
"artifact_manifest_schema_ref",
"artifact_manifest_sha256", "artifact_manifest_sha256",
"ordered_item_receipts",
"ordered_cohort_receipts",
"status", "status",
"route", "route",
"status_written_last", "status_written_last",
@@ -1569,6 +1864,8 @@
"run_binding_digest": {"$ref": "#/$defs/sha256"}, "run_binding_digest": {"$ref": "#/$defs/sha256"},
"parent_stage2_release_sha256": {"$ref": "#/$defs/sha256"}, "parent_stage2_release_sha256": {"$ref": "#/$defs/sha256"},
"s2_30_release_sha256": {"$ref": "#/$defs/sha256"}, "s2_30_release_sha256": {"$ref": "#/$defs/sha256"},
"compile_mode": {"$ref": "#/$defs/compile_mode"},
"provenance": {"$ref": "#/$defs/common_publish_provenance"},
"expected_claim_group_ids": { "expected_claim_group_ids": {
"type": "array", "type": "array",
"items": {"$ref": "#/$defs/claim_group_id"}, "items": {"$ref": "#/$defs/claim_group_id"},
@@ -1585,13 +1882,20 @@
"items": {"$ref": "#/$defs/claim_group_id"}, "items": {"$ref": "#/$defs/claim_group_id"},
"uniqueItems": true "uniqueItems": true
}, },
"terminal_cohort_receipt_sha256s": { "artifact_manifest_path": {"const": "map_s2_30/artifact_manifest.json"},
"artifact_manifest_schema_ref": {"const": "schemas/draft_atoms.schema.json#/$defs/part_manifest_core"},
"artifact_manifest_sha256": {"$ref": "#/$defs/sha256"},
"ordered_item_receipts": {
"type": "array", "type": "array",
"items": {"$ref": "#/$defs/sha256"}, "items": {"$ref": "#/$defs/item_receipt_ref"},
"uniqueItems": true
},
"ordered_cohort_receipts": {
"type": "array",
"items": {"$ref": "#/$defs/receipt_ref"},
"minItems": 1, "minItems": 1,
"uniqueItems": true "uniqueItems": true
}, },
"artifact_manifest_sha256": {"$ref": "#/$defs/sha256"},
"status": {"enum": ["S2_30_COMPLETE", "TECHNICAL_INCOMPLETE"]}, "status": {"enum": ["S2_30_COMPLETE", "TECHNICAL_INCOMPLETE"]},
"route": {"enum": ["TO_S2_40", "STOP_TECHNICAL_INCOMPLETE"]}, "route": {"enum": ["TO_S2_40", "STOP_TECHNICAL_INCOMPLETE"]},
"status_written_last": {"const": true}, "status_written_last": {"const": true},
@@ -0,0 +1,80 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://schemas.liti-agent.local/stage2/s2_40/migration_regression.schema.v1.json",
"title": "S2_40 structural fixture and regression manifest",
"schema_version": "stage2_s2_40_migration_regression.v1",
"oneOf": [
{"$ref": "#/$defs/fixture_payload"},
{"$ref": "#/$defs/regression_manifest"}
],
"$defs": {
"sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
"nonempty": {"type": "string", "minLength": 1},
"path": {"type": "string", "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$)).+$"},
"fixture_header": {
"type": "object",
"additionalProperties": false,
"required": ["fixture_case_id", "fixture_only", "production_admissible", "compile_mode", "oracle_kind", "source_locators"],
"properties": {
"fixture_case_id": {"$ref": "#/$defs/nonempty"},
"fixture_only": {"const": true},
"production_admissible": {"const": false},
"compile_mode": {"const": "STRUCTURAL_FIXTURE"},
"oracle_kind": {"enum": ["NORMAL", "MUTATION", "STATE", "BARRIER", "DIGEST", "REGRESSION_INDEX"]},
"source_locators": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true}
}
},
"expected_result": {
"type": "object",
"additionalProperties": false,
"required": ["route", "run_technical_status", "artifact_technical_status", "legal_readiness", "expected_invariant_results", "expected_reason_codes"],
"properties": {
"route": {"enum": ["PACKAGE_COMMITTED", "WAIT_EXTERNAL_REVIEW", "STOP_TECHNICAL_INCOMPLETE", "RESTART_FROM_S2_00", "RESTART_FROM_S2_10", "RESTART_FROM_S2_20", "RESTART_FROM_S2_30", "CONTRACT_TEST_ONLY"]},
"run_technical_status": {"enum": ["CONSISTENT", "TECHNICAL_REVIEW_REQUIRED", "TECHNICAL_INCOMPLETE"]},
"artifact_technical_status": {"enum": ["CONSISTENT", "TECHNICAL_REVIEW_REQUIRED", "NOT_PRODUCED"]},
"legal_readiness": {"enum": ["READY_FOR_LAWYER_FILING_DECISION", "LAWYER_REVIEW_REQUIRED", "NOT_ASSESSED"]},
"expected_invariant_results": {"type": "object", "propertyNames": {"pattern": "^V(?:0[1-9]|1[0-8])$"}, "additionalProperties": {"enum": ["PASS", "FAIL", "UNEVALUABLE"]}},
"expected_reason_codes": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true}
}
},
"fixture_payload": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "header", "input", "mutations", "expected"],
"properties": {
"schema_version": {"const": "stage2_s2_40_fixture_payload.v1"},
"header": {"$ref": "#/$defs/fixture_header"},
"input": {"type": "object"},
"mutations": {"type": "array", "items": {"type": "object", "required": ["mutation_id", "target", "operation"], "properties": {"mutation_id": {"$ref": "#/$defs/nonempty"}, "target": {"$ref": "#/$defs/nonempty"}, "operation": {"$ref": "#/$defs/nonempty"}}, "additionalProperties": true}},
"expected": {"$ref": "#/$defs/expected_result"}
}
},
"regression_row": {
"type": "object",
"additionalProperties": false,
"required": ["fixture_case_id", "path", "raw_sha256", "oracle_kind", "expected_route", "expected_invariant_ids"],
"properties": {
"fixture_case_id": {"$ref": "#/$defs/nonempty"},
"path": {"$ref": "#/$defs/path"},
"raw_sha256": {"$ref": "#/$defs/sha256"},
"oracle_kind": {"$ref": "#/$defs/nonempty"},
"expected_route": {"$ref": "#/$defs/nonempty"},
"expected_invariant_ids": {"type": "array", "items": {"pattern": "^V(?:0[1-9]|1[0-8])$"}, "uniqueItems": true}
}
},
"regression_manifest": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "fixture_only", "production_admissible", "compile_mode", "rows", "test_sources", "manifest_digest"],
"properties": {
"schema_version": {"const": "stage2_s2_40_regression_manifest.v1"},
"fixture_only": {"const": true},
"production_admissible": {"const": false},
"compile_mode": {"const": "STRUCTURAL_FIXTURE"},
"rows": {"type": "array", "items": {"$ref": "#/$defs/regression_row"}, "minItems": 15},
"test_sources": {"type": "array", "items": {"type": "object", "required": ["path", "raw_sha256"], "properties": {"path": {"$ref": "#/$defs/path"}, "raw_sha256": {"$ref": "#/$defs/sha256"}}, "additionalProperties": false}, "minItems": 6},
"manifest_digest": {"$ref": "#/$defs/sha256"}
}
}
}
}
@@ -0,0 +1,324 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://schemas.liti-agent.local/stage2/s2_40/package.schema.v1.json",
"title": "S2_40 candidate and sealed package contracts",
"schema_version": "stage2_s2_40_package.v1",
"oneOf": [
{"$ref": "#/$defs/candidate_manifest_core"},
{"$ref": "#/$defs/candidate_digest_envelope"},
{"$ref": "#/$defs/rendered_document_metadata"},
{"$ref": "#/$defs/attorney_worknotes_core"},
{"$ref": "#/$defs/attorney_worknotes"},
{"$ref": "#/$defs/usage_projection"},
{"$ref": "#/$defs/render_diagnostic"},
{"$ref": "#/$defs/review_policy_core"},
{"$ref": "#/$defs/review_request_basis"},
{"$ref": "#/$defs/frozen_source_rows"},
{"$ref": "#/$defs/legal_gate_snapshot"},
{"$ref": "#/$defs/lawyer_review_packet_core"},
{"$ref": "#/$defs/lawyer_review_packet"},
{"$ref": "#/$defs/validation_core"},
{"$ref": "#/$defs/validation_envelope_core"},
{"$ref": "#/$defs/validation_envelope"},
{"$ref": "#/$defs/review_subject"},
{"$ref": "#/$defs/stage2_package"}
],
"$defs": {
"sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
"nonempty": {"type": "string", "minLength": 1},
"path": {"type": "string", "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\x00).+$"},
"compile_mode": {"enum": ["STRUCTURAL_FIXTURE", "SUBSET_CANARY", "PRODUCTION"]},
"artifact_row": {
"type": "object",
"additionalProperties": false,
"required": ["path", "raw_sha256", "content_type", "size_bytes", "schema_ref", "producer_id"],
"properties": {
"path": {"$ref": "#/$defs/path"},
"raw_sha256": {"$ref": "#/$defs/sha256"},
"content_type": {"$ref": "#/$defs/nonempty"},
"size_bytes": {"type": "integer", "minimum": 0},
"schema_ref": {"type": ["string", "null"]},
"producer_id": {"const": "S2_40"}
}
},
"dependency_snapshot": {
"type": "object",
"additionalProperties": false,
"required": ["parent_release_sha256", "upstream_barrier_sha256s", "ordered_source_digest"],
"properties": {
"parent_release_sha256": {"$ref": "#/$defs/sha256"},
"upstream_barrier_sha256s": {"type": "array", "items": {"$ref": "#/$defs/sha256"}, "minItems": 4, "uniqueItems": true},
"ordered_source_digest": {"$ref": "#/$defs/sha256"}
}
},
"ordered_source_snapshot_preimage": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "ordered_sha256s", "snapshot_digest"],
"properties": {
"schema_version": {"const": "stage2_s2_40_ordered_source_snapshot_preimage.v1"},
"ordered_sha256s": {"type": "array", "items": {"$ref": "#/$defs/sha256"}},
"snapshot_digest": {"$ref": "#/$defs/sha256"}
}
},
"source_hash_row": {
"type": "object",
"additionalProperties": false,
"required": ["path", "sha256"],
"properties": {
"path": {"$ref": "#/$defs/path"},
"sha256": {"$ref": "#/$defs/sha256"},
"size_bytes": {"type": "integer", "minimum": 0},
"ref_family": {"$ref": "#/$defs/nonempty"}
}
},
"frozen_source_rows": {
"type": "array",
"items": {"$ref": "#/$defs/source_hash_row"}
},
"attorney_worknotes_core": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "producer_id", "run_binding_digest", "rows"],
"properties": {
"schema_version": {"const": "stage2_s2_40_attorney_worknotes_core.v1"},
"producer_id": {"const": "S2_40"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"rows": {"type": "array", "items": {"type": "object", "required": ["worknote_id", "text", "source_refs"], "properties": {"worknote_id": {"$ref": "#/$defs/nonempty"}, "text": {"$ref": "#/$defs/nonempty"}, "source_refs": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "minItems": 1}}, "additionalProperties": false}}
}
},
"render_diagnostic": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "render_errors", "render_absences", "independent_rerender_equal"],
"properties": {
"schema_version": {"const": "stage2_s2_40_render_diagnostic.v1"},
"render_errors": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true},
"render_absences": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true},
"independent_rerender_equal": {"type": "boolean"}
}
},
"review_policy_core": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "policy_registry_sha256", "base_policy", "active_tags", "runtime_triggers", "required_receipt_types", "pre_receipt_ready_eligible"],
"properties": {
"schema_version": {"const": "stage2_s2_40_review_policy_core.v1"},
"policy_registry_sha256": {"$ref": "#/$defs/sha256"},
"base_policy": {"enum": ["STANDARD_ATTORNEY_REVIEW", "MANDATORY_SPECIALIST_REVIEW"]},
"active_tags": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true},
"runtime_triggers": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true},
"required_receipt_types": {"type": "array", "items": {"enum": ["STANDARD_ATTORNEY_REVIEW", "MANDATORY_SPECIALIST_REVIEW"]}, "uniqueItems": true},
"pre_receipt_ready_eligible": {"type": "boolean"}
}
},
"review_request_basis": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "required_receipt_types", "scope_ids", "finding_ids", "policy_version", "policy_sha256", "reviewer_role", "reviewer_qualification", "release_snapshot_sha256s"],
"properties": {
"schema_version": {"const": "stage2_s2_40_review_request_basis.v1"},
"required_receipt_types": {"type": "array", "items": {"enum": ["STANDARD_ATTORNEY_REVIEW", "MANDATORY_SPECIALIST_REVIEW"]}, "uniqueItems": true},
"scope_ids": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true},
"finding_ids": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true},
"policy_version": {"$ref": "#/$defs/nonempty"},
"policy_sha256": {"$ref": "#/$defs/sha256"},
"reviewer_role": {"$ref": "#/$defs/nonempty"},
"reviewer_qualification": {"$ref": "#/$defs/nonempty"},
"release_snapshot_sha256s": {"type": "object", "additionalProperties": false, "required": ["parent", "authority", "corpus", "case_type_coverage"], "properties": {"parent": {"$ref": "#/$defs/sha256"}, "authority": {"$ref": "#/$defs/sha256"}, "corpus": {"$ref": "#/$defs/sha256"}, "case_type_coverage": {"$ref": "#/$defs/sha256"}}}
}
},
"legal_gate_snapshot": {
"type": "object",
"additionalProperties": false,
"required": ["binding", "authority", "renderer_branch", "rule_sub_rule", "review_policy", "case_type_coverage_137", "corpus", "law_value", "calculator", "required_receipts"],
"properties": {
"binding": {"type": "boolean"}, "authority": {"type": "boolean"},
"renderer_branch": {"type": "boolean"}, "rule_sub_rule": {"type": "boolean"},
"review_policy": {"type": "boolean"}, "case_type_coverage_137": {"type": "boolean"},
"corpus": {"type": "boolean"}, "law_value": {"type": "boolean"},
"calculator": {"type": "boolean"}, "required_receipts": {"type": "boolean"}
}
},
"candidate_manifest_core": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "producer_id", "run_binding_digest", "compile_mode", "candidate_attempt_id", "dependency_snapshot", "artifacts"],
"properties": {
"schema_version": {"const": "stage2_s2_40_candidate_manifest_core.v1"},
"producer_id": {"const": "S2_40"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"compile_mode": {"$ref": "#/$defs/compile_mode"},
"candidate_attempt_id": {"$ref": "#/$defs/nonempty"},
"dependency_snapshot": {"$ref": "#/$defs/dependency_snapshot"},
"artifacts": {"type": "array", "items": {"$ref": "#/$defs/artifact_row"}, "minItems": 6}
},
"not": {"anyOf": [{"required": ["candidate_content_digest"]}, {"required": ["self_sha256"]}]}
},
"candidate_digest_envelope": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "domain_separator", "run_binding_digest", "dependency_snapshot_sha256", "candidate_manifest_core_sha256", "document_sha256s", "attorney_worknotes_core_sha256", "final_issue_ledger_sha256", "assumption_ledger_sha256", "validation_core_sha256", "ordered_source_dependency_snapshot_digest", "candidate_content_digest"],
"properties": {
"schema_version": {"const": "stage2_s2_40_candidate_content_digest.v1"},
"domain_separator": {"const": "STAGE2_S2_40_CANDIDATE_CONTENT_V1"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"dependency_snapshot_sha256": {"$ref": "#/$defs/sha256"},
"candidate_manifest_core_sha256": {"$ref": "#/$defs/sha256"},
"document_sha256s": {
"type": "object", "additionalProperties": false,
"required": ["claim_relief", "claim_cause", "pleading_draft"],
"properties": {"claim_relief": {"$ref": "#/$defs/sha256"}, "claim_cause": {"$ref": "#/$defs/sha256"}, "pleading_draft": {"$ref": "#/$defs/sha256"}}
},
"attorney_worknotes_core_sha256": {"$ref": "#/$defs/sha256"},
"final_issue_ledger_sha256": {"$ref": "#/$defs/sha256"},
"assumption_ledger_sha256": {"$ref": "#/$defs/sha256"},
"validation_core_sha256": {"$ref": "#/$defs/sha256"},
"ordered_source_dependency_snapshot_digest": {"$ref": "#/$defs/sha256"},
"candidate_content_digest": {"$ref": "#/$defs/sha256"}
},
"not": {"anyOf": [{"required": ["review_subject_digest"]}, {"required": ["review_receipt_sha256s"]}, {"required": ["commit_result_sha256"]}, {"required": ["run_status_sha256"]}]}
},
"rendered_document_metadata": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "document_kind", "path", "raw_sha256", "normalization_version", "source_atom_ids", "renderer_branch_refs"],
"properties": {
"schema_version": {"const": "stage2_s2_40_rendered_document_metadata.v1"},
"document_kind": {"enum": ["CLAIM_RELIEF", "CLAIM_CAUSE", "PLEADING_DRAFT"]},
"path": {"$ref": "#/$defs/path"},
"raw_sha256": {"$ref": "#/$defs/sha256"},
"normalization_version": {"const": "NFC_LF_UTF8_V1"},
"source_atom_ids": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true},
"renderer_branch_refs": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true}
}
},
"attorney_worknotes": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "producer_id", "run_binding_digest", "candidate_content_digest", "rows"],
"properties": {
"schema_version": {"const": "stage2_s2_40_attorney_worknotes.v1"},
"producer_id": {"const": "S2_40"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"candidate_content_digest": {"$ref": "#/$defs/sha256"},
"rows": {"type": "array", "items": {"type": "object", "required": ["worknote_id", "text", "source_refs"], "properties": {"worknote_id": {"$ref": "#/$defs/nonempty"}, "text": {"$ref": "#/$defs/nonempty"}, "source_refs": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "minItems": 1}}, "additionalProperties": false}}
}
},
"usage_projection": {
"type": "object", "additionalProperties": false,
"required": ["schema_version", "producer_id", "run_binding_digest", "source_usage_part_sha256s", "rows", "conservation_status"],
"properties": {
"schema_version": {"const": "stage2_s2_40_usage_projection.v1"}, "producer_id": {"const": "S2_40"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"source_usage_part_sha256s": {"type": "array", "items": {"$ref": "#/$defs/sha256"}, "uniqueItems": true},
"rows": {"type": "array", "items": {"type": "object"}},
"conservation_status": {"const": "PASS"}
}
},
"lawyer_review_packet_core": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "candidate_content_digest", "finding_ids", "scope_ids", "document_refs", "legal_readiness"],
"properties": {
"schema_version": {"const": "stage2_s2_40_lawyer_review_packet_core.v1"},
"candidate_content_digest": {"$ref": "#/$defs/sha256"},
"finding_ids": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true},
"scope_ids": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true},
"document_refs": {"type": "array", "items": {"$ref": "#/$defs/path"}, "minItems": 1, "uniqueItems": true},
"legal_readiness": {"enum": ["LAWYER_REVIEW_REQUIRED", "READY_FOR_LAWYER_FILING_DECISION"]}
},
"not": {"anyOf": [{"required": ["review_subject_digest"]}, {"required": ["request_id"]}]}
},
"lawyer_review_packet": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "lawyer_review_packet_core", "lawyer_review_packet_core_sha256", "review_subject_digest"],
"properties": {
"schema_version": {"const": "stage2_s2_40_lawyer_review_packet.v1"},
"lawyer_review_packet_core": {"$ref": "#/$defs/lawyer_review_packet_core"},
"lawyer_review_packet_core_sha256": {"$ref": "#/$defs/sha256"},
"review_subject_digest": {"$ref": "#/$defs/sha256"}
}
},
"validation_core": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "run_binding_digest", "compile_mode", "candidate_manifest_core_sha256", "invariant_results", "run_technical_status", "artifact_technical_status"],
"properties": {
"schema_version": {"const": "stage2_s2_40_validation_core.v1"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"compile_mode": {"$ref": "#/$defs/compile_mode"},
"candidate_manifest_core_sha256": {"$ref": "#/$defs/sha256"},
"invariant_results": {"type": "array", "items": {"$ref": "review_status.schema.json#/$defs/evaluation_result"}, "minItems": 18, "maxItems": 18},
"run_technical_status": {"$ref": "review_status.schema.json#/$defs/run_technical_status"},
"artifact_technical_status": {"$ref": "review_status.schema.json#/$defs/artifact_technical_status"}
}
},
"validation_envelope_core": {
"type": "object", "additionalProperties": false,
"required": ["schema_version", "candidate_content_digest", "validation_core_sha256", "legal_readiness"],
"properties": {
"schema_version": {"const": "stage2_s2_40_validation_envelope_core.v1"},
"candidate_content_digest": {"$ref": "#/$defs/sha256"},
"validation_core_sha256": {"$ref": "#/$defs/sha256"},
"legal_readiness": {"$ref": "review_status.schema.json#/$defs/legal_readiness"}
},
"not": {"anyOf": [{"required": ["review_subject_digest"]}, {"required": ["request_id"]}]}
},
"validation_envelope": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "validation_envelope_core", "validation_envelope_core_sha256", "review_subject_digest"],
"properties": {
"schema_version": {"const": "stage2_s2_40_validation_envelope.v1"},
"validation_envelope_core": {"$ref": "#/$defs/validation_envelope_core"},
"validation_envelope_core_sha256": {"$ref": "#/$defs/sha256"},
"review_subject_digest": {"$ref": "#/$defs/sha256"}
}
},
"review_request_core_binding": {
"type": "object",
"additionalProperties": false,
"required": ["receipt_type", "review_request_core_sha256"],
"properties": {
"receipt_type": {"enum": ["STANDARD_ATTORNEY_REVIEW", "MANDATORY_SPECIALIST_REVIEW"]},
"review_request_core_sha256": {"$ref": "#/$defs/sha256"}
}
},
"review_subject": {
"type": "object", "additionalProperties": false,
"required": ["schema_version", "domain_separator", "candidate_content_digest", "review_request_core_bindings", "lawyer_review_packet_core_sha256", "validation_envelope_core_sha256", "finding_ids", "scope_ids", "review_policy_sha256", "release_sha256s", "review_subject_digest"],
"properties": {
"schema_version": {"const": "stage2_s2_40_review_subject.v1"}, "domain_separator": {"const": "STAGE2_S2_40_REVIEW_SUBJECT_V1"},
"candidate_content_digest": {"$ref": "#/$defs/sha256"}, "review_request_core_bindings": {"type": "array", "items": {"$ref": "#/$defs/review_request_core_binding"}, "uniqueItems": true}, "lawyer_review_packet_core_sha256": {"$ref": "#/$defs/sha256"}, "validation_envelope_core_sha256": {"$ref": "#/$defs/sha256"},
"finding_ids": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true}, "scope_ids": {"type": "array", "items": {"$ref": "#/$defs/nonempty"}, "uniqueItems": true}, "review_policy_sha256": {"$ref": "#/$defs/sha256"},
"release_sha256s": {"type": "object", "additionalProperties": false, "required": ["parent", "authority", "corpus", "case_type_coverage"], "properties": {"parent": {"$ref": "#/$defs/sha256"}, "authority": {"$ref": "#/$defs/sha256"}, "corpus": {"$ref": "#/$defs/sha256"}, "case_type_coverage": {"$ref": "#/$defs/sha256"}}},
"review_subject_digest": {"$ref": "#/$defs/sha256"}
}
},
"stage2_package": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "producer_id", "run_binding_digest", "candidate_content_digest", "compile_mode", "candidate_manifest_core_sha256", "artifacts", "validation_report_sha256", "review_policy_result_sha256", "review_receipt_sha256s", "filing_decision_receipt_sha256", "run_technical_status", "artifact_technical_status", "legal_readiness", "filing_permission"],
"properties": {
"schema_version": {"const": "stage2_s2_40_package.v1"},
"producer_id": {"const": "S2_40"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"candidate_content_digest": {"$ref": "#/$defs/sha256"},
"compile_mode": {"$ref": "#/$defs/compile_mode"},
"candidate_manifest_core_sha256": {"$ref": "#/$defs/sha256"},
"artifacts": {"type": "array", "items": {"$ref": "#/$defs/artifact_row"}, "minItems": 8},
"validation_report_sha256": {"$ref": "#/$defs/sha256"},
"review_policy_result_sha256": {"$ref": "#/$defs/sha256"},
"review_receipt_sha256s": {"type": "array", "items": {"$ref": "#/$defs/sha256"}, "uniqueItems": true},
"filing_decision_receipt_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"run_technical_status": {"$ref": "review_status.schema.json#/$defs/run_technical_status"},
"artifact_technical_status": {"$ref": "review_status.schema.json#/$defs/artifact_technical_status"},
"legal_readiness": {"$ref": "review_status.schema.json#/$defs/legal_readiness"},
"filing_permission": {"const": "NOT_GRANTED"}
},
"not": {"anyOf": [{"required": ["artifact_set_digest"]}, {"required": ["commit_result_sha256"]}, {"required": ["run_status_sha256"]}]}
}
}
}
@@ -7,7 +7,16 @@
{"$ref": "#/$defs/issue_ledger_base"}, {"$ref": "#/$defs/issue_ledger_base"},
{"$ref": "relief_plan.schema.json#/$defs/issue_ledger_plan"}, {"$ref": "relief_plan.schema.json#/$defs/issue_ledger_plan"},
{"$ref": "#/$defs/review_normalization_receipt"}, {"$ref": "#/$defs/review_normalization_receipt"},
{"$ref": "#/$defs/status_only_commit"} {"$ref": "#/$defs/status_only_commit"},
{"$ref": "#/$defs/final_issue_ledger"},
{"$ref": "#/$defs/assumption_ledger"},
{"$ref": "#/$defs/review_policy_result"},
{"$ref": "#/$defs/review_request"},
{"$ref": "#/$defs/review_receipt"},
{"$ref": "#/$defs/lawyer_judgment_record"},
{"$ref": "#/$defs/filing_decision_receipt"},
{"$ref": "#/$defs/status_event"},
{"$ref": "#/$defs/run_status"}
], ],
"$defs": { "$defs": {
"sha256": { "sha256": {
@@ -349,6 +358,249 @@
"issue_refs": {"$ref": "#/$defs/string_set"}, "issue_refs": {"$ref": "#/$defs/string_set"},
"commit_status": {"enum": ["STATUS_ONLY_COMMITTED", "STATUS_ONLY_FAILED"]} "commit_status": {"enum": ["STATUS_ONLY_COMMITTED", "STATUS_ONLY_FAILED"]}
} }
},
"evaluation_result": {
"type": "object",
"additionalProperties": false,
"required": ["invariant_id", "evaluation_status", "finding_ids", "impact_scope", "source_refs", "expected", "observed", "reason_codes", "validator_algorithm_id"],
"properties": {
"invariant_id": {"pattern": "^V(?:0[1-9]|1[0-8])$"},
"evaluation_status": {"enum": ["PASS", "FAIL", "UNEVALUABLE"]},
"finding_ids": {"$ref": "#/$defs/string_set"},
"impact_scope": {"enum": ["OK", "REVIEW_REQUIRED", "INCOMPLETE"]},
"source_refs": {"$ref": "#/$defs/string_set"},
"expected": {},
"observed": {},
"reason_codes": {"$ref": "#/$defs/string_set"},
"validator_algorithm_id": {"$ref": "#/$defs/nonempty_string"}
},
"allOf": [{"if": {"properties": {"evaluation_status": {"const": "PASS"}}, "required": ["evaluation_status"]}, "then": {"properties": {"impact_scope": {"const": "OK"}}}}]
},
"final_issue_ledger": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "producer_id", "run_binding_digest", "compile_mode", "source_ledger_sha256s", "source_issue_part_sha256s", "issues", "conservation_status"],
"properties": {
"schema_version": {"const": "stage2_s2_40_final_issue_ledger.v1"},
"producer_id": {"const": "S2_40"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"compile_mode": {"enum": ["STRUCTURAL_FIXTURE", "SUBSET_CANARY", "PRODUCTION"]},
"source_ledger_sha256s": {"type": "array", "items": {"$ref": "#/$defs/sha256"}, "minItems": 2, "uniqueItems": true},
"source_issue_part_sha256s": {"type": "array", "items": {"$ref": "#/$defs/sha256"}, "uniqueItems": true},
"issues": {"type": "array", "items": {"$ref": "#/$defs/issue_row"}},
"conservation_status": {"enum": ["PASS", "FAIL"]}
}
},
"assumption_row": {
"type": "object",
"additionalProperties": false,
"required": ["assumption_id", "text", "status", "source_refs", "impact_scope"],
"properties": {
"assumption_id": {"$ref": "#/$defs/nonempty_string"},
"text": {"$ref": "#/$defs/nonempty_string"},
"status": {"enum": ["OPEN", "SUPPORTED", "REJECTED", "SUPERSEDED"]},
"source_refs": {"$ref": "#/$defs/string_set"},
"impact_scope": {"enum": ["GLOBAL", "CLAIM_GROUP", "ATOMIC_CLAIM", "DOCUMENT"]}
}
},
"assumption_ledger": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "producer_id", "run_binding_digest", "compile_mode", "source_assumption_part_sha256s", "rows", "conservation_status"],
"properties": {
"schema_version": {"const": "stage2_s2_40_assumption_ledger.v1"},
"producer_id": {"const": "S2_40"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"compile_mode": {"enum": ["STRUCTURAL_FIXTURE", "SUBSET_CANARY", "PRODUCTION"]},
"source_assumption_part_sha256s": {"type": "array", "items": {"$ref": "#/$defs/sha256"}, "uniqueItems": true},
"rows": {"type": "array", "items": {"$ref": "#/$defs/assumption_row"}},
"conservation_status": {"const": "PASS"}
}
},
"review_policy_result": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "candidate_content_digest", "policy_registry_sha256", "base_policy", "active_tags", "runtime_triggers", "required_receipt_types", "ready_eligible"],
"properties": {
"schema_version": {"const": "stage2_s2_40_review_policy_result.v1"},
"candidate_content_digest": {"$ref": "#/$defs/sha256"},
"policy_registry_sha256": {"$ref": "#/$defs/sha256"},
"base_policy": {"enum": ["STANDARD_ATTORNEY_REVIEW", "MANDATORY_SPECIALIST_REVIEW"]},
"active_tags": {"$ref": "#/$defs/string_set"},
"runtime_triggers": {"$ref": "#/$defs/string_set"},
"required_receipt_types": {"$ref": "#/$defs/string_set"},
"ready_eligible": {"type": "boolean"}
}
},
"review_request_core": {
"type": "object",
"additionalProperties": false,
"required": ["candidate_content_digest", "receipt_type", "scope_ids", "finding_ids", "policy_version", "policy_sha256", "reviewer_role", "reviewer_qualification", "release_snapshot_sha256s"],
"properties": {
"candidate_content_digest": {"$ref": "#/$defs/sha256"},
"receipt_type": {"enum": ["STANDARD_ATTORNEY_REVIEW", "MANDATORY_SPECIALIST_REVIEW"]},
"scope_ids": {"$ref": "#/$defs/string_set"},
"finding_ids": {"$ref": "#/$defs/string_set"},
"policy_version": {"$ref": "#/$defs/nonempty_string"},
"policy_sha256": {"$ref": "#/$defs/sha256"},
"reviewer_role": {"$ref": "#/$defs/nonempty_string"},
"reviewer_qualification": {"$ref": "#/$defs/nonempty_string"},
"release_snapshot_sha256s": {
"type": "object", "additionalProperties": false,
"required": ["parent", "authority", "corpus", "case_type_coverage"],
"properties": {"parent": {"$ref": "#/$defs/sha256"}, "authority": {"$ref": "#/$defs/sha256"}, "corpus": {"$ref": "#/$defs/sha256"}, "case_type_coverage": {"$ref": "#/$defs/sha256"}}
}
},
"not": {"anyOf": [{"required": ["request_id"]}, {"required": ["review_subject_digest"]}]}
},
"review_request": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "request_id", "review_subject_digest", "review_request_core", "review_request_core_sha256"],
"properties": {
"schema_version": {"const": "stage2_s2_40_review_request.v1"},
"request_id": {"$ref": "#/$defs/nonempty_string"},
"review_subject_digest": {"$ref": "#/$defs/sha256"},
"review_request_core": {"$ref": "#/$defs/review_request_core"},
"review_request_core_sha256": {"$ref": "#/$defs/sha256"}
}
},
"review_receipt": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "receipt_id", "request_id", "receipt_type", "candidate_content_digest", "review_subject_digest", "finding_ids", "scope_ids", "reviewer_role", "reviewer_qualification", "issuer_id", "key_id", "signature_algorithm", "signed_material_digest", "external_verification_attestation_sha256", "issued_at", "expires_at", "revocation_status", "cryptographic_verification_status", "review_disposition", "change_scope", "reason_codes"],
"properties": {
"schema_version": {"const": "stage2_s2_40_review_receipt.v1"},
"receipt_id": {"$ref": "#/$defs/nonempty_string"},
"request_id": {"$ref": "#/$defs/nonempty_string"},
"receipt_type": {"enum": ["STANDARD_ATTORNEY_REVIEW", "MANDATORY_SPECIALIST_REVIEW"]},
"candidate_content_digest": {"$ref": "#/$defs/sha256"},
"review_subject_digest": {"$ref": "#/$defs/sha256"},
"finding_ids": {"$ref": "#/$defs/string_set"},
"scope_ids": {"$ref": "#/$defs/string_set"},
"reviewer_role": {"$ref": "#/$defs/nonempty_string"},
"reviewer_qualification": {"$ref": "#/$defs/nonempty_string"},
"issuer_id": {"$ref": "#/$defs/nonempty_string"},
"key_id": {"$ref": "#/$defs/nonempty_string"},
"signature_algorithm": {"$ref": "#/$defs/nonempty_string"},
"signed_material_digest": {"$ref": "#/$defs/sha256"},
"external_verification_attestation_sha256": {"$ref": "#/$defs/sha256"},
"issued_at": {"type": "string", "format": "date-time"},
"expires_at": {"type": "string", "format": "date-time"},
"revocation_status": {"enum": ["NOT_REVOKED", "REVOKED", "UNKNOWN"]},
"cryptographic_verification_status": {"enum": ["VERIFIED_BY_EXTERNAL_ADAPTER", "PENDING_PLATFORM_ADMISSION", "INVALID"]},
"review_disposition": {"enum": ["APPROVE_AS_IS", "CONTENT_CHANGE_REQUIRED"]},
"change_scope": {"enum": ["NONE", "STAGE1_CONTEXT", "LEGAL_JUDGMENT", "PLAN_RULE_CALCULATION_BINDING", "DRAFTING_TEXT_ATOM"]},
"reason_codes": {"$ref": "#/$defs/string_set"}
},
"allOf": [
{
"if": {"properties": {"review_disposition": {"const": "APPROVE_AS_IS"}}, "required": ["review_disposition"]},
"then": {"properties": {"change_scope": {"const": "NONE"}}}
},
{
"if": {"properties": {"review_disposition": {"const": "CONTENT_CHANGE_REQUIRED"}}, "required": ["review_disposition"]},
"then": {"not": {"properties": {"change_scope": {"const": "NONE"}}, "required": ["change_scope"]}}
}
]
},
"lawyer_judgment_record": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "candidate_content_digest", "review_subject_digest", "review_receipt_ids", "judgment", "writer_role"],
"properties": {
"schema_version": {"const": "stage2_s2_40_lawyer_judgment_record.v1"},
"candidate_content_digest": {"$ref": "#/$defs/sha256"},
"review_subject_digest": {"$ref": "#/$defs/sha256"},
"review_receipt_ids": {"$ref": "#/$defs/string_set"},
"judgment": {"enum": ["APPROVE_AS_IS", "CONTENT_CHANGE_REQUIRED"]},
"writer_role": {"const": "KOREAN_LAWYER_EXTERNAL_WRITER"}
}
},
"filing_decision_receipt": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "decision_id", "candidate_content_digest", "stage2_package_sha256", "artifact_set_digest", "committed_run_status_sha256", "filing_scope", "reviewer_identity", "reviewer_qualification", "issuer_id", "key_id", "signature_algorithm", "signed_material_digest", "external_verification_attestation_sha256", "decision", "issued_at", "expires_at", "revocation_status", "signature_attestation"],
"properties": {
"schema_version": {"const": "stage2_s2_40_filing_decision_receipt.v1"},
"decision_id": {"$ref": "#/$defs/nonempty_string"},
"candidate_content_digest": {"$ref": "#/$defs/sha256"},
"stage2_package_sha256": {"$ref": "#/$defs/sha256"},
"artifact_set_digest": {"$ref": "#/$defs/sha256"},
"committed_run_status_sha256": {"$ref": "#/$defs/sha256"},
"filing_scope": {"$ref": "#/$defs/string_set"},
"reviewer_identity": {"$ref": "#/$defs/nonempty_string"},
"reviewer_qualification": {"const": "QUALIFIED_KOREAN_LAWYER"},
"issuer_id": {"$ref": "#/$defs/nonempty_string"}, "key_id": {"$ref": "#/$defs/nonempty_string"}, "signature_algorithm": {"$ref": "#/$defs/nonempty_string"},
"signed_material_digest": {"$ref": "#/$defs/sha256"}, "external_verification_attestation_sha256": {"$ref": "#/$defs/sha256"},
"decision": {"enum": ["APPROVE_FOR_FILING", "DO_NOT_FILE"]},
"issued_at": {"type": "string", "format": "date-time"},
"expires_at": {"type": "string", "format": "date-time"},
"revocation_status": {"enum": ["NOT_REVOKED", "REVOKED", "UNKNOWN"]},
"signature_attestation": {"$ref": "#/$defs/sha256"}
}
},
"workflow_phase": {"enum": ["CANDIDATE_FROZEN", "AWAITING_EXTERNAL_REVIEW", "READY_TO_COMMIT", "COMMITTED", "SUPERSEDED", "DIAGNOSTIC_ONLY"]},
"status_event": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "writer_id", "run_binding_digest", "candidate_attempt_id", "workflow_phase", "route", "candidate_content_digest", "previous_run_status_sha256", "request_sha256", "host_cas_receipt_sha256", "event_digest"],
"properties": {
"schema_version": {"const": "stage2_s2_40_status_event.v1"},
"writer_id": {"const": "S2_40"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"candidate_attempt_id": {"$ref": "#/$defs/nonempty_string"},
"workflow_phase": {"$ref": "#/$defs/workflow_phase"},
"route": {"$ref": "#/$defs/nonempty_string"},
"candidate_content_digest": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"previous_run_status_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"request_sha256": {"$ref": "#/$defs/sha256"},
"host_cas_receipt_sha256": {"$ref": "#/$defs/sha256"},
"event_digest": {"$ref": "#/$defs/sha256"}
}
},
"run_status": {
"type": "object",
"additionalProperties": false,
"required": ["schema_version", "writer_id", "run_binding_digest", "candidate_attempt_id", "entry_route", "compile_mode", "workflow_phase", "route", "candidate_content_digest", "run_technical_status", "artifact_technical_status", "legal_readiness", "validation_report_sha256", "review_subject_digest", "review_receipt_sha256s", "stage2_package_sha256", "artifact_set_digest", "commit_intent_sha256", "commit_result_sha256", "request_sha256", "host_cas_receipt_sha256", "outer_execution_receipt_sha256", "previous_run_status_sha256", "status_event_sha256", "barrier_written_last", "readback_verified"],
"properties": {
"schema_version": {"const": "stage2_s2_40_run_status.v1"},
"writer_id": {"const": "S2_40"},
"run_binding_digest": {"$ref": "#/$defs/sha256"},
"candidate_attempt_id": {"$ref": "#/$defs/nonempty_string"},
"entry_route": {"enum": ["TO_S2_40", "TO_S2_40_STATUS_ONLY"]},
"compile_mode": {"type": ["string", "null"], "enum": [null, "STRUCTURAL_FIXTURE", "SUBSET_CANARY", "PRODUCTION"]},
"workflow_phase": {"$ref": "#/$defs/workflow_phase"},
"route": {"enum": ["STOP_TECHNICAL_INCOMPLETE", "CHECKPOINT_FROZEN", "WAIT_EXTERNAL_REVIEW", "CONTINUE_TO_COMMIT", "RESTART_FROM_S2_00", "RESTART_FROM_S2_10", "RESTART_FROM_S2_20", "RESTART_FROM_S2_30", "PACKAGE_COMMITTED"]},
"candidate_content_digest": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"run_technical_status": {"$ref": "#/$defs/run_technical_status"},
"artifact_technical_status": {"$ref": "#/$defs/artifact_technical_status"},
"legal_readiness": {"$ref": "#/$defs/legal_readiness"},
"validation_report_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"review_subject_digest": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"review_receipt_sha256s": {"type": "array", "items": {"$ref": "#/$defs/sha256"}, "uniqueItems": true},
"stage2_package_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"artifact_set_digest": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"commit_intent_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"commit_result_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"request_sha256": {"$ref": "#/$defs/sha256"},
"host_cas_receipt_sha256": {"$ref": "#/$defs/sha256"},
"outer_execution_receipt_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"previous_run_status_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"status_event_sha256": {"oneOf": [{"$ref": "#/$defs/sha256"}, {"type": "null"}]},
"barrier_written_last": {"const": true},
"readback_verified": {"const": true}
},
"allOf": [
{
"if": {"properties": {"entry_route": {"const": "TO_S2_40_STATUS_ONLY"}}, "required": ["entry_route"]},
"then": {"properties": {"status_event_sha256": {"type": "null"}}}
},
{
"if": {"properties": {"entry_route": {"const": "TO_S2_40"}}, "required": ["entry_route"]},
"then": {"properties": {"status_event_sha256": {"$ref": "#/$defs/sha256"}}}
}
]
} }
} }
} }
@@ -1236,6 +1236,75 @@
} }
] ]
}, },
"s2_40_fixture_binding": {
"binding_status": "OFFLINE_BYTES_BOUND_LEGAL_AND_LIVE_PENDING",
"fixture_manifest_path": "tests/fixtures/s2_40/regression_manifest.json",
"fixture_manifest_sha256": "ac5d68c8d4061d789aa5c773cd1ffb37728c33c7725785a9dd1f4bea63ec88ce",
"logical_fixture_count": 15,
"payload_file_count": 15,
"payloads": [
{
"path": "tests/fixtures/s2_40/candidate_digest_noncycle.json",
"sha256": "74885602909bd19ca1678de781cac26afd34c2f386e98fc0370fd6ff6fb7b8bf"
},
{
"path": "tests/fixtures/s2_40/cost_provisional_execution_numbering.json",
"sha256": "17c380492f5bc56ecf675cf9683784b2e463241c7d0589b7b496e7a381145c9b"
},
{
"path": "tests/fixtures/s2_40/exhibit_object_party_title_completeness.json",
"sha256": "40045822f45b2a57805504744e751ee420a6187d0790d5a0f442f529ffedcf7e"
},
{
"path": "tests/fixtures/s2_40/part_set_missing_duplicate_or_cross_group.json",
"sha256": "379273497ee23d4a515135771ba4d3bb5ff0e38325ad40eb4e0a0008cd6b88f4"
},
{
"path": "tests/fixtures/s2_40/partial_write_readback_barrier.json",
"sha256": "467387c12a4cc6469d243de9f0a7948276adb558a99b3b661ccd74a5d17629cf"
},
{
"path": "tests/fixtures/s2_40/relief_cause_crossmatch_mutations.json",
"sha256": "e8d148fef61920039e36abd0cfb771cc6e2fe3aa1a9cc0b0b0502c38ddf70567"
},
{
"path": "tests/fixtures/s2_40/renderer_ast_slot_branch_mutations.json",
"sha256": "e70ecac4e71de962dfe8bb025a42c73c7c03cfba32c29319523d19f49e8260d0"
},
{
"path": "tests/fixtures/s2_40/review_policy_state_aggregation.json",
"sha256": "953fc301703ff353de4df3cf46ed4e90b6bf4ce8268b08705e16151ffc8c3a21"
},
{
"path": "tests/fixtures/s2_40/review_receipt_approve_resume.json",
"sha256": "c5b84e34358761750e8e9e7666de6532e0f22a31f32bf027f24efb256a1af5d5"
},
{
"path": "tests/fixtures/s2_40/review_receipt_content_change_supersede.json",
"sha256": "400d4aeb455e5c3ec26c75a552ea91e9af79cb2329998caa1ad72d1be18da8e7"
},
{
"path": "tests/fixtures/s2_40/review_receipt_missing_or_invalid.json",
"sha256": "a88645be90a9e0943358d83f7ea105193dd4b4dfebea4519702a17f69615dc65"
},
{
"path": "tests/fixtures/s2_40/same_binding_idempotence_and_commit_conflict.json",
"sha256": "5536793236fa44da601dc8cf65d94dac32b18ebc2e8dc525a6df92106add57ad"
},
{
"path": "tests/fixtures/s2_40/v01_v18_invariant_matrix.json",
"sha256": "e4c0a5476647fa1860cd685a15aad6d465a36b4f6b648c8e2a066c8747780eb8"
},
{
"path": "tests/fixtures/s2_40/valid_full_candidate_and_commit.json",
"sha256": "e98e8dc55ab60f8f875ad2f58c1aec35eb1da3882371c22c3e232e0e9ae46c2f"
},
{
"path": "tests/fixtures/s2_40/valid_status_only_diagnostic.json",
"sha256": "5676088f5d79168cbae5e1481da4b7cfd9241d06c935378e06dd2af56aae6285"
}
]
},
"test_sources": [ "test_sources": [
{ {
"path": "tests/s2_00/test_canonical_ids.py", "path": "tests/s2_00/test_canonical_ids.py",
@@ -1244,7 +1313,7 @@
}, },
{ {
"path": "tests/s2_00/test_cluster_bundle_compile.py", "path": "tests/s2_00/test_cluster_bundle_compile.py",
"sha256": "aa31cc87246a5c8f6b82e98b9f86dd654bc9306dfc7849af19ec16cfd5137a2a", "sha256": "b643d2d4018ebe3349c64304063edf7ba0194fc92fb1fe9337eca3f384ae794a",
"status": "DEV_HASH_BOUND" "status": "DEV_HASH_BOUND"
}, },
{ {
@@ -1254,7 +1323,7 @@
}, },
{ {
"path": "tests/s2_00/test_failure_and_atomic_publish.py", "path": "tests/s2_00/test_failure_and_atomic_publish.py",
"sha256": "128a82b4e413132c0ff4a61ae2dc7f85b6c1c050ea33ccf4e53f23ccc993aba6", "sha256": "613f0c1b32dc26c302365fc62f36c8ede7204e1ced4920e797a1651af8354527",
"status": "DEV_HASH_BOUND" "status": "DEV_HASH_BOUND"
}, },
{ {
@@ -1299,18 +1368,53 @@
}, },
{ {
"path": "tests/s2_20/test_plan_publish_and_release.py", "path": "tests/s2_20/test_plan_publish_and_release.py",
"sha256": "eb5a96109d95d4b78473f79129c441f9be9b015bba1157dfa4d4d3616d03525e", "sha256": "ce0dc52cca2c6744be1051346ebecabac8c4ccbd97d697f7645eadd35aebd1e8",
"status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING" "status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING"
}, },
{ {
"path": "tests/s2_20/test_regression_manifest_closure.py", "path": "tests/s2_20/test_regression_manifest_closure.py",
"sha256": "886ae584a7846acdb5499d52e1ae8ec177e8d1dc34aa1d43e99dbebafa255516", "sha256": "01ac49ab1ba79f158da9da78313407e3a67a95cf539113c617701a74c29b463f",
"status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING" "status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING"
}, },
{ {
"path": "tests/s2_20/test_retrieval_and_pack.py", "path": "tests/s2_20/test_retrieval_and_pack.py",
"sha256": "c314cf27511b0fe065b8961196084a28b1c7c5cb2fed3dd5c8765172ba40462f", "sha256": "c314cf27511b0fe065b8961196084a28b1c7c5cb2fed3dd5c8765172ba40462f",
"status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING" "status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING"
},
{
"path": "tests/s2_40/test_agent_and_inline_parity.py",
"sha256": "04cc4a14790eceea6ec8a9331212ca6e767ef96994b5b26483392d23145417ae",
"status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING"
},
{
"path": "tests/s2_40/test_c40_reduce_and_conservation.py",
"sha256": "f610eced056420277c67294cdfe76d559073d88a6f42d3e8c5dae8f219fa82d9",
"status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING"
},
{
"path": "tests/s2_40/test_c45_closed_render.py",
"sha256": "b7cad96735b1a0158644f41703b4f279fdd8b6bc68438f0d7d773b8415ebb460",
"status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING"
},
{
"path": "tests/s2_40/test_commit_barrier_and_idempotence.py",
"sha256": "714e2f05397d5dcc31159739363f11c9bbaf5a091de55b465e0b474c21f90ea0",
"status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING"
},
{
"path": "tests/s2_40/test_release_closure.py",
"sha256": "89139e0286facd52c3ce91a1c7b382a584dfc3e6bc337fcb55fbc8eed59f5933",
"status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING"
},
{
"path": "tests/s2_40/test_review_state_machine.py",
"sha256": "f4dab9bb651b4a3c818c73162b972c8ac3df0f50fbe056e392a12673139b9b4a",
"status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING"
},
{
"path": "tests/s2_40/test_v01_v18.py",
"sha256": "72be88be1aa9d495b5c9387e45b75e86f44ac76ffe15c04b5ba33ba21fa8943f",
"status": "OFFLINE_VERIFIED_LEGAL_AND_LIVE_PENDING"
} }
] ]
} }
@@ -1,5 +1,5 @@
{ {
"schema_version": "stage2_s2_30_partial_write_barrier_fixture.v1", "schema_version": "stage2_s2_30_partial_write_barrier_fixture.v2",
"cases": [ "cases": [
{ {
"case_id": "partial_write_preserve_existing_rows", "case_id": "partial_write_preserve_existing_rows",
@@ -23,35 +23,28 @@
"expected": {"failure_code": "READ_BACK_HASH_MISMATCH", "publish_status_written": false, "downstream_allowed": false} "expected": {"failure_code": "READ_BACK_HASH_MISMATCH", "publish_status_written": false, "downstream_allowed": false}
}, },
{ {
"case_id": "status_last_success", "case_id": "status_last_success_shape",
"expected_claim_group_ids": ["CG-1111111111111111", "CG-2222222222222222"], "manifest": {
"read_back_verified_claim_group_ids": ["CG-1111111111111111", "CG-2222222222222222"], "path": "map_s2_30/artifact_manifest.json",
"terminal_cohort_receipt_sha256s": ["5555555555555555555555555555555555555555555555555555555555555555"], "schema_ref": "schemas/draft_atoms.schema.json#/$defs/part_manifest_core",
"artifact_manifest_sha256": "6666666666666666666666666666666666666666666666666666666666666666", "receipt_free": true,
"publish_status": { "part_manifest_core_sha256": "5555555555555555555555555555555555555555555555555555555555555555",
"schema_version": "stage2_s2_30_publish_status.v1", "raw_sha256": "6666666666666666666666666666666666666666666666666666666666666666"
"request_id": "REQ-S2-30-PUBLISH-001",
"run_binding_digest": "7777777777777777777777777777777777777777777777777777777777777777",
"parent_stage2_release_sha256": "8888888888888888888888888888888888888888888888888888888888888888",
"s2_30_release_sha256": "9999999999999999999999999999999999999999999999999999999999999999",
"expected_claim_group_ids": ["CG-1111111111111111", "CG-2222222222222222"],
"published_claim_group_ids": ["CG-1111111111111111", "CG-2222222222222222"],
"terminal_failure_claim_group_ids": [],
"terminal_cohort_receipt_sha256s": ["5555555555555555555555555555555555555555555555555555555555555555"],
"artifact_manifest_sha256": "6666666666666666666666666666666666666666666666666666666666666666",
"status": "S2_30_COMPLETE",
"route": "TO_S2_40",
"status_written_last": true,
"status_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}, },
"expected": {"schema_valid": true, "write_order_last": "map_s2_30/s2_30_publish_status.json", "route": "TO_S2_40"} "ordered_item_receipts": [
{"claim_group_id": "CG-1111111111111111", "path": "map_s2_30/item_receipts/CG-1111111111111111.json", "sha256": "7777777777777777777777777777777777777777777777777777777777777777"}
],
"ordered_cohort_receipts": [
{"path": "map_s2_30/cohort_receipts/COHORT-001/attempt-1.json", "sha256": "8888888888888888888888888888888888888888888888888888888888888888"}
],
"expected": {"write_order_last": "map_s2_30/s2_30_publish_status.json", "route": "TO_S2_40", "directory_scan_used": false}
} }
], ],
"mutations": [ "mutations": [
{"mutation_id": "S30-BARRIER-EARLY", "single_defect": "STATUS_WRITTEN_BEFORE_ALL_READ_BACK", "expected_code": "STATUS_LAST_BARRIER_VIOLATION"}, {"mutation_id": "S30-BARRIER-EARLY", "single_defect": "STATUS_WRITTEN_BEFORE_ALL_READ_BACK", "expected_code": "STATUS_LAST_BARRIER_VIOLATION"},
{"mutation_id": "S30-BARRIER-MISSING-GROUP", "single_defect": "EXPECTED_GROUP_NOT_TERMINAL", "expected_code": "GROUP_TERMINAL_SET_MISMATCH"}, {"mutation_id": "S30-BARRIER-MISSING-GROUP", "single_defect": "EXPECTED_GROUP_NOT_TERMINAL", "expected_code": "PUBLISH_GROUP_SET_MISMATCH"},
{"mutation_id": "S30-BARRIER-OVERWRITE", "single_defect": "EXISTING_NONIDENTICAL_ARTIFACT_OVERWRITTEN", "expected_code": "IMMUTABLE_OUTPUT_CONFLICT"}, {"mutation_id": "S30-BARRIER-UNENUMERATED-PART", "single_defect": "PART_NOT_IN_MANIFEST", "expected_code": "UNENUMERATED_PART_INPUT_FORBIDDEN"},
{"mutation_id": "S30-BARRIER-DELETE-PARTIAL", "single_defect": "SUCCESSFUL_EXISTING_ARTIFACT_DELETED_AFTER_PEER_FAILURE", "expected_code": "PARTIAL_WRITE_PRESERVATION_FAILED"}, {"mutation_id": "S30-BARRIER-MANIFEST-RECEIPT-CYCLE", "single_defect": "RECEIPT_HASH_INSERTED_IN_MANIFEST_CORE", "expected_code": "MANIFEST_RECEIPT_REFERENCE_FORBIDDEN"},
{"mutation_id": "S30-BARRIER-TO-S2-40-ON-FAILURE", "single_defect": "DOWNSTREAM_ROUTE_OPEN_WITH_TERMINAL_FAILURE", "expected_code": "DOWNSTREAM_ROUTE_MUST_STOP"} {"mutation_id": "S30-BARRIER-TO-S2-40-ON-FAILURE", "single_defect": "DOWNSTREAM_ROUTE_OPEN_WITH_TERMINAL_FAILURE", "expected_code": "PUBLISH_SUCCESS_ROUTE_INVALID"}
] ]
} }
@@ -0,0 +1,55 @@
{
"schema_version": "stage2_s2_30_persisted_handoff_chain_fixture.v1",
"contract": {
"manifest_path": "map_s2_30/artifact_manifest.json",
"manifest_schema_ref": "schemas/draft_atoms.schema.json#/$defs/part_manifest_core",
"part_families": ["DRAFT_PART", "ISSUE_PATCH", "USAGE_PART", "WORKNOTE_PART"],
"rows_per_claim_group": 4,
"manifest_receipt_free": true,
"item_and_cohort_receipts_reference": "part_manifest_core_sha256",
"publish_status_written_last": true,
"runtime_directory_scan_allowed": false,
"runtime_glob_allowed": false,
"group_provenance_fields": [
"compile_mode",
"p00_prompt_sha256",
"p30_prompt_sha256",
"p31_rule_and_pack_sha256",
"p32_common_authority_sha256",
"parent_stage2_release_sha256",
"s2_30_agent_sha256",
"s2_30_binding_sha256",
"s2_30_producer_contract_digest",
"s2_30_release_sha256",
"s30_group_slice_sha256"
],
"ordered_receipt_indexes": ["ordered_item_receipts", "ordered_cohort_receipts"]
},
"mutations": [
{
"mutation_id": "S30-HANDOFF-MISSING-PART",
"single_defect": "MANIFEST_ROW_HAS_NO_EXPLICIT_PART_BYTES",
"expected_code": "MANIFEST_PART_BYTES_MISSING"
},
{
"mutation_id": "S30-HANDOFF-UNENUMERATED-PART",
"single_defect": "PART_BYTES_NOT_LISTED_BY_MANIFEST",
"expected_code": "UNENUMERATED_PART_INPUT_FORBIDDEN"
},
{
"mutation_id": "S30-HANDOFF-RECEIPT-CYCLE",
"single_defect": "MANIFEST_CORE_CONTAINS_RECEIPT_REFERENCE",
"expected_code": "MANIFEST_RECEIPT_REFERENCE_FORBIDDEN"
},
{
"mutation_id": "S30-HANDOFF-MODE-DRIFT",
"single_defect": "PUBLISH_COMPILE_MODE_DIFFERS_FROM_MANIFEST",
"expected_code": "PUBLISH_COMPILE_MODE_MISMATCH"
},
{
"mutation_id": "S30-HANDOFF-RECEIPT-CORE-DRIFT",
"single_defect": "RECEIPT_REFERENCES_DIFFERENT_MANIFEST_CORE_HASH",
"expected_code": "RECEIPT_MANIFEST_CORE_HASH_MISMATCH"
}
]
}
@@ -2,7 +2,7 @@
"schema_version": "stage2_s2_30_regression_manifest.v1", "schema_version": "stage2_s2_30_regression_manifest.v1",
"status": "OFFLINE_STRUCTURAL_ORACLES_BOUND_LIVE_AND_LEGAL_ORACLES_PENDING", "status": "OFFLINE_STRUCTURAL_ORACLES_BOUND_LIVE_AND_LEGAL_ORACLES_PENDING",
"hash_algorithm": "SHA-256", "hash_algorithm": "SHA-256",
"fixture_count_excluding_manifest": 13, "fixture_count_excluding_manifest": 14,
"test_source_count": 5, "test_source_count": 5,
"fixtures": [ "fixtures": [
{"filename": "adverse_fact_worknote_policy.json", "sha256": "5b8e9101385f8d65b0332c3be63cb9a22063920675cc86aee51e04da7820aef7", "expected_oracles": ["ADVERSE_FACT_SCHEMA_AND_POLICY_ORACLE"]}, {"filename": "adverse_fact_worknote_policy.json", "sha256": "5b8e9101385f8d65b0332c3be63cb9a22063920675cc86aee51e04da7820aef7", "expected_oracles": ["ADVERSE_FACT_SCHEMA_AND_POLICY_ORACLE"]},
@@ -14,16 +14,17 @@
{"filename": "invalid_preassembled_prompt_item.json", "sha256": "6655402c669e5b40f2e7028a5c0c89571d8e1597dbdef567b4c9d8e2eed15a79", "expected_oracles": ["PARSE_AND_CONTRACT_ORACLE"]}, {"filename": "invalid_preassembled_prompt_item.json", "sha256": "6655402c669e5b40f2e7028a5c0c89571d8e1597dbdef567b4c9d8e2eed15a79", "expected_oracles": ["PARSE_AND_CONTRACT_ORACLE"]},
{"filename": "invalid_reference_output.json", "sha256": "eb2982a09f4948baadc27ae49c4f125426074333ea4a626e9c56ddc5c24ce273", "expected_oracles": ["PARSE_AND_CONTRACT_ORACLE"]}, {"filename": "invalid_reference_output.json", "sha256": "eb2982a09f4948baadc27ae49c4f125426074333ea4a626e9c56ddc5c24ce273", "expected_oracles": ["PARSE_AND_CONTRACT_ORACLE"]},
{"filename": "owner_singleton_dispatch.json", "sha256": "38f9c364591fcdfe60d0dea9f69eb86b2f3b883929f6d60d06a7c35ff376fca6", "expected_oracles": ["OWNER_DISPATCH_AND_MATERIALIZATION_ORACLE"]}, {"filename": "owner_singleton_dispatch.json", "sha256": "38f9c364591fcdfe60d0dea9f69eb86b2f3b883929f6d60d06a7c35ff376fca6", "expected_oracles": ["OWNER_DISPATCH_AND_MATERIALIZATION_ORACLE"]},
{"filename": "partial_write_publish_barrier.json", "sha256": "89f8318c7dbec7bf0095e34194f0a585ea5f4cbce9826af64c30d370612fa1f5", "expected_oracles": ["PARSE_AND_CONTRACT_ORACLE"]}, {"filename": "partial_write_publish_barrier.json", "sha256": "0d878b946ebf810e8d0d8da74af33e56f35e164b04076a3867344b95d5f953eb", "expected_oracles": ["STATUS_LAST_AND_PARTIAL_WRITE_ORACLE"]},
{"filename": "persisted_handoff_chain.json", "sha256": "54d6d781a60640744cba4b9c2f88a0013a6e58656c9c80a809e39fd4ba7c1097", "expected_oracles": ["RECEIPT_FREE_EXACT_HANDOFF_CHAIN_ORACLE"]},
{"filename": "rule_requirement_admission_gap.json", "sha256": "27dfad63f3508c5d40521270707d84b2bc0c58f035f47d0cde1ae2abc54f9a15", "expected_oracles": ["PARSE_AND_CONTRACT_ORACLE"]}, {"filename": "rule_requirement_admission_gap.json", "sha256": "27dfad63f3508c5d40521270707d84b2bc0c58f035f47d0cde1ae2abc54f9a15", "expected_oracles": ["PARSE_AND_CONTRACT_ORACLE"]},
{"filename": "technical_failure.json", "sha256": "bdcc6410e7515edc73d6b154d5b618b3ec34273ddc7269dc3e3ce55a6eb35fa6", "expected_oracles": ["PARSE_AND_CONTRACT_ORACLE"]}, {"filename": "technical_failure.json", "sha256": "bdcc6410e7515edc73d6b154d5b618b3ec34273ddc7269dc3e3ce55a6eb35fa6", "expected_oracles": ["PARSE_AND_CONTRACT_ORACLE"]},
{"filename": "valid_joint_draft_output.json", "sha256": "0135616c9375602693af8e12c3c16cf2031eaf3d9b74783bec9b5065846327e8", "expected_oracles": ["PARSE_AND_CONTRACT_ORACLE"]} {"filename": "valid_joint_draft_output.json", "sha256": "0135616c9375602693af8e12c3c16cf2031eaf3d9b74783bec9b5065846327e8", "expected_oracles": ["PARSE_AND_CONTRACT_ORACLE"]}
], ],
"test_sources": [ "test_sources": [
{"path": "tests/s2_30/test_agent_contract.py", "sha256": "e7d0f069f8c60ff5c5194a9ea9289376e2fd81a50d1b4b18b1b6abf5f2827529"}, {"path": "tests/s2_30/test_agent_contract.py", "sha256": "26a37b0b5fa6c4273ed7deff6b0429e3223869533fc2384f4c364fe88d554da5"},
{"path": "tests/s2_30/test_dispatch_materialization.py", "sha256": "9d6ca17f012566b3d7423195ef19908694604a81059bfc10bd0c34dab1c24665"}, {"path": "tests/s2_30/test_dispatch_materialization.py", "sha256": "9d6ca17f012566b3d7423195ef19908694604a81059bfc10bd0c34dab1c24665"},
{"path": "tests/s2_30/test_draft_atom_contract.py", "sha256": "cb1ecf7131921c37aa4a6dc31f9053f21526f153407b90d1efffd472b0d68923"}, {"path": "tests/s2_30/test_draft_atom_contract.py", "sha256": "cb1ecf7131921c37aa4a6dc31f9053f21526f153407b90d1efffd472b0d68923"},
{"path": "tests/s2_30/test_prompt_cache_and_boundaries.py", "sha256": "9063ca0a247cf06f55e94e586a7ab8ac21facd9f6c607ce4799047aea365e287"}, {"path": "tests/s2_30/test_prompt_cache_and_boundaries.py", "sha256": "1b9b562418bc24be6db09dc1d35f71845033adbc693aeb41fbba07be16fa7c9d"},
{"path": "tests/s2_30/test_release_adapter_retry.py", "sha256": "b15505567db55689527056d608a1cb12d3c605e9df860afba607a6e3e276a0ef"} {"path": "tests/s2_30/test_release_adapter_retry.py", "sha256": "e5af75d54f236eb8ba99b194a06aa31f02fddd5c6aa9ff7385401905359b292c"}
] ]
} }
@@ -0,0 +1 @@
{"schema_version":"stage2_s2_40_fixture_payload.v1","header":{"fixture_case_id":"S40-F015","fixture_only":true,"production_admissible":false,"compile_mode":"STRUCTURAL_FIXTURE","oracle_kind":"DIGEST","source_locators":["fixture://s2_40/noncycle"]},"input":{"ordered_graph":["candidate_manifest_core","candidate_content_digest","review_subject","commit_intent","artifact_set_digest","commit_result","run_status"]},"mutations":[{"mutation_id":"CYCLE","target":"candidate_manifest_core/candidate_content_digest","operation":"ADD"}],"expected":{"route":"CONTRACT_TEST_ONLY","run_technical_status":"TECHNICAL_INCOMPLETE","artifact_technical_status":"NOT_PRODUCED","legal_readiness":"NOT_ASSESSED","expected_invariant_results":{"V14":"FAIL"},"expected_reason_codes":["CANDIDATE_DIGEST_MATERIAL_CYCLE"]}}
@@ -0,0 +1,43 @@
{
"schema_version": "stage2_s2_40_fixture_payload.v1",
"header": {
"fixture_case_id": "S40-F007",
"fixture_only": true,
"production_admissible": false,
"compile_mode": "STRUCTURAL_FIXTURE",
"oracle_kind": "MUTATION",
"source_locators": ["fixture://s2_40/numbering"]
},
"input": {
"renderer_ids": ["R01", "R03", "R05", "R06"],
"actio_structural_dependencies": [
"route", "recipient", "period_one", "period_two", "three_cap", "provisional_execution"
],
"special_case_structural_dependencies": [
"reserved_share_temporal", "forced_apology_prohibition", "simultaneous_performance",
"CE-01", "CE-13", "loan_contract_temporal"
],
"actio_legal_approval_status": "PENDING_LEGAL_ADMISSION",
"special_case_legal_approval_status": "PENDING_LEGAL_ADMISSION"
},
"mutations": [
{"mutation_id":"INELIGIBLE","target":"provisional/R03","operation":"ENABLE"},
{"mutation_id":"NUMBER","target":"relief/order","operation":"PERMUTE"},
{"mutation_id":"ACTIO_ROUTE","target":"actio.route","operation":"DROP"},
{"mutation_id":"ACTIO_RECIPIENT","target":"actio.recipient","operation":"SUBSTITUTE"},
{"mutation_id":"ACTIO_PERIODS","target":"actio.periods","operation":"COLLAPSE_TWO_TO_ONE"},
{"mutation_id":"ACTIO_THREE_CAP","target":"actio.three_cap","operation":"REMOVE_RECEIPT"},
{"mutation_id":"RESERVED_SHARE_TEMPORAL","target":"reserved_share.temporal_branch","operation":"STALE"},
{"mutation_id":"FORCED_APOLOGY","target":"relief.forced_apology","operation":"ENABLE"},
{"mutation_id":"SIMULTANEOUS_PERFORMANCE","target":"relief.counter_performance","operation":"DROP"},
{"mutation_id":"CE01_CE13_LOAN_TEMPORAL","target":"law_value_receipts","operation":"REMOVE_TEMPORAL_SCOPE"}
],
"expected": {
"route": "WAIT_EXTERNAL_REVIEW",
"run_technical_status": "TECHNICAL_REVIEW_REQUIRED",
"artifact_technical_status": "TECHNICAL_REVIEW_REQUIRED",
"legal_readiness": "LAWYER_REVIEW_REQUIRED",
"expected_invariant_results": {"V10":"FAIL", "V18":"FAIL"},
"expected_reason_codes": ["PROVISIONAL_OR_NUMBERING_INVALID"]
}
}
@@ -0,0 +1 @@
{"schema_version":"stage2_s2_40_fixture_payload.v1","header":{"fixture_case_id":"S40-F008","fixture_only":true,"production_admissible":false,"compile_mode":"STRUCTURAL_FIXTURE","oracle_kind":"MUTATION","source_locators":["fixture://s2_40/completeness"]},"input":{"refs":["party:P1","object:O1","exhibit:E1"]},"mutations":[{"mutation_id":"DANGLING","target":"exhibit:E1","operation":"DELETE"}],"expected":{"route":"WAIT_EXTERNAL_REVIEW","run_technical_status":"TECHNICAL_REVIEW_REQUIRED","artifact_technical_status":"TECHNICAL_REVIEW_REQUIRED","legal_readiness":"LAWYER_REVIEW_REQUIRED","expected_invariant_results":{"V15":"FAIL","V17":"FAIL"},"expected_reason_codes":["REFERENCE_DANGLING"]}}
@@ -0,0 +1 @@
{"schema_version":"stage2_s2_40_fixture_payload.v1","header":{"fixture_case_id":"S40-F003","fixture_only":true,"production_admissible":false,"compile_mode":"STRUCTURAL_FIXTURE","oracle_kind":"MUTATION","source_locators":["fixture://s2_40/parts"]},"input":{"expected_groups":["G1","G2"]},"mutations":[{"mutation_id":"MISSING","target":"parts/G2","operation":"DELETE"},{"mutation_id":"DUP","target":"parts/G1","operation":"DUPLICATE"},{"mutation_id":"CROSS","target":"parts/G1/group_id","operation":"REPLACE"}],"expected":{"route":"STOP_TECHNICAL_INCOMPLETE","run_technical_status":"TECHNICAL_INCOMPLETE","artifact_technical_status":"NOT_PRODUCED","legal_readiness":"NOT_ASSESSED","expected_invariant_results":{"V01":"FAIL","V02":"FAIL"},"expected_reason_codes":["PART_SET_NOT_EXACT"]}}
@@ -0,0 +1 @@
{"schema_version":"stage2_s2_40_fixture_payload.v1","header":{"fixture_case_id":"S40-F013","fixture_only":true,"production_admissible":false,"compile_mode":"STRUCTURAL_FIXTURE","oracle_kind":"BARRIER","source_locators":["fixture://s2_40/partial-write"]},"input":{"barrier_last":true},"mutations":[{"mutation_id":"PARTIAL","target":"final/artifact","operation":"TRUNCATE"}],"expected":{"route":"STOP_TECHNICAL_INCOMPLETE","run_technical_status":"TECHNICAL_INCOMPLETE","artifact_technical_status":"NOT_PRODUCED","legal_readiness":"NOT_ASSESSED","expected_invariant_results":{"V14":"FAIL"},"expected_reason_codes":["READBACK_MISMATCH_NO_FINAL_BARRIER"]}}
@@ -0,0 +1,213 @@
{
"schema_version": "stage2_s2_40_regression_manifest.v1",
"fixture_only": true,
"production_admissible": false,
"compile_mode": "STRUCTURAL_FIXTURE",
"rows": [
{
"fixture_case_id": "S40-F001",
"path": "tests/fixtures/s2_40/valid_full_candidate_and_commit.json",
"raw_sha256": "e98e8dc55ab60f8f875ad2f58c1aec35eb1da3882371c22c3e232e0e9ae46c2f",
"oracle_kind": "NORMAL",
"expected_route": "PACKAGE_COMMITTED",
"expected_invariant_ids": [
"V01",
"V18"
]
},
{
"fixture_case_id": "S40-F002",
"path": "tests/fixtures/s2_40/valid_status_only_diagnostic.json",
"raw_sha256": "5676088f5d79168cbae5e1481da4b7cfd9241d06c935378e06dd2af56aae6285",
"oracle_kind": "BARRIER",
"expected_route": "STOP_TECHNICAL_INCOMPLETE",
"expected_invariant_ids": [
"V01"
]
},
{
"fixture_case_id": "S40-F003",
"path": "tests/fixtures/s2_40/part_set_missing_duplicate_or_cross_group.json",
"raw_sha256": "379273497ee23d4a515135771ba4d3bb5ff0e38325ad40eb4e0a0008cd6b88f4",
"oracle_kind": "MUTATION",
"expected_route": "STOP_TECHNICAL_INCOMPLETE",
"expected_invariant_ids": [
"V01",
"V02"
]
},
{
"fixture_case_id": "S40-F004",
"path": "tests/fixtures/s2_40/renderer_ast_slot_branch_mutations.json",
"raw_sha256": "e70ecac4e71de962dfe8bb025a42c73c7c03cfba32c29319523d19f49e8260d0",
"oracle_kind": "MUTATION",
"expected_route": "STOP_TECHNICAL_INCOMPLETE",
"expected_invariant_ids": [
"V10",
"V18"
]
},
{
"fixture_case_id": "S40-F005",
"path": "tests/fixtures/s2_40/relief_cause_crossmatch_mutations.json",
"raw_sha256": "e8d148fef61920039e36abd0cfb771cc6e2fe3aa1a9cc0b0b0502c38ddf70567",
"oracle_kind": "MUTATION",
"expected_route": "WAIT_EXTERNAL_REVIEW",
"expected_invariant_ids": [
"V09",
"V11",
"V18"
]
},
{
"fixture_case_id": "S40-F006",
"path": "tests/fixtures/s2_40/v01_v18_invariant_matrix.json",
"raw_sha256": "e4c0a5476647fa1860cd685a15aad6d465a36b4f6b648c8e2a066c8747780eb8",
"oracle_kind": "MUTATION",
"expected_route": "CONTRACT_TEST_ONLY",
"expected_invariant_ids": [
"V01",
"V02",
"V03",
"V04",
"V05",
"V06",
"V07",
"V08",
"V09",
"V10",
"V11",
"V12",
"V13",
"V14",
"V15",
"V16",
"V17",
"V18"
]
},
{
"fixture_case_id": "S40-F007",
"path": "tests/fixtures/s2_40/cost_provisional_execution_numbering.json",
"raw_sha256": "17c380492f5bc56ecf675cf9683784b2e463241c7d0589b7b496e7a381145c9b",
"oracle_kind": "MUTATION",
"expected_route": "WAIT_EXTERNAL_REVIEW",
"expected_invariant_ids": [
"V10",
"V18"
]
},
{
"fixture_case_id": "S40-F008",
"path": "tests/fixtures/s2_40/exhibit_object_party_title_completeness.json",
"raw_sha256": "40045822f45b2a57805504744e751ee420a6187d0790d5a0f442f529ffedcf7e",
"oracle_kind": "MUTATION",
"expected_route": "WAIT_EXTERNAL_REVIEW",
"expected_invariant_ids": [
"V15",
"V17"
]
},
{
"fixture_case_id": "S40-F009",
"path": "tests/fixtures/s2_40/review_policy_state_aggregation.json",
"raw_sha256": "953fc301703ff353de4df3cf46ed4e90b6bf4ce8268b08705e16151ffc8c3a21",
"oracle_kind": "STATE",
"expected_route": "WAIT_EXTERNAL_REVIEW",
"expected_invariant_ids": [
"V18"
]
},
{
"fixture_case_id": "S40-F010",
"path": "tests/fixtures/s2_40/review_receipt_missing_or_invalid.json",
"raw_sha256": "a88645be90a9e0943358d83f7ea105193dd4b4dfebea4519702a17f69615dc65",
"oracle_kind": "STATE",
"expected_route": "WAIT_EXTERNAL_REVIEW",
"expected_invariant_ids": [
"V14"
]
},
{
"fixture_case_id": "S40-F011",
"path": "tests/fixtures/s2_40/review_receipt_approve_resume.json",
"raw_sha256": "c5b84e34358761750e8e9e7666de6532e0f22a31f32bf027f24efb256a1af5d5",
"oracle_kind": "STATE",
"expected_route": "PACKAGE_COMMITTED",
"expected_invariant_ids": [
"V14"
]
},
{
"fixture_case_id": "S40-F012",
"path": "tests/fixtures/s2_40/review_receipt_content_change_supersede.json",
"raw_sha256": "400d4aeb455e5c3ec26c75a552ea91e9af79cb2329998caa1ad72d1be18da8e7",
"oracle_kind": "STATE",
"expected_route": "RESTART_FROM_S2_30",
"expected_invariant_ids": [
"V14"
]
},
{
"fixture_case_id": "S40-F013",
"path": "tests/fixtures/s2_40/partial_write_readback_barrier.json",
"raw_sha256": "467387c12a4cc6469d243de9f0a7948276adb558a99b3b661ccd74a5d17629cf",
"oracle_kind": "BARRIER",
"expected_route": "STOP_TECHNICAL_INCOMPLETE",
"expected_invariant_ids": [
"V14"
]
},
{
"fixture_case_id": "S40-F014",
"path": "tests/fixtures/s2_40/same_binding_idempotence_and_commit_conflict.json",
"raw_sha256": "5536793236fa44da601dc8cf65d94dac32b18ebc2e8dc525a6df92106add57ad",
"oracle_kind": "BARRIER",
"expected_route": "STOP_TECHNICAL_INCOMPLETE",
"expected_invariant_ids": [
"V14"
]
},
{
"fixture_case_id": "S40-F015",
"path": "tests/fixtures/s2_40/candidate_digest_noncycle.json",
"raw_sha256": "74885602909bd19ca1678de781cac26afd34c2f386e98fc0370fd6ff6fb7b8bf",
"oracle_kind": "DIGEST",
"expected_route": "CONTRACT_TEST_ONLY",
"expected_invariant_ids": [
"V14"
]
}
],
"test_sources": [
{
"path": "tests/s2_40/test_agent_and_inline_parity.py",
"raw_sha256": "04cc4a14790eceea6ec8a9331212ca6e767ef96994b5b26483392d23145417ae"
},
{
"path": "tests/s2_40/test_c40_reduce_and_conservation.py",
"raw_sha256": "f610eced056420277c67294cdfe76d559073d88a6f42d3e8c5dae8f219fa82d9"
},
{
"path": "tests/s2_40/test_c45_closed_render.py",
"raw_sha256": "b7cad96735b1a0158644f41703b4f279fdd8b6bc68438f0d7d773b8415ebb460"
},
{
"path": "tests/s2_40/test_commit_barrier_and_idempotence.py",
"raw_sha256": "714e2f05397d5dcc31159739363f11c9bbaf5a091de55b465e0b474c21f90ea0"
},
{
"path": "tests/s2_40/test_release_closure.py",
"raw_sha256": "89139e0286facd52c3ce91a1c7b382a584dfc3e6bc337fcb55fbc8eed59f5933"
},
{
"path": "tests/s2_40/test_review_state_machine.py",
"raw_sha256": "f4dab9bb651b4a3c818c73162b972c8ac3df0f50fbe056e392a12673139b9b4a"
},
{
"path": "tests/s2_40/test_v01_v18.py",
"raw_sha256": "72be88be1aa9d495b5c9387e45b75e86f44ac76ffe15c04b5ba33ba21fa8943f"
}
],
"manifest_digest": "186e1f1ef33aa20f84004206adcfe0fb3dbfe0c06383411547548d51e20770ab"
}
@@ -0,0 +1 @@
{"schema_version":"stage2_s2_40_fixture_payload.v1","header":{"fixture_case_id":"S40-F005","fixture_only":true,"production_admissible":false,"compile_mode":"STRUCTURAL_FIXTURE","oracle_kind":"MUTATION","source_locators":["fixture://s2_40/crossmatch"]},"input":{"atomic_claim_ids":["A1"]},"mutations":[{"mutation_id":"PARTY","target":"cause/party_ref","operation":"REPLACE"},{"mutation_id":"AMOUNT","target":"cause/amount","operation":"REPLACE"}],"expected":{"route":"WAIT_EXTERNAL_REVIEW","run_technical_status":"TECHNICAL_REVIEW_REQUIRED","artifact_technical_status":"TECHNICAL_REVIEW_REQUIRED","legal_readiness":"LAWYER_REVIEW_REQUIRED","expected_invariant_results":{"V09":"FAIL","V11":"FAIL","V18":"FAIL"},"expected_reason_codes":["RELIEF_CAUSE_MISMATCH"]}}
@@ -0,0 +1,38 @@
{
"schema_version": "stage2_s2_40_fixture_payload.v1",
"header": {
"fixture_case_id": "S40-F004",
"fixture_only": true,
"production_admissible": false,
"compile_mode": "STRUCTURAL_FIXTURE",
"oracle_kind": "MUTATION",
"source_locators": ["fixture://s2_40/renderer"]
},
"input": {
"branch_count": 1,
"unknown_slots": [],
"expected_case_type_catalog_row_count": 137,
"case_type_coverage_legal_approval_status": "PENDING_LEGAL_ADMISSION",
"renderer_legal_approval_status": "PENDING_LEGAL_CONTENT"
},
"mutations": [
{"mutation_id":"ZERO","target":"branch_rows","operation":"CLEAR"},
{"mutation_id":"MULTI","target":"branch_rows","operation":"DUPLICATE"},
{"mutation_id":"UNKNOWN","target":"slots","operation":"ADD_UNKNOWN"},
{"mutation_id":"STALE_HASH","target":"renderer_branch.raw_sha256","operation":"SUBSTITUTE_HASH"},
{"mutation_id":"FREE_TEXT_FALLBACK","target":"render_mode","operation":"SET_FREE_TEXT"},
{"mutation_id":"LEGACY_STAGE2_PATH","target":"source_path","operation":"SET_V0_TO_V3_PATH"},
{"mutation_id":"EXTERNAL_PY","target":"execution_path","operation":"SET_EXTERNAL_PY"},
{"mutation_id":"DIRECTORY_SCAN","target":"input_resolution","operation":"SET_GLOB_SCAN"},
{"mutation_id":"SECRET_INJECTION","target":"slot_value","operation":"ADD_SECRET_TOKEN"},
{"mutation_id":"COVERAGE_137_ROW_MISSING","target":"case_type_coverage.rows","operation":"DELETE_ONE_ROW"}
],
"expected": {
"route": "STOP_TECHNICAL_INCOMPLETE",
"run_technical_status": "TECHNICAL_INCOMPLETE",
"artifact_technical_status": "NOT_PRODUCED",
"legal_readiness": "NOT_ASSESSED",
"expected_invariant_results": {"V10":"FAIL", "V18":"FAIL"},
"expected_reason_codes": ["CLOSED_RENDERER_REJECTED"]
}
}
@@ -0,0 +1 @@
{"schema_version":"stage2_s2_40_fixture_payload.v1","header":{"fixture_case_id":"S40-F009","fixture_only":true,"production_admissible":false,"compile_mode":"STRUCTURAL_FIXTURE","oracle_kind":"STATE","source_locators":["fixture://s2_40/review-policy"]},"input":{"policy_status":"PENDING_LEGAL_CONTENT"},"mutations":[],"expected":{"route":"WAIT_EXTERNAL_REVIEW","run_technical_status":"CONSISTENT","artifact_technical_status":"CONSISTENT","legal_readiness":"LAWYER_REVIEW_REQUIRED","expected_invariant_results":{"V18":"PASS"},"expected_reason_codes":["REVIEW_POLICY_NOT_APPROVED"]}}
@@ -0,0 +1,33 @@
{
"schema_version": "stage2_s2_40_fixture_payload.v1",
"header": {
"fixture_case_id": "S40-F011",
"fixture_only": true,
"production_admissible": false,
"compile_mode": "STRUCTURAL_FIXTURE",
"oracle_kind": "STATE",
"source_locators": ["fixture://s2_40/receipt-approve"]
},
"input": {
"disposition": "APPROVE_AS_IS",
"candidate_bytes_unchanged": true,
"rerender_call_count_on_resume": 0,
"external_verification_status": "VERIFIED_BY_EXTERNAL_ADAPTER",
"phase_sequence": [
"FREEZE",
"AWAITING_EXTERNAL_REVIEW",
"RESUME_VALIDATE",
"READY_TO_COMMIT",
"COMMITTED"
]
},
"mutations": [],
"expected": {
"route": "PACKAGE_COMMITTED",
"run_technical_status": "CONSISTENT",
"artifact_technical_status": "CONSISTENT",
"legal_readiness": "LAWYER_REVIEW_REQUIRED",
"expected_invariant_results": {"V14": "PASS"},
"expected_reason_codes": ["FIXTURE_COMMIT_NOT_FILING_APPROVAL"]
}
}
@@ -0,0 +1 @@
{"schema_version":"stage2_s2_40_fixture_payload.v1","header":{"fixture_case_id":"S40-F012","fixture_only":true,"production_admissible":false,"compile_mode":"STRUCTURAL_FIXTURE","oracle_kind":"STATE","source_locators":["fixture://s2_40/receipt-change"]},"input":{"disposition":"CONTENT_CHANGE_REQUIRED","change_scope":"DRAFTING_TEXT_ATOM"},"mutations":[],"expected":{"route":"RESTART_FROM_S2_30","run_technical_status":"CONSISTENT","artifact_technical_status":"CONSISTENT","legal_readiness":"LAWYER_REVIEW_REQUIRED","expected_invariant_results":{"V14":"PASS"},"expected_reason_codes":["CANDIDATE_SUPERSEDED_NO_IN_PLACE_EDIT"]}}
@@ -0,0 +1 @@
{"schema_version":"stage2_s2_40_fixture_payload.v1","header":{"fixture_case_id":"S40-F010","fixture_only":true,"production_admissible":false,"compile_mode":"STRUCTURAL_FIXTURE","oracle_kind":"STATE","source_locators":["fixture://s2_40/receipt-invalid"]},"input":{"required_receipts":["STANDARD_ATTORNEY_REVIEW"]},"mutations":[{"mutation_id":"WRONG_DIGEST","target":"receipt/candidate_content_digest","operation":"REPLACE"}],"expected":{"route":"WAIT_EXTERNAL_REVIEW","run_technical_status":"CONSISTENT","artifact_technical_status":"CONSISTENT","legal_readiness":"LAWYER_REVIEW_REQUIRED","expected_invariant_results":{"V14":"PASS"},"expected_reason_codes":["RECEIPT_MISSING_OR_INVALID"]}}
@@ -0,0 +1 @@
{"schema_version":"stage2_s2_40_fixture_payload.v1","header":{"fixture_case_id":"S40-F014","fixture_only":true,"production_admissible":false,"compile_mode":"STRUCTURAL_FIXTURE","oracle_kind":"BARRIER","source_locators":["fixture://s2_40/idempotence"]},"input":{"same_binding_same_bytes":"IDEMPOTENT_SUCCESS"},"mutations":[{"mutation_id":"CONFLICT","target":"final/path","operation":"WRITE_DIFFERENT_BYTES"}],"expected":{"route":"STOP_TECHNICAL_INCOMPLETE","run_technical_status":"TECHNICAL_INCOMPLETE","artifact_technical_status":"NOT_PRODUCED","legal_readiness":"NOT_ASSESSED","expected_invariant_results":{"V14":"FAIL"},"expected_reason_codes":["NO_OVERWRITE_CONFLICT"]}}
@@ -0,0 +1,62 @@
{
"schema_version": "stage2_s2_40_fixture_payload.v1",
"header": {
"fixture_case_id": "S40-F006",
"fixture_only": true,
"production_admissible": false,
"compile_mode": "STRUCTURAL_FIXTURE",
"oracle_kind": "MUTATION",
"source_locators": [
"fixture://s2_40/v01-v18",
"discrepancy_report_1.md",
"discrepancy_report_2.md",
"discrepancy_report_3.md",
"discrepancy_report_4.md",
"improvement_merged.md"
]
},
"input": {
"invariant_ids": [
"V01", "V02", "V03", "V04", "V05", "V06", "V07", "V08", "V09",
"V10", "V11", "V12", "V13", "V14", "V15", "V16", "V17", "V18"
],
"normal_oracle": {
"evaluable": true,
"expected": {"contract_state": "BOUND"},
"observed": {"contract_state": "BOUND"},
"evaluation_status": "PASS"
}
},
"mutations": [
{"mutation_id":"V01-CONTRADICTION-OR-ABSENCE","target":"upstream_allowlist.path_hash_schema_producer","operation":"SUBSTITUTE_HASH_OR_DELETE_ROW","source_finding_ids":["DR1-STAGE1_TO_STAGE2_FACT_LOSS"],"contradiction":{"observed":"HASH_DRIFT","evaluation_status":"FAIL","reason_code":"V01_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V01_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V02-CONTRADICTION-OR-ABSENCE","target":"bo_les_ledger_signal_evidence_review_universe","operation":"DROP_OR_CONTRADICT_REVIEW_KEY","source_finding_ids":["IR1-CRITICAL_FACT_CONSERVATION"],"contradiction":{"observed":"MULTISET_MISMATCH","evaluation_status":"FAIL","reason_code":"V02_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V02_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V03-CONTRADICTION-OR-ABSENCE","target":"active_domain_slot_crosswalk_namespace_owner","operation":"CHANGE_OR_REMOVE_NAMESPACE_OWNER","source_finding_ids":["IR2-DOMAIN_CONFIG_COMPLETENESS"],"contradiction":{"observed":"OWNER_MISMATCH","evaluation_status":"FAIL","reason_code":"V03_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V03_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V04-CONTRADICTION-OR-ABSENCE","target":"defense_opposing_fact_rebuttal_evidence_chain","operation":"REVERSE_POLARITY_OR_REMOVE_REBUTTAL","source_finding_ids":["IR3-DEFENSE_CHAIN_LOSS"],"contradiction":{"observed":"POLARITY_CONFLICT","evaluation_status":"FAIL","reason_code":"V04_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V04_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V05-CONTRADICTION-OR-ABSENCE","target":"cluster_dependency_precondition_incompatibility","operation":"VIOLATE_OR_REMOVE_PRECONDITION","source_finding_ids":["IM-CLAIM_GROUP_RELATION"],"contradiction":{"observed":"DEPENDENCY_VIOLATED","evaluation_status":"FAIL","reason_code":"V05_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V05_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V06-CONTRADICTION-OR-ABSENCE","target":"atomic_claim.case_type_id.sub_rule_id","operation":"DUPLICATE_MATCH_OR_REMOVE_BINDING","source_finding_ids":["EVAL-M15-CASE-TYPE-PREDICATE"],"contradiction":{"observed":"MULTI_MATCH","evaluation_status":"FAIL","reason_code":"V06_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V06_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V07-CONTRADICTION-OR-ABSENCE","target":"calculator_receipt.operand.law_value","operation":"SUBSTITUTE_UNRECEIPTED_VALUE_OR_REMOVE_RECEIPT","source_finding_ids":["DR3-ACTIO-CALCULATION-LOSS"],"contradiction":{"observed":"UNRECEIPTED_VALUE","evaluation_status":"FAIL","reason_code":"V07_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V07_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V08-CONTRADICTION-OR-ABSENCE","target":"same_recovery_relation_partial_claim_disposition","operation":"DUPLICATE_RECOVERY_OR_REMOVE_RELATION","source_finding_ids":["IM-SAME-RECOVERY-DUPLICATE"],"contradiction":{"observed":"DUPLICATE_RECOVERY","evaluation_status":"FAIL","reason_code":"V08_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V08_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V09-CONTRADICTION-OR-ABSENCE","target":"relief_party_object_amount_period","operation":"ALTER_AMOUNT_OR_REMOVE_FROZEN_PLAN","source_finding_ids":["DR4-RELIEF-OBJECT-DATE-MISMATCH"],"contradiction":{"observed":"PLAN_RELIEF_MISMATCH","evaluation_status":"FAIL","reason_code":"V09_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V09_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V10-CONTRADICTION-OR-ABSENCE","target":"cost_provisional_numbering_annex_order_template_scope","operation":"PERMUTE_ORDER_OR_REMOVE_RENDERER_BRANCH","source_finding_ids":["IM-RELIEF-FORM-NUMBERING"],"contradiction":{"observed":"CLOSED_TEMPLATE_DRIFT","evaluation_status":"FAIL","reason_code":"V10_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V10_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V11-CONTRADICTION-OR-ABSENCE","target":"relief_cause_claim_party_amount_interest_counterperformance","operation":"ALTER_PARTY_OR_REMOVE_CAUSE_LINK","source_finding_ids":["DR1-RELIEF-CAUSE-CROSSMATCH"],"contradiction":{"observed":"RELIEF_CAUSE_MISMATCH","evaluation_status":"FAIL","reason_code":"V11_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V11_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V12-CONTRADICTION-OR-ABSENCE","target":"corpus_snapshot_locator_approval_isolation_crosswalk","operation":"SUBSTITUTE_CORPUS_HASH_OR_REMOVE_LOCATOR","source_finding_ids":["EVAL-M16-CORPUS-NAMESPACE"],"contradiction":{"observed":"CORPUS_HASH_DRIFT","evaluation_status":"FAIL","reason_code":"V12_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V12_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V13-CONTRADICTION-OR-ABSENCE","target":"authority_temporal_addenda_negative_treatment_law_value","operation":"EXPIRE_AUTHORITY_OR_REMOVE_TEMPORAL_SCOPE","source_finding_ids":["EVAL-M13-LAW-VALUE-SEAL"],"contradiction":{"observed":"AUTHORITY_TEMPORAL_DRIFT","evaluation_status":"FAIL","reason_code":"V13_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V13_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V14-CONTRADICTION-OR-ABSENCE","target":"candidate_validation_review_status_intent_readback_commit_barrier_graph","operation":"INTRODUCE_BACKLINK_OR_REMOVE_GRAPH_EDGE","source_finding_ids":["EVAL-M18-NONCYCLIC-SEAL"],"contradiction":{"observed":"DIGEST_CYCLE","evaluation_status":"FAIL","reason_code":"V14_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V14_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V15-CONTRADICTION-OR-ABSENCE","target":"atom_provenance_fact_evidence","operation":"INJECT_UNSOURCED_FACT_OR_REMOVE_EVIDENCE_REF","source_finding_ids":["EVAL-C1-CAUSE-ATOM-PROVENANCE"],"contradiction":{"observed":"UNSOURCED_FACT","evaluation_status":"FAIL","reason_code":"V15_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V15_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V16-CONTRADICTION-OR-ABSENCE","target":"claim_option_partition","operation":"OVERLAP_BUCKETS_OR_REMOVE_OPTION","source_finding_ids":["IR4-OPTION-SILENT-LOSS"],"contradiction":{"observed":"PARTITION_OVERLAP","evaluation_status":"FAIL","reason_code":"V16_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V16_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V17-CONTRADICTION-OR-ABSENCE","target":"party_title_liability_object_exhibit_tokens","operation":"CHANGE_PARTY_TITLE_OR_REMOVE_OBJECT_TOKEN","source_finding_ids":["DR2-OBJECT-EXHIBIT-COMPLETENESS"],"contradiction":{"observed":"OBJECT_TOKEN_MISMATCH","evaluation_status":"FAIL","reason_code":"V17_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V17_ABSENT_UNEVALUABLE"}},
{"mutation_id":"V18-CONTRADICTION-OR-ABSENCE","target":"closed_ast_independent_rerender_frozen_dependencies","operation":"ALTER_RENDERER_BRANCH_OR_REMOVE_RERENDER_EVIDENCE","source_finding_ids":["IM-CLOSED-RENDERER-INDEPENDENCE"],"contradiction":{"observed":"RERENDER_BYTES_MISMATCH","evaluation_status":"FAIL","reason_code":"V18_CONTRADICTION"},"absence":{"observed":null,"evaluation_status":"UNEVALUABLE","reason_code":"V18_ABSENT_UNEVALUABLE"}}
],
"expected": {
"route": "CONTRACT_TEST_ONLY",
"run_technical_status": "TECHNICAL_REVIEW_REQUIRED",
"artifact_technical_status": "TECHNICAL_REVIEW_REQUIRED",
"legal_readiness": "LAWYER_REVIEW_REQUIRED",
"expected_invariant_results": {
"V01":"PASS", "V02":"PASS", "V03":"PASS", "V04":"PASS", "V05":"PASS", "V06":"PASS",
"V07":"PASS", "V08":"PASS", "V09":"PASS", "V10":"PASS", "V11":"PASS", "V12":"PASS",
"V13":"PASS", "V14":"PASS", "V15":"PASS", "V16":"PASS", "V17":"PASS", "V18":"PASS"
},
"expected_reason_codes": ["MATRIX_ORACLE"]
}
}
@@ -0,0 +1,40 @@
{
"schema_version": "stage2_s2_40_fixture_payload.v1",
"header": {
"fixture_case_id": "S40-F001",
"fixture_only": true,
"production_admissible": false,
"compile_mode": "STRUCTURAL_FIXTURE",
"oracle_kind": "NORMAL",
"source_locators": ["fixture://s2_40/valid"]
},
"input": {
"all_v_pass": true,
"legal_assets_approved": false,
"review_receipt_external_verification_status": "VERIFIED_BY_EXTERNAL_ADAPTER",
"phase_sequence": [
"FREEZE",
"AWAITING_EXTERNAL_REVIEW",
"RESUME_VALIDATE",
"READY_TO_COMMIT",
"COMMITTED"
],
"candidate_bytes_reused_on_resume": true,
"rerender_call_count_on_resume": 0,
"logical_commit_order": [
"commit/commit_intent.json",
"final/*-EXPLICIT-ALLOWLIST-ONLY",
"commit/stage2_commit_result.json",
"control/run_status.json"
]
},
"mutations": [],
"expected": {
"route": "PACKAGE_COMMITTED",
"run_technical_status": "CONSISTENT",
"artifact_technical_status": "CONSISTENT",
"legal_readiness": "LAWYER_REVIEW_REQUIRED",
"expected_invariant_results": {"V01": "PASS", "V18": "PASS"},
"expected_reason_codes": ["STRUCTURAL_FIXTURE_NOT_PRODUCTION"]
}
}
@@ -0,0 +1 @@
{"schema_version":"stage2_s2_40_fixture_payload.v1","header":{"fixture_case_id":"S40-F002","fixture_only":true,"production_admissible":false,"compile_mode":"STRUCTURAL_FIXTURE","oracle_kind":"BARRIER","source_locators":["fixture://s2_40/status-only"]},"input":{"exact_paths":["ingress/ingress_status.json","ingress/technical_diagnostic.json","ingress/stage1_input_manifest.json","ingress/intake_report.json","review/issue_ledger.base.json"]},"mutations":[],"expected":{"route":"STOP_TECHNICAL_INCOMPLETE","run_technical_status":"TECHNICAL_INCOMPLETE","artifact_technical_status":"NOT_PRODUCED","legal_readiness":"NOT_ASSESSED","expected_invariant_results":{"V01":"PASS"},"expected_reason_codes":["STATUS_ONLY_EXACT_FIVE"]}}
@@ -561,7 +561,7 @@ class ClusterAndBundleTests(unittest.TestCase):
self.assertIn("producer_emits_field: false", cache_text) self.assertIn("producer_emits_field: false", cache_text)
self.assertIn("S2_10", cache_text) self.assertIn("S2_10", cache_text)
def test_s2_40_status_only_is_deterministic_non_llm_stub(self) -> None: def test_s2_40_is_implemented_deterministic_non_llm_finalizer(self) -> None:
workflow = yaml.safe_load( workflow = yaml.safe_load(
(ROOT / "workflows/S2_40_final_review_render_and_commit.yml").read_text( (ROOT / "workflows/S2_40_final_review_render_and_commit.yml").read_text(
encoding="utf-8" encoding="utf-8"
@@ -569,16 +569,18 @@ class ClusterAndBundleTests(unittest.TestCase):
) )
stage = workflow["Agent"]["Stages"][0] stage = workflow["Agent"]["Stages"][0]
task = stage["tasks"][0] task = stage["tasks"][0]
self.assertEqual(
workflow["Agent"]["metadata"]["implementation_status"],
"IMPLEMENTED_OFFLINE_CONTRACT_LIVE_ADMISSION_PENDING",
)
self.assertEqual(task["execution_class"], "NON-LLM-DETERMINISTIC") self.assertEqual(task["execution_class"], "NON-LLM-DETERMINISTIC")
self.assertEqual(task["implementation_status"], "STUB_NOT_IMPLEMENTED") self.assertEqual(task["task_name"], "Task_S2_40_deterministic_finalizer")
self.assertFalse(task["invocation_allowed"]) self.assertEqual(task["mcp"], "code-executor")
self.assertEqual(task["tool_name"], "run_code")
self.assertNotIn("prompts", task) self.assertNotIn("prompts", task)
self.assertNotIn("tools", stage) self.assertNotIn("tools", stage)
self.assertFalse(stage["prohibitions"]["llm_call_allowed"]) self.assertFalse(task["llm_call_allowed"])
self.assertEqual( self.assertFalse(task["shell_or_subprocess_allowed"])
stage["handoff_contract"]["final_status_fields"]["legal_readiness"],
["NOT_ASSESSED"],
)
expected_inputs = [ expected_inputs = [
"ingress/ingress_status.json", "ingress/ingress_status.json",
"ingress/technical_diagnostic.json", "ingress/technical_diagnostic.json",
@@ -586,18 +588,17 @@ class ClusterAndBundleTests(unittest.TestCase):
"ingress/intake_report.json", "ingress/intake_report.json",
"review/issue_ledger.base.json", "review/issue_ledger.base.json",
] ]
self.assertEqual(stage["handoff_contract"]["exact_input_count"], 5) entry = stage["entry_contract"]
self.assertEqual(stage["handoff_contract"]["exact_inputs"], expected_inputs) self.assertEqual(entry["accepted_routes"], ["TO_S2_40", "TO_S2_40_STATUS_ONLY"])
self.assertEqual(task["exact_input_files"], expected_inputs) self.assertEqual(entry["status_only_exact_input_count"], 5)
self.assertFalse(stage["handoff_contract"]["additional_input_allowed"]) self.assertEqual(entry["status_only_exact_inputs"], expected_inputs)
self.assertFalse(entry["status_only_additional_input_allowed"])
self.assertEqual( self.assertEqual(
workflow["Agent"]["metadata"]["final_status_single_writer"], workflow["Agent"]["metadata"]["final_status_single_writer"],
"S2_40", "S2_40",
) )
self.assertFalse( self.assertEqual(stage["output_contract"]["final_barrier_path"], "control/run_status.json")
stage["prohibitions"]["final_status_writer_other_than_s2_40_allowed"] self.assertTrue(stage["output_contract"]["barrier_written_last"])
)
self.assertEqual(stage["prohibitions"]["output_paths"], ["control/run_status.json"])
def test_release_oracle_verifies_active_executor_cross_hashes(self) -> None: def test_release_oracle_verifies_active_executor_cross_hashes(self) -> None:
release_path = ROOT / "manifest/stage2_release.json" release_path = ROOT / "manifest/stage2_release.json"
@@ -561,7 +561,7 @@ class ClusterAndBundleTests(unittest.TestCase):
self.assertIn("producer_emits_field: false", cache_text) self.assertIn("producer_emits_field: false", cache_text)
self.assertIn("S2_10", cache_text) self.assertIn("S2_10", cache_text)
def test_s2_40_status_only_is_deterministic_non_llm_stub(self) -> None: def test_s2_40_is_implemented_deterministic_non_llm_finalizer(self) -> None:
workflow = yaml.safe_load( workflow = yaml.safe_load(
(ROOT / "workflows/S2_40_final_review_render_and_commit.yml").read_text( (ROOT / "workflows/S2_40_final_review_render_and_commit.yml").read_text(
encoding="utf-8" encoding="utf-8"
@@ -569,16 +569,18 @@ class ClusterAndBundleTests(unittest.TestCase):
) )
stage = workflow["Agent"]["Stages"][0] stage = workflow["Agent"]["Stages"][0]
task = stage["tasks"][0] task = stage["tasks"][0]
self.assertEqual(
workflow["Agent"]["metadata"]["implementation_status"],
"IMPLEMENTED_OFFLINE_CONTRACT_LIVE_ADMISSION_PENDING",
)
self.assertEqual(task["execution_class"], "NON-LLM-DETERMINISTIC") self.assertEqual(task["execution_class"], "NON-LLM-DETERMINISTIC")
self.assertEqual(task["implementation_status"], "STUB_NOT_IMPLEMENTED") self.assertEqual(task["task_name"], "Task_S2_40_deterministic_finalizer")
self.assertFalse(task["invocation_allowed"]) self.assertEqual(task["mcp"], "code-executor")
self.assertEqual(task["tool_name"], "run_code")
self.assertNotIn("prompts", task) self.assertNotIn("prompts", task)
self.assertNotIn("tools", stage) self.assertNotIn("tools", stage)
self.assertFalse(stage["prohibitions"]["llm_call_allowed"]) self.assertFalse(task["llm_call_allowed"])
self.assertEqual( self.assertFalse(task["shell_or_subprocess_allowed"])
stage["handoff_contract"]["final_status_fields"]["legal_readiness"],
["NOT_ASSESSED"],
)
expected_inputs = [ expected_inputs = [
"ingress/ingress_status.json", "ingress/ingress_status.json",
"ingress/technical_diagnostic.json", "ingress/technical_diagnostic.json",
@@ -586,18 +588,17 @@ class ClusterAndBundleTests(unittest.TestCase):
"ingress/intake_report.json", "ingress/intake_report.json",
"review/issue_ledger.base.json", "review/issue_ledger.base.json",
] ]
self.assertEqual(stage["handoff_contract"]["exact_input_count"], 5) entry = stage["entry_contract"]
self.assertEqual(stage["handoff_contract"]["exact_inputs"], expected_inputs) self.assertEqual(entry["accepted_routes"], ["TO_S2_40", "TO_S2_40_STATUS_ONLY"])
self.assertEqual(task["exact_input_files"], expected_inputs) self.assertEqual(entry["status_only_exact_input_count"], 5)
self.assertFalse(stage["handoff_contract"]["additional_input_allowed"]) self.assertEqual(entry["status_only_exact_inputs"], expected_inputs)
self.assertFalse(entry["status_only_additional_input_allowed"])
self.assertEqual( self.assertEqual(
workflow["Agent"]["metadata"]["final_status_single_writer"], workflow["Agent"]["metadata"]["final_status_single_writer"],
"S2_40", "S2_40",
) )
self.assertFalse( self.assertEqual(stage["output_contract"]["final_barrier_path"], "control/run_status.json")
stage["prohibitions"]["final_status_writer_other_than_s2_40_allowed"] self.assertTrue(stage["output_contract"]["barrier_written_last"])
)
self.assertEqual(stage["prohibitions"]["output_paths"], ["control/run_status.json"])
def test_release_oracle_verifies_active_executor_cross_hashes(self) -> None: def test_release_oracle_verifies_active_executor_cross_hashes(self) -> None:
release_path = ROOT / "manifest/stage2_release.json" release_path = ROOT / "manifest/stage2_release.json"
@@ -572,7 +572,7 @@ class FailureAndAtomicPublishTests(unittest.TestCase):
relative = s2._safe_relative_path(row["path"]).as_posix() relative = s2._safe_relative_path(row["path"]).as_posix()
self.assertIn( self.assertIn(
PurePosixPath(relative).parent.as_posix(), PurePosixPath(relative).parent.as_posix(),
{"tests/s2_00", "tests/s2_20"}, {"tests/s2_00", "tests/s2_20", "tests/s2_40"},
) )
self.assertTrue((ROOT / relative).is_file(), relative) self.assertTrue((ROOT / relative).is_file(), relative)
observed_sha256 = hashlib.sha256((ROOT / relative).read_bytes()).hexdigest() observed_sha256 = hashlib.sha256((ROOT / relative).read_bytes()).hexdigest()
@@ -572,7 +572,7 @@ class FailureAndAtomicPublishTests(unittest.TestCase):
relative = s2._safe_relative_path(row["path"]).as_posix() relative = s2._safe_relative_path(row["path"]).as_posix()
self.assertIn( self.assertIn(
PurePosixPath(relative).parent.as_posix(), PurePosixPath(relative).parent.as_posix(),
{"tests/s2_00", "tests/s2_20"}, {"tests/s2_00", "tests/s2_20", "tests/s2_40"},
) )
self.assertTrue((ROOT / relative).is_file(), relative) self.assertTrue((ROOT / relative).is_file(), relative)
observed_sha256 = hashlib.sha256((ROOT / relative).read_bytes()).hexdigest() observed_sha256 = hashlib.sha256((ROOT / relative).read_bytes()).hexdigest()
@@ -2,10 +2,13 @@ from __future__ import annotations
import copy import copy
import hashlib import hashlib
import importlib.util
import json import json
from pathlib import Path from pathlib import Path
import sys import sys
import tempfile
import unittest import unittest
from unittest import mock
import yaml import yaml
@@ -16,6 +19,21 @@ sys.path.insert(0, str(ROOT))
from offline_build import validate_s2_10_contract as contract # noqa: E402 from offline_build import validate_s2_10_contract as contract # noqa: E402
PROJECTION_BUILDER_PATH = ROOT / "offline_build" / "build_s2_10_agent_projection.py"
def load_module(name: str, path: Path):
spec = importlib.util.spec_from_file_location(name, path)
if spec is None or spec.loader is None:
raise RuntimeError(path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
projection_builder = load_module("s2_10_projection_builder", PROJECTION_BUILDER_PATH)
CAPABILITIES = { CAPABILITIES = {
"HOST_ATOMIC_SINGLE_FLIGHT_CAS_V1", "HOST_ATOMIC_SINGLE_FLIGHT_CAS_V1",
"AGENTBACKEND_MAP_SOURCE_ITEMS_V1", "AGENTBACKEND_MAP_SOURCE_ITEMS_V1",
@@ -34,6 +52,59 @@ def load_json(path: Path) -> dict:
class ReleaseAdapterRetryTests(unittest.TestCase): class ReleaseAdapterRetryTests(unittest.TestCase):
def test_default_check_uses_cumulative_parent_and_downstream_oracles(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
prerequisite_path = root / "projection.yml"
parent_path = root / "stage2_release.json"
child_path = root / "s2_10_release.json"
prerequisite_path.write_bytes(b"projection\n")
parent_path.write_bytes(b"parent\n")
child_path.write_bytes(b"child\n")
prerequisite = {prerequisite_path: b"projection\n"}
parent = {parent_path: b"parent\n"}
child = {child_path: b"child\n"}
with (
mock.patch.object(
projection_builder,
"prerequisite_outputs",
return_value=(prerequisite, {"phase": "prerequisite"}),
),
mock.patch.object(
projection_builder,
"cumulative_parent_outputs",
return_value=(parent, {"phase": "cumulative_parent"}),
),
mock.patch.object(
projection_builder,
"cumulative_child_outputs",
return_value=(child, {"phase": "downstream_child"}),
),
mock.patch.object(
projection_builder,
"child_only_outputs",
side_effect=AssertionError("observed stale child oracle invoked"),
) as observed_child,
mock.patch.object(
projection_builder,
"expected_outputs",
side_effect=AssertionError("obsolete S2_10-only parent oracle invoked"),
) as obsolete,
):
result = projection_builder.check()
self.assertEqual(result["status"], "S2_10_CUMULATIVE_PACKAGE_CHECK_PASS")
self.assertEqual(len(result["checked_paths"]), 3)
obsolete.assert_not_called()
observed_child.assert_not_called()
parent_path.write_bytes(b"stale-parent\n")
with self.assertRaises(projection_builder.BuildError) as caught:
projection_builder.check()
self.assertEqual(caught.exception.code, "OFFLINE_PACKAGE_DRIFT")
self.assertIn(parent_path.as_posix(), caught.exception.detail)
obsolete.assert_not_called()
observed_child.assert_not_called()
def test_binding_and_all_external_receipts_are_honestly_pending(self) -> None: def test_binding_and_all_external_receipts_are_honestly_pending(self) -> None:
binding = yaml.safe_load((ROOT / "deployment" / "stage2_s2_10_llm_binding.yml").read_text()) binding = yaml.safe_load((ROOT / "deployment" / "stage2_s2_10_llm_binding.yml").read_text())
self.assertEqual(binding["binding_status"], "PENDING_EXTERNAL_PLATFORM_BINDING") self.assertEqual(binding["binding_status"], "PENDING_EXTERNAL_PLATFORM_BINDING")
@@ -2,10 +2,13 @@ from __future__ import annotations
import copy import copy
import hashlib import hashlib
import importlib.util
import json import json
from pathlib import Path from pathlib import Path
import sys import sys
import tempfile
import unittest import unittest
from unittest import mock
import yaml import yaml
@@ -16,6 +19,21 @@ sys.path.insert(0, str(ROOT))
from offline_build import validate_s2_10_contract as contract # noqa: E402 from offline_build import validate_s2_10_contract as contract # noqa: E402
PROJECTION_BUILDER_PATH = ROOT / "offline_build" / "build_s2_10_agent_projection.py"
def load_module(name: str, path: Path):
spec = importlib.util.spec_from_file_location(name, path)
if spec is None or spec.loader is None:
raise RuntimeError(path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
projection_builder = load_module("s2_10_projection_builder", PROJECTION_BUILDER_PATH)
CAPABILITIES = { CAPABILITIES = {
"HOST_ATOMIC_SINGLE_FLIGHT_CAS_V1", "HOST_ATOMIC_SINGLE_FLIGHT_CAS_V1",
"AGENTBACKEND_MAP_SOURCE_ITEMS_V1", "AGENTBACKEND_MAP_SOURCE_ITEMS_V1",
@@ -34,6 +52,59 @@ def load_json(path: Path) -> dict:
class ReleaseAdapterRetryTests(unittest.TestCase): class ReleaseAdapterRetryTests(unittest.TestCase):
def test_default_check_uses_cumulative_parent_and_downstream_oracles(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
prerequisite_path = root / "projection.yml"
parent_path = root / "stage2_release.json"
child_path = root / "s2_10_release.json"
prerequisite_path.write_bytes(b"projection\n")
parent_path.write_bytes(b"parent\n")
child_path.write_bytes(b"child\n")
prerequisite = {prerequisite_path: b"projection\n"}
parent = {parent_path: b"parent\n"}
child = {child_path: b"child\n"}
with (
mock.patch.object(
projection_builder,
"prerequisite_outputs",
return_value=(prerequisite, {"phase": "prerequisite"}),
),
mock.patch.object(
projection_builder,
"cumulative_parent_outputs",
return_value=(parent, {"phase": "cumulative_parent"}),
),
mock.patch.object(
projection_builder,
"cumulative_child_outputs",
return_value=(child, {"phase": "downstream_child"}),
),
mock.patch.object(
projection_builder,
"child_only_outputs",
side_effect=AssertionError("observed stale child oracle invoked"),
) as observed_child,
mock.patch.object(
projection_builder,
"expected_outputs",
side_effect=AssertionError("obsolete S2_10-only parent oracle invoked"),
) as obsolete,
):
result = projection_builder.check()
self.assertEqual(result["status"], "S2_10_CUMULATIVE_PACKAGE_CHECK_PASS")
self.assertEqual(len(result["checked_paths"]), 3)
obsolete.assert_not_called()
observed_child.assert_not_called()
parent_path.write_bytes(b"stale-parent\n")
with self.assertRaises(projection_builder.BuildError) as caught:
projection_builder.check()
self.assertEqual(caught.exception.code, "OFFLINE_PACKAGE_DRIFT")
self.assertIn(parent_path.as_posix(), caught.exception.detail)
obsolete.assert_not_called()
observed_child.assert_not_called()
def test_binding_and_all_external_receipts_are_honestly_pending(self) -> None: def test_binding_and_all_external_receipts_are_honestly_pending(self) -> None:
binding = yaml.safe_load((ROOT / "deployment" / "stage2_s2_10_llm_binding.yml").read_text()) binding = yaml.safe_load((ROOT / "deployment" / "stage2_s2_10_llm_binding.yml").read_text())
self.assertEqual(binding["binding_status"], "PENDING_EXTERNAL_PLATFORM_BINDING") self.assertEqual(binding["binding_status"], "PENDING_EXTERNAL_PLATFORM_BINDING")
@@ -175,6 +175,7 @@ class PublishAndReleaseTest(unittest.TestCase):
self.assertIn("stage_bindings:", text) self.assertIn("stage_bindings:", text)
self.assertEqual(text.count("stage_id: S2_00"), 1) self.assertEqual(text.count("stage_id: S2_00"), 1)
self.assertEqual(text.count("stage_id: S2_20"), 1) self.assertEqual(text.count("stage_id: S2_20"), 1)
has_s2_40 = text.count("stage_id: S2_40") == 1
self.assertIn("embedded_task_bindings:", text) self.assertIn("embedded_task_bindings:", text)
self.assertEqual(text.count("host_stage_id: S2_30"), 1) self.assertEqual(text.count("host_stage_id: S2_30"), 1)
self.assertEqual(text.count("task_name: Task_S2_30_dispatch_planner"), 1) self.assertEqual(text.count("task_name: Task_S2_30_dispatch_planner"), 1)
@@ -183,7 +184,8 @@ class PublishAndReleaseTest(unittest.TestCase):
encoding="utf-8" encoding="utf-8"
) )
) )
self.assertEqual(admission["present_deterministic_stage_ids"], ["S2_00", "S2_20"]) expected_stage_ids = ["S2_00", "S2_20"] + (["S2_40"] if has_s2_40 else [])
self.assertEqual(admission["present_deterministic_stage_ids"], expected_stage_ids)
self.assertEqual( self.assertEqual(
admission["embedded_task_admissions"][0]["execution_unit_id"], admission["embedded_task_admissions"][0]["execution_unit_id"],
"S2_30::Task_S2_30_dispatch_planner", "S2_30::Task_S2_30_dispatch_planner",
@@ -260,6 +262,7 @@ class PublishAndReleaseTest(unittest.TestCase):
_write_json(root / "manifest/case_type_coverage.json", _coverage()) _write_json(root / "manifest/case_type_coverage.json", _coverage())
_write_json(root / "manifest/s2_20_parent_member_paths.json", []) _write_json(root / "manifest/s2_20_parent_member_paths.json", [])
_write_json(root / "manifest/s2_30_parent_member_paths.json", []) _write_json(root / "manifest/s2_30_parent_member_paths.json", [])
_write_json(root / "manifest/s2_40_parent_member_paths.json", [])
report = VALIDATOR.validate_package( report = VALIDATOR.validate_package(
root, root,
root / "manifest/module_manifest.json", root / "manifest/module_manifest.json",
@@ -175,6 +175,7 @@ class PublishAndReleaseTest(unittest.TestCase):
self.assertIn("stage_bindings:", text) self.assertIn("stage_bindings:", text)
self.assertEqual(text.count("stage_id: S2_00"), 1) self.assertEqual(text.count("stage_id: S2_00"), 1)
self.assertEqual(text.count("stage_id: S2_20"), 1) self.assertEqual(text.count("stage_id: S2_20"), 1)
has_s2_40 = text.count("stage_id: S2_40") == 1
self.assertIn("embedded_task_bindings:", text) self.assertIn("embedded_task_bindings:", text)
self.assertEqual(text.count("host_stage_id: S2_30"), 1) self.assertEqual(text.count("host_stage_id: S2_30"), 1)
self.assertEqual(text.count("task_name: Task_S2_30_dispatch_planner"), 1) self.assertEqual(text.count("task_name: Task_S2_30_dispatch_planner"), 1)
@@ -183,7 +184,8 @@ class PublishAndReleaseTest(unittest.TestCase):
encoding="utf-8" encoding="utf-8"
) )
) )
self.assertEqual(admission["present_deterministic_stage_ids"], ["S2_00", "S2_20"]) expected_stage_ids = ["S2_00", "S2_20"] + (["S2_40"] if has_s2_40 else [])
self.assertEqual(admission["present_deterministic_stage_ids"], expected_stage_ids)
self.assertEqual( self.assertEqual(
admission["embedded_task_admissions"][0]["execution_unit_id"], admission["embedded_task_admissions"][0]["execution_unit_id"],
"S2_30::Task_S2_30_dispatch_planner", "S2_30::Task_S2_30_dispatch_planner",
@@ -260,6 +262,7 @@ class PublishAndReleaseTest(unittest.TestCase):
_write_json(root / "manifest/case_type_coverage.json", _coverage()) _write_json(root / "manifest/case_type_coverage.json", _coverage())
_write_json(root / "manifest/s2_20_parent_member_paths.json", []) _write_json(root / "manifest/s2_20_parent_member_paths.json", [])
_write_json(root / "manifest/s2_30_parent_member_paths.json", []) _write_json(root / "manifest/s2_30_parent_member_paths.json", [])
_write_json(root / "manifest/s2_40_parent_member_paths.json", [])
report = VALIDATOR.validate_package( report = VALIDATOR.validate_package(
root, root,
root / "manifest/module_manifest.json", root / "manifest/module_manifest.json",
@@ -14,6 +14,7 @@ ROOT = Path(__file__).resolve().parents[2]
FIXTURE_ROOT = ROOT / "tests/fixtures/s2_20" FIXTURE_ROOT = ROOT / "tests/fixtures/s2_20"
MANIFEST_PATH = FIXTURE_ROOT / "regression_manifest.json" MANIFEST_PATH = FIXTURE_ROOT / "regression_manifest.json"
GLOBAL_MANIFEST_PATH = ROOT / "tests/fixtures/regression_manifest.json" GLOBAL_MANIFEST_PATH = ROOT / "tests/fixtures/regression_manifest.json"
S2_40_MANIFEST_PATH = ROOT / "tests/fixtures/s2_40/regression_manifest.json"
SHA256 = re.compile(r"^[a-f0-9]{64}$") SHA256 = re.compile(r"^[a-f0-9]{64}$")
EXPECTED_FIXTURE_IDS = { EXPECTED_FIXTURE_IDS = {
"S20-F01-SINGLE-OPTION-GROUP", "S20-F01-SINGLE-OPTION-GROUP",
@@ -206,6 +207,26 @@ class RegressionManifestClosureTest(unittest.TestCase):
self.assertTrue(physical.is_file()) self.assertTrue(physical.is_file())
self.assertEqual(row["sha256"], sha256(physical)) self.assertEqual(row["sha256"], sha256(physical))
def test_global_manifest_binds_s2_40_manifest_payloads_and_seven_tests(self) -> None:
global_manifest = json.loads(GLOBAL_MANIFEST_PATH.read_text(encoding="utf-8"))
binding = global_manifest.get("s2_40_fixture_binding")
self.assertIsInstance(binding, dict)
self.assertEqual(binding["binding_status"], "OFFLINE_BYTES_BOUND_LEGAL_AND_LIVE_PENDING")
self.assertEqual(binding["logical_fixture_count"], 15)
self.assertEqual(binding["payload_file_count"], 15)
self.assertEqual(ROOT / binding["fixture_manifest_path"], S2_40_MANIFEST_PATH)
self.assertEqual(binding["fixture_manifest_sha256"], sha256(S2_40_MANIFEST_PATH))
local = json.loads(S2_40_MANIFEST_PATH.read_text(encoding="utf-8"))
expected_payloads = {row["path"]: row["raw_sha256"] for row in local["rows"]}
self.assertEqual({row["path"]: row["sha256"] for row in binding["payloads"]}, expected_payloads)
for path, expected in expected_payloads.items():
self.assertEqual(sha256(ROOT / path), expected)
s2_40_test_rows = [row for row in global_manifest["test_sources"] if row["path"].startswith("tests/s2_40/")]
self.assertEqual(len(s2_40_test_rows), 7)
self.assertEqual({row["path"] for row in s2_40_test_rows}, {row["path"] for row in local["test_sources"]})
for row in s2_40_test_rows:
self.assertEqual(row["sha256"], sha256(ROOT / row["path"]))
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
@@ -14,6 +14,7 @@ ROOT = Path(__file__).resolve().parents[2]
FIXTURE_ROOT = ROOT / "tests/fixtures/s2_20" FIXTURE_ROOT = ROOT / "tests/fixtures/s2_20"
MANIFEST_PATH = FIXTURE_ROOT / "regression_manifest.json" MANIFEST_PATH = FIXTURE_ROOT / "regression_manifest.json"
GLOBAL_MANIFEST_PATH = ROOT / "tests/fixtures/regression_manifest.json" GLOBAL_MANIFEST_PATH = ROOT / "tests/fixtures/regression_manifest.json"
S2_40_MANIFEST_PATH = ROOT / "tests/fixtures/s2_40/regression_manifest.json"
SHA256 = re.compile(r"^[a-f0-9]{64}$") SHA256 = re.compile(r"^[a-f0-9]{64}$")
EXPECTED_FIXTURE_IDS = { EXPECTED_FIXTURE_IDS = {
"S20-F01-SINGLE-OPTION-GROUP", "S20-F01-SINGLE-OPTION-GROUP",
@@ -206,6 +207,26 @@ class RegressionManifestClosureTest(unittest.TestCase):
self.assertTrue(physical.is_file()) self.assertTrue(physical.is_file())
self.assertEqual(row["sha256"], sha256(physical)) self.assertEqual(row["sha256"], sha256(physical))
def test_global_manifest_binds_s2_40_manifest_payloads_and_seven_tests(self) -> None:
global_manifest = json.loads(GLOBAL_MANIFEST_PATH.read_text(encoding="utf-8"))
binding = global_manifest.get("s2_40_fixture_binding")
self.assertIsInstance(binding, dict)
self.assertEqual(binding["binding_status"], "OFFLINE_BYTES_BOUND_LEGAL_AND_LIVE_PENDING")
self.assertEqual(binding["logical_fixture_count"], 15)
self.assertEqual(binding["payload_file_count"], 15)
self.assertEqual(ROOT / binding["fixture_manifest_path"], S2_40_MANIFEST_PATH)
self.assertEqual(binding["fixture_manifest_sha256"], sha256(S2_40_MANIFEST_PATH))
local = json.loads(S2_40_MANIFEST_PATH.read_text(encoding="utf-8"))
expected_payloads = {row["path"]: row["raw_sha256"] for row in local["rows"]}
self.assertEqual({row["path"]: row["sha256"] for row in binding["payloads"]}, expected_payloads)
for path, expected in expected_payloads.items():
self.assertEqual(sha256(ROOT / path), expected)
s2_40_test_rows = [row for row in global_manifest["test_sources"] if row["path"].startswith("tests/s2_40/")]
self.assertEqual(len(s2_40_test_rows), 7)
self.assertEqual({row["path"] for row in s2_40_test_rows}, {row["path"] for row in local["test_sources"]})
for row in s2_40_test_rows:
self.assertEqual(row["sha256"], sha256(ROOT / row["path"]))
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
@@ -31,6 +31,7 @@ FIXTURE_FILENAMES = (
"invalid_reference_output.json", "invalid_reference_output.json",
"owner_singleton_dispatch.json", "owner_singleton_dispatch.json",
"partial_write_publish_barrier.json", "partial_write_publish_barrier.json",
"persisted_handoff_chain.json",
"rule_requirement_admission_gap.json", "rule_requirement_admission_gap.json",
"technical_failure.json", "technical_failure.json",
"valid_joint_draft_output.json", "valid_joint_draft_output.json",
@@ -60,7 +61,7 @@ class AgentContractTests(unittest.TestCase):
hashlib.sha256(binding_raw).hexdigest(), hashlib.sha256(binding_raw).hexdigest(),
ROOT, ROOT,
) )
self.assertEqual(report["deterministic_stage_ids"], ["S2_00", "S2_20"]) self.assertEqual(report["deterministic_stage_ids"], ["S2_00", "S2_20", "S2_40"])
self.assertEqual( self.assertEqual(
report["embedded_execution_unit_id"], report["embedded_execution_unit_id"],
"S2_30::Task_S2_30_dispatch_planner", "S2_30::Task_S2_30_dispatch_planner",
@@ -177,7 +178,7 @@ class AgentContractTests(unittest.TestCase):
physical_fixtures = sorted( physical_fixtures = sorted(
path for path in fixtures.glob("*.json") if path.name != "regression_manifest.json" path for path in fixtures.glob("*.json") if path.name != "regression_manifest.json"
) )
self.assertEqual(manifest["fixture_count_excluding_manifest"], 13) self.assertEqual(manifest["fixture_count_excluding_manifest"], 14)
self.assertEqual( self.assertEqual(
[row["filename"] for row in manifest["fixtures"]], [row["filename"] for row in manifest["fixtures"]],
[path.name for path in physical_fixtures], [path.name for path in physical_fixtures],
@@ -209,6 +210,14 @@ class AgentContractTests(unittest.TestCase):
contract.validate_instance(item["s30_source_refs"], "s30_source_refs", schema) contract.validate_instance(item["s30_source_refs"], "s30_source_refs", schema)
contract.validate_raw_output(valid, item, schema) contract.validate_raw_output(valid, item, schema)
handoff = documents["persisted_handoff_chain.json"]["contract"]
self.assertEqual(handoff["rows_per_claim_group"], len(contract.PART_FAMILIES))
self.assertEqual(set(handoff["part_families"]), contract.PART_FAMILIES)
self.assertEqual(set(handoff["group_provenance_fields"]), contract.GROUP_PROVENANCE_FIELDS)
self.assertTrue(handoff["manifest_receipt_free"])
self.assertFalse(handoff["runtime_directory_scan_allowed"])
self.assertFalse(handoff["runtime_glob_allowed"])
for row in documents["adverse_fact_worknote_policy.json"]["cases"]: for row in documents["adverse_fact_worknote_policy.json"]["cases"]:
contract.validate_instance(row["input"], "adverse_fact_row", schema) contract.validate_instance(row["input"], "adverse_fact_row", schema)
for row in documents["rule_requirement_admission_gap.json"]["cases"]: for row in documents["rule_requirement_admission_gap.json"]["cases"]:
@@ -31,6 +31,7 @@ FIXTURE_FILENAMES = (
"invalid_reference_output.json", "invalid_reference_output.json",
"owner_singleton_dispatch.json", "owner_singleton_dispatch.json",
"partial_write_publish_barrier.json", "partial_write_publish_barrier.json",
"persisted_handoff_chain.json",
"rule_requirement_admission_gap.json", "rule_requirement_admission_gap.json",
"technical_failure.json", "technical_failure.json",
"valid_joint_draft_output.json", "valid_joint_draft_output.json",
@@ -60,7 +61,7 @@ class AgentContractTests(unittest.TestCase):
hashlib.sha256(binding_raw).hexdigest(), hashlib.sha256(binding_raw).hexdigest(),
ROOT, ROOT,
) )
self.assertEqual(report["deterministic_stage_ids"], ["S2_00", "S2_20"]) self.assertEqual(report["deterministic_stage_ids"], ["S2_00", "S2_20", "S2_40"])
self.assertEqual( self.assertEqual(
report["embedded_execution_unit_id"], report["embedded_execution_unit_id"],
"S2_30::Task_S2_30_dispatch_planner", "S2_30::Task_S2_30_dispatch_planner",
@@ -177,7 +178,7 @@ class AgentContractTests(unittest.TestCase):
physical_fixtures = sorted( physical_fixtures = sorted(
path for path in fixtures.glob("*.json") if path.name != "regression_manifest.json" path for path in fixtures.glob("*.json") if path.name != "regression_manifest.json"
) )
self.assertEqual(manifest["fixture_count_excluding_manifest"], 13) self.assertEqual(manifest["fixture_count_excluding_manifest"], 14)
self.assertEqual( self.assertEqual(
[row["filename"] for row in manifest["fixtures"]], [row["filename"] for row in manifest["fixtures"]],
[path.name for path in physical_fixtures], [path.name for path in physical_fixtures],
@@ -209,6 +210,14 @@ class AgentContractTests(unittest.TestCase):
contract.validate_instance(item["s30_source_refs"], "s30_source_refs", schema) contract.validate_instance(item["s30_source_refs"], "s30_source_refs", schema)
contract.validate_raw_output(valid, item, schema) contract.validate_raw_output(valid, item, schema)
handoff = documents["persisted_handoff_chain.json"]["contract"]
self.assertEqual(handoff["rows_per_claim_group"], len(contract.PART_FAMILIES))
self.assertEqual(set(handoff["part_families"]), contract.PART_FAMILIES)
self.assertEqual(set(handoff["group_provenance_fields"]), contract.GROUP_PROVENANCE_FIELDS)
self.assertTrue(handoff["manifest_receipt_free"])
self.assertFalse(handoff["runtime_directory_scan_allowed"])
self.assertFalse(handoff["runtime_glob_allowed"])
for row in documents["adverse_fact_worknote_policy.json"]["cases"]: for row in documents["adverse_fact_worknote_policy.json"]["cases"]:
contract.validate_instance(row["input"], "adverse_fact_row", schema) contract.validate_instance(row["input"], "adverse_fact_row", schema)
for row in documents["rule_requirement_admission_gap.json"]["cases"]: for row in documents["rule_requirement_admission_gap.json"]["cases"]:
@@ -5,6 +5,7 @@ from pathlib import Path
import re import re
import sys import sys
import unittest import unittest
import yaml
ROOT = Path(__file__).resolve().parents[2] ROOT = Path(__file__).resolve().parents[2]
@@ -116,6 +117,22 @@ class PromptCacheBoundaryTests(unittest.TestCase):
self.assertIn("file_write_allowed: false", workflow) self.assertIn("file_write_allowed: false", workflow)
self.assertIn("permanent_id_mint_allowed: false", workflow) self.assertIn("permanent_id_mint_allowed: false", workflow)
def test_persisted_handoff_echoes_exact_mode_and_producer_provenance(self) -> None:
document = yaml.safe_load(WORKFLOW.read_text(encoding="utf-8"))
contract = document["output_contract"]["handoff_provenance_contract"]
group_fields = contract["group_fields"]
common_fields = contract["common_fields"]
expected_common = [
"compile_mode", "parent_stage2_release_sha256", "s2_30_release_sha256",
"s2_30_agent_sha256", "s2_30_binding_sha256", "p00_prompt_sha256",
"p30_prompt_sha256", "s2_30_producer_contract_digest",
]
expected_group_only = ["p31_rule_and_pack_sha256", "p32_common_authority_sha256", "s30_group_slice_sha256"]
self.assertEqual(common_fields, expected_common)
self.assertEqual(group_fields, expected_common[:-1] + expected_group_only + ["s2_30_producer_contract_digest"])
self.assertEqual(contract["exact_echo_chain"], "PART_TO_MANIFEST_TO_RECEIPT_TO_PUBLISH_STATUS_TO_S2_40_REQUEST")
self.assertEqual(document["output_contract"]["artifact_manifest_core_contract"]["receipt_free"], True)
@unittest.skipUnless(S2_10_AGENT.is_file() and S2_30_AGENT.is_file(), "derived Agent pair not built yet") @unittest.skipUnless(S2_10_AGENT.is_file() and S2_30_AGENT.is_file(), "derived Agent pair not built yet")
def test_s2_10_and_s2_30_common_prefix_raw_scalars_are_byte_equal(self) -> None: def test_s2_10_and_s2_30_common_prefix_raw_scalars_are_byte_equal(self) -> None:
self.assertEqual( self.assertEqual(

Some files were not shown because too many files have changed in this diff Show More