diff --git a/docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.json b/docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.json index 4bec825..a424c99 100644 --- a/docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.json +++ b/docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.json @@ -1,11 +1,11 @@ { "apply_transition": { "applied_readback": { - "applied_at": "2026-07-10 07:15:32.637281+00", + "applied_at": "2026-07-12 19:13:07.180112+00", "applied_by_agent_id": "44444444-4444-4444-4444-444444444444", "applied_by_handle": "kb-apply", "channel": "clone_canary", - "id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "payload": { "apply_payload": { "agent_id": null, @@ -13,7 +13,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -26,7 +26,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -42,24 +42,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -68,7 +68,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -76,8 +76,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -85,8 +85,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -97,7 +97,7 @@ "proposal_type": "approve_claim", "rationale": "Exercise strict canonical bundle review and apply lifecycle.", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_handle": "m3ta", "source_ref": "working-leo:approve-claim-clone-canary", @@ -108,7 +108,7 @@ "applied_by_agent_id": null, "applied_by_handle": null, "channel": "clone_canary", - "id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "payload": { "apply_payload": { "agent_id": null, @@ -116,7 +116,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -129,7 +129,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -145,24 +145,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -171,7 +171,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -179,8 +179,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -188,8 +188,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -200,7 +200,7 @@ "proposal_type": "approve_claim", "rationale": "Exercise strict canonical bundle review and apply lifecycle.", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_handle": "m3ta", "source_ref": "working-leo:approve-claim-clone-canary", @@ -216,7 +216,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -229,7 +229,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -245,24 +245,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -271,7 +271,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -279,8 +279,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -288,8 +288,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -297,10 +297,10 @@ ] } }, - "proposal_id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "proposal_id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "proposal_type": "approve_claim", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_db_role": "kb_review", "reviewed_by_handle": "m3ta" @@ -325,10 +325,14 @@ "kb_review_used_security_definer": true, "mutation_between_build_and_execute_refused": true, "outer_container_absent_independent_readback": true, + "outer_container_has_no_docker_volumes": true, + "outer_container_network_disabled": true, "outer_isolation_complete": true, "outer_live_counts_exactly_unchanged": true, "outer_live_table_deltas_exactly_zero": true, - "outer_service_stable": true, + "outer_service_observed_if_required": true, + "outer_service_stable_if_observed": true, + "outer_source_tier_enforced": true, "outer_workdir_absent_independent_readback": true, "payload_agents_seeded_exactly": true, "payload_projection_exact": true, @@ -378,7 +382,7 @@ "public.sources": 1 }, "clone_created": true, - "clone_database": "teleo_approve_claim_isolated_e3b683f113", + "clone_database": "teleo_approve_claim_isolated_f1606cd97b", "clone_dropped": true, "clone_prerequisite_sanitization": { "clone_sql_sha256": "a02a03a704954058745d8cee4d25597bb8eaeee2ae211d4f9be4fe055f3d98ec", @@ -390,7 +394,7 @@ "conflict_apply": { "returncode": 1, "source_hash_collision_refusal": true, - "stderr": "psql failed (3)\nSTDOUT:\n\n\nSTDERR:\nERROR: approve_claim: source hash collision for source c9685bc5-9d49-5ae3-ae77-d7ff1a139703\nCONTEXT: PL/pgSQL function inline_code_block line 6 at RAISE" + "stderr": "psql failed (3)\nSTDOUT:\n\n\nSTDERR:\nERROR: approve_claim: source hash collision for source 0b126fb3-438d-5230-8e13-3c28b713a285\nCONTEXT: PL/pgSQL function inline_code_block line 6 at RAISE" }, "conflict_readback": { "canonical_rows": { @@ -409,7 +413,7 @@ { "confidence": 0.5, "created_by": null, - "id": "0ff3cab8-903b-58ee-a7d2-bda1e97f9673", + "id": "d3a11e59-ac6d-571b-b865-f7232e367193", "status": "open", "superseded_by": null, "tags": [ @@ -427,8 +431,8 @@ { "created_by": null, "excerpt": "Conflicting source id.", - "hash": "approve-claim-permission-probe-542b3011-ff1c-51b4-b127-1465da2f151c", - "id": "c9685bc5-9d49-5ae3-ae77-d7ff1a139703", + "hash": "approve-claim-permission-probe-970457bb-09d1-58ab-a2fd-1cbf1abeb3e8", + "id": "0b126fb3-438d-5230-8e13-3c28b713a285", "source_type": "observation", "storage_path": null, "url": null @@ -436,10 +440,10 @@ ] } }, - "proposal_id": "b8ccc5ee-b357-5a9a-bda2-192644abd6a2", + "proposal_id": "78a21286-07ef-558c-9e68-ef5b31fb28e2", "proposal_type": "approve_claim", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:33.79842+00", + "reviewed_at": "2026-07-12 19:13:08.360729+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_db_role": "kb_review", "reviewed_by_handle": "m3ta" @@ -450,7 +454,7 @@ "applied_by_agent_id": null, "applied_by_handle": null, "channel": "clone_canary", - "id": "b8ccc5ee-b357-5a9a-bda2-192644abd6a2", + "id": "78a21286-07ef-558c-9e68-ef5b31fb28e2", "payload": { "apply_payload": { "agent_id": null, @@ -458,7 +462,7 @@ { "confidence": 0.5, "created_by": null, - "id": "0ff3cab8-903b-58ee-a7d2-bda1e97f9673", + "id": "d3a11e59-ac6d-571b-b865-f7232e367193", "status": "open", "superseded_by": null, "tags": [ @@ -476,8 +480,8 @@ { "created_by": null, "excerpt": "Conflicting source id.", - "hash": "approve-claim-permission-probe-542b3011-ff1c-51b4-b127-1465da2f151c", - "id": "c9685bc5-9d49-5ae3-ae77-d7ff1a139703", + "hash": "approve-claim-permission-probe-970457bb-09d1-58ab-a2fd-1cbf1abeb3e8", + "id": "0b126fb3-438d-5230-8e13-3c28b713a285", "source_type": "observation", "storage_path": null, "url": null @@ -488,7 +492,7 @@ "proposal_type": "approve_claim", "rationale": "Exercise strict canonical bundle review and apply lifecycle.", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:33.79842+00", + "reviewed_at": "2026-07-12 19:13:08.360729+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_handle": "m3ta", "source_ref": "working-leo:approve-claim-conflict-canary", @@ -502,7 +506,7 @@ "applied_by_agent_id": null, "applied_by_handle": null, "channel": "clone_canary", - "id": "b8ccc5ee-b357-5a9a-bda2-192644abd6a2", + "id": "78a21286-07ef-558c-9e68-ef5b31fb28e2", "payload": { "apply_payload": { "agent_id": null, @@ -510,7 +514,7 @@ { "confidence": 0.5, "created_by": null, - "id": "0ff3cab8-903b-58ee-a7d2-bda1e97f9673", + "id": "d3a11e59-ac6d-571b-b865-f7232e367193", "status": "open", "superseded_by": null, "tags": [ @@ -528,8 +532,8 @@ { "created_by": null, "excerpt": "Conflicting source id.", - "hash": "approve-claim-permission-probe-542b3011-ff1c-51b4-b127-1465da2f151c", - "id": "c9685bc5-9d49-5ae3-ae77-d7ff1a139703", + "hash": "approve-claim-permission-probe-970457bb-09d1-58ab-a2fd-1cbf1abeb3e8", + "id": "0b126fb3-438d-5230-8e13-3c28b713a285", "source_type": "observation", "storage_path": null, "url": null @@ -540,7 +544,7 @@ "proposal_type": "approve_claim", "rationale": "Exercise strict canonical bundle review and apply lifecycle.", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:33.79842+00", + "reviewed_at": "2026-07-12 19:13:08.360729+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_handle": "m3ta", "source_ref": "working-leo:approve-claim-conflict-canary", @@ -556,7 +560,7 @@ { "confidence": 0.5, "created_by": null, - "id": "0ff3cab8-903b-58ee-a7d2-bda1e97f9673", + "id": "d3a11e59-ac6d-571b-b865-f7232e367193", "status": "open", "superseded_by": null, "tags": [ @@ -574,8 +578,8 @@ { "created_by": null, "excerpt": "Conflicting source id.", - "hash": "approve-claim-permission-probe-542b3011-ff1c-51b4-b127-1465da2f151c", - "id": "c9685bc5-9d49-5ae3-ae77-d7ff1a139703", + "hash": "approve-claim-permission-probe-970457bb-09d1-58ab-a2fd-1cbf1abeb3e8", + "id": "0b126fb3-438d-5230-8e13-3c28b713a285", "source_type": "observation", "storage_path": null, "url": null @@ -583,10 +587,10 @@ ] } }, - "proposal_id": "b8ccc5ee-b357-5a9a-bda2-192644abd6a2", + "proposal_id": "78a21286-07ef-558c-9e68-ef5b31fb28e2", "proposal_type": "approve_claim", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:33.79842+00", + "reviewed_at": "2026-07-12 19:13:08.360729+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_db_role": "kb_review", "reviewed_by_handle": "m3ta" @@ -597,7 +601,7 @@ "applied_by_agent_id": null, "applied_by_handle": null, "channel": "clone_canary", - "id": "b8ccc5ee-b357-5a9a-bda2-192644abd6a2", + "id": "78a21286-07ef-558c-9e68-ef5b31fb28e2", "payload": { "apply_payload": { "agent_id": null, @@ -605,7 +609,7 @@ { "confidence": 0.5, "created_by": null, - "id": "0ff3cab8-903b-58ee-a7d2-bda1e97f9673", + "id": "d3a11e59-ac6d-571b-b865-f7232e367193", "status": "open", "superseded_by": null, "tags": [ @@ -623,8 +627,8 @@ { "created_by": null, "excerpt": "Conflicting source id.", - "hash": "approve-claim-permission-probe-542b3011-ff1c-51b4-b127-1465da2f151c", - "id": "c9685bc5-9d49-5ae3-ae77-d7ff1a139703", + "hash": "approve-claim-permission-probe-970457bb-09d1-58ab-a2fd-1cbf1abeb3e8", + "id": "0b126fb3-438d-5230-8e13-3c28b713a285", "source_type": "observation", "storage_path": null, "url": null @@ -644,7 +648,7 @@ "review_apply": { "returncode": 0, "stderr": "", - "stdout": "{\"id\": \"b8ccc5ee-b357-5a9a-bda2-192644abd6a2\", \"proposal_type\": \"approve_claim\", \"review_note\": \"Reviewed exact strict payload inside the disposable clone.\", \"reviewed_at\": \"2026-07-10 07:15:33.79842+00\", \"reviewed_by_agent_id\": \"99999999-9999-9999-9999-999999999999\", \"reviewed_by_db_role\": \"kb_review\", \"reviewed_by_handle\": \"m3ta\", \"status\": \"approved\"}" + "stdout": "{\"id\": \"78a21286-07ef-558c-9e68-ef5b31fb28e2\", \"proposal_type\": \"approve_claim\", \"review_note\": \"Reviewed exact strict payload inside the disposable clone.\", \"reviewed_at\": \"2026-07-12 19:13:08.360729+00\", \"reviewed_by_agent_id\": \"99999999-9999-9999-9999-999999999999\", \"reviewed_by_db_role\": \"kb_review\", \"reviewed_by_handle\": \"m3ta\", \"status\": \"approved\"}" } }, "current_tier": "T3_live_readonly", @@ -687,28 +691,29 @@ "first_apply": { "returncode": 0, "stderr": "", - "stdout": "applied proposal 80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1 (approve_claim)" + "stdout": "applied proposal 32ba67f7-99b8-57b5-ac60-502cebdd7170 (approve_claim)" }, "fixture_ids": { - "conflict_claim_id": "0ff3cab8-903b-58ee-a7d2-bda1e97f9673", - "conflict_proposal_id": "b8ccc5ee-b357-5a9a-bda2-192644abd6a2", - "conflict_source_id": "c9685bc5-9d49-5ae3-ae77-d7ff1a139703", - "permission_claim_id": "07ac6db0-9bdc-5aa6-a610-3232e2e0eb47", - "permission_source_id": "542b3011-ff1c-51b4-b127-1465da2f151c", - "proposal_id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1" + "conflict_claim_id": "d3a11e59-ac6d-571b-b865-f7232e367193", + "conflict_proposal_id": "78a21286-07ef-558c-9e68-ef5b31fb28e2", + "conflict_source_id": "0b126fb3-438d-5230-8e13-3c28b713a285", + "permission_claim_id": "5c23f79c-86c8-51b6-a6c7-759fa89d6c57", + "permission_source_id": "970457bb-09d1-58ab-a2fd-1cbf1abeb3e8", + "proposal_id": "32ba67f7-99b8-57b5-ac60-502cebdd7170" }, - "generated_at_utc": "2026-07-10T07:15:27.214495+00:00", + "gateway_process_observable": true, + "generated_at_utc": "2026-07-12T19:13:02.328043+00:00", "idempotent_replay": { "already_applied_refusal": true, "returncode": 1, - "stderr": "proposal 80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1 is already applied (idempotent no-op)" + "stderr": "proposal 32ba67f7-99b8-57b5-ac60-502cebdd7170 is already applied (idempotent no-op)" }, "kb_apply_claim_evidence_update_probe": { "after": { - "claim_id": "07ac6db0-9bdc-5aa6-a610-3232e2e0eb47", + "claim_id": "5c23f79c-86c8-51b6-a6c7-759fa89d6c57", "created_by": null, "role": "grounds", - "source_id": "542b3011-ff1c-51b4-b127-1465da2f151c", + "source_id": "970457bb-09d1-58ab-a2fd-1cbf1abeb3e8", "weight": 0.42 }, "attempt": { @@ -718,10 +723,10 @@ "stdout": "" }, "before": { - "claim_id": "07ac6db0-9bdc-5aa6-a610-3232e2e0eb47", + "claim_id": "5c23f79c-86c8-51b6-a6c7-759fa89d6c57", "created_by": null, "role": "grounds", - "source_id": "542b3011-ff1c-51b4-b127-1465da2f151c", + "source_id": "970457bb-09d1-58ab-a2fd-1cbf1abeb3e8", "weight": 0.42 }, "exact_row_unchanged": true @@ -732,7 +737,7 @@ "applied_by_agent_id": null, "applied_by_handle": null, "channel": "clone_canary", - "id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "payload": { "apply_payload": { "agent_id": null, @@ -740,7 +745,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -753,7 +758,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -769,24 +774,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -795,7 +800,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -803,8 +808,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -812,8 +817,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -824,7 +829,7 @@ "proposal_type": "approve_claim", "rationale": "Exercise strict canonical bundle review and apply lifecycle.", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_handle": "m3ta", "source_ref": "working-leo:approve-claim-clone-canary", @@ -841,7 +846,7 @@ "applied_by_agent_id": null, "applied_by_handle": null, "channel": "clone_canary", - "id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "payload": { "apply_payload": { "agent_id": null, @@ -849,7 +854,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -862,7 +867,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -878,24 +883,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -904,7 +909,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -912,8 +917,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -921,8 +926,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -933,7 +938,7 @@ "proposal_type": "approve_claim", "rationale": "Exercise strict canonical bundle review and apply lifecycle.", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_handle": "m3ta", "source_ref": "working-leo:approve-claim-clone-canary", @@ -948,7 +953,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -961,7 +966,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -977,24 +982,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -1003,7 +1008,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -1011,8 +1016,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -1020,8 +1025,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -1029,10 +1034,10 @@ ] } }, - "proposal_id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "proposal_id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "proposal_type": "approve_claim", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_db_role": "kb_review", "reviewed_by_handle": "m3ta" @@ -1045,7 +1050,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -1058,7 +1063,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -1074,24 +1079,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -1100,7 +1105,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -1108,8 +1113,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -1117,8 +1122,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -1126,10 +1131,10 @@ ] } }, - "proposal_id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "proposal_id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "proposal_type": "approve_claim", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_db_role": "kb_review", "reviewed_by_handle": "m3ta" @@ -1156,7 +1161,7 @@ "applied_by_agent_id": null, "applied_by_handle": null, "channel": "clone_canary", - "id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "payload": { "apply_payload": { "agent_id": null, @@ -1164,7 +1169,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -1177,7 +1182,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -1193,24 +1198,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -1219,7 +1224,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -1227,8 +1232,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -1236,8 +1241,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -1248,14 +1253,14 @@ "proposal_type": "approve_claim", "rationale": "Exercise strict canonical bundle review and apply lifecycle.", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_handle": "m3ta", "source_ref": "working-leo:approve-claim-clone-canary", "status": "approved" }, "build_returncode": 0, - "built_sql_sha256": "19d51339ec783df45a44c12e745982f8907b2be75a9a3060511ca22ff3294816", + "built_sql_sha256": "ae4869b1b2019d1cfe6c2c11cc056f8a3b756a51a7859393fab2d9a8ab625db6", "built_sql_uses_assert_approved_proposal": true, "built_sql_uses_finish_approved_proposal": true, "canonical_rows_unchanged": true, @@ -1267,7 +1272,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -1280,7 +1285,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -1296,24 +1301,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -1322,7 +1327,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -1330,8 +1335,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -1339,8 +1344,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -1348,10 +1353,10 @@ ] } }, - "proposal_id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "proposal_id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "proposal_type": "approve_claim", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_db_role": "kb_review", "reviewed_by_handle": "m3ta" @@ -1364,7 +1369,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -1377,7 +1382,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -1393,24 +1398,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -1419,7 +1424,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -1427,8 +1432,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -1436,8 +1441,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -1445,10 +1450,10 @@ ] } }, - "proposal_id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "proposal_id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "proposal_type": "approve_claim", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_db_role": "kb_review", "reviewed_by_handle": "m3ta" @@ -1461,7 +1466,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -1474,7 +1479,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -1490,24 +1495,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -1516,7 +1521,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -1524,8 +1529,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -1533,8 +1538,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -1542,10 +1547,10 @@ ] } }, - "proposal_id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "proposal_id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "proposal_type": "approve_claim", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_db_role": "kb_review", "reviewed_by_handle": "m3ta" @@ -1556,7 +1561,7 @@ "applied_by_agent_id": null, "applied_by_handle": null, "channel": "clone_canary", - "id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "payload": { "apply_payload": { "agent_id": null, @@ -1564,7 +1569,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -1577,7 +1582,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -1593,24 +1598,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -1619,7 +1624,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -1627,8 +1632,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -1636,8 +1641,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -1649,7 +1654,7 @@ "proposal_type": "approve_claim", "rationale": "Exercise strict canonical bundle review and apply lifecycle.", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_handle": "m3ta", "source_ref": "working-leo:approve-claim-clone-canary", @@ -1660,7 +1665,7 @@ "applied_by_agent_id": null, "applied_by_handle": null, "channel": "clone_canary", - "id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "payload": { "apply_payload": { "agent_id": null, @@ -1668,7 +1673,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -1681,7 +1686,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -1697,24 +1702,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -1723,7 +1728,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -1731,8 +1736,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -1740,8 +1745,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -1753,7 +1758,7 @@ "proposal_type": "approve_claim", "rationale": "Exercise strict canonical bundle review and apply lifecycle.", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_handle": "m3ta", "source_ref": "working-leo:approve-claim-clone-canary", @@ -1767,7 +1772,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -1780,7 +1785,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -1796,24 +1801,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -1822,7 +1827,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -1830,8 +1835,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -1839,8 +1844,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -1848,10 +1853,10 @@ ] } }, - "proposal_id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "proposal_id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "proposal_type": "approve_claim", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_db_role": "kb_review", "reviewed_by_handle": "m3ta" @@ -1861,7 +1866,7 @@ "applied_by_agent_id": null, "applied_by_handle": null, "channel": "clone_canary", - "id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "payload": { "apply_payload": { "agent_id": null, @@ -1869,7 +1874,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -1882,7 +1887,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -1898,24 +1903,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -1924,7 +1929,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -1932,8 +1937,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -1941,8 +1946,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -1953,7 +1958,7 @@ "proposal_type": "approve_claim", "rationale": "Exercise strict canonical bundle review and apply lifecycle.", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_handle": "m3ta", "source_ref": "working-leo:approve-claim-clone-canary", @@ -1969,7 +1974,7 @@ "stale_apply_refused": true, "stale_execute": { "returncode": 3, - "stderr": "ERROR: assert_approved_proposal: proposal 80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1 is not the exact immutable approved snapshot\nCONTEXT: PL/pgSQL function kb_stage.assert_approved_proposal(uuid,text,jsonb,text,uuid,timestamp with time zone,text) line 22 at RAISE", + "stderr": "ERROR: assert_approved_proposal: proposal 32ba67f7-99b8-57b5-ac60-502cebdd7170 is not the exact immutable approved snapshot\nCONTEXT: PL/pgSQL function kb_stage.assert_approved_proposal(uuid,text,jsonb,text,uuid,timestamp with time zone,text) line 22 at RAISE", "stdout": "" } }, @@ -1991,21 +1996,38 @@ "workdir_lexists_after_cleanup": false, "workdir_remove_returncode": 0 }, + "container_isolation": { + "network_disabled": true, + "network_mode": "none", + "no_docker_volumes": true, + "volume_mounts": [] + }, "service_after": { "ActiveState": "active", - "ExecMainStartTimestamp": "Fri 2026-07-10 03:47:11 UTC", - "MainPID": "2999690", + "Available": "true", + "ExecMainStartTimestamp": "Sun 2026-07-12 09:14:10 UTC", + "MainPID": "2403328", "NRestarts": "0", "SubState": "running" }, "service_before": { "ActiveState": "active", - "ExecMainStartTimestamp": "Fri 2026-07-10 03:47:11 UTC", - "MainPID": "2999690", + "Available": "true", + "ExecMainStartTimestamp": "Sun 2026-07-12 09:14:10 UTC", + "MainPID": "2403328", "NRestarts": "0", "SubState": "running" }, + "service_gate_passes": true, + "service_observable": true, + "service_required": true, "service_stable": true, + "source_boundary": { + "canary_label": "", + "network_mode": "bridge", + "source_tier": "live-readonly", + "tier_enforced": true + }, "source_container": "teleo-pg", "source_counts_after": { "kb_stage.kb_proposals": 26, @@ -2038,45 +2060,32 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "claim_evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "created_by": null, - "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", - "weight": 0.9 - }, - { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 + }, + { + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "created_by": null, + "role": "grounds", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", + "weight": 0.9 } ], "claims": [ - { - "confidence": 0.9, - "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "status": "open", - "superseded_by": null, - "tags": [ - "working-leo", - "clone-canary" - ], - "text": "An approved strict proposal can create exact canonical rows atomically.", - "type": "structural" - }, { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -2085,6 +2094,19 @@ ], "text": "Row-level proof is the authority for canonical KB state.", "type": "concept" + }, + { + "confidence": 0.9, + "created_by": null, + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "status": "open", + "superseded_by": null, + "tags": [ + "working-leo", + "clone-canary" + ], + "text": "An approved strict proposal can create exact canonical rows atomically.", + "type": "structural" } ], "reasoning_tools": [ @@ -2092,25 +2114,25 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], "sources": [ { "created_by": null, - "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "excerpt": "Disposable clone lifecycle canary source A.", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null }, { "created_by": null, - "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "excerpt": "Disposable clone lifecycle canary source B.", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -2125,11 +2147,12 @@ "public.reasoning_tools": 1, "public.sources": 2 }, - "payload_sha256": "09f67de2ad91c95436f47fec26e7e631c3d82918748655c6d0974ed10084a79b" + "payload_sha256": "192b79d951d84642e16ea352786165d86166076dffef029c5d5060f5ca924c2c" }, "post_run_cleanup": { "gateway_active_state": "active", - "gateway_main_pid": "2999690", + "gateway_main_pid": "2403328", + "gateway_process_observable": true, "gateway_restart_count": "0", "gateway_sub_state": "running", "leftover_clone_database_count": 0 @@ -2145,7 +2168,7 @@ "applied_by_agent_id": null, "applied_by_handle": null, "channel": "clone_canary", - "id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "payload": { "apply_payload": { "agent_id": null, @@ -2153,7 +2176,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -2166,7 +2189,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -2182,24 +2205,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -2208,7 +2231,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -2216,8 +2239,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -2225,8 +2248,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -2237,7 +2260,7 @@ "proposal_type": "approve_claim", "rationale": "Exercise strict canonical bundle review and apply lifecycle.", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_handle": "m3ta", "source_ref": "working-leo:approve-claim-clone-canary", @@ -2253,7 +2276,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -2266,7 +2289,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -2282,24 +2305,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -2308,7 +2331,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -2316,8 +2339,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -2325,8 +2348,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -2334,10 +2357,10 @@ ] } }, - "proposal_id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "proposal_id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "proposal_type": "approve_claim", "review_note": "Reviewed exact strict payload inside the disposable clone.", - "reviewed_at": "2026-07-10 07:15:30.325989+00", + "reviewed_at": "2026-07-12 19:13:04.862904+00", "reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999", "reviewed_by_db_role": "kb_review", "reviewed_by_handle": "m3ta" @@ -2348,7 +2371,7 @@ "applied_by_agent_id": null, "applied_by_handle": null, "channel": "clone_canary", - "id": "80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1", + "id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", "payload": { "apply_payload": { "agent_id": null, @@ -2356,7 +2379,7 @@ { "confidence": 0.9, "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "status": "open", "superseded_by": null, "tags": [ @@ -2369,7 +2392,7 @@ { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -2385,24 +2408,24 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", "created_by": null, "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "weight": 0.9 }, { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 } ], @@ -2411,7 +2434,7 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], @@ -2419,8 +2442,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null @@ -2428,8 +2451,8 @@ { "created_by": null, "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -2449,7 +2472,7 @@ "review_apply": { "returncode": 0, "stderr": "", - "stdout": "{\"id\": \"80cfb6d9-f7c2-5f23-8da8-b61abeacf9c1\", \"proposal_type\": \"approve_claim\", \"review_note\": \"Reviewed exact strict payload inside the disposable clone.\", \"reviewed_at\": \"2026-07-10 07:15:30.325989+00\", \"reviewed_by_agent_id\": \"99999999-9999-9999-9999-999999999999\", \"reviewed_by_db_role\": \"kb_review\", \"reviewed_by_handle\": \"m3ta\", \"status\": \"approved\"}" + "stdout": "{\"id\": \"32ba67f7-99b8-57b5-ac60-502cebdd7170\", \"proposal_type\": \"approve_claim\", \"review_note\": \"Reviewed exact strict payload inside the disposable clone.\", \"reviewed_at\": \"2026-07-12 19:13:04.862904+00\", \"reviewed_by_agent_id\": \"99999999-9999-9999-9999-999999999999\", \"reviewed_by_db_role\": \"kb_review\", \"reviewed_by_handle\": \"m3ta\", \"status\": \"approved\"}" }, "review_dry_run": { "returncode": 0, @@ -2476,45 +2499,32 @@ { "created_by": null, "edge_type": "supports", - "from_claim": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "to_claim": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f", "weight": 0.75 } ], "claim_evidence": [ { - "claim_id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "created_by": null, - "role": "grounds", - "source_id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", - "weight": 0.9 - }, - { - "claim_id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", "created_by": null, "role": "illustrates", - "source_id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "weight": 0.8 + }, + { + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "created_by": null, + "role": "grounds", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", + "weight": 0.9 } ], "claims": [ - { - "confidence": 0.9, - "created_by": null, - "id": "a7fe0762-708f-51e2-ac49-9f32d1de7dbe", - "status": "open", - "superseded_by": null, - "tags": [ - "working-leo", - "clone-canary" - ], - "text": "An approved strict proposal can create exact canonical rows atomically.", - "type": "structural" - }, { "confidence": 0.85, "created_by": null, - "id": "fe4cb543-6877-55d3-ab8a-302e6da981d5", + "id": "a43cff79-e537-58f7-97cb-d2044a70477f", "status": "open", "superseded_by": null, "tags": [ @@ -2523,6 +2533,19 @@ ], "text": "Row-level proof is the authority for canonical KB state.", "type": "concept" + }, + { + "confidence": 0.9, + "created_by": null, + "id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "status": "open", + "superseded_by": null, + "tags": [ + "working-leo", + "clone-canary" + ], + "text": "An approved strict proposal can create exact canonical rows atomically.", + "type": "structural" } ], "reasoning_tools": [ @@ -2530,25 +2553,25 @@ "agent_id": null, "category": "verification", "description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.", - "id": "cc4bcb49-986c-5afb-8936-bca908281207", + "id": "b9b972c3-1415-56ea-a7b3-58e760ede13e", "name": "Canonical row proof canary" } ], "sources": [ { "created_by": null, - "excerpt": "Disposable clone lifecycle canary source B.", - "hash": "approve-claim-canary-e3b683f113-b", - "id": "90e48f41-9fd5-5807-928c-2e10e2b0e32a", + "excerpt": "Disposable clone lifecycle canary source A.", + "hash": "approve-claim-canary-f1606cd97b-a", + "id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", "source_type": "observation", "storage_path": null, "url": null }, { "created_by": null, - "excerpt": "Disposable clone lifecycle canary source A.", - "hash": "approve-claim-canary-e3b683f113-a", - "id": "e278bc23-ac5e-58af-8210-e97e0d77ccd5", + "excerpt": "Disposable clone lifecycle canary source B.", + "hash": "approve-claim-canary-f1606cd97b-b", + "id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c", "source_type": "observation", "storage_path": null, "url": null @@ -2614,18 +2637,20 @@ }, "service_after": { "ActiveState": "active", - "ExecMainStartTimestamp": "Fri 2026-07-10 03:47:11 UTC", - "MainPID": "2999690", + "ExecMainStartTimestamp": "Sun 2026-07-12 09:14:10 UTC", + "MainPID": "2403328", "NRestarts": "0", "SubState": "running", + "available": true, "returncode": 0 }, "service_before": { "ActiveState": "active", - "ExecMainStartTimestamp": "Fri 2026-07-10 03:47:11 UTC", - "MainPID": "2999690", + "ExecMainStartTimestamp": "Sun 2026-07-12 09:14:10 UTC", + "MainPID": "2403328", "NRestarts": "0", "SubState": "running", + "available": true, "returncode": 0 }, "service_restarted": false, @@ -2633,8 +2658,8 @@ "files": [ { "repo_relative_path": "scripts/apply_proposal.py", - "sha256": "b3b6578dbba5bdce617384e344f52d8a1f7aac273aa29f7d67db41572007f225", - "size_bytes": 39736 + "sha256": "2d64833921b6af91b95431f5c36006c52de9aa82fe768be007880add3f9c8130", + "size_bytes": 39810 }, { "repo_relative_path": "scripts/approve_proposal.py", @@ -2648,24 +2673,24 @@ }, { "repo_relative_path": "scripts/run_approve_claim_clone_canary.py", - "sha256": "e27f2470d063547760f018ffaf206ae77f1a2231d2044a6b754d2ee4711f82da", - "size_bytes": 77359 + "sha256": "209bd0a227e925951639abf45a3acff82d875078ccfce00ef3d4582ceb2215e0", + "size_bytes": 82476 }, { "repo_relative_path": "scripts/run_approve_claim_isolated_container_canary.sh", - "sha256": "f793c063f2bce14c824eed783c3d0c6fed2509a472054cf4b5b77e8f1ca00f7e", - "size_bytes": 12046 + "sha256": "2bd622bf90b4eb8fbd10cb86420d30c219b9afb894516b06c5f4e6af08ec2520", + "size_bytes": 16041 } ], "independent_post_cleanup_verification": { "all_match": true, "files": [ { - "actual_sha256": "b3b6578dbba5bdce617384e344f52d8a1f7aac273aa29f7d67db41572007f225", - "expected_sha256": "b3b6578dbba5bdce617384e344f52d8a1f7aac273aa29f7d67db41572007f225", + "actual_sha256": "2d64833921b6af91b95431f5c36006c52de9aa82fe768be007880add3f9c8130", + "expected_sha256": "2d64833921b6af91b95431f5c36006c52de9aa82fe768be007880add3f9c8130", "matches": true, "repo_relative_path": "scripts/apply_proposal.py", - "size_bytes": 39736 + "size_bytes": 39810 }, { "actual_sha256": "e991498264bd0f49755dfef809212fa7151a668ce479b100d830e447775a9fe0", @@ -2682,26 +2707,26 @@ "size_bytes": 42602 }, { - "actual_sha256": "e27f2470d063547760f018ffaf206ae77f1a2231d2044a6b754d2ee4711f82da", - "expected_sha256": "e27f2470d063547760f018ffaf206ae77f1a2231d2044a6b754d2ee4711f82da", + "actual_sha256": "209bd0a227e925951639abf45a3acff82d875078ccfce00ef3d4582ceb2215e0", + "expected_sha256": "209bd0a227e925951639abf45a3acff82d875078ccfce00ef3d4582ceb2215e0", "matches": true, "repo_relative_path": "scripts/run_approve_claim_clone_canary.py", - "size_bytes": 77359 + "size_bytes": 82476 }, { - "actual_sha256": "f793c063f2bce14c824eed783c3d0c6fed2509a472054cf4b5b77e8f1ca00f7e", - "expected_sha256": "f793c063f2bce14c824eed783c3d0c6fed2509a472054cf4b5b77e8f1ca00f7e", + "actual_sha256": "2bd622bf90b4eb8fbd10cb86420d30c219b9afb894516b06c5f4e6af08ec2520", + "expected_sha256": "2bd622bf90b4eb8fbd10cb86420d30c219b9afb894516b06c5f4e6af08ec2520", "matches": true, "repo_relative_path": "scripts/run_approve_claim_isolated_container_canary.sh", - "size_bytes": 12046 + "size_bytes": 16041 } ] }, "post_run_files": [ { "repo_relative_path": "scripts/apply_proposal.py", - "sha256": "b3b6578dbba5bdce617384e344f52d8a1f7aac273aa29f7d67db41572007f225", - "size_bytes": 39736 + "sha256": "2d64833921b6af91b95431f5c36006c52de9aa82fe768be007880add3f9c8130", + "size_bytes": 39810 }, { "repo_relative_path": "scripts/approve_proposal.py", @@ -2715,13 +2740,13 @@ }, { "repo_relative_path": "scripts/run_approve_claim_clone_canary.py", - "sha256": "e27f2470d063547760f018ffaf206ae77f1a2231d2044a6b754d2ee4711f82da", - "size_bytes": 77359 + "sha256": "209bd0a227e925951639abf45a3acff82d875078ccfce00ef3d4582ceb2215e0", + "size_bytes": 82476 }, { "repo_relative_path": "scripts/run_approve_claim_isolated_container_canary.sh", - "sha256": "f793c063f2bce14c824eed783c3d0c6fed2509a472054cf4b5b77e8f1ca00f7e", - "size_bytes": 12046 + "sha256": "2bd622bf90b4eb8fbd10cb86420d30c219b9afb894516b06c5f4e6af08ec2520", + "size_bytes": 16041 } ], "unchanged_during_run": true @@ -2844,5 +2869,133 @@ "sources": [] }, "status": "pass", + "strict_receipt": { + "canonical_row_keys": { + "actual": { + "public.claim_edges": [ + { + "edge_type": "supports", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f" + } + ], + "public.claim_evidence": [ + { + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", + "role": "illustrates", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c" + }, + { + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "role": "grounds", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26" + } + ], + "public.claims": [ + "a43cff79-e537-58f7-97cb-d2044a70477f", + "a710dccd-7e71-5b8b-bb46-61a6c50cba06" + ], + "public.reasoning_tools": [ + "b9b972c3-1415-56ea-a7b3-58e760ede13e" + ], + "public.sources": [ + "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", + "473eb14f-43a5-5cfa-91c0-416cb8f9985c" + ] + }, + "expected": { + "public.claim_edges": [ + { + "edge_type": "supports", + "from_claim": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "to_claim": "a43cff79-e537-58f7-97cb-d2044a70477f" + } + ], + "public.claim_evidence": [ + { + "claim_id": "a43cff79-e537-58f7-97cb-d2044a70477f", + "role": "illustrates", + "source_id": "473eb14f-43a5-5cfa-91c0-416cb8f9985c" + }, + { + "claim_id": "a710dccd-7e71-5b8b-bb46-61a6c50cba06", + "role": "grounds", + "source_id": "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26" + } + ], + "public.claims": [ + "a43cff79-e537-58f7-97cb-d2044a70477f", + "a710dccd-7e71-5b8b-bb46-61a6c50cba06" + ], + "public.reasoning_tools": [ + "b9b972c3-1415-56ea-a7b3-58e760ede13e" + ], + "public.sources": [ + "0dc6a4d6-c1e0-5919-a0cc-cdc494fbdc26", + "473eb14f-43a5-5cfa-91c0-416cb8f9985c" + ] + } + }, + "checks": { + "before_after_counts_present": true, + "canonical_row_keys_exact": true, + "canonical_rows_exact": true, + "clone_database_removed": true, + "conflict_transaction_rolled_back": true, + "proposal_applied_at_present": true, + "proposal_id_exact": true, + "proposal_status_applied": true, + "source_database_unchanged": true, + "table_deltas_exact": true + }, + "pass": true, + "proposal": { + "applied_at": "2026-07-12 19:13:07.180112+00", + "applied_by_handle": "kb-apply", + "id": "32ba67f7-99b8-57b5-ac60-502cebdd7170", + "status": "applied" + }, + "rollback_cleanup": { + "clone_database_removed": true, + "conflict_transaction_rolled_back": true, + "leftover_clone_database_count": 0, + "source_database_unchanged": true + }, + "row_counts": { + "actual_deltas": { + "kb_stage.kb_proposals": 0, + "public.claim_edges": 1, + "public.claim_evidence": 2, + "public.claims": 2, + "public.reasoning_tools": 1, + "public.sources": 2 + }, + "after_apply": { + "kb_stage.kb_proposals": 1, + "public.claim_edges": 1, + "public.claim_evidence": 3, + "public.claims": 3, + "public.reasoning_tools": 1, + "public.sources": 3 + }, + "before_apply": { + "kb_stage.kb_proposals": 1, + "public.claim_edges": 0, + "public.claim_evidence": 1, + "public.claims": 1, + "public.reasoning_tools": 0, + "public.sources": 1 + }, + "expected_deltas": { + "kb_stage.kb_proposals": 0, + "public.claim_edges": 1, + "public.claim_evidence": 2, + "public.claims": 2, + "public.reasoning_tools": 1, + "public.sources": 2 + } + }, + "schema": "working-leo.approved-change-strict-receipt.v1" + }, "telegram_messages_sent": false } diff --git a/fixtures/working-leo/document-ingestion-v1.json b/fixtures/working-leo/document-ingestion-v1.json new file mode 100644 index 0000000..1b0a054 --- /dev/null +++ b/fixtures/working-leo/document-ingestion-v1.json @@ -0,0 +1,39 @@ +{ + "schema": "livingip.workingLeoDocumentIngestionFixture.v1", + "source": { + "identity": "document:working-leo-review-gated-composition-v1", + "source_key": "operating_document", + "source_type": "article", + "title": "Working Leo review-gated composition note", + "locator": "fixture://working-leo/document-ingestion-v1", + "body": "Working Leo composition note. A newly captured document may produce claim and evidence candidates, but those candidates are not canonical knowledge.\n\nA staged proposal remains non-canonical until an operator reviews it and a separate guarded apply succeeds. The proposal must retain the source content hash, exact evidence excerpt, and source identity so reviewers can trace every planned row back to the captured artifact.\n\nFor a staging-only rehearsal, pending_review is the terminal state. No public knowledge-base row should be written.", + "metadata": { + "author": "Working Leo canary fixture", + "captured_at": "2026-07-12T00:00:00Z", + "document_kind": "operating_note", + "language": "en" + } + }, + "extraction": { + "claim": { + "claim_key": "staged_proposal_remains_noncanonical", + "type": "structural", + "confidence": 0.99, + "text": "A staged knowledge proposal remains non-canonical until review and guarded apply succeed.", + "body": "A staged proposal remains non-canonical until an operator reviews it and a separate guarded apply succeeds.", + "metadata": { + "extractor": "deterministic_fixture_replay", + "extraction_version": 1, + "needs_research": false + } + }, + "evidence": { + "role": "grounds", + "body": "A staged proposal remains non-canonical until an operator reviews it and a separate guarded apply succeeds.", + "metadata": { + "evidence_kind": "exact_quote", + "section": "paragraph_2" + } + } + } +} diff --git a/scripts/apply_proposal.py b/scripts/apply_proposal.py index 9fcd003..d1b08f8 100644 --- a/scripts/apply_proposal.py +++ b/scripts/apply_proposal.py @@ -85,6 +85,7 @@ from __future__ import annotations import argparse import json +import shutil import subprocess import sys import uuid @@ -857,8 +858,9 @@ def load_password(secrets_file: str) -> str: def run_psql(args: argparse.Namespace, sql: str, password: str) -> str: + docker_binary = shutil.which("docker") or "docker" command = [ - "docker", "exec", "-e", "PGPASSWORD", "-i", args.container, + docker_binary, "exec", "-e", "PGPASSWORD", "-i", args.container, "psql", "-U", args.role, "-h", args.host, "-d", args.db, "-v", "ON_ERROR_STOP=1", "-At", "-q", ] diff --git a/scripts/run_approve_claim_clone_canary.py b/scripts/run_approve_claim_clone_canary.py index be4b17c..6985401 100644 --- a/scripts/run_approve_claim_clone_canary.py +++ b/scripts/run_approve_claim_clone_canary.py @@ -15,6 +15,7 @@ import argparse import hashlib import json import re +import shutil import subprocess import sys import uuid @@ -135,7 +136,7 @@ def _role_psql( password: str, ) -> subprocess.CompletedProcess[str]: command = [ - "docker", + shutil.which("docker") or "docker", "exec", "-e", "PGPASSWORD", @@ -213,26 +214,34 @@ def _schema_copy(container: str, source_db: str, clone_db: str) -> None: def _service_state(service: str) -> dict[str, Any]: - result = _run( - [ - "systemctl", - "show", - service, - "--no-pager", - "-p", - "ActiveState", - "-p", - "SubState", - "-p", - "MainPID", - "-p", - "NRestarts", - "-p", - "ExecMainStartTimestamp", - ], - check=False, - ) - state: dict[str, Any] = {"returncode": result.returncode} + command = [ + "systemctl", + "show", + service, + "--no-pager", + "-p", + "ActiveState", + "-p", + "SubState", + "-p", + "MainPID", + "-p", + "NRestarts", + "-p", + "ExecMainStartTimestamp", + ] + try: + result = _run(command, check=False) + except FileNotFoundError: + return { + "available": False, + "returncode": 127, + "reason": "systemctl_unavailable", + } + state: dict[str, Any] = { + "available": result.returncode == 0, + "returncode": result.returncode, + } for line in result.stdout.splitlines(): key, separator, value = line.partition("=") if separator: @@ -826,6 +835,108 @@ def _table_deltas(before: dict[str, int], after: dict[str, int]) -> dict[str, in return {key: after[key] - before[key] for key in sorted(before)} +def _canonical_row_keys(rows: dict[str, list[dict[str, Any]]]) -> dict[str, Any]: + """Return stable primary/composite keys for every canonical row in a bundle.""" + return { + "public.claims": sorted(row["id"] for row in rows.get("claims", [])), + "public.sources": sorted(row["id"] for row in rows.get("sources", [])), + "public.claim_evidence": sorted( + [ + { + "claim_id": row["claim_id"], + "source_id": row["source_id"], + "role": row["role"], + } + for row in rows.get("claim_evidence", []) + ], + key=lambda row: (row["claim_id"], row["source_id"], row["role"]), + ), + "public.claim_edges": sorted( + [ + { + "from_claim": row["from_claim"], + "to_claim": row["to_claim"], + "edge_type": row["edge_type"], + } + for row in rows.get("claim_edges", []) + ], + key=lambda row: (row["from_claim"], row["to_claim"], row["edge_type"]), + ), + "public.reasoning_tools": sorted( + row["id"] for row in rows.get("reasoning_tools", []) + ), + } + + +def _strict_receipt( + result: dict[str, Any], + expected_rows: dict[str, list[dict[str, Any]]], + expected_table_deltas: dict[str, int], +) -> dict[str, Any]: + """Build the compact pass/fail surface from actual database readbacks.""" + applied = result.get("apply_transition", {}).get("applied_readback") or {} + actual_rows = result.get("row_readback") or {} + expected_keys = _canonical_row_keys(expected_rows) + actual_keys = _canonical_row_keys(actual_rows) + checks = { + "proposal_id_exact": applied.get("id") + == result.get("fixture_ids", {}).get("proposal_id"), + "proposal_status_applied": applied.get("status") == "applied", + "proposal_applied_at_present": bool(applied.get("applied_at")), + "canonical_rows_exact": actual_rows == expected_rows, + "canonical_row_keys_exact": actual_keys == expected_keys, + "before_after_counts_present": ( + isinstance(result.get("clone_counts_before_apply"), dict) + and isinstance(result.get("clone_counts_after_apply"), dict) + ), + "table_deltas_exact": result.get("clone_apply_table_deltas") + == expected_table_deltas, + "conflict_transaction_rolled_back": result.get("checks", {}).get( + "conflict_transaction_rolled_back_exactly" + ) + is True, + "clone_database_removed": ( + result.get("clone_dropped") is True + and result.get("cleanup_readback", {}).get( + "leftover_clone_database_count" + ) + == 0 + ), + "source_database_unchanged": result.get("source_database_mutated") is False, + } + return { + "schema": "working-leo.approved-change-strict-receipt.v1", + "pass": result.get("status") == "pass" and all(checks.values()), + "checks": checks, + "proposal": { + "id": applied.get("id"), + "status": applied.get("status"), + "applied_at": applied.get("applied_at"), + "applied_by_handle": applied.get("applied_by_handle"), + }, + "canonical_row_keys": { + "expected": expected_keys, + "actual": actual_keys, + }, + "row_counts": { + "before_apply": result.get("clone_counts_before_apply"), + "after_apply": result.get("clone_counts_after_apply"), + "expected_deltas": expected_table_deltas, + "actual_deltas": result.get("clone_apply_table_deltas"), + }, + "rollback_cleanup": { + "conflict_transaction_rolled_back": checks[ + "conflict_transaction_rolled_back" + ], + "clone_database_removed": checks["clone_database_removed"], + "leftover_clone_database_count": result.get("cleanup_readback", {}).get( + "leftover_clone_database_count" + ), + "source_database_unchanged": checks["source_database_unchanged"], + }, + } + + def _exact_bundle_readback( container: str, database: str, payload: dict[str, Any] ) -> dict[str, list[dict[str, Any]]]: @@ -1905,6 +2016,18 @@ drop database if exists {clone_db}; f"{type(exc).__name__}: {exc}" ) + gateway_process_observable = ( + result.get("service_before", {}).get("available") is True + and result.get("service_after", {}).get("available") is True + ) + gateway_process_unchanged = ( + result.get("service_before", {}).get("MainPID") + == result.get("service_after", {}).get("MainPID") + and result.get("service_before", {}).get("NRestarts") + == result.get("service_after", {}).get("NRestarts") + if gateway_process_observable + else None + ) result["checks"] = { "security_definer_dependencies_ready": _security_dependencies_ready( result.get("security_definer_readback") or {} @@ -2058,12 +2181,7 @@ drop database if exists {clone_db}; "source_files_unchanged_during_run": ( result.get("source_binding", {}).get("unchanged_during_run") is True ), - "gateway_process_unchanged": ( - result.get("service_before", {}).get("MainPID") - == result.get("service_after", {}).get("MainPID") - and result.get("service_before", {}).get("NRestarts") - == result.get("service_after", {}).get("NRestarts") - ), + "gateway_process_unchanged": gateway_process_unchanged, "clone_cleanup_complete": ( result.get("clone_dropped") is True and result.get("leftover_clone_count") == 0 @@ -2072,9 +2190,11 @@ drop database if exists {clone_db}; result["source_counts_observed_unchanged"] = ( result.get("source_counts_before") == result.get("source_counts_after") ) + result["gateway_process_observable"] = gateway_process_observable result["status"] = ( "pass" - if all(result["checks"].values()) and "error" not in result + if all(value is True for value in result["checks"].values() if value is not None) + and "error" not in result else "fail" ) result["source_database_mutated"] = not all( @@ -2085,16 +2205,24 @@ drop database if exists {clone_db}; "source_table_deltas_exactly_zero", ) ) - result["service_restarted"] = not result["checks"][ - "gateway_process_unchanged" - ] + result["service_restarted"] = ( + None + if gateway_process_unchanged is None + else not gateway_process_unchanged + ) result["post_run_cleanup"] = { "leftover_clone_database_count": result.get("leftover_clone_count"), + "gateway_process_observable": gateway_process_observable, "gateway_active_state": result.get("service_after", {}).get("ActiveState"), "gateway_sub_state": result.get("service_after", {}).get("SubState"), "gateway_main_pid": result.get("service_after", {}).get("MainPID"), "gateway_restart_count": result.get("service_after", {}).get("NRestarts"), } + result["strict_receipt"] = _strict_receipt( + result, expected_rows, expected_table_deltas + ) + if not result["strict_receipt"]["pass"]: + result["status"] = "fail" return result diff --git a/scripts/run_approve_claim_isolated_container_canary.sh b/scripts/run_approve_claim_isolated_container_canary.sh index daf0dc8..a34f3bf 100755 --- a/scripts/run_approve_claim_isolated_container_canary.sh +++ b/scripts/run_approve_claim_isolated_container_canary.sh @@ -6,6 +6,7 @@ source_container="${SOURCE_CONTAINER:-teleo-pg}" source_db="${SOURCE_DB:-teleo}" service="${LEO_SERVICE:-leoclean-gateway.service}" image="${POSTGRES_CANARY_IMAGE:-postgres:16}" +source_tier="${SOURCE_TIER:-live-readonly}" normalization_json="" output="${repo_root}/docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.json" @@ -31,6 +32,10 @@ while [[ $# -gt 0 ]]; do service="$2" shift 2 ;; + --source-tier) + source_tier="$2" + shift 2 + ;; *) echo "unknown argument: $1" >&2 exit 2 @@ -38,6 +43,22 @@ while [[ $# -gt 0 ]]; do esac done +if [[ "$source_tier" != "isolated-local" && "$source_tier" != "live-readonly" ]]; then + echo "--source-tier must be isolated-local or live-readonly" >&2 + exit 2 +fi + +source_network_mode="$(docker inspect -f '{{.HostConfig.NetworkMode}}' "$source_container")" +source_canary_label="$( + docker inspect -f '{{index .Config.Labels "livingip.canary"}}' "$source_container" +)" +if [[ "$source_tier" == "isolated-local" ]]; then + if [[ "$source_network_mode" != "none" || "$source_canary_label" != "working-leo-approved-source" ]]; then + echo "isolated-local source must be networkless and labeled livingip.canary=working-leo-approved-source" >&2 + exit 2 + fi +fi + container="working-leo-approve-claim-$RANDOM-$$" workdir="/tmp/${container}" apply_password="isolated-apply-${RANDOM}-${RANDOM}" @@ -64,8 +85,17 @@ source_counts() { } service_state() { - systemctl show "$service" --no-pager \ - -p ActiveState -p SubState -p MainPID -p NRestarts -p ExecMainStartTimestamp + if ! command -v systemctl >/dev/null 2>&1; then + printf 'Available=false\nReason=systemctl_unavailable\n' + return 0 + fi + local output + if output="$(systemctl show "$service" --no-pager \ + -p ActiveState -p SubState -p MainPID -p NRestarts -p ExecMainStartTimestamp 2>&1)"; then + printf 'Available=true\n%s\n' "$output" + else + printf 'Available=false\nReason=service_readback_failed\n' + fi } mkdir -p "$workdir" "$(dirname "$output")" @@ -73,17 +103,30 @@ source_counts_before="$(source_counts)" service_before="$(service_state)" docker run -d --name "$container" \ + --network none \ + --tmpfs /var/lib/postgresql/data:rw,nosuid,size=512m \ -e POSTGRES_PASSWORD="isolated-postgres-${RANDOM}-${RANDOM}" \ -e POSTGRES_DB=teleo \ "$image" >/dev/null -for _ in $(seq 1 40); do +ready_streak=0 +for _ in $(seq 1 80); do if docker exec "$container" pg_isready -U postgres -d teleo >/dev/null 2>&1; then - break + ready_streak=$((ready_streak + 1)) + if [[ "$ready_streak" -ge 2 ]]; then + break + fi + else + ready_streak=0 fi sleep 0.25 done -docker exec "$container" pg_isready -U postgres -d teleo >/dev/null +if [[ "$ready_streak" -lt 2 ]]; then + echo "disposable Postgres did not become stably ready" >&2 + exit 1 +fi +container_network_mode="$(docker inspect -f '{{.HostConfig.NetworkMode}}' "$container")" +container_mounts_json="$(docker inspect -f '{{json .Mounts}}' "$container")" docker exec "$source_container" pg_dump -U postgres -d "$source_db" \ --schema-only --no-owner --no-privileges >"$workdir/schema.sql" @@ -173,6 +216,11 @@ CONTAINER_NAME_READBACK="$container_name_readback" \ CONTAINER_NAME_READBACK_RC="$container_name_readback_rc" \ OUTER_WORKDIR_LEXISTS="$outer_workdir_lexists" \ CANARY_RC="$canary_rc" \ +SOURCE_TIER="$source_tier" \ +SOURCE_NETWORK_MODE="$source_network_mode" \ +SOURCE_CANARY_LABEL="$source_canary_label" \ +CANARY_NETWORK_MODE="$container_network_mode" \ +CANARY_MOUNTS_JSON="$container_mounts_json" \ python3 - "$output" <<'PY' import hashlib import json @@ -254,9 +302,40 @@ after_counts = json.loads(os.environ["SOURCE_COUNTS_AFTER"]) live_table_deltas = table_deltas(before_counts, after_counts) before_service = service(os.environ["SERVICE_BEFORE"]) after_service = service(os.environ["SERVICE_AFTER"]) -service_stable = all( - before_service.get(key) == after_service.get(key) - for key in ("ActiveState", "SubState", "MainPID", "NRestarts") +source_tier = os.environ["SOURCE_TIER"] +source_network_mode = os.environ["SOURCE_NETWORK_MODE"] +source_canary_label = os.environ["SOURCE_CANARY_LABEL"] +container_network_mode = os.environ["CANARY_NETWORK_MODE"] +container_mounts = json.loads(os.environ["CANARY_MOUNTS_JSON"]) +container_volume_mounts = [ + mount for mount in container_mounts if mount.get("Type") == "volume" +] +container_isolated = ( + container_network_mode == "none" and not container_volume_mounts +) +source_tier_enforced = ( + source_tier != "isolated-local" + or ( + source_network_mode == "none" + and source_canary_label == "working-leo-approved-source" + ) +) +service_observable = ( + before_service.get("Available") == "true" + and after_service.get("Available") == "true" +) +service_stable = ( + all( + before_service.get(key) == after_service.get(key) + for key in ("ActiveState", "SubState", "MainPID", "NRestarts") + ) + if service_observable + else None +) +service_gate_passes = ( + service_stable is True + if source_tier == "live-readonly" + else service_stable is not False ) container_absent = ( int(os.environ["CONTAINER_NAME_READBACK_RC"]) == 0 @@ -277,15 +356,22 @@ inner_runtime_pass = data.get("status") == "pass" and int(os.environ["CANARY_RC" outer_ok = ( before_counts == after_counts and all(delta == 0 for delta in live_table_deltas.values()) - and service_stable + and service_gate_passes and container_absent and workdir_absent and source_binding_ok and stale_ephemeral_paths_absent + and container_isolated + and source_tier_enforced ) -data["required_tier"] = "T3_live_readonly" -data["required_tiers"] = ["T2_runtime", "T3_live_readonly"] -data["runtime_scope"] = "isolated_postgres_container_from_readonly_live_schema" +if source_tier == "isolated-local": + data["required_tier"] = "T2_runtime" + data["required_tiers"] = ["T2_runtime"] + data["runtime_scope"] = "isolated_postgres_container_from_readonly_local_fixture" +else: + data["required_tier"] = "T3_live_readonly" + data["required_tiers"] = ["T2_runtime", "T3_live_readonly"] + data["runtime_scope"] = "isolated_postgres_container_from_readonly_live_schema" data["outer_isolation"] = { "source_container": os.environ.get("SOURCE_CONTAINER", "teleo-pg"), "source_database": os.environ.get("SOURCE_DB", "teleo"), @@ -295,7 +381,22 @@ data["outer_isolation"] = { "source_counts_unchanged": before_counts == after_counts, "service_before": before_service, "service_after": after_service, + "service_required": source_tier == "live-readonly", + "service_observable": service_observable, "service_stable": service_stable, + "service_gate_passes": service_gate_passes, + "source_boundary": { + "source_tier": source_tier, + "network_mode": source_network_mode, + "canary_label": source_canary_label, + "tier_enforced": source_tier_enforced, + }, + "container_isolation": { + "network_mode": container_network_mode, + "volume_mounts": container_volume_mounts, + "network_disabled": container_network_mode == "none", + "no_docker_volumes": not container_volume_mounts, + }, "cleanup_readback": { "container_remove_returncode": int(os.environ["OUTER_CONTAINER_REMOVE_RC"]), "container_name_query_returncode": int( @@ -312,14 +413,24 @@ data["checks"]["outer_live_counts_exactly_unchanged"] = before_counts == after_c data["checks"]["outer_live_table_deltas_exactly_zero"] = all( delta == 0 for delta in live_table_deltas.values() ) -data["checks"]["outer_service_stable"] = service_stable +data["checks"]["outer_service_observed_if_required"] = ( + source_tier != "live-readonly" or service_observable +) +data["checks"]["outer_service_stable_if_observed"] = service_gate_passes data["checks"]["outer_container_absent_independent_readback"] = container_absent data["checks"]["outer_workdir_absent_independent_readback"] = workdir_absent data["checks"]["source_binding_independently_verified"] = source_binding_ok data["checks"]["stale_ephemeral_paths_absent"] = stale_ephemeral_paths_absent +data["checks"]["outer_source_tier_enforced"] = source_tier_enforced +data["checks"]["outer_container_network_disabled"] = ( + container_network_mode == "none" +) +data["checks"]["outer_container_has_no_docker_volumes"] = not container_volume_mounts data["checks"]["outer_isolation_complete"] = outer_ok if outer_ok and inner_runtime_pass: - data["current_tier"] = "T3_live_readonly" + data["current_tier"] = ( + "T2_runtime" if source_tier == "isolated-local" else "T3_live_readonly" + ) else: data["status"] = "fail" data["current_tier"] = "T2_runtime" if inner_runtime_pass else "T1_model" diff --git a/scripts/run_leo_local_ingestion_proposal_canary.py b/scripts/run_leo_local_ingestion_proposal_canary.py new file mode 100644 index 0000000..89270dc --- /dev/null +++ b/scripts/run_leo_local_ingestion_proposal_canary.py @@ -0,0 +1,519 @@ +#!/usr/bin/env python3 +"""Run a document-ingestion-to-staged-proposal canary in disposable local Postgres.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +import shutil +import subprocess +import sys +import time +import uuid +from pathlib import Path +from typing import Any + +HERE = Path(__file__).resolve().parent +REPO_ROOT = HERE.parent +sys.path.insert(0, str(HERE)) + +import apply_proposal as ap # noqa: E402 +import stage_normalized_proposal as normalized_stage # noqa: E402 + +SCHEMA = "livingip.workingLeoLocalIngestionProposalCanary.v1" +FIXTURE_SCHEMA = "livingip.workingLeoDocumentIngestionFixture.v1" +DEFAULT_FIXTURE = REPO_ROOT / "fixtures" / "working-leo" / "document-ingestion-v1.json" +CONTAINER_LABEL = "livingip.canary=working-leo-local-ingestion" + + +class CanaryError(RuntimeError): + pass + + +def sha256_bytes(value: bytes) -> str: + return hashlib.sha256(value).hexdigest() + + +def canonical_sha256(value: Any) -> str: + return sha256_bytes(json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=True).encode()) + + +def stable_uuid(artifact_sha256: str, label: str) -> str: + return str(uuid.uuid5(uuid.NAMESPACE_URL, f"livingip:working-leo-ingestion:{artifact_sha256}:{label}")) + + +def load_fixture(path: Path) -> tuple[dict[str, Any], dict[str, Any]]: + raw = path.read_bytes() + try: + fixture = json.loads(raw) + except json.JSONDecodeError as exc: + raise CanaryError(f"fixture is not valid JSON: {exc}") from exc + if not isinstance(fixture, dict) or fixture.get("schema") != FIXTURE_SCHEMA: + raise CanaryError(f"fixture schema must be {FIXTURE_SCHEMA}") + source = fixture.get("source") + extraction = fixture.get("extraction") + claim = extraction.get("claim") if isinstance(extraction, dict) else None + evidence = extraction.get("evidence") if isinstance(extraction, dict) else None + if not all(isinstance(item, dict) for item in (source, claim, evidence)): + raise CanaryError("fixture requires source, extraction.claim, and extraction.evidence objects") + required_source = ("identity", "source_key", "source_type", "title", "locator", "body", "metadata") + required_claim = ("claim_key", "type", "confidence", "text", "body", "metadata") + required_evidence = ("role", "body", "metadata") + for label, value, required in ( + ("source", source, required_source), + ("claim", claim, required_claim), + ("evidence", evidence, required_evidence), + ): + missing = [key for key in required if value.get(key) in (None, "")] + if missing: + raise CanaryError(f"fixture {label} is missing: {', '.join(missing)}") + if not isinstance(value.get("metadata"), dict): + raise CanaryError(f"fixture {label}.metadata must be an object") + if claim["body"] not in source["body"]: + raise CanaryError("extracted claim body must be an exact substring of source.body") + if evidence["body"] not in source["body"]: + raise CanaryError("extracted evidence body must be an exact substring of source.body") + artifact_sha256 = sha256_bytes(raw) + source_content_sha256 = sha256_bytes(source["body"].encode()) + return fixture, { + "path": str(path.resolve()), + "artifact_sha256": artifact_sha256, + "source_content_sha256": source_content_sha256, + "source_identity": source["identity"], + } + + +def build_row_ids(artifact_sha256: str) -> dict[str, str]: + return { + "source_capture_id": stable_uuid(artifact_sha256, "source-capture"), + "claim_extraction_id": stable_uuid(artifact_sha256, "claim-extraction"), + "evidence_extraction_id": stable_uuid(artifact_sha256, "evidence-extraction"), + "parent_proposal_id": stable_uuid(artifact_sha256, "rich-parent-proposal"), + } + + +def build_parent_packet( + fixture: dict[str, Any], input_receipt: dict[str, Any], row_ids: dict[str, str] +) -> dict[str, Any]: + source = fixture["source"] + claim = fixture["extraction"]["claim"] + evidence = fixture["extraction"]["evidence"] + parent_source_ref = ( + f"local-ingestion:{input_receipt['artifact_sha256']}:" + f"source={row_ids['source_capture_id']}:claim={row_ids['claim_extraction_id']}:" + f"evidence={row_ids['evidence_extraction_id']}" + ) + return { + "id": row_ids["parent_proposal_id"], + "proposal_type": "attach_evidence", + "status": "pending_review", + "proposed_by_handle": "leo", + "proposed_by_agent_id": None, + "channel": "local_ingestion_canary", + "source_ref": parent_source_ref, + "rationale": "Stage one hash-bound claim/evidence extraction from a captured local document fixture.", + "payload": { + "claim_candidates": [ + { + "claim_key": claim["claim_key"], + "type": claim["type"], + "confidence": claim["confidence"], + "text": claim["text"], + "body": claim["body"], + "evidence_tier": "isolated_fixture", + "needs_research": claim["metadata"].get("needs_research", False), + "evidence": [{"source_key": source["source_key"], "role": evidence["role"]}], + "edges": [], + } + ], + "source_candidates": [ + { + "source_key": source["source_key"], + "source_type": source["source_type"], + "title": source["title"], + "storage_path": input_receipt["path"], + "url": None, + "source_quality": "local realistic ingestion fixture", + "key_excerpt": evidence["body"], + "content_sha256": input_receipt["source_content_sha256"], + } + ], + "dedupe_conflict_assessment": { + "database_search_query": claim["claim_key"].replace("_", " "), + "potential_existing_claim_ids": [], + "conflicts": [], + }, + }, + } + + +def build_schema_sql() -> str: + return r"""\set ON_ERROR_STOP on +create schema kb_canary; +create schema kb_stage; +create table kb_canary.source_captures ( + id uuid primary key, + source_identity text not null unique, + source_type text not null, + title text not null, + locator text not null, + artifact_path text not null, + artifact_sha256 text not null check (artifact_sha256 ~ '^[0-9a-f]{64}$'), + content_sha256 text not null check (content_sha256 ~ '^[0-9a-f]{64}$'), + body text not null, + metadata jsonb not null +); +create table kb_canary.claim_extractions ( + id uuid primary key, + source_capture_id uuid not null references kb_canary.source_captures(id), + claim_key text not null, + body text not null, + metadata jsonb not null +); +create table kb_canary.evidence_extractions ( + id uuid primary key, + claim_extraction_id uuid not null references kb_canary.claim_extractions(id), + source_capture_id uuid not null references kb_canary.source_captures(id), + role text not null, + body text not null, + metadata jsonb not null +); +create table kb_stage.kb_proposals ( + id uuid primary key, + proposal_type text not null, + status text not null, + proposed_by_handle text, + proposed_by_agent_id uuid, + channel text not null, + source_ref text not null, + rationale text not null, + payload jsonb not null, + reviewed_by_handle text, + reviewed_by_agent_id uuid, + reviewed_at timestamptz, + review_note text, + applied_by_handle text, + applied_by_agent_id uuid, + applied_at timestamptz +); +""" + + +def build_capture_sql(fixture: dict[str, Any], input_receipt: dict[str, Any], row_ids: dict[str, str]) -> str: + source = fixture["source"] + claim = fixture["extraction"]["claim"] + evidence = fixture["extraction"]["evidence"] + q = ap.sql_literal + claim_metadata = { + **claim["metadata"], + "claim_type": claim["type"], + "confidence": claim["confidence"], + "text": claim["text"], + } + return rf"""\set ON_ERROR_STOP on +begin; +insert into kb_canary.source_captures + (id, source_identity, source_type, title, locator, artifact_path, + artifact_sha256, content_sha256, body, metadata) +values + ({q(row_ids["source_capture_id"])}::uuid, {q(source["identity"])}, {q(source["source_type"])}, + {q(source["title"])}, {q(source["locator"])}, {q(input_receipt["path"])}, + {q(input_receipt["artifact_sha256"])}, {q(input_receipt["source_content_sha256"])}, + {q(source["body"])}, {q(json.dumps(source["metadata"], sort_keys=True))}::jsonb); +insert into kb_canary.claim_extractions + (id, source_capture_id, claim_key, body, metadata) +values + ({q(row_ids["claim_extraction_id"])}::uuid, {q(row_ids["source_capture_id"])}::uuid, + {q(claim["claim_key"])}, {q(claim["body"])}, {q(json.dumps(claim_metadata, sort_keys=True))}::jsonb); +insert into kb_canary.evidence_extractions + (id, claim_extraction_id, source_capture_id, role, body, metadata) +values + ({q(row_ids["evidence_extraction_id"])}::uuid, {q(row_ids["claim_extraction_id"])}::uuid, + {q(row_ids["source_capture_id"])}::uuid, {q(evidence["role"])}, {q(evidence["body"])}, + {q(json.dumps(evidence["metadata"], sort_keys=True))}::jsonb); +commit; +""" + + +def build_readback_sql(row_ids: dict[str, str], proposal_id: str) -> str: + q = ap.sql_literal + return rf"""\set ON_ERROR_STOP on +begin transaction read only; +select jsonb_build_object( + 'source_capture', (select to_jsonb(s) from kb_canary.source_captures s + where id = {q(row_ids["source_capture_id"])}::uuid), + 'claim_extraction', (select to_jsonb(c) from kb_canary.claim_extractions c + where id = {q(row_ids["claim_extraction_id"])}::uuid), + 'evidence_extraction', (select to_jsonb(e) from kb_canary.evidence_extractions e + where id = {q(row_ids["evidence_extraction_id"])}::uuid), + 'staged_proposal', (select to_jsonb(p) from kb_stage.kb_proposals p + where id = {q(proposal_id)}::uuid), + 'counts', jsonb_build_object( + 'source_captures', (select count(*) from kb_canary.source_captures), + 'claim_extractions', (select count(*) from kb_canary.claim_extractions), + 'evidence_extractions', (select count(*) from kb_canary.evidence_extractions), + 'staged_proposals', (select count(*) from kb_stage.kb_proposals) + ) +)::text; +rollback; +""" + + +class DockerPostgres: + def __init__(self, name: str) -> None: + self.name = name + self.docker = shutil.which("docker") + if not self.docker: + raise CanaryError("docker executable is unavailable") + self.started = False + self.volume_mounts: list[dict[str, Any]] = [] + + def _run( + self, args: list[str], *, input_text: str | None = None, check: bool = True + ) -> subprocess.CompletedProcess[str]: + result = subprocess.run([self.docker, *args], input=input_text, text=True, capture_output=True, check=False) + if check and result.returncode != 0: + detail = (result.stderr or result.stdout).strip() + raise CanaryError(f"docker {' '.join(args[:3])} failed ({result.returncode}): {detail}") + return result + + def start(self) -> dict[str, Any]: + result = self._run( + [ + "run", + "--rm", + "-d", + "--name", + self.name, + "--network", + "none", + "--label", + CONTAINER_LABEL, + "--tmpfs", + "/var/lib/postgresql/data:rw,nosuid,size=256m", + "-e", + "POSTGRES_HOST_AUTH_METHOD=trust", + "-e", + "POSTGRES_DB=teleo", + "postgres:16-alpine", + ] + ) + self.started = True + container_id = result.stdout.strip() + deadline = time.monotonic() + 30 + ready_streak = 0 + while time.monotonic() < deadline: + ready = self._run(["exec", self.name, "pg_isready", "-U", "postgres", "-d", "teleo"], check=False) + if ready.returncode == 0: + ready_streak += 1 + if ready_streak >= 2: + break + else: + ready_streak = 0 + time.sleep(0.25) + else: + raise CanaryError("disposable Postgres did not become ready within 30 seconds") + inspect = json.loads(self._run(["inspect", self.name]).stdout)[0] + if inspect["HostConfig"]["NetworkMode"] != "none": + raise CanaryError("disposable Postgres must use network mode none") + if inspect["Config"]["Labels"].get("livingip.canary") != "working-leo-local-ingestion": + raise CanaryError("disposable Postgres is missing its canary label") + self.volume_mounts = [ + { + "type": mount.get("Type"), + "name": mount.get("Name"), + "destination": mount.get("Destination"), + } + for mount in inspect.get("Mounts", []) + if mount.get("Type") == "volume" + ] + if self.volume_mounts: + raise CanaryError("disposable Postgres unexpectedly created a Docker volume") + return { + "container_id": container_id, + "name": self.name, + "image": inspect["Config"]["Image"], + "network_mode": inspect["HostConfig"]["NetworkMode"], + "tmpfs_data_dir": "/var/lib/postgresql/data" in inspect["HostConfig"].get("Tmpfs", {}), + "docker_volume_mounts": self.volume_mounts, + "canary_label": inspect["Config"]["Labels"].get("livingip.canary"), + } + + def psql(self, sql: str) -> str: + result = self._run( + ["exec", "-i", self.name, "psql", "-U", "postgres", "-d", "teleo", "-Atq"], + input_text=sql, + ) + return result.stdout.strip() + + def psql_json(self, sql: str) -> dict[str, Any]: + output = self.psql(sql) + lines = [line for line in output.splitlines() if line.strip()] + if not lines: + raise CanaryError("Postgres readback returned no JSON") + try: + value = json.loads(lines[-1]) + except json.JSONDecodeError as exc: + raise CanaryError(f"Postgres readback was not JSON: {lines[-1]}") from exc + if not isinstance(value, dict): + raise CanaryError("Postgres readback must be a JSON object") + return value + + def cleanup(self) -> dict[str, Any]: + remove = self._run(["rm", "-f", self.name], check=False) if self.started else None + inspect = self._run(["inspect", self.name], check=False) + return { + "remove_attempted": self.started, + "remove_returncode": remove.returncode if remove else None, + "container_absent": inspect.returncode != 0, + "docker_volume_mounts_observed": self.volume_mounts, + "anonymous_or_named_volume_created": bool(self.volume_mounts), + } + + +def proposal_links(readback: dict[str, Any], input_receipt: dict[str, Any]) -> dict[str, Any]: + proposal = readback["staged_proposal"] + apply_payload = proposal["payload"]["apply_payload"] + source_rows = apply_payload["sources"] + evidence_rows = apply_payload["evidence"] + return { + "proposal_id": proposal["id"], + "proposal_status": proposal["status"], + "proposal_source_ref": proposal["source_ref"], + "planned_claim_ids": [row["id"] for row in apply_payload["claims"]], + "planned_source_ids": [row["id"] for row in source_rows], + "planned_evidence_keys": [ + {"claim_id": row["claim_id"], "source_id": row["source_id"], "role": row["role"]} for row in evidence_rows + ], + "source_content_hash_matches": any( + row.get("hash") == input_receipt["source_content_sha256"] for row in source_rows + ), + "parent_source_ref_embedded": any( + readback["source_capture"]["artifact_sha256"] in str(row.get("excerpt")) + and readback["source_capture"]["id"] in str(row.get("excerpt")) + and readback["claim_extraction"]["id"] in str(row.get("excerpt")) + and readback["evidence_extraction"]["id"] in str(row.get("excerpt")) + for row in source_rows + ), + } + + +def evaluate_checks( + fixture: dict[str, Any], input_receipt: dict[str, Any], row_ids: dict[str, str], readback: dict[str, Any] +) -> dict[str, bool]: + source = readback.get("source_capture") or {} + claim = readback.get("claim_extraction") or {} + evidence = readback.get("evidence_extraction") or {} + proposal = readback.get("staged_proposal") or {} + links = proposal_links(readback, input_receipt) + return { + "input_artifact_hash_persisted": source.get("artifact_sha256") == input_receipt["artifact_sha256"], + "source_content_hash_persisted": source.get("content_sha256") == input_receipt["source_content_sha256"], + "source_identity_persisted": source.get("source_identity") == input_receipt["source_identity"], + "claim_links_to_source_capture": claim.get("source_capture_id") == row_ids["source_capture_id"], + "claim_body_and_metadata_persisted": ( + claim.get("body") == fixture["extraction"]["claim"]["body"] + and claim.get("metadata", {}).get("text") == fixture["extraction"]["claim"]["text"] + ), + "evidence_links_to_claim_and_source": ( + evidence.get("claim_extraction_id") == row_ids["claim_extraction_id"] + and evidence.get("source_capture_id") == row_ids["source_capture_id"] + ), + "evidence_body_and_metadata_persisted": ( + evidence.get("body") == fixture["extraction"]["evidence"]["body"] + and evidence.get("metadata") == fixture["extraction"]["evidence"]["metadata"] + ), + "one_row_per_ingestion_stage": readback.get("counts") + == {"source_captures": 1, "claim_extractions": 1, "evidence_extractions": 1, "staged_proposals": 1}, + "proposal_is_pending_review": proposal.get("status") == "pending_review", + "proposal_has_source_ref": bool(proposal.get("source_ref")), + "proposal_payload_contains_input_hash": links["source_content_hash_matches"], + "proposal_payload_contains_capture_row_linkage": links["parent_source_ref_embedded"], + "no_review_or_apply_metadata": all( + proposal.get(key) is None + for key in ("reviewed_by_handle", "reviewed_at", "applied_by_handle", "applied_at") + ), + } + + +def run_canary(fixture_path: Path, output: Path | None = None) -> dict[str, Any]: + fixture, input_receipt = load_fixture(fixture_path) + row_ids = build_row_ids(input_receipt["artifact_sha256"]) + parent = build_parent_packet(fixture, input_receipt, row_ids) + child = normalized_stage.prepare_normalized_child(parent) + container_name = f"working-leo-ingest-{uuid.uuid4().hex[:12]}" + postgres = DockerPostgres(container_name) + receipt: dict[str, Any] = { + "schema": SCHEMA, + "status": "fail", + "required_tier": "isolated_realistic_ingestion_to_proposal", + "input": input_receipt, + "row_ids": row_ids, + "production_mutation_attempted": False, + "canonical_apply_attempted": False, + } + try: + receipt["environment"] = postgres.start() + postgres.psql(build_schema_sql()) + postgres.psql(build_capture_sql(fixture, input_receipt, row_ids)) + stage_result = postgres.psql_json(normalized_stage.build_stage_sql(child)) + readback = postgres.psql_json(build_readback_sql(row_ids, child["id"])) + checks = evaluate_checks(fixture, input_receipt, row_ids, readback) + receipt.update( + { + "stage_command_result": stage_result, + "rows": readback, + "row_link_fields_proven": proposal_links(readback, input_receipt), + "checks": checks, + "status": "pass" if all(checks.values()) else "fail", + } + ) + except (CanaryError, OSError, ValueError, KeyError) as exc: + receipt["error"] = {"type": type(exc).__name__, "message": str(exc)} + finally: + receipt["cleanup"] = postgres.cleanup() + receipt["cleanup"]["network_mode_none"] = ( + receipt.get("environment", {}).get("network_mode") == "none" + ) + receipt["cleanup"]["no_production_target_referenced"] = receipt[ + "cleanup" + ]["network_mode_none"] + if not all( + ( + receipt["cleanup"]["container_absent"], + receipt["cleanup"]["network_mode_none"], + ) + ): + receipt["status"] = "fail" + receipt["strongest_claim"] = ( + "A realistic local document fixture was hash-captured, replayed through deterministic claim/evidence " + "extraction, normalized by the existing rich-proposal normalizer, and staged/read back as one " + "pending_review proposal in disposable networkless Postgres." + ) + receipt["residual_gap"] = ( + "This does not prove live generative extraction, arbitrary document coverage, canonical apply, or any " + "hosted/production runtime." + ) + if output: + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text(json.dumps(receipt, indent=2, sort_keys=True) + "\n", encoding="utf-8") + return receipt + + +def parse_args(argv: list[str] | None = None) -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--fixture", type=Path, default=DEFAULT_FIXTURE) + parser.add_argument("--output", type=Path) + return parser.parse_args(argv) + + +def main(argv: list[str] | None = None) -> int: + args = parse_args(argv) + receipt = run_canary(args.fixture.resolve(), args.output.resolve() if args.output else None) + print(json.dumps(receipt, sort_keys=True, separators=(",", ":"))) + return 0 if receipt["status"] == "pass" else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/test_run_approve_claim_clone_canary.py b/tests/test_run_approve_claim_clone_canary.py new file mode 100644 index 0000000..a978da0 --- /dev/null +++ b/tests/test_run_approve_claim_clone_canary.py @@ -0,0 +1,79 @@ +"""Focused tests for the strict approved-change clone receipt.""" + +from __future__ import annotations + +import sys +from pathlib import Path + +import pytest + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "scripts")) + +import run_approve_claim_clone_canary as canary # noqa: E402 + + +def _passing_result(expected_rows: dict, expected_deltas: dict) -> dict: + proposal_id = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa" + return { + "status": "pass", + "fixture_ids": {"proposal_id": proposal_id}, + "apply_transition": { + "applied_readback": { + "id": proposal_id, + "status": "applied", + "applied_at": "2026-07-12 12:00:00+00", + "applied_by_handle": "kb-apply", + } + }, + "row_readback": expected_rows, + "clone_counts_before_apply": {key: 0 for key in expected_deltas}, + "clone_counts_after_apply": expected_deltas, + "clone_apply_table_deltas": expected_deltas, + "clone_dropped": True, + "cleanup_readback": {"leftover_clone_database_count": 0}, + "source_database_mutated": False, + "checks": {"conflict_transaction_rolled_back_exactly": True}, + } + + +def test_service_state_records_unavailable_systemctl(monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setattr( + canary, + "_run", + lambda *_args, **_kwargs: (_ for _ in ()).throw(FileNotFoundError()), + ) + + assert canary._service_state("unused.service") == { + "available": False, + "returncode": 127, + "reason": "systemctl_unavailable", + } + + +def test_strict_receipt_requires_exact_ids_counts_applied_at_and_cleanup() -> None: + expected_rows = canary._expected_bundle_rows(canary.build_fixture("unit")["apply_payload"]) + expected_deltas = canary._expected_table_deltas(expected_rows) + result = _passing_result(expected_rows, expected_deltas) + + receipt = canary._strict_receipt(result, expected_rows, expected_deltas) + + assert receipt["pass"] is True + assert receipt["proposal"]["status"] == "applied" + assert receipt["proposal"]["applied_at"] + assert receipt["canonical_row_keys"]["actual"] == receipt["canonical_row_keys"]["expected"] + assert receipt["row_counts"]["actual_deltas"] == expected_deltas + assert receipt["rollback_cleanup"]["clone_database_removed"] is True + + result["apply_transition"]["applied_readback"]["applied_at"] = None + result["row_readback"] = {**expected_rows, "claims": []} + result["clone_apply_table_deltas"] = {**expected_deltas, "public.claims": 0} + result["clone_dropped"] = False + + failed = canary._strict_receipt(result, expected_rows, expected_deltas) + + assert failed["pass"] is False + assert failed["checks"]["proposal_applied_at_present"] is False + assert failed["checks"]["canonical_row_keys_exact"] is False + assert failed["checks"]["table_deltas_exact"] is False + assert failed["checks"]["clone_database_removed"] is False diff --git a/tests/test_run_approve_claim_clone_canary_macos_path.py b/tests/test_run_approve_claim_clone_canary_macos_path.py new file mode 100644 index 0000000..ad472db --- /dev/null +++ b/tests/test_run_approve_claim_clone_canary_macos_path.py @@ -0,0 +1,102 @@ +"""Platform-path regression tests for the approved-change clone canary.""" + +from __future__ import annotations + +import subprocess +import sys +from pathlib import Path + +import pytest + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "scripts")) +WRAPPER = ROOT / "scripts" / "run_approve_claim_isolated_container_canary.sh" + +import apply_proposal as apply # noqa: E402 +import run_approve_claim_clone_canary as canary # noqa: E402 + + +def test_role_psql_resolves_docker_before_scrubbing_path( + monkeypatch: pytest.MonkeyPatch, +) -> None: + captured: dict[str, object] = {} + + monkeypatch.setattr( + canary.shutil, + "which", + lambda executable: "/opt/homebrew/bin/docker" + if executable == "docker" + else None, + ) + + def fake_run(command: list[str], **kwargs: object) -> subprocess.CompletedProcess[str]: + captured["command"] = command + captured["env"] = kwargs["env"] + return subprocess.CompletedProcess(command, 0, "", "") + + monkeypatch.setattr(canary, "_run", fake_run) + + canary._role_psql( + "local-postgres", + "teleo", + "select 1;", + role="kb_apply", + password="test-only-password", + ) + + assert captured["command"][0] == "/opt/homebrew/bin/docker" + assert captured["env"] == { + "PGPASSWORD": "test-only-password", + "PATH": "/usr/bin:/bin:/usr/local/bin", + } + + +def test_apply_tool_resolves_docker_before_scrubbing_path( + monkeypatch: pytest.MonkeyPatch, +) -> None: + captured: dict[str, object] = {} + monkeypatch.setattr( + apply.shutil, + "which", + lambda executable: "/opt/homebrew/bin/docker" + if executable == "docker" + else None, + ) + + def fake_run(command: list[str], **kwargs: object) -> subprocess.CompletedProcess[str]: + captured["command"] = command + captured["env"] = kwargs["env"] + return subprocess.CompletedProcess(command, 0, "ok", "") + + monkeypatch.setattr(apply.subprocess, "run", fake_run) + args = type( + "Args", + (), + { + "container": "local-postgres", + "role": "kb_apply", + "host": "127.0.0.1", + "db": "teleo", + }, + )() + + assert apply.run_psql(args, "select 1;", "test-only-password") == "ok" + assert captured["command"][0] == "/opt/homebrew/bin/docker" + assert captured["env"] == { + "PGPASSWORD": "test-only-password", + "PATH": "/usr/bin:/bin:/usr/local/bin", + } + + +def test_outer_wrapper_enforces_local_source_and_networkless_tmpfs() -> None: + text = WRAPPER.read_text(encoding="utf-8") + + assert 'source_canary_label" != "working-leo-approved-source"' in text + assert "--network none" in text + assert "--tmpfs /var/lib/postgresql/data:rw,nosuid,size=512m" in text + assert 'CANARY_NETWORK_MODE="$container_network_mode"' in text + assert 'CANARY_MOUNTS_JSON="$container_mounts_json"' in text + assert 'data["checks"]["outer_source_tier_enforced"]' in text + assert 'data["checks"]["outer_container_network_disabled"]' in text + assert 'data["checks"]["outer_container_has_no_docker_volumes"]' in text + assert 'source_tier != "live-readonly" or service_observable' in text diff --git a/tests/test_run_leo_local_ingestion_proposal_canary.py b/tests/test_run_leo_local_ingestion_proposal_canary.py new file mode 100644 index 0000000..ec57f0b --- /dev/null +++ b/tests/test_run_leo_local_ingestion_proposal_canary.py @@ -0,0 +1,164 @@ +from __future__ import annotations + +import copy +import json +import sys +from pathlib import Path + +import pytest + +REPO_ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(REPO_ROOT / "scripts")) + +import run_leo_local_ingestion_proposal_canary as canary # noqa: E402 + + +def _loaded() -> tuple[dict, dict, dict]: + fixture, input_receipt = canary.load_fixture(canary.DEFAULT_FIXTURE) + row_ids = canary.build_row_ids(input_receipt["artifact_sha256"]) + return fixture, input_receipt, row_ids + + +def test_fixture_is_realistic_hash_bound_and_exactly_evidenced() -> None: + fixture, input_receipt, row_ids = _loaded() + + assert fixture["extraction"]["evidence"]["body"] in fixture["source"]["body"] + assert len(input_receipt["artifact_sha256"]) == 64 + assert len(input_receipt["source_content_sha256"]) == 64 + assert input_receipt["artifact_sha256"] != input_receipt["source_content_sha256"] + assert len(set(row_ids.values())) == 4 + + +def test_fixture_validation_fails_closed_when_evidence_is_not_in_source(tmp_path: Path) -> None: + fixture = json.loads(canary.DEFAULT_FIXTURE.read_text(encoding="utf-8")) + fixture["extraction"]["evidence"]["body"] = "invented evidence" + path = tmp_path / "bad-fixture.json" + path.write_text(json.dumps(fixture), encoding="utf-8") + + with pytest.raises(canary.CanaryError, match="exact substring"): + canary.load_fixture(path) + + +def test_fixture_validation_fails_closed_when_claim_body_is_not_in_source( + tmp_path: Path, +) -> None: + fixture = json.loads(canary.DEFAULT_FIXTURE.read_text(encoding="utf-8")) + fixture["extraction"]["claim"]["body"] = "invented claim body" + path = tmp_path / "bad-claim-fixture.json" + path.write_text(json.dumps(fixture), encoding="utf-8") + + with pytest.raises(canary.CanaryError, match="claim body must be an exact substring"): + canary.load_fixture(path) + + +def test_capture_sql_escapes_quotes_and_backslashes_from_fixture( + tmp_path: Path, +) -> None: + fixture = json.loads(canary.DEFAULT_FIXTURE.read_text(encoding="utf-8")) + fixture["source"]["title"] = "O'Brien\\review" + fixture["source"]["metadata"]["note"] = "quoted ' value \\ path" + path = tmp_path / "quoted-fixture.json" + path.write_text(json.dumps(fixture), encoding="utf-8") + loaded, input_receipt = canary.load_fixture(path) + row_ids = canary.build_row_ids(input_receipt["artifact_sha256"]) + + sql = canary.build_capture_sql(loaded, input_receipt, row_ids) + + assert canary.ap.sql_literal(fixture["source"]["title"]) in sql + assert canary.ap.sql_literal( + json.dumps(fixture["source"]["metadata"], sort_keys=True) + ) in sql + + +def test_parent_normalizes_to_hash_bound_pending_proposal_with_embedded_row_links() -> None: + fixture, input_receipt, row_ids = _loaded() + parent = canary.build_parent_packet(fixture, input_receipt, row_ids) + child = canary.normalized_stage.prepare_normalized_child(parent) + payload = child["payload"]["apply_payload"] + + assert child["status"] == "pending_review" + assert child["proposal_type"] == "approve_claim" + assert len(payload["claims"]) == 1 + assert len(payload["sources"]) == 2 + assert len(payload["evidence"]) == 2 + assert input_receipt["source_content_sha256"] in {row["hash"] for row in payload["sources"]} + excerpts = "\n".join(row["excerpt"] for row in payload["sources"]) + assert input_receipt["artifact_sha256"] in excerpts + assert row_ids["source_capture_id"] in excerpts + assert row_ids["claim_extraction_id"] in excerpts + assert row_ids["evidence_extraction_id"] in excerpts + + +def test_capture_and_stage_sql_never_mutate_canonical_public_tables() -> None: + fixture, input_receipt, row_ids = _loaded() + child = canary.normalized_stage.prepare_normalized_child( + canary.build_parent_packet(fixture, input_receipt, row_ids) + ) + sql = "\n".join( + ( + canary.build_schema_sql(), + canary.build_capture_sql(fixture, input_receipt, row_ids), + canary.normalized_stage.build_stage_sql(child), + ) + ).lower() + + assert "insert into public." not in sql + assert "update public." not in sql + assert "delete from public." not in sql + assert "insert into kb_canary.source_captures" in sql + assert "insert into kb_canary.claim_extractions" in sql + assert "insert into kb_canary.evidence_extractions" in sql + assert "insert into kb_stage.kb_proposals" in sql + + +def test_check_evaluation_requires_every_row_link_and_staging_boundary() -> None: + fixture, input_receipt, row_ids = _loaded() + child = canary.normalized_stage.prepare_normalized_child( + canary.build_parent_packet(fixture, input_receipt, row_ids) + ) + apply_payload = child["payload"]["apply_payload"] + readback = { + "source_capture": { + "id": row_ids["source_capture_id"], + "artifact_sha256": input_receipt["artifact_sha256"], + "content_sha256": input_receipt["source_content_sha256"], + "source_identity": input_receipt["source_identity"], + }, + "claim_extraction": { + "id": row_ids["claim_extraction_id"], + "source_capture_id": row_ids["source_capture_id"], + "body": fixture["extraction"]["claim"]["body"], + "metadata": {"text": fixture["extraction"]["claim"]["text"]}, + }, + "evidence_extraction": { + "id": row_ids["evidence_extraction_id"], + "claim_extraction_id": row_ids["claim_extraction_id"], + "source_capture_id": row_ids["source_capture_id"], + "body": fixture["extraction"]["evidence"]["body"], + "metadata": fixture["extraction"]["evidence"]["metadata"], + }, + "staged_proposal": { + "id": child["id"], + "status": "pending_review", + "source_ref": child["source_ref"], + "payload": {"apply_payload": apply_payload}, + "reviewed_by_handle": None, + "reviewed_at": None, + "applied_by_handle": None, + "applied_at": None, + }, + "counts": { + "source_captures": 1, + "claim_extractions": 1, + "evidence_extractions": 1, + "staged_proposals": 1, + }, + } + + checks = canary.evaluate_checks(fixture, input_receipt, row_ids, readback) + assert all(checks.values()) + broken = copy.deepcopy(readback) + broken["evidence_extraction"]["claim_extraction_id"] = canary.stable_uuid("0" * 64, "wrong") + assert ( + canary.evaluate_checks(fixture, input_receipt, row_ids, broken)["evidence_links_to_claim_and_source"] is False + )