diff --git a/.kaizen/agents/custodian-codex/supervision.json b/.kaizen/agents/custodian-codex/supervision.json index 0beae271..50e073c3 100644 --- a/.kaizen/agents/custodian-codex/supervision.json +++ b/.kaizen/agents/custodian-codex/supervision.json @@ -766,8 +766,8 @@ }, { "proposal_id": "STATE-WP-0095-T06-cluster-frozen-receiving-r1", - "disposition": "pending", - "outcome": "not_executed", + "disposition": "accepted_revised", + "outcome": "succeeded", "proposal_ref": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/proposal-metadata.json", "original_revision": 1, "original_digest_sha256": "5bef9e7818ce1ebc64b81e300b6b40dcfc710a8625d6e0595534f8284dc2052d", @@ -776,21 +776,21 @@ "current_digest_sha256": "63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32", "target": "railiance01 state-hub release/API/MCP and exact-new-trial migration Job only", "expected_result": "Normal owner image promotion makes exact frozen cluster receiving available; API/MCP ready, expected c4 schema and exact three historical parents/15 tasks preserved; only then is later registrar admission eligible. No original TLS/identity native acceptance is inferred.", - "verification_ref": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/FINAL-PROPOSAL.md", + "verification_ref": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json", "rollback_ref": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/MIGRATION-JOB-RECOVERY.md", "cost_estimate_eur": null, "risk_estimate_eur": null, "cost_estimate": "Unknown attributable execution/network/operator recovery cost on existing infrastructure; no zero-cost claim or budget reservation inferred.", "risk_estimate": "Unpriced production coordination outage, message migration locks/data compatibility, retained active migration Job, uncertain connection/lock mapping and recovery time; three-minute Helm wait is not a bound on outage or DB effects. Explicit supervised risk disposition required.", "supervisor": "Bernd Worsch", - "approval_ref": null, - "approved_revision": null, - "approved_digest_sha256": null, - "executed_revision": null, - "executed_digest_sha256": null, + "approval_ref": "e3798419-8aa9-5425-8c08-20df6bd82a19", + "approved_revision": 4, + "approved_digest_sha256": "63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32", + "executed_revision": 4, + "executed_digest_sha256": "63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32", "refinement_or_rescue": true, "promotion_evidence": false, - "reason": "Exact native rollout proposal remains pending. Source preparation, synthetic compatibility and public artifact verification are evidence only; earlier preparation failures and revisions remain one trial.", + "reason": "Founder-approved revision4 executed successfully. Helm76, exact image/module, expected schema, 18 unchanged historical full rows and five rollback-only native cases verified. Original proposal refinements retained; no unchanged-success credit.", "revisions": [ { "revision": 1, @@ -813,6 +813,60 @@ "disposition": "not_submitted_or_unadjudicated", "executed": false } + ], + "approved_digest": "63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32", + "approved_at": "2026-10-16T23:55:32.549865+00:00", + "supervisor_disposition": "Founder approved exact presented revision4 unchanged; original r1 was refined before submission, so this remains accepted_revised for original-trial scoring.", + "approval_scope": "Exact pinned receiver rollout including inbox migration and documented conditional recovery; no authority promotion.", + "executed_digest": "63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32", + "execution_started_at": "2026-10-16T23:57:03.186884+00:00", + "execution_ref": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/execution.json", + "verified_at": "2026-10-17T00:07:47.015454+00:00", + "recovery_required": false, + "post_execution_findings_ref": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/ordinary-pipeline-preservation-finding.json", + "post_execution_finding": "Later ordinary Cluster deep-consistency binding refresh changed three historical parent hashes; original delivered-rollout preservation and five rollback probes passed before that separate pipeline. Further acceptance stays open." + }, + { + "proposal_id": "STATE-WP-0095-T10-frozen-bindings-guard-r1", + "disposition": "pending", + "outcome": "not_executed", + "proposal_ref": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/proposal-metadata.json", + "original_revision": 1, + "original_digest_sha256": "81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932", + "original_digest": "81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932", + "current_revision": 2, + "current_digest_sha256": "5d0ddebc21bcb035809cc8b57f4c2e1ba8ed09204be5b965460e178a90913f1e", + "target": "railiance01/92.205.62.239 state-hub release API/MCP and exact-new-trial migration Job", + "expected_result": "New API binding guard delivered and current-baseline native/whole-pipeline preservation verified, with earlier parent mismatch retained as explicit exception.", + "verification_ref": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/FINAL-PROPOSAL.md", + "rollback_ref": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/RECOVERY.md", + "cost_estimate_eur": null, + "risk_estimate_eur": null, + "cost_estimate": "Unpriced incremental execution and recovery costs on existing infrastructure.", + "risk_estimate": "Unpriced coordination outage, hook lifetime, lock mapping and recovery; reviewed conditional limits stop for attended owner on unknown state.", + "supervisor": "Bernd Worsch", + "approval_ref": null, + "approved_revision": null, + "approved_digest_sha256": null, + "executed_revision": null, + "executed_digest_sha256": null, + "refinement_or_rescue": true, + "promotion_evidence": false, + "related_proposal_id": "STATE-WP-0095-T06-cluster-frozen-receiving-r1", + "reason": "Separate new-code runtime request follows retained ordinary-pipeline and stale-installed-client failures. Six source refinements and real writeback regression remain visible; no extra success or authority is inferred.", + "revision_history": [ + { + "revision": 1, + "digest_sha256": "81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932", + "outcome": "not_executed", + "refinement": "Normal secret scan flagged probe source-hash metadata; original retained locally and by digest." + }, + { + "revision": 2, + "digest_sha256": "5d0ddebc21bcb035809cc8b57f4c2e1ba8ed09204be5b965460e178a90913f1e", + "outcome": "not_executed", + "refinement": "Typed module/SHA256 records; unchanged runtime and probe logic." + } ] } ], diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/conditional-T07-completion-overlay.json b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/conditional-T07-completion-overlay.json new file mode 100644 index 00000000..5085823a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/conditional-T07-completion-overlay.json @@ -0,0 +1,30 @@ +{ + "schema": "statehub.conditional-T07-completion-overlay.v1", + "status": "prepared_not_applied_no_completion_claim", + "source_preimage": { + "path": "workplans/STATE-WP-0095-historical-source-receiving.md", + "sha256": "146caec8f37833d9cd0b509750e5131640725b5617f4b2eede989185e1869d5c" + }, + "guards": [ + "Actual normal cluster owner publication and central receiving status applied, with exact pushed commit receipt", + "RMGR-WP-0019-T06 actually done and source status/UUID projection verified", + "All three exact archived source SHA256 bytes remain equal to frozen manifest", + "All three historical parents/15 tasks full DB row hashes unchanged after normal receiving", + "No missing/unresolved/foreign-holder identity or retirement refusal hidden as success" + ], + "edits_after_guards_only": [ + { + "task_id": "STATE-WP-0095-T07", + "state_hub_task_id": "cfd1ea99-e75b-542e-a434-acefb62f3c7d", + "status": "done", + "evidence": "insert exact actual cluster commit/publication/receiving and preservation receipt refs at activation" + }, + { + "workplan_id": "STATE-WP-0095", + "frontmatter_status": "finished", + "only_if": "all eight retained task IDs done and no unresolved retained work remains" + } + ], + "preserve_all_IDs_UUIDs_history": true, + "normal_owner_commit_push_projection_required": true +} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/manifest.json b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/manifest.json new file mode 100644 index 00000000..080b1005 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/manifest.json @@ -0,0 +1,53 @@ +{ + "schema": "statehub.source-owner-followthrough.v1", + "status": "isolated_source_candidate_not_applied", + "base_revision": "086d79a2736e34b916bd7de3c8a65e2ea38a3d64", + "files": [ + { + "path": "workplans/STATE-WP-0095-historical-source-receiving.md", + "base_sha256": "ef10359cc5974283b5bdbfc602adf14e3c24362adf00640698d2937c6538483a", + "candidate_sha256": "146caec8f37833d9cd0b509750e5131640725b5617f4b2eede989185e1869d5c", + "action": "modify" + }, + { + "path": "Makefile", + "base_sha256": "5584ef94071044cca8215141ecd8aee8d6ae5cfe73e8f5719358c680eb8af0d4", + "candidate_sha256": "c5b70e8d4b8ae70380e0ade1c35f9e7fe80038de10080a4723b21ef07a98001e", + "action": "modify" + }, + { + "path": "deploy/railiance/apps/charts/state-hub/Chart.yaml", + "base_sha256": "7fe02b390ffd2ba4ce6f82bd62df900826826401e31bdc2138dd5bf36b51a6ae", + "candidate_sha256": "61a989fcf277d05ffbececb7332ee3ca1d8f369c72f960ab1bc4dbc6815536b8", + "action": "modify" + }, + { + "path": "deploy/railiance/apps/helm/state-hub-values.yaml", + "base_sha256": "f7cc0e9968598f6ce0faa0d56f62d6817845c3570c18b6ac39ed6561b952b197", + "candidate_sha256": "b51296fc937450f4ecf0ae43243262a631b551389c0d09c8bfe58fa10e2f3ee9", + "action": "modify" + }, + { + "path": "docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json", + "base_sha256": null, + "candidate_sha256": "db6cd6931c5763ff390e54c6eb9430aad2c4c7c9f42dd6652f436e549e6f6297", + "action": "add" + } + ], + "patch_sha256": "sha256:3a2f8446262062a9183aff6f219fd6c300ed447624355cb778bb050cdb14a2b9", + "live_effects": false, + "new_runtime_image": false, + "T06": "done_actual_approved_verified_rollout", + "T07": "wait_until_actual_RMGR19T06_cluster_publication_and_preservation_return", + "T08": "done_source_readiness_preserved", + "generic_chart_default_tag": "empty_required_explicit_pin_unchanged", + "declared_production_image": "main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015", + "preserve_preexisting_dirty": [ + ".custodian-brief.md", + "WORK-RECORDS.md", + "docs/evidence/legacy-meter-weekly-review-20261014.json", + "docs/evidence/legacy-meter-weekly-review-20261015.json", + "docs/evidence/legacy-meter-weekly-review-20261016.json", + "docs/evidence/legacy-meter-weekly-review-20261017.json" + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/state-hub-followthrough.patch b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/state-hub-followthrough.patch new file mode 100644 index 00000000..e44333ab --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/state-hub-followthrough.patch @@ -0,0 +1,199 @@ +--- a/workplans/STATE-WP-0095-historical-source-receiving.md ++++ b/workplans/STATE-WP-0095-historical-source-receiving.md +@@ -199,27 +199,37 @@ + + ```task + id: STATE-WP-0095-T06 +-status: wait ++status: done + priority: high + depends_on: [STATE-WP-0095-T05] +-needs_human: true +-intervention_note: "Review exact committed source, CI image and owner deployment proposal before rollout." ++needs_human: false ++intervention_note: "Exact revision 4 approved and verified; no pending rollout intervention." + state_hub_task_id: "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4" + ``` + +-Use the normal CI image and Helm owner path after exact revision/image pin, +-fresh headroom and reviewed dry-run/diff. API/MCP currently run main-7d99282; +-Helm revision75 is the observed rollback baseline, requiring freshness before +-execution. No deployment assent exists for this successor. Verify delivered +-module hash, health, both readiness checks and expected migrated schema +-c4d5e6f7a8b9; verify exact +-three parents/15 tasks and rejection behavior without committed probe changes. +-Only the verified return unblocks RMGR-WP-0019-T05. The full current image also carries inbox-feed migration c4d5e6f7a8b9, +-although this receiver patch adds none. Helm rollback leaves that migration in +-place; unrelated migration acceptance and old-image compatibility need normal +-owner evidence before rollout approval. Do not run destructive default local +-DB tests; use only exact disposable DB containment. Costs and monetary risk are +-unknown pending exact rollout proposal; no zero-cost or autonomy grant is inferred. ++Completed 2026-10-17 on the founder's approval of exact revision 4 of stable ++proposal STATE-WP-0095-T06-cluster-frozen-receiving-r1 (decision ++ e3798419-8aa9-5425-8c08-20df6bd82a19; approved digest ++ sha256:63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32). ++The ordinary owner Helm path delivered revision 76, runtime source 51bc70d and ++exact image manifest sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015. ++API/MCP Ready and primary/railiance01 health report expected schema ++c4d5e6f7a8b9; delivered historical module sha256:e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2 matches. ++All three parent and 15 task full DB row hashes/columns/UUIDs remained unchanged. ++Five actual native probes passed: preserve, actual foreign-parent holder move, ++nonterminal task, nonterminal parent and missing task. Every probe rolled back; ++a fresh transaction confirmed complete row restoration. The foreign-holder ++case precisely verified historical binding refusal, not the separate global ++UUID-holder creation branch. No committed probe writes were made. ++ ++Evidence: [verified receiving rollout](../docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json). ++This actual receiving return satisfies the prerequisite of RMGR-WP-0019-T05. ++Normal cluster publication and its immutable-source/row return remain T07; ++source readiness and this deployment do not count that later acceptance twice. ++The additive inbox migration is retained; Helm rollback does not downgrade ++schema or stop an active migration Job. Original failures and exact-UID recovery ++limits remain in the referenced approved packet. No TLS recovery/native private ++admission or new autonomy/cost grant is inferred. + + ## Verify ordinary cluster receiving and immutable historical rows + +@@ -256,6 +266,6 @@ + Command-fixture tests verify both requests and preserve other dry-run phases. + Evidence and original refusal remain in the Custodian cluster historical + publication packet, revisions/r2 and r3-readiness. This is completed source +-preparation; T06 remains the explicit native rollout gate. The runtime image ++preparation; T06 separately records the verified actual rollout. The runtime image + continues to be main-51bc70d; Makefile/workplan changes do not create a new + application image or native acceptance. +--- a/Makefile ++++ b/Makefile +@@ -9,7 +9,7 @@ + RAILIANCE_STATE_HUB_NAMESPACE ?= state-hub + RAILIANCE_STATE_HUB_CHART ?= deploy/railiance/apps/charts/state-hub + RAILIANCE_STATE_HUB_VALUES ?= deploy/railiance/apps/helm/state-hub-values.yaml +-RAILIANCE_STATE_HUB_IMAGE_TAG ?= main-0747b4d ++RAILIANCE_STATE_HUB_IMAGE_TAG ?= main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015 + RAILIANCE_STATE_HUB_PLATFORM_DIR ?= deploy/railiance/platform + RAILIANCE_STATE_HUB_APP_MANIFESTS ?= deploy/railiance/apps/manifests + # Codex/WSL non-login shells may not source ~/.profile; keep uv discoverable. +--- a/deploy/railiance/apps/charts/state-hub/Chart.yaml ++++ b/deploy/railiance/apps/charts/state-hub/Chart.yaml +@@ -3,4 +3,4 @@ + description: State Hub API service for private Railiance operation + type: application + version: 0.1.0 +-appVersion: "main-5dd3df9" ++appVersion: "main-51bc70d" +--- a/deploy/railiance/apps/helm/state-hub-values.yaml ++++ b/deploy/railiance/apps/helm/state-hub-values.yaml +@@ -6,7 +6,7 @@ + + image: + repository: forgejo.coulomb.social/coulomb/state-hub +- tag: "main-0747b4d" ++ tag: "main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015" + + ingress: + enabled: false +--- /dev/null ++++ b/docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json +@@ -0,0 +1,102 @@ ++{ ++ "schema": "statehub.cluster-historical-receiving-delivered.v1", ++ "status": "verified", ++ "proposal_id": "STATE-WP-0095-T06-cluster-frozen-receiving-r1", ++ "approved_revision": 4, ++ "approved_digest_sha256": "sha256:63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32", ++ "approval_decision_id": "e3798419-8aa9-5425-8c08-20df6bd82a19", ++ "source_revision": "51bc70d1ff8f25450a8650d8e50caf053093a02e", ++ "readiness_source_revision": "086d79a2736e34b916bd7de3c8a65e2ea38a3d64", ++ "helm_revision": 76, ++ "image_reference": "forgejo.coulomb.social/coulomb/state-hub:main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015", ++ "expected_schema": "c4d5e6f7a8b9", ++ "health": { ++ "status": "ok", ++ "instance_role": "primary", ++ "instance_label": "railiance01", ++ "schema": { ++ "status": "ok", ++ "applied": "c4d5e6f7a8b9", ++ "expected": "c4d5e6f7a8b9" ++ } ++ }, ++ "pods_ready": true, ++ "historical_module_sha256": "sha256:e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2", ++ "historical_preservation_verified": true, ++ "parents": 3, ++ "tasks": 15, ++ "full_historical_rows_equal": true, ++ "native_rollback_probes": { ++ "foreign-holder": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "missing-task": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "nonterminal-parent": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "nonterminal-task": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "preserve": { ++ "full_historical_rows_equal": true, ++ "full_historical_rows_restored": true, ++ "native_outcome_status": "applied", ++ "rolled_back": true, ++ "status": "passed" ++ } ++ }, ++ "native_probe_commits": 0, ++ "fresh_transaction_full_rows_equal": true, ++ "source_receiving_gate_delivered": true, ++ "normal_cluster_publication_verified": false, ++ "registrar_admission_or_cluster_publication_not_inferred": true, ++ "authority_limits": [ ++ "Rollback probe SQL effects rolled back; foreign-holder case is historical-binding refusal, not separate global holder branch.", ++ "Actual historical native receiving is verified; owner-native TLS/private admission remains unresolved.", ++ "Migration schema remains additive; Helm rollback does not downgrade schema or stop an active hook Job." ++ ], ++ "evidence": [ ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/approval-decision.json", ++ "sha256": "sha256:b51554c004daa882f3709f67bdae7f2e939d611120383e61be04ec6969878134" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/helm-return.json", ++ "sha256": "sha256:61727deacf22d37da2d28cbaf04f5a3ddee0f9ff7571c77f1e85dba97963b572" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/delivered-runtime.json", ++ "sha256": "sha256:89681066e8fe139456163ebfafa3efe77ffae8534ea167219230b0a74367f129" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/native-refusal-probes.json", ++ "sha256": "sha256:673ccef965c820704dc310a1bf7832b583c30c3edfeb814528cf892555199172" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-full-row-hashes.json", ++ "sha256": "sha256:75cdd87eef79059ff3f484ed24ca69e285899cdf8d851cc4e472653c417eb0ee" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-full-row-hashes.json", ++ "sha256": "sha256:2156aad18f190384838c27e792706a156a7423391408afbc6107e6c28c5872d8" ++ } ++ ] ++} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/validation.json b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/validation.json new file mode 100644 index 00000000..1e94c920 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/validation.json @@ -0,0 +1,21 @@ +{ + "schema": "statehub-followthrough-source-validation.v1", + "patch_apply_check_exit": 0, + "direct_local_helm_render_exit": 0, + "all3runtime_images_match_promoted_digest": true, + "appVersion": "main-51bc70d", + "cluster_contacted": false, + "production_mutations": false, + "normal_make_render": { + "status": "refused_preexisting_canon_copy_drift", + "guard_not_bypassed": true, + "chart_copy_version": "1.0", + "canon_version": "1.1", + "differences": [ + "category publication", + "purpose history", + "purpose participation" + ], + "scope": "No classification copy edit/guard relaxation included in followthrough." + } +} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/conditional-T07-completion-overlay.json b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/conditional-T07-completion-overlay.json new file mode 100644 index 00000000..cb3200df --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/conditional-T07-completion-overlay.json @@ -0,0 +1,30 @@ +{ + "schema": "statehub.conditional-T07-completion-overlay.v1", + "status": "prepared_not_applied_no_completion_claim", + "source_preimage": { + "path": "workplans/STATE-WP-0095-historical-source-receiving.md", + "sha256": "921716ab00993a79917ae5b4750e5b61ae22af4c4fd410b9ccf2be9ec54560df" + }, + "guards": [ + "Actual normal cluster owner publication and central receiving status applied, with exact pushed commit receipt", + "RMGR-WP-0019-T06 actually done and source status/UUID projection verified", + "All three exact archived source SHA256 bytes remain equal to frozen manifest", + "All three historical parents/15 tasks full DB row hashes unchanged after normal receiving", + "No missing/unresolved/foreign-holder identity or retirement refusal hidden as success" + ], + "edits_after_guards_only": [ + { + "task_id": "STATE-WP-0095-T07", + "state_hub_task_id": "cfd1ea99-e75b-542e-a434-acefb62f3c7d", + "status": "done", + "evidence": "insert exact actual cluster commit/publication/receiving and preservation receipt refs at activation" + }, + { + "workplan_id": "STATE-WP-0095", + "frontmatter_status": "finished", + "only_if": "all eight retained task IDs done and no unresolved retained work remains" + } + ], + "preserve_all_IDs_UUIDs_history": true, + "normal_owner_commit_push_projection_required": true +} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/generated-copy-exact-diff.patch b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/generated-copy-exact-diff.patch new file mode 100644 index 00000000..6578d7b3 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/generated-copy-exact-diff.patch @@ -0,0 +1,28 @@ +--- prior-chart-copy ++++ generated-canon-copy +@@ -13,7 +13,7 @@ + # to match the standard version. CUST-WP-0050 T01. + + standard: "Repo Classification Standard" +-version: "1.0" ++version: "1.1" + canon_id: "canon-repo-classification" + + # category — exactly 1 required (§5) +@@ -24,6 +24,7 @@ + - tooling + - product + - business ++ - publication + + # domain / secondary_domains — primary exactly 1; secondaries 0..n (§6) + domains: +@@ -85,6 +86,8 @@ + - traceability + - documentation + - decision-support ++ - history ++ - participation + platform_and_operations: + - platform + - deployment diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/manifest.json b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/manifest.json new file mode 100644 index 00000000..c2d1f89a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/manifest.json @@ -0,0 +1,61 @@ +{ + "schema": "statehub.source-owner-followthrough.v1", + "status": "isolated_six_path_source_refinement_not_applied", + "base_revision": "086d79a2736e34b916bd7de3c8a65e2ea38a3d64", + "files": [ + { + "path": "workplans/STATE-WP-0095-historical-source-receiving.md", + "action": "modify", + "base_sha256": "ef10359cc5974283b5bdbfc602adf14e3c24362adf00640698d2937c6538483a", + "candidate_sha256": "921716ab00993a79917ae5b4750e5b61ae22af4c4fd410b9ccf2be9ec54560df" + }, + { + "path": "Makefile", + "action": "modify", + "base_sha256": "5584ef94071044cca8215141ecd8aee8d6ae5cfe73e8f5719358c680eb8af0d4", + "candidate_sha256": "c5b70e8d4b8ae70380e0ade1c35f9e7fe80038de10080a4723b21ef07a98001e" + }, + { + "path": "deploy/railiance/apps/charts/state-hub/Chart.yaml", + "action": "modify", + "base_sha256": "7fe02b390ffd2ba4ce6f82bd62df900826826401e31bdc2138dd5bf36b51a6ae", + "candidate_sha256": "61a989fcf277d05ffbececb7332ee3ca1d8f369c72f960ab1bc4dbc6815536b8" + }, + { + "path": "deploy/railiance/apps/helm/state-hub-values.yaml", + "action": "modify", + "base_sha256": "f7cc0e9968598f6ce0faa0d56f62d6817845c3570c18b6ac39ed6561b952b197", + "candidate_sha256": "b51296fc937450f4ecf0ae43243262a631b551389c0d09c8bfe58fa10e2f3ee9" + }, + { + "path": "docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json", + "action": "add", + "base_sha256": null, + "candidate_sha256": "db6cd6931c5763ff390e54c6eb9430aad2c4c7c9f42dd6652f436e549e6f6297" + }, + { + "path": "deploy/railiance/apps/charts/state-hub/files/repo-classification.allowed.yaml", + "action": "modify", + "base_sha256": "9c36fbd5308b19695f9f05d86f8e315bbeccdd267575ce4e2fccf6fb2ea82e32", + "candidate_sha256": "f53c651bb4329c09c04c66f906e2462fe4339ab51ef0ec3da9f942c3016f5bed" + } + ], + "patch_sha256": "sha256:12ee2ab6f4cc45ff8cfcb4c03ef84a7e207eff13fdaa194a7281734f5cbc4021", + "live_effects": false, + "new_runtime_image": false, + "T06": "done_actual_approved_verified_rollout", + "T07": "wait_until_actual_RMGR19T06_cluster_publication_and_preservation_return", + "T08": "done_source_readiness_preserved", + "generic_chart_default_tag": "empty_required_explicit_pin_unchanged", + "declared_production_image": "main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015", + "preserve_preexisting_dirty": [ + ".custodian-brief.md", + "WORK-RECORDS.md", + "docs/evidence/legacy-meter-weekly-review-20261014.json", + "docs/evidence/legacy-meter-weekly-review-20261015.json", + "docs/evidence/legacy-meter-weekly-review-20261016.json", + "docs/evidence/legacy-meter-weekly-review-20261017.json" + ], + "revision": 2, + "source_repair": "Existing generator refreshes chart classification copy to unchanged authoritative canon; no live ConfigMap apply or new runtime image." +} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/state-hub-followthrough.patch b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/state-hub-followthrough.patch new file mode 100644 index 00000000..0584675b --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/state-hub-followthrough.patch @@ -0,0 +1,238 @@ +--- a/workplans/STATE-WP-0095-historical-source-receiving.md ++++ b/workplans/STATE-WP-0095-historical-source-receiving.md +@@ -199,27 +199,37 @@ + + ```task + id: STATE-WP-0095-T06 +-status: wait ++status: done + priority: high + depends_on: [STATE-WP-0095-T05] +-needs_human: true +-intervention_note: "Review exact committed source, CI image and owner deployment proposal before rollout." ++needs_human: false ++intervention_note: "Exact revision 4 approved and verified; no pending rollout intervention." + state_hub_task_id: "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4" + ``` + +-Use the normal CI image and Helm owner path after exact revision/image pin, +-fresh headroom and reviewed dry-run/diff. API/MCP currently run main-7d99282; +-Helm revision75 is the observed rollback baseline, requiring freshness before +-execution. No deployment assent exists for this successor. Verify delivered +-module hash, health, both readiness checks and expected migrated schema +-c4d5e6f7a8b9; verify exact +-three parents/15 tasks and rejection behavior without committed probe changes. +-Only the verified return unblocks RMGR-WP-0019-T05. The full current image also carries inbox-feed migration c4d5e6f7a8b9, +-although this receiver patch adds none. Helm rollback leaves that migration in +-place; unrelated migration acceptance and old-image compatibility need normal +-owner evidence before rollout approval. Do not run destructive default local +-DB tests; use only exact disposable DB containment. Costs and monetary risk are +-unknown pending exact rollout proposal; no zero-cost or autonomy grant is inferred. ++Completed 2026-10-17 on the founder's approval of exact revision 4 of stable ++proposal STATE-WP-0095-T06-cluster-frozen-receiving-r1 (decision ++ e3798419-8aa9-5425-8c08-20df6bd82a19; approved digest ++ sha256:63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32). ++The ordinary owner Helm path delivered revision 76, runtime source 51bc70d and ++exact image manifest sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015. ++API/MCP Ready and primary/railiance01 health report expected schema ++c4d5e6f7a8b9; delivered historical module sha256:e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2 matches. ++All three parent and 15 task full DB row hashes/columns/UUIDs remained unchanged. ++Five actual native probes passed: preserve, actual foreign-parent holder move, ++nonterminal task, nonterminal parent and missing task. Every probe rolled back; ++a fresh transaction confirmed complete row restoration. The foreign-holder ++case precisely verified historical binding refusal, not the separate global ++UUID-holder creation branch. No committed probe writes were made. ++ ++Evidence: [verified receiving rollout](../docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json). ++This actual receiving return satisfies the prerequisite of RMGR-WP-0019-T05. ++Normal cluster publication and its immutable-source/row return remain T07; ++source readiness and this deployment do not count that later acceptance twice. ++The additive inbox migration is retained; Helm rollback does not downgrade ++schema or stop an active migration Job. Original failures and exact-UID recovery ++limits remain in the referenced approved packet. No TLS recovery/native private ++admission or new autonomy/cost grant is inferred. + + ## Verify ordinary cluster receiving and immutable historical rows + +@@ -256,6 +266,17 @@ + Command-fixture tests verify both requests and preserve other dry-run phases. + Evidence and original refusal remain in the Custodian cluster historical + publication packet, revisions/r2 and r3-readiness. This is completed source +-preparation; T06 remains the explicit native rollout gate. The runtime image ++preparation; T06 separately records the verified actual rollout. The runtime image + continues to be main-51bc70d; Makefile/workplan changes do not create a new + application image or native acceptance. ++ ++ ++T08 source repair refinement, 2026-10-17: the required normal Make render ++correctly refused a pre-existing generated chart classification copy at v1.0 ++after authoritative canon reached v1.1. Regenerated only through the existing ++scripts/sync_classification_allowed.py, preserving canon and strict check. ++The exact source diff is version 1.0→1.1 plus publication/history/participation. ++Normal Make rendering and the focused classification check passed in an ++isolated owner-layout copy. The original refusal is retained in the Custodian ++owner-followthrough-r1 validation receipt. This is source repair only: no live ++ConfigMap apply, new runtime image, policy relaxation or T07 completion. +--- a/Makefile ++++ b/Makefile +@@ -9,7 +9,7 @@ + RAILIANCE_STATE_HUB_NAMESPACE ?= state-hub + RAILIANCE_STATE_HUB_CHART ?= deploy/railiance/apps/charts/state-hub + RAILIANCE_STATE_HUB_VALUES ?= deploy/railiance/apps/helm/state-hub-values.yaml +-RAILIANCE_STATE_HUB_IMAGE_TAG ?= main-0747b4d ++RAILIANCE_STATE_HUB_IMAGE_TAG ?= main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015 + RAILIANCE_STATE_HUB_PLATFORM_DIR ?= deploy/railiance/platform + RAILIANCE_STATE_HUB_APP_MANIFESTS ?= deploy/railiance/apps/manifests + # Codex/WSL non-login shells may not source ~/.profile; keep uv discoverable. +--- a/deploy/railiance/apps/charts/state-hub/Chart.yaml ++++ b/deploy/railiance/apps/charts/state-hub/Chart.yaml +@@ -3,4 +3,4 @@ + description: State Hub API service for private Railiance operation + type: application + version: 0.1.0 +-appVersion: "main-5dd3df9" ++appVersion: "main-51bc70d" +--- a/deploy/railiance/apps/helm/state-hub-values.yaml ++++ b/deploy/railiance/apps/helm/state-hub-values.yaml +@@ -6,7 +6,7 @@ + + image: + repository: forgejo.coulomb.social/coulomb/state-hub +- tag: "main-0747b4d" ++ tag: "main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015" + + ingress: + enabled: false +--- /dev/null ++++ b/docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json +@@ -0,0 +1,102 @@ ++{ ++ "schema": "statehub.cluster-historical-receiving-delivered.v1", ++ "status": "verified", ++ "proposal_id": "STATE-WP-0095-T06-cluster-frozen-receiving-r1", ++ "approved_revision": 4, ++ "approved_digest_sha256": "sha256:63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32", ++ "approval_decision_id": "e3798419-8aa9-5425-8c08-20df6bd82a19", ++ "source_revision": "51bc70d1ff8f25450a8650d8e50caf053093a02e", ++ "readiness_source_revision": "086d79a2736e34b916bd7de3c8a65e2ea38a3d64", ++ "helm_revision": 76, ++ "image_reference": "forgejo.coulomb.social/coulomb/state-hub:main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015", ++ "expected_schema": "c4d5e6f7a8b9", ++ "health": { ++ "status": "ok", ++ "instance_role": "primary", ++ "instance_label": "railiance01", ++ "schema": { ++ "status": "ok", ++ "applied": "c4d5e6f7a8b9", ++ "expected": "c4d5e6f7a8b9" ++ } ++ }, ++ "pods_ready": true, ++ "historical_module_sha256": "sha256:e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2", ++ "historical_preservation_verified": true, ++ "parents": 3, ++ "tasks": 15, ++ "full_historical_rows_equal": true, ++ "native_rollback_probes": { ++ "foreign-holder": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "missing-task": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "nonterminal-parent": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "nonterminal-task": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "preserve": { ++ "full_historical_rows_equal": true, ++ "full_historical_rows_restored": true, ++ "native_outcome_status": "applied", ++ "rolled_back": true, ++ "status": "passed" ++ } ++ }, ++ "native_probe_commits": 0, ++ "fresh_transaction_full_rows_equal": true, ++ "source_receiving_gate_delivered": true, ++ "normal_cluster_publication_verified": false, ++ "registrar_admission_or_cluster_publication_not_inferred": true, ++ "authority_limits": [ ++ "Rollback probe SQL effects rolled back; foreign-holder case is historical-binding refusal, not separate global holder branch.", ++ "Actual historical native receiving is verified; owner-native TLS/private admission remains unresolved.", ++ "Migration schema remains additive; Helm rollback does not downgrade schema or stop an active hook Job." ++ ], ++ "evidence": [ ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/approval-decision.json", ++ "sha256": "sha256:b51554c004daa882f3709f67bdae7f2e939d611120383e61be04ec6969878134" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/helm-return.json", ++ "sha256": "sha256:61727deacf22d37da2d28cbaf04f5a3ddee0f9ff7571c77f1e85dba97963b572" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/delivered-runtime.json", ++ "sha256": "sha256:89681066e8fe139456163ebfafa3efe77ffae8534ea167219230b0a74367f129" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/native-refusal-probes.json", ++ "sha256": "sha256:673ccef965c820704dc310a1bf7832b583c30c3edfeb814528cf892555199172" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-full-row-hashes.json", ++ "sha256": "sha256:75cdd87eef79059ff3f484ed24ca69e285899cdf8d851cc4e472653c417eb0ee" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-full-row-hashes.json", ++ "sha256": "sha256:2156aad18f190384838c27e792706a156a7423391408afbc6107e6c28c5872d8" ++ } ++ ] ++} +--- a/deploy/railiance/apps/charts/state-hub/files/repo-classification.allowed.yaml ++++ b/deploy/railiance/apps/charts/state-hub/files/repo-classification.allowed.yaml +@@ -13,7 +13,7 @@ + # to match the standard version. CUST-WP-0050 T01. + + standard: "Repo Classification Standard" +-version: "1.0" ++version: "1.1" + canon_id: "canon-repo-classification" + + # category — exactly 1 required (§5) +@@ -24,6 +24,7 @@ + - tooling + - product + - business ++ - publication + + # domain / secondary_domains — primary exactly 1; secondaries 0..n (§6) + domains: +@@ -85,6 +86,8 @@ + - traceability + - documentation + - decision-support ++ - history ++ - participation + platform_and_operations: + - platform + - deployment diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/validation.json b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/validation.json new file mode 100644 index 00000000..220461db --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/validation.json @@ -0,0 +1,25 @@ +{ + "schema": "statehub-source-refinement-validation.v1", + "normal_owner_make_render_exit": 0, + "focused_classification_check_exit": 0, + "sync_script_sha256": "sha256:b1c06691843d15ac4e82c0eba59d566c754aa5163337ed4ee8644c3dc9283bcd", + "canon_sha256": "sha256:c0e0452bb08fe1700f2672b5b019da08c3d70737fa5b00bdfeab14ef32cb6477", + "exact_copy_diff": { + "removed": [ + "version: \"1.0\"" + ], + "added": [ + "version: \"1.1\"", + " - publication", + " - history", + " - participation" + ] + }, + "all3runtime_images_exact_promoted_digest": true, + "original_failed_render_receipt": "../owner-followthrough-r1/validation.json", + "canon_edited": false, + "guard_changed": false, + "cluster_contacted": false, + "new_runtime_image": false, + "canonical_mutations": false +} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/REVIEW.md b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/REVIEW.md new file mode 100644 index 00000000..55f4a7fb --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/REVIEW.md @@ -0,0 +1,17 @@ +# Immutable ordinary-binding repair, source revision 3 + +Canonical base: 086d79a2736e34b916bd7de3c8a65e2ea38a3d64. The ten-path patch includes the previously reviewed six-path followthrough and four guard/test paths. Originals and the actual failed publication receipt remain untouched. + +The approved revision-4 receiving rollout preserved all 18 rows at its verification stage. A later ordinary Cluster publication changed exactly three parent full-row hashes; all 15 task hashes remained unchanged. The binding endpoint assigns a new backing sync timestamp unconditionally, providing a concrete mutation path. Hash-only snapshots do not establish the exact changed columns or supply original preimages. This patch does not restore them. + +Only the three existing task-bound railiance-cluster registry entries receive this guard. The CLI requires all three scan members, validates their exact source bytes and metadata, and omits valid immutable bindings before contacting any receiver. A refused batch becomes C-44 FAIL and returns a nonzero exit even in remote-all mode. The API independently validates all request metadata before any assignment, locks and refreshes parent/task rows, checks actual repo ownership and existing terminal required-bound tasks, and skips every setter for valid frozen rows. Additional children retain existing Forge receiving semantics; no new child-set invariant is introduced. The ordinary binding response retains updated/received and adds preserved. Frozen-only requests perform no commit or cache invalidation. Existing get_session uses an async-session context manager, which closes the read transaction and releases locks on exit. + +Validation: 40 isolated tests pass with --noconftest. Tests extract actual source functions/classes without importing owner app configuration or opening a DB. They verify all three exact sources, missing scan member/UUID, changed source and metadata, foreign names, complete mixed-batch refusal, API ownership and terminal-state refusal, no frozen setters/commit, ordinary compatibility, lock/refresh query intent and actual CLI exit criteria. The full tracked chart plus overlay passes normal Make render/classification check: eight objects, three unchanged digest-qualified images. No concurrency/native DB behavior is claimed by these source tests. + +T06 remains done for the approved delivery at its verification stage; T07 remains wait for failed whole-pipeline preservation. T09 is progress until source publication. T10 is wait/needs_human for a separate exact new runtime approval. New task UUIDs are intentionally unallocated pending root review and normal managed allocation. Preserve the original dirty brief/index/weekly evidence and index state. + +## Next runtime proposal preparation + +After reviewed source integration and normal publication, obtain normal CI status and resolve the resulting exact immutable image manifest. Inspect selected delivered source hashes, including historical_projection.py, workstreams.py and the installed closure; do not reuse the prior main-51bc70d runtime for the new API guard. Prepare digest-qualified packaged-chart reuse-values server dry-run, compare intended object identities/spec hashes, collect fresh release/headroom/schema and full-row hash baseline, then record a new scoped proposal and supervisor disposition. Current known prior baseline was Helm 76/schema c4d5e6f7a8b9; refresh rather than assume it remains current. CI revision, new image digest, final chart package hash and exact execution digest remain unresolved until publication. + +No new rollout is authorized by the prior revision-4 approval. A new rollout must retain migration closure and rollback limits: Helm rollback does not downgrade schema, and timeout/atomic does not necessarily stop an active hook Job. Cancellation may address only the exact owned trial Job UID/image after identity verification. Unknown migration recovery or connection/lock quiescence stops for attended owner handling; no credential grant or invented DB-session mapping. EUR cost and risk are unknown until reviewed; no bounded-outage assertion. New baseline preservation and rollback-only refusal probes prove the new stage, never restoration of the unavailable original parent preimages. T07/RMGR19T06 cannot close on source publication alone. diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/manifest.json b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/manifest.json new file mode 100644 index 00000000..32fbd9e7 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/manifest.json @@ -0,0 +1,77 @@ +{ + "schema": "statehub.source-owner-followthrough.v1", + "revision": 3, + "status": "isolated_source_candidate_not_published", + "base_revision": "086d79a2736e34b916bd7de3c8a65e2ea38a3d64", + "files": [ + { + "path": "workplans/STATE-WP-0095-historical-source-receiving.md", + "action": "modify", + "base_sha256": "ef10359cc5974283b5bdbfc602adf14e3c24362adf00640698d2937c6538483a", + "candidate_sha256": "287001ec92d5a9b851b0d70e56747730a9bb150fcda09e97d6e6e9ddf39c7b5c" + }, + { + "path": "Makefile", + "action": "modify", + "base_sha256": "5584ef94071044cca8215141ecd8aee8d6ae5cfe73e8f5719358c680eb8af0d4", + "candidate_sha256": "c5b70e8d4b8ae70380e0ade1c35f9e7fe80038de10080a4723b21ef07a98001e" + }, + { + "path": "deploy/railiance/apps/charts/state-hub/Chart.yaml", + "action": "modify", + "base_sha256": "7fe02b390ffd2ba4ce6f82bd62df900826826401e31bdc2138dd5bf36b51a6ae", + "candidate_sha256": "61a989fcf277d05ffbececb7332ee3ca1d8f369c72f960ab1bc4dbc6815536b8" + }, + { + "path": "deploy/railiance/apps/helm/state-hub-values.yaml", + "action": "modify", + "base_sha256": "f7cc0e9968598f6ce0faa0d56f62d6817845c3570c18b6ac39ed6561b952b197", + "candidate_sha256": "b51296fc937450f4ecf0ae43243262a631b551389c0d09c8bfe58fa10e2f3ee9" + }, + { + "path": "docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json", + "action": "add", + "base_sha256": null, + "candidate_sha256": "fb0b59ba3558e084fb4ae2c36c556f3cfbb2a889f6fd86d4e803c52f483b26fd" + }, + { + "path": "deploy/railiance/apps/charts/state-hub/files/repo-classification.allowed.yaml", + "action": "modify", + "base_sha256": "9c36fbd5308b19695f9f05d86f8e315bbeccdd267575ce4e2fccf6fb2ea82e32", + "candidate_sha256": "f53c651bb4329c09c04c66f906e2462fe4339ab51ef0ec3da9f942c3016f5bed" + }, + { + "path": "api/services/historical_projection.py", + "action": "modify", + "base_sha256": "e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2", + "candidate_sha256": "e24e57c58f4aaa4ec9d9bf088009ac69006e53f75b9477ee53dc26c4e850b975" + }, + { + "path": "api/routers/workstreams.py", + "action": "modify", + "base_sha256": "61e7a0ab638b155e9e0b2a72fe8e0ddd2edf5bc6c2d3ca7f6c3ff51e8868910b", + "candidate_sha256": "9c9bf4376dd323b52109912bb3f615949e89ac02c8b88b4720f569f8565ad1d6" + }, + { + "path": "scripts/consistency_check.py", + "action": "modify", + "base_sha256": "1827921c79b476bee823c2ddf9896aeb83f3efca6548427e17b3244216bbc6b5", + "candidate_sha256": "ae96d6260f6c88d35bc2d3f22f2a6061367621fd0416387d25d8683c8e804e06" + }, + { + "path": "tests/test_frozen_binding_guard_isolated.py", + "action": "add", + "base_sha256": null, + "candidate_sha256": "78eb62178fdecf9b5f6c40d398f8c44e93ff740abaf86557ab51ceb708d2ed65" + } + ], + "patch_sha256": "sha256:e9bc2ba9f81b6290945b6de6e0a00ba4c995478b17da786605f5a0466e300b3d", + "T06": "done_verified_approved_rollout_at_stage", + "T07": "wait_actual_later_parent_row_preservation_failure", + "T08": "done_source_repair_pending_publication", + "T09": "progress_until_source_published", + "T10": "wait_needs_human_new_runtime", + "live_effects": false, + "original_parent_preimages": "unknown_do_not_restore_guesses", + "managed_UUIDs": "T09_T10_not_allocated_pending_review" +} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/state-hub-followthrough.patch b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/state-hub-followthrough.patch new file mode 100644 index 00000000..4611548e --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/state-hub-followthrough.patch @@ -0,0 +1,650 @@ +--- a/workplans/STATE-WP-0095-historical-source-receiving.md ++++ b/workplans/STATE-WP-0095-historical-source-receiving.md +@@ -199,27 +199,37 @@ + + ```task + id: STATE-WP-0095-T06 +-status: wait ++status: done + priority: high + depends_on: [STATE-WP-0095-T05] +-needs_human: true +-intervention_note: "Review exact committed source, CI image and owner deployment proposal before rollout." ++needs_human: false ++intervention_note: "Exact revision 4 approved and verified; no pending rollout intervention." + state_hub_task_id: "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4" + ``` + +-Use the normal CI image and Helm owner path after exact revision/image pin, +-fresh headroom and reviewed dry-run/diff. API/MCP currently run main-7d99282; +-Helm revision75 is the observed rollback baseline, requiring freshness before +-execution. No deployment assent exists for this successor. Verify delivered +-module hash, health, both readiness checks and expected migrated schema +-c4d5e6f7a8b9; verify exact +-three parents/15 tasks and rejection behavior without committed probe changes. +-Only the verified return unblocks RMGR-WP-0019-T05. The full current image also carries inbox-feed migration c4d5e6f7a8b9, +-although this receiver patch adds none. Helm rollback leaves that migration in +-place; unrelated migration acceptance and old-image compatibility need normal +-owner evidence before rollout approval. Do not run destructive default local +-DB tests; use only exact disposable DB containment. Costs and monetary risk are +-unknown pending exact rollout proposal; no zero-cost or autonomy grant is inferred. ++Completed 2026-10-17 on the founder's approval of exact revision 4 of stable ++proposal STATE-WP-0095-T06-cluster-frozen-receiving-r1 (decision ++ e3798419-8aa9-5425-8c08-20df6bd82a19; approved digest ++ sha256:63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32). ++The ordinary owner Helm path delivered revision 76, runtime source 51bc70d and ++exact image manifest sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015. ++API/MCP Ready and primary/railiance01 health report expected schema ++c4d5e6f7a8b9; delivered historical module sha256:e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2 matches. ++All three parent and 15 task full DB row hashes/columns/UUIDs remained unchanged. ++Five actual native probes passed: preserve, actual foreign-parent holder move, ++nonterminal task, nonterminal parent and missing task. Every probe rolled back; ++a fresh transaction confirmed complete row restoration. The foreign-holder ++case precisely verified historical binding refusal, not the separate global ++UUID-holder creation branch. No committed probe writes were made. ++ ++Evidence: [verified receiving rollout](../docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json). ++This actual receiving return satisfies the prerequisite of RMGR-WP-0019-T05. ++Normal cluster publication and its immutable-source/row return remain T07; ++source readiness and this deployment do not count that later acceptance twice. ++The additive inbox migration is retained; Helm rollback does not downgrade ++schema or stop an active migration Job. Original failures and exact-UID recovery ++limits remain in the referenced approved packet. No TLS recovery/native private ++admission or new autonomy/cost grant is inferred. + + ## Verify ordinary cluster receiving and immutable historical rows + +@@ -256,6 +266,70 @@ + Command-fixture tests verify both requests and preserve other dry-run phases. + Evidence and original refusal remain in the Custodian cluster historical + publication packet, revisions/r2 and r3-readiness. This is completed source +-preparation; T06 remains the explicit native rollout gate. The runtime image ++preparation; T06 separately records the verified actual rollout. The runtime image + continues to be main-51bc70d; Makefile/workplan changes do not create a new + application image or native acceptance. ++ ++ ++T08 source repair refinement, 2026-10-17: the required normal Make render ++correctly refused a pre-existing generated chart classification copy at v1.0 ++after authoritative canon reached v1.1. Regenerated only through the existing ++scripts/sync_classification_allowed.py, preserving canon and strict check. ++The exact source diff is version 1.0→1.1 plus publication/history/participation. ++Normal Make rendering and the focused classification check passed in an ++isolated owner-layout copy. The original refusal is retained in the Custodian ++owner-followthrough-r1 validation receipt. This is source repair only: no live ++ConfigMap apply, new runtime image, policy relaxation or T07 completion. ++ ++ ++T07 actual ordinary-publication return, 2026-10-17: cluster owner deep consistency ++and normal fast projection completed, exact archived source bytes and all 15 ++historical task full-row hashes remained unchanged. The later full-row check ++FAILED for exactly the three parent rows. The earlier approved T06 rollout had ++preserved all 18 rows at its verification stage; that success is not the later ++whole-pipeline acceptance. The original snapshots retain hashes only, so exact ++changed columns and original field preimages are not established. No guessed ++DB repair or claim that all 18 original row hashes are restored is authorized. ++T07 and RMGR-WP-0019-T06 remain waiting pending T09/T10 and a reviewed return. ++ ++## Guard immutable historical index bindings in CLI and receiving API ++ ++```task ++id: STATE-WP-0095-T09 ++status: progress ++priority: high ++depends_on: [STATE-WP-0095-T06] ++``` ++ ++Prepare and publish the narrowly scoped ordinary-binding repair for the three ++existing task-bound Cluster registry entries. The CLI verifies exact frozen ++source metadata/bytes and omits those bindings, including on old receivers. ++The API independently validates the complete batch before any mutation, checks ++actual repo ownership and the existing terminal parent/task closure, and ++preserves valid frozen rows without field or timestamp assignments. Invalid ++metadata, missing/foreign/nonterminal rows refuse the batch. Unknown ordinary ++bindings retain existing behavior; historical IDs, UUIDs and source bytes stay ++unchanged. Isolated regression tests and normal owner rendering are required. ++Mark done only after reviewed source publication and normal owner projection; ++source preparation does not establish delivered runtime or T07 acceptance. ++ ++## Deliver and verify the ordinary-binding guard successor ++ ++```task ++id: STATE-WP-0095-T10 ++status: wait ++priority: high ++depends_on: [STATE-WP-0095-T09] ++needs_human: true ++intervention_note: "New API runtime requires its own exact image, reviewed preflight and scoped rollout approval; prior revision-4 approval does not cover it." ++``` ++ ++After source publication, resolve normal CI status and immutable image identity, ++verify delivered guard source closure, prepare exact chart/reuse-values dry-run, ++full closure/headroom/schema baseline and conditional recovery. Retain additive ++migration and active-Job cancellation limitations; no Helm schema downgrade or ++bounded-outage claim. Obtain scoped approval before live rollout. Then verify ++new full-row baseline preservation and actual rollback-only refusal probes, ++and only then return to T07 ordinary-pipeline acceptance. This prevents future ++binding mutation; it does not reconstruct or restore original parent hashes. ++No production changes, new autonomy or credential authority are granted here. +--- a/Makefile ++++ b/Makefile +@@ -9,7 +9,7 @@ + RAILIANCE_STATE_HUB_NAMESPACE ?= state-hub + RAILIANCE_STATE_HUB_CHART ?= deploy/railiance/apps/charts/state-hub + RAILIANCE_STATE_HUB_VALUES ?= deploy/railiance/apps/helm/state-hub-values.yaml +-RAILIANCE_STATE_HUB_IMAGE_TAG ?= main-0747b4d ++RAILIANCE_STATE_HUB_IMAGE_TAG ?= main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015 + RAILIANCE_STATE_HUB_PLATFORM_DIR ?= deploy/railiance/platform + RAILIANCE_STATE_HUB_APP_MANIFESTS ?= deploy/railiance/apps/manifests + # Codex/WSL non-login shells may not source ~/.profile; keep uv discoverable. +--- a/deploy/railiance/apps/charts/state-hub/Chart.yaml ++++ b/deploy/railiance/apps/charts/state-hub/Chart.yaml +@@ -3,4 +3,4 @@ + description: State Hub API service for private Railiance operation + type: application + version: 0.1.0 +-appVersion: "main-5dd3df9" ++appVersion: "main-51bc70d" +--- a/deploy/railiance/apps/helm/state-hub-values.yaml ++++ b/deploy/railiance/apps/helm/state-hub-values.yaml +@@ -6,7 +6,7 @@ + + image: + repository: forgejo.coulomb.social/coulomb/state-hub +- tag: "main-0747b4d" ++ tag: "main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015" + + ingress: + enabled: false +--- /dev/null ++++ b/docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json +@@ -0,0 +1,116 @@ ++{ ++ "schema": "statehub.cluster-historical-receiving-delivered.v1", ++ "status": "verified", ++ "proposal_id": "STATE-WP-0095-T06-cluster-frozen-receiving-r1", ++ "approved_revision": 4, ++ "approved_digest_sha256": "sha256:63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32", ++ "approval_decision_id": "e3798419-8aa9-5425-8c08-20df6bd82a19", ++ "source_revision": "51bc70d1ff8f25450a8650d8e50caf053093a02e", ++ "readiness_source_revision": "086d79a2736e34b916bd7de3c8a65e2ea38a3d64", ++ "helm_revision": 76, ++ "image_reference": "forgejo.coulomb.social/coulomb/state-hub:main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015", ++ "expected_schema": "c4d5e6f7a8b9", ++ "health": { ++ "status": "ok", ++ "instance_role": "primary", ++ "instance_label": "railiance01", ++ "schema": { ++ "status": "ok", ++ "applied": "c4d5e6f7a8b9", ++ "expected": "c4d5e6f7a8b9" ++ } ++ }, ++ "pods_ready": true, ++ "historical_module_sha256": "sha256:e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2", ++ "historical_preservation_verified": true, ++ "parents": 3, ++ "tasks": 15, ++ "full_historical_rows_equal": true, ++ "native_rollback_probes": { ++ "foreign-holder": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "missing-task": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "nonterminal-parent": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "nonterminal-task": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "preserve": { ++ "full_historical_rows_equal": true, ++ "full_historical_rows_restored": true, ++ "native_outcome_status": "applied", ++ "rolled_back": true, ++ "status": "passed" ++ } ++ }, ++ "native_probe_commits": 0, ++ "fresh_transaction_full_rows_equal": true, ++ "source_receiving_gate_delivered": true, ++ "normal_cluster_publication_verified": false, ++ "registrar_admission_or_cluster_publication_not_inferred": true, ++ "authority_limits": [ ++ "Rollback probe SQL effects rolled back; foreign-holder case is historical-binding refusal, not separate global holder branch.", ++ "Actual historical native receiving is verified; owner-native TLS/private admission remains unresolved.", ++ "Migration schema remains additive; Helm rollback does not downgrade schema or stop an active hook Job." ++ ], ++ "evidence": [ ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/approval-decision.json", ++ "sha256": "sha256:b51554c004daa882f3709f67bdae7f2e939d611120383e61be04ec6969878134" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/helm-return.json", ++ "sha256": "sha256:61727deacf22d37da2d28cbaf04f5a3ddee0f9ff7571c77f1e85dba97963b572" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/delivered-runtime.json", ++ "sha256": "sha256:89681066e8fe139456163ebfafa3efe77ffae8534ea167219230b0a74367f129" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/native-refusal-probes.json", ++ "sha256": "sha256:673ccef965c820704dc310a1bf7832b583c30c3edfeb814528cf892555199172" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-full-row-hashes.json", ++ "sha256": "sha256:75cdd87eef79059ff3f484ed24ca69e285899cdf8d851cc4e472653c417eb0ee" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-full-row-hashes.json", ++ "sha256": "sha256:2156aad18f190384838c27e792706a156a7423391408afbc6107e6c28c5872d8" ++ } ++ ], ++ "later_ordinary_cluster_publication": { ++ "status": "failed_full_parent_row_preservation", ++ "changed_parent_hashes": 3, ++ "unchanged_task_hashes": 15, ++ "exact_changed_columns": "unknown_hash_only_baseline", ++ "original_parent_preimages": "unavailable_no_guessed_restoration", ++ "receipt": "the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json", ++ "T07": "wait", ++ "RMGR_WP_0019_T06": "wait", ++ "followup": [ ++ "STATE-WP-0095-T09", ++ "STATE-WP-0095-T10" ++ ] ++ } ++} +--- a/deploy/railiance/apps/charts/state-hub/files/repo-classification.allowed.yaml ++++ b/deploy/railiance/apps/charts/state-hub/files/repo-classification.allowed.yaml +@@ -13,7 +13,7 @@ + # to match the standard version. CUST-WP-0050 T01. + + standard: "Repo Classification Standard" +-version: "1.0" ++version: "1.1" + canon_id: "canon-repo-classification" + + # category — exactly 1 required (§5) +@@ -24,6 +24,7 @@ + - tooling + - product + - business ++ - publication + + # domain / secondary_domains — primary exactly 1; secondaries 0..n (§6) + domains: +@@ -85,6 +86,8 @@ + - traceability + - documentation + - decision-support ++ - history ++ - participation + platform_and_operations: + - platform + - deployment +--- a/api/services/historical_projection.py ++++ b/api/services/historical_projection.py +@@ -193,3 +193,46 @@ + raise ValueError("Historical source binding changed: " + entry["path"]) + result.append((entry, data.decode("utf-8"))) + return result ++ ++ ++# Only the three existing full-task Cluster bindings have immutable DB rows. ++# Other historical views retain their existing compatibility behavior. ++FROZEN_CLUSTER_BINDINGS = tuple( ++ entry for entry in BINDINGS ++ if entry["repo"] == "railiance-cluster" and "tasks" in entry ++) ++ ++ ++def frozen_cluster_binding(binding): ++ """Validate a claimed frozen binding; unrelated requests remain ordinary.""" ++ matches = [entry for entry in FROZEN_CLUSTER_BINDINGS ++ if str(binding["workplan_id"]) == entry["uuid"] ++ or (binding["repo_slug"] == "railiance-cluster" ++ and (binding["relative_path"] == entry["path"] ++ or binding["filename"] == Path(entry["path"]).name))] ++ if not matches: ++ return None ++ if len(matches) != 1: ++ raise ValueError("frozen historical binding is ambiguous") ++ entry = matches[0] ++ expected = { ++ "workplan_id": entry["uuid"], "repo_slug": entry["repo"], ++ "filename": Path(entry["path"]).name, "relative_path": entry["path"], ++ "archived": True, "status": "finished", ++ } ++ if any((str(binding[key]) if key == "workplan_id" else binding[key]) != value ++ for key, value in expected.items()): ++ raise ValueError("frozen historical binding metadata changed") ++ return entry ++ ++ ++def validate_frozen_cluster_rows(entry, parent, tasks, repo_id): ++ """Receiving requires the exact existing terminal closure, never repair.""" ++ if (parent is None or str(parent.id) != entry["uuid"] ++ or repo_id is None or parent.repo_id != repo_id ++ or parent.status not in {"done", "finished", "archived", "completed"}): ++ raise ValueError("frozen historical parent missing, foreign or nonterminal") ++ local = {str(task.id): task for task in tasks if task.workplan_id == parent.id} ++ if any(task["uuid"] not in local or local[task["uuid"]].status not in {"done", "cancel"} ++ for task in entry["tasks"]): ++ raise ValueError("frozen historical task missing, foreign or nonterminal") +--- a/api/routers/workstreams.py ++++ b/api/routers/workstreams.py +@@ -16,6 +16,8 @@ + from api.events import EventEnvelope, publish_event + from api.models.managed_repo import ManagedRepo + from api.models.workplan import Workplan ++from api.models.task import Task ++from api.services.historical_projection import frozen_cluster_binding, validate_frozen_cluster_rows + from api.schemas.workplan import ( + WorkplanBindingsSync, + WorkplanCreate, +@@ -435,12 +437,42 @@ + session: AsyncSession = Depends(get_session), + ) -> dict[str, int]: + """Upsert workstation workplan file bindings for remote API index fallback.""" ++ # Preflight the complete batch before assigning even an ordinary row. ++ try: ++ frozen = {entry.workplan_id: bound for entry in body.bindings ++ if (bound := frozen_cluster_binding(entry.model_dump())) is not None} ++ except ValueError as exc: ++ raise HTTPException(status_code=409, detail=str(exc)) from exc ++ requested_ids = {entry.workplan_id for entry in body.bindings} ++ rows = await session.execute( ++ select(Workplan).where(Workplan.id.in_(requested_ids)) ++ .order_by(Workplan.id).with_for_update().execution_options(populate_existing=True) ++ ) ++ workplans = {workplan.id: workplan for workplan in rows.scalars().all()} ++ if frozen: ++ repo_rows = await session.execute( ++ select(ManagedRepo).where(ManagedRepo.slug == "railiance-cluster") ++ ) ++ repo = repo_rows.scalar_one_or_none() ++ task_rows = await session.execute( ++ select(Task).where(Task.workplan_id.in_(frozen)) ++ .order_by(Task.id).with_for_update().execution_options(populate_existing=True) ++ ) ++ tasks = task_rows.scalars().all() ++ try: ++ for workplan_id, bound in frozen.items(): ++ validate_frozen_cluster_rows( ++ bound, workplans.get(workplan_id), tasks, repo.id if repo else None ++ ) ++ except ValueError as exc: ++ raise HTTPException(status_code=409, detail=str(exc)) from exc + synced_at = datetime.now(timezone.utc) + updated = 0 +- requested_ids = {entry.workplan_id for entry in body.bindings} +- rows = await session.execute(select(Workplan).where(Workplan.id.in_(requested_ids))) +- workplans = {workplan.id: workplan for workplan in rows.scalars().all()} ++ preserved = 0 + for entry in body.bindings: ++ if entry.workplan_id in frozen: ++ preserved += 1 ++ continue # No setters, including backing_synced_at/updated_at. + wp = workplans.get(entry.workplan_id) + if wp is None: + continue +@@ -449,9 +481,10 @@ + wp.backing_archived = entry.archived + wp.backing_synced_at = synced_at + updated += 1 +- await session.commit() +- _invalidate_workplan_index_cache() +- return {"updated": updated, "received": len(body.bindings)} ++ if updated: ++ await session.commit() ++ _invalidate_workplan_index_cache() ++ return {"updated": updated, "received": len(body.bindings), "preserved": preserved} + + + @router.post("/", status_code=status.HTTP_410_GONE) +--- a/scripts/consistency_check.py ++++ b/scripts/consistency_check.py +@@ -120,7 +120,9 @@ + resolve_topic_domain_slug, + ) + from api.services.lifecycle import should_activate_parent_for_active_tasks # noqa: E402 +-from api.services.historical_projection import BINDINGS as _HISTORICAL_BINDINGS # noqa: E402 ++from api.services.historical_projection import ( # noqa: E402 ++ BINDINGS as _HISTORICAL_BINDINGS, FROZEN_CLUSTER_BINDINGS, frozen_cluster_binding, ++) + from api.task_status import ( # noqa: E402 + CANONICAL_TASK_STATUSES, + OPEN_TASK_STATUSES, +@@ -318,7 +320,7 @@ + + # C-00 marks infrastructure/automation faults (API down, repo missing in DB). + # All other FAIL severities are assessment findings for follow-up. +-_AUTOMATION_ERROR_CHECKS: frozenset[str] = frozenset({"C-00"}) ++_AUTOMATION_ERROR_CHECKS: frozenset[str] = frozenset({"C-00", "C-44"}) + _NON_WORKPLAN_WORKPLAN_FILES: frozenset[str] = frozenset({"README.md"}) + + +@@ -2496,23 +2498,44 @@ + repo_dir: Path, + report: ConsistencyReport, + ) -> None: ++ if repo_slug == "railiance-cluster": ++ scanned_paths = {workplan_display_path(repo_dir, path) for path, _, _ in workplan_infos} ++ missing = [entry["path"] for entry in FROZEN_CLUSTER_BINDINGS ++ if entry["path"] not in scanned_paths] ++ if missing: ++ report.add(severity="FAIL", check_id="C-44", ++ message="Frozen binding batch refused: bound source missing from scan", ++ fixable=False) ++ return + bindings: list[dict[str, Any]] = [] + for wp_file, meta, _ in workplan_infos: + ws_id = str(meta.get("state_hub_workstream_id", "")).strip().strip('"') ++ archived = wp_file.parent.name == "archived" ++ file_status = normalise_workstream_status(str(meta.get("status", "")).strip()) ++ binding = { ++ "workplan_id": ws_id, "filename": wp_file.name, ++ "relative_path": workplan_display_path(repo_dir, wp_file), ++ "repo_slug": repo_slug, "archived": archived, ++ "status": file_status or None, ++ } ++ try: ++ frozen = frozen_cluster_binding(binding) ++ if frozen is not None: ++ # Verify exact source before omitting the immutable binding. ++ # This is safe even against a receiver predating the API guard. ++ from hashlib import sha256 ++ if (wp_file.is_symlink() or not wp_file.is_file() ++ or sha256(wp_file.read_bytes()).hexdigest() != frozen["sha256"]): ++ raise ValueError("frozen historical source missing or changed") ++ continue ++ except ValueError as exc: ++ report.add(severity="FAIL", check_id="C-44", ++ message=f"Frozen binding batch refused: {exc}", ++ file_path=str(wp_file), fixable=False) ++ return # Never send a partial batch after a frozen-source refusal. + if not ws_id: + continue +- archived = wp_file.parent.name == "archived" +- file_status = normalise_workstream_status(str(meta.get("status", "")).strip()) +- bindings.append( +- { +- "workplan_id": ws_id, +- "filename": wp_file.name, +- "relative_path": workplan_display_path(repo_dir, wp_file), +- "repo_slug": repo_slug, +- "archived": archived, +- "status": file_status or None, +- } +- ) ++ bindings.append(binding) + if not bindings: + return + result = _api_put(api_base, "/workplans/index/bindings", {"bindings": bindings}) +--- /dev/null ++++ b/tests/test_frozen_binding_guard_isolated.py +@@ -0,0 +1,143 @@ ++from pathlib import Path ++import ast, asyncio, importlib.util, types, uuid ++from dataclasses import dataclass, field ++from datetime import datetime, timezone ++import pytest ++ ++ROOT = Path(__file__).resolve().parents[1] ++spec=importlib.util.spec_from_file_location('historical',ROOT/'api/services/historical_projection.py') ++h=importlib.util.module_from_spec(spec);spec.loader.exec_module(h) ++B=h.FROZEN_CLUSTER_BINDINGS[0] ++def binding(**changes): ++ d=dict(workplan_id=uuid.UUID(B['uuid']),repo_slug=B['repo'],filename=Path(B['path']).name,relative_path=B['path'],archived=True,status='finished');d.update(changes);return d ++class Obj: ++ def __init__(self,**kw):self.__dict__.update(kw);self.writes=[] ++ def __setattr__(self,k,v): ++ if 'writes' in self.__dict__:self.writes.append(k) ++ object.__setattr__(self,k,v) ++class Entry(Obj): ++ def model_dump(self):return {k:v for k,v in self.__dict__.items() if k!='writes'} ++class Col: ++ def in_(self,x):return self ++ def __eq__(self,x):return self ++class Query: ++ def __init__(self):self.locked=False;self.refreshed=False;self.ordered=False ++ def where(self,*a):return self ++ def order_by(self,*a):self.ordered=True;return self ++ def with_for_update(self):self.locked=True;return self ++ def execution_options(self,**kw):self.refreshed=kw.get("populate_existing") is True;return self ++class Model: id=Col();slug=Col();workplan_id=Col() ++class Result: ++ def __init__(self,values):self.values=values ++ def scalars(self):return self ++ def all(self):return self.values ++ def scalar_one_or_none(self):return self.values[0] if self.values else None ++class Session: ++ def __init__(self,rows):self.results=iter(rows);self.commits=0;self.queries=[] ++ async def execute(self,q):self.queries.append(q);return Result(next(self.results)) ++ async def commit(self):self.commits+=1 ++class HTTPException(Exception): ++ def __init__(self,status_code,detail):self.status_code=status_code;super().__init__(detail) ++def extracted(path,name,extra): ++ tree=ast.parse((ROOT/path).read_text());node=next(n for n in tree.body if isinstance(n,(ast.FunctionDef,ast.AsyncFunctionDef)) and n.name==name) ++ node.decorator_list=[];node.returns=None ++ for a in node.args.args + node.args.kwonlyargs:a.annotation=None ++ node.args.defaults=[] ++ ns=dict(Path=Path,datetime=datetime,timezone=timezone,**extra) ++ exec(compile(ast.Module(body=[node],type_ignores=[]),str(path),'exec'),ns);return ns[name] ++def actual_report(): ++ tree=ast.parse((ROOT/'scripts/consistency_check.py').read_text()) ++ nodes=[n for n in tree.body if (isinstance(n,ast.ClassDef) and n.name in {'Issue','ConsistencyReport'}) or (isinstance(n,ast.AnnAssign) and isinstance(n.target,ast.Name) and n.target.id=='_AUTOMATION_ERROR_CHECKS')] ++ ns=dict(dataclass=dataclass,field=field,_AUTOMATION_ERROR_CHECKS=frozenset({'C-00','C-44'})) ++ exec(compile(ast.Module(body=nodes,type_ignores=[]),'actual_report','exec'),ns) ++ return ns['ConsistencyReport']('railiance-cluster','/unused') ++ ++def closure(): ++ repo=Obj(id=uuid.uuid4());parent=Obj(id=uuid.UUID(B['uuid']),repo_id=repo.id,status='finished') ++ tasks=[Obj(id=uuid.UUID(t['uuid']),workplan_id=parent.id,status='done') for t in B['tasks']] ++ return repo,parent,tasks ++async def run_api(entries,repo,parent,tasks,ordinary=None): ++ rows=([parent] if parent else [])+([ordinary] if ordinary else []) ++ session=Session([rows,[repo] if repo else [],tasks]) ++ fn=extracted('api/routers/workstreams.py','sync_workplan_bindings',dict(frozen_cluster_binding=h.frozen_cluster_binding,validate_frozen_cluster_rows=h.validate_frozen_cluster_rows,HTTPException=HTTPException,select=lambda *_:Query(),Workplan=Model,Task=Model,ManagedRepo=Model,_invalidate_workplan_index_cache=lambda:None)) ++ result=await fn(Obj(bindings=[Entry(**e) for e in entries]),session) ++ return result,session ++@pytest.mark.parametrize('change',[dict(repo_slug='foreign'),dict(workplan_id=uuid.uuid4()),dict(relative_path='workplans/other.md'),dict(filename='other.md'),dict(archived=False),dict(status='active')]) ++def test_metadata_refuses(change): ++ with pytest.raises(ValueError):h.frozen_cluster_binding(binding(**change)) ++def test_unrelated_binding_unchanged():assert h.frozen_cluster_binding(binding(workplan_id=uuid.uuid4(),filename='ordinary.md',relative_path='workplans/ordinary.md',repo_slug='other')) is None ++@pytest.mark.parametrize('fault',['parent_missing','foreign_repo','parent_active','task_missing','task_active','task_foreign','repo_missing']) ++def test_mixed_batch_refusal_precedes_all_writes(fault): ++ repo,parent,tasks=closure();ordinary=Obj(id=uuid.uuid4()) ++ if fault=='repo_missing':repo=None ++ if fault=='parent_missing':parent=None ++ if fault=='foreign_repo':parent.repo_id=uuid.uuid4() ++ if fault=='parent_active':parent.status='active' ++ if fault=='task_missing':tasks.pop() ++ if fault=='task_active':tasks[0].status='progress' ++ if fault=='task_foreign':tasks[0].workplan_id=uuid.uuid4() ++ if parent:parent.writes.clear() ++ for t in tasks:t.writes.clear() ++ normal=binding(workplan_id=ordinary.id,repo_slug='ordinary',filename='ordinary.md',relative_path='workplans/ordinary.md') ++ with pytest.raises(HTTPException):asyncio.run(run_api([normal,binding()],repo,parent,tasks,ordinary)) ++ assert ordinary.writes==[] ++ if parent:assert parent.writes==[] ++ assert all(t.writes==[] for t in tasks) ++def test_exact_frozen_no_setters_or_commit(): ++ repo,parent,tasks=closure();result,session=asyncio.run(run_api([binding()],repo,parent,tasks)) ++ assert result==dict(updated=0,received=1,preserved=1);assert session.commits==0;assert parent.writes==[] ++ assert all(q.locked and q.refreshed and q.ordered for q in (session.queries[0],session.queries[2])) ++def test_mixed_valid_preserves_frozen_and_updates_ordinary(): ++ repo,parent,tasks=closure();ordinary=Obj(id=uuid.uuid4()) ++ normal=binding(workplan_id=ordinary.id,repo_slug='ordinary',filename='ordinary.md',relative_path='workplans/ordinary.md') ++ result,session=asyncio.run(run_api([normal,binding()],repo,parent,tasks,ordinary)) ++ assert result==dict(updated=1,received=2,preserved=1);assert session.commits==1;assert parent.writes==[] ++ assert ordinary.writes==['backing_filename','backing_relative_path','backing_archived','backing_synced_at'] ++@pytest.mark.parametrize('tamper',['metadata','bytes','symlink','missing_scan','missing_uuid','valid']) ++@pytest.mark.parametrize("bound_index", range(3)) ++def test_cli_exact_source_omission_or_whole_batch_refusal(tmp_path,tamper,bound_index): ++ bound=h.FROZEN_CLUSTER_BINDINGS[bound_index] ++ import shutil ++ infos=[] ++ for entry in h.FROZEN_CLUSTER_BINDINGS: ++ target=tmp_path/entry['path'];target.parent.mkdir(parents=True,exist_ok=True) ++ shutil.copyfile(Path('/home/worsch/railiance-cluster')/entry['path'],target) ++ infos.append((target,dict(state_hub_workstream_id=entry['uuid'],status='finished'),'')) ++ path=tmp_path/bound['path'] ++ meta=dict(state_hub_workstream_id=bound['uuid'],status='finished') ++ if tamper=='metadata':meta['status']='active' ++ if tamper=='missing_uuid':meta.pop('state_hub_workstream_id') ++ if tamper=='bytes':path.write_text(path.read_text()+'\n') ++ if tamper=='symlink':path.unlink();path.symlink_to(Path('/home/worsch/railiance-cluster')/bound['path']) ++ ordinary=tmp_path/'workplans/ordinary.md';ordinary.write_text('ordinary') ++ if tamper=='missing_scan':infos.pop(bound_index) ++ else:infos[bound_index]=(path,meta,'') ++ calls=[];report=actual_report() ++ fn=extracted('scripts/consistency_check.py','_sync_workplan_bindings',dict(FROZEN_CLUSTER_BINDINGS=h.FROZEN_CLUSTER_BINDINGS,frozen_cluster_binding=h.frozen_cluster_binding,normalise_workstream_status=lambda s:s,workplan_display_path=lambda root,p:p.relative_to(root).as_posix(),_api_put=lambda *a:calls.append(a) or dict(updated=1,received=1))) ++ fn('http://unused','railiance-cluster',[(ordinary,dict(state_hub_workstream_id=str(uuid.uuid4()),status='active'),''),*infos],tmp_path,report) ++ if tamper=='valid':assert len(calls)==1 and len(calls[0][2]['bindings'])==1 ++ else:assert calls==[] and report.failures[0].check_id=='C-44' and report.automation_errors ++ ++ ++def test_api_tampered_mixed_batch_refuses_before_queries_or_assignments(): ++ repo,parent,tasks=closure();ordinary=Obj(id=uuid.uuid4()) ++ with pytest.raises(HTTPException): ++ asyncio.run(run_api([binding(workplan_id=ordinary.id,repo_slug='ordinary',filename='ordinary.md',relative_path='workplans/ordinary.md'),binding(archived=False)],repo,parent,tasks,ordinary)) ++ assert ordinary.writes==[] and parent.writes==[] ++ ++ ++def test_foreign_repo_same_filename_path_is_ordinary(): ++ assert h.frozen_cluster_binding(binding(workplan_id=uuid.uuid4(),repo_slug='foreign')) is None ++ ++ ++@pytest.mark.parametrize('entry',h.FROZEN_CLUSTER_BINDINGS) ++def test_all_three_registry_bindings_are_guarded(entry): ++ good=dict(workplan_id=entry['uuid'],repo_slug=entry['repo'],filename=Path(entry['path']).name,relative_path=entry['path'],archived=True,status='finished') ++ assert h.frozen_cluster_binding(good) is entry ++ with pytest.raises(ValueError):h.frozen_cluster_binding(dict(good,status='active')) ++ ++ ++def test_real_cli_exit_criterion_is_nonzero_including_remote_all(): ++ report=actual_report();report.add(severity='FAIL',check_id='C-44',message='refused') ++ fn=extracted('scripts/consistency_check.py','consistency_exit_code',{}) ++ assert fn([report])==1 and fn([report],remote_all=True)==1 diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/validation.json b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/validation.json new file mode 100644 index 00000000..b6e64947 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/validation.json @@ -0,0 +1,17 @@ +{ + "isolated_regression_tests": 40, + "pytest_exit": 0, + "pytest_command": "python3 -m pytest --noconftest -q state-hub/tests/test_frozen_binding_guard_isolated.py", + "normal_make_render_exit": 0, + "render_complete_tracked_chart": true, + "rendered_objects": 8, + "runtime_images": [ + "forgejo.coulomb.social/coulomb/state-hub:main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015", + "forgejo.coulomb.social/coulomb/state-hub:main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015", + "forgejo.coulomb.social/coulomb/state-hub:main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015" + ], + "classification_check_exit": 0, + "no_DB_or_cluster_access": true, + "no_canonical_mutations": true, + "original_r1_r2_receipts_preserved": true +} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/REVIEW.md b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/REVIEW.md new file mode 100644 index 00000000..680fc1be --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/REVIEW.md @@ -0,0 +1,43 @@ +# Immutable ordinary-binding repair, source revision 4 + +Canonical base: 086d79a2736e34b916bd7de3c8a65e2ea38a3d64. The ten-path patch includes the previously reviewed six-path followthrough and four guard/test paths. Originals and the actual failed publication receipt remain untouched. + +The approved revision-4 receiving rollout preserved all 18 rows at its verification stage. A later ordinary Cluster publication changed exactly three parent full-row hashes; all 15 task hashes remained unchanged. The binding endpoint assigns a new backing sync timestamp unconditionally, providing a concrete mutation path. Hash-only snapshots do not establish the exact changed columns or supply original preimages. This patch does not restore them. + +Only the three existing task-bound railiance-cluster registry entries receive this guard. The CLI requires all three scan members, validates their exact source bytes and metadata, and omits valid immutable bindings before contacting any receiver. A refused batch becomes C-44 FAIL and returns a nonzero exit even in remote-all mode. The API independently validates all request metadata before any assignment, locks and refreshes parent/task rows, checks actual repo ownership and existing terminal required-bound tasks, and skips every setter for valid frozen rows. Additional children retain existing Forge receiving semantics; no new child-set invariant is introduced. The ordinary binding response retains updated/received and adds preserved. Frozen-only requests perform no commit or cache invalidation. Existing get_session uses an async-session context manager, which closes the read transaction and releases locks on exit. + +Validation: 75 isolated tests pass with --noconftest. Tests extract actual source functions/classes without importing owner app configuration or opening a DB. They verify all three exact sources, missing scan member/UUID, changed source and metadata, foreign names, complete mixed-batch refusal, API ownership and terminal-state refusal, no frozen setters/commit, ordinary compatibility, lock/refresh query intent and actual CLI exit criteria. The full tracked chart plus overlay passes normal Make render/classification check: eight objects, three unchanged digest-qualified images. No concurrency/native DB behavior is claimed by these source tests. + +T06 remains done for the approved delivery at its verification stage; T07 remains wait for failed whole-pipeline preservation. T09 is progress until source publication. T10 is wait/needs_human for a separate exact new runtime approval. New task UUIDs are intentionally unallocated pending root review and normal managed allocation. Preserve the original dirty brief/index/weekly evidence and index state. + +## Next runtime proposal preparation + +After reviewed source integration and normal publication, obtain normal CI status and resolve the resulting exact immutable image manifest. Inspect selected delivered source hashes, including historical_projection.py, workstreams.py and the installed closure; do not reuse the prior main-51bc70d runtime for the new API guard. Prepare digest-qualified packaged-chart reuse-values server dry-run, compare intended object identities/spec hashes, collect fresh release/headroom/schema and full-row hash baseline, then record a new scoped proposal and supervisor disposition. Current known prior baseline was Helm 76/schema c4d5e6f7a8b9; refresh rather than assume it remains current. CI revision, new image digest, final chart package hash and exact execution digest remain unresolved until publication. + +No new rollout is authorized by the prior revision-4 approval. A new rollout must retain migration closure and rollback limits: Helm rollback does not downgrade schema, and timeout/atomic does not necessarily stop an active hook Job. Cancellation may address only the exact owned trial Job UID/image after identity verification. Unknown migration recovery or connection/lock quiescence stops for attended owner handling; no credential grant or invented DB-session mapping. EUR cost and risk are unknown until reviewed; no bounded-outage assertion. New baseline preservation and rollback-only refusal probes prove the new stage, never restoration of the unavailable original parent preimages. T07/RMGR19T06 cannot close on source publication alone. + + +Revision 4 retains frozen revision 3 and adds central consistency repair-batch +refusal. The same helper checks exact registered parent/task UUIDs and source +paths before check_repo can issue an index binding PUT and again before +fix_repo can invoke reconcile, push, metadata registration or individual fixes. +A protected repair finding refuses the complete batch with C-44, including +when an ordinary fix appears first. Existing C-44 refusal is not duplicated. +This prevents generic C-04/C-10/C-22 and related fixes from modifying frozen +rows through other APIs. It does not disable ordinary checks or silently +accept source/DB drift: owner review and the waiting live records remain. +Tests invoke the actual fix engine with mixed fix lists for all three parents, +exercise bound task/source contexts, and verify unchanged ordinary behavior. +API preservation/refusal simulations now exercise all three parent closures. + + +The post-publication client regression can compare fresh CURRENT full-row hashes +before/after the fixed normal Cluster deep consistency and fast projection. +That is a separate stage from the preserved original failure; equal fresh +hashes do not restore or accept the unavailable original parent preimages. +For T10 prefer the exact originally approved b5c chart archive with only the +newly verified immutable guard image changed, after artifact identity and +server dry-run comparison. Do not infer authority to roll out the source chart's +v1.1 classification ConfigMap or other chart metadata changes. Source Make +pins continue to declare the actually delivered 51bc70d@c802 artifact until a +new exact runtime is approved and verified. diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/manifest.json b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/manifest.json new file mode 100644 index 00000000..8933cca7 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/manifest.json @@ -0,0 +1,77 @@ +{ + "schema": "statehub.source-owner-followthrough.v1", + "revision": 4, + "status": "isolated_source_candidate_not_published", + "base_revision": "086d79a2736e34b916bd7de3c8a65e2ea38a3d64", + "files": [ + { + "path": "workplans/STATE-WP-0095-historical-source-receiving.md", + "action": "modify", + "base_sha256": "ef10359cc5974283b5bdbfc602adf14e3c24362adf00640698d2937c6538483a", + "candidate_sha256": "5671189ee87f2d4dff08979f6243e5eb7888b140955899642a74d569496b71c7" + }, + { + "path": "Makefile", + "action": "modify", + "base_sha256": "5584ef94071044cca8215141ecd8aee8d6ae5cfe73e8f5719358c680eb8af0d4", + "candidate_sha256": "c5b70e8d4b8ae70380e0ade1c35f9e7fe80038de10080a4723b21ef07a98001e" + }, + { + "path": "deploy/railiance/apps/charts/state-hub/Chart.yaml", + "action": "modify", + "base_sha256": "7fe02b390ffd2ba4ce6f82bd62df900826826401e31bdc2138dd5bf36b51a6ae", + "candidate_sha256": "61a989fcf277d05ffbececb7332ee3ca1d8f369c72f960ab1bc4dbc6815536b8" + }, + { + "path": "deploy/railiance/apps/helm/state-hub-values.yaml", + "action": "modify", + "base_sha256": "f7cc0e9968598f6ce0faa0d56f62d6817845c3570c18b6ac39ed6561b952b197", + "candidate_sha256": "b51296fc937450f4ecf0ae43243262a631b551389c0d09c8bfe58fa10e2f3ee9" + }, + { + "path": "docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json", + "action": "add", + "base_sha256": null, + "candidate_sha256": "fb0b59ba3558e084fb4ae2c36c556f3cfbb2a889f6fd86d4e803c52f483b26fd" + }, + { + "path": "deploy/railiance/apps/charts/state-hub/files/repo-classification.allowed.yaml", + "action": "modify", + "base_sha256": "9c36fbd5308b19695f9f05d86f8e315bbeccdd267575ce4e2fccf6fb2ea82e32", + "candidate_sha256": "f53c651bb4329c09c04c66f906e2462fe4339ab51ef0ec3da9f942c3016f5bed" + }, + { + "path": "api/services/historical_projection.py", + "action": "modify", + "base_sha256": "e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2", + "candidate_sha256": "e24e57c58f4aaa4ec9d9bf088009ac69006e53f75b9477ee53dc26c4e850b975" + }, + { + "path": "api/routers/workstreams.py", + "action": "modify", + "base_sha256": "61e7a0ab638b155e9e0b2a72fe8e0ddd2edf5bc6c2d3ca7f6c3ff51e8868910b", + "candidate_sha256": "9c9bf4376dd323b52109912bb3f615949e89ac02c8b88b4720f569f8565ad1d6" + }, + { + "path": "scripts/consistency_check.py", + "action": "modify", + "base_sha256": "1827921c79b476bee823c2ddf9896aeb83f3efca6548427e17b3244216bbc6b5", + "candidate_sha256": "c2dc6e1b930198ae8352de05573fc6d3b58709996a8499cec4e3f5217546c543" + }, + { + "path": "tests/test_frozen_binding_guard_isolated.py", + "action": "add", + "base_sha256": null, + "candidate_sha256": "17dfc4733dce5da4195556d1b0b87eca4783f8760b40c74220c331edfcef32f5" + } + ], + "patch_sha256": "sha256:c06bc0a3e667e9ae6407f60887ba8feddc66d19a2c21dfc86d1bbe3718361708", + "T06": "done_verified_approved_rollout_at_stage", + "T07": "wait_actual_later_parent_row_preservation_failure", + "T08": "done_source_repair_pending_publication", + "T09": "progress_until_source_published", + "T10": "wait_needs_human_new_runtime", + "live_effects": false, + "original_parent_preimages": "unknown_do_not_restore_guesses", + "managed_UUIDs": "T09_T10_not_allocated_pending_review" +} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/state-hub-followthrough.patch b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/state-hub-followthrough.patch new file mode 100644 index 00000000..99884afa --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/state-hub-followthrough.patch @@ -0,0 +1,756 @@ +--- a/workplans/STATE-WP-0095-historical-source-receiving.md ++++ b/workplans/STATE-WP-0095-historical-source-receiving.md +@@ -199,27 +199,37 @@ + + ```task + id: STATE-WP-0095-T06 +-status: wait ++status: done + priority: high + depends_on: [STATE-WP-0095-T05] +-needs_human: true +-intervention_note: "Review exact committed source, CI image and owner deployment proposal before rollout." ++needs_human: false ++intervention_note: "Exact revision 4 approved and verified; no pending rollout intervention." + state_hub_task_id: "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4" + ``` + +-Use the normal CI image and Helm owner path after exact revision/image pin, +-fresh headroom and reviewed dry-run/diff. API/MCP currently run main-7d99282; +-Helm revision75 is the observed rollback baseline, requiring freshness before +-execution. No deployment assent exists for this successor. Verify delivered +-module hash, health, both readiness checks and expected migrated schema +-c4d5e6f7a8b9; verify exact +-three parents/15 tasks and rejection behavior without committed probe changes. +-Only the verified return unblocks RMGR-WP-0019-T05. The full current image also carries inbox-feed migration c4d5e6f7a8b9, +-although this receiver patch adds none. Helm rollback leaves that migration in +-place; unrelated migration acceptance and old-image compatibility need normal +-owner evidence before rollout approval. Do not run destructive default local +-DB tests; use only exact disposable DB containment. Costs and monetary risk are +-unknown pending exact rollout proposal; no zero-cost or autonomy grant is inferred. ++Completed 2026-10-17 on the founder's approval of exact revision 4 of stable ++proposal STATE-WP-0095-T06-cluster-frozen-receiving-r1 (decision ++ e3798419-8aa9-5425-8c08-20df6bd82a19; approved digest ++ sha256:63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32). ++The ordinary owner Helm path delivered revision 76, runtime source 51bc70d and ++exact image manifest sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015. ++API/MCP Ready and primary/railiance01 health report expected schema ++c4d5e6f7a8b9; delivered historical module sha256:e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2 matches. ++All three parent and 15 task full DB row hashes/columns/UUIDs remained unchanged. ++Five actual native probes passed: preserve, actual foreign-parent holder move, ++nonterminal task, nonterminal parent and missing task. Every probe rolled back; ++a fresh transaction confirmed complete row restoration. The foreign-holder ++case precisely verified historical binding refusal, not the separate global ++UUID-holder creation branch. No committed probe writes were made. ++ ++Evidence: [verified receiving rollout](../docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json). ++This actual receiving return satisfies the prerequisite of RMGR-WP-0019-T05. ++Normal cluster publication and its immutable-source/row return remain T07; ++source readiness and this deployment do not count that later acceptance twice. ++The additive inbox migration is retained; Helm rollback does not downgrade ++schema or stop an active migration Job. Original failures and exact-UID recovery ++limits remain in the referenced approved packet. No TLS recovery/native private ++admission or new autonomy/cost grant is inferred. + + ## Verify ordinary cluster receiving and immutable historical rows + +@@ -256,6 +266,74 @@ + Command-fixture tests verify both requests and preserve other dry-run phases. + Evidence and original refusal remain in the Custodian cluster historical + publication packet, revisions/r2 and r3-readiness. This is completed source +-preparation; T06 remains the explicit native rollout gate. The runtime image ++preparation; T06 separately records the verified actual rollout. The runtime image + continues to be main-51bc70d; Makefile/workplan changes do not create a new + application image or native acceptance. ++ ++ ++T08 source repair refinement, 2026-10-17: the required normal Make render ++correctly refused a pre-existing generated chart classification copy at v1.0 ++after authoritative canon reached v1.1. Regenerated only through the existing ++scripts/sync_classification_allowed.py, preserving canon and strict check. ++The exact source diff is version 1.0→1.1 plus publication/history/participation. ++Normal Make rendering and the focused classification check passed in an ++isolated owner-layout copy. The original refusal is retained in the Custodian ++owner-followthrough-r1 validation receipt. This is source repair only: no live ++ConfigMap apply, new runtime image, policy relaxation or T07 completion. ++ ++ ++T07 actual ordinary-publication return, 2026-10-17: cluster owner deep consistency ++and normal fast projection completed, exact archived source bytes and all 15 ++historical task full-row hashes remained unchanged. The later full-row check ++FAILED for exactly the three parent rows. The earlier approved T06 rollout had ++preserved all 18 rows at its verification stage; that success is not the later ++whole-pipeline acceptance. The original snapshots retain hashes only, so exact ++changed columns and original field preimages are not established. No guessed ++DB repair or claim that all 18 original row hashes are restored is authorized. ++T07 and RMGR-WP-0019-T06 remain waiting pending T09/T10 and a reviewed return. ++ ++## Guard immutable historical index bindings in CLI and receiving API ++ ++```task ++id: STATE-WP-0095-T09 ++status: progress ++priority: high ++depends_on: [STATE-WP-0095-T06] ++``` ++ ++Prepare and publish the narrowly scoped ordinary-binding repair for the three ++existing task-bound Cluster registry entries. The CLI verifies exact frozen ++source metadata/bytes and omits those bindings, including on old receivers. ++The API independently validates the complete batch before any mutation, checks ++actual repo ownership and the existing terminal parent/task closure, and ++preserves valid frozen rows without field or timestamp assignments. Invalid ++metadata, missing/foreign/nonterminal rows refuse the batch. Unknown ordinary ++bindings retain existing behavior; historical IDs, UUIDs and source bytes stay ++unchanged. Isolated regression tests and normal owner rendering are required. ++Mark done only after reviewed source publication and normal owner projection; ++source preparation does not establish delivered runtime or T07 acceptance. ++Central check/fix engines also refuse the complete repair batch if any fixable ++context touches an exact registered parent/task UUID or frozen source path. ++This runs before index bindings and before reconcile/push/individual fixes; ++ordinary earlier fixes cannot partially execute before a later frozen refusal. ++ ++## Deliver and verify the ordinary-binding guard successor ++ ++```task ++id: STATE-WP-0095-T10 ++status: wait ++priority: high ++depends_on: [STATE-WP-0095-T09] ++needs_human: true ++intervention_note: "New API runtime requires its own exact image, reviewed preflight and scoped rollout approval; prior revision-4 approval does not cover it." ++``` ++ ++After source publication, resolve normal CI status and immutable image identity, ++verify delivered guard source closure, prepare exact chart/reuse-values dry-run, ++full closure/headroom/schema baseline and conditional recovery. Retain additive ++migration and active-Job cancellation limitations; no Helm schema downgrade or ++bounded-outage claim. Obtain scoped approval before live rollout. Then verify ++new full-row baseline preservation and actual rollback-only refusal probes, ++and only then return to T07 ordinary-pipeline acceptance. This prevents future ++binding mutation; it does not reconstruct or restore original parent hashes. ++No production changes, new autonomy or credential authority are granted here. +--- a/Makefile ++++ b/Makefile +@@ -9,7 +9,7 @@ + RAILIANCE_STATE_HUB_NAMESPACE ?= state-hub + RAILIANCE_STATE_HUB_CHART ?= deploy/railiance/apps/charts/state-hub + RAILIANCE_STATE_HUB_VALUES ?= deploy/railiance/apps/helm/state-hub-values.yaml +-RAILIANCE_STATE_HUB_IMAGE_TAG ?= main-0747b4d ++RAILIANCE_STATE_HUB_IMAGE_TAG ?= main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015 + RAILIANCE_STATE_HUB_PLATFORM_DIR ?= deploy/railiance/platform + RAILIANCE_STATE_HUB_APP_MANIFESTS ?= deploy/railiance/apps/manifests + # Codex/WSL non-login shells may not source ~/.profile; keep uv discoverable. +--- a/deploy/railiance/apps/charts/state-hub/Chart.yaml ++++ b/deploy/railiance/apps/charts/state-hub/Chart.yaml +@@ -3,4 +3,4 @@ + description: State Hub API service for private Railiance operation + type: application + version: 0.1.0 +-appVersion: "main-5dd3df9" ++appVersion: "main-51bc70d" +--- a/deploy/railiance/apps/helm/state-hub-values.yaml ++++ b/deploy/railiance/apps/helm/state-hub-values.yaml +@@ -6,7 +6,7 @@ + + image: + repository: forgejo.coulomb.social/coulomb/state-hub +- tag: "main-0747b4d" ++ tag: "main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015" + + ingress: + enabled: false +--- /dev/null ++++ b/docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json +@@ -0,0 +1,116 @@ ++{ ++ "schema": "statehub.cluster-historical-receiving-delivered.v1", ++ "status": "verified", ++ "proposal_id": "STATE-WP-0095-T06-cluster-frozen-receiving-r1", ++ "approved_revision": 4, ++ "approved_digest_sha256": "sha256:63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32", ++ "approval_decision_id": "e3798419-8aa9-5425-8c08-20df6bd82a19", ++ "source_revision": "51bc70d1ff8f25450a8650d8e50caf053093a02e", ++ "readiness_source_revision": "086d79a2736e34b916bd7de3c8a65e2ea38a3d64", ++ "helm_revision": 76, ++ "image_reference": "forgejo.coulomb.social/coulomb/state-hub:main-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015", ++ "expected_schema": "c4d5e6f7a8b9", ++ "health": { ++ "status": "ok", ++ "instance_role": "primary", ++ "instance_label": "railiance01", ++ "schema": { ++ "status": "ok", ++ "applied": "c4d5e6f7a8b9", ++ "expected": "c4d5e6f7a8b9" ++ } ++ }, ++ "pods_ready": true, ++ "historical_module_sha256": "sha256:e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2", ++ "historical_preservation_verified": true, ++ "parents": 3, ++ "tasks": 15, ++ "full_historical_rows_equal": true, ++ "native_rollback_probes": { ++ "foreign-holder": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "missing-task": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "nonterminal-parent": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "nonterminal-task": { ++ "full_historical_rows_restored": true, ++ "historical_binding_refused": true, ++ "native_outcome_status": "refused", ++ "rolled_back": true, ++ "status": "passed" ++ }, ++ "preserve": { ++ "full_historical_rows_equal": true, ++ "full_historical_rows_restored": true, ++ "native_outcome_status": "applied", ++ "rolled_back": true, ++ "status": "passed" ++ } ++ }, ++ "native_probe_commits": 0, ++ "fresh_transaction_full_rows_equal": true, ++ "source_receiving_gate_delivered": true, ++ "normal_cluster_publication_verified": false, ++ "registrar_admission_or_cluster_publication_not_inferred": true, ++ "authority_limits": [ ++ "Rollback probe SQL effects rolled back; foreign-holder case is historical-binding refusal, not separate global holder branch.", ++ "Actual historical native receiving is verified; owner-native TLS/private admission remains unresolved.", ++ "Migration schema remains additive; Helm rollback does not downgrade schema or stop an active hook Job." ++ ], ++ "evidence": [ ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/approval-decision.json", ++ "sha256": "sha256:b51554c004daa882f3709f67bdae7f2e939d611120383e61be04ec6969878134" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/helm-return.json", ++ "sha256": "sha256:61727deacf22d37da2d28cbaf04f5a3ddee0f9ff7571c77f1e85dba97963b572" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/delivered-runtime.json", ++ "sha256": "sha256:89681066e8fe139456163ebfafa3efe77ffae8534ea167219230b0a74367f129" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/native-refusal-probes.json", ++ "sha256": "sha256:673ccef965c820704dc310a1bf7832b583c30c3edfeb814528cf892555199172" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-full-row-hashes.json", ++ "sha256": "sha256:75cdd87eef79059ff3f484ed24ca69e285899cdf8d851cc4e472653c417eb0ee" ++ }, ++ { ++ "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-full-row-hashes.json", ++ "sha256": "sha256:2156aad18f190384838c27e792706a156a7423391408afbc6107e6c28c5872d8" ++ } ++ ], ++ "later_ordinary_cluster_publication": { ++ "status": "failed_full_parent_row_preservation", ++ "changed_parent_hashes": 3, ++ "unchanged_task_hashes": 15, ++ "exact_changed_columns": "unknown_hash_only_baseline", ++ "original_parent_preimages": "unavailable_no_guessed_restoration", ++ "receipt": "the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json", ++ "T07": "wait", ++ "RMGR_WP_0019_T06": "wait", ++ "followup": [ ++ "STATE-WP-0095-T09", ++ "STATE-WP-0095-T10" ++ ] ++ } ++} +--- a/deploy/railiance/apps/charts/state-hub/files/repo-classification.allowed.yaml ++++ b/deploy/railiance/apps/charts/state-hub/files/repo-classification.allowed.yaml +@@ -13,7 +13,7 @@ + # to match the standard version. CUST-WP-0050 T01. + + standard: "Repo Classification Standard" +-version: "1.0" ++version: "1.1" + canon_id: "canon-repo-classification" + + # category — exactly 1 required (§5) +@@ -24,6 +24,7 @@ + - tooling + - product + - business ++ - publication + + # domain / secondary_domains — primary exactly 1; secondaries 0..n (§6) + domains: +@@ -85,6 +86,8 @@ + - traceability + - documentation + - decision-support ++ - history ++ - participation + platform_and_operations: + - platform + - deployment +--- a/api/services/historical_projection.py ++++ b/api/services/historical_projection.py +@@ -193,3 +193,46 @@ + raise ValueError("Historical source binding changed: " + entry["path"]) + result.append((entry, data.decode("utf-8"))) + return result ++ ++ ++# Only the three existing full-task Cluster bindings have immutable DB rows. ++# Other historical views retain their existing compatibility behavior. ++FROZEN_CLUSTER_BINDINGS = tuple( ++ entry for entry in BINDINGS ++ if entry["repo"] == "railiance-cluster" and "tasks" in entry ++) ++ ++ ++def frozen_cluster_binding(binding): ++ """Validate a claimed frozen binding; unrelated requests remain ordinary.""" ++ matches = [entry for entry in FROZEN_CLUSTER_BINDINGS ++ if str(binding["workplan_id"]) == entry["uuid"] ++ or (binding["repo_slug"] == "railiance-cluster" ++ and (binding["relative_path"] == entry["path"] ++ or binding["filename"] == Path(entry["path"]).name))] ++ if not matches: ++ return None ++ if len(matches) != 1: ++ raise ValueError("frozen historical binding is ambiguous") ++ entry = matches[0] ++ expected = { ++ "workplan_id": entry["uuid"], "repo_slug": entry["repo"], ++ "filename": Path(entry["path"]).name, "relative_path": entry["path"], ++ "archived": True, "status": "finished", ++ } ++ if any((str(binding[key]) if key == "workplan_id" else binding[key]) != value ++ for key, value in expected.items()): ++ raise ValueError("frozen historical binding metadata changed") ++ return entry ++ ++ ++def validate_frozen_cluster_rows(entry, parent, tasks, repo_id): ++ """Receiving requires the exact existing terminal closure, never repair.""" ++ if (parent is None or str(parent.id) != entry["uuid"] ++ or repo_id is None or parent.repo_id != repo_id ++ or parent.status not in {"done", "finished", "archived", "completed"}): ++ raise ValueError("frozen historical parent missing, foreign or nonterminal") ++ local = {str(task.id): task for task in tasks if task.workplan_id == parent.id} ++ if any(task["uuid"] not in local or local[task["uuid"]].status not in {"done", "cancel"} ++ for task in entry["tasks"]): ++ raise ValueError("frozen historical task missing, foreign or nonterminal") +--- a/api/routers/workstreams.py ++++ b/api/routers/workstreams.py +@@ -16,6 +16,8 @@ + from api.events import EventEnvelope, publish_event + from api.models.managed_repo import ManagedRepo + from api.models.workplan import Workplan ++from api.models.task import Task ++from api.services.historical_projection import frozen_cluster_binding, validate_frozen_cluster_rows + from api.schemas.workplan import ( + WorkplanBindingsSync, + WorkplanCreate, +@@ -435,12 +437,42 @@ + session: AsyncSession = Depends(get_session), + ) -> dict[str, int]: + """Upsert workstation workplan file bindings for remote API index fallback.""" ++ # Preflight the complete batch before assigning even an ordinary row. ++ try: ++ frozen = {entry.workplan_id: bound for entry in body.bindings ++ if (bound := frozen_cluster_binding(entry.model_dump())) is not None} ++ except ValueError as exc: ++ raise HTTPException(status_code=409, detail=str(exc)) from exc ++ requested_ids = {entry.workplan_id for entry in body.bindings} ++ rows = await session.execute( ++ select(Workplan).where(Workplan.id.in_(requested_ids)) ++ .order_by(Workplan.id).with_for_update().execution_options(populate_existing=True) ++ ) ++ workplans = {workplan.id: workplan for workplan in rows.scalars().all()} ++ if frozen: ++ repo_rows = await session.execute( ++ select(ManagedRepo).where(ManagedRepo.slug == "railiance-cluster") ++ ) ++ repo = repo_rows.scalar_one_or_none() ++ task_rows = await session.execute( ++ select(Task).where(Task.workplan_id.in_(frozen)) ++ .order_by(Task.id).with_for_update().execution_options(populate_existing=True) ++ ) ++ tasks = task_rows.scalars().all() ++ try: ++ for workplan_id, bound in frozen.items(): ++ validate_frozen_cluster_rows( ++ bound, workplans.get(workplan_id), tasks, repo.id if repo else None ++ ) ++ except ValueError as exc: ++ raise HTTPException(status_code=409, detail=str(exc)) from exc + synced_at = datetime.now(timezone.utc) + updated = 0 +- requested_ids = {entry.workplan_id for entry in body.bindings} +- rows = await session.execute(select(Workplan).where(Workplan.id.in_(requested_ids))) +- workplans = {workplan.id: workplan for workplan in rows.scalars().all()} ++ preserved = 0 + for entry in body.bindings: ++ if entry.workplan_id in frozen: ++ preserved += 1 ++ continue # No setters, including backing_synced_at/updated_at. + wp = workplans.get(entry.workplan_id) + if wp is None: + continue +@@ -449,9 +481,10 @@ + wp.backing_archived = entry.archived + wp.backing_synced_at = synced_at + updated += 1 +- await session.commit() +- _invalidate_workplan_index_cache() +- return {"updated": updated, "received": len(body.bindings)} ++ if updated: ++ await session.commit() ++ _invalidate_workplan_index_cache() ++ return {"updated": updated, "received": len(body.bindings), "preserved": preserved} + + + @router.post("/", status_code=status.HTTP_410_GONE) +--- a/scripts/consistency_check.py ++++ b/scripts/consistency_check.py +@@ -120,7 +120,9 @@ + resolve_topic_domain_slug, + ) + from api.services.lifecycle import should_activate_parent_for_active_tasks # noqa: E402 +-from api.services.historical_projection import BINDINGS as _HISTORICAL_BINDINGS # noqa: E402 ++from api.services.historical_projection import ( # noqa: E402 ++ BINDINGS as _HISTORICAL_BINDINGS, FROZEN_CLUSTER_BINDINGS, frozen_cluster_binding, ++) + from api.task_status import ( # noqa: E402 + CANONICAL_TASK_STATUSES, + OPEN_TASK_STATUSES, +@@ -318,7 +320,7 @@ + + # C-00 marks infrastructure/automation faults (API down, repo missing in DB). + # All other FAIL severities are assessment findings for follow-up. +-_AUTOMATION_ERROR_CHECKS: frozenset[str] = frozenset({"C-00"}) ++_AUTOMATION_ERROR_CHECKS: frozenset[str] = frozenset({"C-00", "C-44"}) + _NON_WORKPLAN_WORKPLAN_FILES: frozenset[str] = frozenset({"README.md"}) + + +@@ -2484,6 +2486,8 @@ + _check_workplan_id_collisions(api_base, repo_slug, repo_dir, workplan_infos, report) + _check_scope_freshness(repo_dir, workplan_infos, report) + ++ if _refuse_frozen_fix_batch(report, repo_slug): ++ return report + _sync_workplan_bindings(api_base, repo_slug, workplan_infos, repo_dir, report) + + return report +@@ -2496,23 +2500,44 @@ + repo_dir: Path, + report: ConsistencyReport, + ) -> None: ++ if repo_slug == "railiance-cluster": ++ scanned_paths = {workplan_display_path(repo_dir, path) for path, _, _ in workplan_infos} ++ missing = [entry["path"] for entry in FROZEN_CLUSTER_BINDINGS ++ if entry["path"] not in scanned_paths] ++ if missing: ++ report.add(severity="FAIL", check_id="C-44", ++ message="Frozen binding batch refused: bound source missing from scan", ++ fixable=False) ++ return + bindings: list[dict[str, Any]] = [] + for wp_file, meta, _ in workplan_infos: + ws_id = str(meta.get("state_hub_workstream_id", "")).strip().strip('"') ++ archived = wp_file.parent.name == "archived" ++ file_status = normalise_workstream_status(str(meta.get("status", "")).strip()) ++ binding = { ++ "workplan_id": ws_id, "filename": wp_file.name, ++ "relative_path": workplan_display_path(repo_dir, wp_file), ++ "repo_slug": repo_slug, "archived": archived, ++ "status": file_status or None, ++ } ++ try: ++ frozen = frozen_cluster_binding(binding) ++ if frozen is not None: ++ # Verify exact source before omitting the immutable binding. ++ # This is safe even against a receiver predating the API guard. ++ from hashlib import sha256 ++ if (wp_file.is_symlink() or not wp_file.is_file() ++ or sha256(wp_file.read_bytes()).hexdigest() != frozen["sha256"]): ++ raise ValueError("frozen historical source missing or changed") ++ continue ++ except ValueError as exc: ++ report.add(severity="FAIL", check_id="C-44", ++ message=f"Frozen binding batch refused: {exc}", ++ file_path=str(wp_file), fixable=False) ++ return # Never send a partial batch after a frozen-source refusal. + if not ws_id: + continue +- archived = wp_file.parent.name == "archived" +- file_status = normalise_workstream_status(str(meta.get("status", "")).strip()) +- bindings.append( +- { +- "workplan_id": ws_id, +- "filename": wp_file.name, +- "relative_path": workplan_display_path(repo_dir, wp_file), +- "repo_slug": repo_slug, +- "archived": archived, +- "status": file_status or None, +- } +- ) ++ bindings.append(binding) + if not bindings: + return + result = _api_put(api_base, "/workplans/index/bindings", {"bindings": bindings}) +@@ -3610,6 +3635,44 @@ + # Fix engine + # --------------------------------------------------------------------------- + ++def _refuse_frozen_fix_batch(report: ConsistencyReport, repo_slug: str) -> bool: ++ """Refuse a complete repair batch touching the exact bound histories.""" ++ if any(issue.check_id == "C-44" and issue.severity == "FAIL" for issue in report.issues): ++ return True ++ protected_ids = {entry["uuid"] for entry in FROZEN_CLUSTER_BINDINGS} ++ protected_ids.update(task["uuid"] for entry in FROZEN_CLUSTER_BINDINGS ++ for task in entry["tasks"]) ++ paths = {entry["path"] for entry in FROZEN_CLUSTER_BINDINGS} ++ root = Path(report.repo_path).absolute() if report.repo_path else None ++ ++ def protected(value, key=""): ++ if isinstance(value, dict): ++ return any(protected(item, name) for name, item in value.items()) ++ if isinstance(value, (list, tuple)): ++ return any(protected(item, key) for item in value) ++ text = str(value) ++ if (key in {"id", "db_id", "ws_id", "task_id"} ++ or key.endswith(("_id", "_uuid"))): ++ if text in protected_ids: ++ return True ++ if key in {"file_path", "wp_file", "md_path", "path"} and text: ++ candidate = Path(text) ++ if candidate.is_absolute(): ++ return root is not None and any(candidate.absolute() == root / path for path in paths) ++ return repo_slug == "railiance-cluster" and candidate.as_posix() in paths ++ return False ++ ++ for issue in report.issues: ++ if issue.fixable and (protected(issue.db_id, "db_id") ++ or protected(issue.file_path, "file_path") ++ or protected(issue._fix_context)): ++ report.add(severity="FAIL", check_id="C-44", ++ message="Frozen historical repair batch refused; owner review required", ++ fixable=False) ++ return True ++ return False ++ ++ + def fix_repo( + api_base: str, + repo_slug: str, +@@ -3624,7 +3687,9 @@ + repo_path_override, + bootstrap_empty_projection=bootstrap_empty_projection, + ) +- if any(i.check_id in {"C-00", "C-36"} for i in report.failures): ++ if _refuse_frozen_fix_batch(report, repo_slug): ++ return report ++ if any(i.check_id in {"C-00", "C-36", "C-44"} for i in report.failures): + return report + + # RMGR-WP-0002: optional repo-manager reconcile proxy (index rebuild) for pilots +--- /dev/null ++++ b/tests/test_frozen_binding_guard_isolated.py +@@ -0,0 +1,180 @@ ++from pathlib import Path ++import ast, asyncio, importlib.util, types, uuid ++from dataclasses import dataclass, field ++from datetime import datetime, timezone ++import pytest ++ ++ROOT = Path(__file__).resolve().parents[1] ++spec=importlib.util.spec_from_file_location('historical',ROOT/'api/services/historical_projection.py') ++h=importlib.util.module_from_spec(spec);spec.loader.exec_module(h) ++B=h.FROZEN_CLUSTER_BINDINGS[0] ++def binding(_bound=B,**changes): ++ B=_bound ++ d=dict(workplan_id=uuid.UUID(B['uuid']),repo_slug=B['repo'],filename=Path(B['path']).name,relative_path=B['path'],archived=True,status='finished');d.update(changes);return d ++class Obj: ++ def __init__(self,**kw):self.__dict__.update(kw);self.writes=[] ++ def __setattr__(self,k,v): ++ if 'writes' in self.__dict__:self.writes.append(k) ++ object.__setattr__(self,k,v) ++class Entry(Obj): ++ def model_dump(self):return {k:v for k,v in self.__dict__.items() if k!='writes'} ++class Col: ++ def in_(self,x):return self ++ def __eq__(self,x):return self ++class Query: ++ def __init__(self):self.locked=False;self.refreshed=False;self.ordered=False ++ def where(self,*a):return self ++ def order_by(self,*a):self.ordered=True;return self ++ def with_for_update(self):self.locked=True;return self ++ def execution_options(self,**kw):self.refreshed=kw.get("populate_existing") is True;return self ++class Model: id=Col();slug=Col();workplan_id=Col() ++class Result: ++ def __init__(self,values):self.values=values ++ def scalars(self):return self ++ def all(self):return self.values ++ def scalar_one_or_none(self):return self.values[0] if self.values else None ++class Session: ++ def __init__(self,rows):self.results=iter(rows);self.commits=0;self.queries=[] ++ async def execute(self,q):self.queries.append(q);return Result(next(self.results)) ++ async def commit(self):self.commits+=1 ++class HTTPException(Exception): ++ def __init__(self,status_code,detail):self.status_code=status_code;super().__init__(detail) ++def extracted(path,name,extra): ++ tree=ast.parse((ROOT/path).read_text());node=next(n for n in tree.body if isinstance(n,(ast.FunctionDef,ast.AsyncFunctionDef)) and n.name==name) ++ node.decorator_list=[];node.returns=None ++ for a in node.args.args + node.args.kwonlyargs:a.annotation=None ++ node.args.defaults=[] ++ ns=dict(Path=Path,datetime=datetime,timezone=timezone,**extra) ++ exec(compile(ast.Module(body=[node],type_ignores=[]),str(path),'exec'),ns);return ns[name] ++def actual_report(): ++ tree=ast.parse((ROOT/'scripts/consistency_check.py').read_text()) ++ nodes=[n for n in tree.body if (isinstance(n,ast.ClassDef) and n.name in {'Issue','ConsistencyReport'}) or (isinstance(n,ast.AnnAssign) and isinstance(n.target,ast.Name) and n.target.id=='_AUTOMATION_ERROR_CHECKS')] ++ ns=dict(dataclass=dataclass,field=field,_AUTOMATION_ERROR_CHECKS=frozenset({'C-00','C-44'})) ++ exec(compile(ast.Module(body=nodes,type_ignores=[]),'actual_report','exec'),ns) ++ return ns['ConsistencyReport']('railiance-cluster','/unused') ++ ++def closure(B=B): ++ repo=Obj(id=uuid.uuid4());parent=Obj(id=uuid.UUID(B['uuid']),repo_id=repo.id,status='finished') ++ tasks=[Obj(id=uuid.UUID(t['uuid']),workplan_id=parent.id,status='done') for t in B['tasks']] ++ return repo,parent,tasks ++async def run_api(entries,repo,parent,tasks,ordinary=None): ++ rows=([parent] if parent else [])+([ordinary] if ordinary else []) ++ session=Session([rows,[repo] if repo else [],tasks]) ++ fn=extracted('api/routers/workstreams.py','sync_workplan_bindings',dict(frozen_cluster_binding=h.frozen_cluster_binding,validate_frozen_cluster_rows=h.validate_frozen_cluster_rows,HTTPException=HTTPException,select=lambda *_:Query(),Workplan=Model,Task=Model,ManagedRepo=Model,_invalidate_workplan_index_cache=lambda:None)) ++ result=await fn(Obj(bindings=[Entry(**e) for e in entries]),session) ++ return result,session ++@pytest.mark.parametrize('change',[dict(repo_slug='foreign'),dict(workplan_id=uuid.uuid4()),dict(relative_path='workplans/other.md'),dict(filename='other.md'),dict(archived=False),dict(status='active')]) ++def test_metadata_refuses(change): ++ with pytest.raises(ValueError):h.frozen_cluster_binding(binding(**change)) ++def test_unrelated_binding_unchanged():assert h.frozen_cluster_binding(binding(workplan_id=uuid.uuid4(),filename='ordinary.md',relative_path='workplans/ordinary.md',repo_slug='other')) is None ++@pytest.mark.parametrize('fault',['parent_missing','foreign_repo','parent_active','task_missing','task_active','task_foreign','repo_missing']) ++@pytest.mark.parametrize("bound",h.FROZEN_CLUSTER_BINDINGS) ++def test_mixed_batch_refusal_precedes_all_writes(fault,bound): ++ repo,parent,tasks=closure(bound);ordinary=Obj(id=uuid.uuid4()) ++ if fault=='repo_missing':repo=None ++ if fault=='parent_missing':parent=None ++ if fault=='foreign_repo':parent.repo_id=uuid.uuid4() ++ if fault=='parent_active':parent.status='active' ++ if fault=='task_missing':tasks.pop() ++ if fault=='task_active':tasks[0].status='progress' ++ if fault=='task_foreign':tasks[0].workplan_id=uuid.uuid4() ++ if parent:parent.writes.clear() ++ for t in tasks:t.writes.clear() ++ normal=binding(workplan_id=ordinary.id,repo_slug='ordinary',filename='ordinary.md',relative_path='workplans/ordinary.md') ++ with pytest.raises(HTTPException):asyncio.run(run_api([normal,binding(_bound=bound)],repo,parent,tasks,ordinary)) ++ assert ordinary.writes==[] ++ if parent:assert parent.writes==[] ++ assert all(t.writes==[] for t in tasks) ++@pytest.mark.parametrize("bound",h.FROZEN_CLUSTER_BINDINGS) ++def test_exact_frozen_no_setters_or_commit(bound): ++ repo,parent,tasks=closure(bound);result,session=asyncio.run(run_api([binding(_bound=bound)],repo,parent,tasks)) ++ assert result==dict(updated=0,received=1,preserved=1);assert session.commits==0;assert parent.writes==[] ++ assert all(q.locked and q.refreshed and q.ordered for q in (session.queries[0],session.queries[2])) ++@pytest.mark.parametrize("bound",h.FROZEN_CLUSTER_BINDINGS) ++def test_mixed_valid_preserves_frozen_and_updates_ordinary(bound): ++ repo,parent,tasks=closure(bound);ordinary=Obj(id=uuid.uuid4()) ++ normal=binding(workplan_id=ordinary.id,repo_slug='ordinary',filename='ordinary.md',relative_path='workplans/ordinary.md') ++ result,session=asyncio.run(run_api([normal,binding(_bound=bound)],repo,parent,tasks,ordinary)) ++ assert result==dict(updated=1,received=2,preserved=1);assert session.commits==1;assert parent.writes==[] ++ assert ordinary.writes==['backing_filename','backing_relative_path','backing_archived','backing_synced_at'] ++@pytest.mark.parametrize('tamper',['metadata','bytes','symlink','missing_scan','missing_uuid','valid']) ++@pytest.mark.parametrize("bound_index", range(3)) ++def test_cli_exact_source_omission_or_whole_batch_refusal(tmp_path,tamper,bound_index): ++ bound=h.FROZEN_CLUSTER_BINDINGS[bound_index] ++ import shutil ++ infos=[] ++ for entry in h.FROZEN_CLUSTER_BINDINGS: ++ target=tmp_path/entry['path'];target.parent.mkdir(parents=True,exist_ok=True) ++ shutil.copyfile(Path('/home/worsch/railiance-cluster')/entry['path'],target) ++ infos.append((target,dict(state_hub_workstream_id=entry['uuid'],status='finished'),'')) ++ path=tmp_path/bound['path'] ++ meta=dict(state_hub_workstream_id=bound['uuid'],status='finished') ++ if tamper=='metadata':meta['status']='active' ++ if tamper=='missing_uuid':meta.pop('state_hub_workstream_id') ++ if tamper=='bytes':path.write_text(path.read_text()+'\n') ++ if tamper=='symlink':path.unlink();path.symlink_to(Path('/home/worsch/railiance-cluster')/bound['path']) ++ ordinary=tmp_path/'workplans/ordinary.md';ordinary.write_text('ordinary') ++ if tamper=='missing_scan':infos.pop(bound_index) ++ else:infos[bound_index]=(path,meta,'') ++ calls=[];report=actual_report() ++ fn=extracted('scripts/consistency_check.py','_sync_workplan_bindings',dict(FROZEN_CLUSTER_BINDINGS=h.FROZEN_CLUSTER_BINDINGS,frozen_cluster_binding=h.frozen_cluster_binding,normalise_workstream_status=lambda s:s,workplan_display_path=lambda root,p:p.relative_to(root).as_posix(),_api_put=lambda *a:calls.append(a) or dict(updated=1,received=1))) ++ fn('http://unused','railiance-cluster',[(ordinary,dict(state_hub_workstream_id=str(uuid.uuid4()),status='active'),''),*infos],tmp_path,report) ++ if tamper=='valid':assert len(calls)==1 and len(calls[0][2]['bindings'])==1 ++ else:assert calls==[] and report.failures[0].check_id=='C-44' and report.automation_errors ++ ++ ++def test_api_tampered_mixed_batch_refuses_before_queries_or_assignments(): ++ repo,parent,tasks=closure();ordinary=Obj(id=uuid.uuid4()) ++ with pytest.raises(HTTPException): ++ asyncio.run(run_api([binding(workplan_id=ordinary.id,repo_slug='ordinary',filename='ordinary.md',relative_path='workplans/ordinary.md'),binding(archived=False)],repo,parent,tasks,ordinary)) ++ assert ordinary.writes==[] and parent.writes==[] ++ ++ ++def test_foreign_repo_same_filename_path_is_ordinary(): ++ assert h.frozen_cluster_binding(binding(workplan_id=uuid.uuid4(),repo_slug='foreign')) is None ++ ++ ++@pytest.mark.parametrize('entry',h.FROZEN_CLUSTER_BINDINGS) ++def test_all_three_registry_bindings_are_guarded(entry): ++ good=dict(workplan_id=entry['uuid'],repo_slug=entry['repo'],filename=Path(entry['path']).name,relative_path=entry['path'],archived=True,status='finished') ++ assert h.frozen_cluster_binding(good) is entry ++ with pytest.raises(ValueError):h.frozen_cluster_binding(dict(good,status='active')) ++ ++ ++def test_real_cli_exit_criterion_is_nonzero_including_remote_all(): ++ report=actual_report();report.add(severity='FAIL',check_id='C-44',message='refused') ++ fn=extracted('scripts/consistency_check.py','consistency_exit_code',{}) ++ assert fn([report])==1 and fn([report],remote_all=True)==1 ++ ++ ++@pytest.mark.parametrize('check,key,protected_kind',[ ++ ('C-04','ws_id','parent'),('C-10','task_id','task'),('C-22','task_id','task'), ++ ('C-09','db_id','parent'),('C-23','wp_file','path'), ++]) ++@pytest.mark.parametrize('bound',h.FROZEN_CLUSTER_BINDINGS) ++def test_complete_fix_batch_preflight_before_ordinary_writes(check,key,protected_kind,bound): ++ report=actual_report();report.repo_path='/tmp/fixture-cluster' ++ report.add(severity='WARN',check_id='C-05',message='ordinary first',fixable=True,_fix_context={'ws_id':str(uuid.uuid4()),'field':'title','value':'ordinary'}) ++ value=bound['uuid'] if protected_kind=='parent' else bound['tasks'][0]['uuid'] if protected_kind=='task' else str(Path(report.repo_path)/bound['path']) ++ report.add(severity='WARN',check_id=check,message='protected later',fixable=True,db_id=value if key=='db_id' else '',_fix_context={key:value}) ++ guard=extracted('scripts/consistency_check.py','_refuse_frozen_fix_batch',dict(FROZEN_CLUSTER_BINDINGS=h.FROZEN_CLUSTER_BINDINGS)) ++ assert guard(report,'railiance-cluster') and report.automation_errors ++ calls=[] ++ fn=extracted('scripts/consistency_check.py','fix_repo',dict(check_repo=lambda *a,**kw:report,_refuse_frozen_fix_batch=guard,_api_post=lambda *a:calls.append(a),_api_patch=lambda *a:calls.append(a))) ++ assert fn('http://unused','railiance-cluster',None,False,False) is report and calls==[] ++ ++def test_unrelated_fix_context_not_refused(): ++ report=actual_report();report.add(severity='WARN',check_id='C-05',message='ordinary',fixable=True,_fix_context={'ws_id':str(uuid.uuid4())}) ++ guard=extracted('scripts/consistency_check.py','_refuse_frozen_fix_batch',dict(FROZEN_CLUSTER_BINDINGS=h.FROZEN_CLUSTER_BINDINGS)) ++ assert not guard(report,'other') ++ ++ ++def test_check_repo_guard_precedes_binding_sync_and_does_not_duplicate(): ++ tree=ast.parse((ROOT/'scripts/consistency_check.py').read_text()) ++ node=next(n for n in tree.body if isinstance(n,ast.FunctionDef) and n.name=='check_repo') ++ guard_lines=[n.lineno for n in ast.walk(node) if isinstance(n,ast.Call) and isinstance(n.func,ast.Name) and n.func.id=='_refuse_frozen_fix_batch'] ++ sync_lines=[n.lineno for n in ast.walk(node) if isinstance(n,ast.Call) and isinstance(n.func,ast.Name) and n.func.id=='_sync_workplan_bindings'] ++ assert len(guard_lines)==len(sync_lines)==1 and guard_lines[0] dict[str, int]: + """Upsert workstation workplan file bindings for remote API index fallback.""" ++ # Preflight the complete batch before assigning even an ordinary row. ++ try: ++ frozen = {entry.workplan_id: bound for entry in body.bindings ++ if (bound := frozen_cluster_binding(entry.model_dump())) is not None} ++ except ValueError as exc: ++ raise HTTPException(status_code=409, detail=str(exc)) from exc ++ requested_ids = {entry.workplan_id for entry in body.bindings} ++ rows = await session.execute( ++ select(Workplan).where(Workplan.id.in_(requested_ids)) ++ .order_by(Workplan.id).with_for_update().execution_options(populate_existing=True) ++ ) ++ workplans = {workplan.id: workplan for workplan in rows.scalars().all()} ++ if frozen: ++ repo_rows = await session.execute( ++ select(ManagedRepo).where(ManagedRepo.slug == "railiance-cluster") ++ ) ++ repo = repo_rows.scalar_one_or_none() ++ task_rows = await session.execute( ++ select(Task).where(Task.workplan_id.in_(frozen)) ++ .order_by(Task.id).with_for_update().execution_options(populate_existing=True) ++ ) ++ tasks = task_rows.scalars().all() ++ try: ++ for workplan_id, bound in frozen.items(): ++ validate_frozen_cluster_rows( ++ bound, workplans.get(workplan_id), tasks, repo.id if repo else None ++ ) ++ except ValueError as exc: ++ raise HTTPException(status_code=409, detail=str(exc)) from exc + synced_at = datetime.now(timezone.utc) + updated = 0 +- requested_ids = {entry.workplan_id for entry in body.bindings} +- rows = await session.execute(select(Workplan).where(Workplan.id.in_(requested_ids))) +- workplans = {workplan.id: workplan for workplan in rows.scalars().all()} ++ preserved = 0 + for entry in body.bindings: ++ if entry.workplan_id in frozen: ++ preserved += 1 ++ continue # No setters, including backing_synced_at/updated_at. + wp = workplans.get(entry.workplan_id) + if wp is None: + continue +@@ -449,9 +481,10 @@ + wp.backing_archived = entry.archived + wp.backing_synced_at = synced_at + updated += 1 +- await session.commit() +- _invalidate_workplan_index_cache() +- return {"updated": updated, "received": len(body.bindings)} ++ if updated: ++ await session.commit() ++ _invalidate_workplan_index_cache() ++ return {"updated": updated, "received": len(body.bindings), "preserved": preserved} + + + @router.post("/", status_code=status.HTTP_410_GONE) +--- a/scripts/consistency_check.py ++++ b/scripts/consistency_check.py +@@ -120,7 +120,9 @@ + resolve_topic_domain_slug, + ) + from api.services.lifecycle import should_activate_parent_for_active_tasks # noqa: E402 +-from api.services.historical_projection import BINDINGS as _HISTORICAL_BINDINGS # noqa: E402 ++from api.services.historical_projection import ( # noqa: E402 ++ BINDINGS as _HISTORICAL_BINDINGS, FROZEN_CLUSTER_BINDINGS, frozen_cluster_binding, ++) + from api.task_status import ( # noqa: E402 + CANONICAL_TASK_STATUSES, + OPEN_TASK_STATUSES, +@@ -318,7 +320,7 @@ + + # C-00 marks infrastructure/automation faults (API down, repo missing in DB). + # All other FAIL severities are assessment findings for follow-up. +-_AUTOMATION_ERROR_CHECKS: frozenset[str] = frozenset({"C-00"}) ++_AUTOMATION_ERROR_CHECKS: frozenset[str] = frozenset({"C-00", "C-44"}) + _NON_WORKPLAN_WORKPLAN_FILES: frozenset[str] = frozenset({"README.md"}) + + +@@ -2484,6 +2486,8 @@ + _check_workplan_id_collisions(api_base, repo_slug, repo_dir, workplan_infos, report) + _check_scope_freshness(repo_dir, workplan_infos, report) + ++ if _refuse_frozen_fix_batch(report, repo_slug): ++ return report + _sync_workplan_bindings(api_base, repo_slug, workplan_infos, repo_dir, report) + + return report +@@ -2496,23 +2500,44 @@ + repo_dir: Path, + report: ConsistencyReport, + ) -> None: ++ if repo_slug == "railiance-cluster": ++ scanned_paths = {workplan_display_path(repo_dir, path) for path, _, _ in workplan_infos} ++ missing = [entry["path"] for entry in FROZEN_CLUSTER_BINDINGS ++ if entry["path"] not in scanned_paths] ++ if missing: ++ report.add(severity="FAIL", check_id="C-44", ++ message="Frozen binding batch refused: bound source missing from scan", ++ fixable=False) ++ return + bindings: list[dict[str, Any]] = [] + for wp_file, meta, _ in workplan_infos: + ws_id = str(meta.get("state_hub_workstream_id", "")).strip().strip('"') ++ archived = wp_file.parent.name == "archived" ++ file_status = normalise_workstream_status(str(meta.get("status", "")).strip()) ++ binding = { ++ "workplan_id": ws_id, "filename": wp_file.name, ++ "relative_path": workplan_display_path(repo_dir, wp_file), ++ "repo_slug": repo_slug, "archived": archived, ++ "status": file_status or None, ++ } ++ try: ++ frozen = frozen_cluster_binding(binding) ++ if frozen is not None: ++ # Verify exact source before omitting the immutable binding. ++ # This is safe even against a receiver predating the API guard. ++ from hashlib import sha256 ++ if (wp_file.is_symlink() or not wp_file.is_file() ++ or sha256(wp_file.read_bytes()).hexdigest() != frozen["sha256"]): ++ raise ValueError("frozen historical source missing or changed") ++ continue ++ except ValueError as exc: ++ report.add(severity="FAIL", check_id="C-44", ++ message=f"Frozen binding batch refused: {exc}", ++ file_path=str(wp_file), fixable=False) ++ return # Never send a partial batch after a frozen-source refusal. + if not ws_id: + continue +- archived = wp_file.parent.name == "archived" +- file_status = normalise_workstream_status(str(meta.get("status", "")).strip()) +- bindings.append( +- { +- "workplan_id": ws_id, +- "filename": wp_file.name, +- "relative_path": workplan_display_path(repo_dir, wp_file), +- "repo_slug": repo_slug, +- "archived": archived, +- "status": file_status or None, +- } +- ) ++ bindings.append(binding) + if not bindings: + return + result = _api_put(api_base, "/workplans/index/bindings", {"bindings": bindings}) +@@ -3610,6 +3635,45 @@ + # Fix engine + # --------------------------------------------------------------------------- + ++def _refuse_frozen_fix_batch(report: ConsistencyReport, repo_slug: str) -> bool: ++ """Refuse a complete repair batch touching the exact bound histories.""" ++ if any(issue.check_id == "C-44" and issue.severity == "FAIL" for issue in report.issues): ++ return True ++ protected_ids = {entry["uuid"] for entry in FROZEN_CLUSTER_BINDINGS} ++ protected_ids.update(task["uuid"] for entry in FROZEN_CLUSTER_BINDINGS ++ for task in entry["tasks"]) ++ paths = {entry["path"] for entry in FROZEN_CLUSTER_BINDINGS} ++ root = Path(report.repo_path).absolute() if report.repo_path else None ++ ++ def protected(value, key=""): ++ if isinstance(value, dict): ++ return any(protected(item, name) for name, item in value.items()) ++ if isinstance(value, (list, tuple)): ++ return any(protected(item, key) for item in value) ++ text = str(value) ++ if key in {"db_id", "ws_id", "task_id", "from_workstream_id", ++ "from_workplan_id", "from_task_id", "desired_ws_id", ++ "desired_task_id", "desired_record_id", "state_hub_workstream_id", "state_hub_task_id"}: ++ if text in protected_ids: ++ return True ++ if key in {"file_path", "wp_file", "md_path", "path"} and text: ++ candidate = Path(text) ++ if candidate.is_absolute(): ++ return root is not None and any(candidate.absolute() == root / path for path in paths) ++ return repo_slug == "railiance-cluster" and candidate.as_posix() in paths ++ return False ++ ++ for issue in report.issues: ++ if issue.fixable and (protected(issue.db_id, "db_id") ++ or protected(issue.file_path, "file_path") ++ or protected(issue._fix_context)): ++ report.add(severity="FAIL", check_id="C-44", ++ message="Frozen historical repair batch refused; owner review required", ++ fixable=False) ++ return True ++ return False ++ ++ + def fix_repo( + api_base: str, + repo_slug: str, +@@ -3624,7 +3688,9 @@ + repo_path_override, + bootstrap_empty_projection=bootstrap_empty_projection, + ) +- if any(i.check_id in {"C-00", "C-36"} for i in report.failures): ++ if _refuse_frozen_fix_batch(report, repo_slug): ++ return report ++ if any(i.check_id in {"C-00", "C-36", "C-44"} for i in report.failures): + return report + + # RMGR-WP-0002: optional repo-manager reconcile proxy (index rebuild) for pilots +--- /dev/null ++++ b/tests/test_frozen_binding_guard_isolated.py +@@ -0,0 +1,200 @@ ++from pathlib import Path ++import ast, asyncio, importlib.util, types, uuid ++from dataclasses import dataclass, field ++from datetime import datetime, timezone ++import pytest ++ ++ROOT = Path(__file__).resolve().parents[1] ++spec=importlib.util.spec_from_file_location('historical',ROOT/'api/services/historical_projection.py') ++h=importlib.util.module_from_spec(spec);spec.loader.exec_module(h) ++B=h.FROZEN_CLUSTER_BINDINGS[0] ++def binding(_bound=B,**changes): ++ B=_bound ++ d=dict(workplan_id=uuid.UUID(B['uuid']),repo_slug=B['repo'],filename=Path(B['path']).name,relative_path=B['path'],archived=True,status='finished');d.update(changes);return d ++class Obj: ++ def __init__(self,**kw):self.__dict__.update(kw);self.writes=[] ++ def __setattr__(self,k,v): ++ if 'writes' in self.__dict__:self.writes.append(k) ++ object.__setattr__(self,k,v) ++class Entry(Obj): ++ def model_dump(self):return {k:v for k,v in self.__dict__.items() if k!='writes'} ++class Col: ++ def in_(self,x):return self ++ def __eq__(self,x):return self ++class Query: ++ def __init__(self):self.locked=False;self.refreshed=False;self.ordered=False ++ def where(self,*a):return self ++ def order_by(self,*a):self.ordered=True;return self ++ def with_for_update(self):self.locked=True;return self ++ def execution_options(self,**kw):self.refreshed=kw.get("populate_existing") is True;return self ++class Model: id=Col();slug=Col();workplan_id=Col() ++class Result: ++ def __init__(self,values):self.values=values ++ def scalars(self):return self ++ def all(self):return self.values ++ def scalar_one_or_none(self):return self.values[0] if self.values else None ++class Session: ++ def __init__(self,rows):self.results=iter(rows);self.commits=0;self.queries=[] ++ async def execute(self,q):self.queries.append(q);return Result(next(self.results)) ++ async def commit(self):self.commits+=1 ++class HTTPException(Exception): ++ def __init__(self,status_code,detail):self.status_code=status_code;super().__init__(detail) ++def extracted(path,name,extra): ++ tree=ast.parse((ROOT/path).read_text());node=next(n for n in tree.body if isinstance(n,(ast.FunctionDef,ast.AsyncFunctionDef)) and n.name==name) ++ node.decorator_list=[];node.returns=None ++ for a in node.args.args + node.args.kwonlyargs:a.annotation=None ++ node.args.defaults=[] ++ ns=dict(Path=Path,datetime=datetime,timezone=timezone,**extra) ++ exec(compile(ast.Module(body=[node],type_ignores=[]),str(path),'exec'),ns);return ns[name] ++def actual_report(): ++ tree=ast.parse((ROOT/'scripts/consistency_check.py').read_text()) ++ nodes=[n for n in tree.body if (isinstance(n,ast.ClassDef) and n.name in {'Issue','ConsistencyReport'}) or (isinstance(n,ast.AnnAssign) and isinstance(n.target,ast.Name) and n.target.id=='_AUTOMATION_ERROR_CHECKS')] ++ ns=dict(dataclass=dataclass,field=field,_AUTOMATION_ERROR_CHECKS=frozenset({'C-00','C-44'})) ++ exec(compile(ast.Module(body=nodes,type_ignores=[]),'actual_report','exec'),ns) ++ return ns['ConsistencyReport']('railiance-cluster','/unused') ++ ++def closure(B=B): ++ repo=Obj(id=uuid.uuid4());parent=Obj(id=uuid.UUID(B['uuid']),repo_id=repo.id,status='finished') ++ tasks=[Obj(id=uuid.UUID(t['uuid']),workplan_id=parent.id,status='done') for t in B['tasks']] ++ return repo,parent,tasks ++async def run_api(entries,repo,parent,tasks,ordinary=None): ++ rows=([parent] if parent else [])+([ordinary] if ordinary else []) ++ session=Session([rows,[repo] if repo else [],tasks]) ++ fn=extracted('api/routers/workstreams.py','sync_workplan_bindings',dict(frozen_cluster_binding=h.frozen_cluster_binding,validate_frozen_cluster_rows=h.validate_frozen_cluster_rows,HTTPException=HTTPException,select=lambda *_:Query(),Workplan=Model,Task=Model,ManagedRepo=Model,_invalidate_workplan_index_cache=lambda:None)) ++ result=await fn(Obj(bindings=[Entry(**e) for e in entries]),session) ++ return result,session ++@pytest.mark.parametrize('change',[dict(repo_slug='foreign'),dict(workplan_id=uuid.uuid4()),dict(relative_path='workplans/other.md'),dict(filename='other.md'),dict(archived=False),dict(status='active')]) ++def test_metadata_refuses(change): ++ with pytest.raises(ValueError):h.frozen_cluster_binding(binding(**change)) ++def test_unrelated_binding_unchanged():assert h.frozen_cluster_binding(binding(workplan_id=uuid.uuid4(),filename='ordinary.md',relative_path='workplans/ordinary.md',repo_slug='other')) is None ++@pytest.mark.parametrize('fault',['parent_missing','foreign_repo','parent_active','task_missing','task_active','task_foreign','repo_missing']) ++@pytest.mark.parametrize("bound",h.FROZEN_CLUSTER_BINDINGS) ++def test_mixed_batch_refusal_precedes_all_writes(fault,bound): ++ repo,parent,tasks=closure(bound);ordinary=Obj(id=uuid.uuid4()) ++ if fault=='repo_missing':repo=None ++ if fault=='parent_missing':parent=None ++ if fault=='foreign_repo':parent.repo_id=uuid.uuid4() ++ if fault=='parent_active':parent.status='active' ++ if fault=='task_missing':tasks.pop() ++ if fault=='task_active':tasks[0].status='progress' ++ if fault=='task_foreign':tasks[0].workplan_id=uuid.uuid4() ++ if parent:parent.writes.clear() ++ for t in tasks:t.writes.clear() ++ normal=binding(workplan_id=ordinary.id,repo_slug='ordinary',filename='ordinary.md',relative_path='workplans/ordinary.md') ++ with pytest.raises(HTTPException):asyncio.run(run_api([normal,binding(_bound=bound)],repo,parent,tasks,ordinary)) ++ assert ordinary.writes==[] ++ if parent:assert parent.writes==[] ++ assert all(t.writes==[] for t in tasks) ++@pytest.mark.parametrize("bound",h.FROZEN_CLUSTER_BINDINGS) ++def test_exact_frozen_no_setters_or_commit(bound): ++ repo,parent,tasks=closure(bound);result,session=asyncio.run(run_api([binding(_bound=bound)],repo,parent,tasks)) ++ assert result==dict(updated=0,received=1,preserved=1);assert session.commits==0;assert parent.writes==[] ++ assert all(q.locked and q.refreshed and q.ordered for q in (session.queries[0],session.queries[2])) ++@pytest.mark.parametrize("bound",h.FROZEN_CLUSTER_BINDINGS) ++def test_mixed_valid_preserves_frozen_and_updates_ordinary(bound): ++ repo,parent,tasks=closure(bound);ordinary=Obj(id=uuid.uuid4()) ++ normal=binding(workplan_id=ordinary.id,repo_slug='ordinary',filename='ordinary.md',relative_path='workplans/ordinary.md') ++ result,session=asyncio.run(run_api([normal,binding(_bound=bound)],repo,parent,tasks,ordinary)) ++ assert result==dict(updated=1,received=2,preserved=1);assert session.commits==1;assert parent.writes==[] ++ assert ordinary.writes==['backing_filename','backing_relative_path','backing_archived','backing_synced_at'] ++@pytest.mark.parametrize('tamper',['metadata','bytes','symlink','missing_scan','missing_uuid','valid']) ++@pytest.mark.parametrize("bound_index", range(3)) ++def test_cli_exact_source_omission_or_whole_batch_refusal(tmp_path,tamper,bound_index): ++ bound=h.FROZEN_CLUSTER_BINDINGS[bound_index] ++ import shutil ++ infos=[] ++ for entry in h.FROZEN_CLUSTER_BINDINGS: ++ target=tmp_path/entry['path'];target.parent.mkdir(parents=True,exist_ok=True) ++ shutil.copyfile(Path('/home/worsch/railiance-cluster')/entry['path'],target) ++ infos.append((target,dict(state_hub_workstream_id=entry['uuid'],status='finished'),'')) ++ path=tmp_path/bound['path'] ++ meta=dict(state_hub_workstream_id=bound['uuid'],status='finished') ++ if tamper=='metadata':meta['status']='active' ++ if tamper=='missing_uuid':meta.pop('state_hub_workstream_id') ++ if tamper=='bytes':path.write_text(path.read_text()+'\n') ++ if tamper=='symlink':path.unlink();path.symlink_to(Path('/home/worsch/railiance-cluster')/bound['path']) ++ ordinary=tmp_path/'workplans/ordinary.md';ordinary.write_text('ordinary') ++ if tamper=='missing_scan':infos.pop(bound_index) ++ else:infos[bound_index]=(path,meta,'') ++ calls=[];report=actual_report() ++ fn=extracted('scripts/consistency_check.py','_sync_workplan_bindings',dict(FROZEN_CLUSTER_BINDINGS=h.FROZEN_CLUSTER_BINDINGS,frozen_cluster_binding=h.frozen_cluster_binding,normalise_workstream_status=lambda s:s,workplan_display_path=lambda root,p:p.relative_to(root).as_posix(),_api_put=lambda *a:calls.append(a) or dict(updated=1,received=1))) ++ fn('http://unused','railiance-cluster',[(ordinary,dict(state_hub_workstream_id=str(uuid.uuid4()),status='active'),''),*infos],tmp_path,report) ++ if tamper=='valid':assert len(calls)==1 and len(calls[0][2]['bindings'])==1 ++ else:assert calls==[] and report.failures[0].check_id=='C-44' and report.automation_errors ++ ++ ++def test_api_tampered_mixed_batch_refuses_before_queries_or_assignments(): ++ repo,parent,tasks=closure();ordinary=Obj(id=uuid.uuid4()) ++ with pytest.raises(HTTPException): ++ asyncio.run(run_api([binding(workplan_id=ordinary.id,repo_slug='ordinary',filename='ordinary.md',relative_path='workplans/ordinary.md'),binding(archived=False)],repo,parent,tasks,ordinary)) ++ assert ordinary.writes==[] and parent.writes==[] ++ ++ ++def test_foreign_repo_same_filename_path_is_ordinary(): ++ assert h.frozen_cluster_binding(binding(workplan_id=uuid.uuid4(),repo_slug='foreign')) is None ++ ++ ++@pytest.mark.parametrize('entry',h.FROZEN_CLUSTER_BINDINGS) ++def test_all_three_registry_bindings_are_guarded(entry): ++ good=dict(workplan_id=entry['uuid'],repo_slug=entry['repo'],filename=Path(entry['path']).name,relative_path=entry['path'],archived=True,status='finished') ++ assert h.frozen_cluster_binding(good) is entry ++ with pytest.raises(ValueError):h.frozen_cluster_binding(dict(good,status='active')) ++ ++ ++def test_real_cli_exit_criterion_is_nonzero_including_remote_all(): ++ report=actual_report();report.add(severity='FAIL',check_id='C-44',message='refused') ++ fn=extracted('scripts/consistency_check.py','consistency_exit_code',{}) ++ assert fn([report])==1 and fn([report],remote_all=True)==1 ++ ++ ++@pytest.mark.parametrize('check,key,protected_kind',[ ++ ('C-04','ws_id','parent'),('C-10','task_id','task'),('C-22','task_id','task'), ++ ('C-09','db_id','parent'),('C-23','wp_file','path'), ++]) ++@pytest.mark.parametrize('bound',h.FROZEN_CLUSTER_BINDINGS) ++def test_complete_fix_batch_preflight_before_ordinary_writes(check,key,protected_kind,bound): ++ report=actual_report();report.repo_path='/tmp/fixture-cluster' ++ report.add(severity='WARN',check_id='C-05',message='ordinary first',fixable=True,_fix_context={'ws_id':str(uuid.uuid4()),'field':'title','value':'ordinary'}) ++ value=bound['uuid'] if protected_kind=='parent' else bound['tasks'][0]['uuid'] if protected_kind=='task' else str(Path(report.repo_path)/bound['path']) ++ report.add(severity='WARN',check_id=check,message='protected later',fixable=True,db_id=value if key=='db_id' else '',_fix_context={key:value}) ++ guard=extracted('scripts/consistency_check.py','_refuse_frozen_fix_batch',dict(FROZEN_CLUSTER_BINDINGS=h.FROZEN_CLUSTER_BINDINGS)) ++ assert guard(report,'railiance-cluster') and report.automation_errors ++ calls=[] ++ fn=extracted('scripts/consistency_check.py','fix_repo',dict(check_repo=lambda *a,**kw:report,_refuse_frozen_fix_batch=guard,_api_post=lambda *a:calls.append(a),_api_patch=lambda *a:calls.append(a))) ++ assert fn('http://unused','railiance-cluster',None,False,False) is report and calls==[] ++ ++def test_unrelated_fix_context_not_refused(): ++ report=actual_report();report.add(severity='WARN',check_id='C-05',message='ordinary',fixable=True,_fix_context={'ws_id':str(uuid.uuid4())}) ++ guard=extracted('scripts/consistency_check.py','_refuse_frozen_fix_batch',dict(FROZEN_CLUSTER_BINDINGS=h.FROZEN_CLUSTER_BINDINGS)) ++ assert not guard(report,'other') ++ ++ ++def test_check_repo_guard_precedes_binding_sync_and_does_not_duplicate(): ++ tree=ast.parse((ROOT/'scripts/consistency_check.py').read_text()) ++ node=next(n for n in tree.body if isinstance(n,ast.FunctionDef) and n.name=='check_repo') ++ guard_lines=[n.lineno for n in ast.walk(node) if isinstance(n,ast.Call) and isinstance(n.func,ast.Name) and n.func.id=='_refuse_frozen_fix_batch'] ++ sync_lines=[n.lineno for n in ast.walk(node) if isinstance(n,ast.Call) and isinstance(n.func,ast.Name) and n.func.id=='_sync_workplan_bindings'] ++ assert len(guard_lines)==len(sync_lines)==1 and guard_lines[0] -- /app/.venv/bin/python -c +, passing the payload bytes as stdin. No TTY, secret +argument, file credential or environment dump is needed. Keep any command error +stdout/stderr private and publish only the helper's fixed JSON receipt. Root +retains the real approved action/verification receipt; source compile is not +native proof. All helpers are compiled, not run against a live DB by this lane. diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/api-baseline-receipt.json b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/api-baseline-receipt.json new file mode 100644 index 00000000..112cb20a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/api-baseline-receipt.json @@ -0,0 +1,13 @@ +{ + "status": "private_api_baseline_captured", + "observed_at": "2026-10-16T23:55:07.822861+00:00", + "rows": { + "parents": 3, + "tasks": 15 + }, + "private_snapshot": "/tmp/state95-private-api-baseline-dkreewoe/baseline.json", + "snapshot_sha256": "sha256:8204a2095433feb777694bfef5b2beec512acaaadd5129501d8ca1f278838c6c", + "limitations": [ + "API fields only, not all DBcolumns. No schema migration or database mutation performed." + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/compare_snapshots.py b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/compare_snapshots.py new file mode 100644 index 00000000..c0965e5f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/compare_snapshots.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 +"""Compare sanitized full-row hash receipts only; never consumes row values.""" +import argparse,json +from pathlib import Path +ap=argparse.ArgumentParser();ap.add_argument('before');ap.add_argument('after');args=ap.parse_args() +a=json.loads(Path(args.before).read_text());b=json.loads(Path(args.after).read_text()) +assert a['status']==b['status']=='captured_readonly' +assert a['tables']['workplans']['row_count']==b['tables']['workplans']['row_count']==3 +assert a['tables']['tasks']['row_count']==b['tables']['tasks']['row_count']==15 +same=a['tables']==b['tables'] +expected='sha256:e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2' +result={'schema':'state95.historical-full-row-preservation.v1','status':'passed' if same and b['historical_module_sha256']==expected else 'refused_or_unverified','full_row_columns_uuids_hashes_equal':same,'delivered_historical_module_hash_matches':b['historical_module_sha256']==expected,'parent_count':3,'task_count':15,'raw_rows_retained':False} +print(json.dumps(result));raise SystemExit(result['status']!='passed') diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/manifest.json b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/manifest.json new file mode 100644 index 00000000..648f8ec5 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/manifest.json @@ -0,0 +1,32 @@ +{ + "schema": "state95.postdeployment-verifier-source.v1", + "status": "source_prepared_for_root_review_not_native_executed_by_subagent", + "approved_rollout_proposal_digest": "63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32", + "runtime_source": "51bc70d1ff8f25450a8650d8e50caf053093a02e", + "files": [ + { + "path": "snapshot_full_row_hashes.py", + "sha256": "sha256:f01e93c0fcb4ca155bdf76813626c33e4343f6a8caec2870ab1d785243c60479" + }, + { + "path": "native_rollback_refusal_probes.py", + "sha256": "sha256:839d90fd336fe56bbd73d101b0770e8eba3d7517a3953b8afd075feccdd0b94d" + }, + { + "path": "compare_snapshots.py", + "sha256": "sha256:fe38d1268a8c4bb54f0941f87a9aab5ee24410cc0197b082dbebe71bc94b0b78" + }, + { + "path": "README.md", + "sha256": "sha256:f432c3bcb29ee0715ef8e72d5ae806a800f07338cd9b5faea9d71c470c51d699" + }, + { + "path": "private-published-source-payload-receipt.json", + "sha256": "sha256:df2c438c455578d778b00363203b69aedd46e8bcdbdb3e0bd6650de6bde14bb9" + }, + { + "path": "api-baseline-receipt.json", + "sha256": "sha256:8f6da30c33482b552392d16584f704265750f3a0263fa6ec4f20f5175b7bd852" + } + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/native_rollback_refusal_probes.py b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/native_rollback_refusal_probes.py new file mode 100644 index 00000000..4c3d5418 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/native_rollback_refusal_probes.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +"""Root-reviewed in-pod native probes only; private source stdin, every DB effect rolled back.""" +import asyncio,base64,copy,hashlib,json,logging,sys,tempfile,uuid +from pathlib import Path +logging.disable(logging.CRITICAL) +BINDINGS=[{'repo': 'railiance-cluster', 'path': 'workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md', 'sha256': '8d6f8533c119117686bc0d5bb9ed5349726aa6c3189ff98b53409c68ac685ca9', 'record_id': 'RAIL-BS-WP-0002', 'uuid': '4c63dfc6-9eac-4e79-9f77-8f644ad7147d', 'parent_record_id': 'RAIL-BS-WP-0002', 'source_status': 'finished', 'tasks': [{'label': 'T01', 'uuid': '3f042630-eab0-4c6a-9167-e2b28ff20e40', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1'}, {'label': 'T02', 'uuid': 'e8510646-46ed-4697-a345-f3d3009eea78', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2'}, {'label': 'T03', 'uuid': 'dab2c07f-8aa0-4635-8df6-857e87e93fc5', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3'}, {'label': 'T04', 'uuid': '5c3d40e4-239b-488e-9519-6f7a38d2325f', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4'}, {'label': 'T05', 'uuid': '7f9e0e58-a130-467a-a2d0-b3f2564e496f', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5'}]}, {'repo': 'railiance-cluster', 'path': 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md', 'sha256': '4dc2f61e15adc3c5c81f9ecf8b933512275b95e8f829fac52ae7cde1385cea4a', 'record_id': 'RAIL-BS-WP-0003', 'uuid': '7ee9ee22-1fae-4567-9194-8d70a9e0f45b', 'parent_record_id': 'RAIL-BS-WP-0003', 'source_status': 'finished', 'tasks': [{'label': 'T01', 'uuid': '6841c93a-f146-47eb-9f7c-8fa0e02c1bbc', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1'}, {'label': 'T02', 'uuid': 'ab166073-30a7-4702-a037-4091e8706e20', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2'}, {'label': 'T03', 'uuid': '140da396-8e30-4f4d-b88c-c42c0cd46c01', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3'}, {'label': 'T04', 'uuid': 'd8a3ba40-fda0-4c1f-a9f1-ffcd621a5b3d', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4'}]}, {'repo': 'railiance-cluster', 'path': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md', 'sha256': '04f787078232395bd2d43861de16c521848559fa286f06e1caa9cb779aa71ac3', 'record_id': 'RAIL-BS-WP-0004', 'uuid': '7e8b0c20-51eb-40c9-9e3b-85dd380d7625', 'parent_record_id': 'RAIL-BS-WP-0004', 'source_status': 'finished', 'tasks': [{'label': 'T01', 'uuid': '4526a842-ea31-4874-9231-92ab556cfe7b', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1'}, {'label': 'T02', 'uuid': 'a6313e06-1976-46a7-8e31-df4eb2eca880', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2'}, {'label': 'T03', 'uuid': '05d42a55-921f-4aa7-bb76-e8af9c7e0ac3', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3'}, {'label': 'T04', 'uuid': '08233868-d522-4117-bc4e-6c0f52545665', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4'}, {'label': 'T05', 'uuid': '2d5acff7-4a4e-4ddd-ad06-08237ad3dac8', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5'}, {'label': 'T06', 'uuid': 'f8e4a094-c367-40eb-b895-da17bc144b07', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6'}]}] +PAYLOAD_SHA='82af93c3f8585f97fed63fafca2a6105caaeed8d52848ad628091663386fa949' +EXPECTED_HP='e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2' +EXPECTED_FP='b980e62cbd85c3e7df42b01abf14354e04133374db94af6531dcd91629c3487d' +def digest(value):return 'sha256:'+hashlib.sha256(json.dumps(value,sort_keys=True,separators=(',',':'),ensure_ascii=False).encode()).hexdigest() +async def main(): + from sqlalchemy import text + from api.database import async_session_factory,engine + from api.services import forge_projection as fp,historical_projection as hp + from api.models.workplan import Workplan + from api.models.task import Task + engine.echo=False + assert Workplan.__tablename__=='workplans' and Task.__tablename__=='tasks' + assert hashlib.sha256(Path(hp.__file__).read_bytes()).hexdigest()==EXPECTED_HP + assert hashlib.sha256(Path(fp.__file__).read_bytes()).hexdigest()==EXPECTED_FP + raw=sys.stdin.buffer.read(2097153);assert len(raw)<=2097152 and hashlib.sha256(raw).hexdigest()==PAYLOAD_SHA + payload=json.loads(raw);assert set(payload)=={'repo','revision','files'} and payload['repo']=='railiance-cluster' + parents=[e['uuid'] for e in BINDINGS];task_ids=[t['uuid'] for e in BINDINGS for t in e['tasks']] + async def snapshot(session): + result={} + for table,ids in [('workplans',parents),('tasks',task_ids)]: + values=(await session.execute(text('SELECT to_jsonb(row) FROM '+table+' AS row WHERE row.id=ANY(:ids) ORDER BY row.id'),{'ids':[uuid.UUID(v) for v in ids]})).scalars().all() + assert len(values)==len(ids) + result[table]=digest(values) + return result + with tempfile.TemporaryDirectory(prefix='state95-exact-published-source-') as temporary: + checkout=Path(temporary)/'railiance-cluster';checkout.mkdir(mode=0o700) + for name,value in payload['files'].items(): + path=Path(name);assert path.parts[0]=='workplans' and not path.is_absolute() and '..' not in path.parts and path.suffix=='.md' + target=checkout/path;target.parent.mkdir(parents=True,exist_ok=True);target.write_bytes(base64.b64decode(value,validate=True));target.chmod(0o600) + derived=fp.derive_from_checkout(checkout,'railiance-cluster',payload['revision']) + histories=[w for w in derived.workplans if w.historical_preservation] + assert len(histories)==3 and {w.uuid for w in histories}==set(parents) + result={'schema':'state95.native-rollback-refusal-probes.v1','status':'failed','source_revision':payload['revision'],'private_source_payload_sha256':'sha256:'+PAYLOAD_SHA,'module_hashes_verified':True,'commits_performed':0,'cases':{},'raw_rows_or_diagnostics_retained':False} + async with async_session_factory() as session: + try: + await session.execute(text("SET LOCAL statement_timeout='5s'")) + await session.execute(text("SET LOCAL lock_timeout='1s'")) + await session.execute(text("SET LOCAL idle_in_transaction_session_timeout='10s'")) + before=await snapshot(session);result['before_full_row_hashes']=before + for case in ('preserve','foreign-holder','nonterminal-task','nonterminal-parent','missing-task'): + nested=await session.begin_nested();row={'status':'unverified','rolled_back':False} + try: + session.expire_all() + if case=='foreign-holder':await session.execute(text('UPDATE tasks SET workplan_id=:parent WHERE id=:task'),{'parent':uuid.UUID(parents[1]),'task':uuid.UUID(task_ids[0])}) + elif case=='nonterminal-task':await session.execute(text("UPDATE tasks SET status='progress' WHERE id=:task"),{'task':uuid.UUID(task_ids[0])}) + elif case=='nonterminal-parent':await session.execute(text("UPDATE workplans SET status='active' WHERE id=:parent"),{'parent':uuid.UUID(parents[0])}) + elif case=='missing-task':await session.execute(text('DELETE FROM tasks WHERE id=:task'),{'task':uuid.UUID(task_ids[0])}) + outcome=await fp.reset_repository_projection(session,'railiance-cluster',derived=copy.deepcopy(derived)) + reasons={r.get('reason') for r in outcome.refused} + if case=='preserve': + await session.flush();row['full_historical_rows_equal']=await snapshot(session)==before + row['status']='passed' if outcome.status in {'noop','applied'} and not outcome.refused and row['full_historical_rows_equal'] else 'refused_or_unverified' + else: + row['historical_binding_refused']=outcome.status=='refused' and 'historical binding requires existing parent and task UUIDs' in reasons + row['status']='passed' if row['historical_binding_refused'] else 'wrong_or_unverified_refusal' + row['native_outcome_status']=outcome.status + except BaseException as error: + code=getattr(getattr(error,'orig',error),'sqlstate',None) + row={'status':'native_probe_error','sqlstate':code if isinstance(code,str) and len(code)==5 and code.isalnum() else None,'rolled_back':False} + finally: + await nested.rollback();session.expire_all();row['rolled_back']=True + row['full_historical_rows_restored']=await snapshot(session)==before + result['cases'][case]=row + result['after_full_row_hashes']=await snapshot(session) + finally:await session.rollback() + async with async_session_factory() as check: + try:result['fresh_transaction_full_rows_equal']=await snapshot(check)==before + finally:await check.rollback() + result['status']='passed' if all(v['status']=='passed' and v['rolled_back'] and v['full_historical_rows_restored'] for v in result['cases'].values()) and result['fresh_transaction_full_rows_equal'] else 'refused_or_unverified' + await engine.dispose();print(json.dumps(result,sort_keys=True)) +if __name__=='__main__': + try:asyncio.run(main()) + except BaseException:print(json.dumps({'schema':'state95.native-rollback-refusal-probes.v1','status':'refused_or_unverified','commits_performed':0,'raw_rows_or_diagnostics_retained':False}));raise SystemExit(1) diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/private-published-source-payload-receipt.json b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/private-published-source-payload-receipt.json new file mode 100644 index 00000000..b0a77ae9 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/private-published-source-payload-receipt.json @@ -0,0 +1,10 @@ +{ + "schema": "state95.source-probe-payload.v1", + "scope": "exact_current_git_HEAD_workplans_only_uncommitted_additions_excluded", + "revision": "cac8eabef5a0d0990a7b0de8f5e2c762666ac7f0", + "private_payload_path": "/tmp/state95-private-source-payload-frvylkw5/published-workplans.json", + "bytes": 155730, + "sha256": "sha256:82af93c3f8585f97fed63fafca2a6105caaeed8d52848ad628091663386fa949", + "file_count": 22, + "native_authority": false +} diff --git a/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/snapshot_full_row_hashes.py b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/snapshot_full_row_hashes.py new file mode 100644 index 00000000..28b8f3ce --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/snapshot_full_row_hashes.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +"""Run by approved owner inside API pod; SELECT-only, output full-row hashes only.""" +import asyncio +import hashlib +import json +import logging +from pathlib import Path +import uuid +logging.disable(logging.CRITICAL) +BINDINGS=[{'repo': 'railiance-cluster', 'path': 'workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md', 'sha256': '8d6f8533c119117686bc0d5bb9ed5349726aa6c3189ff98b53409c68ac685ca9', 'record_id': 'RAIL-BS-WP-0002', 'uuid': '4c63dfc6-9eac-4e79-9f77-8f644ad7147d', 'parent_record_id': 'RAIL-BS-WP-0002', 'source_status': 'finished', 'tasks': [{'label': 'T01', 'uuid': '3f042630-eab0-4c6a-9167-e2b28ff20e40', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1'}, {'label': 'T02', 'uuid': 'e8510646-46ed-4697-a345-f3d3009eea78', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2'}, {'label': 'T03', 'uuid': 'dab2c07f-8aa0-4635-8df6-857e87e93fc5', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3'}, {'label': 'T04', 'uuid': '5c3d40e4-239b-488e-9519-6f7a38d2325f', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4'}, {'label': 'T05', 'uuid': '7f9e0e58-a130-467a-a2d0-b3f2564e496f', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5'}]}, {'repo': 'railiance-cluster', 'path': 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md', 'sha256': '4dc2f61e15adc3c5c81f9ecf8b933512275b95e8f829fac52ae7cde1385cea4a', 'record_id': 'RAIL-BS-WP-0003', 'uuid': '7ee9ee22-1fae-4567-9194-8d70a9e0f45b', 'parent_record_id': 'RAIL-BS-WP-0003', 'source_status': 'finished', 'tasks': [{'label': 'T01', 'uuid': '6841c93a-f146-47eb-9f7c-8fa0e02c1bbc', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1'}, {'label': 'T02', 'uuid': 'ab166073-30a7-4702-a037-4091e8706e20', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2'}, {'label': 'T03', 'uuid': '140da396-8e30-4f4d-b88c-c42c0cd46c01', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3'}, {'label': 'T04', 'uuid': 'd8a3ba40-fda0-4c1f-a9f1-ffcd621a5b3d', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4'}]}, {'repo': 'railiance-cluster', 'path': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md', 'sha256': '04f787078232395bd2d43861de16c521848559fa286f06e1caa9cb779aa71ac3', 'record_id': 'RAIL-BS-WP-0004', 'uuid': '7e8b0c20-51eb-40c9-9e3b-85dd380d7625', 'parent_record_id': 'RAIL-BS-WP-0004', 'source_status': 'finished', 'tasks': [{'label': 'T01', 'uuid': '4526a842-ea31-4874-9231-92ab556cfe7b', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1'}, {'label': 'T02', 'uuid': 'a6313e06-1976-46a7-8e31-df4eb2eca880', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2'}, {'label': 'T03', 'uuid': '05d42a55-921f-4aa7-bb76-e8af9c7e0ac3', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3'}, {'label': 'T04', 'uuid': '08233868-d522-4117-bc4e-6c0f52545665', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4'}, {'label': 'T05', 'uuid': '2d5acff7-4a4e-4ddd-ad06-08237ad3dac8', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5'}, {'label': 'T06', 'uuid': 'f8e4a094-c367-40eb-b895-da17bc144b07', 'status': 'done', 'source': 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6'}]}] +def digest(value):return 'sha256:'+hashlib.sha256(json.dumps(value,sort_keys=True,separators=(',',':'),ensure_ascii=False).encode()).hexdigest() +async def main(): + from sqlalchemy import text + from api.database import async_session_factory,engine + from api.models.workplan import Workplan + from api.models.task import Task + engine.echo=False + assert Workplan.__tablename__=='workplans' and Task.__tablename__=='tasks' + parents=[entry['uuid'] for entry in BINDINGS] + tasks={task['uuid']:entry['uuid'] for entry in BINDINGS for task in entry['tasks']} + result={'schema':'state95.full-db-row-hash-snapshot.v1','status':'failed','credential_values_exposed':False,'raw_rows_retained':False} + async with async_session_factory() as session: + try: + await session.execute(text('SET TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ ONLY')) + rows={} + for table,identifiers in [('workplans',parents),('tasks',list(tasks))]: + query=text('SELECT to_jsonb(row) FROM '+table+' AS row WHERE row.id=ANY(:ids) ORDER BY row.id') + values=(await session.execute(query,{'ids':[uuid.UUID(v) for v in identifiers]})).scalars().all() + assert len(values)==len(identifiers) and {v['id'] for v in values}==set(identifiers) + if table=='tasks':assert all(v['workplan_id']==tasks[v['id']] for v in values) + assert all(v['status'] in {'done','cancel','finished','archived','completed'} for v in values) + rows[table]={'row_count':len(values),'columns':sorted(values[0]),'rows':[{'uuid':v['id'],'sha256':digest(v)} for v in values],'all_rows_sha256':digest(values)} + from api.services import historical_projection + result.update(status='captured_readonly',tables=rows,historical_module_sha256='sha256:'+hashlib.sha256(Path(historical_projection.__file__).read_bytes()).hexdigest()) + finally:await session.rollback() + await engine.dispose() + print(json.dumps(result,sort_keys=True)) +if __name__=='__main__': + try:asyncio.run(main()) + except BaseException:print(json.dumps({'schema':'state95.full-db-row-hash-snapshot.v1','status':'refused_or_unverified','raw_rows_retained':False}));raise SystemExit(1) diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/WP18.candidate.md b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/WP18.candidate.md new file mode 100644 index 00000000..f8ff4eb9 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/WP18.candidate.md @@ -0,0 +1,152 @@ +--- +id: RCLUSTER-WP-0018 +type: workplan +title: "Establish original KeyCape TLS recovery and future archive boundary" +domain: financials +repo: railiance-cluster +status: active +owner: codex +topic_slug: railiance +created: "2026-10-17" +updated: "2026-10-17" +flavor: implementation +depends_on: [] +related: [CUST-WP-0080, NK-WP-0049, RCLUSTER-WP-0007, RCLUSTER-WP-0017] +state_hub_workstream_id: "e0a7813d-c916-5e49-84b2-5e5b30441891" +--- + +Required owner source work for NK-WP-0049-T35 and CUST-WP-0080 G08. Reviewed +against current INTENT/SCOPE, backup sources and existing work records; ready +means work can proceed, not privileged execute authority. This does not promote +HA/backlog work, reopen archived local backup delivery or duplicate signer0017. +Source-owner scope is certificate plumbing/backup posture; NetKingdom owns +namespace ingress, while exact original independent TLS custody remains to be +established. No secret read, reissue, live change or native assent occurred. + +## Record source boundary and public-only metadata preparation + +```task +id: RCLUSTER-WP-0018-T01 +status: done +priority: high +assignee: codex +state_hub_task_id: "7280193d-0d59-5b78-a2d3-96ebd127127f" +``` + +Completed 2026-10-17 as isolated source preparation. Independently reviewed the +17 public source references against current owner bytes, checked current owner +instructions/environment/supervision and existing plans, and recorded the exact +boundary in docs/keycape-tls-recovery-boundary.md. Prepared bounded public-only +certificate/trust metadata projection with generated-certificate tests; no actual +certificate/key read. Source integration/publication and task projection remain +separate receipts, not claimed by this completed preparation task. + +Evidence: the-custodian docs/changes/netkingdom-target-2026-10-16/ +recovery-owner-handoffs-r1/ and prior recovery-attempt-r1/t35-t36-source-next/. + +Publication return, 2026-10-17: normal owner source publication at +c562d7134c38679952a8ffd17a8a893a900aef0d was applied on primary/railiance01 +with expected and derived commits equal. Read-only source/remote/Hub proof +verified this workplan's five exact task ID/UUID/status bindings and three +internal dependency edges. Receipts are retained in the Custodian packet +docs/changes/netkingdom-target-2026-10-17/railiance-cluster-projection.json and +cluster-publication-readback.json. The later legitimate C23 lifecycle repair +at 26671d33600e218316d29c9cd020f115ebfb35b2 changed ready to active; active +is retained. This return records publication separately from the completed +source preparation above. Original TLS artifact/provider custody, extraction +and native admission remain T02–T05 obligations; publication proves no TLS +recovery, private-key custody or native acceptance. + +The whole maintenance pipeline's historical-row guard failed for three parent +rows while 15 task full-row hashes remained unchanged. STATE-WP-0095-T07 and +RMGR-WP-0019-T06 remain wait; neither publication nor this memo asserts full +historical-row preservation or restoration. The subsequent forward correction +restores the brief's committed content to its pre-accident version while restoring +the original staged/worktree change for its owner; history is not rewound. No legacy deep consistency fix is run by the correction. + +## Establish exact independent original TLS artifact and provider custody metadata + +```task +id: RCLUSTER-WP-0018-T02 +status: todo +priority: high +assignee: codex +state_hub_task_id: "90836435-917f-504c-a711-3f29ece348e3" +``` + +Next: identify the actual original sso/kc-tls custody owner and independent public +provenance through existing owner processes. Record artifact/provider, timestamp, +public certificate/trust hashes, private custody entry point and outage dependencies +without values. Source review cannot infer a fresh backup, original key coverage +or independent decryption custody from a local backup script. Use credential +routing before any later credential need; missing route is not proof of absence. +Done when exact independent recovery or an explicitly owned unavailable capability +is evidenced as metadata and a reviewed next action, with no guessed assent. + +## Prepare safe isolated original extraction or explicit reissue alternative + +```task +id: RCLUSTER-WP-0018-T03 +status: wait +priority: high +assignee: codex +depends_on: [RCLUSTER-WP-0018-T02] +blocking_reason: "Exact original artifact/provider/custody disposition is required before selecting extraction or reissue source." +state_hub_task_id: "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a" +``` + +From T02, reuse the actual owner path to prepare an exact attended private-only +recovery command and full dependency/cleanup proof. Do not run whole-state restore +or expose raw state/Secret output. If existing backup staging is required, correct +only the needed path with bounded memory-only staging and early exact cleanup, +including error/parent-loss tests before use. Original recovery and accepted +reissue are distinct claims; no self-signed trust substitute, new broker or +implicit production action. Done when the exact source proposal, public metadata +preflight, negatives, timeout, abort and custody obligations are reviewed. + +## Verify admitted original TLS recovery through the actual owner boundary + +```task +id: RCLUSTER-WP-0018-T04 +status: wait +priority: high +assignee: codex +needs_human: true +depends_on: [RCLUSTER-WP-0018-T02, RCLUSTER-WP-0018-T03] +blocking_reason: "Await exact reviewed attended owner custody path and its existing scoped authority; no private input or native attempt requested yet." +state_hub_task_id: "021b07bb-65bc-5743-bac5-4294b4be74f6" +``` + +Only the actual admitted owner action can prove recovered certificate/key pairing, +original hostname/trust and independent outage operation, or the expressly accepted +reissue result. Retain exact source/artifact/target/identity/negative/cleanup receipts. +Human custody/authority gates are not worker wakeups. Source and historical local +backup proof never fill native assent. Return bounded public proof to NK49T35; +no production mutation, credential retrieval or approval is granted by this task. + +## Disposition original TLS coverage in the future identity archive contract + +```task +id: RCLUSTER-WP-0018-T05 +status: todo +priority: high +assignee: codex +state_hub_task_id: "5bc67a22-0991-5625-86a6-f749560d8a0e" +``` + +Next: deliver the source-owned requirement in docs/keycape-tls-recovery-boundary.md +to NetKingdom's existing contract process: original TLS custody or accepted reissue, +independent provider/key recovery, public identity hashes, scoped capture/read +permissions and verification/retention. Record named owner dependencies as live +work before closure. Do not append kc-tls to secret_refs, expand capture credentials +or rewrite a historical archive without those owner reviews/authority. Done when +the future contract requirement has an exact tracked disposition/handoff; it is +not proof of current archive coverage or actual future capture. + +## Coordination and completion + +Beneficiary NK-WP-0049-T35/CUST-WP-0080 remains linked to this obligor record by +derived cross_owner_wait case nk49-t35-rcluster18 in the packet. No new project +driver, live worker injection or message was created. Own T03 wait has an explicit +local prerequisite; T04 is a human gate. Close only after source/native obligations +are proved or an explicit bounded scope disposition hands off remaining live work. diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/WP18.preimage.md b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/WP18.preimage.md new file mode 100644 index 00000000..78f73196 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/WP18.preimage.md @@ -0,0 +1,132 @@ +--- +id: RCLUSTER-WP-0018 +type: workplan +title: "Establish original KeyCape TLS recovery and future archive boundary" +domain: financials +repo: railiance-cluster +status: active +owner: codex +topic_slug: railiance +created: "2026-10-17" +updated: "2026-10-17" +flavor: implementation +depends_on: [] +related: [CUST-WP-0080, NK-WP-0049, RCLUSTER-WP-0007, RCLUSTER-WP-0017] +state_hub_workstream_id: "e0a7813d-c916-5e49-84b2-5e5b30441891" +--- + +Required owner source work for NK-WP-0049-T35 and CUST-WP-0080 G08. Reviewed +against current INTENT/SCOPE, backup sources and existing work records; ready +means work can proceed, not privileged execute authority. This does not promote +HA/backlog work, reopen archived local backup delivery or duplicate signer0017. +Source-owner scope is certificate plumbing/backup posture; NetKingdom owns +namespace ingress, while exact original independent TLS custody remains to be +established. No secret read, reissue, live change or native assent occurred. + +## Record source boundary and public-only metadata preparation + +```task +id: RCLUSTER-WP-0018-T01 +status: done +priority: high +assignee: codex +state_hub_task_id: "7280193d-0d59-5b78-a2d3-96ebd127127f" +``` + +Completed 2026-10-17 as isolated source preparation. Independently reviewed the +17 public source references against current owner bytes, checked current owner +instructions/environment/supervision and existing plans, and recorded the exact +boundary in docs/keycape-tls-recovery-boundary.md. Prepared bounded public-only +certificate/trust metadata projection with generated-certificate tests; no actual +certificate/key read. Source integration/publication and task projection remain +separate receipts, not claimed by this completed preparation task. + +Evidence: the-custodian docs/changes/netkingdom-target-2026-10-16/ +recovery-owner-handoffs-r1/ and prior recovery-attempt-r1/t35-t36-source-next/. + +## Establish exact independent original TLS artifact and provider custody metadata + +```task +id: RCLUSTER-WP-0018-T02 +status: todo +priority: high +assignee: codex +state_hub_task_id: "90836435-917f-504c-a711-3f29ece348e3" +``` + +Next: identify the actual original sso/kc-tls custody owner and independent public +provenance through existing owner processes. Record artifact/provider, timestamp, +public certificate/trust hashes, private custody entry point and outage dependencies +without values. Source review cannot infer a fresh backup, original key coverage +or independent decryption custody from a local backup script. Use credential +routing before any later credential need; missing route is not proof of absence. +Done when exact independent recovery or an explicitly owned unavailable capability +is evidenced as metadata and a reviewed next action, with no guessed assent. + +## Prepare safe isolated original extraction or explicit reissue alternative + +```task +id: RCLUSTER-WP-0018-T03 +status: wait +priority: high +assignee: codex +depends_on: [RCLUSTER-WP-0018-T02] +blocking_reason: "Exact original artifact/provider/custody disposition is required before selecting extraction or reissue source." +state_hub_task_id: "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a" +``` + +From T02, reuse the actual owner path to prepare an exact attended private-only +recovery command and full dependency/cleanup proof. Do not run whole-state restore +or expose raw state/Secret output. If existing backup staging is required, correct +only the needed path with bounded memory-only staging and early exact cleanup, +including error/parent-loss tests before use. Original recovery and accepted +reissue are distinct claims; no self-signed trust substitute, new broker or +implicit production action. Done when the exact source proposal, public metadata +preflight, negatives, timeout, abort and custody obligations are reviewed. + +## Verify admitted original TLS recovery through the actual owner boundary + +```task +id: RCLUSTER-WP-0018-T04 +status: wait +priority: high +assignee: codex +needs_human: true +depends_on: [RCLUSTER-WP-0018-T02, RCLUSTER-WP-0018-T03] +blocking_reason: "Await exact reviewed attended owner custody path and its existing scoped authority; no private input or native attempt requested yet." +state_hub_task_id: "021b07bb-65bc-5743-bac5-4294b4be74f6" +``` + +Only the actual admitted owner action can prove recovered certificate/key pairing, +original hostname/trust and independent outage operation, or the expressly accepted +reissue result. Retain exact source/artifact/target/identity/negative/cleanup receipts. +Human custody/authority gates are not worker wakeups. Source and historical local +backup proof never fill native assent. Return bounded public proof to NK49T35; +no production mutation, credential retrieval or approval is granted by this task. + +## Disposition original TLS coverage in the future identity archive contract + +```task +id: RCLUSTER-WP-0018-T05 +status: todo +priority: high +assignee: codex +state_hub_task_id: "5bc67a22-0991-5625-86a6-f749560d8a0e" +``` + +Next: deliver the source-owned requirement in docs/keycape-tls-recovery-boundary.md +to NetKingdom's existing contract process: original TLS custody or accepted reissue, +independent provider/key recovery, public identity hashes, scoped capture/read +permissions and verification/retention. Record named owner dependencies as live +work before closure. Do not append kc-tls to secret_refs, expand capture credentials +or rewrite a historical archive without those owner reviews/authority. Done when +the future contract requirement has an exact tracked disposition/handoff; it is +not proof of current archive coverage or actual future capture. + +## Coordination and completion + +Beneficiary NK-WP-0049-T35/CUST-WP-0080 remains linked to this obligor record by +derived cross_owner_wait case nk49-t35-rcluster18 in the packet. No new project +driver, live worker injection or message was created. Own T03 wait has an explicit +local prerequisite; T04 is a human gate. Close only after source/native obligations +are proved or an explicit bounded scope disposition hands off remaining live work. diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/apply_forward_correction.py b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/apply_forward_correction.py new file mode 100644 index 00000000..6c994e66 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/apply_forward_correction.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +"""Reviewed forward-only two-path commit; retain original brief/index/worktree dirt.""" +from pathlib import Path +import argparse,hashlib,json,subprocess +P=Path(__file__).resolve().parent +R=Path('/home/worsch/railiance-cluster') +B=P.parent/'railiance-cluster-publication-backup' +M=json.loads((P/'manifest.json').read_text()) +def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest() +def git(*args): + r=subprocess.run(['git','-C',str(R),*args],capture_output=True,timeout=180) + if r.returncode:raise RuntimeError(json.dumps({'args':args,'exit':r.returncode,'stdout':r.stdout.decode(errors='replace'),'stderr':r.stderr.decode(errors='replace')})) + return r.stdout +parser=argparse.ArgumentParser();parser.add_argument('--execute',action='store_true');a=parser.parse_args() +assert git('rev-parse','HEAD').decode().strip()==M['base'] +for name,h in M['files'].items():assert sha(P/name)==h +for name,h in M['original_backup_sha256'].items():assert sha(B/name)==h +originals=json.loads((B/'originals.json').read_text()) +for name,index in originals.items(): + assert (R/name).read_bytes()==(B/(name+'.worktree')).read_bytes() + assert git('ls-files','--stage','--',name).decode()==index +wp,brief=M['paths'];assert (R/wp).read_bytes()==(P/'WP18.preimage.md').read_bytes() +assert git('show',M['restore_brief_from_commit']+':'+brief)==(P/'brief.forward-restore.md').read_bytes() +assert git('diff','--cached','--name-only')==b'' +before_index=git('ls-files','--stage').decode().splitlines() +frozen={str(p.relative_to(R)):sha(p) for p in (R/'workplans/archived').glob('260622-RAIL-BS-WP-000[234]-*.md')};assert len(frozen)==3 +assert sha(R/'WORK-RECORDS.md')==M['original_backup_sha256']['WORK-RECORDS.md.worktree'] +git('apply','--check',str(P/'forward-correction.patch')) +if not a.execute:print(json.dumps({'status':'checked-ready','paths':M['paths'],'original_brief_and_work_records_preserved':True}));raise SystemExit(0) +(P/'execution-start.json').write_text(json.dumps({'status':'started','base':M['base'],'index_entries':before_index,'frozen_sha256':frozen},indent=2)+'\n') +commit_output='';error=None +try: + git('apply',str(P/'forward-correction.patch')) + # --only feeds exactly the two reviewed worktree versions to normal hooks. + commit_output=git('commit','--only','-m','Record Cluster publication and restore unrelated staged brief','--',*M['paths']).decode() +finally: + # The owner's original brief index/worktree is reinstated even if a hook refuses. + (R/brief).write_bytes((B/(brief+'.worktree')).read_bytes()) + mode,oid,stagepath=originals[brief].split(' ',2) + assert stagepath=='0\t'+brief+'\n' + git('update-index','--cacheinfo',mode,oid,brief) + for name,index in originals.items(): + assert (R/name).read_bytes()==(B/(name+'.worktree')).read_bytes() + assert git('ls-files','--stage','--',name).decode()==index +head=git('rev-parse','HEAD').decode().strip();assert head!=M['base'] +assert set(git('diff-tree','--no-commit-id','--name-only','-r',head).decode().splitlines())==set(M['paths']) +assert git('show','HEAD:'+brief)==(P/'brief.forward-restore.md').read_bytes() +assert git('show','HEAD:'+wp)==(P/'WP18.candidate.md').read_bytes() +# Every unrelated stage entry is identical, including user's exact brief entry. +without_wp=lambda entries:[line for line in entries if line.split('\t',1)[1]!=wp] +assert without_wp(git('ls-files','--stage').decode().splitlines())==without_wp(before_index) +assert {path:sha(R/path) for path in frozen}==frozen +receipt={'status':'committed-forward-correction','head':head,'parent':M['base'],'paths':M['paths'],'commit_output':commit_output,'head_brief_equals_c562':True,'original_brief_index_and_worktree_restored':True,'all_other_index_entries_identical':True,'work_records_index_and_dirty_worktree_preserved':True,'three_archives_unchanged':True,'wp18_status':'active','task_blocks_and_UUIDs_unchanged':True,'legacy_deepfix':False,'history_rewrite':False,'native_TLS_acceptance':False,'all18historical_preservation_claim':False,'status_porcelain':git('status','--porcelain').decode()} +(P/'forward-correction-commit.json').write_text(json.dumps(receipt,indent=2)+'\n');print(json.dumps(receipt,indent=2)) diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/brief.committed-preimage.md b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/brief.committed-preimage.md new file mode 100644 index 00000000..86c0e6c7 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/brief.committed-preimage.md @@ -0,0 +1,33 @@ + +# Custodian Brief — railiance-cluster + +**Domain:** financials +**Last synced:** 2026-10-16 19:05 UTC +**State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)* + +## Current Goal + +Install k3s and Kubernetes Baseline on the HostEurope Server + +## Active Workstreams + +### Review NetKingdom signer runtime and node-local storage readiness +Progress: 1/3 done | workplan_id: `f383557d-c8a8-553e-adcd-9f82ff9c2929` + +**Open tasks:** +- ► Review the bounded native preflight and storage action `7f4320c6` +- · Verify the approved runtime and storage result `747a8d77` + +## Inbox Hygiene + +**Stale unread:** 6 message(s) older than 3 day(s) — triage at session start. +**Missing thread_id:** 8 unread message(s) lack supersession chains. +- ! the-custodian: Workplan 'three-phoenix-ha-cluster' is blocked with no wait task `a1368d99` + +--- +## MCP Orientation (when available) + +If the state-hub MCP server is reachable, call: +`get_domain_summary("financials")` +This provides richer cross-domain context. +If the MCP call fails, use this file as your orientation source. diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/brief.forward-restore.md b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/brief.forward-restore.md new file mode 100644 index 00000000..70010a1a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/brief.forward-restore.md @@ -0,0 +1,28 @@ + +# Custodian Brief — railiance-cluster + +**Domain:** financials +**Last synced:** 2026-10-13 18:24 UTC +**State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)* + +## Current Goal + +Install k3s and Kubernetes Baseline on the HostEurope Server + +## Active Workstreams + +*(none — repo may need first-session setup)* + +## Inbox Hygiene + +**Stale unread:** 6 message(s) older than 3 day(s) — triage at session start. +**Missing thread_id:** 6 unread message(s) lack supersession chains. +- ! the-custodian: Workplan 'three-phoenix-ha-cluster' is blocked with no wait task `a1368d99` + +--- +## MCP Orientation (when available) + +If the state-hub MCP server is reachable, call: +`get_domain_summary("financials")` +This provides richer cross-domain context. +If the MCP call fails, use this file as your orientation source. diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/execution-plan.json b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/execution-plan.json new file mode 100644 index 00000000..1842fa0f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/execution-plan.json @@ -0,0 +1,29 @@ +{ + "status": "review-required-before-execution", + "helper_sha256": "02b028822e07cc1612a2e5dea3c9f271f0020f9adfb656c0aac42555b0805502", + "patch_sha256": "a50c419c4ab3a35a6f953559546c88fe0cfb75605ef63b51fe30307180262610", + "manifest_sha256": "9ac8f5e43f84add61ec8560be78e4d10e55bdd2918467581f367e816a4592385", + "check_only_result": "passed at26671d33600e218316d29c9cd020f115ebfb35b2", + "execute_command": [ + "python3", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/apply_forward_correction.py", + "--execute" + ], + "then_required_publication": [ + "/home/worsch/repo-manager/.venv/bin/rmgr", + "sync", + "--path", + "/home/worsch/railiance-cluster", + "--push" + ], + "postconditions": [ + "new forward commit exactly two paths, parent266", + "HEAD brief bytes equal c562; original86c0brief indexentry and originalbackupworktree retained", + "original WORK-RECORDS.md indexentry and dirtyworktree unchanged", + "all other indexentries unchanged except intentional WP18", + "source/remote HEAD identical and primary/railiance01 expected=derived applied receipt", + "WP18 active and exact5taskIDs/UUIDs/status3internaledges readback", + "no legacydeepfix or full18rowrestoration/nativeTLSclaim" + ], + "canonical_mutations": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/execution-start.json b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/execution-start.json new file mode 100644 index 00000000..cbd74345 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/execution-start.json @@ -0,0 +1,148 @@ +{ + "status": "started", + "base": "26671d33600e218316d29c9cd020f115ebfb35b2", + "index_entries": [ + "100644 0e8a5d95b6d263fbaeae4261a7051112fb27ee18 0\t.claude/rules/agents.md", + "100644 7c2a64580a2fb55d6586e154ee70d801430faa3e 0\t.claude/rules/architecture.md", + "100644 64b84033daa3eea88ed07993a62bf0d35abd5705 0\t.claude/rules/credential-routing.md", + "100644 3b263fc0085c9cbcdc9de1dce015b5af67937875 0\t.claude/rules/first-session.md", + "100644 2f85f27000175e115dc6210ce3f87b5d1eefdb21 0\t.claude/rules/repo-boundary.md", + "100644 60c065fa1af76a3234ab5a156cda98612f67f14c 0\t.claude/rules/repo-identity.md", + "100644 a26f834124d5c9e7cdc77842b5b46f1923f0d6c3 0\t.claude/rules/session-protocol.md", + "100644 ee026b2fbbcf7f920ca21b7ad4209c5d2009ef44 0\t.claude/rules/stack-and-commands.md", + "100644 7d08acc433f44cbe649a66ae2c0c312dfb588cdd 0\t.claude/rules/workplan-convention.md", + "100644 86c0e6c7306f54aebda9b59c7e3b72e4ab3e75ba 0\t.custodian-brief.md", + "100644 95847006236387ab1a6a17f40b9efb0445d56547 0\t.editorconfig", + "100644 bd44c56a4f8a6c12bdab40257e450c2a676f751a 0\t.forgejo/workflows/ci-smoke.yaml", + "100644 e3975118068d1760ad2915fa15dd74cc1ef16d21 0\t.gitattributes", + "100644 bfd3dd9e1dffd45197045b9ef7b8dc7bb8dd9534 0\t.github/workflows/tests.yml", + "100644 57cf4d7e3e5e362da4e55b276b562871f36a39d2 0\t.gitignore", + "100644 34833e54fc69369cfeef8cbca71f2a416032d027 0\t.repo-classification.yaml", + "100644 18185bcf111aa96fc9204e04a9acb9f90eecda88 0\t.sops.yaml", + "100644 895538687b80cfdd1dacdd9c410bb675a24f480d 0\tAGENTS.md", + "100644 84f1c45d5992562844466d519011c04946f464eb 0\tCLAUDE.md", + "100644 31ab8b7d44ac38ddceae11094b1a67de6c515649 0\tDECISIONS.md", + "100644 03774676ce916c5b4abc897e17cfd0b38b82ff3c 0\tINTENT.md", + "100644 7e08e28d5f32bdea3a9e1c828ae9f1e21d9edae7 0\tLICENSE", + "100644 c958ede876b319ac9c9a254c1534f86c37009673 0\tMakefile", + "100644 d75037495f97c0d5c43ae94e0afab77c57315d10 0\tQUICKSTART.md", + "100644 c0012eae79f18baaf11a966c3c5c9f3c627f90b2 0\tREADME.md", + "100644 d4b3ea41d327292b492cafa3c6241c32b0b7ebee 0\tSCOPE.md", + "100644 ffbf8bc5fdd53b659ef84e6468dd1d43d745a8bf 0\tWORK-RECORDS.md", + "100644 66667e3d177459af1d44ecc0fd3f1dc56b774450 0\tansible/ansible.cfg", + "100644 7e4719f07dc5d27bfcaa41ad1e8ab328e64024db 0\tansible/bootstrap.yml", + "100644 e4bb7f5d25c74e545d66a550fc636a824226491c 0\tansible/harden.yml", + "100644 da2e3994cdce71d181f361401f125b087ae8b676 0\tansible/hosts.ini.example", + "100644 4e52fd4bbadc00b14e566ea003270b8fa37e79ad 0\tansible/requirements.yml", + "100755 28499688ae41aa60e946bf5b262d401bd55903e7 0\tbin/railiance", + "100644 5261f8886d61c50f4f531a2900a12d0025f73021 0\tcloudinit/user-data.yaml", + "100644 2ca9e9a23dae7f1334002109d6bd3253a34f980f 0\tdocs/CONTRIBUTING.md", + "100644 bc5cda9c1391119aab14b8224d6851aa1546ee9e 0\tdocs/OODA.md", + "100644 0da1fb472a503162151920b4faf58a8851950385 0\tdocs/README.md", + "100644 cbd2d280777a35123a52fae508d6ac095c7cef0c 0\tdocs/app-toml-contract.md", + "100644 5a3f5d96bf2a0b97c143d29c3e0495c94b517640 0\tdocs/backup-restore.md", + "100644 54d4ce16a98292c378af6f89b2bc051b6ff655cb 0\tdocs/canary-helm-template.md", + "100644 800ccefc95212fe5512a51a5e73c9ade0096fcdb 0\tdocs/cluster-resource-evidence.md", + "100644 2dcdf5d96cab063c8bce952f83bff235e700d8bf 0\tdocs/deployment-lifecycle.md", + "100644 28e9604f496b73001fdcdbc4ef1db0b4bdc059b1 0\tdocs/evidence/2026-10-13-publication-diagnosis.json", + "100644 97af3b44c8a4fd65835d72797a35287e46ff7e00 0\tdocs/evidence/2026-10-13-publication-timeout-rollout.json", + "100644 91157a54602517987dbee52dcbd8b4a991b624f5 0\tdocs/evidence/2026-10-13-publication-upload-timings.json", + "100644 69ce806c009c1846c650dc9858110818a07277a6 0\tdocs/evidence/2026-10-13-published-image-pull.json", + "100644 2a82cc9488046edb48213e3665290730d2c6d1bf 0\tdocs/evidence/resource-reef-railiance-k3s/observations/20260822T100349Z.json", + "100644 2a82cc9488046edb48213e3665290730d2c6d1bf 0\tdocs/evidence/resource-reef-railiance-k3s/observations/latest.json", + "100644 8caed08a5d292ca335df7dd2194c5824c1eba792 0\tdocs/first_host.md", + "100644 ad03fad9a435e82d2b95497b44c6d6d6f213df7f 0\tdocs/incidents/2026-03-10-pgpool-missing-secret.md", + "100644 40953976dd249c53fa650d670822216abd07e71c 0\tdocs/keycape-tls-recovery-boundary.md", + "100644 d74014ffa05a656d02356c350948bd7bc6b1f8da 0\tdocs/kubeconfig.md", + "100644 88ef13d70a4006c3adaf0e8acb85c6a131fdc967 0\tdocs/operator-runbook.md", + "100644 ce2e68dd9f76bada355862d08656bef167cfba33 0\tdocs/overlay-repo-pattern.md", + "100644 99ced4683e494209919507cbe633944752f4b0dd 0\tdocs/promote-rollback-onboarding.md", + "100644 7973760dcfd6b5995fb4075778ce5b1f6ebbac9b 0\tdocs/rail-kubernetes-compatibility-shim.md", + "100644 8034f074198be24650bb32cf2b9cf698814bc13f 0\tdocs/rail-kubernetes-extraction-map.md", + "100644 c2c4ca68d39d7da3d19df878600620586239a45f 0\tdocs/rail-kubernetes-substrate-profile.md", + "100644 7390e2a751969b07aa05895e0f5c66077eb28a15 0\tdocs/railiance-run-command.md", + "100644 b6e315b8274adc3caf8d6829ce89f925f9b8bf3a 0\tdocs/stage2-deploy-observe.md", + "100644 dbba0a87e2193472e0e0263665524eb57d334442 0\tdocs/threephoenix-implementation-gate.md", + "100644 d97f37b871efcced405ff0404b5ccce444c88dc8 0\texamples/railiance/app.toml", + "100644 84f399494219054e6c740a1365199f6c4a0d26f2 0\thelm/MOVED.md", + "100644 ca9ccf397fd401bd8a5355d94c66bd4825872f81 0\thelm/gitea-ssh-nodeport.yaml", + "100644 87f4228e1b12449e0cfe8f0257c442e0a1166e3b 0\tinstall/knative/README.md", + "100755 0d6797ce819172a8825d2b866c4a1895203fabc9 0\tinstall/knative/install.sh", + "100644 9245114e677f4f558a89b4af7d4abf023c638709 0\tinstall/knative/overlays/kourier/cpu-requests.patch.yaml", + "100644 4a5501c87b8c0731dbdc15161a6a8f536644b7c8 0\tinstall/knative/overlays/kourier/kustomization.yaml", + "100644 cdac368756da136ffd7d01efe57257f02505a1cf 0\tinstall/knative/overlays/kourier/service-clusterip.patch.yaml", + "100644 8676ab8c8d33a46b4465dd5f971448cc9463b56c 0\tinstall/knative/overlays/serving-core/cpu-requests.patch.yaml", + "100644 6e1be69e25ff00a22f2e50d40c946bc3d982a08b 0\tinstall/knative/overlays/serving-core/kustomization.yaml", + "100644 03cd8fa5a0bbcf1b8db77ab12e4c12d34702ca33 0\tinstall/knative/release-lock.env", + "100755 5e5fd2339f8a26048b13b441097195cb9a55e389 0\tinstall/knative/render.sh", + "100755 49b07865173f1653faf3b420548b8f417a65d504 0\tinstall/knative/verify.sh", + "100644 92232a6dbed33d5926c1732632e55b76272a97a9 0\tinstall/traefik/README.md", + "100644 ada1efe8a4e55b4dff31879c47b0172957e90729 0\tinstall/traefik/railiance01-helmchartconfig.yaml", + "100644 22a977bcb726ad6f9137492331b81f4f8cb2525a 0\tlib/railiance-print.sh", + "100644 687943e1d9115a182de136f6137f6b7911ee2226 0\tpyproject.toml", + "100644 569abe99c95e163d39048f4b02ccb47165751c7e 0\tregistry/README.md", + "100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0\tregistry/capabilities/.gitkeep", + "100644 6b7a5c0633b4a71f201f52c8ebe1e7923f12ac6e 0\tregistry/capabilities/capability.railiance.cluster-bootstrap.md", + "100644 a6161da4395f626569955ef486b981a5cc000853 0\tregistry/indexes/capabilities.yaml", + "100644 21cde4335115ab3071bdc258f5c51a271f92435c 0\tsbom-tools.yaml", + "100644 2ff92a5e869a7c4fee6854f920031731c2ca16f3 0\tschemas/railiance-app.schema.json", + "100644 cd841cad4977c04743955ffee339e7c16a772bbc 0\ttests/smoke_kube.sh", + "100644 aab9ea62a0d4cd139b8cae6b865b3ccb9d6f40df 0\ttests/test_cluster_resources.py", + "100755 add5bbd4b685750021bf01c40ee505ef13ae23c1 0\ttests/test_ha_failover.sh", + "100644 fc295bd80c263c30d99e5547db3fec090db7f78d 0\ttests/test_knative_render.py", + "100644 53b323ec2a5df12a2d61ffbc21b15e1b5e19c9ca 0\ttests/test_public_tls_metadata.py", + "100644 512082e7c84971ef8f51e14a1fded03787757892 0\ttools/README_tools.md", + "100644 9a09669cef3d69d6197faaacb29adbbc61a1b821 0\ttools/build_spore.sh", + "100755 6ebb8be44fe0d54ca69774f26aa604f825c3c2df 0\ttools/cmd/railiance-admin-sync-smoke", + "100755 f7b124bb7cec773441053092c9aa6fa7c22b1ba5 0\ttools/cmd/railiance-backup", + "100755 79fe69ed1e8d8a1c192a2b45bca198c82300c447 0\ttools/cmd/railiance-backup-s2", + "100755 1ef60715ff7abafb2c3cb31d6c9418a516ad7c4b 0\ttools/cmd/railiance-deploy-activity-core-triage-robustness", + "100644 6720eed5e96ebe789f165ed84146d690df5615ef 0\ttools/cmd/railiance-doctor", + "100755 4413b89d57126cfdfc6eb26507181e136b0dc0cb 0\ttools/cmd/railiance-plan-host", + "100755 323e6d1205cb4ed2255ce99a09aa8a65ee32522a 0\ttools/cmd/railiance-preflight", + "100755 0742f2e5b9cdba161875e86ed8310686fc14b499 0\ttools/cmd/railiance-reconcile-activity-core-llm-connect", + "100755 0aa3eb4910886b101bf259c2011250aa023c3ca3 0\ttools/cmd/railiance-restore-s2", + "100755 45c15d93fef3bba542fd95d28c392891330ca027 0\ttools/cmd/railiance-run", + "100755 2961eb8cf6081dc73bca167f09a38f0576528333 0\ttools/cmd/railiance-stage2", + "100755 0aa76e8ca0ca5b46397cddde1879908c3d564d0b 0\ttools/cmd/railiance-stage3", + "100755 5d26e13a3d6b6454cbdef6a09be7048f9846a767 0\ttools/cmd/railiance-verify-activity-core", + "100755 8a44e308bd4a14303eca09fa5e97f1767351902c 0\ttools/create_railiance_overlay_repo.sh", + "100644 83680c80c1afc01ad9ed81f60dd0fcaffede863e 0\ttools/create_railiance_repo.sh", + "100644 df5734ab3b12da40d0e748be27f465852bca5046 0\ttools/furnish_railiance_repo.sh", + "100755 d32abaa70bacbb9ca6446958e6c021a6315231d4 0\ttools/knative-preflight.sh", + "100755 08e5a33490db582444d92945e54f5f2f901adccc 0\ttools/observe_cluster_resources.py", + "100644 b3d429f318a0531fdb9769a75ea6f88c8a2ef84c 0\ttools/public-tls-metadata.py", + "100644 a486165db61a8303e0388bd20d29f08e666687e7 0\ttools/seed_node.sh", + "100644 c25ac23649217e15db35f184e87e07cad1c61891 0\tuv.lock", + "100644 1430ac54fc1bfb099e84cc48cf755714bce77541 0\twiki/RailianceThreePhoenix.md", + "100644 db2b87c5f12d5ca3c60cfa180f098e552a0c4f0d 0\twiki/ThreePhoenixWorkplan.md", + "100644 30a71bcd36f7660a1e9c17baec245f112249a4f5 0\tworkplans/ADHOC-2026-07-27.md", + "100644 43139e0843d52926b963310bf7aacc731e9da073 0\tworkplans/RAIL-BS-WP-0008-activity-core-wp0016-triage-output-deploy.md", + "100644 ea669bd74c15e6ec7ddae8d4ada22981b522561c 0\tworkplans/RAIL-BS-WP-0009-activity-core-admin-sync-smoke.md", + "100644 20270d80de60eddbbadba56e672f15ee71fb067d 0\tworkplans/RAIL-BS-WP-0010-weekly-legacy-meter-review-rollout.md", + "100644 e5526e441cd41dd31f5a969c8d2c5c6d4fad6f7e 0\tworkplans/RAIL-BS-WP-0011-legacy-meter-8h-capture-image-reconcile.md", + "100644 ae22dfb2b9fe831227784dd461bcf78bf2cd11de 0\tworkplans/RAIL-BS-WP-0012-rail-kubernetes-extraction.md", + "100644 525ce5d6caea8929ebc5233bf2053342db3f44b8 0\tworkplans/RAIL-BS-WP-0013-knative-substrate.md", + "100644 868aa948f8fa0d65c1f6fb0587ceb493d991c068 0\tworkplans/RAIL-BS-WP-0014-state-hub-surge-headroom.md", + "100644 6954393976731375ed1570f0c92edbe03892aeb5 0\tworkplans/RAIL-BS-WP-0015-knative-declared-cpu-requests.md", + "100644 555ae300fd36e7db282c51bca21a42217f01af7e 0\tworkplans/RCLUSTER-WP-0007-threephoenix-ha-cluster.md", + "100644 f205ac6cb1a0def27715edeb8f9f741f77693f62 0\tworkplans/RCLUSTER-WP-0014-capacity-utilization-and-allocation-evidence.md", + "100644 b2f385967cde17a870a96b6447a1ec3c40213da5 0\tworkplans/RCLUSTER-WP-0016-forgejo-upload-timeout.md", + "100644 bf474d1fc329f4fd547382e32d156fad4bf1fde6 0\tworkplans/RCLUSTER-WP-0017-netkingdom-signer-runtime-storage-review.md", + "100644 78f7319674238fe8afd9f540db48651837f041d3 0\tworkplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md", + "100644 375d935626d073011f52b8c5929a770b0c5655e1 0\tworkplans/archived/260622-RAIL-BS-WP-0001-dependency-management.md", + "100644 595cd5c19fa88faae24c5ae784d210194af36d61 0\tworkplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md", + "100644 fe7b21da629dd86942be36db4e6fc7e5920f8bc6 0\tworkplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md", + "100644 89d14fff27277d467c896611bb3b26324fef5f4b 0\tworkplans/archived/260622-RAIL-BS-WP-0004-safety-net.md", + "100644 28bf1d4e58420a6d1fab7b44c57b98f0a20ac9e4 0\tworkplans/archived/260622-RAIL-BS-WP-0005-kubeconfig-delivery.md", + "100644 2cf33b46fbae45bba67ec257259a61df4fc3f878 0\tworkplans/archived/260622-RCLUSTER-WP-0001-activity-core-cluster-owned-deploy-verify.md", + "100644 d7e2374c72813c2e3d8bbfc9b9a85bba1af02938 0\tworkplans/archived/260622-RCLUSTER-WP-0002-activity-core-verifier-evidence-hardening.md", + "100644 7f258e7c9b2da1f99fb7e115cd75157e1376ef0a 0\tworkplans/archived/260627-RAIL-BS-WP-0006-staged-promotion-lifecycle.md", + "100644 0944b98107bb5ed99884ef359106bfcf330707e1 0\tworkplans/archived/260701-RCLUSTER-WP-0003-activity-core-llm-connect-live-reconcile.md" + ], + "frozen_sha256": { + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md": "4dc2f61e15adc3c5c81f9ecf8b933512275b95e8f829fac52ae7cde1385cea4a", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md": "04f787078232395bd2d43861de16c521848559fa286f06e1caa9cb779aa71ac3", + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md": "8d6f8533c119117686bc0d5bb9ed5349726aa6c3189ff98b53409c68ac685ca9" + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-commit.json b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-commit.json new file mode 100644 index 00000000..6d8d3152 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-commit.json @@ -0,0 +1,22 @@ +{ + "status": "committed-forward-correction", + "head": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "parent": "26671d33600e218316d29c9cd020f115ebfb35b2", + "paths": [ + "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md", + ".custodian-brief.md" + ], + "commit_output": "[main 6ae3f84] Record Cluster publication and restore unrelated staged brief\n 2 files changed, 23 insertions(+), 8 deletions(-)\n", + "head_brief_equals_c562": true, + "original_brief_index_and_worktree_restored": true, + "all_other_index_entries_identical": true, + "work_records_index_and_dirty_worktree_preserved": true, + "three_archives_unchanged": true, + "wp18_status": "active", + "task_blocks_and_UUIDs_unchanged": true, + "legacy_deepfix": false, + "history_rewrite": false, + "native_TLS_acceptance": false, + "all18historical_preservation_claim": false, + "status_porcelain": "M .custodian-brief.md\n M WORK-RECORDS.md\n" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-publication-readback.json b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-publication-readback.json new file mode 100644 index 00000000..a630e9e3 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-publication-readback.json @@ -0,0 +1,77 @@ +{ + "status": "verified", + "scope": "Cluster WP18 owner publication; read-only Git remote and Hub snapshots", + "writes_to_source_index_refs_or_Hub": false, + "rows": [ + { + "repo": "railiance-cluster", + "published_commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "remote": { + "HEAD": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "refs/heads/main": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "symbolic_HEAD": "refs/heads/main" + }, + "workplan": { + "id": "e0a7813d-c916-5e49-84b2-5e5b30441891", + "slug": "rcluster-wp-0018", + "status": "active" + }, + "source_record_id": "RCLUSTER-WP-0018", + "tasks": [ + { + "id": "7280193d-0d59-5b78-a2d3-96ebd127127f", + "record_id": "RCLUSTER-WP-0018-T01", + "status": "done" + }, + { + "id": "90836435-917f-504c-a711-3f29ece348e3", + "record_id": "RCLUSTER-WP-0018-T02", + "status": "todo" + }, + { + "id": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a", + "record_id": "RCLUSTER-WP-0018-T03", + "status": "wait" + }, + { + "id": "021b07bb-65bc-5743-bac5-4294b4be74f6", + "record_id": "RCLUSTER-WP-0018-T04", + "status": "wait" + }, + { + "id": "5bc67a22-0991-5625-86a6-f749560d8a0e", + "record_id": "RCLUSTER-WP-0018-T05", + "status": "todo" + } + ], + "external_source_declarations_not_projected": [], + "dependencies": [ + { + "from_task_id": "021b07bb-65bc-5743-bac5-4294b4be74f6", + "to_task_id": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a", + "relationship_type": "starts_after" + }, + { + "from_task_id": "021b07bb-65bc-5743-bac5-4294b4be74f6", + "to_task_id": "90836435-917f-504c-a711-3f29ece348e3", + "relationship_type": "starts_after" + }, + { + "from_task_id": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a", + "to_task_id": "90836435-917f-504c-a711-3f29ece348e3", + "relationship_type": "starts_after" + } + ], + "source_file_sha256": "96d52b6dbae056399159632d50b32ccc6662e4f6d3677af154f7c8a3d618334b", + "source_file_unchanged": true, + "dependency_scope": "internal edges verified; external source target identities checked without claiming projected external edges", + "index_stat_unchanged": true + } + ], + "hub_instance": { + "status": "ok", + "instance_role": "primary", + "instance_label": "railiance01" + }, + "verifier_sha256": "ccf1776a2a8b3de5b1cc75f90ba4c10fbf8ade1b79fa4ba721be1c908be11d7d" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-sync.json b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-sync.json new file mode 100644 index 00000000..76e49c56 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-sync.json @@ -0,0 +1,246 @@ +{ + "ok": true, + "status": "applied", + "repo_slug": "railiance-cluster", + "commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "requests": 2, + "elapsed_ms": 6624.2, + "git": { + "upstream": "origin/main", + "behind": 0, + "ahead": 0 + }, + "identifiers": { + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": true, + "repo": "railiance-cluster", + "namespace": "helixforge", + "assignments": [], + "historical_invalid_identifiers": [ + { + "kind": "task", + "id": "T01", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1" + }, + { + "kind": "task", + "id": "T02", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2" + }, + { + "kind": "task", + "id": "T03", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3" + }, + { + "kind": "task", + "id": "T04", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4" + }, + { + "kind": "task", + "id": "T05", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5" + }, + { + "kind": "task", + "id": "T01", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1" + }, + { + "kind": "task", + "id": "T02", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2" + }, + { + "kind": "task", + "id": "T03", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3" + }, + { + "kind": "task", + "id": "T04", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4" + }, + { + "kind": "task", + "id": "T01", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1" + }, + { + "kind": "task", + "id": "T02", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2" + }, + { + "kind": "task", + "id": "T03", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3" + }, + { + "kind": "task", + "id": "T04", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4" + }, + { + "kind": "task", + "id": "T05", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5" + }, + { + "kind": "task", + "id": "T06", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6" + } + ], + "historical_identity_collisions": [ + { + "kind": "task", + "id": "T01", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "3f042630-eab0-4c6a-9167-e2b28ff20e40", + "4526a842-ea31-4874-9231-92ab556cfe7b", + "6841c93a-f146-47eb-9f7c-8fa0e02c1bbc" + ] + }, + { + "kind": "task", + "id": "T02", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "a6313e06-1976-46a7-8e31-df4eb2eca880", + "ab166073-30a7-4702-a037-4091e8706e20", + "e8510646-46ed-4697-a345-f3d3009eea78" + ] + }, + { + "kind": "task", + "id": "T03", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "05d42a55-921f-4aa7-bb76-e8af9c7e0ac3", + "140da396-8e30-4f4d-b88c-c42c0cd46c01", + "dab2c07f-8aa0-4635-8df6-857e87e93fc5" + ] + }, + { + "kind": "task", + "id": "T04", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "08233868-d522-4117-bc4e-6c0f52545665", + "5c3d40e4-239b-488e-9519-6f7a38d2325f", + "d8a3ba40-fda0-4c1f-a9f1-ffcd621a5b3d" + ] + }, + { + "kind": "task", + "id": "T05", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "2d5acff7-4a4e-4ddd-ad06-08237ad3dac8", + "7f9e0e58-a130-467a-a2d0-b3f2564e496f" + ] + } + ], + "files_changed": [] + }, + "receipt": { + "schema": "state-hub.repository-projection-reconcile.v1", + "instance_role": "primary", + "instance_label": "railiance01", + "expected_commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "derived_commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "outcome": { + "schema": "state-hub.projection-reset.v1", + "repo_slug": "railiance-cluster", + "commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "status": "applied", + "counts": { + "created": 0, + "updated": 20, + "retired": 0, + "refused": 0, + "released": 0, + "created_tasks": 0, + "updated_tasks": 1, + "cancelled_tasks": 0, + "created_edges": 0, + "removed_edges": 0, + "unresolved_edges": 0, + "external_edges": 0 + }, + "created": [], + "updated": [ + "RAIL-BS-WP-0001", + "RAIL-BS-WP-0005", + "RAIL-BS-WP-0006", + "RAIL-BS-WP-0008", + "RAIL-BS-WP-0009", + "RAIL-BS-WP-0010", + "RAIL-BS-WP-0011", + "RAIL-BS-WP-0012", + "RAIL-BS-WP-0013", + "RAIL-BS-WP-0014", + "RAIL-BS-WP-0015", + "RCLUSTER-WP-0001", + "RCLUSTER-WP-0002", + "RCLUSTER-WP-0003", + "RCLUSTER-WP-0007", + "RCLUSTER-WP-0014", + "RCLUSTER-WP-0016", + "RCLUSTER-WP-0017", + "RCLUSTER-WP-0018", + "RCLUSTER-WP-ADHOC-2026-07-27" + ], + "retired": [], + "released": [], + "created_tasks": [], + "updated_tasks": [ + "RCLUSTER-WP-0018-T01" + ], + "cancelled_tasks": [], + "created_edges": [], + "removed_edges": [], + "unresolved_edges": [], + "external_edges": [], + "refused": [], + "notes": [ + "Preserved bound historical row and task UUIDs: RAIL-BS-WP-0002", + "Preserved bound historical row and task UUIDs: RAIL-BS-WP-0003", + "Preserved bound historical row and task UUIDs: RAIL-BS-WP-0004" + ] + } + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction.patch b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction.patch new file mode 100644 index 00000000..2dc76d89 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction.patch @@ -0,0 +1,60 @@ +--- a/workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md ++++ b/workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md +@@ -43,6 +43,26 @@ + + Evidence: the-custodian docs/changes/netkingdom-target-2026-10-16/ + recovery-owner-handoffs-r1/ and prior recovery-attempt-r1/t35-t36-source-next/. ++ ++Publication return, 2026-10-17: normal owner source publication at ++c562d7134c38679952a8ffd17a8a893a900aef0d was applied on primary/railiance01 ++with expected and derived commits equal. Read-only source/remote/Hub proof ++verified this workplan's five exact task ID/UUID/status bindings and three ++internal dependency edges. Receipts are retained in the Custodian packet ++docs/changes/netkingdom-target-2026-10-17/railiance-cluster-projection.json and ++cluster-publication-readback.json. The later legitimate C23 lifecycle repair ++at 26671d33600e218316d29c9cd020f115ebfb35b2 changed ready to active; active ++is retained. This return records publication separately from the completed ++source preparation above. Original TLS artifact/provider custody, extraction ++and native admission remain T02–T05 obligations; publication proves no TLS ++recovery, private-key custody or native acceptance. ++ ++The whole maintenance pipeline's historical-row guard failed for three parent ++rows while 15 task full-row hashes remained unchanged. STATE-WP-0095-T07 and ++RMGR-WP-0019-T06 remain wait; neither publication nor this memo asserts full ++historical-row preservation or restoration. The subsequent forward correction ++restores the brief's committed content to its pre-accident version while restoring ++the original staged/worktree change for its owner; history is not rewound. No legacy deep consistency fix is run by the correction. + + ## Establish exact independent original TLS artifact and provider custody metadata + +--- a/.custodian-brief.md ++++ b/.custodian-brief.md +@@ -2,7 +2,7 @@ + # Custodian Brief — railiance-cluster + + **Domain:** financials +-**Last synced:** 2026-10-16 19:05 UTC ++**Last synced:** 2026-10-13 18:24 UTC + **State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)* + + ## Current Goal +@@ -11,17 +11,12 @@ + + ## Active Workstreams + +-### Review NetKingdom signer runtime and node-local storage readiness +-Progress: 1/3 done | workplan_id: `f383557d-c8a8-553e-adcd-9f82ff9c2929` +- +-**Open tasks:** +-- ► Review the bounded native preflight and storage action `7f4320c6` +-- · Verify the approved runtime and storage result `747a8d77` ++*(none — repo may need first-session setup)* + + ## Inbox Hygiene + + **Stale unread:** 6 message(s) older than 3 day(s) — triage at session start. +-**Missing thread_id:** 8 unread message(s) lack supersession chains. ++**Missing thread_id:** 6 unread message(s) lack supersession chains. + - ! the-custodian: Workplan 'three-phoenix-ha-cluster' is blocked with no wait task `a1368d99` + + --- diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/manifest.json b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/manifest.json new file mode 100644 index 00000000..26137d7b --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/manifest.json @@ -0,0 +1,28 @@ +{ + "status": "prepared-not-applied", + "base": "26671d33600e218316d29c9cd020f115ebfb35b2", + "restore_brief_from_commit": "c562d7134c38679952a8ffd17a8a893a900aef0d", + "paths": [ + "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md", + ".custodian-brief.md" + ], + "files": { + "WP18.preimage.md": "ec6213ddedd82a872f727ba030268d253ffbc8363e56df8b0f85c8d2168f1a49", + "WP18.candidate.md": "96d52b6dbae056399159632d50b32ccc6662e4f6d3677af154f7c8a3d618334b", + "brief.committed-preimage.md": "973c36a552854aa801708aecf45f80d07ce2215dfc7bfa58e1ab8c9e78b2de67", + "brief.forward-restore.md": "ce9a06a6e85437781f090615d989b82cb1fa2e8c509ed0dd99b6dc28152128b5", + "forward-correction.patch": "a50c419c4ab3a35a6f953559546c88fe0cfb75605ef63b51fe30307180262610" + }, + "original_backup": "../railiance-cluster-publication-backup", + "original_backup_sha256": { + "originals.json": "009ec3ff5b3e4556ec06a363e6b4e43c6d58d97796258b4a06974932fd3ca1d2", + ".custodian-brief.md.worktree": "973c36a552854aa801708aecf45f80d07ce2215dfc7bfa58e1ab8c9e78b2de67", + "WORK-RECORDS.md.worktree": "37bc7e5d2c28f62776189db3d89b5d238931a683d8b05ddae39c8f42f9778cce" + }, + "brief_original_index_entry": "100644 86c0e6c7306f54aebda9b59c7e3b72e4ab3e75ba 0\t.custodian-brief.md\n", + "workplan_task_blocks_UUIDs_and_statuses_unchanged": true, + "workplan_status_retained": "active", + "legacy_deepfix": false, + "history_rewrite": false, + "all18preservation_claim": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/publication-final-manifest.json b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/publication-final-manifest.json new file mode 100644 index 00000000..9fa356b5 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/publication-final-manifest.json @@ -0,0 +1,30 @@ +{ + "status": "forward-correction-published-verified", + "head": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "parent": "26671d33600e218316d29c9cd020f115ebfb35b2", + "paths": [ + "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md", + ".custodian-brief.md" + ], + "HEAD_brief_restored_to_c562": true, + "original_brief_staged_entry_and_worktree_exact": true, + "staged_brief_change_visible_again": true, + "original_WORK_RECORDS_dirty_worktree_and_index_exact": true, + "three_archive_hashes_unchanged": true, + "normal_fast_sync_applied_primary": true, + "five_task_three_edge_active_readback_verified": true, + "history_rewrite": false, + "legacy_deepfix": false, + "all18historical_preservation_or_restoration_claim": false, + "native_TLS_acceptance": false, + "files": { + "manifest.json": "9ac8f5e43f84add61ec8560be78e4d10e55bdd2918467581f367e816a4592385", + "execution-plan.json": "c374c9299bf30b5a746955e7ab3f883d76350a4eb0823f26ff5abccab1d5e69c", + "apply_forward_correction.py": "02b028822e07cc1612a2e5dea3c9f271f0020f9adfb656c0aac42555b0805502", + "forward-correction.patch": "a50c419c4ab3a35a6f953559546c88fe0cfb75605ef63b51fe30307180262610", + "forward-correction-commit.json": "d93f1d84b052b786332bc2238301cecf9d68f5a73d5ddc1376f25c859a765ed8", + "forward-correction-sync.json": "e022e5f8b92d154babe76de39dbc799d4cb04d4349f8642ed69f8587de18cb58", + "verify_forward_publication.py": "ccf1776a2a8b3de5b1cc75f90ba4c10fbf8ade1b79fa4ba721be1c908be11d7d", + "forward-correction-publication-readback.json": "cd1903b634511da269d19dd6d367482933ce06a175f8392db82b5655bd1b1de0" + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/verify_forward_publication.py b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/verify_forward_publication.py new file mode 100644 index 00000000..274418cf --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/verify_forward_publication.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 +"""Read-only Git+Hub task binding verifier; never syncs or changes source/index.""" +import hashlib +import json +import os +from pathlib import Path +import re +import subprocess +import urllib.request + +HERE=Path(__file__).resolve().parent +OWNERS=[{'repo':'railiance-cluster','commit':'6ae3f847c83da3402883453ee7110457bfb2d0d6','path':'workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md','id':'RCLUSTER-WP-0018','tasks':5}] +API=os.environ.get('API_BASE','http://127.0.0.1:8000').rstrip('/') +EXTERNAL={'STATE-WP-0095-T03':'e8566341-cf6e-5b9c-ad80-8564d14cd52a','STATE-WP-0095-T06':'6af973b4-1964-5d4d-a2f8-8dbd4c01fda4','NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'} + + +class Refused(Exception):pass + + +def git(root,*args): + result=subprocess.run(['git','--no-optional-locks','-C',str(root),*args], + capture_output=True,timeout=30,check=False) + if result.returncode:raise Refused('read-only-git-failed') + return result.stdout + + +def field(text,key): + values=re.findall(r'^'+re.escape(key)+r':\s*(.*?)\s*$',text,re.M) + if len(values)!=1:raise Refused('source-field-ambiguous') + return values[0].strip('"\'') + + +def source(text): + header=text.split('---',2)[1] + tasks=[] + for block in re.findall(r'```task\n(.*?)\n```',text,re.S): + deps=re.findall(r'^depends_on:\s*\[(.*?)\]',block,re.M) + tasks.append({'record_id':field(block,'id'),'id':field(block,'state_hub_task_id'), + 'status':field(block,'status'),'dependencies':[x.strip() for x in deps[0].split(',') if x.strip()] if deps else []}) + return {'id':field(header,'state_hub_workstream_id'),'source_record_id':field(header,'id'), + 'slug':field(header,'id').lower(), + 'status':field(header,'status'),'tasks':tasks} + + +def get(path): + class NoRedirect(urllib.request.HTTPRedirectHandler): + def redirect_request(self,*args,**kwargs):raise Refused('hub-redirect-refused') + opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect) + with opener.open(urllib.request.Request(API+path,method='GET'),timeout=20) as response: + data=response.read(8*1024**2+1) + if len(data)>8*1024**2:raise Refused('hub-read-limit') + return json.loads(data) + + +def index_stat(root): + raw=git(root,'rev-parse','--git-path','index').decode().strip();path=Path(raw) + if not path.is_absolute():path=root/path + try:item=path.lstat() + except FileNotFoundError:return None + return [item.st_dev,item.st_ino,item.st_size,item.st_mtime_ns,item.st_mode] + + +def remote(root,expected,repo): + if git(root,'remote','get-url','origin').decode().strip()!='forgejo-remote:coulomb/'+repo+'.git': + raise Refused('remote-route-drift') + lines=git(root,'ls-remote','--symref','origin','HEAD','refs/heads/main').decode().splitlines() + if set(lines)!={'ref: refs/heads/main\tHEAD',expected+'\tHEAD',expected+'\trefs/heads/main'}: + raise Refused('remote-head-mismatch') + return {'HEAD':expected,'refs/heads/main':expected,'symbolic_HEAD':'refs/heads/main'} + + +def verify(): + result={'status':'unverified','scope':'Cluster WP18 owner publication; read-only Git remote and Hub snapshots', + 'writes_to_source_index_refs_or_Hub':False,'rows':[]} + try: + if API not in {'http://127.0.0.1:8000','http://127.0.0.1:18080','http://10.43.68.154:8000'}: + raise Refused('unrecognized-hub-endpoint') + health=get('/state/health') + result['hub_instance']={key:health.get(key) for key in ('status','instance_role','instance_label')} + if result['hub_instance']!={'status':'ok','instance_role':'primary','instance_label':'railiance01'}: + raise Refused('hub-identity-mismatch') + for owner in OWNERS: + root=Path('/home/worsch')/owner['repo'];before_index=index_stat(root) + if git(root,'rev-parse','HEAD').decode().strip()!=owner['commit']: + raise Refused('local-head-drift') + committed=git(root,'show',owner['commit']+':'+owner['path']) + local=(root/owner['path']).read_bytes() + if local!=committed:raise Refused('published-workplan-local-drift') + expected=source(committed.decode()) + if expected['source_record_id']!=owner['id'] or len(expected['tasks'])!=owner['tasks']: + raise Refused('source-task-denominator-mismatch') + snapshot=get('/repos/'+owner['repo']+'/work-record-projection/snapshot') + plans=[row for row in snapshot['workplans'] if row['id']==expected['id']] + if len(plans)!=1 or any(plans[0].get(key)!=expected[key] for key in ('id','slug','status')): + raise Refused('workplan-binding-mismatch') + projected=[row for row in snapshot['tasks'] + if row.get('workplan_id',row.get('workstream_id'))==expected['id']] + if len(projected)!=len(expected['tasks']):raise Refused('projected-task-denominator-mismatch') + byid={row['id']:row for row in projected} + if len(byid)!=len(projected):raise Refused('duplicate-projected-uuid') + observed=[] + for task in expected['tasks']: + row=byid.get(task['id'],{}) + if any(row.get(key)!=task[key] for key in ('id','record_id','status')): + raise Refused('task-id-uuid-status-mismatch') + observed.append({key:row[key] for key in ('id','record_id','status')}) + identifiers={task['record_id']:task['id'] for task in expected['tasks']} + edges={(task['id'],identifiers[dep],'starts_after') for task in expected['tasks'] for dep in task['dependencies'] if dep in identifiers} + actual=[edge for edge in snapshot['dependencies'] if edge['from_workplan_id']==expected['id']] + projected_edges={(edge.get('from_task_id'),edge.get('to_task_id'),edge['relationship_type']) for edge in actual} + if len(actual)!=len(edges) or projected_edges!=edges: + raise Refused('dependency-binding-mismatch') + # Unchanged exact three edges retain their original creation commit. + if any(edge.get('source_commit') not in (None,owner['commit']) and not (edge.get('source_commit')=='c562d7134c38679952a8ffd17a8a893a900aef0d' and edge.get('source_owner')=='forge:railiance-cluster') for edge in actual): + raise Refused('dependency-source-commit-mismatch') + for task in expected['tasks']: + for dep in task['dependencies']: + if dep in EXTERNAL: + target=get('/tasks/'+EXTERNAL[dep]) + if target.get('id')!=EXTERNAL[dep] or target.get('record_id')!=dep: + raise Refused('external-dependency-target-mismatch') + remote_readback=remote(root,owner['commit'],owner['repo']) + if index_stat(root)!=before_index or (root/owner['path']).read_bytes()!=local: + raise Refused('source-or-index-stat-changed') + result['rows'].append({'repo':owner['repo'],'published_commit':owner['commit'], + 'remote':remote_readback,'workplan':{key:plans[0][key] for key in ('id','slug','status')}, + 'source_record_id':expected['source_record_id'], + 'tasks':observed,'external_source_declarations_not_projected':[{'from_task_id':task['id'],'target_record_id':dep,'target_uuid':EXTERNAL[dep]} for task in expected['tasks'] for dep in task['dependencies'] if dep in EXTERNAL],'dependencies':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(edges)], + 'source_file_sha256':hashlib.sha256(local).hexdigest(),'source_file_unchanged':True,'dependency_scope':'internal edges verified; external source target identities checked without claiming projected external edges', + 'index_stat_unchanged':True}) + result['status']='verified' + except Exception as error: + result['reason']=error.args[0] if isinstance(error,Refused) else 'readback-unavailable' + result['verifier_sha256']=hashlib.sha256(Path(__file__).read_bytes()).hexdigest() + (HERE/'forward-correction-publication-readback.json').write_text(json.dumps(result,indent=2)+'\n') + print(json.dumps({'status':result['status'],'owners':len(result['rows'])})) + return 0 if result['status']=='verified' else 2 + + +if __name__=='__main__':raise SystemExit(verify()) diff --git a/docs/changes/netkingdom-target-2026-10-17/cluster-publication-readback.json b/docs/changes/netkingdom-target-2026-10-17/cluster-publication-readback.json new file mode 100644 index 00000000..a52ef0cc --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/cluster-publication-readback.json @@ -0,0 +1,77 @@ +{ + "status": "verified", + "scope": "Cluster WP18 owner publication; read-only Git remote and Hub snapshots", + "writes_to_source_index_refs_or_Hub": false, + "rows": [ + { + "repo": "railiance-cluster", + "published_commit": "c562d7134c38679952a8ffd17a8a893a900aef0d", + "remote": { + "HEAD": "c562d7134c38679952a8ffd17a8a893a900aef0d", + "refs/heads/main": "c562d7134c38679952a8ffd17a8a893a900aef0d", + "symbolic_HEAD": "refs/heads/main" + }, + "workplan": { + "id": "e0a7813d-c916-5e49-84b2-5e5b30441891", + "slug": "rcluster-wp-0018", + "status": "ready" + }, + "source_record_id": "RCLUSTER-WP-0018", + "tasks": [ + { + "id": "7280193d-0d59-5b78-a2d3-96ebd127127f", + "record_id": "RCLUSTER-WP-0018-T01", + "status": "done" + }, + { + "id": "90836435-917f-504c-a711-3f29ece348e3", + "record_id": "RCLUSTER-WP-0018-T02", + "status": "todo" + }, + { + "id": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a", + "record_id": "RCLUSTER-WP-0018-T03", + "status": "wait" + }, + { + "id": "021b07bb-65bc-5743-bac5-4294b4be74f6", + "record_id": "RCLUSTER-WP-0018-T04", + "status": "wait" + }, + { + "id": "5bc67a22-0991-5625-86a6-f749560d8a0e", + "record_id": "RCLUSTER-WP-0018-T05", + "status": "todo" + } + ], + "external_source_declarations_not_projected": [], + "dependencies": [ + { + "from_task_id": "021b07bb-65bc-5743-bac5-4294b4be74f6", + "to_task_id": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a", + "relationship_type": "starts_after" + }, + { + "from_task_id": "021b07bb-65bc-5743-bac5-4294b4be74f6", + "to_task_id": "90836435-917f-504c-a711-3f29ece348e3", + "relationship_type": "starts_after" + }, + { + "from_task_id": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a", + "to_task_id": "90836435-917f-504c-a711-3f29ece348e3", + "relationship_type": "starts_after" + } + ], + "source_file_sha256": "ca521f5330dfd42d22f6ee92774e036d0d3c85e33ebbd27ea89e4be2b3f62b5c", + "source_file_unchanged": true, + "dependency_scope": "internal edges verified; external source target identities checked without claiming projected external edges", + "index_stat_unchanged": true + } + ], + "hub_instance": { + "status": "ok", + "instance_role": "primary", + "instance_label": "railiance01" + }, + "verifier_sha256": "a0687ae6e05a6faf4efd2122c9ebd9f9a25a8cfb936741c8971295bb029abb1f" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-consistency.json b/docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-consistency.json new file mode 100644 index 00000000..4853c2fd --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-consistency.json @@ -0,0 +1,553 @@ +{ + "repo_slug": "railiance-cluster", + "repo_path": "/home/worsch/railiance-cluster", + "source_revision": "c562d7134c38679952a8ffd17a8a893a900aef0d", + "source_revision_reason": null, + "issues": [ + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager warning: .repo-classification.yaml: category is project but slug is not prj-*; not every category:project is a prj- repo", + "file_path": ".repo-classification.yaml", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1: task id 'T01' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2: task id 'T02' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3: task id 'T03' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4: task id 'T04' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5: task id 'T05' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1: task id 'T01' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2: task id 'T02' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3: task id 'T03' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4: task id 'T04' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1: task id 'T01' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2: task id 'T02' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3: task id 'T03' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4: task id 'T04' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5: task id 'T05' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6: task id 'T06' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1: task 'T01' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1', 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1']", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2: task 'T02' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2', 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2']", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3: task 'T03' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3', 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3']", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4: task 'T04' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4', 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4']", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5: task 'T05' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5']", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-33", + "message": "WORK-RECORDS.md is missing or stale \u2014 regenerate via fix-consistency (CUST-WP-0061-T04 generated work-record index)", + "file_path": "WORK-RECORDS.md", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": true + }, + { + "severity": "WARN", + "check_id": "C-23", + "message": "Lifecycle drift in 'rcluster-wp-0018': workplan status 'ready' has an active task \u2014 repair to 'active'", + "file_path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md", + "db_id": "e0a7813d-c916-5e49-84b2-5e5b30441891", + "file_value": "ready", + "db_value": "ready", + "fixable": true + }, + { + "severity": "WARN", + "check_id": "C-34", + "message": "status=ready without quality_dor DoR-Ok \u2014 process claim without DoR assessment (soft; see docs/work-record-quality-gates.md)", + "file_path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md", + "db_id": "", + "file_value": "unassessed", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-39", + "message": "Human wait task 'RCLUSTER-WP-0018-T04' in workplan 'RCLUSTER-WP-0018' has needs_human: true without decision_id \u2014 unrouted human gate", + "file_path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md#RCLUSTER-WP-0018-T04", + "db_id": "", + "file_value": "needs_human: true", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'rail-bs-wp-0008-activity-core-wp0016-triage-output-deploy@retired-20260828' (id=f2ca1a5d\u2026, status=archived) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "f2ca1a5d-4dd6-42ea-8003-969c7265f891", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'rail-bs-wp-0009-activity-core-admin-sync-smoke@retired-20260828' (id=366eec46\u2026, status=archived) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "366eec46-3139-4810-ace6-ea75750fe821", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Closed DB workstream 'rail-bs-wp-0008' (id=5032c55c\u2026, status=finished) has no backing workplan file", + "file_path": "", + "db_id": "5032c55c-2ee2-4b7e-b1eb-157f0f8ac647", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0014@retired-20260826' (id=a152ddda\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "a152ddda-d60a-4a65-9b9c-59e2db9ff2b7", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0012@retired-20260826' (id=6434f7cb\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "6434f7cb-e13c-4c05-839b-197bb239d5cd", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0013@retired-20260826' (id=a3abb83a\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "a3abb83a-2d42-40f9-a5f6-1dbc36903436", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'rail-bs-rcluster-wp-adhoc-2026-07-27@retired-20260828' (id=b37f3c6e\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "b37f3c6e-a9e5-58c2-84ec-77ef2a2978a7", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'rail-bs-adhoc-2026-07-27@retired-20260828' (id=9a77bc91\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "9a77bc91-f457-5545-996f-04f49707f54b", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-28", + "message": "8 unread inbox message(s) older than 3 day(s): railiance-platform:0c1023ce, railiance-platform:f643ce05, prj-forgejo-org-refactor:be06609c, prj-forgejo-org-refactor:6eac8c3f, prj-forgejo-org-refactor:82225aca, ...", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-28", + "message": "8 unread message(s) lack thread_id for supersession tracking: railiance-platform:0c1023ce, railiance-platform:f643ce05, prj-forgejo-org-refactor:be06609c, prj-forgejo-org-refactor:6eac8c3f, prj-forgejo-org-refactor:82225aca", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-29", + "message": "Unread work request from railiance-platform (f643ce05) may need a workplan file: RPF56: implement native JWT consumer-group mapping for Playwright", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-29", + "message": "Unread work request from the-custodian (a1368d99) may need a workplan file: Workplan 'three-phoenix-ha-cluster' is blocked with no wait task", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0007' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/RCLUSTER-WP-0007-threephoenix-ha-cluster.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0007", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0014' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/RCLUSTER-WP-0014-capacity-utilization-and-allocation-evidence.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0014", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0016' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/RCLUSTER-WP-0016-forgejo-upload-timeout.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0016", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0017' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/RCLUSTER-WP-0017-netkingdom-signer-runtime-storage-review.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0017", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0018' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0018", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0001' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/archived/260622-RCLUSTER-WP-0001-activity-core-cluster-owned-deploy-verify.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0001", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0002' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/archived/260622-RCLUSTER-WP-0002-activity-core-verifier-evidence-hardening.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0002", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0003' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/archived/260701-RCLUSTER-WP-0003-activity-core-llm-connect-live-reconcile.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0003", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0008' collides across repos: railiance-bootstrap/RAIL-BS-WP-0008-activity-core-wp0016-triage-output-deploy.md, railiance-cluster/RAIL-BS-WP-0008-activity-core-wp0016-triage-output-deploy.md", + "file_path": "workplans/RAIL-BS-WP-0008-activity-core-wp0016-triage-output-deploy.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0008", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0009' collides across repos: railiance-bootstrap/RAIL-BS-WP-0009-activity-core-admin-sync-smoke.md, railiance-cluster/RAIL-BS-WP-0009-activity-core-admin-sync-smoke.md", + "file_path": "workplans/RAIL-BS-WP-0009-activity-core-admin-sync-smoke.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0009", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0001' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0001-dependency-management.md, railiance-cluster/260622-RAIL-BS-WP-0001-dependency-management.md", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0001-dependency-management.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0001", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0002' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0002-k3s-baseline.md, railiance-cluster/260622-RAIL-BS-WP-0002-k3s-baseline.md", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0002", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0003' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md, railiance-cluster/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0003", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0004' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0004-safety-net.md, railiance-cluster/260622-RAIL-BS-WP-0004-safety-net.md", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0004", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0005' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0005-kubeconfig-delivery.md, railiance-cluster/260622-RAIL-BS-WP-0005-kubeconfig-delivery.md", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0005-kubeconfig-delivery.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0005", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0006' collides across repos: railiance-bootstrap/260627-RAIL-BS-WP-0006-staged-promotion-lifecycle.md, railiance-cluster/260627-RAIL-BS-WP-0006-staged-promotion-lifecycle.md", + "file_path": "workplans/archived/260627-RAIL-BS-WP-0006-staged-promotion-lifecycle.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0006", + "db_value": "", + "fixable": false + } + ], + "fixes_applied": [ + "bindings: synced 23/23", + "C-33 fixed: regenerated WORK-RECORDS.md", + "C-23 fixed: workstream e0a7813d\u2026 status \u2192 'active'", + "C-23 fixed: RCLUSTER-WP-0018-keycape-original-tls-recovery.md status ready \u2192 active (committed)", + "brief: .custodian-brief.md updated", + "push: pushed" + ], + "summary": { + "fail": 0, + "automation_error": 0, + "warn": 45, + "info": 8 + }, + "result": "warn" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-projection.json b/docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-projection.json new file mode 100644 index 00000000..d0389d25 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-projection.json @@ -0,0 +1,244 @@ +{ + "ok": true, + "status": "applied", + "repo_slug": "railiance-cluster", + "commit": "26671d33600e218316d29c9cd020f115ebfb35b2", + "requests": 2, + "elapsed_ms": 2311.2, + "git": { + "upstream": "origin/main", + "behind": 0, + "ahead": 0 + }, + "identifiers": { + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": true, + "repo": "railiance-cluster", + "namespace": "helixforge", + "assignments": [], + "historical_invalid_identifiers": [ + { + "kind": "task", + "id": "T01", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1" + }, + { + "kind": "task", + "id": "T02", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2" + }, + { + "kind": "task", + "id": "T03", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3" + }, + { + "kind": "task", + "id": "T04", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4" + }, + { + "kind": "task", + "id": "T05", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5" + }, + { + "kind": "task", + "id": "T01", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1" + }, + { + "kind": "task", + "id": "T02", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2" + }, + { + "kind": "task", + "id": "T03", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3" + }, + { + "kind": "task", + "id": "T04", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4" + }, + { + "kind": "task", + "id": "T01", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1" + }, + { + "kind": "task", + "id": "T02", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2" + }, + { + "kind": "task", + "id": "T03", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3" + }, + { + "kind": "task", + "id": "T04", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4" + }, + { + "kind": "task", + "id": "T05", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5" + }, + { + "kind": "task", + "id": "T06", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6" + } + ], + "historical_identity_collisions": [ + { + "kind": "task", + "id": "T01", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "3f042630-eab0-4c6a-9167-e2b28ff20e40", + "4526a842-ea31-4874-9231-92ab556cfe7b", + "6841c93a-f146-47eb-9f7c-8fa0e02c1bbc" + ] + }, + { + "kind": "task", + "id": "T02", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "a6313e06-1976-46a7-8e31-df4eb2eca880", + "ab166073-30a7-4702-a037-4091e8706e20", + "e8510646-46ed-4697-a345-f3d3009eea78" + ] + }, + { + "kind": "task", + "id": "T03", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "05d42a55-921f-4aa7-bb76-e8af9c7e0ac3", + "140da396-8e30-4f4d-b88c-c42c0cd46c01", + "dab2c07f-8aa0-4635-8df6-857e87e93fc5" + ] + }, + { + "kind": "task", + "id": "T04", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "08233868-d522-4117-bc4e-6c0f52545665", + "5c3d40e4-239b-488e-9519-6f7a38d2325f", + "d8a3ba40-fda0-4c1f-a9f1-ffcd621a5b3d" + ] + }, + { + "kind": "task", + "id": "T05", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "2d5acff7-4a4e-4ddd-ad06-08237ad3dac8", + "7f9e0e58-a130-467a-a2d0-b3f2564e496f" + ] + } + ], + "files_changed": [] + }, + "receipt": { + "schema": "state-hub.repository-projection-reconcile.v1", + "instance_role": "primary", + "instance_label": "railiance01", + "expected_commit": "26671d33600e218316d29c9cd020f115ebfb35b2", + "derived_commit": "26671d33600e218316d29c9cd020f115ebfb35b2", + "outcome": { + "schema": "state-hub.projection-reset.v1", + "repo_slug": "railiance-cluster", + "commit": "26671d33600e218316d29c9cd020f115ebfb35b2", + "status": "applied", + "counts": { + "created": 0, + "updated": 20, + "retired": 0, + "refused": 0, + "released": 0, + "created_tasks": 0, + "updated_tasks": 0, + "cancelled_tasks": 0, + "created_edges": 0, + "removed_edges": 0, + "unresolved_edges": 0, + "external_edges": 0 + }, + "created": [], + "updated": [ + "RAIL-BS-WP-0001", + "RAIL-BS-WP-0005", + "RAIL-BS-WP-0006", + "RAIL-BS-WP-0008", + "RAIL-BS-WP-0009", + "RAIL-BS-WP-0010", + "RAIL-BS-WP-0011", + "RAIL-BS-WP-0012", + "RAIL-BS-WP-0013", + "RAIL-BS-WP-0014", + "RAIL-BS-WP-0015", + "RCLUSTER-WP-0001", + "RCLUSTER-WP-0002", + "RCLUSTER-WP-0003", + "RCLUSTER-WP-0007", + "RCLUSTER-WP-0014", + "RCLUSTER-WP-0016", + "RCLUSTER-WP-0017", + "RCLUSTER-WP-0018", + "RCLUSTER-WP-ADHOC-2026-07-27" + ], + "retired": [], + "released": [], + "created_tasks": [], + "updated_tasks": [], + "cancelled_tasks": [], + "created_edges": [], + "removed_edges": [], + "unresolved_edges": [], + "external_edges": [], + "refused": [], + "notes": [ + "Preserved bound historical row and task UUIDs: RAIL-BS-WP-0002", + "Preserved bound historical row and task UUIDs: RAIL-BS-WP-0003", + "Preserved bound historical row and task UUIDs: RAIL-BS-WP-0004" + ] + } + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/e9bc-reviewed-manifest.json b/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/e9bc-reviewed-manifest.json new file mode 100644 index 00000000..32fbd9e7 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/e9bc-reviewed-manifest.json @@ -0,0 +1,77 @@ +{ + "schema": "statehub.source-owner-followthrough.v1", + "revision": 3, + "status": "isolated_source_candidate_not_published", + "base_revision": "086d79a2736e34b916bd7de3c8a65e2ea38a3d64", + "files": [ + { + "path": "workplans/STATE-WP-0095-historical-source-receiving.md", + "action": "modify", + "base_sha256": "ef10359cc5974283b5bdbfc602adf14e3c24362adf00640698d2937c6538483a", + "candidate_sha256": "287001ec92d5a9b851b0d70e56747730a9bb150fcda09e97d6e6e9ddf39c7b5c" + }, + { + "path": "Makefile", + "action": "modify", + "base_sha256": "5584ef94071044cca8215141ecd8aee8d6ae5cfe73e8f5719358c680eb8af0d4", + "candidate_sha256": "c5b70e8d4b8ae70380e0ade1c35f9e7fe80038de10080a4723b21ef07a98001e" + }, + { + "path": "deploy/railiance/apps/charts/state-hub/Chart.yaml", + "action": "modify", + "base_sha256": "7fe02b390ffd2ba4ce6f82bd62df900826826401e31bdc2138dd5bf36b51a6ae", + "candidate_sha256": "61a989fcf277d05ffbececb7332ee3ca1d8f369c72f960ab1bc4dbc6815536b8" + }, + { + "path": "deploy/railiance/apps/helm/state-hub-values.yaml", + "action": "modify", + "base_sha256": "f7cc0e9968598f6ce0faa0d56f62d6817845c3570c18b6ac39ed6561b952b197", + "candidate_sha256": "b51296fc937450f4ecf0ae43243262a631b551389c0d09c8bfe58fa10e2f3ee9" + }, + { + "path": "docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json", + "action": "add", + "base_sha256": null, + "candidate_sha256": "fb0b59ba3558e084fb4ae2c36c556f3cfbb2a889f6fd86d4e803c52f483b26fd" + }, + { + "path": "deploy/railiance/apps/charts/state-hub/files/repo-classification.allowed.yaml", + "action": "modify", + "base_sha256": "9c36fbd5308b19695f9f05d86f8e315bbeccdd267575ce4e2fccf6fb2ea82e32", + "candidate_sha256": "f53c651bb4329c09c04c66f906e2462fe4339ab51ef0ec3da9f942c3016f5bed" + }, + { + "path": "api/services/historical_projection.py", + "action": "modify", + "base_sha256": "e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2", + "candidate_sha256": "e24e57c58f4aaa4ec9d9bf088009ac69006e53f75b9477ee53dc26c4e850b975" + }, + { + "path": "api/routers/workstreams.py", + "action": "modify", + "base_sha256": "61e7a0ab638b155e9e0b2a72fe8e0ddd2edf5bc6c2d3ca7f6c3ff51e8868910b", + "candidate_sha256": "9c9bf4376dd323b52109912bb3f615949e89ac02c8b88b4720f569f8565ad1d6" + }, + { + "path": "scripts/consistency_check.py", + "action": "modify", + "base_sha256": "1827921c79b476bee823c2ddf9896aeb83f3efca6548427e17b3244216bbc6b5", + "candidate_sha256": "ae96d6260f6c88d35bc2d3f22f2a6061367621fd0416387d25d8683c8e804e06" + }, + { + "path": "tests/test_frozen_binding_guard_isolated.py", + "action": "add", + "base_sha256": null, + "candidate_sha256": "78eb62178fdecf9b5f6c40d398f8c44e93ff740abaf86557ab51ceb708d2ed65" + } + ], + "patch_sha256": "sha256:e9bc2ba9f81b6290945b6de6e0a00ba4c995478b17da786605f5a0466e300b3d", + "T06": "done_verified_approved_rollout_at_stage", + "T07": "wait_actual_later_parent_row_preservation_failure", + "T08": "done_source_repair_pending_publication", + "T09": "progress_until_source_published", + "T10": "wait_needs_human_new_runtime", + "live_effects": false, + "original_parent_preimages": "unknown_do_not_restore_guesses", + "managed_UUIDs": "T09_T10_not_allocated_pending_review" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/intermediate-review.json b/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/intermediate-review.json new file mode 100644 index 00000000..93380f97 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/intermediate-review.json @@ -0,0 +1,19 @@ +{ + "status": "intermediate-reviewed-new-fix-guard-pending", + "reviewed_patch": "e9bc2ba9f81b6290945b6de6e0a00ba4c995478b17da786605f5a0466e300b3d", + "isolated_tests": { + "candidate": 40, + "independent": 4, + "passed": 44, + "seconds": 2.84 + }, + "tests_scope": "AST-extracted API/checker functions; generated in-memory rows and copies of exact historical source files; no actual DB/network", + "findings": [ + "original missing frozen scan path guard fixed in e9bc", + "original repo-unqualified path matcher fixed in e9bc", + "original refusal without automation FAIL fixed in e9bc", + "legacy fix_repo still needs protected parent/task repair preflight; recovery agent notified" + ], + "independent_test_sha256": "6896ec48f02829cbc97954c78f29284024727330af38997149e7f03b01f36abc", + "canonical_source_mutation": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-final-review.json b/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-final-review.json new file mode 100644 index 00000000..1ae2e9dc --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-final-review.json @@ -0,0 +1,27 @@ +{ + "status": "reviewed-no-blocking-source-findings", + "reviewed_patch_sha256": "ad3d49b83435dd026118ee1e4a25779b5a7739473619bbda256f160c4eb0e56a", + "manifest_file": "r5-reviewed-manifest.json", + "isolated_tests": { + "candidate": 102, + "reviewer": 7, + "passed": 109, + "seconds": 10.89 + }, + "coverage": [ + "all3parents API no-setter preservation and missing expected-task refusal", + "ordinary-first all3frozen invalid-final-task batch refuses with no setter or commit", + "all18knownUUIDs nested mutating-context denial, including foreign repo claims", + "candidate exact3source metadata/hash/missing/symlink failclosed and C44automationnonzero", + "candidate protected legacy repair preflight before binding sync and fix side effects", + "ordinary dependency TO historical record allowed; FROM protected parent/task refused" + ], + "limits": [ + "AST-extracted endpoint and checker tests use in-memory generated rows, not delivered runtime or PostgreSQL transactions", + "API requires all15knownUUIDs owned and terminal; additional children remain permitted, consistent current Forge semantics", + "no original parent preimages reconstructed; no restoration claim", + "source review does not complete T07/RMGR19T06 or authorize new runtime activation" + ], + "canonical_source_or_database_changes": false, + "test_file_sha256": "fa2a347d8a2f0a28f9e81752de42d151138f71f5d1e83adb86f7cfe3e530486f" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-reviewed-manifest.json b/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-reviewed-manifest.json new file mode 100644 index 00000000..6bbc2df3 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-reviewed-manifest.json @@ -0,0 +1,77 @@ +{ + "schema": "statehub.source-owner-followthrough.v1", + "revision": 5, + "status": "isolated_source_candidate_not_published", + "base_revision": "086d79a2736e34b916bd7de3c8a65e2ea38a3d64", + "files": [ + { + "path": "workplans/STATE-WP-0095-historical-source-receiving.md", + "action": "modify", + "base_sha256": "ef10359cc5974283b5bdbfc602adf14e3c24362adf00640698d2937c6538483a", + "candidate_sha256": "5671189ee87f2d4dff08979f6243e5eb7888b140955899642a74d569496b71c7" + }, + { + "path": "Makefile", + "action": "modify", + "base_sha256": "5584ef94071044cca8215141ecd8aee8d6ae5cfe73e8f5719358c680eb8af0d4", + "candidate_sha256": "c5b70e8d4b8ae70380e0ade1c35f9e7fe80038de10080a4723b21ef07a98001e" + }, + { + "path": "deploy/railiance/apps/charts/state-hub/Chart.yaml", + "action": "modify", + "base_sha256": "7fe02b390ffd2ba4ce6f82bd62df900826826401e31bdc2138dd5bf36b51a6ae", + "candidate_sha256": "61a989fcf277d05ffbececb7332ee3ca1d8f369c72f960ab1bc4dbc6815536b8" + }, + { + "path": "deploy/railiance/apps/helm/state-hub-values.yaml", + "action": "modify", + "base_sha256": "f7cc0e9968598f6ce0faa0d56f62d6817845c3570c18b6ac39ed6561b952b197", + "candidate_sha256": "b51296fc937450f4ecf0ae43243262a631b551389c0d09c8bfe58fa10e2f3ee9" + }, + { + "path": "docs/evidence/2026-10-17-cluster-historical-receiving-rollout.json", + "action": "add", + "base_sha256": null, + "candidate_sha256": "fb0b59ba3558e084fb4ae2c36c556f3cfbb2a889f6fd86d4e803c52f483b26fd" + }, + { + "path": "deploy/railiance/apps/charts/state-hub/files/repo-classification.allowed.yaml", + "action": "modify", + "base_sha256": "9c36fbd5308b19695f9f05d86f8e315bbeccdd267575ce4e2fccf6fb2ea82e32", + "candidate_sha256": "f53c651bb4329c09c04c66f906e2462fe4339ab51ef0ec3da9f942c3016f5bed" + }, + { + "path": "api/services/historical_projection.py", + "action": "modify", + "base_sha256": "e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2", + "candidate_sha256": "e24e57c58f4aaa4ec9d9bf088009ac69006e53f75b9477ee53dc26c4e850b975" + }, + { + "path": "api/routers/workstreams.py", + "action": "modify", + "base_sha256": "61e7a0ab638b155e9e0b2a72fe8e0ddd2edf5bc6c2d3ca7f6c3ff51e8868910b", + "candidate_sha256": "9c9bf4376dd323b52109912bb3f615949e89ac02c8b88b4720f569f8565ad1d6" + }, + { + "path": "scripts/consistency_check.py", + "action": "modify", + "base_sha256": "1827921c79b476bee823c2ddf9896aeb83f3efca6548427e17b3244216bbc6b5", + "candidate_sha256": "eaee916f46a11f49d2621fc9386717d73b7fd517acbe4b695e7b551d67bfa8f7" + }, + { + "path": "tests/test_frozen_binding_guard_isolated.py", + "action": "add", + "base_sha256": null, + "candidate_sha256": "4dc64df78a02dc633e5744d0277afe5d350fbb0637196e78dec992f91135bded" + } + ], + "patch_sha256": "sha256:ad3d49b83435dd026118ee1e4a25779b5a7739473619bbda256f160c4eb0e56a", + "T06": "done_verified_approved_rollout_at_stage", + "T07": "wait_actual_later_parent_row_preservation_failure", + "T08": "done_source_repair_pending_publication", + "T09": "progress_until_source_published", + "T10": "wait_needs_human_new_runtime", + "live_effects": false, + "original_parent_preimages": "unknown_do_not_restore_guesses", + "managed_UUIDs": "T09_T10_not_allocated_pending_review" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-test-independent-review.py b/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-test-independent-review.py new file mode 100644 index 00000000..474ee8b1 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-test-independent-review.py @@ -0,0 +1,34 @@ +import importlib.util,asyncio,uuid +from pathlib import Path +import pytest +spec=importlib.util.spec_from_file_location('guardtest',Path(__file__).with_name('test_frozen_binding_guard_isolated.py')) +t=importlib.util.module_from_spec(spec);spec.loader.exec_module(t) +@pytest.mark.parametrize('bound',t.h.FROZEN_CLUSTER_BINDINGS) +def test_independent_all_three_preserve_and_missing_refuse(bound): + previous=t.B;t.B=bound + try: + repo,parent,tasks=t.closure(bound) + r,s=asyncio.run(t.run_api([t.binding(_bound=bound)],repo,parent,tasks)) + assert r['preserved']==1 and s.commits==0 and parent.writes==[] + with pytest.raises(t.HTTPException):asyncio.run(t.run_api([t.binding(_bound=bound)],repo,parent,tasks[:-1])) + finally:t.B=previous + +def test_independent_three_parent_invalid_last_batch_no_setters(): + repo=t.Obj(id=uuid.uuid4());parents=[];tasks=[];entries=[] + for b in t.h.FROZEN_CLUSTER_BINDINGS: + parent=t.Obj(id=uuid.UUID(b['uuid']),repo_id=repo.id,status='finished');parents.append(parent) + tasks.extend(t.Obj(id=uuid.UUID(x['uuid']),workplan_id=parent.id,status='done') for x in b['tasks']) + entries.append(t.Entry(workplan_id=parent.id,repo_slug=b['repo'],filename=Path(b['path']).name,relative_path=b['path'],archived=True,status='finished')) + ordinary=t.Obj(id=uuid.uuid4());normal=t.Entry(workplan_id=ordinary.id,repo_slug='ordinary',filename='ordinary.md',relative_path='workplans/ordinary.md',archived=False,status='active') + tasks[-1].status='progress';tasks[-1].writes.clear() + session=t.Session([[ordinary,*parents],[repo],tasks]) + fn=t.extracted('api/routers/workstreams.py','sync_workplan_bindings',dict(frozen_cluster_binding=t.h.frozen_cluster_binding,validate_frozen_cluster_rows=t.h.validate_frozen_cluster_rows,HTTPException=t.HTTPException,select=lambda *_:t.Query(),Workplan=t.Model,Task=t.Model,ManagedRepo=t.Model,_invalidate_workplan_index_cache=lambda:None)) + with pytest.raises(t.HTTPException):asyncio.run(fn(t.Obj(bindings=[normal,*entries]),session)) + assert session.commits==0 and ordinary.writes==[] and all(p.writes==[] for p in parents) and all(x.writes==[] for x in tasks) + +@pytest.mark.parametrize('bound',t.h.FROZEN_CLUSTER_BINDINGS) +def test_independent_all_eighteen_ids_nested_repair_denied(bound): + guard=t.extracted('scripts/consistency_check.py','_refuse_frozen_fix_batch',dict(FROZEN_CLUSTER_BINDINGS=t.h.FROZEN_CLUSTER_BINDINGS)) + for protected in [bound['uuid'],*[x['uuid'] for x in bound['tasks']]]: + report=t.actual_report();report.add(severity='WARN',check_id='C-41',message='drift',fixable=True,_fix_context={'nested':[{'from_task_id':protected}]}) + assert guard(report,'foreign') and report.automation_errors diff --git a/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/test_independent_review.py b/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/test_independent_review.py new file mode 100644 index 00000000..18cb8434 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/test_independent_review.py @@ -0,0 +1,27 @@ +import importlib.util,asyncio,uuid +from pathlib import Path +import pytest +spec=importlib.util.spec_from_file_location('guardtest',Path(__file__).with_name('test_frozen_binding_guard_isolated.py')) +t=importlib.util.module_from_spec(spec);spec.loader.exec_module(t) +@pytest.mark.parametrize('bound',t.h.FROZEN_CLUSTER_BINDINGS) +def test_independent_all_three_preserve_and_missing_refuse(bound): + previous=t.B;t.B=bound + try: + repo,parent,tasks=t.closure() + r,s=asyncio.run(t.run_api([t.binding()],repo,parent,tasks)) + assert r['preserved']==1 and s.commits==0 and parent.writes==[] + with pytest.raises(t.HTTPException):asyncio.run(t.run_api([t.binding()],repo,parent,tasks[:-1])) + finally:t.B=previous + +def test_independent_three_parent_invalid_last_batch_no_setters(): + repo=t.Obj(id=uuid.uuid4());parents=[];tasks=[];entries=[] + for b in t.h.FROZEN_CLUSTER_BINDINGS: + parent=t.Obj(id=uuid.UUID(b['uuid']),repo_id=repo.id,status='finished');parents.append(parent) + tasks.extend(t.Obj(id=uuid.UUID(x['uuid']),workplan_id=parent.id,status='done') for x in b['tasks']) + entries.append(t.Entry(workplan_id=parent.id,repo_slug=b['repo'],filename=Path(b['path']).name,relative_path=b['path'],archived=True,status='finished')) + ordinary=t.Obj(id=uuid.uuid4());normal=t.Entry(workplan_id=ordinary.id,repo_slug='ordinary',filename='ordinary.md',relative_path='workplans/ordinary.md',archived=False,status='active') + tasks[-1].status='progress';tasks[-1].writes.clear() + session=t.Session([[ordinary,*parents],[repo],tasks]) + fn=t.extracted('api/routers/workstreams.py','sync_workplan_bindings',dict(frozen_cluster_binding=t.h.frozen_cluster_binding,validate_frozen_cluster_rows=t.h.validate_frozen_cluster_rows,HTTPException=t.HTTPException,select=lambda *_:t.Query(),Workplan=t.Model,Task=t.Model,ManagedRepo=t.Model,_invalidate_workplan_index_cache=lambda:None)) + with pytest.raises(t.HTTPException):asyncio.run(fn(t.Obj(bindings=[normal,*entries]),session)) + assert session.commits==0 and ordinary.writes==[] and all(p.writes==[] for p in parents) and all(x.writes==[] for x in tasks) diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-image-a25b62f-inspection.json b/docs/changes/netkingdom-target-2026-10-17/guard-image-a25b62f-inspection.json new file mode 100644 index 00000000..e3f4fe80 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-image-a25b62f-inspection.json @@ -0,0 +1,774 @@ +{ + "schema": "statehub.guard-image-inspection.v1", + "status": "verified-selected-public-image-bytes", + "source_commit": "a25b62f75aab6165ee9872ee53ac90c679ec746a", + "tag": "main-a25b62f", + "image_digest": "sha256:226086b1acaec3fc77e30014a101c96de687e38c9eb52cd522e5e69efb1980a0", + "selected_source_hashes": { + "app/api/services/historical_projection.py": "sha256:e24e57c58f4aaa4ec9d9bf088009ac69006e53f75b9477ee53dc26c4e850b975", + "app/api/routers/workstreams.py": "sha256:9c9bf4376dd323b52109912bb3f615949e89ac02c8b88b4720f569f8565ad1d6", + "app/scripts/consistency_check.py": "sha256:eaee916f46a11f49d2621fc9386717d73b7fd517acbe4b695e7b551d67bfa8f7", + "app/api/services/forge_projection.py": "sha256:b980e62cbd85c3e7df42b01abf14354e04133374db94af6531dcd91629c3487d", + "app/migrations/versions/c4d5e6f7a8b9_inbox_feed_revision.py": "sha256:48f1730037be99b5623e878d7f20a06bec243ce27317fde81c82e16006d7b3ce", + "tmp/.ci-build-id": "sha256:ea57ead67d610c44a6237a7d96be66a8f9882f026de544b8efc69dbd7d57315d" + }, + "observed_files": { + "tmp/.ci-build-id": "sha256:ea57ead67d610c44a6237a7d96be66a8f9882f026de544b8efc69dbd7d57315d", + "tmp/hub-core/hub_core/__init__.py": "sha256:098578bae76f7d97354b8f3dfe8ddc63b15806a46d1691d70ed12d9839d69aec", + "tmp/hub-core/hub_core/conformance/__init__.py": "sha256:f7ce0a651913f157e586afd6e953b483add0dd5257ee9f2406c47e8d46ee9587", + "tmp/hub-core/hub_core/conformance/harness.py": "sha256:ca870fbbec7b7f5db6521d615fd76dfcbb9e97cbdfb037ffa993851a663b3c40", + "tmp/hub-core/hub_core/contracts/__init__.py": "sha256:ffb7a6b79ce15ddd57943bfbc40799e078c6f57c6690018237baa3f3a755ac49", + "tmp/hub-core/hub_core/contracts/helixforge_hub_extension/__init__.py": "sha256:32c095a16f777127ec0d2cd5e8373889866b81e9955d01e5adaf9503f6864da4", + "tmp/hub-core/hub_core/contracts/helixforge_hub_extension/v0_1_0/__init__.py": "sha256:e176b86b24d79c11f78ad714878bc3fca41c7821654fa766278b697360a41201", + "tmp/hub-core/hub_core/contracts/repository_navigation/__init__.py": "sha256:64912fe6673b72c3c0d8a2da28673d58bdf6f4185a1376ffe43d3735350adb60", + "tmp/hub-core/hub_core/contracts/repository_navigation/v1_0_0/__init__.py": "sha256:574cf1fee8433e0b11d9475cfbcc3837730b55f6ea1faa4920cba106d959464f", + "tmp/hub-core/hub_core/contracts/workload_projection/__init__.py": "sha256:c01198d23571442c1c3a596c7cd16be17dc1a3efdcfe3e8f9725b7dba16fc103", + "tmp/hub-core/hub_core/contracts/workload_projection/v1_0_0/__init__.py": "sha256:a9ecfecbf44893d32268288c872cdede0440d2a1373d37a47f69ba8c6431de0d", + "tmp/hub-core/hub_core/database.py": "sha256:a7704e97509433e90655b0ea22d5fa626d75b8b6470015ef8b9e5997e7a7f5ea", + "tmp/hub-core/hub_core/events.py": "sha256:c7125a242ed638a3ede29129e4ad826cd188cf76239b59a8587a40d182bbd0e7", + "tmp/hub-core/hub_core/mcp/__init__.py": "sha256:f97b25193573e56886b66f91cb8c86ef4a39f2100d709869e279e17456959859", + "tmp/hub-core/hub_core/mcp/credentials.py": "sha256:f5433d29848bd5a399a5e31695e0d908748e0a0856d26b2d691b667c50c95c34", + "tmp/hub-core/hub_core/mcp/server.py": "sha256:fc6a6de0a29ad9b6da176302a7d24e4ba987f667b6a7fb001029f00cb0d0c582", + "tmp/hub-core/hub_core/message_identity.py": "sha256:0ab996ba50f236c1342ce72ca8ae6ff28102ef41216972a745f7260e0c93fb24", + "tmp/hub-core/hub_core/migrations/__init__.py": "sha256:ccf4820e270c97fd5d4ac02f0c96362a772b8f4d1bcccc3f5e0077b77f575d36", + "tmp/hub-core/hub_core/migrations/env.py": "sha256:282e6e1a9e4a3cfdc111887f04dc5c1645307b3943a421852abe1709ce712e57", + "tmp/hub-core/hub_core/migrations/roles.py": "sha256:91e85297d296b0c4b9c78b16ae67d3a4707232d8f32b2cac2b2e84f31fa80e89", + "tmp/hub-core/hub_core/migrations/versions/0001_core_schema.py": "sha256:c65f076a7b56fb93ee67869e04d922ea396eab72a4c2d2f0dabd706c918aa081", + "tmp/hub-core/hub_core/migrations/versions/0002_runtime_ports.py": "sha256:d3ce15463841b3c13eaafdd137a65d4cf2839c0b8e8fddcb2cb2f1adbceb9f00", + "tmp/hub-core/hub_core/migrations/versions/0003_repository_navigation.py": "sha256:fb2d2cb5ed10f1760ab789ced8d43c657c1bedc29ba666231a70a18636160902", + "tmp/hub-core/hub_core/migrations/versions/0004_workload_projection.py": "sha256:87ce668bfef5cf4aaf0cfd3b48d498f2370f68e06a6e66375e446af6fbbb9c96", + "tmp/hub-core/hub_core/migrations/versions/0005_message_identity_aliases.py": "sha256:ec05d2c3cb906b78cdec4d220a7ce09264c38904c792cdad3cd1082e7eace7c0", + "tmp/hub-core/hub_core/migrations/versions/0006_outcome_outbox.py": "sha256:05effdf6f258836d1cd223f9d9fc3447d264484021d3a51cfa42517453d613e1", + "tmp/hub-core/hub_core/migrations/versions/__init__.py": "sha256:569f6d7e5cc1c17b7b1eee3eec3b82774b745d01ee1dfdf851a5c6f5c337f0bb", + "tmp/hub-core/hub_core/models/__init__.py": "sha256:c0b6de4986614a163dbb2467d15882eadbd66800478a50de4d6404198d1f773a", + "tmp/hub-core/hub_core/models/agent_message.py": "sha256:23d16eeaffe780f326b08e6c441100e6ae7b4075bbb6421734c06156a87c4375", + "tmp/hub-core/hub_core/models/base.py": "sha256:85bb40bde6f4cf8e6c5700a3a016a711fab4adff77c5eb78f89827fe28b9537b", + "tmp/hub-core/hub_core/models/capability_catalog.py": "sha256:eebbb31f264821a61662d3c9e8c7eba74f46d7f68b946e35f8127343bf2ff9c4", + "tmp/hub-core/hub_core/models/capability_request.py": "sha256:70a867c82aaa061a4e1c671b023d213032464e776226280f99e2ca192e2a6eba", + "tmp/hub-core/hub_core/models/domain.py": "sha256:ddf45c37e3c37014ddd9148be01cf104658e1601abba2a8ba96f7680cdb581b3", + "tmp/hub-core/hub_core/models/managed_repo.py": "sha256:835c5d44581daf7d7dd95325e3f7fdf0add4d529b83779ed83b5e812dcb3aa61", + "tmp/hub-core/hub_core/models/message_identity_alias.py": "sha256:d07d59cd9c9351669e8319727d08bc0e9bb7e0ee36bf8a34c0c258f0b4ea61e4", + "tmp/hub-core/hub_core/models/progress_event.py": "sha256:ee750127db2f49c5b9b94773a408f7f965d834b02e6d962220f4bc762309161f", + "tmp/hub-core/hub_core/models/tpsc.py": "sha256:cb28cbe3512486adb73c0bce633b3c542a41a64e7ec673e86a5a25ab20d94afe", + "tmp/hub-core/hub_core/routers/__init__.py": "sha256:800d1c45f597fcb4970ca7a83acd2b36016006efbdf638e14a3482a954d9046d", + "tmp/hub-core/hub_core/routers/capabilities.py": "sha256:18a403ad6ac961bc490543b698e079336f60ef9902a6cd71ef9899076660d5c0", + "tmp/hub-core/hub_core/routers/domains.py": "sha256:d4c4061d2ab0d2d6390a10f4f815deb0b93b3979345aee965b666110ba32e6e0", + "tmp/hub-core/hub_core/routers/messages.py": "sha256:903bd4f8c8ca599b606cf2229315de21097360816fcda907159dac4f48cee512", + "tmp/hub-core/hub_core/routers/policy.py": "sha256:358271263295fdebb5bcb95c3a27bd3ea456964a77bc01c3f784fb7a8754aacf", + "tmp/hub-core/hub_core/routers/progress.py": "sha256:680cf4dea00a1734d7d70ef7880acc8fd39f045521baa47f415c17934779d18a", + "tmp/hub-core/hub_core/routers/repos.py": "sha256:1bca6c9b2b5bbe172f5b935b763ac1e399b1d403cdc2c463000ae79f843257a2", + "tmp/hub-core/hub_core/routers/tpsc.py": "sha256:706815b01be1c0320bf73cf9cff3e9415c1f27b8449ee9e6fea67b12d3042fd1", + "tmp/hub-core/hub_core/runtime/__init__.py": "sha256:c522e626373407bf9bcd727dac7bb812cbdc8c3ef5bb6509a74949e5b49ab4c2", + "tmp/hub-core/hub_core/runtime/app.py": "sha256:87b077498bbe321c73139e51f7ca689fdc7963a98c4d72a5a3bbcc564f47ee76", + "tmp/hub-core/hub_core/runtime/cli.py": "sha256:98ec00f2a12911245827f515877472ae1c37cea65a42454494450ffbe7380e57", + "tmp/hub-core/hub_core/runtime/compat.py": "sha256:9f1c4575bb406ae1174da1a005ec16f44ace63768617e11164b44b4051162d0d", + "tmp/hub-core/hub_core/runtime/compat_catalogs.py": "sha256:250f61ea39cced32c8cd932c4e770ae8be54ff1cf1e257ee2c82324bde0d7a26", + "tmp/hub-core/hub_core/runtime/config.py": "sha256:009b2fc5d1f8fc390d478b01444f610ada91e5fee30534936382be2529a843fc", + "tmp/hub-core/hub_core/runtime/inbox_projection.py": "sha256:84499238654310b86f7a97f2817163ff4c4da0dfce562c677294fa3dfef7f398", + "tmp/hub-core/hub_core/runtime/migration.py": "sha256:d12731fa581c48bf58deec19405ece977c89d08993b2a2ad047cb1fd17318ea8", + "tmp/hub-core/hub_core/runtime/models.py": "sha256:367ca4aa29f59f8e3f59eab22f12782146cf623fa7ac7c22346c794b85a88185", + "tmp/hub-core/hub_core/runtime/ports.py": "sha256:ab70a401deae73389761a0e88dc8ee843df00a671fae6919b1f7eed344cfb542", + "tmp/hub-core/hub_core/runtime/postgres_store.py": "sha256:9286e7845009b66f00069d67177733dabe372d79986c33ca9b43e00dfa5a2341", + "tmp/hub-core/hub_core/runtime/repo_manager_client.py": "sha256:8fa305277c5f3ddfdbe1daf4023ce6c3cde03b5c18c1292dd6aac3fe995aabe1", + "tmp/hub-core/hub_core/runtime/repository_navigation.py": "sha256:f3503596781f3e7f7d53dd28dd3aaf563905f1398575b40c8080e2b1b9978b1e", + "tmp/hub-core/hub_core/runtime/repository_navigation_routes.py": "sha256:eab78ab418a7b542dcdcab5da023bacc65fb50520853f8d179accb2105e373cf", + "tmp/hub-core/hub_core/runtime/store.py": "sha256:2fb78f14bab8df08807322d6f6416745856d69e6001381246abbac879891858d", + "tmp/hub-core/hub_core/runtime/tables.py": "sha256:a5ff72a9c54eedcc8bb81330e62ee72578a383a1d03a1acb598c72c96cdfbe9e", + "tmp/hub-core/hub_core/runtime/validation.py": "sha256:2add804d95d5d0469d6d8d605fbd1013885da972489a017260c6fddef7b80c79", + "tmp/hub-core/hub_core/runtime/workload_projection.py": "sha256:8500260404b0c566a62e51fef63ee320d4e3dafe5e2467f44db884296b9e3bf4", + "tmp/hub-core/hub_core/runtime/workload_projection_routes.py": "sha256:5c71189b98867f2f1f7612f47ee69c0ec3ddf836b9b1c7e134b98a2be45791de", + "tmp/hub-core/hub_core/schemas/__init__.py": "sha256:dfa2ec2d125f03a532637d2fbef3058ebe1f85c515ff42a930198e164b7812f7", + "tmp/hub-core/hub_core/schemas/agent_message.py": "sha256:d6a7f40dc9a3c61be761f4d2e2c08f726fb0a423ef73e273a7cd97c69ae6c6a3", + "tmp/hub-core/hub_core/schemas/capability.py": "sha256:949c55cb1f2694de4617ad53dc9cb7bc0e72addd7b9d0f104b93d783e4edc647", + "tmp/hub-core/hub_core/schemas/doi.py": "sha256:73d675aecabd5a62ae13184494a4b9db122ad24b3132e1d0e908eef802382f36", + "tmp/hub-core/hub_core/schemas/domain.py": "sha256:872a704fea959d2e4d0ff771770a97160457282218f4748ba4f830c489543aac", + "tmp/hub-core/hub_core/schemas/managed_repo.py": "sha256:a7ab3b1ab399da81324693dcd5d3feeccb211642b10f11cd3f03c7fe6ba751d4", + "tmp/hub-core/hub_core/schemas/policy.py": "sha256:bdaef1640783ac325a050cadf214e731d7c8e5e3a35dbb8f7562d5abbd209a4c", + "tmp/hub-core/hub_core/schemas/progress_event.py": "sha256:9ac7b7fd4881d424bfe59c5001554fd7302243e8489d5e777584d11ead1db328", + "tmp/hub-core/hub_core/schemas/tpsc.py": "sha256:5640d96a7fa862a468eeb0d6da002697b1f58e4cd675a4603b91e448d4db851e", + "tmp/hub-core/hub_core/security/__init__.py": "sha256:2754e25ec0f5725c33cb0b4dff1b7d10b364ebd828e609bb5b44eee3309d2d60", + "tmp/hub-core/hub_core/security/account_reader.py": "sha256:27019616b84cf030969a8e3c0850b5ae52f336008fd9daa4c26360566e74a39b", + "tmp/hub-core/hub_core/security/audit.py": "sha256:94cb85d71f065443c6423871b59d41e929af0441c95928273caf3e38dad8125c", + "tmp/hub-core/hub_core/security/boundary.py": "sha256:a1629ac717672276f61015c83f7af6e375bbd8c1234c712dd3d225da307ae0d6", + "tmp/hub-core/hub_core/security/browser.py": "sha256:fd474ee4b9611fe8dd2c60111402c2fce67d680a7da3519b5d4a495a6b559b7a", + "tmp/hub-core/hub_core/security/config.py": "sha256:7d604f6aeebde393a371ec3e0ab174934e10808c29fb370acba031486e9c02a3", + "tmp/hub-core/hub_core/security/context.py": "sha256:1181bbf12ba86bfd5046dab2f3a22a64ee3686be6dd52ab3e843303349b13a52", + "tmp/hub-core/hub_core/security/facts.py": "sha256:3de4db38ffd3f86f4918d76f811289cd501be3c28dcba16f5088aa2a2b7529ce", + "tmp/hub-core/hub_core/security/identity.py": "sha256:d7a0bab9d59a5f342fdedc9723d818a9d2537a59c6a9415455786af748f912e9", + "tmp/hub-core/hub_core/security/policy.py": "sha256:a2370e9ea5b04b1d5a429644d7f81edb1cbe8e15214c23b16cd6f949613eebd6", + "tmp/hub-core/hub_core/utils/__init__.py": "sha256:ce4ddb30ccc4fd2c4ee59e8a3c088a12165171af02aea957f17f72cd868e1899", + "tmp/hub-core/hub_core/utils/pagination.py": "sha256:366250b85052c7aabc2a2262521d34233124ba3a41026042792f8eda706ecb4f", + "tmp/hub-core/hub_core/utils/paths.py": "sha256:988a889be74f0626ca3c27b1d6677bd4a556e35de389c060d07ab64fa1c22fc8", + "tmp/hub-core/hub_core/utils/routing.py": "sha256:c94b44c5f1ab723e123503e20e0309f28abeeabea6d51beda79247d99852ad1e", + "tmp/hub-core/hub_core/utils/slugs.py": "sha256:eda7a7d18ff21a4d949223b75a2b615a949e615f461152a9cb9a2cf74b491e2d", + "app/.venv/lib/python3.12/site-packages/hub_core/__init__.py": "sha256:098578bae76f7d97354b8f3dfe8ddc63b15806a46d1691d70ed12d9839d69aec", + "app/.venv/lib/python3.12/site-packages/hub_core/conformance/__init__.py": "sha256:f7ce0a651913f157e586afd6e953b483add0dd5257ee9f2406c47e8d46ee9587", + "app/.venv/lib/python3.12/site-packages/hub_core/conformance/harness.py": "sha256:ca870fbbec7b7f5db6521d615fd76dfcbb9e97cbdfb037ffa993851a663b3c40", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/__init__.py": "sha256:ffb7a6b79ce15ddd57943bfbc40799e078c6f57c6690018237baa3f3a755ac49", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/helixforge_hub_extension/__init__.py": "sha256:32c095a16f777127ec0d2cd5e8373889866b81e9955d01e5adaf9503f6864da4", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/helixforge_hub_extension/v0_1_0/__init__.py": "sha256:e176b86b24d79c11f78ad714878bc3fca41c7821654fa766278b697360a41201", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/repository_navigation/__init__.py": "sha256:64912fe6673b72c3c0d8a2da28673d58bdf6f4185a1376ffe43d3735350adb60", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/repository_navigation/v1_0_0/__init__.py": "sha256:574cf1fee8433e0b11d9475cfbcc3837730b55f6ea1faa4920cba106d959464f", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/workload_projection/__init__.py": "sha256:c01198d23571442c1c3a596c7cd16be17dc1a3efdcfe3e8f9725b7dba16fc103", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/workload_projection/v1_0_0/__init__.py": "sha256:a9ecfecbf44893d32268288c872cdede0440d2a1373d37a47f69ba8c6431de0d", + "app/.venv/lib/python3.12/site-packages/hub_core/database.py": "sha256:a7704e97509433e90655b0ea22d5fa626d75b8b6470015ef8b9e5997e7a7f5ea", + "app/.venv/lib/python3.12/site-packages/hub_core/events.py": "sha256:c7125a242ed638a3ede29129e4ad826cd188cf76239b59a8587a40d182bbd0e7", + "app/.venv/lib/python3.12/site-packages/hub_core/mcp/__init__.py": "sha256:f97b25193573e56886b66f91cb8c86ef4a39f2100d709869e279e17456959859", + "app/.venv/lib/python3.12/site-packages/hub_core/mcp/credentials.py": "sha256:f5433d29848bd5a399a5e31695e0d908748e0a0856d26b2d691b667c50c95c34", + "app/.venv/lib/python3.12/site-packages/hub_core/mcp/server.py": "sha256:fc6a6de0a29ad9b6da176302a7d24e4ba987f667b6a7fb001029f00cb0d0c582", + "app/.venv/lib/python3.12/site-packages/hub_core/message_identity.py": "sha256:0ab996ba50f236c1342ce72ca8ae6ff28102ef41216972a745f7260e0c93fb24", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/__init__.py": "sha256:ccf4820e270c97fd5d4ac02f0c96362a772b8f4d1bcccc3f5e0077b77f575d36", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/env.py": "sha256:282e6e1a9e4a3cfdc111887f04dc5c1645307b3943a421852abe1709ce712e57", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/roles.py": "sha256:91e85297d296b0c4b9c78b16ae67d3a4707232d8f32b2cac2b2e84f31fa80e89", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/0001_core_schema.py": "sha256:c65f076a7b56fb93ee67869e04d922ea396eab72a4c2d2f0dabd706c918aa081", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/0002_runtime_ports.py": "sha256:d3ce15463841b3c13eaafdd137a65d4cf2839c0b8e8fddcb2cb2f1adbceb9f00", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/0003_repository_navigation.py": "sha256:fb2d2cb5ed10f1760ab789ced8d43c657c1bedc29ba666231a70a18636160902", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/0004_workload_projection.py": "sha256:87ce668bfef5cf4aaf0cfd3b48d498f2370f68e06a6e66375e446af6fbbb9c96", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/0005_message_identity_aliases.py": "sha256:ec05d2c3cb906b78cdec4d220a7ce09264c38904c792cdad3cd1082e7eace7c0", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/0006_outcome_outbox.py": "sha256:05effdf6f258836d1cd223f9d9fc3447d264484021d3a51cfa42517453d613e1", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/__init__.py": "sha256:569f6d7e5cc1c17b7b1eee3eec3b82774b745d01ee1dfdf851a5c6f5c337f0bb", + "app/.venv/lib/python3.12/site-packages/hub_core/models/__init__.py": "sha256:c0b6de4986614a163dbb2467d15882eadbd66800478a50de4d6404198d1f773a", + "app/.venv/lib/python3.12/site-packages/hub_core/models/agent_message.py": "sha256:23d16eeaffe780f326b08e6c441100e6ae7b4075bbb6421734c06156a87c4375", + "app/.venv/lib/python3.12/site-packages/hub_core/models/base.py": "sha256:85bb40bde6f4cf8e6c5700a3a016a711fab4adff77c5eb78f89827fe28b9537b", + "app/.venv/lib/python3.12/site-packages/hub_core/models/capability_catalog.py": "sha256:eebbb31f264821a61662d3c9e8c7eba74f46d7f68b946e35f8127343bf2ff9c4", + "app/.venv/lib/python3.12/site-packages/hub_core/models/capability_request.py": "sha256:70a867c82aaa061a4e1c671b023d213032464e776226280f99e2ca192e2a6eba", + "app/.venv/lib/python3.12/site-packages/hub_core/models/domain.py": "sha256:ddf45c37e3c37014ddd9148be01cf104658e1601abba2a8ba96f7680cdb581b3", + "app/.venv/lib/python3.12/site-packages/hub_core/models/managed_repo.py": "sha256:835c5d44581daf7d7dd95325e3f7fdf0add4d529b83779ed83b5e812dcb3aa61", + "app/.venv/lib/python3.12/site-packages/hub_core/models/message_identity_alias.py": "sha256:d07d59cd9c9351669e8319727d08bc0e9bb7e0ee36bf8a34c0c258f0b4ea61e4", + "app/.venv/lib/python3.12/site-packages/hub_core/models/progress_event.py": "sha256:ee750127db2f49c5b9b94773a408f7f965d834b02e6d962220f4bc762309161f", + "app/.venv/lib/python3.12/site-packages/hub_core/models/tpsc.py": "sha256:cb28cbe3512486adb73c0bce633b3c542a41a64e7ec673e86a5a25ab20d94afe", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/__init__.py": "sha256:800d1c45f597fcb4970ca7a83acd2b36016006efbdf638e14a3482a954d9046d", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/capabilities.py": "sha256:18a403ad6ac961bc490543b698e079336f60ef9902a6cd71ef9899076660d5c0", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/domains.py": "sha256:d4c4061d2ab0d2d6390a10f4f815deb0b93b3979345aee965b666110ba32e6e0", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/messages.py": "sha256:903bd4f8c8ca599b606cf2229315de21097360816fcda907159dac4f48cee512", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/policy.py": "sha256:358271263295fdebb5bcb95c3a27bd3ea456964a77bc01c3f784fb7a8754aacf", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/progress.py": "sha256:680cf4dea00a1734d7d70ef7880acc8fd39f045521baa47f415c17934779d18a", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/repos.py": "sha256:1bca6c9b2b5bbe172f5b935b763ac1e399b1d403cdc2c463000ae79f843257a2", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/tpsc.py": "sha256:706815b01be1c0320bf73cf9cff3e9415c1f27b8449ee9e6fea67b12d3042fd1", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/__init__.py": "sha256:c522e626373407bf9bcd727dac7bb812cbdc8c3ef5bb6509a74949e5b49ab4c2", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/app.py": "sha256:87b077498bbe321c73139e51f7ca689fdc7963a98c4d72a5a3bbcc564f47ee76", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/cli.py": "sha256:98ec00f2a12911245827f515877472ae1c37cea65a42454494450ffbe7380e57", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/compat.py": "sha256:9f1c4575bb406ae1174da1a005ec16f44ace63768617e11164b44b4051162d0d", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/compat_catalogs.py": "sha256:250f61ea39cced32c8cd932c4e770ae8be54ff1cf1e257ee2c82324bde0d7a26", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/config.py": "sha256:009b2fc5d1f8fc390d478b01444f610ada91e5fee30534936382be2529a843fc", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/inbox_projection.py": "sha256:84499238654310b86f7a97f2817163ff4c4da0dfce562c677294fa3dfef7f398", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/migration.py": "sha256:d12731fa581c48bf58deec19405ece977c89d08993b2a2ad047cb1fd17318ea8", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/models.py": "sha256:367ca4aa29f59f8e3f59eab22f12782146cf623fa7ac7c22346c794b85a88185", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/ports.py": "sha256:ab70a401deae73389761a0e88dc8ee843df00a671fae6919b1f7eed344cfb542", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/postgres_store.py": "sha256:9286e7845009b66f00069d67177733dabe372d79986c33ca9b43e00dfa5a2341", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/repo_manager_client.py": "sha256:8fa305277c5f3ddfdbe1daf4023ce6c3cde03b5c18c1292dd6aac3fe995aabe1", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/repository_navigation.py": "sha256:f3503596781f3e7f7d53dd28dd3aaf563905f1398575b40c8080e2b1b9978b1e", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/repository_navigation_routes.py": "sha256:eab78ab418a7b542dcdcab5da023bacc65fb50520853f8d179accb2105e373cf", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/store.py": "sha256:2fb78f14bab8df08807322d6f6416745856d69e6001381246abbac879891858d", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/tables.py": "sha256:a5ff72a9c54eedcc8bb81330e62ee72578a383a1d03a1acb598c72c96cdfbe9e", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/validation.py": "sha256:2add804d95d5d0469d6d8d605fbd1013885da972489a017260c6fddef7b80c79", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/workload_projection.py": "sha256:8500260404b0c566a62e51fef63ee320d4e3dafe5e2467f44db884296b9e3bf4", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/workload_projection_routes.py": "sha256:5c71189b98867f2f1f7612f47ee69c0ec3ddf836b9b1c7e134b98a2be45791de", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/__init__.py": "sha256:dfa2ec2d125f03a532637d2fbef3058ebe1f85c515ff42a930198e164b7812f7", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/agent_message.py": "sha256:d6a7f40dc9a3c61be761f4d2e2c08f726fb0a423ef73e273a7cd97c69ae6c6a3", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/capability.py": "sha256:949c55cb1f2694de4617ad53dc9cb7bc0e72addd7b9d0f104b93d783e4edc647", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/doi.py": "sha256:73d675aecabd5a62ae13184494a4b9db122ad24b3132e1d0e908eef802382f36", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/domain.py": "sha256:872a704fea959d2e4d0ff771770a97160457282218f4748ba4f830c489543aac", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/managed_repo.py": "sha256:a7ab3b1ab399da81324693dcd5d3feeccb211642b10f11cd3f03c7fe6ba751d4", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/policy.py": "sha256:bdaef1640783ac325a050cadf214e731d7c8e5e3a35dbb8f7562d5abbd209a4c", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/progress_event.py": "sha256:9ac7b7fd4881d424bfe59c5001554fd7302243e8489d5e777584d11ead1db328", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/tpsc.py": "sha256:5640d96a7fa862a468eeb0d6da002697b1f58e4cd675a4603b91e448d4db851e", + "app/.venv/lib/python3.12/site-packages/hub_core/security/__init__.py": "sha256:2754e25ec0f5725c33cb0b4dff1b7d10b364ebd828e609bb5b44eee3309d2d60", + "app/.venv/lib/python3.12/site-packages/hub_core/security/account_reader.py": "sha256:27019616b84cf030969a8e3c0850b5ae52f336008fd9daa4c26360566e74a39b", + "app/.venv/lib/python3.12/site-packages/hub_core/security/audit.py": "sha256:94cb85d71f065443c6423871b59d41e929af0441c95928273caf3e38dad8125c", + "app/.venv/lib/python3.12/site-packages/hub_core/security/boundary.py": "sha256:a1629ac717672276f61015c83f7af6e375bbd8c1234c712dd3d225da307ae0d6", + "app/.venv/lib/python3.12/site-packages/hub_core/security/browser.py": "sha256:fd474ee4b9611fe8dd2c60111402c2fce67d680a7da3519b5d4a495a6b559b7a", + "app/.venv/lib/python3.12/site-packages/hub_core/security/config.py": "sha256:7d604f6aeebde393a371ec3e0ab174934e10808c29fb370acba031486e9c02a3", + "app/.venv/lib/python3.12/site-packages/hub_core/security/context.py": "sha256:1181bbf12ba86bfd5046dab2f3a22a64ee3686be6dd52ab3e843303349b13a52", + "app/.venv/lib/python3.12/site-packages/hub_core/security/facts.py": "sha256:3de4db38ffd3f86f4918d76f811289cd501be3c28dcba16f5088aa2a2b7529ce", + "app/.venv/lib/python3.12/site-packages/hub_core/security/identity.py": "sha256:d7a0bab9d59a5f342fdedc9723d818a9d2537a59c6a9415455786af748f912e9", + "app/.venv/lib/python3.12/site-packages/hub_core/security/policy.py": "sha256:a2370e9ea5b04b1d5a429644d7f81edb1cbe8e15214c23b16cd6f949613eebd6", + "app/.venv/lib/python3.12/site-packages/hub_core/utils/__init__.py": "sha256:ce4ddb30ccc4fd2c4ee59e8a3c088a12165171af02aea957f17f72cd868e1899", + "app/.venv/lib/python3.12/site-packages/hub_core/utils/pagination.py": "sha256:366250b85052c7aabc2a2262521d34233124ba3a41026042792f8eda706ecb4f", + "app/.venv/lib/python3.12/site-packages/hub_core/utils/paths.py": "sha256:988a889be74f0626ca3c27b1d6677bd4a556e35de389c060d07ab64fa1c22fc8", + "app/.venv/lib/python3.12/site-packages/hub_core/utils/routing.py": "sha256:c94b44c5f1ab723e123503e20e0309f28abeeabea6d51beda79247d99852ad1e", + "app/.venv/lib/python3.12/site-packages/hub_core/utils/slugs.py": "sha256:eda7a7d18ff21a4d949223b75a2b615a949e615f461152a9cb9a2cf74b491e2d", + "app/api/routers/workstreams.py": "sha256:9c9bf4376dd323b52109912bb3f615949e89ac02c8b88b4720f569f8565ad1d6", + "app/api/services/forge_projection.py": "sha256:b980e62cbd85c3e7df42b01abf14354e04133374db94af6531dcd91629c3487d", + "app/api/services/historical_projection.py": "sha256:e24e57c58f4aaa4ec9d9bf088009ac69006e53f75b9477ee53dc26c4e850b975", + "app/migrations/versions/c4d5e6f7a8b9_inbox_feed_revision.py": "sha256:48f1730037be99b5623e878d7f20a06bec243ce27317fde81c82e16006d7b3ce", + "app/scripts/consistency_check.py": "sha256:eaee916f46a11f49d2621fc9386717d73b7fd517acbe4b695e7b551d67bfa8f7" + }, + "layers": [ + { + "digest": "sha256:304074f06047f3dee0c586de265e0e27b577930bc80dc7f97f3829b188bc4fb0", + "compressed_bytes": 30855435, + "archive_entries": 3271, + "whiteouts": 0 + }, + { + "digest": "sha256:75b6a36c64a1cf3520fc4b4aae4739d5caa8a6a05c27835a920a61784c9c32f8", + "compressed_bytes": 1294052, + "archive_entries": 553, + "whiteouts": 0 + }, + { + "digest": "sha256:6912e23eb44595b44dc6d9882b34f305ad6f6e9667cec70b13e5dbc4f8cd97f4", + "compressed_bytes": 12121637, + "archive_entries": 1828, + "whiteouts": 0 + }, + { + "digest": "sha256:bbc5a12237474ec0b23b5051260d56d6436a24d70d9cad961adebe7a037ed813", + "compressed_bytes": 249, + "archive_entries": 8, + "whiteouts": 0 + }, + { + "digest": "sha256:e16e3995c15e64ae03e700d74eab2389f1151e6bd5d40f55faa047e9124aeb20", + "compressed_bytes": 93, + "archive_entries": 1, + "whiteouts": 0 + }, + { + "digest": "sha256:14568be832d0c877348328755de4e94cf4d0397d03f2161f6995e3b3e756e802", + "compressed_bytes": 55305356, + "archive_entries": 2898, + "whiteouts": 62 + }, + { + "digest": "sha256:2a6eb309967b62bf0c483ef7ca6b595a3222af9824d7d76df93588d2db516195", + "compressed_bytes": 148, + "archive_entries": 2, + "whiteouts": 0 + }, + { + "digest": "sha256:fb5adb1b205f7c2a5a53dc53c300aa7fa968e3bf2ba85bfcf569b8f45131ae94", + "compressed_bytes": 940, + "archive_entries": 2, + "whiteouts": 0 + }, + { + "digest": "sha256:2971f0a710787419ec533843974be96de47b083059b02e4a0dfdd48a98fdb458", + "compressed_bytes": 35700592, + "archive_entries": 5471, + "whiteouts": 0 + }, + { + "digest": "sha256:ab3e8c3939ccb8f5d731704f1e752ddb7fa9d135402990246724232683b00ff0", + "compressed_bytes": 598, + "archive_entries": 3, + "whiteouts": 0 + }, + { + "digest": "sha256:d1dbbe039887ff15d19e26f1fb3c559ea123a580c77bff5e286de1d6e3540595", + "compressed_bytes": 102610, + "archive_entries": 143, + "whiteouts": 0 + }, + { + "digest": "sha256:b62bd61a70f8477e54c01355ae337a553326e09974eebd65870d66f0b2f1ae3f", + "compressed_bytes": 109565, + "archive_entries": 160, + "whiteouts": 0 + }, + { + "digest": "sha256:99e6faeb00ebe8336cefd27da2bbedb3b4edc9d3c9e36ce05097163ba105a036", + "compressed_bytes": 475, + "archive_entries": 2, + "whiteouts": 0 + }, + { + "digest": "sha256:f910ccb3f35e942317fb817caf1ea13ddd0a49263e7bfbf6b8be6d132a663b29", + "compressed_bytes": 243471, + "archive_entries": 181, + "whiteouts": 0 + }, + { + "digest": "sha256:793e1ade12c8a9541429984963ef1084a96d41a69cbd5669d655829982b3bea7", + "compressed_bytes": 1675, + "archive_entries": 7, + "whiteouts": 0 + }, + { + "digest": "sha256:7a36c195ce44bc1ce1c7964cfd1fa3f3c32daf3dc9568a4ff7b550b0d93ef0fc", + "compressed_bytes": 36056, + "archive_entries": 7, + "whiteouts": 0 + }, + { + "digest": "sha256:231fbd5b3576f8c671a67522bad6a83935990a9a7fbe120ff26b422f78bd5f60", + "compressed_bytes": 33942, + "archive_entries": 63, + "whiteouts": 0 + }, + { + "digest": "sha256:23a0876f55835a5ee79ed45c5a67ba7ac9ca1e4e3168dfa2436dd234a370434a", + "compressed_bytes": 10801, + "archive_entries": 8, + "whiteouts": 0 + }, + { + "digest": "sha256:9a13796803f4255f7c8a1df9b693923fa002647c2690a148ebf901e4de66cb4f", + "compressed_bytes": 2116, + "archive_entries": 3, + "whiteouts": 0 + }, + { + "digest": "sha256:48d53f6a4a6c1a1f0ee5b6f45e8e8b47792ff9a4416c00c9c92454634155f915", + "compressed_bytes": 155200, + "archive_entries": 67, + "whiteouts": 0 + }, + { + "digest": "sha256:d5d5b11d971cbb2269dc1684898da2c0a41bff26630affbd8123ba7c82bd41b1", + "compressed_bytes": 2963, + "archive_entries": 7, + "whiteouts": 0 + }, + { + "digest": "sha256:d8438040b445dc9c2ad739b44d49d347d4c276ba889d5cdd8153fdadbe14f34d", + "compressed_bytes": 538, + "archive_entries": 4, + "whiteouts": 0 + } + ], + "python_package_metadata": { + "usr/local/lib/python3.12/site-packages/pip-25.0.1.dist-info/METADATA": { + "name": "pip", + "version": "25.0.1", + "metadata_sha256": "sha256:4fa7318cf30f979db7cec45c12cbbc2b4f88a15f12eefbf59a6291d0a03af926" + }, + "usr/local/lib/python3.12/site-packages/uv-0.13.1.dist-info/METADATA": { + "name": "uv", + "version": "0.13.1", + "metadata_sha256": "sha256:3554d26fcb1db453b54bde82aa3830ddc37179f3ac4394d670361553c02d0cf2" + }, + "app/.venv/lib/python3.12/site-packages/aiofile-3.12.3.dist-info/METADATA": { + "name": "aiofile", + "version": "3.12.3", + "metadata_sha256": "sha256:faaa3115c495ac1989aa6bda262b79a6c97e056c83e04afcfc71584a59e3ceb1" + }, + "app/.venv/lib/python3.12/site-packages/alembic-1.20.0.dist-info/METADATA": { + "name": "alembic", + "version": "1.20.0", + "metadata_sha256": "sha256:bd32c118c43955c106bfa4255b2fb5ac9db410b0f7255a4cafb14b9e221ff41c" + }, + "app/.venv/lib/python3.12/site-packages/annotated_doc-0.0.5.dist-info/METADATA": { + "name": "annotated-doc", + "version": "0.0.5", + "metadata_sha256": "sha256:8c24d70c5d9153d22123353a906042fd7603df2d15c2196290b0f8a962558c46" + }, + "app/.venv/lib/python3.12/site-packages/annotated_types-0.8.0.dist-info/METADATA": { + "name": "annotated-types", + "version": "0.8.0", + "metadata_sha256": "sha256:614985b278f601b8ef863f82783b991cc3ada4b89f592eb71c7c48c5f2ef2298" + }, + "app/.venv/lib/python3.12/site-packages/anyio-4.15.1.dist-info/METADATA": { + "name": "anyio", + "version": "4.15.1", + "metadata_sha256": "sha256:043aecb571af7189e8a6c528f5d8e32545f1b2cdfaaf761d51e6d5b67ea3ca81" + }, + "app/.venv/lib/python3.12/site-packages/asyncpg-0.32.0.dist-info/METADATA": { + "name": "asyncpg", + "version": "0.32.0", + "metadata_sha256": "sha256:10c1e84f762a55c69630704e8a429793dcab1ce5edba7deadb35f40476d502c9" + }, + "app/.venv/lib/python3.12/site-packages/attrs-26.1.0.dist-info/METADATA": { + "name": "attrs", + "version": "26.1.0", + "metadata_sha256": "sha256:4cd40e690f23bf37cbcad34efd6758e062df1df07c86833f7e3ce95bf1fa38cc" + }, + "app/.venv/lib/python3.12/site-packages/authlib-1.9.1.dist-info/METADATA": { + "name": "Authlib", + "version": "1.9.1", + "metadata_sha256": "sha256:7141e57ccac936724fd004b401d0695e0ae48f32f2aee14d90259a9d4bc4fdbd" + }, + "app/.venv/lib/python3.12/site-packages/beartype-0.23.1.dist-info/METADATA": { + "name": "beartype", + "version": "0.23.1", + "metadata_sha256": "sha256:ac75ec7a0bd6407db75c5c1da887798dfd4d5d12099e299602d03baa0ba22986" + }, + "app/.venv/lib/python3.12/site-packages/cachetools-7.2.2.dist-info/METADATA": { + "name": "cachetools", + "version": "7.2.2", + "metadata_sha256": "sha256:76bbee4a06789a8c42253966988a07aff8f2f29cb1ae3ff9d6f16d661f01f2d4" + }, + "app/.venv/lib/python3.12/site-packages/caio-0.12.9.dist-info/METADATA": { + "name": "caio", + "version": "0.12.9", + "metadata_sha256": "sha256:3128051d993cbf71f589f68b0082167fe1c910b17379d27653b6945ec848c3c8" + }, + "app/.venv/lib/python3.12/site-packages/certifi-2026.7.22.dist-info/METADATA": { + "name": "certifi", + "version": "2026.7.22", + "metadata_sha256": "sha256:ef5af1638fbb23676ac3c5777dfcfc2cd9c348fe4172ed5ba3d277655b248090" + }, + "app/.venv/lib/python3.12/site-packages/cffi-2.1.1.dist-info/METADATA": { + "name": "cffi", + "version": "2.1.1", + "metadata_sha256": "sha256:558bafb9093a8e790175d9ecff9688382981d744877dad86fd6770db0f4dc918" + }, + "app/.venv/lib/python3.12/site-packages/click-8.5.0.dist-info/METADATA": { + "name": "click", + "version": "8.5.0", + "metadata_sha256": "sha256:e87bce0bd194de70dfb8e708e0a6b0483009f25611804eaf87bfeb63e6c20501" + }, + "app/.venv/lib/python3.12/site-packages/cryptography-50.0.2.dist-info/METADATA": { + "name": "cryptography", + "version": "50.0.2", + "metadata_sha256": "sha256:047cfc71226409de4318b360aef15c63a2adf609731e3dcf7fe932f14ea042ee" + }, + "app/.venv/lib/python3.12/site-packages/cyclopts-5.2.0.dist-info/METADATA": { + "name": "cyclopts", + "version": "5.2.0", + "metadata_sha256": "sha256:a1bcd1e587744ec6f5c5c64126ac03a03fc2468f7c91cd1c44572a5ac11dcb2a" + }, + "app/.venv/lib/python3.12/site-packages/dnspython-2.9.0.dist-info/METADATA": { + "name": "dnspython", + "version": "2.9.0", + "metadata_sha256": "sha256:d25dbd09b39758cd5cebe518701012a6278731986cd384fc4a7f25e78f7de929" + }, + "app/.venv/lib/python3.12/site-packages/docstring_parser-0.18.0.dist-info/METADATA": { + "name": "docstring_parser", + "version": "0.18.0", + "metadata_sha256": "sha256:cbc42027997fd4b194ae5fd064a4d1e57b92976941d0c26d369561a7c016a333" + }, + "app/.venv/lib/python3.12/site-packages/email_validator-2.3.0.dist-info/METADATA": { + "name": "email-validator", + "version": "2.3.0", + "metadata_sha256": "sha256:2a97b81eefcd856bc80b0346f47fa2d800b9a438bf8f9231ae00fe931d5c9fbc" + }, + "app/.venv/lib/python3.12/site-packages/exceptiongroup-1.3.1.dist-info/METADATA": { + "name": "exceptiongroup", + "version": "1.3.1", + "metadata_sha256": "sha256:81984a523a2f7a522ad12bea784a8bb85edec0805ebbd0fb4e350169a36dd802" + }, + "app/.venv/lib/python3.12/site-packages/fastapi-0.143.3.dist-info/METADATA": { + "name": "fastapi", + "version": "0.143.3", + "metadata_sha256": "sha256:364f68b16f489abe36d621da2fa727f774bec90916cd3325b78e422af3b59a5f" + }, + "app/.venv/lib/python3.12/site-packages/fastmcp-4.1.0.dist-info/METADATA": { + "name": "fastmcp", + "version": "4.1.0", + "metadata_sha256": "sha256:cfdcfd24ad904514087ec1735baa54df174f72f570833a16b6074887cfc51fa6" + }, + "app/.venv/lib/python3.12/site-packages/fastmcp_slim-4.1.0.dist-info/METADATA": { + "name": "fastmcp-slim", + "version": "4.1.0", + "metadata_sha256": "sha256:e8eca5fbae348ee6dcda0a0f1bf0dffa493e8d4d8763647ee48f4f871e35c998" + }, + "app/.venv/lib/python3.12/site-packages/greenlet-3.5.6.dist-info/METADATA": { + "name": "greenlet", + "version": "3.5.6", + "metadata_sha256": "sha256:b9b4cbbc1f3165e50fbc4696c433fe82b8a151fde65eede28fb6ec5efb3e1fab" + }, + "app/.venv/lib/python3.12/site-packages/griffelib-2.3.2.dist-info/METADATA": { + "name": "griffelib", + "version": "2.3.2", + "metadata_sha256": "sha256:fd24a68ed08309718d5759b8de3b90392b5804240d94834e6455be110ead34b3" + }, + "app/.venv/lib/python3.12/site-packages/h11-0.16.0.dist-info/METADATA": { + "name": "h11", + "version": "0.16.0", + "metadata_sha256": "sha256:28f326098ac09fcba79b8f180f96087c841fe2456215cb7b872a9c7d5cd19d64" + }, + "app/.venv/lib/python3.12/site-packages/httpcore-1.0.9.dist-info/METADATA": { + "name": "httpcore", + "version": "1.0.9", + "metadata_sha256": "sha256:fe2d4fda6199128978779e0cf27f3c045c531863fcdd987eacc74f3a18d41c21" + }, + "app/.venv/lib/python3.12/site-packages/httpcore2-2.13.1.dist-info/METADATA": { + "name": "httpcore2", + "version": "2.13.1", + "metadata_sha256": "sha256:37a0ea0674e98b7c3a1f99c17d9bb5457de27a0f93c8b6560c9d17d525139abb" + }, + "app/.venv/lib/python3.12/site-packages/httptools-0.9.0.dist-info/METADATA": { + "name": "httptools", + "version": "0.9.0", + "metadata_sha256": "sha256:8a743396f45465204e2b44b43cb57ec4a343c423f52604bbaf1777fd438698c9" + }, + "app/.venv/lib/python3.12/site-packages/httpx-0.28.1.dist-info/METADATA": { + "name": "httpx", + "version": "0.28.1", + "metadata_sha256": "sha256:febb9b0f8f3e80d57c8199c304f35c4336e8581d1d18d7983c92766b82793b25" + }, + "app/.venv/lib/python3.12/site-packages/httpx2-2.13.1.dist-info/METADATA": { + "name": "httpx2", + "version": "2.13.1", + "metadata_sha256": "sha256:b75b03a003b5593e000907cf7239fcc3f688b8f17db4ecff883d11221ea988fc" + }, + "app/.venv/lib/python3.12/site-packages/idna-3.20.dist-info/METADATA": { + "name": "idna", + "version": "3.20", + "metadata_sha256": "sha256:dbd8c14c1e4ca1e0c9824a6dbc7cbbf78884f38eb52d91148cd3025f671e4b85" + }, + "app/.venv/lib/python3.12/site-packages/jaraco.classes-3.4.0.dist-info/METADATA": { + "name": "jaraco.classes", + "version": "3.4.0", + "metadata_sha256": "sha256:2e6b102232edd45ae1bb8a6b4091fd40cf3201a6bb6fd4bc97c5e8cd765a44b8" + }, + "app/.venv/lib/python3.12/site-packages/jaraco_context-6.1.2.dist-info/METADATA": { + "name": "jaraco.context", + "version": "6.1.2", + "metadata_sha256": "sha256:f1b65b60aea229af54e09b17ae0036cf048fe4a6161fa2e7966a8ea5c2321491" + }, + "app/.venv/lib/python3.12/site-packages/jaraco_functools-4.6.0.dist-info/METADATA": { + "name": "jaraco.functools", + "version": "4.6.0", + "metadata_sha256": "sha256:6ed3cae5b8eef084c3c7b2385a0a8ac4c8155ab7c729212bea099bee69d5bd6c" + }, + "app/.venv/lib/python3.12/site-packages/jeepney-0.9.0.dist-info/METADATA": { + "name": "jeepney", + "version": "0.9.0", + "metadata_sha256": "sha256:b8e6c353e9aaed0ed0144029556417fda23b64f344e718331907054ba05b8c62" + }, + "app/.venv/lib/python3.12/site-packages/joserfc-1.7.5.dist-info/METADATA": { + "name": "joserfc", + "version": "1.7.5", + "metadata_sha256": "sha256:17df62bbdc7212bbcda3144e72720a62fc34bbf76c573062939120738545250f" + }, + "app/.venv/lib/python3.12/site-packages/jsonref-1.1.0.dist-info/METADATA": { + "name": "jsonref", + "version": "1.1.0", + "metadata_sha256": "sha256:f98db3890394fba23912faab86ad8f70ed564fc8c885298b636b270f28453e43" + }, + "app/.venv/lib/python3.12/site-packages/jsonschema-4.26.0.dist-info/METADATA": { + "name": "jsonschema", + "version": "4.26.0", + "metadata_sha256": "sha256:05b189866ca98a96da3934bf6b83687ced3ff85325273b77e16b705f6d8b26d2" + }, + "app/.venv/lib/python3.12/site-packages/jsonschema_path-0.5.0.dist-info/METADATA": { + "name": "jsonschema-path", + "version": "0.5.0", + "metadata_sha256": "sha256:cd7e9a4426436980f099d826dbce8f61afa6603b496385fba9a9eb0ad59cdd48" + }, + "app/.venv/lib/python3.12/site-packages/jsonschema_specifications-2025.9.1.dist-info/METADATA": { + "name": "jsonschema-specifications", + "version": "2025.9.1", + "metadata_sha256": "sha256:35abd41757f32b4ea24756920ded47b70173d77cbc052a5a6d3ab583b2e8d89d" + }, + "app/.venv/lib/python3.12/site-packages/keyring-25.7.0.dist-info/METADATA": { + "name": "keyring", + "version": "25.7.0", + "metadata_sha256": "sha256:bd54de98fede6dc3e1f3cd89b4e37c95d8842a523bdbb9e52ab40edff1837163" + }, + "app/.venv/lib/python3.12/site-packages/mako-1.4.3.dist-info/METADATA": { + "name": "Mako", + "version": "1.4.3", + "metadata_sha256": "sha256:39ea65f21e706265428ea6f2925520f419a10f0113a59318192ed38175d8838b" + }, + "app/.venv/lib/python3.12/site-packages/markdown_it_py-4.2.0.dist-info/METADATA": { + "name": "markdown-it-py", + "version": "4.2.0", + "metadata_sha256": "sha256:72c36ff516755443b1ecb61e17b2567a990230b49a504b0eb0c42d5f82448a9c" + }, + "app/.venv/lib/python3.12/site-packages/markupsafe-3.0.4.dist-info/METADATA": { + "name": "MarkupSafe", + "version": "3.0.4", + "metadata_sha256": "sha256:66767d76388ece15d49d50dafb655891ef5d868715e7128e7f7d737a70b353c4" + }, + "app/.venv/lib/python3.12/site-packages/mcp-2.3.0.dist-info/METADATA": { + "name": "mcp", + "version": "2.3.0", + "metadata_sha256": "sha256:a94577513a4fa0cb639c279c1ad6f4d49650872d45f2f4ab9bb2d9c2a505d457" + }, + "app/.venv/lib/python3.12/site-packages/mcp_types-2.3.0.dist-info/METADATA": { + "name": "mcp-types", + "version": "2.3.0", + "metadata_sha256": "sha256:eb973e8b7f53d52ab1df9d1f18854ffa84f074f6052e310089e2655961c48ca9" + }, + "app/.venv/lib/python3.12/site-packages/mdurl-0.1.2.dist-info/METADATA": { + "name": "mdurl", + "version": "0.1.2", + "metadata_sha256": "sha256:b53b29d48f499367053fda3c81e7ce27d2558380ebbf83e66023b02eb7ddd25d" + }, + "app/.venv/lib/python3.12/site-packages/more_itertools-11.2.1.dist-info/METADATA": { + "name": "more-itertools", + "version": "11.2.1", + "metadata_sha256": "sha256:8c558bfab61818450e78db4018281f8f7b22115e681cd53ae1d9d4931be54f15" + }, + "app/.venv/lib/python3.12/site-packages/nats_py-2.16.0.dist-info/METADATA": { + "name": "nats-py", + "version": "2.16.0", + "metadata_sha256": "sha256:58ddf3dd698f9026d397e5bb56a0baac723ba221d3dddae0831cfacc75c34255" + }, + "app/.venv/lib/python3.12/site-packages/openapi_pydantic-0.6.0.dist-info/METADATA": { + "name": "openapi-pydantic", + "version": "0.6.0", + "metadata_sha256": "sha256:e46a181161c62fa24d7d3d0ff2eaabea3a7b580ad7aa9f70d1f08bd129d46f49" + }, + "app/.venv/lib/python3.12/site-packages/opentelemetry_api-1.45.1.dist-info/METADATA": { + "name": "opentelemetry-api", + "version": "1.45.1", + "metadata_sha256": "sha256:5bc71e90cb421be92a43bf5ad5b0f25dccfa2a24ddceaa2877779879962a4c9e" + }, + "app/.venv/lib/python3.12/site-packages/packaging-26.3.dist-info/METADATA": { + "name": "packaging", + "version": "26.3", + "metadata_sha256": "sha256:70fdb89fc4d4a9a043bf7372b8972bcc883fddff34ab55e9cf80d73875384763" + }, + "app/.venv/lib/python3.12/site-packages/pathable-0.6.0.dist-info/METADATA": { + "name": "pathable", + "version": "0.6.0", + "metadata_sha256": "sha256:c418727931012c2306cb8fa2726d044616c3178c1fc078ce182385dcf2b59922" + }, + "app/.venv/lib/python3.12/site-packages/platformdirs-4.13.3.dist-info/METADATA": { + "name": "platformdirs", + "version": "4.13.3", + "metadata_sha256": "sha256:3814840758f662bb98053d08f99085fb77721812258573732b092fd7f2120c30" + }, + "app/.venv/lib/python3.12/site-packages/psycopg2_binary-2.9.13.dist-info/METADATA": { + "name": "psycopg2-binary", + "version": "2.9.13", + "metadata_sha256": "sha256:a5267b4520191137e34589704162fce02cfd40efcfeb899c45187c7f6bfea7e5" + }, + "app/.venv/lib/python3.12/site-packages/py_key_value_aio-0.4.6.dist-info/METADATA": { + "name": "py-key-value-aio", + "version": "0.4.6", + "metadata_sha256": "sha256:0c1af357b841bc3862e39543faa863346c487be9f2e2ffefba009e957a256bee" + }, + "app/.venv/lib/python3.12/site-packages/pycparser-3.11.dist-info/METADATA": { + "name": "pycparser", + "version": "3.11", + "metadata_sha256": "sha256:e3a74c846648bb55f4f907284b745e2003b87b96d9c9d17a8a50cf37804541c9" + }, + "app/.venv/lib/python3.12/site-packages/pydantic-2.14.1.dist-info/METADATA": { + "name": "pydantic", + "version": "2.14.1", + "metadata_sha256": "sha256:4d4c8e8d5e6a27d5208f0d7949f25628e6747133034969d4d1399b1ad5394036" + }, + "app/.venv/lib/python3.12/site-packages/pydantic_core-2.50.1.dist-info/METADATA": { + "name": "pydantic_core", + "version": "2.50.1", + "metadata_sha256": "sha256:ae6817764b603fa2300cd31b9566ecc33476df46163c4150fffc353121a166f2" + }, + "app/.venv/lib/python3.12/site-packages/pydantic_settings-2.16.0.dist-info/METADATA": { + "name": "pydantic-settings", + "version": "2.16.0", + "metadata_sha256": "sha256:470656112388bca95fd7d27b8954fda1f11dd6579563cfb9c0ea0445d1746b77" + }, + "app/.venv/lib/python3.12/site-packages/pygments-2.21.0.dist-info/METADATA": { + "name": "Pygments", + "version": "2.21.0", + "metadata_sha256": "sha256:1dde075570136774c706bf0009183a793fe0ee262e4a5590cc6eff8453eedd43" + }, + "app/.venv/lib/python3.12/site-packages/pyjwt-2.15.1.dist-info/METADATA": { + "name": "PyJWT", + "version": "2.15.1", + "metadata_sha256": "sha256:1ea0c9f139b8c928276b3628af165955f6f764491448a6ad8f103cdcbb382da3" + }, + "app/.venv/lib/python3.12/site-packages/pyperclip-1.11.0.dist-info/METADATA": { + "name": "pyperclip", + "version": "1.11.0", + "metadata_sha256": "sha256:2493839e0751761f27d39aa6d5c5dfd1df839c45da8f328aba4ae4102868b825" + }, + "app/.venv/lib/python3.12/site-packages/python_dotenv-1.2.4.dist-info/METADATA": { + "name": "python-dotenv", + "version": "1.2.4", + "metadata_sha256": "sha256:87cfee6042412d48df1100ea7822684988c3f2b79de7a250f4717f4df3026d6f" + }, + "app/.venv/lib/python3.12/site-packages/python_multipart-0.0.32.dist-info/METADATA": { + "name": "python-multipart", + "version": "0.0.32", + "metadata_sha256": "sha256:e9d399d7dea5eddf0e4d24b5c24687a82e7e50bf2c2b30f8f8a06a64d887dd86" + }, + "app/.venv/lib/python3.12/site-packages/pyyaml-6.0.3.dist-info/METADATA": { + "name": "PyYAML", + "version": "6.0.3", + "metadata_sha256": "sha256:03c3b415ed38d09faedc49360e930769b40c58f68585e6de00e2e4916a858d34" + }, + "app/.venv/lib/python3.12/site-packages/referencing-0.37.0.dist-info/METADATA": { + "name": "referencing", + "version": "0.37.0", + "metadata_sha256": "sha256:c93b00e6ab1524fd60848376604c189a114374776475c25a31d57be47b29de6a" + }, + "app/.venv/lib/python3.12/site-packages/rich-15.0.0.dist-info/METADATA": { + "name": "rich", + "version": "15.0.0", + "metadata_sha256": "sha256:fad34fc603fac4481bf81f8dd629492fc302c0ec31909c86644751512afb2e3b" + }, + "app/.venv/lib/python3.12/site-packages/rich_rst-2.2.0.dist-info/METADATA": { + "name": "rich-rst", + "version": "2.2.0", + "metadata_sha256": "sha256:2cd1f39149e69bd94c4f1c30cb26c763e45689e6d6527b4c23afa1112c48f165" + }, + "app/.venv/lib/python3.12/site-packages/rpds_py-2026.9.1.dist-info/METADATA": { + "name": "rpds-py", + "version": "2026.9.1", + "metadata_sha256": "sha256:5d72dca2e387c8d2b4180b68ee87c15b64751e059100a6db58891ec9995445c3" + }, + "app/.venv/lib/python3.12/site-packages/secretstorage-3.5.0.dist-info/METADATA": { + "name": "SecretStorage", + "version": "3.5.0", + "metadata_sha256": "sha256:b98e3dc42ff7e9b1bacce60dac2662cd9965fad6e4469fc9483c9eb99998c367" + }, + "app/.venv/lib/python3.12/site-packages/sqlalchemy-2.1.5.dist-info/METADATA": { + "name": "SQLAlchemy", + "version": "2.1.5", + "metadata_sha256": "sha256:7f568ea71aecfb29792ccee2c8b1345825e385d54b7e7bba755e445e53b5696f" + }, + "app/.venv/lib/python3.12/site-packages/sse_starlette-3.5.0.dist-info/METADATA": { + "name": "sse-starlette", + "version": "3.5.0", + "metadata_sha256": "sha256:6dc401682bdae1a3e1f31b1c320b7f926c354643993840393875ebfc171c9014" + }, + "app/.venv/lib/python3.12/site-packages/starlette-1.8.0.dist-info/METADATA": { + "name": "starlette", + "version": "1.8.0", + "metadata_sha256": "sha256:551e8d74d290002521c655b816b27654e49922b88cb474c8d710a893099036f8" + }, + "app/.venv/lib/python3.12/site-packages/truststore-0.10.5.dist-info/METADATA": { + "name": "truststore", + "version": "0.10.5", + "metadata_sha256": "sha256:1fd496f290853214e630d96f7163d2dd916f84ebe634b58aa827d6853e8f8610" + }, + "app/.venv/lib/python3.12/site-packages/typing_extensions-4.16.0.dist-info/METADATA": { + "name": "typing_extensions", + "version": "4.16.0", + "metadata_sha256": "sha256:b05084ca1d50879865178d9fff9fabeab61bdfb1f361bfbde95421ffc8f9be46" + }, + "app/.venv/lib/python3.12/site-packages/typing_inspection-0.4.4.dist-info/METADATA": { + "name": "typing-inspection", + "version": "0.4.4", + "metadata_sha256": "sha256:bad3d9e6342ef6750cf5128ec942327b8bebdce0b6e4d6f67cb15b27ae5118da" + }, + "app/.venv/lib/python3.12/site-packages/uncalled_for-0.4.1.dist-info/METADATA": { + "name": "uncalled-for", + "version": "0.4.1", + "metadata_sha256": "sha256:45a21666ddfa8ca8d4e2423c05edaeaa7827686a3ae4fed82b24427854745c2f" + }, + "app/.venv/lib/python3.12/site-packages/uvicorn-0.54.0.dist-info/METADATA": { + "name": "uvicorn", + "version": "0.54.0", + "metadata_sha256": "sha256:9399e5ddda3d26e842d6fb5420c38b0857aac568d53badbdc224b3a21339efa8" + }, + "app/.venv/lib/python3.12/site-packages/uvloop-0.23.0.dist-info/METADATA": { + "name": "uvloop", + "version": "0.23.0", + "metadata_sha256": "sha256:fe11a50198ffd4d9f1cb20922dc638ad459d5e63e6c615b0c1c69448d3362977" + }, + "app/.venv/lib/python3.12/site-packages/watchfiles-1.3.0.dist-info/METADATA": { + "name": "watchfiles", + "version": "1.3.0", + "metadata_sha256": "sha256:1fba87d08d66f10f7515e4817abd4ac7f27abf3300cb33b7ad3f79762987a502" + }, + "app/.venv/lib/python3.12/site-packages/websockets-17.2.dist-info/METADATA": { + "name": "websockets", + "version": "17.2", + "metadata_sha256": "sha256:0d5f1279d095e7ba84ef21614af0822dc500ccb2e51b7c3a19eda7159b2dade4" + }, + "app/.venv/lib/python3.12/site-packages/hub_core-0.2.0.dist-info/METADATA": { + "name": "hub-core", + "version": "0.2.0", + "metadata_sha256": "sha256:84a59c6ea36d6d8a0b91b76e52f351a5ce6f2fd9ace8a4c887b51bab05973953" + } + }, + "package_metadata_equal_to_deployed_image": true, + "hub_core_source_hashes_equal_to_deployed_image": true, + "image_executed": false, + "image_installed_or_daemon_pulled": false, + "anonymous_protocol_only": true, + "token_retained": false, + "limitations": [ + "Selected code hashes and package inventory do not prove full application acceptance or hermetic provenance.", + "Floating dependency origins remain unknown; observed byte changes require explicit review.", + "New API behavior is not deployed or natively accepted." + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-image-c103cbf-inspection.json b/docs/changes/netkingdom-target-2026-10-17/guard-image-c103cbf-inspection.json new file mode 100644 index 00000000..6b7cf3fa --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-image-c103cbf-inspection.json @@ -0,0 +1,774 @@ +{ + "schema": "statehub.guard-image-inspection.v1", + "status": "verified-selected-public-image-bytes", + "source_commit": "c103cbf3c8bed5dba87a03e320595ddded9301a3", + "tag": "main-c103cbf", + "image_digest": "sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1", + "selected_source_hashes": { + "app/api/services/historical_projection.py": "sha256:e24e57c58f4aaa4ec9d9bf088009ac69006e53f75b9477ee53dc26c4e850b975", + "app/api/routers/workstreams.py": "sha256:9c9bf4376dd323b52109912bb3f615949e89ac02c8b88b4720f569f8565ad1d6", + "app/scripts/consistency_check.py": "sha256:1bfbc89d3ff5c621ec541fd32384083cc7dcf96a639b217d62b6fc34de238efd", + "app/api/services/forge_projection.py": "sha256:b980e62cbd85c3e7df42b01abf14354e04133374db94af6531dcd91629c3487d", + "app/migrations/versions/c4d5e6f7a8b9_inbox_feed_revision.py": "sha256:48f1730037be99b5623e878d7f20a06bec243ce27317fde81c82e16006d7b3ce", + "tmp/.ci-build-id": "sha256:97f14badea4537238f1f271813f40c4390fb6c99fbe7fc00025ee2af974901e2" + }, + "observed_files": { + "tmp/.ci-build-id": "sha256:97f14badea4537238f1f271813f40c4390fb6c99fbe7fc00025ee2af974901e2", + "tmp/hub-core/hub_core/__init__.py": "sha256:098578bae76f7d97354b8f3dfe8ddc63b15806a46d1691d70ed12d9839d69aec", + "tmp/hub-core/hub_core/conformance/__init__.py": "sha256:f7ce0a651913f157e586afd6e953b483add0dd5257ee9f2406c47e8d46ee9587", + "tmp/hub-core/hub_core/conformance/harness.py": "sha256:ca870fbbec7b7f5db6521d615fd76dfcbb9e97cbdfb037ffa993851a663b3c40", + "tmp/hub-core/hub_core/contracts/__init__.py": "sha256:ffb7a6b79ce15ddd57943bfbc40799e078c6f57c6690018237baa3f3a755ac49", + "tmp/hub-core/hub_core/contracts/helixforge_hub_extension/__init__.py": "sha256:32c095a16f777127ec0d2cd5e8373889866b81e9955d01e5adaf9503f6864da4", + "tmp/hub-core/hub_core/contracts/helixforge_hub_extension/v0_1_0/__init__.py": "sha256:e176b86b24d79c11f78ad714878bc3fca41c7821654fa766278b697360a41201", + "tmp/hub-core/hub_core/contracts/repository_navigation/__init__.py": "sha256:64912fe6673b72c3c0d8a2da28673d58bdf6f4185a1376ffe43d3735350adb60", + "tmp/hub-core/hub_core/contracts/repository_navigation/v1_0_0/__init__.py": "sha256:574cf1fee8433e0b11d9475cfbcc3837730b55f6ea1faa4920cba106d959464f", + "tmp/hub-core/hub_core/contracts/workload_projection/__init__.py": "sha256:c01198d23571442c1c3a596c7cd16be17dc1a3efdcfe3e8f9725b7dba16fc103", + "tmp/hub-core/hub_core/contracts/workload_projection/v1_0_0/__init__.py": "sha256:a9ecfecbf44893d32268288c872cdede0440d2a1373d37a47f69ba8c6431de0d", + "tmp/hub-core/hub_core/database.py": "sha256:a7704e97509433e90655b0ea22d5fa626d75b8b6470015ef8b9e5997e7a7f5ea", + "tmp/hub-core/hub_core/events.py": "sha256:c7125a242ed638a3ede29129e4ad826cd188cf76239b59a8587a40d182bbd0e7", + "tmp/hub-core/hub_core/mcp/__init__.py": "sha256:f97b25193573e56886b66f91cb8c86ef4a39f2100d709869e279e17456959859", + "tmp/hub-core/hub_core/mcp/credentials.py": "sha256:f5433d29848bd5a399a5e31695e0d908748e0a0856d26b2d691b667c50c95c34", + "tmp/hub-core/hub_core/mcp/server.py": "sha256:fc6a6de0a29ad9b6da176302a7d24e4ba987f667b6a7fb001029f00cb0d0c582", + "tmp/hub-core/hub_core/message_identity.py": "sha256:0ab996ba50f236c1342ce72ca8ae6ff28102ef41216972a745f7260e0c93fb24", + "tmp/hub-core/hub_core/migrations/__init__.py": "sha256:ccf4820e270c97fd5d4ac02f0c96362a772b8f4d1bcccc3f5e0077b77f575d36", + "tmp/hub-core/hub_core/migrations/env.py": "sha256:282e6e1a9e4a3cfdc111887f04dc5c1645307b3943a421852abe1709ce712e57", + "tmp/hub-core/hub_core/migrations/roles.py": "sha256:91e85297d296b0c4b9c78b16ae67d3a4707232d8f32b2cac2b2e84f31fa80e89", + "tmp/hub-core/hub_core/migrations/versions/0001_core_schema.py": "sha256:c65f076a7b56fb93ee67869e04d922ea396eab72a4c2d2f0dabd706c918aa081", + "tmp/hub-core/hub_core/migrations/versions/0002_runtime_ports.py": "sha256:d3ce15463841b3c13eaafdd137a65d4cf2839c0b8e8fddcb2cb2f1adbceb9f00", + "tmp/hub-core/hub_core/migrations/versions/0003_repository_navigation.py": "sha256:fb2d2cb5ed10f1760ab789ced8d43c657c1bedc29ba666231a70a18636160902", + "tmp/hub-core/hub_core/migrations/versions/0004_workload_projection.py": "sha256:87ce668bfef5cf4aaf0cfd3b48d498f2370f68e06a6e66375e446af6fbbb9c96", + "tmp/hub-core/hub_core/migrations/versions/0005_message_identity_aliases.py": "sha256:ec05d2c3cb906b78cdec4d220a7ce09264c38904c792cdad3cd1082e7eace7c0", + "tmp/hub-core/hub_core/migrations/versions/0006_outcome_outbox.py": "sha256:05effdf6f258836d1cd223f9d9fc3447d264484021d3a51cfa42517453d613e1", + "tmp/hub-core/hub_core/migrations/versions/__init__.py": "sha256:569f6d7e5cc1c17b7b1eee3eec3b82774b745d01ee1dfdf851a5c6f5c337f0bb", + "tmp/hub-core/hub_core/models/__init__.py": "sha256:c0b6de4986614a163dbb2467d15882eadbd66800478a50de4d6404198d1f773a", + "tmp/hub-core/hub_core/models/agent_message.py": "sha256:23d16eeaffe780f326b08e6c441100e6ae7b4075bbb6421734c06156a87c4375", + "tmp/hub-core/hub_core/models/base.py": "sha256:85bb40bde6f4cf8e6c5700a3a016a711fab4adff77c5eb78f89827fe28b9537b", + "tmp/hub-core/hub_core/models/capability_catalog.py": "sha256:eebbb31f264821a61662d3c9e8c7eba74f46d7f68b946e35f8127343bf2ff9c4", + "tmp/hub-core/hub_core/models/capability_request.py": "sha256:70a867c82aaa061a4e1c671b023d213032464e776226280f99e2ca192e2a6eba", + "tmp/hub-core/hub_core/models/domain.py": "sha256:ddf45c37e3c37014ddd9148be01cf104658e1601abba2a8ba96f7680cdb581b3", + "tmp/hub-core/hub_core/models/managed_repo.py": "sha256:835c5d44581daf7d7dd95325e3f7fdf0add4d529b83779ed83b5e812dcb3aa61", + "tmp/hub-core/hub_core/models/message_identity_alias.py": "sha256:d07d59cd9c9351669e8319727d08bc0e9bb7e0ee36bf8a34c0c258f0b4ea61e4", + "tmp/hub-core/hub_core/models/progress_event.py": "sha256:ee750127db2f49c5b9b94773a408f7f965d834b02e6d962220f4bc762309161f", + "tmp/hub-core/hub_core/models/tpsc.py": "sha256:cb28cbe3512486adb73c0bce633b3c542a41a64e7ec673e86a5a25ab20d94afe", + "tmp/hub-core/hub_core/routers/__init__.py": "sha256:800d1c45f597fcb4970ca7a83acd2b36016006efbdf638e14a3482a954d9046d", + "tmp/hub-core/hub_core/routers/capabilities.py": "sha256:18a403ad6ac961bc490543b698e079336f60ef9902a6cd71ef9899076660d5c0", + "tmp/hub-core/hub_core/routers/domains.py": "sha256:d4c4061d2ab0d2d6390a10f4f815deb0b93b3979345aee965b666110ba32e6e0", + "tmp/hub-core/hub_core/routers/messages.py": "sha256:903bd4f8c8ca599b606cf2229315de21097360816fcda907159dac4f48cee512", + "tmp/hub-core/hub_core/routers/policy.py": "sha256:358271263295fdebb5bcb95c3a27bd3ea456964a77bc01c3f784fb7a8754aacf", + "tmp/hub-core/hub_core/routers/progress.py": "sha256:680cf4dea00a1734d7d70ef7880acc8fd39f045521baa47f415c17934779d18a", + "tmp/hub-core/hub_core/routers/repos.py": "sha256:1bca6c9b2b5bbe172f5b935b763ac1e399b1d403cdc2c463000ae79f843257a2", + "tmp/hub-core/hub_core/routers/tpsc.py": "sha256:706815b01be1c0320bf73cf9cff3e9415c1f27b8449ee9e6fea67b12d3042fd1", + "tmp/hub-core/hub_core/runtime/__init__.py": "sha256:c522e626373407bf9bcd727dac7bb812cbdc8c3ef5bb6509a74949e5b49ab4c2", + "tmp/hub-core/hub_core/runtime/app.py": "sha256:87b077498bbe321c73139e51f7ca689fdc7963a98c4d72a5a3bbcc564f47ee76", + "tmp/hub-core/hub_core/runtime/cli.py": "sha256:98ec00f2a12911245827f515877472ae1c37cea65a42454494450ffbe7380e57", + "tmp/hub-core/hub_core/runtime/compat.py": "sha256:9f1c4575bb406ae1174da1a005ec16f44ace63768617e11164b44b4051162d0d", + "tmp/hub-core/hub_core/runtime/compat_catalogs.py": "sha256:250f61ea39cced32c8cd932c4e770ae8be54ff1cf1e257ee2c82324bde0d7a26", + "tmp/hub-core/hub_core/runtime/config.py": "sha256:009b2fc5d1f8fc390d478b01444f610ada91e5fee30534936382be2529a843fc", + "tmp/hub-core/hub_core/runtime/inbox_projection.py": "sha256:84499238654310b86f7a97f2817163ff4c4da0dfce562c677294fa3dfef7f398", + "tmp/hub-core/hub_core/runtime/migration.py": "sha256:d12731fa581c48bf58deec19405ece977c89d08993b2a2ad047cb1fd17318ea8", + "tmp/hub-core/hub_core/runtime/models.py": "sha256:367ca4aa29f59f8e3f59eab22f12782146cf623fa7ac7c22346c794b85a88185", + "tmp/hub-core/hub_core/runtime/ports.py": "sha256:ab70a401deae73389761a0e88dc8ee843df00a671fae6919b1f7eed344cfb542", + "tmp/hub-core/hub_core/runtime/postgres_store.py": "sha256:9286e7845009b66f00069d67177733dabe372d79986c33ca9b43e00dfa5a2341", + "tmp/hub-core/hub_core/runtime/repo_manager_client.py": "sha256:8fa305277c5f3ddfdbe1daf4023ce6c3cde03b5c18c1292dd6aac3fe995aabe1", + "tmp/hub-core/hub_core/runtime/repository_navigation.py": "sha256:f3503596781f3e7f7d53dd28dd3aaf563905f1398575b40c8080e2b1b9978b1e", + "tmp/hub-core/hub_core/runtime/repository_navigation_routes.py": "sha256:eab78ab418a7b542dcdcab5da023bacc65fb50520853f8d179accb2105e373cf", + "tmp/hub-core/hub_core/runtime/store.py": "sha256:2fb78f14bab8df08807322d6f6416745856d69e6001381246abbac879891858d", + "tmp/hub-core/hub_core/runtime/tables.py": "sha256:a5ff72a9c54eedcc8bb81330e62ee72578a383a1d03a1acb598c72c96cdfbe9e", + "tmp/hub-core/hub_core/runtime/validation.py": "sha256:2add804d95d5d0469d6d8d605fbd1013885da972489a017260c6fddef7b80c79", + "tmp/hub-core/hub_core/runtime/workload_projection.py": "sha256:8500260404b0c566a62e51fef63ee320d4e3dafe5e2467f44db884296b9e3bf4", + "tmp/hub-core/hub_core/runtime/workload_projection_routes.py": "sha256:5c71189b98867f2f1f7612f47ee69c0ec3ddf836b9b1c7e134b98a2be45791de", + "tmp/hub-core/hub_core/schemas/__init__.py": "sha256:dfa2ec2d125f03a532637d2fbef3058ebe1f85c515ff42a930198e164b7812f7", + "tmp/hub-core/hub_core/schemas/agent_message.py": "sha256:d6a7f40dc9a3c61be761f4d2e2c08f726fb0a423ef73e273a7cd97c69ae6c6a3", + "tmp/hub-core/hub_core/schemas/capability.py": "sha256:949c55cb1f2694de4617ad53dc9cb7bc0e72addd7b9d0f104b93d783e4edc647", + "tmp/hub-core/hub_core/schemas/doi.py": "sha256:73d675aecabd5a62ae13184494a4b9db122ad24b3132e1d0e908eef802382f36", + "tmp/hub-core/hub_core/schemas/domain.py": "sha256:872a704fea959d2e4d0ff771770a97160457282218f4748ba4f830c489543aac", + "tmp/hub-core/hub_core/schemas/managed_repo.py": "sha256:a7ab3b1ab399da81324693dcd5d3feeccb211642b10f11cd3f03c7fe6ba751d4", + "tmp/hub-core/hub_core/schemas/policy.py": "sha256:bdaef1640783ac325a050cadf214e731d7c8e5e3a35dbb8f7562d5abbd209a4c", + "tmp/hub-core/hub_core/schemas/progress_event.py": "sha256:9ac7b7fd4881d424bfe59c5001554fd7302243e8489d5e777584d11ead1db328", + "tmp/hub-core/hub_core/schemas/tpsc.py": "sha256:5640d96a7fa862a468eeb0d6da002697b1f58e4cd675a4603b91e448d4db851e", + "tmp/hub-core/hub_core/security/__init__.py": "sha256:2754e25ec0f5725c33cb0b4dff1b7d10b364ebd828e609bb5b44eee3309d2d60", + "tmp/hub-core/hub_core/security/account_reader.py": "sha256:27019616b84cf030969a8e3c0850b5ae52f336008fd9daa4c26360566e74a39b", + "tmp/hub-core/hub_core/security/audit.py": "sha256:94cb85d71f065443c6423871b59d41e929af0441c95928273caf3e38dad8125c", + "tmp/hub-core/hub_core/security/boundary.py": "sha256:a1629ac717672276f61015c83f7af6e375bbd8c1234c712dd3d225da307ae0d6", + "tmp/hub-core/hub_core/security/browser.py": "sha256:fd474ee4b9611fe8dd2c60111402c2fce67d680a7da3519b5d4a495a6b559b7a", + "tmp/hub-core/hub_core/security/config.py": "sha256:7d604f6aeebde393a371ec3e0ab174934e10808c29fb370acba031486e9c02a3", + "tmp/hub-core/hub_core/security/context.py": "sha256:1181bbf12ba86bfd5046dab2f3a22a64ee3686be6dd52ab3e843303349b13a52", + "tmp/hub-core/hub_core/security/facts.py": "sha256:3de4db38ffd3f86f4918d76f811289cd501be3c28dcba16f5088aa2a2b7529ce", + "tmp/hub-core/hub_core/security/identity.py": "sha256:d7a0bab9d59a5f342fdedc9723d818a9d2537a59c6a9415455786af748f912e9", + "tmp/hub-core/hub_core/security/policy.py": "sha256:a2370e9ea5b04b1d5a429644d7f81edb1cbe8e15214c23b16cd6f949613eebd6", + "tmp/hub-core/hub_core/utils/__init__.py": "sha256:ce4ddb30ccc4fd2c4ee59e8a3c088a12165171af02aea957f17f72cd868e1899", + "tmp/hub-core/hub_core/utils/pagination.py": "sha256:366250b85052c7aabc2a2262521d34233124ba3a41026042792f8eda706ecb4f", + "tmp/hub-core/hub_core/utils/paths.py": "sha256:988a889be74f0626ca3c27b1d6677bd4a556e35de389c060d07ab64fa1c22fc8", + "tmp/hub-core/hub_core/utils/routing.py": "sha256:c94b44c5f1ab723e123503e20e0309f28abeeabea6d51beda79247d99852ad1e", + "tmp/hub-core/hub_core/utils/slugs.py": "sha256:eda7a7d18ff21a4d949223b75a2b615a949e615f461152a9cb9a2cf74b491e2d", + "app/.venv/lib/python3.12/site-packages/hub_core/__init__.py": "sha256:098578bae76f7d97354b8f3dfe8ddc63b15806a46d1691d70ed12d9839d69aec", + "app/.venv/lib/python3.12/site-packages/hub_core/conformance/__init__.py": "sha256:f7ce0a651913f157e586afd6e953b483add0dd5257ee9f2406c47e8d46ee9587", + "app/.venv/lib/python3.12/site-packages/hub_core/conformance/harness.py": "sha256:ca870fbbec7b7f5db6521d615fd76dfcbb9e97cbdfb037ffa993851a663b3c40", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/__init__.py": "sha256:ffb7a6b79ce15ddd57943bfbc40799e078c6f57c6690018237baa3f3a755ac49", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/helixforge_hub_extension/__init__.py": "sha256:32c095a16f777127ec0d2cd5e8373889866b81e9955d01e5adaf9503f6864da4", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/helixforge_hub_extension/v0_1_0/__init__.py": "sha256:e176b86b24d79c11f78ad714878bc3fca41c7821654fa766278b697360a41201", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/repository_navigation/__init__.py": "sha256:64912fe6673b72c3c0d8a2da28673d58bdf6f4185a1376ffe43d3735350adb60", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/repository_navigation/v1_0_0/__init__.py": "sha256:574cf1fee8433e0b11d9475cfbcc3837730b55f6ea1faa4920cba106d959464f", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/workload_projection/__init__.py": "sha256:c01198d23571442c1c3a596c7cd16be17dc1a3efdcfe3e8f9725b7dba16fc103", + "app/.venv/lib/python3.12/site-packages/hub_core/contracts/workload_projection/v1_0_0/__init__.py": "sha256:a9ecfecbf44893d32268288c872cdede0440d2a1373d37a47f69ba8c6431de0d", + "app/.venv/lib/python3.12/site-packages/hub_core/database.py": "sha256:a7704e97509433e90655b0ea22d5fa626d75b8b6470015ef8b9e5997e7a7f5ea", + "app/.venv/lib/python3.12/site-packages/hub_core/events.py": "sha256:c7125a242ed638a3ede29129e4ad826cd188cf76239b59a8587a40d182bbd0e7", + "app/.venv/lib/python3.12/site-packages/hub_core/mcp/__init__.py": "sha256:f97b25193573e56886b66f91cb8c86ef4a39f2100d709869e279e17456959859", + "app/.venv/lib/python3.12/site-packages/hub_core/mcp/credentials.py": "sha256:f5433d29848bd5a399a5e31695e0d908748e0a0856d26b2d691b667c50c95c34", + "app/.venv/lib/python3.12/site-packages/hub_core/mcp/server.py": "sha256:fc6a6de0a29ad9b6da176302a7d24e4ba987f667b6a7fb001029f00cb0d0c582", + "app/.venv/lib/python3.12/site-packages/hub_core/message_identity.py": "sha256:0ab996ba50f236c1342ce72ca8ae6ff28102ef41216972a745f7260e0c93fb24", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/__init__.py": "sha256:ccf4820e270c97fd5d4ac02f0c96362a772b8f4d1bcccc3f5e0077b77f575d36", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/env.py": "sha256:282e6e1a9e4a3cfdc111887f04dc5c1645307b3943a421852abe1709ce712e57", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/roles.py": "sha256:91e85297d296b0c4b9c78b16ae67d3a4707232d8f32b2cac2b2e84f31fa80e89", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/0001_core_schema.py": "sha256:c65f076a7b56fb93ee67869e04d922ea396eab72a4c2d2f0dabd706c918aa081", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/0002_runtime_ports.py": "sha256:d3ce15463841b3c13eaafdd137a65d4cf2839c0b8e8fddcb2cb2f1adbceb9f00", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/0003_repository_navigation.py": "sha256:fb2d2cb5ed10f1760ab789ced8d43c657c1bedc29ba666231a70a18636160902", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/0004_workload_projection.py": "sha256:87ce668bfef5cf4aaf0cfd3b48d498f2370f68e06a6e66375e446af6fbbb9c96", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/0005_message_identity_aliases.py": "sha256:ec05d2c3cb906b78cdec4d220a7ce09264c38904c792cdad3cd1082e7eace7c0", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/0006_outcome_outbox.py": "sha256:05effdf6f258836d1cd223f9d9fc3447d264484021d3a51cfa42517453d613e1", + "app/.venv/lib/python3.12/site-packages/hub_core/migrations/versions/__init__.py": "sha256:569f6d7e5cc1c17b7b1eee3eec3b82774b745d01ee1dfdf851a5c6f5c337f0bb", + "app/.venv/lib/python3.12/site-packages/hub_core/models/__init__.py": "sha256:c0b6de4986614a163dbb2467d15882eadbd66800478a50de4d6404198d1f773a", + "app/.venv/lib/python3.12/site-packages/hub_core/models/agent_message.py": "sha256:23d16eeaffe780f326b08e6c441100e6ae7b4075bbb6421734c06156a87c4375", + "app/.venv/lib/python3.12/site-packages/hub_core/models/base.py": "sha256:85bb40bde6f4cf8e6c5700a3a016a711fab4adff77c5eb78f89827fe28b9537b", + "app/.venv/lib/python3.12/site-packages/hub_core/models/capability_catalog.py": "sha256:eebbb31f264821a61662d3c9e8c7eba74f46d7f68b946e35f8127343bf2ff9c4", + "app/.venv/lib/python3.12/site-packages/hub_core/models/capability_request.py": "sha256:70a867c82aaa061a4e1c671b023d213032464e776226280f99e2ca192e2a6eba", + "app/.venv/lib/python3.12/site-packages/hub_core/models/domain.py": "sha256:ddf45c37e3c37014ddd9148be01cf104658e1601abba2a8ba96f7680cdb581b3", + "app/.venv/lib/python3.12/site-packages/hub_core/models/managed_repo.py": "sha256:835c5d44581daf7d7dd95325e3f7fdf0add4d529b83779ed83b5e812dcb3aa61", + "app/.venv/lib/python3.12/site-packages/hub_core/models/message_identity_alias.py": "sha256:d07d59cd9c9351669e8319727d08bc0e9bb7e0ee36bf8a34c0c258f0b4ea61e4", + "app/.venv/lib/python3.12/site-packages/hub_core/models/progress_event.py": "sha256:ee750127db2f49c5b9b94773a408f7f965d834b02e6d962220f4bc762309161f", + "app/.venv/lib/python3.12/site-packages/hub_core/models/tpsc.py": "sha256:cb28cbe3512486adb73c0bce633b3c542a41a64e7ec673e86a5a25ab20d94afe", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/__init__.py": "sha256:800d1c45f597fcb4970ca7a83acd2b36016006efbdf638e14a3482a954d9046d", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/capabilities.py": "sha256:18a403ad6ac961bc490543b698e079336f60ef9902a6cd71ef9899076660d5c0", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/domains.py": "sha256:d4c4061d2ab0d2d6390a10f4f815deb0b93b3979345aee965b666110ba32e6e0", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/messages.py": "sha256:903bd4f8c8ca599b606cf2229315de21097360816fcda907159dac4f48cee512", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/policy.py": "sha256:358271263295fdebb5bcb95c3a27bd3ea456964a77bc01c3f784fb7a8754aacf", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/progress.py": "sha256:680cf4dea00a1734d7d70ef7880acc8fd39f045521baa47f415c17934779d18a", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/repos.py": "sha256:1bca6c9b2b5bbe172f5b935b763ac1e399b1d403cdc2c463000ae79f843257a2", + "app/.venv/lib/python3.12/site-packages/hub_core/routers/tpsc.py": "sha256:706815b01be1c0320bf73cf9cff3e9415c1f27b8449ee9e6fea67b12d3042fd1", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/__init__.py": "sha256:c522e626373407bf9bcd727dac7bb812cbdc8c3ef5bb6509a74949e5b49ab4c2", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/app.py": "sha256:87b077498bbe321c73139e51f7ca689fdc7963a98c4d72a5a3bbcc564f47ee76", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/cli.py": "sha256:98ec00f2a12911245827f515877472ae1c37cea65a42454494450ffbe7380e57", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/compat.py": "sha256:9f1c4575bb406ae1174da1a005ec16f44ace63768617e11164b44b4051162d0d", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/compat_catalogs.py": "sha256:250f61ea39cced32c8cd932c4e770ae8be54ff1cf1e257ee2c82324bde0d7a26", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/config.py": "sha256:009b2fc5d1f8fc390d478b01444f610ada91e5fee30534936382be2529a843fc", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/inbox_projection.py": "sha256:84499238654310b86f7a97f2817163ff4c4da0dfce562c677294fa3dfef7f398", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/migration.py": "sha256:d12731fa581c48bf58deec19405ece977c89d08993b2a2ad047cb1fd17318ea8", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/models.py": "sha256:367ca4aa29f59f8e3f59eab22f12782146cf623fa7ac7c22346c794b85a88185", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/ports.py": "sha256:ab70a401deae73389761a0e88dc8ee843df00a671fae6919b1f7eed344cfb542", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/postgres_store.py": "sha256:9286e7845009b66f00069d67177733dabe372d79986c33ca9b43e00dfa5a2341", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/repo_manager_client.py": "sha256:8fa305277c5f3ddfdbe1daf4023ce6c3cde03b5c18c1292dd6aac3fe995aabe1", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/repository_navigation.py": "sha256:f3503596781f3e7f7d53dd28dd3aaf563905f1398575b40c8080e2b1b9978b1e", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/repository_navigation_routes.py": "sha256:eab78ab418a7b542dcdcab5da023bacc65fb50520853f8d179accb2105e373cf", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/store.py": "sha256:2fb78f14bab8df08807322d6f6416745856d69e6001381246abbac879891858d", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/tables.py": "sha256:a5ff72a9c54eedcc8bb81330e62ee72578a383a1d03a1acb598c72c96cdfbe9e", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/validation.py": "sha256:2add804d95d5d0469d6d8d605fbd1013885da972489a017260c6fddef7b80c79", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/workload_projection.py": "sha256:8500260404b0c566a62e51fef63ee320d4e3dafe5e2467f44db884296b9e3bf4", + "app/.venv/lib/python3.12/site-packages/hub_core/runtime/workload_projection_routes.py": "sha256:5c71189b98867f2f1f7612f47ee69c0ec3ddf836b9b1c7e134b98a2be45791de", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/__init__.py": "sha256:dfa2ec2d125f03a532637d2fbef3058ebe1f85c515ff42a930198e164b7812f7", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/agent_message.py": "sha256:d6a7f40dc9a3c61be761f4d2e2c08f726fb0a423ef73e273a7cd97c69ae6c6a3", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/capability.py": "sha256:949c55cb1f2694de4617ad53dc9cb7bc0e72addd7b9d0f104b93d783e4edc647", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/doi.py": "sha256:73d675aecabd5a62ae13184494a4b9db122ad24b3132e1d0e908eef802382f36", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/domain.py": "sha256:872a704fea959d2e4d0ff771770a97160457282218f4748ba4f830c489543aac", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/managed_repo.py": "sha256:a7ab3b1ab399da81324693dcd5d3feeccb211642b10f11cd3f03c7fe6ba751d4", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/policy.py": "sha256:bdaef1640783ac325a050cadf214e731d7c8e5e3a35dbb8f7562d5abbd209a4c", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/progress_event.py": "sha256:9ac7b7fd4881d424bfe59c5001554fd7302243e8489d5e777584d11ead1db328", + "app/.venv/lib/python3.12/site-packages/hub_core/schemas/tpsc.py": "sha256:5640d96a7fa862a468eeb0d6da002697b1f58e4cd675a4603b91e448d4db851e", + "app/.venv/lib/python3.12/site-packages/hub_core/security/__init__.py": "sha256:2754e25ec0f5725c33cb0b4dff1b7d10b364ebd828e609bb5b44eee3309d2d60", + "app/.venv/lib/python3.12/site-packages/hub_core/security/account_reader.py": "sha256:27019616b84cf030969a8e3c0850b5ae52f336008fd9daa4c26360566e74a39b", + "app/.venv/lib/python3.12/site-packages/hub_core/security/audit.py": "sha256:94cb85d71f065443c6423871b59d41e929af0441c95928273caf3e38dad8125c", + "app/.venv/lib/python3.12/site-packages/hub_core/security/boundary.py": "sha256:a1629ac717672276f61015c83f7af6e375bbd8c1234c712dd3d225da307ae0d6", + "app/.venv/lib/python3.12/site-packages/hub_core/security/browser.py": "sha256:fd474ee4b9611fe8dd2c60111402c2fce67d680a7da3519b5d4a495a6b559b7a", + "app/.venv/lib/python3.12/site-packages/hub_core/security/config.py": "sha256:7d604f6aeebde393a371ec3e0ab174934e10808c29fb370acba031486e9c02a3", + "app/.venv/lib/python3.12/site-packages/hub_core/security/context.py": "sha256:1181bbf12ba86bfd5046dab2f3a22a64ee3686be6dd52ab3e843303349b13a52", + "app/.venv/lib/python3.12/site-packages/hub_core/security/facts.py": "sha256:3de4db38ffd3f86f4918d76f811289cd501be3c28dcba16f5088aa2a2b7529ce", + "app/.venv/lib/python3.12/site-packages/hub_core/security/identity.py": "sha256:d7a0bab9d59a5f342fdedc9723d818a9d2537a59c6a9415455786af748f912e9", + "app/.venv/lib/python3.12/site-packages/hub_core/security/policy.py": "sha256:a2370e9ea5b04b1d5a429644d7f81edb1cbe8e15214c23b16cd6f949613eebd6", + "app/.venv/lib/python3.12/site-packages/hub_core/utils/__init__.py": "sha256:ce4ddb30ccc4fd2c4ee59e8a3c088a12165171af02aea957f17f72cd868e1899", + "app/.venv/lib/python3.12/site-packages/hub_core/utils/pagination.py": "sha256:366250b85052c7aabc2a2262521d34233124ba3a41026042792f8eda706ecb4f", + "app/.venv/lib/python3.12/site-packages/hub_core/utils/paths.py": "sha256:988a889be74f0626ca3c27b1d6677bd4a556e35de389c060d07ab64fa1c22fc8", + "app/.venv/lib/python3.12/site-packages/hub_core/utils/routing.py": "sha256:c94b44c5f1ab723e123503e20e0309f28abeeabea6d51beda79247d99852ad1e", + "app/.venv/lib/python3.12/site-packages/hub_core/utils/slugs.py": "sha256:eda7a7d18ff21a4d949223b75a2b615a949e615f461152a9cb9a2cf74b491e2d", + "app/api/routers/workstreams.py": "sha256:9c9bf4376dd323b52109912bb3f615949e89ac02c8b88b4720f569f8565ad1d6", + "app/api/services/forge_projection.py": "sha256:b980e62cbd85c3e7df42b01abf14354e04133374db94af6531dcd91629c3487d", + "app/api/services/historical_projection.py": "sha256:e24e57c58f4aaa4ec9d9bf088009ac69006e53f75b9477ee53dc26c4e850b975", + "app/migrations/versions/c4d5e6f7a8b9_inbox_feed_revision.py": "sha256:48f1730037be99b5623e878d7f20a06bec243ce27317fde81c82e16006d7b3ce", + "app/scripts/consistency_check.py": "sha256:1bfbc89d3ff5c621ec541fd32384083cc7dcf96a639b217d62b6fc34de238efd" + }, + "layers": [ + { + "digest": "sha256:304074f06047f3dee0c586de265e0e27b577930bc80dc7f97f3829b188bc4fb0", + "compressed_bytes": 30855435, + "archive_entries": 3271, + "whiteouts": 0 + }, + { + "digest": "sha256:75b6a36c64a1cf3520fc4b4aae4739d5caa8a6a05c27835a920a61784c9c32f8", + "compressed_bytes": 1294052, + "archive_entries": 553, + "whiteouts": 0 + }, + { + "digest": "sha256:6912e23eb44595b44dc6d9882b34f305ad6f6e9667cec70b13e5dbc4f8cd97f4", + "compressed_bytes": 12121637, + "archive_entries": 1828, + "whiteouts": 0 + }, + { + "digest": "sha256:bbc5a12237474ec0b23b5051260d56d6436a24d70d9cad961adebe7a037ed813", + "compressed_bytes": 249, + "archive_entries": 8, + "whiteouts": 0 + }, + { + "digest": "sha256:e16e3995c15e64ae03e700d74eab2389f1151e6bd5d40f55faa047e9124aeb20", + "compressed_bytes": 93, + "archive_entries": 1, + "whiteouts": 0 + }, + { + "digest": "sha256:14568be832d0c877348328755de4e94cf4d0397d03f2161f6995e3b3e756e802", + "compressed_bytes": 55305356, + "archive_entries": 2898, + "whiteouts": 62 + }, + { + "digest": "sha256:bf1e1db2d1d373afe88df2f128ce08f7d271029d1c17de4d10e5e78124a6bb2d", + "compressed_bytes": 149, + "archive_entries": 2, + "whiteouts": 0 + }, + { + "digest": "sha256:cca568db8f6125ab1f5cc9404ac5cb680bd5f01aa44b2629cf2de438b91c177a", + "compressed_bytes": 939, + "archive_entries": 2, + "whiteouts": 0 + }, + { + "digest": "sha256:c7a4b7e67b1547f874baf3665689c5a71ac812dd3f4a457e88718704e3455d87", + "compressed_bytes": 35705202, + "archive_entries": 5471, + "whiteouts": 0 + }, + { + "digest": "sha256:7d941269c77dad23eb3cf2e20c329048395c423fe9757df3a6caa8fafca24255", + "compressed_bytes": 598, + "archive_entries": 3, + "whiteouts": 0 + }, + { + "digest": "sha256:2a88d6d68641dd9017cbb4c2a77c4a935a731d4ba1f2f118a62ec3105c97a960", + "compressed_bytes": 102613, + "archive_entries": 143, + "whiteouts": 0 + }, + { + "digest": "sha256:3558878fca903a25435eb78655b429261a518d3cdd69d8e27ed24a26cef6bfa5", + "compressed_bytes": 109561, + "archive_entries": 160, + "whiteouts": 0 + }, + { + "digest": "sha256:2c7101586f5978e425a539185f940607388c99304a1cfebbaf7574bec6f15273", + "compressed_bytes": 475, + "archive_entries": 2, + "whiteouts": 0 + }, + { + "digest": "sha256:59d38644e2bc333e0aa244c6ac7ef2e48d1eaa81e6134debe010e4322915fa6d", + "compressed_bytes": 243466, + "archive_entries": 181, + "whiteouts": 0 + }, + { + "digest": "sha256:52fa1200348c5b4962eb106f996f253ad7f4bd3b26cfa55b80a526398560246a", + "compressed_bytes": 1678, + "archive_entries": 7, + "whiteouts": 0 + }, + { + "digest": "sha256:82fdcd1e818c2dcee02108202c3c67a6a4c6ad59304dc8040f77dd824db82b3d", + "compressed_bytes": 36058, + "archive_entries": 7, + "whiteouts": 0 + }, + { + "digest": "sha256:085010e655b31f98dcf873b131d4a11742af387bec0a75d341058635a2f5cecb", + "compressed_bytes": 33942, + "archive_entries": 63, + "whiteouts": 0 + }, + { + "digest": "sha256:4aa7035189d4ba6594935b119c6014a27ca406f740f36ed66a586c03b547247d", + "compressed_bytes": 10803, + "archive_entries": 8, + "whiteouts": 0 + }, + { + "digest": "sha256:f7b6a72fd1110c2fb3e9e34032269dd8b47627bb2b8bdd142716a547f9a4fefe", + "compressed_bytes": 2118, + "archive_entries": 3, + "whiteouts": 0 + }, + { + "digest": "sha256:dc64ac4230f824b7ba637ebd59951abca1e9cbdcbbfc4b26f1600c0e95e7f554", + "compressed_bytes": 155207, + "archive_entries": 67, + "whiteouts": 0 + }, + { + "digest": "sha256:26abb1e017025d62034b1ea4b8c461f330c282e529bc7949788f455ed633d864", + "compressed_bytes": 2966, + "archive_entries": 7, + "whiteouts": 0 + }, + { + "digest": "sha256:4a46de9d4b0f85f756bf71e82b4e00459b9a0968013da1a92a848213448814b0", + "compressed_bytes": 539, + "archive_entries": 4, + "whiteouts": 0 + } + ], + "python_package_metadata": { + "usr/local/lib/python3.12/site-packages/pip-25.0.1.dist-info/METADATA": { + "name": "pip", + "version": "25.0.1", + "metadata_sha256": "sha256:4fa7318cf30f979db7cec45c12cbbc2b4f88a15f12eefbf59a6291d0a03af926" + }, + "usr/local/lib/python3.12/site-packages/uv-0.13.1.dist-info/METADATA": { + "name": "uv", + "version": "0.13.1", + "metadata_sha256": "sha256:3554d26fcb1db453b54bde82aa3830ddc37179f3ac4394d670361553c02d0cf2" + }, + "app/.venv/lib/python3.12/site-packages/aiofile-3.12.3.dist-info/METADATA": { + "name": "aiofile", + "version": "3.12.3", + "metadata_sha256": "sha256:faaa3115c495ac1989aa6bda262b79a6c97e056c83e04afcfc71584a59e3ceb1" + }, + "app/.venv/lib/python3.12/site-packages/alembic-1.20.0.dist-info/METADATA": { + "name": "alembic", + "version": "1.20.0", + "metadata_sha256": "sha256:bd32c118c43955c106bfa4255b2fb5ac9db410b0f7255a4cafb14b9e221ff41c" + }, + "app/.venv/lib/python3.12/site-packages/annotated_doc-0.0.5.dist-info/METADATA": { + "name": "annotated-doc", + "version": "0.0.5", + "metadata_sha256": "sha256:8c24d70c5d9153d22123353a906042fd7603df2d15c2196290b0f8a962558c46" + }, + "app/.venv/lib/python3.12/site-packages/annotated_types-0.8.0.dist-info/METADATA": { + "name": "annotated-types", + "version": "0.8.0", + "metadata_sha256": "sha256:614985b278f601b8ef863f82783b991cc3ada4b89f592eb71c7c48c5f2ef2298" + }, + "app/.venv/lib/python3.12/site-packages/anyio-4.15.1.dist-info/METADATA": { + "name": "anyio", + "version": "4.15.1", + "metadata_sha256": "sha256:043aecb571af7189e8a6c528f5d8e32545f1b2cdfaaf761d51e6d5b67ea3ca81" + }, + "app/.venv/lib/python3.12/site-packages/asyncpg-0.32.0.dist-info/METADATA": { + "name": "asyncpg", + "version": "0.32.0", + "metadata_sha256": "sha256:10c1e84f762a55c69630704e8a429793dcab1ce5edba7deadb35f40476d502c9" + }, + "app/.venv/lib/python3.12/site-packages/attrs-26.1.0.dist-info/METADATA": { + "name": "attrs", + "version": "26.1.0", + "metadata_sha256": "sha256:4cd40e690f23bf37cbcad34efd6758e062df1df07c86833f7e3ce95bf1fa38cc" + }, + "app/.venv/lib/python3.12/site-packages/authlib-1.9.1.dist-info/METADATA": { + "name": "Authlib", + "version": "1.9.1", + "metadata_sha256": "sha256:7141e57ccac936724fd004b401d0695e0ae48f32f2aee14d90259a9d4bc4fdbd" + }, + "app/.venv/lib/python3.12/site-packages/beartype-0.23.1.dist-info/METADATA": { + "name": "beartype", + "version": "0.23.1", + "metadata_sha256": "sha256:ac75ec7a0bd6407db75c5c1da887798dfd4d5d12099e299602d03baa0ba22986" + }, + "app/.venv/lib/python3.12/site-packages/cachetools-7.2.2.dist-info/METADATA": { + "name": "cachetools", + "version": "7.2.2", + "metadata_sha256": "sha256:76bbee4a06789a8c42253966988a07aff8f2f29cb1ae3ff9d6f16d661f01f2d4" + }, + "app/.venv/lib/python3.12/site-packages/caio-0.12.9.dist-info/METADATA": { + "name": "caio", + "version": "0.12.9", + "metadata_sha256": "sha256:3128051d993cbf71f589f68b0082167fe1c910b17379d27653b6945ec848c3c8" + }, + "app/.venv/lib/python3.12/site-packages/certifi-2026.7.22.dist-info/METADATA": { + "name": "certifi", + "version": "2026.7.22", + "metadata_sha256": "sha256:ef5af1638fbb23676ac3c5777dfcfc2cd9c348fe4172ed5ba3d277655b248090" + }, + "app/.venv/lib/python3.12/site-packages/cffi-2.1.1.dist-info/METADATA": { + "name": "cffi", + "version": "2.1.1", + "metadata_sha256": "sha256:558bafb9093a8e790175d9ecff9688382981d744877dad86fd6770db0f4dc918" + }, + "app/.venv/lib/python3.12/site-packages/click-8.5.0.dist-info/METADATA": { + "name": "click", + "version": "8.5.0", + "metadata_sha256": "sha256:e87bce0bd194de70dfb8e708e0a6b0483009f25611804eaf87bfeb63e6c20501" + }, + "app/.venv/lib/python3.12/site-packages/cryptography-50.0.2.dist-info/METADATA": { + "name": "cryptography", + "version": "50.0.2", + "metadata_sha256": "sha256:047cfc71226409de4318b360aef15c63a2adf609731e3dcf7fe932f14ea042ee" + }, + "app/.venv/lib/python3.12/site-packages/cyclopts-5.2.0.dist-info/METADATA": { + "name": "cyclopts", + "version": "5.2.0", + "metadata_sha256": "sha256:a1bcd1e587744ec6f5c5c64126ac03a03fc2468f7c91cd1c44572a5ac11dcb2a" + }, + "app/.venv/lib/python3.12/site-packages/dnspython-2.9.0.dist-info/METADATA": { + "name": "dnspython", + "version": "2.9.0", + "metadata_sha256": "sha256:d25dbd09b39758cd5cebe518701012a6278731986cd384fc4a7f25e78f7de929" + }, + "app/.venv/lib/python3.12/site-packages/docstring_parser-0.18.0.dist-info/METADATA": { + "name": "docstring_parser", + "version": "0.18.0", + "metadata_sha256": "sha256:cbc42027997fd4b194ae5fd064a4d1e57b92976941d0c26d369561a7c016a333" + }, + "app/.venv/lib/python3.12/site-packages/email_validator-2.3.0.dist-info/METADATA": { + "name": "email-validator", + "version": "2.3.0", + "metadata_sha256": "sha256:2a97b81eefcd856bc80b0346f47fa2d800b9a438bf8f9231ae00fe931d5c9fbc" + }, + "app/.venv/lib/python3.12/site-packages/exceptiongroup-1.3.1.dist-info/METADATA": { + "name": "exceptiongroup", + "version": "1.3.1", + "metadata_sha256": "sha256:81984a523a2f7a522ad12bea784a8bb85edec0805ebbd0fb4e350169a36dd802" + }, + "app/.venv/lib/python3.12/site-packages/fastapi-0.143.3.dist-info/METADATA": { + "name": "fastapi", + "version": "0.143.3", + "metadata_sha256": "sha256:364f68b16f489abe36d621da2fa727f774bec90916cd3325b78e422af3b59a5f" + }, + "app/.venv/lib/python3.12/site-packages/fastmcp-4.1.0.dist-info/METADATA": { + "name": "fastmcp", + "version": "4.1.0", + "metadata_sha256": "sha256:cfdcfd24ad904514087ec1735baa54df174f72f570833a16b6074887cfc51fa6" + }, + "app/.venv/lib/python3.12/site-packages/fastmcp_slim-4.1.0.dist-info/METADATA": { + "name": "fastmcp-slim", + "version": "4.1.0", + "metadata_sha256": "sha256:e8eca5fbae348ee6dcda0a0f1bf0dffa493e8d4d8763647ee48f4f871e35c998" + }, + "app/.venv/lib/python3.12/site-packages/greenlet-3.5.6.dist-info/METADATA": { + "name": "greenlet", + "version": "3.5.6", + "metadata_sha256": "sha256:b9b4cbbc1f3165e50fbc4696c433fe82b8a151fde65eede28fb6ec5efb3e1fab" + }, + "app/.venv/lib/python3.12/site-packages/griffelib-2.3.2.dist-info/METADATA": { + "name": "griffelib", + "version": "2.3.2", + "metadata_sha256": "sha256:fd24a68ed08309718d5759b8de3b90392b5804240d94834e6455be110ead34b3" + }, + "app/.venv/lib/python3.12/site-packages/h11-0.16.0.dist-info/METADATA": { + "name": "h11", + "version": "0.16.0", + "metadata_sha256": "sha256:28f326098ac09fcba79b8f180f96087c841fe2456215cb7b872a9c7d5cd19d64" + }, + "app/.venv/lib/python3.12/site-packages/httpcore-1.0.9.dist-info/METADATA": { + "name": "httpcore", + "version": "1.0.9", + "metadata_sha256": "sha256:fe2d4fda6199128978779e0cf27f3c045c531863fcdd987eacc74f3a18d41c21" + }, + "app/.venv/lib/python3.12/site-packages/httpcore2-2.13.1.dist-info/METADATA": { + "name": "httpcore2", + "version": "2.13.1", + "metadata_sha256": "sha256:37a0ea0674e98b7c3a1f99c17d9bb5457de27a0f93c8b6560c9d17d525139abb" + }, + "app/.venv/lib/python3.12/site-packages/httptools-0.9.0.dist-info/METADATA": { + "name": "httptools", + "version": "0.9.0", + "metadata_sha256": "sha256:8a743396f45465204e2b44b43cb57ec4a343c423f52604bbaf1777fd438698c9" + }, + "app/.venv/lib/python3.12/site-packages/httpx-0.28.1.dist-info/METADATA": { + "name": "httpx", + "version": "0.28.1", + "metadata_sha256": "sha256:febb9b0f8f3e80d57c8199c304f35c4336e8581d1d18d7983c92766b82793b25" + }, + "app/.venv/lib/python3.12/site-packages/httpx2-2.13.1.dist-info/METADATA": { + "name": "httpx2", + "version": "2.13.1", + "metadata_sha256": "sha256:b75b03a003b5593e000907cf7239fcc3f688b8f17db4ecff883d11221ea988fc" + }, + "app/.venv/lib/python3.12/site-packages/idna-3.20.dist-info/METADATA": { + "name": "idna", + "version": "3.20", + "metadata_sha256": "sha256:dbd8c14c1e4ca1e0c9824a6dbc7cbbf78884f38eb52d91148cd3025f671e4b85" + }, + "app/.venv/lib/python3.12/site-packages/jaraco.classes-3.4.0.dist-info/METADATA": { + "name": "jaraco.classes", + "version": "3.4.0", + "metadata_sha256": "sha256:2e6b102232edd45ae1bb8a6b4091fd40cf3201a6bb6fd4bc97c5e8cd765a44b8" + }, + "app/.venv/lib/python3.12/site-packages/jaraco_context-6.1.2.dist-info/METADATA": { + "name": "jaraco.context", + "version": "6.1.2", + "metadata_sha256": "sha256:f1b65b60aea229af54e09b17ae0036cf048fe4a6161fa2e7966a8ea5c2321491" + }, + "app/.venv/lib/python3.12/site-packages/jaraco_functools-4.6.0.dist-info/METADATA": { + "name": "jaraco.functools", + "version": "4.6.0", + "metadata_sha256": "sha256:6ed3cae5b8eef084c3c7b2385a0a8ac4c8155ab7c729212bea099bee69d5bd6c" + }, + "app/.venv/lib/python3.12/site-packages/jeepney-0.9.0.dist-info/METADATA": { + "name": "jeepney", + "version": "0.9.0", + "metadata_sha256": "sha256:b8e6c353e9aaed0ed0144029556417fda23b64f344e718331907054ba05b8c62" + }, + "app/.venv/lib/python3.12/site-packages/joserfc-1.7.5.dist-info/METADATA": { + "name": "joserfc", + "version": "1.7.5", + "metadata_sha256": "sha256:17df62bbdc7212bbcda3144e72720a62fc34bbf76c573062939120738545250f" + }, + "app/.venv/lib/python3.12/site-packages/jsonref-1.1.0.dist-info/METADATA": { + "name": "jsonref", + "version": "1.1.0", + "metadata_sha256": "sha256:f98db3890394fba23912faab86ad8f70ed564fc8c885298b636b270f28453e43" + }, + "app/.venv/lib/python3.12/site-packages/jsonschema-4.26.0.dist-info/METADATA": { + "name": "jsonschema", + "version": "4.26.0", + "metadata_sha256": "sha256:05b189866ca98a96da3934bf6b83687ced3ff85325273b77e16b705f6d8b26d2" + }, + "app/.venv/lib/python3.12/site-packages/jsonschema_path-0.5.0.dist-info/METADATA": { + "name": "jsonschema-path", + "version": "0.5.0", + "metadata_sha256": "sha256:cd7e9a4426436980f099d826dbce8f61afa6603b496385fba9a9eb0ad59cdd48" + }, + "app/.venv/lib/python3.12/site-packages/jsonschema_specifications-2025.9.1.dist-info/METADATA": { + "name": "jsonschema-specifications", + "version": "2025.9.1", + "metadata_sha256": "sha256:35abd41757f32b4ea24756920ded47b70173d77cbc052a5a6d3ab583b2e8d89d" + }, + "app/.venv/lib/python3.12/site-packages/keyring-25.7.0.dist-info/METADATA": { + "name": "keyring", + "version": "25.7.0", + "metadata_sha256": "sha256:bd54de98fede6dc3e1f3cd89b4e37c95d8842a523bdbb9e52ab40edff1837163" + }, + "app/.venv/lib/python3.12/site-packages/mako-1.4.3.dist-info/METADATA": { + "name": "Mako", + "version": "1.4.3", + "metadata_sha256": "sha256:39ea65f21e706265428ea6f2925520f419a10f0113a59318192ed38175d8838b" + }, + "app/.venv/lib/python3.12/site-packages/markdown_it_py-4.2.0.dist-info/METADATA": { + "name": "markdown-it-py", + "version": "4.2.0", + "metadata_sha256": "sha256:72c36ff516755443b1ecb61e17b2567a990230b49a504b0eb0c42d5f82448a9c" + }, + "app/.venv/lib/python3.12/site-packages/markupsafe-3.0.4.dist-info/METADATA": { + "name": "MarkupSafe", + "version": "3.0.4", + "metadata_sha256": "sha256:66767d76388ece15d49d50dafb655891ef5d868715e7128e7f7d737a70b353c4" + }, + "app/.venv/lib/python3.12/site-packages/mcp-2.3.0.dist-info/METADATA": { + "name": "mcp", + "version": "2.3.0", + "metadata_sha256": "sha256:a94577513a4fa0cb639c279c1ad6f4d49650872d45f2f4ab9bb2d9c2a505d457" + }, + "app/.venv/lib/python3.12/site-packages/mcp_types-2.3.0.dist-info/METADATA": { + "name": "mcp-types", + "version": "2.3.0", + "metadata_sha256": "sha256:eb973e8b7f53d52ab1df9d1f18854ffa84f074f6052e310089e2655961c48ca9" + }, + "app/.venv/lib/python3.12/site-packages/mdurl-0.1.2.dist-info/METADATA": { + "name": "mdurl", + "version": "0.1.2", + "metadata_sha256": "sha256:b53b29d48f499367053fda3c81e7ce27d2558380ebbf83e66023b02eb7ddd25d" + }, + "app/.venv/lib/python3.12/site-packages/more_itertools-11.2.1.dist-info/METADATA": { + "name": "more-itertools", + "version": "11.2.1", + "metadata_sha256": "sha256:8c558bfab61818450e78db4018281f8f7b22115e681cd53ae1d9d4931be54f15" + }, + "app/.venv/lib/python3.12/site-packages/nats_py-2.16.0.dist-info/METADATA": { + "name": "nats-py", + "version": "2.16.0", + "metadata_sha256": "sha256:58ddf3dd698f9026d397e5bb56a0baac723ba221d3dddae0831cfacc75c34255" + }, + "app/.venv/lib/python3.12/site-packages/openapi_pydantic-0.6.0.dist-info/METADATA": { + "name": "openapi-pydantic", + "version": "0.6.0", + "metadata_sha256": "sha256:e46a181161c62fa24d7d3d0ff2eaabea3a7b580ad7aa9f70d1f08bd129d46f49" + }, + "app/.venv/lib/python3.12/site-packages/opentelemetry_api-1.45.1.dist-info/METADATA": { + "name": "opentelemetry-api", + "version": "1.45.1", + "metadata_sha256": "sha256:5bc71e90cb421be92a43bf5ad5b0f25dccfa2a24ddceaa2877779879962a4c9e" + }, + "app/.venv/lib/python3.12/site-packages/packaging-26.3.dist-info/METADATA": { + "name": "packaging", + "version": "26.3", + "metadata_sha256": "sha256:70fdb89fc4d4a9a043bf7372b8972bcc883fddff34ab55e9cf80d73875384763" + }, + "app/.venv/lib/python3.12/site-packages/pathable-0.6.0.dist-info/METADATA": { + "name": "pathable", + "version": "0.6.0", + "metadata_sha256": "sha256:c418727931012c2306cb8fa2726d044616c3178c1fc078ce182385dcf2b59922" + }, + "app/.venv/lib/python3.12/site-packages/platformdirs-4.13.3.dist-info/METADATA": { + "name": "platformdirs", + "version": "4.13.3", + "metadata_sha256": "sha256:3814840758f662bb98053d08f99085fb77721812258573732b092fd7f2120c30" + }, + "app/.venv/lib/python3.12/site-packages/psycopg2_binary-2.9.13.dist-info/METADATA": { + "name": "psycopg2-binary", + "version": "2.9.13", + "metadata_sha256": "sha256:a5267b4520191137e34589704162fce02cfd40efcfeb899c45187c7f6bfea7e5" + }, + "app/.venv/lib/python3.12/site-packages/py_key_value_aio-0.4.6.dist-info/METADATA": { + "name": "py-key-value-aio", + "version": "0.4.6", + "metadata_sha256": "sha256:0c1af357b841bc3862e39543faa863346c487be9f2e2ffefba009e957a256bee" + }, + "app/.venv/lib/python3.12/site-packages/pycparser-3.11.dist-info/METADATA": { + "name": "pycparser", + "version": "3.11", + "metadata_sha256": "sha256:e3a74c846648bb55f4f907284b745e2003b87b96d9c9d17a8a50cf37804541c9" + }, + "app/.venv/lib/python3.12/site-packages/pydantic-2.14.1.dist-info/METADATA": { + "name": "pydantic", + "version": "2.14.1", + "metadata_sha256": "sha256:4d4c8e8d5e6a27d5208f0d7949f25628e6747133034969d4d1399b1ad5394036" + }, + "app/.venv/lib/python3.12/site-packages/pydantic_core-2.50.1.dist-info/METADATA": { + "name": "pydantic_core", + "version": "2.50.1", + "metadata_sha256": "sha256:ae6817764b603fa2300cd31b9566ecc33476df46163c4150fffc353121a166f2" + }, + "app/.venv/lib/python3.12/site-packages/pydantic_settings-2.16.0.dist-info/METADATA": { + "name": "pydantic-settings", + "version": "2.16.0", + "metadata_sha256": "sha256:470656112388bca95fd7d27b8954fda1f11dd6579563cfb9c0ea0445d1746b77" + }, + "app/.venv/lib/python3.12/site-packages/pygments-2.21.0.dist-info/METADATA": { + "name": "Pygments", + "version": "2.21.0", + "metadata_sha256": "sha256:1dde075570136774c706bf0009183a793fe0ee262e4a5590cc6eff8453eedd43" + }, + "app/.venv/lib/python3.12/site-packages/pyjwt-2.15.1.dist-info/METADATA": { + "name": "PyJWT", + "version": "2.15.1", + "metadata_sha256": "sha256:1ea0c9f139b8c928276b3628af165955f6f764491448a6ad8f103cdcbb382da3" + }, + "app/.venv/lib/python3.12/site-packages/pyperclip-1.11.0.dist-info/METADATA": { + "name": "pyperclip", + "version": "1.11.0", + "metadata_sha256": "sha256:2493839e0751761f27d39aa6d5c5dfd1df839c45da8f328aba4ae4102868b825" + }, + "app/.venv/lib/python3.12/site-packages/python_dotenv-1.2.4.dist-info/METADATA": { + "name": "python-dotenv", + "version": "1.2.4", + "metadata_sha256": "sha256:87cfee6042412d48df1100ea7822684988c3f2b79de7a250f4717f4df3026d6f" + }, + "app/.venv/lib/python3.12/site-packages/python_multipart-0.0.32.dist-info/METADATA": { + "name": "python-multipart", + "version": "0.0.32", + "metadata_sha256": "sha256:e9d399d7dea5eddf0e4d24b5c24687a82e7e50bf2c2b30f8f8a06a64d887dd86" + }, + "app/.venv/lib/python3.12/site-packages/pyyaml-6.0.3.dist-info/METADATA": { + "name": "PyYAML", + "version": "6.0.3", + "metadata_sha256": "sha256:03c3b415ed38d09faedc49360e930769b40c58f68585e6de00e2e4916a858d34" + }, + "app/.venv/lib/python3.12/site-packages/referencing-0.37.0.dist-info/METADATA": { + "name": "referencing", + "version": "0.37.0", + "metadata_sha256": "sha256:c93b00e6ab1524fd60848376604c189a114374776475c25a31d57be47b29de6a" + }, + "app/.venv/lib/python3.12/site-packages/rich-15.0.0.dist-info/METADATA": { + "name": "rich", + "version": "15.0.0", + "metadata_sha256": "sha256:fad34fc603fac4481bf81f8dd629492fc302c0ec31909c86644751512afb2e3b" + }, + "app/.venv/lib/python3.12/site-packages/rich_rst-2.2.0.dist-info/METADATA": { + "name": "rich-rst", + "version": "2.2.0", + "metadata_sha256": "sha256:2cd1f39149e69bd94c4f1c30cb26c763e45689e6d6527b4c23afa1112c48f165" + }, + "app/.venv/lib/python3.12/site-packages/rpds_py-2026.9.1.dist-info/METADATA": { + "name": "rpds-py", + "version": "2026.9.1", + "metadata_sha256": "sha256:5d72dca2e387c8d2b4180b68ee87c15b64751e059100a6db58891ec9995445c3" + }, + "app/.venv/lib/python3.12/site-packages/secretstorage-3.5.0.dist-info/METADATA": { + "name": "SecretStorage", + "version": "3.5.0", + "metadata_sha256": "sha256:b98e3dc42ff7e9b1bacce60dac2662cd9965fad6e4469fc9483c9eb99998c367" + }, + "app/.venv/lib/python3.12/site-packages/sqlalchemy-2.1.5.dist-info/METADATA": { + "name": "SQLAlchemy", + "version": "2.1.5", + "metadata_sha256": "sha256:7f568ea71aecfb29792ccee2c8b1345825e385d54b7e7bba755e445e53b5696f" + }, + "app/.venv/lib/python3.12/site-packages/sse_starlette-3.5.0.dist-info/METADATA": { + "name": "sse-starlette", + "version": "3.5.0", + "metadata_sha256": "sha256:6dc401682bdae1a3e1f31b1c320b7f926c354643993840393875ebfc171c9014" + }, + "app/.venv/lib/python3.12/site-packages/starlette-1.8.0.dist-info/METADATA": { + "name": "starlette", + "version": "1.8.0", + "metadata_sha256": "sha256:551e8d74d290002521c655b816b27654e49922b88cb474c8d710a893099036f8" + }, + "app/.venv/lib/python3.12/site-packages/truststore-0.10.5.dist-info/METADATA": { + "name": "truststore", + "version": "0.10.5", + "metadata_sha256": "sha256:1fd496f290853214e630d96f7163d2dd916f84ebe634b58aa827d6853e8f8610" + }, + "app/.venv/lib/python3.12/site-packages/typing_extensions-4.16.0.dist-info/METADATA": { + "name": "typing_extensions", + "version": "4.16.0", + "metadata_sha256": "sha256:b05084ca1d50879865178d9fff9fabeab61bdfb1f361bfbde95421ffc8f9be46" + }, + "app/.venv/lib/python3.12/site-packages/typing_inspection-0.4.4.dist-info/METADATA": { + "name": "typing-inspection", + "version": "0.4.4", + "metadata_sha256": "sha256:bad3d9e6342ef6750cf5128ec942327b8bebdce0b6e4d6f67cb15b27ae5118da" + }, + "app/.venv/lib/python3.12/site-packages/uncalled_for-0.4.1.dist-info/METADATA": { + "name": "uncalled-for", + "version": "0.4.1", + "metadata_sha256": "sha256:45a21666ddfa8ca8d4e2423c05edaeaa7827686a3ae4fed82b24427854745c2f" + }, + "app/.venv/lib/python3.12/site-packages/uvicorn-0.54.0.dist-info/METADATA": { + "name": "uvicorn", + "version": "0.54.0", + "metadata_sha256": "sha256:9399e5ddda3d26e842d6fb5420c38b0857aac568d53badbdc224b3a21339efa8" + }, + "app/.venv/lib/python3.12/site-packages/uvloop-0.23.0.dist-info/METADATA": { + "name": "uvloop", + "version": "0.23.0", + "metadata_sha256": "sha256:fe11a50198ffd4d9f1cb20922dc638ad459d5e63e6c615b0c1c69448d3362977" + }, + "app/.venv/lib/python3.12/site-packages/watchfiles-1.3.0.dist-info/METADATA": { + "name": "watchfiles", + "version": "1.3.0", + "metadata_sha256": "sha256:1fba87d08d66f10f7515e4817abd4ac7f27abf3300cb33b7ad3f79762987a502" + }, + "app/.venv/lib/python3.12/site-packages/websockets-17.2.dist-info/METADATA": { + "name": "websockets", + "version": "17.2", + "metadata_sha256": "sha256:0d5f1279d095e7ba84ef21614af0822dc500ccb2e51b7c3a19eda7159b2dade4" + }, + "app/.venv/lib/python3.12/site-packages/hub_core-0.2.0.dist-info/METADATA": { + "name": "hub-core", + "version": "0.2.0", + "metadata_sha256": "sha256:84a59c6ea36d6d8a0b91b76e52f351a5ce6f2fd9ace8a4c887b51bab05973953" + } + }, + "package_metadata_equal_to_deployed_image": true, + "hub_core_source_hashes_equal_to_deployed_image": true, + "image_executed": false, + "image_installed_or_daemon_pulled": false, + "anonymous_protocol_only": true, + "token_retained": false, + "limitations": [ + "Selected code hashes and package inventory do not prove full application acceptance or hermetic provenance.", + "Floating dependency origins remain unknown; observed byte changes require explicit review.", + "New API behavior is not deployed or natively accepted." + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/FINAL-PROPOSAL.md b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/FINAL-PROPOSAL.md new file mode 100644 index 00000000..51d5d6a5 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/FINAL-PROPOSAL.md @@ -0,0 +1,23 @@ +# Deploy the frozen-binding API guard + +Proposal **STATE-WP-0095-T10-frozen-bindings-guard-r1**, revision 1. Pending founder approval for `ADMINISTER @ realm:kubernetes/railiance01`, `activation=APPROVED`. + +The approved receiver rollout is healthy at Helm 76. Its later ordinary maintenance path exposed a separate defect: the legacy binding endpoint refreshed three frozen parent rows. All fifteen task rows and the archive bytes stayed unchanged. The original failed full-row comparison is retained; the original parent preimages were not saved and will not be guessed. + +The source fixes are published in State Hub c103cbf3c8bed5dba87a03e320595ddded9301a3. They protect the exact three bound parents and fifteen task UUIDs in the checker, repair engine and API binding endpoint. Ordinary inbound dependencies remain allowed. The installed checker is now hash-verified against that source. Its actual maintenance rerun omitted all three frozen bindings and preserved all eighteen **current** full rows. The unrelated staged brief accidentally included by the old writeback helper was restored through a forward commit; its original index/worktree state is preserved. Five real Git tests verify the corrected file-scoped commit behavior. Independent guard review passed 109 isolated cases; canonical guard tests passed 102. These are separate from new runtime acceptance. + +Promote this verified CI artifact through the owner Helm path: + +`forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1` + +Use the already frozen chart archive with SHA256 b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4, preserving release values. Its fresh server dry-run passes: eight identities, three image changes. Public read-only image inspection verifies the selected guard/receiver/migration files and CI build ID; package metadata and hub-core source hashes match the deployed image. Fresh target/schema/readiness/headroom checks pass. All are refreshed before actual execution. Floating build origins and complete application/concurrent-writer acceptance remain outside these byte checks. + +The exact upgrade is bound in proposal-metadata.json: stage the hash-verified archive in the specified owned remote directory, then use `--reuse-values --set-string image.tag= --atomic --timeout 3m`. Observe the exact new Job and owned Pods. Schema is already c4d5e6f7a8b9, and no migration file changed, but the existing migration hook and its recovery limitations still apply. + +Verify delivered digest and module hashes, API/MCP readiness, schema and full-row preservation from a fresh **current** baseline. Run the eight prepared native cases only inside rollback transactions with commit interception enforced, then compare a fresh transaction. The prepared probe helper covers all three parents, ordinary-first invalid batches and expected-task/ownership/status refusals; its actual schema and commit-interception contracts are checked without a database connection. New probes are not yet executed. Rerun the verified-client ordinary maintenance path between current hash snapshots, preserve archive bytes and unrelated staged files, and read back source/remote/Hub bindings. + +Approval includes using the current hashed rows for successor acceptance while retaining the prior parent-row mismatch as an explicit historical exception. It does not turn that failed comparison into a pass or restore its unavailable preimages. T07 and RMGR19T06 close only after the new receiving and corrected whole-pipeline checks pass with that exception recorded. All sixteen NetKingdom native target gates remain separate. + +Approval must also cover [the exact conditional recovery](RECOVERY.md): only the newly observed owned Job may be cancelled with a UID precondition; verify database connection/lock quiescence before rollback to Helm **76**. Unknown mapping or mixed state stops for attended owner recovery. Helm timeout is not an outage or Job-lifetime bound; rollback retains schema. + +Attributable EUR cost and credible loss exposure remain unpriced on the existing cluster. This needs scoped supervised approval and creates no autopilot, credential or monetary grant. diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/RECOVERY.md b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/RECOVERY.md new file mode 100644 index 00000000..7d699db3 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/RECOVERY.md @@ -0,0 +1,17 @@ +# Guard successor: conditional recovery + +Proposal STATE-WP-0095-T10-frozen-bindings-guard-r1, revision 1. + +The prior deployed release is Helm 76, with image manifest c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015 and schema c4d5e6f7a8b9. Refresh this baseline before execution. The successor's migration files are unchanged, but its existing pre-upgrade migration hook still runs. Its three-minute Helm wait does not stop the Job or bound outage, and the Job has no active deadline. + +Observe the new Job UID, creation timestamp, exact successor image, Helm release/hook ownership and owned Pod UIDs/IPs using watch_rollout.py. If Helm fails or times out with this trial Job active, revalidate all identities immediately. Approval includes deleting only this exact new Job with a UID precondition and foreground propagation, and observing its bound Pods terminate. A reused name, foreign ownership, unexpected image, unobserved UID or ambiguous mapping stops automatic recovery. No name-only or blanket deletion, finalizer removal or broad database cancellation is authorized. + +Through the existing private database-owner execution path, bind migration connections to the captured Pod/IP and start window, and verify those exact connections, transactions and locks are gone. Retain only connection-identity/state/lock-count metadata. Query text, parameters, credentials and DSNs remain private. If pooling/NAT, missing observation or access makes this mapping unknown, stop for attended database-owner recovery. Pod disappearance alone is insufficient. + +After verified quiescence, inspect actual schema and release state. If application rollback is needed, the approved prior target is **76**, retaining frozen Forge receiving support. Use the normal owner SSH path, KUBECONFIG=/etc/rancher/k3s/k3s.yaml, and: + +``` +helm -n state-hub rollback state-hub 76 --no-hooks --wait --timeout 3m +``` + +Verify image, readiness, schema, full-row hashes and remaining Job/Pod state. The database retains its additive schema; do not downgrade or invent old parent values. The verified installed client guard remains in use. Removing receiving support or reverting the client guard is outside this recovery. Unknown/mixed state stops for attended handling; a failed or rescued attempt remains a failed/refined outcome. diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/SUPERSEDED.md b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/SUPERSEDED.md new file mode 100644 index 00000000..3e611541 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/SUPERSEDED.md @@ -0,0 +1,9 @@ +Revision 1 was never approved or executed. The same proposal's current review is +[revision 2](../guard-successor-review-r2/FINAL-PROPOSAL.md). + +The original metadata and its bound digests remain unchanged. The original helper +is retained locally; its generic API-key scanner finding was a module-to-SHA256 +mapping. Revision 2 exposes the same hashes as explicit module/SHA256 records. +The published `verify_revision1_helper_preimage.py` reconstructs the original +helper bytes in memory and checks their original bound SHA256 without executing +the helper or printing source. No scanner rule or ignore list was changed. diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/exact-server-dryrun.json b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/exact-server-dryrun.json new file mode 100644 index 00000000..ce1a1f9f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/exact-server-dryrun.json @@ -0,0 +1,136 @@ +{ + "schema": "statehub.exact-reuse-values-readonly-diff.v1", + "status": "passed_images_only", + "dryrun_argv": [ + "helm", + "--kubeconfig", + "/home/worsch/.kube/config-railiance01", + "-n", + "state-hub", + "upgrade", + "state-hub", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/state-hub-0.1.0.tgz", + "--reuse-values", + "--set-string", + "image.tag=main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1", + "--dry-run=server", + "--hide-secret", + "--no-hooks", + "--timeout", + "3m" + ], + "production_mutations": false, + "hooks_executed": false, + "raw_helm_values_release_content_logs_retained": false, + "limitations": [ + "Dry-run admission/render only, not an actual image pull/migration/deployment.", + "Helm timeout does not stop a later live migration Job; exact scoped cancellation/quiescence remains required." + ], + "chart_archive_sha256": "sha256:b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4", + "stage": "exact_upgrade_server_dryrun", + "objects": [ + { + "api_version": "apps/v1", + "kind": "Deployment", + "namespace": "state-hub", + "name": "state-hub", + "intended_images": [ + "forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1" + ], + "intended_spec_sha256": "sha256:df32d106c28b270c67aa683c8a4f20b26c430b121420c4023d34d23ede0eaed9", + "baseline_object_sha256": "sha256:01e7278447f3204ec8abfd9a7b5b6be61850995b3e792fc1f97fbc3207536d69", + "intended_object_sha256": "sha256:7b7c78921b071732c8e7c4c062bdbd26787498581102ea9916b07c1f57887a73", + "changed_paths": [ + "/spec/template/spec/containers/0/image" + ] + }, + { + "api_version": "apps/v1", + "kind": "Deployment", + "namespace": "state-hub", + "name": "state-hub-mcp", + "intended_images": [ + "forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1" + ], + "intended_spec_sha256": "sha256:50ae88c8c57919bf745a772a8ff34ea7e469751a403ac39d1d01ab2e9d3a27db", + "baseline_object_sha256": "sha256:9a4376e004060a4ec2c76784fd50ec6ce05f61b3793f6458625d88122a7b8713", + "intended_object_sha256": "sha256:b78c66a3e27bca60ff4dd4f51c1bbe789a4e246be3d1e7e6fb9659ffdce80127", + "changed_paths": [ + "/spec/template/spec/containers/0/image" + ] + }, + { + "api_version": "batch/v1", + "kind": "Job", + "namespace": "state-hub", + "name": "state-hub-migrate", + "intended_images": [ + "forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1" + ], + "intended_spec_sha256": "sha256:2eb273b5e2ca5538fa1b13a8cf8cd10d259ad7cd3510bce1e86075f8c4c4a915", + "baseline_object_sha256": "sha256:6909dca9acd5e1b816491b91b6a32ef6d934e288e2d8d0d3d66fac9fe67468ec", + "intended_object_sha256": "sha256:208b52d9b958b9d4490182bda4d0da27b4a6f0961f6bf182c34ef4b640fcbb5e", + "changed_paths": [ + "/spec/template/spec/containers/0/image" + ] + }, + { + "api_version": "v1", + "kind": "ConfigMap", + "namespace": "state-hub", + "name": "state-hub-classification-allowed", + "intended_images": [], + "intended_spec_sha256": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "baseline_object_sha256": "sha256:924d16a0a6b4ba8a46b59f0990dcc2adc6dd813cf5d7d83bdb389844068d7cfd", + "intended_object_sha256": "sha256:924d16a0a6b4ba8a46b59f0990dcc2adc6dd813cf5d7d83bdb389844068d7cfd", + "changed_paths": [] + }, + { + "api_version": "v1", + "kind": "ConfigMap", + "namespace": "state-hub", + "name": "state-hub-config", + "intended_images": [], + "intended_spec_sha256": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "baseline_object_sha256": "sha256:26707b20933b4f6de78f9059c0efec6df7f0e90c8f1a67db6d2f1ac72e674560", + "intended_object_sha256": "sha256:26707b20933b4f6de78f9059c0efec6df7f0e90c8f1a67db6d2f1ac72e674560", + "changed_paths": [] + }, + { + "api_version": "v1", + "kind": "Service", + "namespace": "state-hub", + "name": "state-hub", + "intended_images": [], + "intended_spec_sha256": "sha256:da5895e6aee1f619d16c07dafd4342cf7ec8f9de0944a84979c624a4e9eea22a", + "baseline_object_sha256": "sha256:62098bbc3ef6265e072f416ecb11de85d59fce7e2e0d22b2616bd233e720dafe", + "intended_object_sha256": "sha256:62098bbc3ef6265e072f416ecb11de85d59fce7e2e0d22b2616bd233e720dafe", + "changed_paths": [] + }, + { + "api_version": "v1", + "kind": "Service", + "namespace": "state-hub", + "name": "state-hub-mcp", + "intended_images": [], + "intended_spec_sha256": "sha256:4e04175b03bcd75833109d6843e282cee79d73eae2bc85e36097264b832ba26f", + "baseline_object_sha256": "sha256:ab096d239c9cd72e6177a260d9b4d548a7d5b7c0a285c3a11b7267193e336bba", + "intended_object_sha256": "sha256:ab096d239c9cd72e6177a260d9b4d548a7d5b7c0a285c3a11b7267193e336bba", + "changed_paths": [] + }, + { + "api_version": "v1", + "kind": "ServiceAccount", + "namespace": "state-hub", + "name": "state-hub", + "intended_images": [], + "intended_spec_sha256": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "baseline_object_sha256": "sha256:750594b51a534d603f50640d02a3c4eec79cc52fe07d5f442102d37b7299adb8", + "intended_object_sha256": "sha256:750594b51a534d603f50640d02a3c4eec79cc52fe07d5f442102d37b7299adb8", + "changed_paths": [] + } + ], + "changed_object_count": 3, + "intended_diff_only_images": true, + "object_identity_set_unchanged": true +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/fresh-readonly-preflight.json b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/fresh-readonly-preflight.json new file mode 100644 index 00000000..07c885e4 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/fresh-readonly-preflight.json @@ -0,0 +1,46 @@ +{ + "schema": "state95.guard-successor-readonly-preflight.v1", + "observed_at": "2026-10-17T00:33:19.687847+00:00", + "target": "railiance01/92.205.62.239", + "node_identity_verified": true, + "kubeconfig": "/home/worsch/.kube/config-railiance01", + "helm_revision": 76, + "current_image_manifest": "sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015", + "health": { + "status": "ok", + "db": "connected", + "instance_role": "primary", + "instance_label": "railiance01", + "schema": { + "status": "ok", + "applied": "c4d5e6f7a8b9", + "expected": "c4d5e6f7a8b9" + } + }, + "headroom": { + "schema": "state-hub.release-headroom-preflight.v1", + "ok": true, + "observed_at": "2026-10-17T00:33:19.561580+00:00", + "freshness_seconds": 0, + "remaining_cpu_m": 420, + "remaining_memory_bytes": 6535979008, + "pending_unrelated_cpu_m": 0, + "api_surge_cpu_m": 100, + "mcp_surge_cpu_m": 10, + "migrate_cpu_m": 50, + "atomic": true, + "reasons": [], + "notes": [ + "Aggregate remaining millicores is not a kube-scheduler guarantee.", + "Preflight does not lower requests and does not start Helm." + ], + "hook_order": [ + "pre-upgrade migrate job (helm.sh/hook-weight -5)", + "API RollingUpdate maxSurge=1 maxUnavailable=0", + "MCP RollingUpdate maxSurge=1 maxUnavailable=0" + ] + }, + "migration_job_and_pods_absent": true, + "runtime_readback_ref": "../receiver-rollout-r4/final-runtime-check.json", + "live_changes": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/pending-decision.json b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/pending-decision.json new file mode 100644 index 00000000..316dfd6d --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/pending-decision.json @@ -0,0 +1,18 @@ +{ + "workplan_id": "79579572-8120-5d3b-aca5-dd4aff60d058", + "id": "df703266-6719-4c04-ae1b-ba9afd3bca1c", + "topic_id": null, + "title": "Review exact frozen-binding API guard successor and retained baseline exception", + "description": "Pending proposal STATE-WP-0095-T10-frozen-bindings-guard-r1 revision1 SHA25681d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932. Image main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1; frozen chart b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4. Eight-identity image-only server dry-run and explicit target/headroom/schema pass. Verified installed checker maintenance preserves all18 CURRENT rows; prior three-parent hash failures remain historical exceptions, never restored or backfilled. Requested ADMINISTER @ realm:kubernetes/railiance01 activation=APPROVED includes exact new Job conditional recovery, rollback76 after verified quiescence, current-baseline successor acceptance, unpriced cost/risk and attended stop for unknown mapping. Full review: the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/FINAL-PROPOSAL.md. No new runtime is approved or executed.", + "decision_type": "pending", + "status": "open", + "rationale": "Agent-prepared exact new-code proposal. Only the founder may resolve approval; prior receiver revision4 approval does not cover this new image.", + "decided_by": null, + "decided_at": null, + "deadline": null, + "escalation_note": null, + "superseded_by": null, + "created_at": "2026-10-17T00:37:26.205185Z", + "updated_at": "2026-10-17T00:37:26.205185Z", + "workstream_id": "79579572-8120-5d3b-aca5-dd4aff60d058" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/probe-helper-preparation-check.json b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/probe-helper-preparation-check.json new file mode 100644 index 00000000..bfd40a7e --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/probe-helper-preparation-check.json @@ -0,0 +1,7 @@ +{ + "status": "prepared-helper-contract-checked", + "actual_workplan_binding_schema_accepts_exact_three": true, + "commit_interception_checked_with_actual_unbound_AsyncSession": true, + "DB_connected": false, + "native_probes_executed": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/proposal-metadata.json b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/proposal-metadata.json new file mode 100644 index 00000000..59868071 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/proposal-metadata.json @@ -0,0 +1,103 @@ +{ + "schema": "custodian.supervised-runtime-proposal.v1", + "proposal_id": "STATE-WP-0095-T10-frozen-bindings-guard-r1", + "revision": 1, + "status": "pending_supervisor_approval_not_executed", + "prepared_at": "2026-10-17T00:37:11.095872+00:00", + "owner_task_id": "STATE-WP-0095-T10", + "owner_task_uuid": "88585c69-d9b9-5e1f-a256-6416ff71e824", + "target": "railiance01/92.205.62.239 state-hub release API/MCP and exact-new-trial migration Job", + "authority_requested": "ADMINISTER @ realm:kubernetes/railiance01 activation=APPROVED", + "source_commit": "c103cbf3c8bed5dba87a03e320595ddded9301a3", + "image": "forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1", + "image_digest": "sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1", + "chart_archive": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/state-hub-0.1.0.tgz", + "chart_sha256": "b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4", + "remote_owned_chart": "/tmp/statehub-binding-guard-b5c0663d830f/state-hub-0.1.0.tgz", + "expected_prior_helm_revision": 76, + "expected_schema": "c4d5e6f7a8b9", + "migration_files_changed_since_deployed_source": false, + "exact_upgrade_argv": [ + "ssh", + "railiance01", + "KUBECONFIG=/etc/rancher/k3s/k3s.yaml helm -n state-hub upgrade state-hub /tmp/statehub-binding-guard-b5c0663d830f/state-hub-0.1.0.tgz --reuse-values --set-string image.tag=main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1 --atomic --timeout 3m" + ], + "staging": "Create exact new private owned directory, refuse unexpected existing ownership/content, copy only frozen chart, verify remote SHA before execution and remove only owned exact archive/directory after proof.", + "readiness_refresh_required_before_execution": true, + "native_probe_cases": 8, + "verification": [ + "Delivered manifest and guard module hashes, API/MCP Ready, primary/railiance01 and expected schema.", + "Fresh CURRENT full historical-row hashes before and after; enforce rollback and commit interception for eight exact native cases, then fresh-transaction comparison including ordinary parent.", + "Verified installed local CLI guard, ordinary consistency/fast projection between current snapshots, archive bytes and unrelated staged work preserved; source/remote/Hub IDs/statuses read back." + ], + "acceptance_disposition_requested": "Use current hashed baseline for successor acceptance; retain the earlier three-parent mismatch as a historical exception, without guessed restoration or backfilling its failed result. T07/RMGR19T06 close only after new receiving and corrected pipeline pass with exception recorded.", + "conditional_recovery_included": true, + "rollback_helm_revision": 76, + "recovery_limits": "Exact observed new Job UID/image/ownership and bound Pods only; foreground UID-precondition cancellation after revalidation. Verify private owner DB connection/transaction/lock quiescence; unknown mapping/mixed state stops for attended recovery. No schema downgrade or broad backend termination.", + "cost_estimate_eur": null, + "risk_estimate_eur": null, + "cost_and_risk_disposition": "Unpriced attributable cost and credible loss/outage exposure on existing infrastructure require supervised founder acceptance. Helm timeout is not Job/outage bound.", + "autopilot_grant": false, + "bound_receipts": [ + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/FINAL-PROPOSAL.md", + "sha256": "7addca35af1973be4a2f2c1aeec658a00b581108da03e6509e645045f2767ae4" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/RECOVERY.md", + "sha256": "dc72dea7cdf519a712ee8f6d28fc6aa5667b44655d948f2c0160869383f33cef" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/native_binding_probes.py", + "sha256": "ef5c07affb15d20b4194edda68fd14b4d0fee1e9dab857e3242c3a1a1e49046f" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/probe-helper-preparation-check.json", + "sha256": "e11f48b18cdb57e1b8f2bddcf7e6ffc7473ab2ab2b031c3c1a26afae609f831c" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/watch_rollout.py", + "sha256": "a496da3c9a415ac800921ce755446be4bb55bc17e4e6b913143a5d6baf48f815" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/reuse_values_dryrun.py", + "sha256": "5e653ae8439c773b27a167464b620805055e9d820a907761ab30652e65fae200" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/exact-server-dryrun.json", + "sha256": "2bfb02130876aeb71a773585dae8b446ad5c671050ebc14d0fc7bcce86dffea5" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/fresh-readonly-preflight.json", + "sha256": "01bbdc94ebd6fb266ab21bdc0851eac6eddeafbabcd7105cce23806931ebfbce" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-image-c103cbf-inspection.json", + "sha256": "21b4ddd3fa65743bed5eae568e0c08f2d150fcecacb7949263cef06bab99a683" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-verified-client.json", + "sha256": "ee41be2d74085603abf2bfe2c91c1bb430b4ea0539a6cbf988528b18f3f5ef46" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-verified-client.json", + "sha256": "8cd8921271cd647fe40dde0f00bc55b714313426e14091397d8fd11314c5e610" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/verified-loaded-client.json", + "sha256": "0745b5df92d2533714e2a87a43c73b3b685e7bab7bcf4444f7a5fbd82dd4722f" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-projection.json", + "sha256": "c25b43575273df0e648842d447979aca1b41ade16fcdaf9f5f870024e7ca06e9" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-consistency.json", + "sha256": "fd8a7d58d9e08b4866420ad77d01fbc7c28c0c2c9610ffbe95ddc77dddd9b1a6" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/ordinary-pipeline-preservation-finding.json", + "sha256": "43d4adc0ffbf61345865eebb3f8948f82a3c33a28fd0436eccd08bc93ba973c1" + } + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/reuse_values_dryrun.py b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/reuse_values_dryrun.py new file mode 100644 index 00000000..d1ea3cba --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/reuse_values_dryrun.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +"""Read-only exact owner Helm reuse-values render/diff; no raw output retained.""" +import copy +import hashlib +import json +import os +from pathlib import Path +import re +import subprocess +import yaml +OWNER=Path('/home/worsch/state-hub') +KUBE='/home/worsch/.kube/config-railiance01' +CHART='/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/state-hub-0.1.0.tgz' +CHART_SHA256='b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4' +TAG='main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1' +HELM=['helm','--kubeconfig',KUBE,'-n','state-hub'] +DRYRUN=HELM+['upgrade','state-hub',CHART,'--reuse-values','--set-string','image.tag='+TAG, + '--dry-run=server','--hide-secret','--no-hooks','--timeout','3m'] +PUBLIC_COORDINATES={'OPENBAO_K8S_TOKEN_PATH':'/var/run/secrets/openbao/token', + 'FORGE_READ_SECRET_PATH':'platform/data/workloads/state-hub/forge-derivation', + 'FORGE_READ_SECRET_KEY':'FORGE_READ_TOKEN'} +ALLOWED={'ConfigMap','Deployment','Job','Service','ServiceAccount','Namespace','Ingress'} +LIMIT=2*1024*1024 +class Refusal(RuntimeError):pass + +def digest(obj):return 'sha256:'+hashlib.sha256(json.dumps(obj,sort_keys=True,separators=(',',':')).encode()).hexdigest() + +def parse(raw): + if len(raw)>LIMIT:raise Refusal('render_size_refused') + result=[] + for obj in yaml.safe_load_all(raw): + if not obj:continue + if not isinstance(obj,dict) or obj.get('kind') not in ALLOWED:raise Refusal('unexpected_or_secret_resource_refused') + result.append(obj) + return result + +def sections(raw): + text=raw.decode() + if '\nMANIFEST:\n' not in text:raise Refusal('helm_render_sections_unrecognized') + before,manifest=text.split('\nMANIFEST:\n',1) + manifest=manifest.split('\nNOTES:',1)[0] + hooks=before.split('\nHOOKS:\n',1)[1] if '\nHOOKS:\n' in before else '' + return parse(hooks)+parse(manifest) + +def identity(obj): + meta=obj.get('metadata') or {} + return (obj['apiVersion'],obj['kind'],meta.get('namespace') or ('' if obj['kind']=='Namespace' else 'state-hub'),meta['name']) + +def diff_paths(a,b,prefix=''): + if type(a)!=type(b):return [prefix] + if isinstance(a,dict): + paths=[] + for key in sorted(set(a)|set(b)): + path=prefix+'/'+key.replace('~','~0').replace('/','~1') + paths.extend([path] if key not in a or key not in b else diff_paths(a[key],b[key],path)) + return paths + if isinstance(a,list): + if len(a)!=len(b):return [prefix] + return [p for i,(x,y) in enumerate(zip(a,b)) for p in diff_paths(x,y,prefix+'/'+str(i))] + return [] if a==b else [prefix] + +def compare(old,new): + baseline={identity(o):o for o in old};intended={identity(o):o for o in new} + if len(baseline)!=len(old) or len(intended)!=len(new):raise Refusal('duplicate_object_identity') + rows=[] + for key in sorted(set(baseline)|set(intended)): + a=baseline.get(key);b=intended.get(key);paths=diff_paths(a,b) + images=[] + if b and b['kind'] in {'Deployment','Job'}: + spec=b.get('spec',{}).get('template',{}).get('spec',{}) + for container in (spec.get('containers',[])+spec.get('initContainers',[])): + image=container.get('image','') + if not re.fullmatch(r'forgejo\.coulomb\.social/coulomb/state-hub:main-[0-9a-f]{7}(?:@sha256:[0-9a-f]{64})?',image):raise Refusal('unexpected_image_refused') + images.append(image) + for env in container.get('env',[]): + if 'value' in env and re.search(r'PASSWORD|TOKEN|SECRET|DATABASE_URL',env.get('name',''),re.I): + if env.get('name') not in PUBLIC_COORDINATES or env['value']!=PUBLIC_COORDINATES[env['name']]:raise Refusal('literal_sensitive_env_refused') + rows.append({'api_version':key[0],'kind':key[1],'namespace':key[2],'name':key[3], + 'intended_images':images,'intended_spec_sha256':digest(b.get('spec',{})) if b else None, + 'baseline_object_sha256':digest(a) if a else None,'intended_object_sha256':digest(b) if b else None, + 'changed_paths':paths}) + image_path=re.compile(r'^/spec/template/spec/(?:initContainers|containers)/[0-9]+/image$') + only_images=all(image_path.fullmatch(p) for row in rows for p in row['changed_paths']) + return {'objects':rows,'changed_object_count':sum(bool(r['changed_paths']) for r in rows), + 'intended_diff_only_images':only_images,'object_identity_set_unchanged':set(baseline)==set(intended)} + +def command(args): + env=dict(os.environ);env['KUBECONFIG']=KUBE + p=subprocess.run(args,cwd=OWNER,env=env,capture_output=True,timeout=45) + if len(p.stdout)>LIMIT:raise Refusal('command_output_size_refused') + if p.returncode: + lower=p.stderr.decode(errors='replace').lower() + label=next((label for marker,label in [('reject-secret-last-applied','secret_annotation_policy_refused'),('forbidden','admission_or_auth_refused'),('cannot patch','patch_validation_refused'),('is invalid','resource_validation_refused'),('timeout','bounded_timeout'),('connection refused','api_unavailable')] if marker in lower),'unknown_refusal') + raise Refusal(label) + return p.stdout + +def main(): + result={'schema':'statehub.exact-reuse-values-readonly-diff.v1','status':'failed', + 'dryrun_argv':DRYRUN,'production_mutations':False,'hooks_executed':False, + 'raw_helm_values_release_content_logs_retained':False, + 'limitations':['Dry-run admission/render only, not an actual image pull/migration/deployment.', + 'Helm timeout does not stop a later live migration Job; exact scoped cancellation/quiescence remains required.']} + try: + archive=Path(CHART) + if archive.is_symlink() or not archive.is_file() or hashlib.sha256(archive.read_bytes()).hexdigest()!=CHART_SHA256:raise Refusal('reviewed_chart_archive_drift') + result['chart_archive_sha256']='sha256:'+CHART_SHA256 + nodes=json.loads(command(['kubectl','--kubeconfig',KUBE,'get','nodes','-o','json'])) + if not any(a.get('address')=='92.205.62.239' for n in nodes.get('items',[]) for a in n.get('status',{}).get('addresses',[])):raise Refusal('target_identity_refused') + result['stage']='baseline_release_manifest' + old=parse(command(HELM+['get','manifest','state-hub'])) + result['stage']='baseline_release_hooks' + old+=parse(command(HELM+['get','hooks','state-hub'])) + result['stage']='exact_upgrade_server_dryrun' + new=sections(command(DRYRUN)) + result.update(compare(old,new));result['status']='passed_images_only' if result['intended_diff_only_images'] and result['object_identity_set_unchanged'] else 'review_nonimage_delta_required' + except (Refusal,subprocess.TimeoutExpired,ValueError,yaml.YAMLError) as error: + result['error_class']=type(error).__name__ + result['error_label']=str(error) if isinstance(error,Refusal) else 'bounded_parse_or_command_failure' + print(json.dumps(result,indent=2)) + return int(result['status']!='passed_images_only') +if __name__=='__main__':raise SystemExit(main()) diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/watch_rollout.py b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/watch_rollout.py new file mode 100644 index 00000000..c680ddc5 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/watch_rollout.py @@ -0,0 +1,57 @@ +"""Observe the approved release Job and owned Pods; never mutate resources.""" +from pathlib import Path +from datetime import datetime, timezone +import json +import subprocess +import time + +BASE = Path(__file__).resolve().parent +KUBE = ['kubectl', '--kubeconfig', '/home/worsch/.kube/config-railiance01', '-n', 'state-hub'] +IMAGE = 'forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1' +def get(args): + result = subprocess.run(KUBE + args, capture_output=True, timeout=10) + if result.returncode: + return None + return json.loads(result.stdout) if result.stdout.strip() else {} + +result = {'schema': 'state95.approved-job-observation.v1', 'mutation': False, + 'started_at': datetime.now(timezone.utc).isoformat(), 'jobs': {}, 'poll_failures': 0} +deadline = time.monotonic() + 240 +while time.monotonic() < deadline: + try: + job = get(['get', 'job', 'state-hub-migrate', '--ignore-not-found', '-o', 'json']) + if job is None: + result['poll_failures'] += 1 + elif job: + meta = job['metadata'] + images = [c['image'] for c in job['spec']['template']['spec']['containers']] + if (images != [IMAGE] or meta.get('labels', {}).get('app.kubernetes.io/instance') != 'state-hub' + or meta.get('labels', {}).get('app.kubernetes.io/managed-by') != 'Helm' + or meta.get('annotations', {}).get('helm.sh/hook') != 'pre-install,pre-upgrade'): + result['unexpected_job_identity'] = True + break + entry = result['jobs'].setdefault(meta['uid'], {'uid': meta['uid'], 'name': meta['name'], + 'created_at': meta['creationTimestamp'], 'image': IMAGE, 'managed_by': 'Helm', + 'release': 'state-hub', 'hook': 'pre-install,pre-upgrade', 'pods': {}}) + entry['last_status'] = {k: job.get('status', {}).get(k) for k in ['active', 'succeeded', 'failed']} + pods = get(['get', 'pods', '-l', 'job-name=state-hub-migrate', '-o', 'json']) + if pods: + for pod in pods['items']: + owners = pod['metadata'].get('ownerReferences', []) + if not any(o['uid'] == meta['uid'] and o['kind'] == 'Job' for o in owners): + continue + entry['pods'][pod['metadata']['uid']] = {'name': pod['metadata']['name'], + 'uid': pod['metadata']['uid'], 'owner_job_uid': meta['uid'], + 'pod_ip': pod.get('status', {}).get('podIP'), 'phase': pod.get('status', {}).get('phase')} + elif result['jobs']: + result['job_absent_after_observation'] = True + (BASE / 'job-observation.json').write_text(json.dumps(result, indent=2) + '\n') + if (BASE / 'helm-return.json').exists(): + result['helm_return_observed'] = True + break + except (subprocess.TimeoutExpired, ValueError, KeyError): + result['poll_failures'] += 1 + time.sleep(0.7) +result['ended_at'] = datetime.now(timezone.utc).isoformat() +(BASE / 'job-observation.json').write_text(json.dumps(result, indent=2) + '\n') +print(json.dumps({'observed_trial_jobs': len(result['jobs']), 'mutation': False})) diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/FINAL-PROPOSAL.md b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/FINAL-PROPOSAL.md new file mode 100644 index 00000000..7daf4025 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/FINAL-PROPOSAL.md @@ -0,0 +1,25 @@ +# Deploy the frozen-binding API guard + +Proposal **STATE-WP-0095-T10-frozen-bindings-guard-r1**, revision 2. Pending founder approval for `ADMINISTER @ realm:kubernetes/railiance01`, `activation=APPROVED`. + +The approved receiver rollout is healthy at Helm 76. Its later ordinary maintenance path exposed a separate defect: the legacy binding endpoint refreshed three frozen parent rows. All fifteen task rows and the archive bytes stayed unchanged. The original failed full-row comparison is retained; the original parent preimages were not saved and will not be guessed. + +The source fixes are published in State Hub c103cbf3c8bed5dba87a03e320595ddded9301a3. They protect the exact three bound parents and fifteen task UUIDs in the checker, repair engine and API binding endpoint. Ordinary inbound dependencies remain allowed. The installed checker is now hash-verified against that source. Its actual maintenance rerun omitted all three frozen bindings and preserved all eighteen **current** full rows. The unrelated staged brief accidentally included by the old writeback helper was restored through a forward commit; its original index/worktree state is preserved. Five real Git tests verify the corrected file-scoped commit behavior. Independent guard review passed 109 isolated cases; canonical guard tests passed 102. These are separate from new runtime acceptance. + +Promote this verified CI artifact through the owner Helm path: + +`forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1` + +Use the already frozen chart archive with SHA256 b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4, preserving release values. Its fresh server dry-run passes: eight identities, three image changes. Public read-only image inspection verifies the selected guard/receiver/migration files and CI build ID; package metadata and hub-core source hashes match the deployed image. Fresh target/schema/readiness/headroom checks pass. All are refreshed before actual execution. Floating build origins and complete application/concurrent-writer acceptance remain outside these byte checks. + +The exact upgrade is bound in proposal-metadata.json: stage the hash-verified archive in the specified owned remote directory, then use `--reuse-values --set-string image.tag= --atomic --timeout 3m`. Observe the exact new Job and owned Pods. Schema is already c4d5e6f7a8b9, and no migration file changed, but the existing migration hook and its recovery limitations still apply. + +Verify delivered digest and module hashes, API/MCP readiness, schema and full-row preservation from a fresh **current** baseline. Run the eight prepared native cases only inside rollback transactions with commit interception enforced, then compare a fresh transaction. The prepared probe helper covers all three parents, ordinary-first invalid batches and expected-task/ownership/status refusals; its actual schema and commit-interception contracts are checked without a database connection. New probes are not yet executed. Rerun the verified-client ordinary maintenance path between current hash snapshots, preserve archive bytes and unrelated staged files, and read back source/remote/Hub bindings. + +Approval includes using the current hashed rows for successor acceptance while retaining the prior parent-row mismatch as an explicit historical exception. It does not turn that failed comparison into a pass or restore its unavailable preimages. T07 and RMGR19T06 close only after the new receiving and corrected whole-pipeline checks pass with that exception recorded. All sixteen NetKingdom native target gates remain separate. + +Approval must also cover [the exact conditional recovery](RECOVERY.md): only the newly observed owned Job may be cancelled with a UID precondition; verify database connection/lock quiescence before rollback to Helm **76**. Unknown mapping or mixed state stops for attended owner recovery. Helm timeout is not an outage or Job-lifetime bound; rollback retains schema. + +Attributable EUR cost and credible loss exposure remain unpriced on the existing cluster. This needs scoped supervised approval and creates no autopilot, credential or monetary grant. + +Revision 2 changes only the probe helper’s representation of verified source hashes to explicit module/SHA256 records, resolving the normal scanner’s hash-metadata false positive. Runtime image, commands, case logic, acceptance and recovery scope are unchanged. Original revision 1 and its digest remain recorded; it was never approved or executed. diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/RECOVERY.md b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/RECOVERY.md new file mode 100644 index 00000000..7d699db3 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/RECOVERY.md @@ -0,0 +1,17 @@ +# Guard successor: conditional recovery + +Proposal STATE-WP-0095-T10-frozen-bindings-guard-r1, revision 1. + +The prior deployed release is Helm 76, with image manifest c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015 and schema c4d5e6f7a8b9. Refresh this baseline before execution. The successor's migration files are unchanged, but its existing pre-upgrade migration hook still runs. Its three-minute Helm wait does not stop the Job or bound outage, and the Job has no active deadline. + +Observe the new Job UID, creation timestamp, exact successor image, Helm release/hook ownership and owned Pod UIDs/IPs using watch_rollout.py. If Helm fails or times out with this trial Job active, revalidate all identities immediately. Approval includes deleting only this exact new Job with a UID precondition and foreground propagation, and observing its bound Pods terminate. A reused name, foreign ownership, unexpected image, unobserved UID or ambiguous mapping stops automatic recovery. No name-only or blanket deletion, finalizer removal or broad database cancellation is authorized. + +Through the existing private database-owner execution path, bind migration connections to the captured Pod/IP and start window, and verify those exact connections, transactions and locks are gone. Retain only connection-identity/state/lock-count metadata. Query text, parameters, credentials and DSNs remain private. If pooling/NAT, missing observation or access makes this mapping unknown, stop for attended database-owner recovery. Pod disappearance alone is insufficient. + +After verified quiescence, inspect actual schema and release state. If application rollback is needed, the approved prior target is **76**, retaining frozen Forge receiving support. Use the normal owner SSH path, KUBECONFIG=/etc/rancher/k3s/k3s.yaml, and: + +``` +helm -n state-hub rollback state-hub 76 --no-hooks --wait --timeout 3m +``` + +Verify image, readiness, schema, full-row hashes and remaining Job/Pod state. The database retains its additive schema; do not downgrade or invent old parent values. The verified installed client guard remains in use. Removing receiving support or reverting the client guard is outside this recovery. Unknown/mixed state stops for attended handling; a failed or rescued attempt remains a failed/refined outcome. diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/exact-server-dryrun.json b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/exact-server-dryrun.json new file mode 100644 index 00000000..ce1a1f9f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/exact-server-dryrun.json @@ -0,0 +1,136 @@ +{ + "schema": "statehub.exact-reuse-values-readonly-diff.v1", + "status": "passed_images_only", + "dryrun_argv": [ + "helm", + "--kubeconfig", + "/home/worsch/.kube/config-railiance01", + "-n", + "state-hub", + "upgrade", + "state-hub", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/state-hub-0.1.0.tgz", + "--reuse-values", + "--set-string", + "image.tag=main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1", + "--dry-run=server", + "--hide-secret", + "--no-hooks", + "--timeout", + "3m" + ], + "production_mutations": false, + "hooks_executed": false, + "raw_helm_values_release_content_logs_retained": false, + "limitations": [ + "Dry-run admission/render only, not an actual image pull/migration/deployment.", + "Helm timeout does not stop a later live migration Job; exact scoped cancellation/quiescence remains required." + ], + "chart_archive_sha256": "sha256:b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4", + "stage": "exact_upgrade_server_dryrun", + "objects": [ + { + "api_version": "apps/v1", + "kind": "Deployment", + "namespace": "state-hub", + "name": "state-hub", + "intended_images": [ + "forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1" + ], + "intended_spec_sha256": "sha256:df32d106c28b270c67aa683c8a4f20b26c430b121420c4023d34d23ede0eaed9", + "baseline_object_sha256": "sha256:01e7278447f3204ec8abfd9a7b5b6be61850995b3e792fc1f97fbc3207536d69", + "intended_object_sha256": "sha256:7b7c78921b071732c8e7c4c062bdbd26787498581102ea9916b07c1f57887a73", + "changed_paths": [ + "/spec/template/spec/containers/0/image" + ] + }, + { + "api_version": "apps/v1", + "kind": "Deployment", + "namespace": "state-hub", + "name": "state-hub-mcp", + "intended_images": [ + "forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1" + ], + "intended_spec_sha256": "sha256:50ae88c8c57919bf745a772a8ff34ea7e469751a403ac39d1d01ab2e9d3a27db", + "baseline_object_sha256": "sha256:9a4376e004060a4ec2c76784fd50ec6ce05f61b3793f6458625d88122a7b8713", + "intended_object_sha256": "sha256:b78c66a3e27bca60ff4dd4f51c1bbe789a4e246be3d1e7e6fb9659ffdce80127", + "changed_paths": [ + "/spec/template/spec/containers/0/image" + ] + }, + { + "api_version": "batch/v1", + "kind": "Job", + "namespace": "state-hub", + "name": "state-hub-migrate", + "intended_images": [ + "forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1" + ], + "intended_spec_sha256": "sha256:2eb273b5e2ca5538fa1b13a8cf8cd10d259ad7cd3510bce1e86075f8c4c4a915", + "baseline_object_sha256": "sha256:6909dca9acd5e1b816491b91b6a32ef6d934e288e2d8d0d3d66fac9fe67468ec", + "intended_object_sha256": "sha256:208b52d9b958b9d4490182bda4d0da27b4a6f0961f6bf182c34ef4b640fcbb5e", + "changed_paths": [ + "/spec/template/spec/containers/0/image" + ] + }, + { + "api_version": "v1", + "kind": "ConfigMap", + "namespace": "state-hub", + "name": "state-hub-classification-allowed", + "intended_images": [], + "intended_spec_sha256": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "baseline_object_sha256": "sha256:924d16a0a6b4ba8a46b59f0990dcc2adc6dd813cf5d7d83bdb389844068d7cfd", + "intended_object_sha256": "sha256:924d16a0a6b4ba8a46b59f0990dcc2adc6dd813cf5d7d83bdb389844068d7cfd", + "changed_paths": [] + }, + { + "api_version": "v1", + "kind": "ConfigMap", + "namespace": "state-hub", + "name": "state-hub-config", + "intended_images": [], + "intended_spec_sha256": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "baseline_object_sha256": "sha256:26707b20933b4f6de78f9059c0efec6df7f0e90c8f1a67db6d2f1ac72e674560", + "intended_object_sha256": "sha256:26707b20933b4f6de78f9059c0efec6df7f0e90c8f1a67db6d2f1ac72e674560", + "changed_paths": [] + }, + { + "api_version": "v1", + "kind": "Service", + "namespace": "state-hub", + "name": "state-hub", + "intended_images": [], + "intended_spec_sha256": "sha256:da5895e6aee1f619d16c07dafd4342cf7ec8f9de0944a84979c624a4e9eea22a", + "baseline_object_sha256": "sha256:62098bbc3ef6265e072f416ecb11de85d59fce7e2e0d22b2616bd233e720dafe", + "intended_object_sha256": "sha256:62098bbc3ef6265e072f416ecb11de85d59fce7e2e0d22b2616bd233e720dafe", + "changed_paths": [] + }, + { + "api_version": "v1", + "kind": "Service", + "namespace": "state-hub", + "name": "state-hub-mcp", + "intended_images": [], + "intended_spec_sha256": "sha256:4e04175b03bcd75833109d6843e282cee79d73eae2bc85e36097264b832ba26f", + "baseline_object_sha256": "sha256:ab096d239c9cd72e6177a260d9b4d548a7d5b7c0a285c3a11b7267193e336bba", + "intended_object_sha256": "sha256:ab096d239c9cd72e6177a260d9b4d548a7d5b7c0a285c3a11b7267193e336bba", + "changed_paths": [] + }, + { + "api_version": "v1", + "kind": "ServiceAccount", + "namespace": "state-hub", + "name": "state-hub", + "intended_images": [], + "intended_spec_sha256": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", + "baseline_object_sha256": "sha256:750594b51a534d603f50640d02a3c4eec79cc52fe07d5f442102d37b7299adb8", + "intended_object_sha256": "sha256:750594b51a534d603f50640d02a3c4eec79cc52fe07d5f442102d37b7299adb8", + "changed_paths": [] + } + ], + "changed_object_count": 3, + "intended_diff_only_images": true, + "object_identity_set_unchanged": true +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/fresh-readonly-preflight.json b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/fresh-readonly-preflight.json new file mode 100644 index 00000000..07c885e4 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/fresh-readonly-preflight.json @@ -0,0 +1,46 @@ +{ + "schema": "state95.guard-successor-readonly-preflight.v1", + "observed_at": "2026-10-17T00:33:19.687847+00:00", + "target": "railiance01/92.205.62.239", + "node_identity_verified": true, + "kubeconfig": "/home/worsch/.kube/config-railiance01", + "helm_revision": 76, + "current_image_manifest": "sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015", + "health": { + "status": "ok", + "db": "connected", + "instance_role": "primary", + "instance_label": "railiance01", + "schema": { + "status": "ok", + "applied": "c4d5e6f7a8b9", + "expected": "c4d5e6f7a8b9" + } + }, + "headroom": { + "schema": "state-hub.release-headroom-preflight.v1", + "ok": true, + "observed_at": "2026-10-17T00:33:19.561580+00:00", + "freshness_seconds": 0, + "remaining_cpu_m": 420, + "remaining_memory_bytes": 6535979008, + "pending_unrelated_cpu_m": 0, + "api_surge_cpu_m": 100, + "mcp_surge_cpu_m": 10, + "migrate_cpu_m": 50, + "atomic": true, + "reasons": [], + "notes": [ + "Aggregate remaining millicores is not a kube-scheduler guarantee.", + "Preflight does not lower requests and does not start Helm." + ], + "hook_order": [ + "pre-upgrade migrate job (helm.sh/hook-weight -5)", + "API RollingUpdate maxSurge=1 maxUnavailable=0", + "MCP RollingUpdate maxSurge=1 maxUnavailable=0" + ] + }, + "migration_job_and_pods_absent": true, + "runtime_readback_ref": "../receiver-rollout-r4/final-runtime-check.json", + "live_changes": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/native_binding_probes.py b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/native_binding_probes.py new file mode 100644 index 00000000..9efa04f9 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/native_binding_probes.py @@ -0,0 +1,82 @@ +"""Prepared owner in-pod probes. Requires separate approval; commits are intercepted.""" +import asyncio,hashlib,json,logging,uuid +from pathlib import Path +logging.disable(logging.CRITICAL) +EXPECTED = [ + { + "module": "api.services.historical_projection", + "sha256": "e24e57c58f4aaa4ec9d9bf088009ac69006e53f75b9477ee53dc26c4e850b975" + }, + { + "module": "api.routers.workstreams", + "sha256": "9c9bf4376dd323b52109912bb3f615949e89ac02c8b88b4720f569f8565ad1d6" + } +] +ORDINARY='e0a7813d-c916-5e49-84b2-5e5b30441891' +class UnexpectedCommit(Exception):pass +class NoCommit: + def __init__(self,session):self.session=session;self.attempts=0 + async def execute(self,*args,**kwargs):return await self.session.execute(*args,**kwargs) + async def commit(self):self.attempts+=1;raise UnexpectedCommit() +def digest(v):return 'sha256:'+hashlib.sha256(json.dumps(v,sort_keys=True,separators=(',',':'),ensure_ascii=False).encode()).hexdigest() +async def main(): + import importlib + from sqlalchemy import text + from fastapi import HTTPException + for entry in EXPECTED: + name,pin=entry["module"],entry["sha256"] + module=importlib.import_module(name);assert hashlib.sha256(Path(module.__file__).read_bytes()).hexdigest()==pin + from api.database import async_session_factory,engine + from api.services.historical_projection import FROZEN_CLUSTER_BINDINGS + from api.routers.workstreams import sync_workplan_bindings + from api.schemas.workplan import WorkplanBindingsSync + engine.echo=False + entries=FROZEN_CLUSTER_BINDINGS;assert len(entries)==3 + parents=[v['uuid'] for v in entries];task_ids=[t['uuid'] for v in entries for t in v['tasks']];assert len(task_ids)==15 + def body(ordinary=False): + values=[dict(workplan_id=v['uuid'],repo_slug=v['repo'],filename=Path(v['path']).name,relative_path=v['path'],archived=True,status='finished') for v in entries] + if ordinary:values.insert(0,dict(workplan_id=ORDINARY,repo_slug='railiance-cluster',filename='RCLUSTER-WP-0018-keycape-original-tls-recovery.md',relative_path='workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md',archived=False,status='active')) + return values + async def snapshot(session): + result={} + for table,ids in [('workplans',parents+[ORDINARY]),('tasks',task_ids)]: + rows=(await session.execute(text('SELECT to_jsonb(row) FROM '+table+' AS row WHERE row.id=ANY(:ids) ORDER BY row.id'),{'ids':[uuid.UUID(v) for v in ids]})).scalars().all() + assert len(rows)==len(ids) and {v['id'] for v in rows}==set(ids) + result[table]=digest(rows) + return result + cases={};before=None + async with async_session_factory() as session: + try: + await session.execute(text("SET LOCAL statement_timeout='5s'"));await session.execute(text("SET LOCAL lock_timeout='1s'"));await session.execute(text("SET LOCAL idle_in_transaction_session_timeout='10s'")) + before=await snapshot(session) + for name in ['preserve-three','invalid-path-mixed','foreign-repo-mixed','missing-task-mixed','foreign-holder-mixed','nonterminal-parent-mixed','nonterminal-task-mixed','invalid-last-binding-mixed']: + nested=await session.begin_nested();proxy=NoCommit(session);outcome='unverified' + try: + values=body(ordinary=name!='preserve-three') + if name=='invalid-path-mixed':values[1]['relative_path']='workplans/incorrect.md' + if name=='foreign-repo-mixed':values[1]['repo_slug']='foreign' + if name=='missing-task-mixed':await session.execute(text('DELETE FROM tasks WHERE id=:id'),{'id':uuid.UUID(task_ids[0])}) + if name=='foreign-holder-mixed':await session.execute(text('UPDATE tasks SET workplan_id=:parent WHERE id=:id'),{'id':uuid.UUID(task_ids[0]),'parent':uuid.UUID(ORDINARY)}) + if name=='nonterminal-parent-mixed':await session.execute(text("UPDATE workplans SET status='active' WHERE id=:id"),{'id':uuid.UUID(parents[0])}) + if name=='nonterminal-task-mixed':await session.execute(text("UPDATE tasks SET status='progress' WHERE id=:id"),{'id':uuid.UUID(task_ids[0])}) + if name=='invalid-last-binding-mixed':values[-1]['archived']=False + try: + answer=await sync_workplan_bindings(WorkplanBindingsSync(bindings=values),proxy) + assert name=='preserve-three' and answer=={'updated':0,'received':3,'preserved':3} + outcome='preserved' + except HTTPException as exc: + assert name!='preserve-three' and exc.status_code==409;outcome='refused' + assert proxy.attempts==0 + finally: + await nested.rollback();session.expire_all() + restored=await snapshot(session);assert restored==before + cases[name]={'status':'passed','outcome':outcome,'commit_attempts':proxy.attempts,'rolled_back':True,'full_rows_restored':True} + finally:await session.rollback() + async with async_session_factory() as fresh: + try:after=await snapshot(fresh);assert before==after + finally:await fresh.rollback() + await engine.dispose() + print(json.dumps({'schema':'state95.native-guard-probes.v1','status':'passed','cases':cases,'before_full_row_hashes':before,'after_full_row_hashes':after,'historical_parents':3,'historical_tasks':15,'ordinary_parent_also_preserved':True,'fresh_transaction_full_rows_equal':True,'commits_performed':0,'commit_interception_enforced':True,'raw_rows_or_credentials_retained':False,'limits':['No claim of restoring pre-legacy-refresh parent preimages.','Missing actual parent/repo rows and full concurrent-writer behavior remain source-test coverage, not claimed as these native cases.']},sort_keys=True)) +if __name__=='__main__': + try:asyncio.run(main()) + except BaseException:print(json.dumps({'schema':'state95.native-guard-probes.v1','status':'refused-or-unverified','raw_rows_or_credentials_retained':False}));raise SystemExit(1) diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/pending-decision.json b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/pending-decision.json new file mode 100644 index 00000000..9b521139 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/pending-decision.json @@ -0,0 +1,18 @@ +{ + "workplan_id": "79579572-8120-5d3b-aca5-dd4aff60d058", + "id": "df703266-6719-4c04-ae1b-ba9afd3bca1c", + "topic_id": null, + "title": "Review exact frozen-binding API guard successor and retained baseline exception", + "description": "Pending proposal STATE-WP-0095-T10-frozen-bindings-guard-r1 revision2 SHA2565d0ddebc21bcb035809cc8b57f4c2e1ba8ed09204be5b965460e178a90913f1e. Image main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1; frozen chart b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4. Eight-identity image-only server dry-run and explicit target/headroom/schema pass. Verified installed checker maintenance preserves all18 CURRENT rows; prior three-parent hash failures remain historical exceptions, never restored or backfilled. Requested ADMINISTER @ realm:kubernetes/railiance01 activation=APPROVED includes exact new Job conditional recovery, rollback76 after verified quiescence, current-baseline successor acceptance, unpriced cost/risk and attended stop for unknown mapping. Full review: the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/FINAL-PROPOSAL.md. No new runtime is approved or executed. Original revision1 remains retained and unexecuted. Revision2 only represents source hashes as typed metadata after the normal scanner false positive; runtime, case logic, acceptance and recovery scope are unchanged.", + "decision_type": "pending", + "status": "open", + "rationale": "Agent-prepared exact new-code proposal. Only the founder may resolve approval; prior receiver revision4 approval does not cover this new image.", + "decided_by": null, + "decided_at": null, + "deadline": null, + "escalation_note": null, + "superseded_by": null, + "created_at": "2026-10-17T00:37:26.205185Z", + "updated_at": "2026-10-17T00:48:51.550636Z", + "workstream_id": "79579572-8120-5d3b-aca5-dd4aff60d058" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/probe-helper-preparation-check.json b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/probe-helper-preparation-check.json new file mode 100644 index 00000000..5c9d5f7f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/probe-helper-preparation-check.json @@ -0,0 +1,11 @@ +{ + "status": "prepared-helper-contract-checked", + "actual_workplan_binding_schema_accepts_exact_three": true, + "commit_interception_checked_with_actual_unbound_AsyncSession": true, + "DB_connected": false, + "native_probes_executed": false, + "revision": 2, + "expected_module_hashes_equal_revision1": true, + "probe_logic_after_hash_loading_byte_identical": true, + "syntax_checked": true +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/proposal-metadata.json b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/proposal-metadata.json new file mode 100644 index 00000000..cef1277f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/proposal-metadata.json @@ -0,0 +1,108 @@ +{ + "schema": "custodian.supervised-runtime-proposal.v1", + "proposal_id": "STATE-WP-0095-T10-frozen-bindings-guard-r1", + "revision": 2, + "status": "pending_supervisor_approval_not_executed", + "prepared_at": "2026-10-17T00:48:23.064918+00:00", + "owner_task_id": "STATE-WP-0095-T10", + "owner_task_uuid": "88585c69-d9b9-5e1f-a256-6416ff71e824", + "target": "railiance01/92.205.62.239 state-hub release API/MCP and exact-new-trial migration Job", + "authority_requested": "ADMINISTER @ realm:kubernetes/railiance01 activation=APPROVED", + "source_commit": "c103cbf3c8bed5dba87a03e320595ddded9301a3", + "image": "forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1", + "image_digest": "sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1", + "chart_archive": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/state-hub-0.1.0.tgz", + "chart_sha256": "b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4", + "remote_owned_chart": "/tmp/statehub-binding-guard-b5c0663d830f/state-hub-0.1.0.tgz", + "expected_prior_helm_revision": 76, + "expected_schema": "c4d5e6f7a8b9", + "migration_files_changed_since_deployed_source": false, + "exact_upgrade_argv": [ + "ssh", + "railiance01", + "KUBECONFIG=/etc/rancher/k3s/k3s.yaml helm -n state-hub upgrade state-hub /tmp/statehub-binding-guard-b5c0663d830f/state-hub-0.1.0.tgz --reuse-values --set-string image.tag=main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1 --atomic --timeout 3m" + ], + "staging": "Create exact new private owned directory, refuse unexpected existing ownership/content, copy only frozen chart, verify remote SHA before execution and remove only owned exact archive/directory after proof.", + "readiness_refresh_required_before_execution": true, + "native_probe_cases": 8, + "verification": [ + "Delivered manifest and guard module hashes, API/MCP Ready, primary/railiance01 and expected schema.", + "Fresh CURRENT full historical-row hashes before and after; enforce rollback and commit interception for eight exact native cases, then fresh-transaction comparison including ordinary parent.", + "Verified installed local CLI guard, ordinary consistency/fast projection between current snapshots, archive bytes and unrelated staged work preserved; source/remote/Hub IDs/statuses read back." + ], + "acceptance_disposition_requested": "Use current hashed baseline for successor acceptance; retain the earlier three-parent mismatch as a historical exception, without guessed restoration or backfilling its failed result. T07/RMGR19T06 close only after new receiving and corrected pipeline pass with exception recorded.", + "conditional_recovery_included": true, + "rollback_helm_revision": 76, + "recovery_limits": "Exact observed new Job UID/image/ownership and bound Pods only; foreground UID-precondition cancellation after revalidation. Verify private owner DB connection/transaction/lock quiescence; unknown mapping/mixed state stops for attended recovery. No schema downgrade or broad backend termination.", + "cost_estimate_eur": null, + "risk_estimate_eur": null, + "cost_and_risk_disposition": "Unpriced attributable cost and credible loss/outage exposure on existing infrastructure require supervised founder acceptance. Helm timeout is not Job/outage bound.", + "autopilot_grant": false, + "bound_receipts": [ + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/FINAL-PROPOSAL.md", + "sha256": "5ff105f0eb66e85f6d5c64a496e5f1ce7b816a32fb93351f4cd07133b9a053fd" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/RECOVERY.md", + "sha256": "dc72dea7cdf519a712ee8f6d28fc6aa5667b44655d948f2c0160869383f33cef" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/native_binding_probes.py", + "sha256": "ce492d0713c987e47eefc991a6312c1c63ed72056a597e9e28aee959d06e71d5" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/probe-helper-preparation-check.json", + "sha256": "36feaa02e17850c56685ccaf78556d12447fdeddae9c483721cd996da848f400" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/watch_rollout.py", + "sha256": "a496da3c9a415ac800921ce755446be4bb55bc17e4e6b913143a5d6baf48f815" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/reuse_values_dryrun.py", + "sha256": "5e653ae8439c773b27a167464b620805055e9d820a907761ab30652e65fae200" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/exact-server-dryrun.json", + "sha256": "2bfb02130876aeb71a773585dae8b446ad5c671050ebc14d0fc7bcce86dffea5" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/fresh-readonly-preflight.json", + "sha256": "01bbdc94ebd6fb266ab21bdc0851eac6eddeafbabcd7105cce23806931ebfbce" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-image-c103cbf-inspection.json", + "sha256": "21b4ddd3fa65743bed5eae568e0c08f2d150fcecacb7949263cef06bab99a683" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-verified-client.json", + "sha256": "ee41be2d74085603abf2bfe2c91c1bb430b4ea0539a6cbf988528b18f3f5ef46" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-verified-client.json", + "sha256": "8cd8921271cd647fe40dde0f00bc55b714313426e14091397d8fd11314c5e610" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/verified-loaded-client.json", + "sha256": "0745b5df92d2533714e2a87a43c73b3b685e7bab7bcf4444f7a5fbd82dd4722f" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-projection.json", + "sha256": "c25b43575273df0e648842d447979aca1b41ade16fcdaf9f5f870024e7ca06e9" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-consistency.json", + "sha256": "fd8a7d58d9e08b4866420ad77d01fbc7c28c0c2c9610ffbe95ddc77dddd9b1a6" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/ordinary-pipeline-preservation-finding.json", + "sha256": "43d4adc0ffbf61345865eebb3f8948f82a3c33a28fd0436eccd08bc93ba973c1" + } + ], + "supersedes": { + "revision": 1, + "sha256": "81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932", + "reason": "Explicit module/SHA256 metadata representation in probe helper; no runtime/acceptance/recovery change." + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/reuse_values_dryrun.py b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/reuse_values_dryrun.py new file mode 100644 index 00000000..d1ea3cba --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/reuse_values_dryrun.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +"""Read-only exact owner Helm reuse-values render/diff; no raw output retained.""" +import copy +import hashlib +import json +import os +from pathlib import Path +import re +import subprocess +import yaml +OWNER=Path('/home/worsch/state-hub') +KUBE='/home/worsch/.kube/config-railiance01' +CHART='/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/state-hub-0.1.0.tgz' +CHART_SHA256='b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4' +TAG='main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1' +HELM=['helm','--kubeconfig',KUBE,'-n','state-hub'] +DRYRUN=HELM+['upgrade','state-hub',CHART,'--reuse-values','--set-string','image.tag='+TAG, + '--dry-run=server','--hide-secret','--no-hooks','--timeout','3m'] +PUBLIC_COORDINATES={'OPENBAO_K8S_TOKEN_PATH':'/var/run/secrets/openbao/token', + 'FORGE_READ_SECRET_PATH':'platform/data/workloads/state-hub/forge-derivation', + 'FORGE_READ_SECRET_KEY':'FORGE_READ_TOKEN'} +ALLOWED={'ConfigMap','Deployment','Job','Service','ServiceAccount','Namespace','Ingress'} +LIMIT=2*1024*1024 +class Refusal(RuntimeError):pass + +def digest(obj):return 'sha256:'+hashlib.sha256(json.dumps(obj,sort_keys=True,separators=(',',':')).encode()).hexdigest() + +def parse(raw): + if len(raw)>LIMIT:raise Refusal('render_size_refused') + result=[] + for obj in yaml.safe_load_all(raw): + if not obj:continue + if not isinstance(obj,dict) or obj.get('kind') not in ALLOWED:raise Refusal('unexpected_or_secret_resource_refused') + result.append(obj) + return result + +def sections(raw): + text=raw.decode() + if '\nMANIFEST:\n' not in text:raise Refusal('helm_render_sections_unrecognized') + before,manifest=text.split('\nMANIFEST:\n',1) + manifest=manifest.split('\nNOTES:',1)[0] + hooks=before.split('\nHOOKS:\n',1)[1] if '\nHOOKS:\n' in before else '' + return parse(hooks)+parse(manifest) + +def identity(obj): + meta=obj.get('metadata') or {} + return (obj['apiVersion'],obj['kind'],meta.get('namespace') or ('' if obj['kind']=='Namespace' else 'state-hub'),meta['name']) + +def diff_paths(a,b,prefix=''): + if type(a)!=type(b):return [prefix] + if isinstance(a,dict): + paths=[] + for key in sorted(set(a)|set(b)): + path=prefix+'/'+key.replace('~','~0').replace('/','~1') + paths.extend([path] if key not in a or key not in b else diff_paths(a[key],b[key],path)) + return paths + if isinstance(a,list): + if len(a)!=len(b):return [prefix] + return [p for i,(x,y) in enumerate(zip(a,b)) for p in diff_paths(x,y,prefix+'/'+str(i))] + return [] if a==b else [prefix] + +def compare(old,new): + baseline={identity(o):o for o in old};intended={identity(o):o for o in new} + if len(baseline)!=len(old) or len(intended)!=len(new):raise Refusal('duplicate_object_identity') + rows=[] + for key in sorted(set(baseline)|set(intended)): + a=baseline.get(key);b=intended.get(key);paths=diff_paths(a,b) + images=[] + if b and b['kind'] in {'Deployment','Job'}: + spec=b.get('spec',{}).get('template',{}).get('spec',{}) + for container in (spec.get('containers',[])+spec.get('initContainers',[])): + image=container.get('image','') + if not re.fullmatch(r'forgejo\.coulomb\.social/coulomb/state-hub:main-[0-9a-f]{7}(?:@sha256:[0-9a-f]{64})?',image):raise Refusal('unexpected_image_refused') + images.append(image) + for env in container.get('env',[]): + if 'value' in env and re.search(r'PASSWORD|TOKEN|SECRET|DATABASE_URL',env.get('name',''),re.I): + if env.get('name') not in PUBLIC_COORDINATES or env['value']!=PUBLIC_COORDINATES[env['name']]:raise Refusal('literal_sensitive_env_refused') + rows.append({'api_version':key[0],'kind':key[1],'namespace':key[2],'name':key[3], + 'intended_images':images,'intended_spec_sha256':digest(b.get('spec',{})) if b else None, + 'baseline_object_sha256':digest(a) if a else None,'intended_object_sha256':digest(b) if b else None, + 'changed_paths':paths}) + image_path=re.compile(r'^/spec/template/spec/(?:initContainers|containers)/[0-9]+/image$') + only_images=all(image_path.fullmatch(p) for row in rows for p in row['changed_paths']) + return {'objects':rows,'changed_object_count':sum(bool(r['changed_paths']) for r in rows), + 'intended_diff_only_images':only_images,'object_identity_set_unchanged':set(baseline)==set(intended)} + +def command(args): + env=dict(os.environ);env['KUBECONFIG']=KUBE + p=subprocess.run(args,cwd=OWNER,env=env,capture_output=True,timeout=45) + if len(p.stdout)>LIMIT:raise Refusal('command_output_size_refused') + if p.returncode: + lower=p.stderr.decode(errors='replace').lower() + label=next((label for marker,label in [('reject-secret-last-applied','secret_annotation_policy_refused'),('forbidden','admission_or_auth_refused'),('cannot patch','patch_validation_refused'),('is invalid','resource_validation_refused'),('timeout','bounded_timeout'),('connection refused','api_unavailable')] if marker in lower),'unknown_refusal') + raise Refusal(label) + return p.stdout + +def main(): + result={'schema':'statehub.exact-reuse-values-readonly-diff.v1','status':'failed', + 'dryrun_argv':DRYRUN,'production_mutations':False,'hooks_executed':False, + 'raw_helm_values_release_content_logs_retained':False, + 'limitations':['Dry-run admission/render only, not an actual image pull/migration/deployment.', + 'Helm timeout does not stop a later live migration Job; exact scoped cancellation/quiescence remains required.']} + try: + archive=Path(CHART) + if archive.is_symlink() or not archive.is_file() or hashlib.sha256(archive.read_bytes()).hexdigest()!=CHART_SHA256:raise Refusal('reviewed_chart_archive_drift') + result['chart_archive_sha256']='sha256:'+CHART_SHA256 + nodes=json.loads(command(['kubectl','--kubeconfig',KUBE,'get','nodes','-o','json'])) + if not any(a.get('address')=='92.205.62.239' for n in nodes.get('items',[]) for a in n.get('status',{}).get('addresses',[])):raise Refusal('target_identity_refused') + result['stage']='baseline_release_manifest' + old=parse(command(HELM+['get','manifest','state-hub'])) + result['stage']='baseline_release_hooks' + old+=parse(command(HELM+['get','hooks','state-hub'])) + result['stage']='exact_upgrade_server_dryrun' + new=sections(command(DRYRUN)) + result.update(compare(old,new));result['status']='passed_images_only' if result['intended_diff_only_images'] and result['object_identity_set_unchanged'] else 'review_nonimage_delta_required' + except (Refusal,subprocess.TimeoutExpired,ValueError,yaml.YAMLError) as error: + result['error_class']=type(error).__name__ + result['error_label']=str(error) if isinstance(error,Refusal) else 'bounded_parse_or_command_failure' + print(json.dumps(result,indent=2)) + return int(result['status']!='passed_images_only') +if __name__=='__main__':raise SystemExit(main()) diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/revision1-preimage-reconstruction.json b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/revision1-preimage-reconstruction.json new file mode 100644 index 00000000..bb800b31 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/revision1-preimage-reconstruction.json @@ -0,0 +1,6 @@ +{ + "status": "original_draft_bytes_reconstructed_in_memory", + "original_helper_sha256": "ef5c07affb15d20b4194edda68fd14b4d0fee1e9dab857e3242c3a1a1e49046f", + "native_probes_executed": false, + "source_or_private_values_printed": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/verify_revision1_helper_preimage.py b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/verify_revision1_helper_preimage.py new file mode 100644 index 00000000..7870a50c --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/verify_revision1_helper_preimage.py @@ -0,0 +1,28 @@ +"""Reconstruct the unexecuted draft's bytes in memory from published revision 2. + +This audits the retained original proposal digest without executing a probe or +printing source. Only the source-hash metadata representation was refined. +""" +from pathlib import Path +import ast +import hashlib +import json + +base = Path(__file__).resolve().parent +source = (base / 'native_binding_probes.py').read_text() +assignment = next(n for n in ast.parse(source).body if isinstance(n, ast.Assign) + and any(isinstance(t, ast.Name) and t.id == 'EXPECTED' for t in n.targets)) +records = ast.literal_eval(assignment.value) +lines = source.splitlines() +lines[assignment.lineno - 1:assignment.end_lineno] = [ + 'EXPECTED={' + ','.join(repr(r['module']) + ':' + repr(r['sha256']) for r in records) + '}'] +original = ('\n'.join(lines) + '\n').replace( + ' for entry in EXPECTED:\n name,pin=entry["module"],entry["sha256"]', + ' for name,pin in EXPECTED.items():') +digest = hashlib.sha256(original.encode()).hexdigest() +assert digest == 'ef5c07affb15d20b4194edda68fd14b4d0fee1e9dab857e3242c3a1a1e49046f' +result = {'status': 'original_draft_bytes_reconstructed_in_memory', + 'original_helper_sha256': digest, 'native_probes_executed': False, + 'source_or_private_values_printed': False} +(base / 'revision1-preimage-reconstruction.json').write_text(json.dumps(result, indent=2) + '\n') +print(json.dumps(result)) diff --git a/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/watch_rollout.py b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/watch_rollout.py new file mode 100644 index 00000000..c680ddc5 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/watch_rollout.py @@ -0,0 +1,57 @@ +"""Observe the approved release Job and owned Pods; never mutate resources.""" +from pathlib import Path +from datetime import datetime, timezone +import json +import subprocess +import time + +BASE = Path(__file__).resolve().parent +KUBE = ['kubectl', '--kubeconfig', '/home/worsch/.kube/config-railiance01', '-n', 'state-hub'] +IMAGE = 'forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1' +def get(args): + result = subprocess.run(KUBE + args, capture_output=True, timeout=10) + if result.returncode: + return None + return json.loads(result.stdout) if result.stdout.strip() else {} + +result = {'schema': 'state95.approved-job-observation.v1', 'mutation': False, + 'started_at': datetime.now(timezone.utc).isoformat(), 'jobs': {}, 'poll_failures': 0} +deadline = time.monotonic() + 240 +while time.monotonic() < deadline: + try: + job = get(['get', 'job', 'state-hub-migrate', '--ignore-not-found', '-o', 'json']) + if job is None: + result['poll_failures'] += 1 + elif job: + meta = job['metadata'] + images = [c['image'] for c in job['spec']['template']['spec']['containers']] + if (images != [IMAGE] or meta.get('labels', {}).get('app.kubernetes.io/instance') != 'state-hub' + or meta.get('labels', {}).get('app.kubernetes.io/managed-by') != 'Helm' + or meta.get('annotations', {}).get('helm.sh/hook') != 'pre-install,pre-upgrade'): + result['unexpected_job_identity'] = True + break + entry = result['jobs'].setdefault(meta['uid'], {'uid': meta['uid'], 'name': meta['name'], + 'created_at': meta['creationTimestamp'], 'image': IMAGE, 'managed_by': 'Helm', + 'release': 'state-hub', 'hook': 'pre-install,pre-upgrade', 'pods': {}}) + entry['last_status'] = {k: job.get('status', {}).get(k) for k in ['active', 'succeeded', 'failed']} + pods = get(['get', 'pods', '-l', 'job-name=state-hub-migrate', '-o', 'json']) + if pods: + for pod in pods['items']: + owners = pod['metadata'].get('ownerReferences', []) + if not any(o['uid'] == meta['uid'] and o['kind'] == 'Job' for o in owners): + continue + entry['pods'][pod['metadata']['uid']] = {'name': pod['metadata']['name'], + 'uid': pod['metadata']['uid'], 'owner_job_uid': meta['uid'], + 'pod_ip': pod.get('status', {}).get('podIP'), 'phase': pod.get('status', {}).get('phase')} + elif result['jobs']: + result['job_absent_after_observation'] = True + (BASE / 'job-observation.json').write_text(json.dumps(result, indent=2) + '\n') + if (BASE / 'helm-return.json').exists(): + result['helm_return_observed'] = True + break + except (subprocess.TimeoutExpired, ValueError, KeyError): + result['poll_failures'] += 1 + time.sleep(0.7) +result['ended_at'] = datetime.now(timezone.utc).isoformat() +(BASE / 'job-observation.json').write_text(json.dumps(result, indent=2) + '\n') +print(json.dumps({'observed_trial_jobs': len(result['jobs']), 'mutation': False})) diff --git a/docs/changes/netkingdom-target-2026-10-17/inspect_guard_image.py b/docs/changes/netkingdom-target-2026-10-17/inspect_guard_image.py new file mode 100644 index 00000000..f7584cff --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/inspect_guard_image.py @@ -0,0 +1,59 @@ +"""Resolve and inspect public guard image bytes; no pull, install or execution.""" +from pathlib import Path,PurePosixPath +import argparse,hashlib,io,json,re,tarfile,time,urllib.request,urllib.parse +p=argparse.ArgumentParser();p.add_argument('--commit',required=True);a=p.parse_args();assert re.fullmatch('[0-9a-f]{40}',a.commit) +here=Path(__file__).resolve().parent;owner=Path('/home/worsch/state-hub');short=a.commit[:7] +host='https://forgejo.coulomb.social';base='/v2/coulomb/state-hub/';deadline=time.monotonic()+180 +class NoRedirect(urllib.request.HTTPRedirectHandler): + def redirect_request(self,*args,**kwargs):raise RuntimeError('redirect-refused') +opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect) +def get(path,limit,token=None,accept=None): + assert time.monotonic() --gate-sha256 `. + Without `--execute`, the helper only checks seven preimages. Execution applies + precisely the frozen seven-file source patch, verifies exact postimages and + unchanged index, and records `source-application.json`. It does not allocate, + complete tasks, commit, publish, change Cluster source or call the Hub. + Its applied source will become the repo-local CLI's registrar implementation; + do not describe source application as an inactive copy. +3. Rerun canonical focused tests using Repo Manager's venv and exact paths: + `tests/test_cluster_frozen_history.py`, `tests/test_historical_sync_validation.py`, + `tests/test_historical_sources.py`, `tests/test_custodian_legacy_identity.py`. + Expected 47 passes. Record exact source/import hashes. Root owns the read-only + actual Cluster allocator preview and its seven expected assignments/two-file + comparison. No Cluster execute/write belongs to this source integration lane. +4. After both receiving and canonical test/preview facts pass, apply + `T05-conditional-completion.patch` against the exact frozen WP19 postimage. + T04 stays done for preparation, T05 changes wait→done for receiving-gated source + admission, T06 stays wait for actual ordinary Cluster publication/preservation. + The exact proposed postimage is `RMGR-WP-0019.conditional-completion.md`. + This is conditional future text, not evidence already delivered by this agent. +5. Use the normal managed Repo Manager identifier path for missing **own WP19** + T04/T05/T06 UUIDs before source publication; preview must show only those three + task fields in that workplan, with no other allocations or migrations. Preserve + existing WP19 parent/T01–T03 UUIDs and scanner WP21 content exactly. Stop on + unexpected pending changes. Root handles Cluster's separate seven fields. +6. Stage and commit only the frozen seven paths, with WP19's reviewed completion + and normal three managed task identifiers. Normal secret/generated-only hooks + remain enabled. If a guard refuses, retain its result and review the cause; + do not bypass or weaken it. Preserve every unrelated dirty/staged source and + index entry. This lane has no production TLS/custody/consumer action. +7. Publish using the exact repo-local command: + `/home/worsch/repo-manager/.venv/bin/rmgr sync --path /home/worsch/repo-manager --push`. + A process exit 0 or `pending_push` is not success. Require `status=applied`, + primary/railiance01, expected commit equals derived commit, and zero unexpected + refusals/retirements. Read back origin HEAD/main and exact own WP19 UUID/IDs, + statuses and dependency edges. Expected workplan active, T01–T05 done, T06 wait. + Keep source/application, publication and actual Cluster acceptance receipts + separate. No general canonical syntax/grandfathering rule has changed. +8. Only the root coordinator proceeds with ordinary Cluster owner publication, + reviewed seven-field managed allocation, dirty-source preservation and all + 18 row/three archive preservation checks. T06 cannot become done from this + source-only publication. Fence Cluster sync and restore the prior registrar + refusal before any later receiver rollback that removes support. + +No global CLI installation, direct Hub UUID repair, broad retirement, historical +file rename/rewriting, credential retrieval, native recovery, TLS/trust assent, +private admission or whole NetKingdom target acceptance is in this lane. diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.conditional-completion.md b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.conditional-completion.md new file mode 100644 index 00000000..bc38cae1 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.conditional-completion.md @@ -0,0 +1,238 @@ +--- +id: RMGR-WP-0019 +type: workplan +title: "Admit exact historical source views after receiving preservation support" +domain: infotech +repo: repo-manager +status: active +owner: codex +created: "2026-10-04" +updated: "2026-10-17" +flavor: implementation +depends_on: [] +state_hub_workstream_id: "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab" +--- + +## Goal + +Unblock normal authoritative registration of the exact closed Activity legacy +source views and Custodian retired ADHOC source after receiving preserves their +existing records. Preserve every legacy source byte, label and UUID; do not +expand canonical syntax or the general grandfathering rules. CUST-WP-0077 owns +cross-owner coordination with STATE-WP-0095. + +## Review exact historical receiving contract + +```task +id: RMGR-WP-0019-T01 +status: done +priority: high +state_hub_task_id: "d78a622e-39f9-5923-b4e1-f70fdc17fb42" +``` + +Seven Activity sources yield four existing parents/64 closed bound tasks; +three split views repeat the archived parent. One Custodian retired source keeps +its existing parent/task IDs. Earlier /tmp/activity-core-bound-history-write.py +is superseded and must not be applied: registrar bypass alone would admit an +unsupported receiving projection. RMGR-WP-0014/0015 are finished and do not own +this new implementation demand; this workplan is not residual. + +## Enable exact frozen registrar exceptions after receiving deployment + +```task +id: RMGR-WP-0019-T02 +status: done +priority: high +depends_on: [STATE-WP-0095-T03] +state_hub_task_id: "95240c81-1805-5365-9b35-d238621a16bf" +``` + +Prepared code permits only source paths with reviewed full SHA256 digests in +repo_manager/historical_sources.py. Strict conformance scans retain their legacy +findings. Unknown/missing/altered source refuses before allocation. Source UUIDs +are neither changed nor allocated for these histories. Receiving and registrar +manifests must remain identical. Apply helper requires a deployment receipt. + +## Run normal owner sync and verify preserved identities + +```task +id: RMGR-WP-0019-T03 +status: done +priority: high +depends_on: [RMGR-WP-0019-T02] +state_hub_task_id: "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d" +``` + +Use rmgr sync --path --push. No deep-check repair or direct hub UUID +patch substitutes for receiving. Historical unrelated stale projections are not +retirement-authorized by this workplan. Feed receipts back to STATE-WP-0095-T04. + +## Offline evidence, 2026-10-04 + +Prepared registrar suite: 38 focused cases passed (identifiers, registrar, +Custodian legacy identity and exact frozen source cases). Read-only execute=False +against both current owning repos accepted exact histories without source writes. +Implementation is staged; deployment gate is unresolved. + +## Approved deployment and actual registrar verification, 2026-10-04 + +STATE-WP-0095-T03 returned verified main-5dd3df9 / Helm revision72. +Global task-holder refusal passed inside the delivered API against the retired +Custodian parent, with transaction rollback and no committed probe. Five +historical parents/65 tasks retained their entire row snapshots. The gated +three-file registrar patch committed as c41d36c2ef8930628221ef36ec81d8b5d2145ed6; +38 actual owning-source cases passed and Repo Manager primary sync applied. + +Normal owner sync admitted all exact frozen histories without changing their +source bytes, UUIDs, parent ownership or row content. Custodian receiving +applied. Activity receiving refused only three empty duplicate projections +that would be retired; no retirement acknowledgement was issued. Registrar +allocated four missing IDs in ordinary Activity ad-hoc sources through its +normal path; frozen historical source files stayed unchanged. T03 remains wait +for explicit disposition and bounded receiving support under STATE-WP-0095-T04 +(decision91b7c633-a66f-5d43-9f4b-6565aefb9356). +Evidence: docs/evidence/2026-10-04-historical-registrar-verification.json. + +## Ungated T03 preparation, 2026-10-06 + +Re-ran the registrar suite at 8a47a5c (registrar source unchanged since +c41d36c2): 89 focused registrar/identity/historical cases and the full suite +(226) passed. Read-only hub check: the three refused projections are +683724d9 (custodian-wp-0003), 644017c7 (custodian-wp-0003a) and a5806df9 +(custodian-wp-0003b), each with zero tasks; every custodian-WP-0003* source +file binds parent b4eb45a9, which holds the tasks and must not be retired. +Added repo_manager.retirement_disposition, a read-only check that an Activity +expected_retirement_uuids set equals exactly those three empty projections and +excludes the preserved parent. It authorizes nothing; retirement stays with +Activity receiving under STATE-WP-0095-T04. + +## Activity disposition received, 2026-10-06 + +activity-core returned the exact expected_retirement_uuids (message 17ba4201, +evidence activity-core 941fac0, ACTIVITY-WP-0045): 683724d9, 644017c7, +a5806df9. repo_manager.retirement_disposition accepted the set: it equals the +three projections the 2026-10-04 run refused, each holds zero tasks, and it +excludes preserved parent b4eb45a9. Nothing was applied. T03 stays wait: its +acceptance needs a successful Activity owner sync with receipts, which can run +only after the founder decides 91b7c633 and STATE-WP-0095-T04 retires exactly +this set in a reviewed live rollout. Then re-run rmgr sync --path +~/activity-core --push and feed the receipt back to STATE-WP-0095-T04. + +## Post-retirement owner sync attempt, 2026-10-06 + +State Hub reported decision 91b7c633 resolved, main-968a811 / Helm rev 74 +deployed, and Activity reconcile at 67a92d2 retiring exactly the three empty +projections (3 retired, 0 created, 0 refused; 4 historical parents / 64 tasks +unchanged). Evidence: state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. +`rmgr sync --path ~/activity-core --push` stopped before reconciliation with +status pending_commit: uncommitted `state_hub_workstream_id` / `state_hub_task_id` +writeback in activity-core workplans/ACTIVITY-WP-0045-stale-historical-projection-disposition.md +(plus WORK-RECORDS.md). No hub request was made. Repo Manager does not commit in +activity-core; T03 stays wait until Activity Core commits and the sync re-runs. + +Re-run 2026-10-06 08:42Z after Activity Core committed the writeback (e809fb2): +status applied, created 0 / updated 45 (ACTIVITY-WP only) / retired 0 / refused 0, +no task changes, notes preserve custodian-WP-0001..0004 UUIDs; hub shows 4 parents, +64 tasks. Not closed: historical parent b4eb45a9 (custodian-WP-0003, source +`status: archived`, evidence snapshot archived) now reads `finished` in the hub, +updated 08:42:03Z during this sync. Needs State Hub review before T03 closes. + +Closed 2026-10-06: State Hub traced the b4eb45a9 status change to its own C-04 +check, which ran once per file. The custodian-WP-0003a/b/c split views share the +parent UUID, so whichever view ran last set the row. The Forge reconcile did not +cause it. Fixed in state-hub 2b5d8f9 (STATE-WP-ADHOC-2026-10-06-T01); b4eb45a9 is +back to `archived`. Re-check: 4 parents (b4eb45a9 archived; 3a4f47d9, 759b1255, +e22516cc finished) holding 64 tasks (24+12+7+21). Receipt: Activity sync at e809fb2, +primary/railiance01, applied, 0 created / 45 updated (ACTIVITY-WP only) / 0 retired +/ 0 refused, 0 task changes, historical UUIDs preserved. Evidence: +state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. + + +## Cluster exact historical source successor, 2026-10-17 + +This scoped extension preserves the completed Activity/Custodian work above. +The cluster publisher now refuses three closed RAIL-BS source files containing +15 existing UUID-bound bare task labels. Preserve all three source bytes, IDs, +and UUIDs. No new alias or general syntax exemption is introduced. Evidence and +exact receiver-first proposal: cluster-historical-publication-r1 in the Custodian +NetKingdom change packet. The existing SHR-WP-0001 project driver owns the +Repo Manager / State Hub cross-owner wait; NK-WP-0049-T35 benefits from the +blocked cluster publication. No worker or human gate is woken here. + +## Prepare exact cluster registrar successor + +```task +id: RMGR-WP-0019-T04 +status: done +priority: high +``` + +Prepared full-file SHA256 bindings for three archives and 15 exact task +occurrences; strict scans still return 15 invalid labels and five collisions. +Unknown/live sources, changed/missing/symlinked histories, UUID drift and +qualified/global collisions refuse before allocation. Candidate tests pass 47; +canonical application remains a separate reviewed step. The read-only current +cluster preview proposes seven ordinary UUID bindings in two files and changes +no bytes. One pre-existing ADHOC field is included explicitly: task +RCLUSTER-WP-ADHOC-2026-07-27-T01 in workplans/ADHOC-2026-07-27.md receives +3e3f39d3-5070-5ba3-97db-19f5f361f264 through managed allocation only. + +## Admit cluster registrar successor only after receiving verification + +```task +id: RMGR-WP-0019-T05 +status: done +priority: high +depends_on: [STATE-WP-0095-T06] +``` + +Retain the current guard until exact reviewed receiving source has been delivered +and verified through State Hub's normal owner deployment. Match both manifests, +then integrate reviewed registrar source and verify ordinary allocator preview. +No direct API patch, history rename or bypass substitutes for this gate. + +## Run ordinary cluster owner publication and verify preservation + +```task +id: RMGR-WP-0019-T06 +status: wait +priority: high +depends_on: [RMGR-WP-0019-T05] +``` + +Only then run normal owner consistency/publication with the reviewed expected +file set: RCLUSTER-WP-0018 and the one-field ADHOC managed backfill, plus ordinary +generated indexes. Preserve all three archived files and all 18 existing +parent/task rows. Return actual receiving/publication receipts to STATE-WP-0095-T07. +Do not infer TLS recovery, credential custody or native acceptance from sync. + + +## Receiver-first registrar source follow-through, 2026-10-17 + +The exact receiving return is retained in Custodian +`docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.json`, +bound to the actual native rollout/preservation/refusal receipts. It verifies the +reviewed receiver source/image/module, API/MCP readiness, expected additive schema, +three existing historical parents/15 tasks and rolled-back safe refusal probes. +Only after that return was the exact registrar patch +`232552c3d601d185984be5a8e5bc9937bc9ddda7327923b5f0440f6deb2c87fc` +admitted in the Repo Manager owner source. T04 retains its source-preparation +outcome; T05 records this receiving-gated registrar admission, not a substitute +for receiving. Canonical focused registrar/identity checks and the bounded +read-only current Cluster allocator preview must agree with the reviewed source: +47 checks, seven ordinary missing UUID bindings in exactly the new WP0018 and +one-field existing ADHOC backfill, with 15 invalid labels/five collisions still +reported by the strict conformance scan. The three historical file bytes, IDs, +UUIDs and ownership are unchanged. No broad syntax relaxation or direct Hub UUID +patch is introduced. Exact source application/test/preview receipts travel with +the same packet; source publication/projection is verified separately. + +T06 remains wait until actual ordinary Cluster owner publication and receiving +preservation are verified. Registrar source readiness alone does not mark that +publication complete. Preserve the 18 existing rows and all three archives; the +root coordinator owns the normal seven-field managed allocation and dirty-source +preservation. Own Repo Manager projection must show exactly T01–T05 done, T06 +wait and active workplan status, including the managed new T04/T05/T06 UUIDs and +unchanged earlier task UUIDs. The separate scanner RMGR-WP-0021-T05 completion +and unrelated owner work remain untouched. No native TLS recovery, custody, +current registration/private admission or NetKingdom target acceptance follows. diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.verified-completion.md b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.verified-completion.md new file mode 100644 index 00000000..00be5ca3 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.verified-completion.md @@ -0,0 +1,238 @@ +--- +id: RMGR-WP-0019 +type: workplan +title: "Admit exact historical source views after receiving preservation support" +domain: infotech +repo: repo-manager +status: active +owner: codex +created: "2026-10-04" +updated: "2026-10-17" +flavor: implementation +depends_on: [] +state_hub_workstream_id: "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab" +--- + +## Goal + +Unblock normal authoritative registration of the exact closed Activity legacy +source views and Custodian retired ADHOC source after receiving preserves their +existing records. Preserve every legacy source byte, label and UUID; do not +expand canonical syntax or the general grandfathering rules. CUST-WP-0077 owns +cross-owner coordination with STATE-WP-0095. + +## Review exact historical receiving contract + +```task +id: RMGR-WP-0019-T01 +status: done +priority: high +state_hub_task_id: "d78a622e-39f9-5923-b4e1-f70fdc17fb42" +``` + +Seven Activity sources yield four existing parents/64 closed bound tasks; +three split views repeat the archived parent. One Custodian retired source keeps +its existing parent/task IDs. Earlier /tmp/activity-core-bound-history-write.py +is superseded and must not be applied: registrar bypass alone would admit an +unsupported receiving projection. RMGR-WP-0014/0015 are finished and do not own +this new implementation demand; this workplan is not residual. + +## Enable exact frozen registrar exceptions after receiving deployment + +```task +id: RMGR-WP-0019-T02 +status: done +priority: high +depends_on: [STATE-WP-0095-T03] +state_hub_task_id: "95240c81-1805-5365-9b35-d238621a16bf" +``` + +Prepared code permits only source paths with reviewed full SHA256 digests in +repo_manager/historical_sources.py. Strict conformance scans retain their legacy +findings. Unknown/missing/altered source refuses before allocation. Source UUIDs +are neither changed nor allocated for these histories. Receiving and registrar +manifests must remain identical. Apply helper requires a deployment receipt. + +## Run normal owner sync and verify preserved identities + +```task +id: RMGR-WP-0019-T03 +status: done +priority: high +depends_on: [RMGR-WP-0019-T02] +state_hub_task_id: "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d" +``` + +Use rmgr sync --path --push. No deep-check repair or direct hub UUID +patch substitutes for receiving. Historical unrelated stale projections are not +retirement-authorized by this workplan. Feed receipts back to STATE-WP-0095-T04. + +## Offline evidence, 2026-10-04 + +Prepared registrar suite: 38 focused cases passed (identifiers, registrar, +Custodian legacy identity and exact frozen source cases). Read-only execute=False +against both current owning repos accepted exact histories without source writes. +Implementation is staged; deployment gate is unresolved. + +## Approved deployment and actual registrar verification, 2026-10-04 + +STATE-WP-0095-T03 returned verified main-5dd3df9 / Helm revision72. +Global task-holder refusal passed inside the delivered API against the retired +Custodian parent, with transaction rollback and no committed probe. Five +historical parents/65 tasks retained their entire row snapshots. The gated +three-file registrar patch committed as c41d36c2ef8930628221ef36ec81d8b5d2145ed6; +38 actual owning-source cases passed and Repo Manager primary sync applied. + +Normal owner sync admitted all exact frozen histories without changing their +source bytes, UUIDs, parent ownership or row content. Custodian receiving +applied. Activity receiving refused only three empty duplicate projections +that would be retired; no retirement acknowledgement was issued. Registrar +allocated four missing IDs in ordinary Activity ad-hoc sources through its +normal path; frozen historical source files stayed unchanged. T03 remains wait +for explicit disposition and bounded receiving support under STATE-WP-0095-T04 +(decision91b7c633-a66f-5d43-9f4b-6565aefb9356). +Evidence: docs/evidence/2026-10-04-historical-registrar-verification.json. + +## Ungated T03 preparation, 2026-10-06 + +Re-ran the registrar suite at 8a47a5c (registrar source unchanged since +c41d36c2): 89 focused registrar/identity/historical cases and the full suite +(226) passed. Read-only hub check: the three refused projections are +683724d9 (custodian-wp-0003), 644017c7 (custodian-wp-0003a) and a5806df9 +(custodian-wp-0003b), each with zero tasks; every custodian-WP-0003* source +file binds parent b4eb45a9, which holds the tasks and must not be retired. +Added repo_manager.retirement_disposition, a read-only check that an Activity +expected_retirement_uuids set equals exactly those three empty projections and +excludes the preserved parent. It authorizes nothing; retirement stays with +Activity receiving under STATE-WP-0095-T04. + +## Activity disposition received, 2026-10-06 + +activity-core returned the exact expected_retirement_uuids (message 17ba4201, +evidence activity-core 941fac0, ACTIVITY-WP-0045): 683724d9, 644017c7, +a5806df9. repo_manager.retirement_disposition accepted the set: it equals the +three projections the 2026-10-04 run refused, each holds zero tasks, and it +excludes preserved parent b4eb45a9. Nothing was applied. T03 stays wait: its +acceptance needs a successful Activity owner sync with receipts, which can run +only after the founder decides 91b7c633 and STATE-WP-0095-T04 retires exactly +this set in a reviewed live rollout. Then re-run rmgr sync --path +~/activity-core --push and feed the receipt back to STATE-WP-0095-T04. + +## Post-retirement owner sync attempt, 2026-10-06 + +State Hub reported decision 91b7c633 resolved, main-968a811 / Helm rev 74 +deployed, and Activity reconcile at 67a92d2 retiring exactly the three empty +projections (3 retired, 0 created, 0 refused; 4 historical parents / 64 tasks +unchanged). Evidence: state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. +`rmgr sync --path ~/activity-core --push` stopped before reconciliation with +status pending_commit: uncommitted `state_hub_workstream_id` / `state_hub_task_id` +writeback in activity-core workplans/ACTIVITY-WP-0045-stale-historical-projection-disposition.md +(plus WORK-RECORDS.md). No hub request was made. Repo Manager does not commit in +activity-core; T03 stays wait until Activity Core commits and the sync re-runs. + +Re-run 2026-10-06 08:42Z after Activity Core committed the writeback (e809fb2): +status applied, created 0 / updated 45 (ACTIVITY-WP only) / retired 0 / refused 0, +no task changes, notes preserve custodian-WP-0001..0004 UUIDs; hub shows 4 parents, +64 tasks. Not closed: historical parent b4eb45a9 (custodian-WP-0003, source +`status: archived`, evidence snapshot archived) now reads `finished` in the hub, +updated 08:42:03Z during this sync. Needs State Hub review before T03 closes. + +Closed 2026-10-06: State Hub traced the b4eb45a9 status change to its own C-04 +check, which ran once per file. The custodian-WP-0003a/b/c split views share the +parent UUID, so whichever view ran last set the row. The Forge reconcile did not +cause it. Fixed in state-hub 2b5d8f9 (STATE-WP-ADHOC-2026-10-06-T01); b4eb45a9 is +back to `archived`. Re-check: 4 parents (b4eb45a9 archived; 3a4f47d9, 759b1255, +e22516cc finished) holding 64 tasks (24+12+7+21). Receipt: Activity sync at e809fb2, +primary/railiance01, applied, 0 created / 45 updated (ACTIVITY-WP only) / 0 retired +/ 0 refused, 0 task changes, historical UUIDs preserved. Evidence: +state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. + + +## Cluster exact historical source successor, 2026-10-17 + +This scoped extension preserves the completed Activity/Custodian work above. +The cluster publisher now refuses three closed RAIL-BS source files containing +15 existing UUID-bound bare task labels. Preserve all three source bytes, IDs, +and UUIDs. No new alias or general syntax exemption is introduced. Evidence and +exact receiver-first proposal: cluster-historical-publication-r1 in the Custodian +NetKingdom change packet. The existing SHR-WP-0001 project driver owns the +Repo Manager / State Hub cross-owner wait; NK-WP-0049-T35 benefits from the +blocked cluster publication. No worker or human gate is woken here. + +## Prepare exact cluster registrar successor + +```task +id: RMGR-WP-0019-T04 +status: done +priority: high +``` + +Prepared full-file SHA256 bindings for three archives and 15 exact task +occurrences; strict scans still return 15 invalid labels and five collisions. +Unknown/live sources, changed/missing/symlinked histories, UUID drift and +qualified/global collisions refuse before allocation. Candidate tests pass 47; +canonical application remains a separate reviewed step. The read-only current +cluster preview proposes seven ordinary UUID bindings in two files and changes +no bytes. One pre-existing ADHOC field is included explicitly: task +RCLUSTER-WP-ADHOC-2026-07-27-T01 in workplans/ADHOC-2026-07-27.md receives +3e3f39d3-5070-5ba3-97db-19f5f361f264 through managed allocation only. + +## Admit cluster registrar successor only after receiving verification + +```task +id: RMGR-WP-0019-T05 +status: done +priority: high +depends_on: [STATE-WP-0095-T06] +``` + +Retain the current guard until exact reviewed receiving source has been delivered +and verified through State Hub's normal owner deployment. Match both manifests, +then integrate reviewed registrar source and verify ordinary allocator preview. +No direct API patch, history rename or bypass substitutes for this gate. + +## Run ordinary cluster owner publication and verify preservation + +```task +id: RMGR-WP-0019-T06 +status: wait +priority: high +depends_on: [RMGR-WP-0019-T05] +``` + +Only then run normal owner consistency/publication with the reviewed expected +file set: RCLUSTER-WP-0018 and the one-field ADHOC managed backfill, plus ordinary +generated indexes. Preserve all three archived files and all 18 existing +parent/task rows. Return actual receiving/publication receipts to STATE-WP-0095-T07. +Do not infer TLS recovery, credential custody or native acceptance from sync. + + +## Receiver-first registrar source follow-through, 2026-10-17 + +The exact receiving return is retained in Custodian +`docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json`, +bound to the actual native rollout/preservation/refusal receipts. It verifies the +reviewed receiver source/image/module, API/MCP readiness, expected additive schema, +three existing historical parents/15 tasks and rolled-back safe refusal probes. +Only after that return was the exact registrar patch +`232552c3d601d185984be5a8e5bc9937bc9ddda7327923b5f0440f6deb2c87fc` +admitted in the Repo Manager owner source. T04 retains its source-preparation +outcome; T05 records this receiving-gated registrar admission, not a substitute +for receiving. Canonical focused registrar/identity checks passed 47 cases in 5.84 seconds. +The actual bounded read-only current Cluster allocator preview agreed with the +reviewed source: seven ordinary missing UUID bindings in exactly the new WP0018 and +one-field existing ADHOC backfill, with 15 invalid labels/five collisions still +reported by the strict conformance scan. The three historical file bytes, IDs, +UUIDs and ownership are unchanged. No broad syntax relaxation or direct Hub UUID +patch is introduced. Exact source application/test/preview receipts travel with +the same packet; source publication/projection is verified separately. + +T06 remains wait until actual ordinary Cluster owner publication and receiving +preservation are verified. Registrar source readiness alone does not mark that +publication complete. Preserve the 18 existing rows and all three archives; the +root coordinator owns the normal seven-field managed allocation and dirty-source +preservation. Own Repo Manager projection must show exactly T01–T05 done, T06 +wait and active workplan status, including the managed new T04/T05/T06 UUIDs and +unchanged earlier task UUIDs. The separate scanner RMGR-WP-0021-T05 completion +and unrelated owner work remain untouched. No native TLS recovery, custody, +current registration/private admission or NetKingdom target acceptance follows. diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.wait.preimage.md b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.wait.preimage.md new file mode 100644 index 00000000..fcfa4b3f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.wait.preimage.md @@ -0,0 +1,207 @@ +--- +id: RMGR-WP-0019 +type: workplan +title: "Admit exact historical source views after receiving preservation support" +domain: infotech +repo: repo-manager +status: active +owner: codex +created: "2026-10-04" +updated: "2026-10-17" +flavor: implementation +depends_on: [] +state_hub_workstream_id: "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab" +--- + +## Goal + +Unblock normal authoritative registration of the exact closed Activity legacy +source views and Custodian retired ADHOC source after receiving preserves their +existing records. Preserve every legacy source byte, label and UUID; do not +expand canonical syntax or the general grandfathering rules. CUST-WP-0077 owns +cross-owner coordination with STATE-WP-0095. + +## Review exact historical receiving contract + +```task +id: RMGR-WP-0019-T01 +status: done +priority: high +state_hub_task_id: "d78a622e-39f9-5923-b4e1-f70fdc17fb42" +``` + +Seven Activity sources yield four existing parents/64 closed bound tasks; +three split views repeat the archived parent. One Custodian retired source keeps +its existing parent/task IDs. Earlier /tmp/activity-core-bound-history-write.py +is superseded and must not be applied: registrar bypass alone would admit an +unsupported receiving projection. RMGR-WP-0014/0015 are finished and do not own +this new implementation demand; this workplan is not residual. + +## Enable exact frozen registrar exceptions after receiving deployment + +```task +id: RMGR-WP-0019-T02 +status: done +priority: high +depends_on: [STATE-WP-0095-T03] +state_hub_task_id: "95240c81-1805-5365-9b35-d238621a16bf" +``` + +Prepared code permits only source paths with reviewed full SHA256 digests in +repo_manager/historical_sources.py. Strict conformance scans retain their legacy +findings. Unknown/missing/altered source refuses before allocation. Source UUIDs +are neither changed nor allocated for these histories. Receiving and registrar +manifests must remain identical. Apply helper requires a deployment receipt. + +## Run normal owner sync and verify preserved identities + +```task +id: RMGR-WP-0019-T03 +status: done +priority: high +depends_on: [RMGR-WP-0019-T02] +state_hub_task_id: "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d" +``` + +Use rmgr sync --path --push. No deep-check repair or direct hub UUID +patch substitutes for receiving. Historical unrelated stale projections are not +retirement-authorized by this workplan. Feed receipts back to STATE-WP-0095-T04. + +## Offline evidence, 2026-10-04 + +Prepared registrar suite: 38 focused cases passed (identifiers, registrar, +Custodian legacy identity and exact frozen source cases). Read-only execute=False +against both current owning repos accepted exact histories without source writes. +Implementation is staged; deployment gate is unresolved. + +## Approved deployment and actual registrar verification, 2026-10-04 + +STATE-WP-0095-T03 returned verified main-5dd3df9 / Helm revision72. +Global task-holder refusal passed inside the delivered API against the retired +Custodian parent, with transaction rollback and no committed probe. Five +historical parents/65 tasks retained their entire row snapshots. The gated +three-file registrar patch committed as c41d36c2ef8930628221ef36ec81d8b5d2145ed6; +38 actual owning-source cases passed and Repo Manager primary sync applied. + +Normal owner sync admitted all exact frozen histories without changing their +source bytes, UUIDs, parent ownership or row content. Custodian receiving +applied. Activity receiving refused only three empty duplicate projections +that would be retired; no retirement acknowledgement was issued. Registrar +allocated four missing IDs in ordinary Activity ad-hoc sources through its +normal path; frozen historical source files stayed unchanged. T03 remains wait +for explicit disposition and bounded receiving support under STATE-WP-0095-T04 +(decision91b7c633-a66f-5d43-9f4b-6565aefb9356). +Evidence: docs/evidence/2026-10-04-historical-registrar-verification.json. + +## Ungated T03 preparation, 2026-10-06 + +Re-ran the registrar suite at 8a47a5c (registrar source unchanged since +c41d36c2): 89 focused registrar/identity/historical cases and the full suite +(226) passed. Read-only hub check: the three refused projections are +683724d9 (custodian-wp-0003), 644017c7 (custodian-wp-0003a) and a5806df9 +(custodian-wp-0003b), each with zero tasks; every custodian-WP-0003* source +file binds parent b4eb45a9, which holds the tasks and must not be retired. +Added repo_manager.retirement_disposition, a read-only check that an Activity +expected_retirement_uuids set equals exactly those three empty projections and +excludes the preserved parent. It authorizes nothing; retirement stays with +Activity receiving under STATE-WP-0095-T04. + +## Activity disposition received, 2026-10-06 + +activity-core returned the exact expected_retirement_uuids (message 17ba4201, +evidence activity-core 941fac0, ACTIVITY-WP-0045): 683724d9, 644017c7, +a5806df9. repo_manager.retirement_disposition accepted the set: it equals the +three projections the 2026-10-04 run refused, each holds zero tasks, and it +excludes preserved parent b4eb45a9. Nothing was applied. T03 stays wait: its +acceptance needs a successful Activity owner sync with receipts, which can run +only after the founder decides 91b7c633 and STATE-WP-0095-T04 retires exactly +this set in a reviewed live rollout. Then re-run rmgr sync --path +~/activity-core --push and feed the receipt back to STATE-WP-0095-T04. + +## Post-retirement owner sync attempt, 2026-10-06 + +State Hub reported decision 91b7c633 resolved, main-968a811 / Helm rev 74 +deployed, and Activity reconcile at 67a92d2 retiring exactly the three empty +projections (3 retired, 0 created, 0 refused; 4 historical parents / 64 tasks +unchanged). Evidence: state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. +`rmgr sync --path ~/activity-core --push` stopped before reconciliation with +status pending_commit: uncommitted `state_hub_workstream_id` / `state_hub_task_id` +writeback in activity-core workplans/ACTIVITY-WP-0045-stale-historical-projection-disposition.md +(plus WORK-RECORDS.md). No hub request was made. Repo Manager does not commit in +activity-core; T03 stays wait until Activity Core commits and the sync re-runs. + +Re-run 2026-10-06 08:42Z after Activity Core committed the writeback (e809fb2): +status applied, created 0 / updated 45 (ACTIVITY-WP only) / retired 0 / refused 0, +no task changes, notes preserve custodian-WP-0001..0004 UUIDs; hub shows 4 parents, +64 tasks. Not closed: historical parent b4eb45a9 (custodian-WP-0003, source +`status: archived`, evidence snapshot archived) now reads `finished` in the hub, +updated 08:42:03Z during this sync. Needs State Hub review before T03 closes. + +Closed 2026-10-06: State Hub traced the b4eb45a9 status change to its own C-04 +check, which ran once per file. The custodian-WP-0003a/b/c split views share the +parent UUID, so whichever view ran last set the row. The Forge reconcile did not +cause it. Fixed in state-hub 2b5d8f9 (STATE-WP-ADHOC-2026-10-06-T01); b4eb45a9 is +back to `archived`. Re-check: 4 parents (b4eb45a9 archived; 3a4f47d9, 759b1255, +e22516cc finished) holding 64 tasks (24+12+7+21). Receipt: Activity sync at e809fb2, +primary/railiance01, applied, 0 created / 45 updated (ACTIVITY-WP only) / 0 retired +/ 0 refused, 0 task changes, historical UUIDs preserved. Evidence: +state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. + + +## Cluster exact historical source successor, 2026-10-17 + +This scoped extension preserves the completed Activity/Custodian work above. +The cluster publisher now refuses three closed RAIL-BS source files containing +15 existing UUID-bound bare task labels. Preserve all three source bytes, IDs, +and UUIDs. No new alias or general syntax exemption is introduced. Evidence and +exact receiver-first proposal: cluster-historical-publication-r1 in the Custodian +NetKingdom change packet. The existing SHR-WP-0001 project driver owns the +Repo Manager / State Hub cross-owner wait; NK-WP-0049-T35 benefits from the +blocked cluster publication. No worker or human gate is woken here. + +## Prepare exact cluster registrar successor + +```task +id: RMGR-WP-0019-T04 +status: done +priority: high +``` + +Prepared full-file SHA256 bindings for three archives and 15 exact task +occurrences; strict scans still return 15 invalid labels and five collisions. +Unknown/live sources, changed/missing/symlinked histories, UUID drift and +qualified/global collisions refuse before allocation. Candidate tests pass 47; +canonical application remains a separate reviewed step. The read-only current +cluster preview proposes seven ordinary UUID bindings in two files and changes +no bytes. One pre-existing ADHOC field is included explicitly: task +RCLUSTER-WP-ADHOC-2026-07-27-T01 in workplans/ADHOC-2026-07-27.md receives +3e3f39d3-5070-5ba3-97db-19f5f361f264 through managed allocation only. + +## Admit cluster registrar successor only after receiving verification + +```task +id: RMGR-WP-0019-T05 +status: wait +priority: high +depends_on: [STATE-WP-0095-T06] +``` + +Retain the current guard until exact reviewed receiving source has been delivered +and verified through State Hub's normal owner deployment. Match both manifests, +then integrate reviewed registrar source and verify ordinary allocator preview. +No direct API patch, history rename or bypass substitutes for this gate. + +## Run ordinary cluster owner publication and verify preservation + +```task +id: RMGR-WP-0019-T06 +status: wait +priority: high +depends_on: [RMGR-WP-0019-T05] +``` + +Only then run normal owner consistency/publication with the reviewed expected +file set: RCLUSTER-WP-0018 and the one-field ADHOC managed backfill, plus ordinary +generated indexes. Preserve all three archived files and all 18 existing +parent/task rows. Return actual receiving/publication receipts to STATE-WP-0095-T07. +Do not infer TLS recovery, credential custody or native acceptance from sync. diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/T05-conditional-completion.patch b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/T05-conditional-completion.patch new file mode 100644 index 00000000..ac91958f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/T05-conditional-completion.patch @@ -0,0 +1,46 @@ +--- a/workplans/RMGR-WP-0019-historical-source-admission.md ++++ b/workplans/RMGR-WP-0019-historical-source-admission.md +@@ -181,7 +181,7 @@ + + ```task + id: RMGR-WP-0019-T05 +-status: wait ++status: done + priority: high + depends_on: [STATE-WP-0095-T06] + ``` +@@ -205,3 +205,34 @@ + generated indexes. Preserve all three archived files and all 18 existing + parent/task rows. Return actual receiving/publication receipts to STATE-WP-0095-T07. + Do not infer TLS recovery, credential custody or native acceptance from sync. ++ ++ ++## Receiver-first registrar source follow-through, 2026-10-17 ++ ++The exact receiving return is retained in Custodian ++`docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.json`, ++bound to the actual native rollout/preservation/refusal receipts. It verifies the ++reviewed receiver source/image/module, API/MCP readiness, expected additive schema, ++three existing historical parents/15 tasks and rolled-back safe refusal probes. ++Only after that return was the exact registrar patch ++`232552c3d601d185984be5a8e5bc9937bc9ddda7327923b5f0440f6deb2c87fc` ++admitted in the Repo Manager owner source. T04 retains its source-preparation ++outcome; T05 records this receiving-gated registrar admission, not a substitute ++for receiving. Canonical focused registrar/identity checks and the bounded ++read-only current Cluster allocator preview must agree with the reviewed source: ++47 checks, seven ordinary missing UUID bindings in exactly the new WP0018 and ++one-field existing ADHOC backfill, with 15 invalid labels/five collisions still ++reported by the strict conformance scan. The three historical file bytes, IDs, ++UUIDs and ownership are unchanged. No broad syntax relaxation or direct Hub UUID ++patch is introduced. Exact source application/test/preview receipts travel with ++the same packet; source publication/projection is verified separately. ++ ++T06 remains wait until actual ordinary Cluster owner publication and receiving ++preservation are verified. Registrar source readiness alone does not mark that ++publication complete. Preserve the 18 existing rows and all three archives; the ++root coordinator owns the normal seven-field managed allocation and dirty-source ++preservation. Own Repo Manager projection must show exactly T01–T05 done, T06 ++wait and active workplan status, including the managed new T04/T05/T06 UUIDs and ++unchanged earlier task UUIDs. The separate scanner RMGR-WP-0021-T05 completion ++and unrelated owner work remain untouched. No native TLS recovery, custody, ++current registration/private admission or NetKingdom target acceptance follows. diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/actual-cluster-allocator-preview.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/actual-cluster-allocator-preview.json new file mode 100644 index 00000000..7b93981a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/actual-cluster-allocator-preview.json @@ -0,0 +1,212 @@ +{ + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": false, + "repo": "railiance-cluster", + "namespace": "helixforge", + "assignments": [ + { + "kind": "task", + "record_id": "RCLUSTER-WP-ADHOC-2026-07-27-T01", + "uuid": "3e3f39d3-5070-5ba3-97db-19f5f361f264", + "path": "workplans/ADHOC-2026-07-27.md" + }, + { + "kind": "workplan", + "record_id": "RCLUSTER-WP-0018", + "uuid": "e0a7813d-c916-5e49-84b2-5e5b30441891", + "path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md" + }, + { + "kind": "task", + "record_id": "RCLUSTER-WP-0018-T01", + "uuid": "7280193d-0d59-5b78-a2d3-96ebd127127f", + "path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md" + }, + { + "kind": "task", + "record_id": "RCLUSTER-WP-0018-T02", + "uuid": "90836435-917f-504c-a711-3f29ece348e3", + "path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md" + }, + { + "kind": "task", + "record_id": "RCLUSTER-WP-0018-T03", + "uuid": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a", + "path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md" + }, + { + "kind": "task", + "record_id": "RCLUSTER-WP-0018-T04", + "uuid": "021b07bb-65bc-5743-bac5-4294b4be74f6", + "path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md" + }, + { + "kind": "task", + "record_id": "RCLUSTER-WP-0018-T05", + "uuid": "5bc67a22-0991-5625-86a6-f749560d8a0e", + "path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md" + } + ], + "historical_invalid_identifiers": [ + { + "kind": "task", + "id": "T01", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1" + }, + { + "kind": "task", + "id": "T02", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2" + }, + { + "kind": "task", + "id": "T03", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3" + }, + { + "kind": "task", + "id": "T04", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4" + }, + { + "kind": "task", + "id": "T05", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5" + }, + { + "kind": "task", + "id": "T01", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1" + }, + { + "kind": "task", + "id": "T02", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2" + }, + { + "kind": "task", + "id": "T03", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3" + }, + { + "kind": "task", + "id": "T04", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4" + }, + { + "kind": "task", + "id": "T01", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1" + }, + { + "kind": "task", + "id": "T02", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2" + }, + { + "kind": "task", + "id": "T03", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3" + }, + { + "kind": "task", + "id": "T04", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4" + }, + { + "kind": "task", + "id": "T05", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5" + }, + { + "kind": "task", + "id": "T06", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6" + } + ], + "historical_identity_collisions": [ + { + "kind": "task", + "id": "T01", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "3f042630-eab0-4c6a-9167-e2b28ff20e40", + "4526a842-ea31-4874-9231-92ab556cfe7b", + "6841c93a-f146-47eb-9f7c-8fa0e02c1bbc" + ] + }, + { + "kind": "task", + "id": "T02", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "a6313e06-1976-46a7-8e31-df4eb2eca880", + "ab166073-30a7-4702-a037-4091e8706e20", + "e8510646-46ed-4697-a345-f3d3009eea78" + ] + }, + { + "kind": "task", + "id": "T03", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "05d42a55-921f-4aa7-bb76-e8af9c7e0ac3", + "140da396-8e30-4f4d-b88c-c42c0cd46c01", + "dab2c07f-8aa0-4635-8df6-857e87e93fc5" + ] + }, + { + "kind": "task", + "id": "T04", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "08233868-d522-4117-bc4e-6c0f52545665", + "5c3d40e4-239b-488e-9519-6f7a38d2325f", + "d8a3ba40-fda0-4c1f-a9f1-ffcd621a5b3d" + ] + }, + { + "kind": "task", + "id": "T05", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "2d5acff7-4a4e-4ddd-ad06-08237ad3dac8", + "7f9e0e58-a130-467a-a2d0-b3f2564e496f" + ] + } + ], + "files_changed": [ + "workplans/ADHOC-2026-07-27.md", + "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md" + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/apply_registrar_source.py b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/apply_registrar_source.py new file mode 100644 index 00000000..29a0c7d1 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/apply_registrar_source.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +"""Exact local registrar source application; check-only unless explicitly executed. + +Receiving-return metadata is evidence binding, not an approval or authority grant. +The coordinator must explicitly authorize execution after native verification. +No allocator, task completion, commit, push, cluster write or Hub write occurs. +""" +import argparse +import hashlib +import json +from pathlib import Path +import subprocess + +HERE=Path(__file__).resolve().parent +PACKET=HERE.parent.parent/'netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r2' +ROOT=Path('/home/worsch/repo-manager') +BASE='9ebde0a9bd60d5c82910494fbe6bd1b891455cee' +PATCH_SHA='232552c3d601d185984be5a8e5bc9937bc9ddda7327923b5f0440f6deb2c87fc' +MANIFEST_SHA='f75391603c703b71b76eaf3432adef5022e73d61e4d3b22da4820f583dd435b4' +EXPECTED={'schema':'custodian.registrar-receiving-return.v1','status':'verified', + 'proposal_id':'STATE-WP-0095-T06-cluster-frozen-receiving-r1', + 'receiver_source_commit':'51bc70d1ff8f25450a8650d8e50caf053093a02e', + 'receiver_image_digest':'sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015', + 'delivered_module_sha256':'e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2', + 'schema_revision':'c4d5e6f7a8b9','api_ready':True,'mcp_ready':True, + 'historical_three_parents_fifteen_tasks_preserved':True,'safe_refusal_probe_rollback_verified':True} + + +def sha(path):return hashlib.sha256(path.read_bytes()).hexdigest() + + +def git(*args): + result=subprocess.run(['git','--no-optional-locks','-C',str(ROOT),*args],capture_output=True,timeout=30,check=False) + if result.returncode:raise RuntimeError('git-precondition-or-apply-refused') + return result.stdout + + +def main(): + parser=argparse.ArgumentParser();parser.add_argument('--execute',action='store_true');parser.add_argument('--gate',type=Path);parser.add_argument('--gate-sha256') + args=parser.parse_args();patch=PACKET/'repo-manager.patch' + if sha(PACKET/'source-patch-manifest.json')!=MANIFEST_SHA or sha(patch)!=PATCH_SHA:raise RuntimeError('frozen-input-drift') + manifest=json.loads((PACKET/'source-patch-manifest.json').read_text())['repos']['repo-manager'] + if git('rev-parse','HEAD').decode().strip()!=BASE:raise RuntimeError('base-drift') + paths=[line[6:] for line in patch.read_text().splitlines() if line.startswith('+++ b/')] + if len(paths)!=len(set(paths)) or set(paths)!={row['path'] for row in manifest['files']}:raise RuntimeError('patch-path-drift') + for row in manifest['files']: + path=ROOT/row['path'];actual=sha(path) if path.exists() else None + if actual!=row['base_sha256'] or git('status','--porcelain','--',row['path']).strip():raise RuntimeError('source-preimage-drift') + git('apply','--check',str(patch)) + if not args.execute: + print(json.dumps({'status':'check-only','preimages':len(paths),'canonical_mutation':False}));return 0 + if not args.gate or not args.gate_sha256 or sha(args.gate)!=args.gate_sha256:raise RuntimeError('exact-receiving-return-required') + gate=json.loads(args.gate.read_text()) + if any(gate.get(key)!=value for key,value in EXPECTED.items()):raise RuntimeError('receiving-return-incomplete') + receipts=gate.get('native_receipts') + if not isinstance(receipts,list) or not receipts:raise RuntimeError('native-receipt-binding-missing') + for item in receipts: + path=Path(item['path']) + if not path.is_absolute() or not path.is_relative_to(HERE.parent) or sha(path)!=item['sha256']:raise RuntimeError('native-receipt-drift') + # No task can be marked complete merely by this source application. + index=git('ls-files','--stage','-z') + git('apply',str(patch)) + for row in manifest['files']: + if sha(ROOT/row['path'])!=row['candidate_sha256']:raise RuntimeError('postimage-mismatch') + if git('ls-files','--stage','-z')!=index:raise RuntimeError('index-changed') + receipt={'status':'applied-exact-local-registrar-source','base':BASE,'frozen_patch_sha256':PATCH_SHA, + 'receiving_gate_sha256':args.gate_sha256,'files':{row['path']:row['candidate_sha256'] for row in manifest['files']}, + 'index_unchanged':True,'allocator_executed':False,'task_completion_applied':False, + 'cluster_source_or_hub_mutation':False,'commit_or_push_performed':False} + (HERE/'source-application.json').write_text(json.dumps(receipt,indent=2)+'\n');print(json.dumps({'status':receipt['status']}));return 0 + + +if __name__=='__main__':raise SystemExit(main()) diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/canonical-test-confirmation.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/canonical-test-confirmation.json new file mode 100644 index 00000000..0af31ca1 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/canonical-test-confirmation.json @@ -0,0 +1,14 @@ +{ + "status": "passed", + "authority": "root coordinator actual canonical test return", + "session_id": 16273, + "tests_passed": 47, + "seconds": 5.84, + "warning": "pytest cache read-only warning only", + "test_files": [ + "tests/test_cluster_frozen_history.py", + "tests/test_historical_sync_validation.py", + "tests/test_historical_sources.py", + "tests/test_custodian_legacy_identity.py" + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/isolated-47-tests.txt b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/isolated-47-tests.txt new file mode 100644 index 00000000..457f73b4 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/isolated-47-tests.txt @@ -0,0 +1,2 @@ +............................................... [100%] +47 passed in 5.34s diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/manifest.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/manifest.json new file mode 100644 index 00000000..bba6919f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/manifest.json @@ -0,0 +1,25 @@ +{ + "state": "review-only conditional source follow-through; no canonical edit or activation", + "owner_base": "9ebde0a9bd60d5c82910494fbe6bd1b891455cee", + "frozen_registrar_patch_sha256": "232552c3d601d185984be5a8e5bc9937bc9ddda7327923b5f0440f6deb2c87fc", + "isolated_current_base_tests": { + "passed": 47, + "seconds": 5.34 + }, + "canonical_preimages_matched": 7, + "completion_overlay_preimage_sha256": "6378d96b70259ae81435b6ce8f97864698bdc5b6679cabbe9dc61a1fc1d09699", + "completion_overlay_result_sha256": "4aa0aad970d31e9e08fd38a676c289e74d293b4484b3ae0fd2f40d7b72376183", + "completion_overlay_patch_sha256": "b88efdd3b62b056ef53b9498a5c04e699593853a96332e4c86264825a9fbe1cb", + "apply_script_sha256": "d54988c12263d4994a9e54b6e1d1e2423c485ca6055cbf2df89e5f93e02ebe4a", + "WP21_scanner_T05_unchanged": true, + "T04": "done source preparation", + "T05": "wait in frozen stage1; conditional done onlyafter rootreceivingreturn+canonicalproof", + "T06": "wait until actualClusterpublication", + "actual_cluster_allocator_executed": false, + "canonical_mutations_performed": false, + "registrar_activated": false, + "publication_plan_sha256": "e7119344687a46de66b38814f31b87cc5f399af4496f9c1f972609f8ea409e54", + "source_review_receipt_sha256": "b67463db89789aeae5a347bd09b221d74df0e8da2d0466392634b505902d1244", + "isolated_test_receipt_sha256": "da4f11fa49d639096b0010461a642db91ebb31771671a8a0f9225e4c35d14d42", + "pending_gate_template_sha256": "0ef70ae4b57045b81d2b226ecc36788b1905cd0dbac84850f906e59e2340c0e6" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/own-managed-application.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/own-managed-application.json new file mode 100644 index 00000000..32d7104d --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/own-managed-application.json @@ -0,0 +1,32 @@ +{ + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": true, + "repo": "repo-manager", + "namespace": "helixforge", + "assignments": [ + { + "kind": "task", + "record_id": "RMGR-WP-0019-T04", + "uuid": "1ccb06c6-ad30-5847-8704-e5628ba81f35", + "path": "workplans/RMGR-WP-0019-historical-source-admission.md" + }, + { + "kind": "task", + "record_id": "RMGR-WP-0019-T05", + "uuid": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "path": "workplans/RMGR-WP-0019-historical-source-admission.md" + }, + { + "kind": "task", + "record_id": "RMGR-WP-0019-T06", + "uuid": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "path": "workplans/RMGR-WP-0019-historical-source-admission.md" + } + ], + "historical_invalid_identifiers": [], + "historical_identity_collisions": [], + "files_changed": [ + "workplans/RMGR-WP-0019-historical-source-admission.md" + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/own-managed-preview.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/own-managed-preview.json new file mode 100644 index 00000000..cfca555c --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/own-managed-preview.json @@ -0,0 +1,32 @@ +{ + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": false, + "repo": "repo-manager", + "namespace": "helixforge", + "assignments": [ + { + "kind": "task", + "record_id": "RMGR-WP-0019-T04", + "uuid": "1ccb06c6-ad30-5847-8704-e5628ba81f35", + "path": "workplans/RMGR-WP-0019-historical-source-admission.md" + }, + { + "kind": "task", + "record_id": "RMGR-WP-0019-T05", + "uuid": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "path": "workplans/RMGR-WP-0019-historical-source-admission.md" + }, + { + "kind": "task", + "record_id": "RMGR-WP-0019-T06", + "uuid": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "path": "workplans/RMGR-WP-0019-historical-source-admission.md" + } + ], + "historical_invalid_identifiers": [], + "historical_identity_collisions": [], + "files_changed": [ + "workplans/RMGR-WP-0019-historical-source-admission.md" + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/publication-final-manifest.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/publication-final-manifest.json new file mode 100644 index 00000000..4d82f5c1 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/publication-final-manifest.json @@ -0,0 +1,27 @@ +{ + "status": "published-and-readback-verified", + "commit": "70cd754996870638848616e37819790a5c4d52b3", + "t05": "done", + "t06": "wait", + "canonical_tests": 47, + "managed_own_task_fields": 3, + "cluster_mutations": false, + "source_worktree_clean": true, + "scanner_source_and_T05_preserved": true, + "readback_scope": "exact WP19 six tasks and preserved WP21 five tasks; remote HEAD/main; internal projected dependencies; external declarations and target identities separately", + "files": { + "publish_registrar.py": "afed552b62d432ba5e117d0474dd0f03cd5d9192f3131c53de66824de3761ea6", + "RMGR-WP-0019.verified-completion.md": "eb8bda226be2ad3cb91fe771b27fe106715aa5d61e44d43f4f534f9f5ee4ad83", + "canonical-test-confirmation.json": "242a3eb25744a41c99646e69870cf85f395aaa543a2768815e6a71cb514471da", + "actual-cluster-allocator-preview.json": "78725ea97b70b26eed0b0ac8c3b72161eacd893343f6b087548540e784a0e792", + "own-managed-preview.json": "6989fd9e70cae86d7013e596d8182622e5eff4f58c59f73613b0c0fc797ca895", + "own-managed-application.json": "6d5672786575cf6e13c27619d562b03fe23d2b82fd09b345a38c4e28dcaf4593", + "registrar-commit.json": "02adaa482d7bfbe4db165f071620a36a1e5d37ed01eb44dffa01eec756a528fb", + "registrar-sync.json": "876c27d4b1464ff024268a8b53aa77767dbeaec110bf8afadb016fc9584f97cd", + "verify_registrar_publication.py": "a7ea9793e5d31a1deddecf9422e57178cb8734aad9619dc1ec5c4d01cc8b53f7", + "registrar-publication-readback.json": "26e359c17a342c1155c6d1265398f8f89b43cd3597de567cf9591d73fc05a3cf", + "r1-registrar-publication-readback.json": "5570f34c598cc8e15459e450dc7b8ce8dffda900217584ce1ebc383d5c1f36bf", + "r1-verify_registrar_publication.py": "3603e96dd0cec3ea1634561c28eac545d35ae8e4936b5d43d0305aa76094d389", + "wp19-actual-projected-dependencies.json": "6f55ab18c74825a26a525ed0e5f3324fe6b2ec202f788f0eb99978d28bfd3292" + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/publish_registrar.py b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/publish_registrar.py new file mode 100644 index 00000000..5870afad --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/publish_registrar.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +"""Exact receiver-gated RepoManager overlay, managed own identifiers and normal commit.""" +from pathlib import Path +import hashlib,json,subprocess,sys,argparse +P=Path(__file__).resolve().parent +R=Path('/home/worsch/repo-manager') +WP='workplans/RMGR-WP-0019-historical-source-admission.md' +def digest(p): return hashlib.sha256(p.read_bytes()).hexdigest() +def run(*args): + r=subprocess.run(args,cwd=R,text=True,capture_output=True,timeout=180) + if r.returncode: raise RuntimeError(json.dumps({'command':list(args),'code':r.returncode,'stdout':r.stdout,'stderr':r.stderr})) + return r.stdout +parser=argparse.ArgumentParser();parser.add_argument('--execute',action='store_true');a=parser.parse_args() +m=json.loads((P/'source-application.json').read_text()); paths=list(m['files']) +assert len(paths)==7 and m['status']=='applied-exact-local-registrar-source' +assert run('git','rev-parse','HEAD').strip()==m['base'] +assert not run('git','diff','--cached','--name-only') +assert digest(P.parent/'receiver-rollout-r4/verified-receiving-return.json')==m['receiving_gate_sha256']=='d088c336d62c7bdde0e586b0f1b73c3aa3d4031a4debd9ac90206128728257f4' +for f,h in m['files'].items(): assert digest(R/f)==h,(f,'source drift') +assert digest(P/'RMGR-WP-0019.verified-completion.md')=='eb8bda226be2ad3cb91fe771b27fe106715aa5d61e44d43f4f534f9f5ee4ad83' +preview=json.loads((P/'actual-cluster-allocator-preview.json').read_text()) +assert preview['ok'] and not preview['executed'] and len(preview['assignments'])==7 and len(preview['files_changed'])==2 +assert len(preview['historical_invalid_identifiers'])==15 and len(preview['historical_identity_collisions'])==5 +assert json.loads((P/'canonical-test-confirmation.json').read_text())['tests_passed']==47 +scanner=R/'src/repo_manager/secret_scan.py'; scanner_before=digest(scanner) +assert scanner_before=='e709c658f779534fcab093207b0a78e49d54fc584c515fdf7ac535ce75f6c400' +# Work outside this exact seven-file source delta may remain, but never enters this commit. +if not a.execute: + print(json.dumps({'status':'checked-ready','paths':paths,'t05':'conditional-done','t06':'wait'}));sys.exit(0) +(R/WP).write_bytes((P/'RMGR-WP-0019.verified-completion.md').read_bytes()) +sys.path.insert(0,str(R/'src')) +from repo_manager.identifiers import ensure_missing_work_record_identifiers +own=ensure_missing_work_record_identifiers(R,execute=False) +expected={f'RMGR-WP-0019-T{x:02d}' for x in (4,5,6)} +assert {x['record_id'] for x in own['assignments']}==expected and len(own['assignments'])==3 +assert own['files_changed']==[WP] and all(x['kind']=='task' and x['path']==WP for x in own['assignments']) +(P/'own-managed-preview.json').write_text(json.dumps(own,indent=2)+'\n') +actual=ensure_missing_work_record_identifiers(R,execute=True) +assert actual['assignments']==own['assignments'] +(P/'own-managed-application.json').write_text(json.dumps(actual,indent=2)+'\n') +assert not ensure_missing_work_record_identifiers(R,execute=False)['assignments'] +assert digest(scanner)==scanner_before +run('git','add','--',*paths) +assert set(run('git','diff','--cached','--name-only').splitlines())==set(paths) +run('git','diff','--cached','--check') +output=run('git','commit','-m','Admit exact frozen Cluster histories after verified receiving') +head=run('git','rev-parse','HEAD').strip() +assert set(run('git','diff-tree','--no-commit-id','--name-only','-r',head).splitlines())==set(paths) +receipt={'status':'committed-exact-seven-paths','head':head,'parent':m['base'],'paths':paths,'managed_assignments':actual['assignments'],'scanner_sha256_unchanged':scanner_before,'t05':'done','t06':'wait','commit_output':output,'source_files':{f:digest(R/f) for f in paths},'receiving_gate_sha256':m['receiving_gate_sha256'],'cluster_source_mutation':False} +(P/'registrar-commit.json').write_text(json.dumps(receipt,indent=2)+'\n') +print(json.dumps(receipt,indent=2)) diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/r1-registrar-publication-readback.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/r1-registrar-publication-readback.json new file mode 100644 index 00000000..9dd6f3bc --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/r1-registrar-publication-readback.json @@ -0,0 +1,13 @@ +{ + "status": "unverified", + "scope": "RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots", + "writes_to_source_index_refs_or_Hub": false, + "rows": [], + "hub_instance": { + "status": "ok", + "instance_role": "primary", + "instance_label": "railiance01" + }, + "reason": "dependency-binding-mismatch", + "verifier_sha256": "3603e96dd0cec3ea1634561c28eac545d35ae8e4936b5d43d0305aa76094d389" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/r1-verify_registrar_publication.py b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/r1-verify_registrar_publication.py new file mode 100644 index 00000000..b254ed10 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/r1-verify_registrar_publication.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +"""Read-only Git+Hub task binding verifier; never syncs or changes source/index.""" +import hashlib +import json +import os +from pathlib import Path +import re +import subprocess +import urllib.request + +HERE=Path(__file__).resolve().parent +OWNERS=[ + {'repo':'repo-manager','commit':'70cd754996870638848616e37819790a5c4d52b3','path':'workplans/RMGR-WP-0019-historical-source-admission.md','id':'RMGR-WP-0019','tasks':6}, + {'repo':'repo-manager','commit':'70cd754996870638848616e37819790a5c4d52b3','path':'workplans/RMGR-WP-0021-secret-detection-controls.md','id':'RMGR-WP-0021','tasks':5}, +] +API=os.environ.get('API_BASE','http://127.0.0.1:8000').rstrip('/') +EXTERNAL={'STATE-WP-0095-T03':'e8566341-cf6e-5b9c-ad80-8564d14cd52a','STATE-WP-0095-T06':'6af973b4-1964-5d4d-a2f8-8dbd4c01fda4','NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'} + + +class Refused(Exception):pass + + +def git(root,*args): + result=subprocess.run(['git','--no-optional-locks','-C',str(root),*args], + capture_output=True,timeout=30,check=False) + if result.returncode:raise Refused('read-only-git-failed') + return result.stdout + + +def field(text,key): + values=re.findall(r'^'+re.escape(key)+r':\s*(.*?)\s*$',text,re.M) + if len(values)!=1:raise Refused('source-field-ambiguous') + return values[0].strip('"\'') + + +def source(text): + header=text.split('---',2)[1] + tasks=[] + for block in re.findall(r'```task\n(.*?)\n```',text,re.S): + deps=re.findall(r'^depends_on:\s*\[(.*?)\]',block,re.M) + tasks.append({'record_id':field(block,'id'),'id':field(block,'state_hub_task_id'), + 'status':field(block,'status'),'dependencies':[x.strip() for x in deps[0].split(',') if x.strip()] if deps else []}) + return {'id':field(header,'state_hub_workstream_id'),'source_record_id':field(header,'id'), + 'slug':field(header,'id').lower(), + 'status':field(header,'status'),'tasks':tasks} + + +def get(path): + class NoRedirect(urllib.request.HTTPRedirectHandler): + def redirect_request(self,*args,**kwargs):raise Refused('hub-redirect-refused') + opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect) + with opener.open(urllib.request.Request(API+path,method='GET'),timeout=20) as response: + data=response.read(8*1024**2+1) + if len(data)>8*1024**2:raise Refused('hub-read-limit') + return json.loads(data) + + +def index_stat(root): + raw=git(root,'rev-parse','--git-path','index').decode().strip();path=Path(raw) + if not path.is_absolute():path=root/path + try:item=path.lstat() + except FileNotFoundError:return None + return [item.st_dev,item.st_ino,item.st_size,item.st_mtime_ns,item.st_mode] + + +def remote(root,expected,repo): + if git(root,'remote','get-url','origin').decode().strip()!='forgejo-remote:coulomb/'+repo+'.git': + raise Refused('remote-route-drift') + lines=git(root,'ls-remote','--symref','origin','HEAD','refs/heads/main').decode().splitlines() + if set(lines)!={'ref: refs/heads/main\tHEAD',expected+'\tHEAD',expected+'\trefs/heads/main'}: + raise Refused('remote-head-mismatch') + return {'HEAD':expected,'refs/heads/main':expected,'symbolic_HEAD':'refs/heads/main'} + + +def verify(): + result={'status':'unverified','scope':'RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots', + 'writes_to_source_index_refs_or_Hub':False,'rows':[]} + try: + if API not in {'http://127.0.0.1:8000','http://127.0.0.1:18080','http://10.43.68.154:8000'}: + raise Refused('unrecognized-hub-endpoint') + health=get('/state/health') + result['hub_instance']={key:health.get(key) for key in ('status','instance_role','instance_label')} + if result['hub_instance']!={'status':'ok','instance_role':'primary','instance_label':'railiance01'}: + raise Refused('hub-identity-mismatch') + for owner in OWNERS: + root=Path('/home/worsch')/owner['repo'];before_index=index_stat(root) + if git(root,'rev-parse','HEAD').decode().strip()!=owner['commit']: + raise Refused('local-head-drift') + committed=git(root,'show',owner['commit']+':'+owner['path']) + local=(root/owner['path']).read_bytes() + if local!=committed:raise Refused('published-workplan-local-drift') + expected=source(committed.decode()) + if expected['source_record_id']!=owner['id'] or len(expected['tasks'])!=owner['tasks']: + raise Refused('source-task-denominator-mismatch') + snapshot=get('/repos/'+owner['repo']+'/work-record-projection/snapshot') + plans=[row for row in snapshot['workplans'] if row['id']==expected['id']] + if len(plans)!=1 or any(plans[0].get(key)!=expected[key] for key in ('id','slug','status')): + raise Refused('workplan-binding-mismatch') + projected=[row for row in snapshot['tasks'] + if row.get('workplan_id',row.get('workstream_id'))==expected['id']] + if len(projected)!=len(expected['tasks']):raise Refused('projected-task-denominator-mismatch') + byid={row['id']:row for row in projected} + if len(byid)!=len(projected):raise Refused('duplicate-projected-uuid') + observed=[] + for task in expected['tasks']: + row=byid.get(task['id'],{}) + if any(row.get(key)!=task[key] for key in ('id','record_id','status')): + raise Refused('task-id-uuid-status-mismatch') + observed.append({key:row[key] for key in ('id','record_id','status')}) + identifiers={task['record_id']:task['id'] for task in expected['tasks']}|EXTERNAL + edges={(task['id'],identifiers[dep],'starts_after') for task in expected['tasks'] for dep in task['dependencies']} + actual=[edge for edge in snapshot['dependencies'] if edge['from_workplan_id']==expected['id']] + projected_edges={(edge.get('from_task_id'),edge.get('to_task_id'),edge['relationship_type']) for edge in actual} + if len(actual)!=len(edges) or projected_edges!=edges: + raise Refused('dependency-binding-mismatch') + if any(edge.get('source_commit') not in (None,owner['commit']) for edge in actual): + raise Refused('dependency-source-commit-mismatch') + for task in expected['tasks']: + for dep in task['dependencies']: + if dep in EXTERNAL: + target=get('/tasks/'+EXTERNAL[dep]) + if target.get('id')!=EXTERNAL[dep] or target.get('record_id')!=dep: + raise Refused('external-dependency-target-mismatch') + remote_readback=remote(root,owner['commit'],owner['repo']) + if index_stat(root)!=before_index or (root/owner['path']).read_bytes()!=local: + raise Refused('source-or-index-stat-changed') + result['rows'].append({'repo':owner['repo'],'published_commit':owner['commit'], + 'remote':remote_readback,'workplan':{key:plans[0][key] for key in ('id','slug','status')}, + 'source_record_id':expected['source_record_id'], + 'tasks':observed,'dependencies':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(edges)], + 'source_file_sha256':hashlib.sha256(local).hexdigest(),'source_file_unchanged':True, + 'index_stat_unchanged':True}) + result['status']='verified' + except Exception as error: + result['reason']=error.args[0] if isinstance(error,Refused) else 'readback-unavailable' + result['verifier_sha256']=hashlib.sha256(Path(__file__).read_bytes()).hexdigest() + (HERE/'registrar-publication-readback.json').write_text(json.dumps(result,indent=2)+'\n') + print(json.dumps({'status':result['status'],'owners':len(result['rows'])})) + return 0 if result['status']=='verified' else 2 + + +if __name__=='__main__':raise SystemExit(verify()) diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.json new file mode 100644 index 00000000..afa6e6fd --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.json @@ -0,0 +1,41 @@ +{ + "schema": "custodian.registrar-receiving-return.v1", + "status": "verified", + "proposal_id": "STATE-WP-0095-T06-cluster-frozen-receiving-r1", + "receiver_source_commit": "51bc70d1ff8f25450a8650d8e50caf053093a02e", + "receiver_image_digest": "sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015", + "delivered_module_sha256": "e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2", + "schema_revision": "c4d5e6f7a8b9", + "api_ready": true, + "mcp_ready": true, + "historical_three_parents_fifteen_tasks_preserved": true, + "safe_refusal_probe_rollback_verified": true, + "helm_revision": 76, + "verified_at": "2026-10-17T00:07:47.015454+00:00", + "native_receipts": [ + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/delivered-runtime.json", + "sha256": "89681066e8fe139456163ebfafa3efe77ffae8534ea167219230b0a74367f129" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/native-refusal-probes.json", + "sha256": "673ccef965c820704dc310a1bf7832b583c30c3edfeb814528cf892555199172" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-full-row-hashes.json", + "sha256": "75cdd87eef79059ff3f484ed24ca69e285899cdf8d851cc4e472653c417eb0ee" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-full-row-hashes.json", + "sha256": "2156aad18f190384838c27e792706a156a7423391408afbc6107e6c28c5872d8" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/helm-return.json", + "sha256": "61727deacf22d37da2d28cbaf04f5a3ddee0f9ff7571c77f1e85dba97963b572" + }, + { + "path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/job-observation.json", + "sha256": "b0db49a54f040142be46f0caa76bfd3f09e4ac060fbc1e88c74c4077eeb0552c" + } + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.pending-template.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.pending-template.json new file mode 100644 index 00000000..e0b5750b --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.pending-template.json @@ -0,0 +1,15 @@ +{ + "schema": "custodian.registrar-receiving-return.v1", + "status": "pending-root-native-verification", + "proposal_id": "STATE-WP-0095-T06-cluster-frozen-receiving-r1", + "receiver_source_commit": "51bc70d1ff8f25450a8650d8e50caf053093a02e", + "receiver_image_digest": "sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015", + "delivered_module_sha256": "e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2", + "schema_revision": "c4d5e6f7a8b9", + "api_ready": null, + "mcp_ready": null, + "historical_three_parents_fifteen_tasks_preserved": null, + "safe_refusal_probe_rollback_verified": null, + "native_receipts": [], + "authority_note": "evidence binding only; root explicit go remains required" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-commit.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-commit.json new file mode 100644 index 00000000..c63b59d0 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-commit.json @@ -0,0 +1,49 @@ +{ + "status": "committed-exact-seven-paths", + "head": "70cd754996870638848616e37819790a5c4d52b3", + "parent": "9ebde0a9bd60d5c82910494fbe6bd1b891455cee", + "paths": [ + "src/repo_manager/historical_sources.py", + "src/repo_manager/identifiers.py", + "tests/test_cluster_frozen_history.py", + "workplans/RMGR-WP-0019-historical-source-admission.md", + "tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md", + "tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md", + "tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md" + ], + "managed_assignments": [ + { + "kind": "task", + "record_id": "RMGR-WP-0019-T04", + "uuid": "1ccb06c6-ad30-5847-8704-e5628ba81f35", + "path": "workplans/RMGR-WP-0019-historical-source-admission.md" + }, + { + "kind": "task", + "record_id": "RMGR-WP-0019-T05", + "uuid": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "path": "workplans/RMGR-WP-0019-historical-source-admission.md" + }, + { + "kind": "task", + "record_id": "RMGR-WP-0019-T06", + "uuid": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "path": "workplans/RMGR-WP-0019-historical-source-admission.md" + } + ], + "scanner_sha256_unchanged": "e709c658f779534fcab093207b0a78e49d54fc584c515fdf7ac535ce75f6c400", + "t05": "done", + "t06": "wait", + "commit_output": "[main 70cd754] Admit exact frozen Cluster histories after verified receiving\n 7 files changed, 934 insertions(+), 6 deletions(-)\n create mode 100644 tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md\n create mode 100644 tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md\n create mode 100644 tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md\n create mode 100644 tests/test_cluster_frozen_history.py\n", + "source_files": { + "src/repo_manager/historical_sources.py": "838a0422b81e1215e3ec148c3104dd603d9dfc476610bb5617d98ccf5d3be218", + "src/repo_manager/identifiers.py": "4e35fcd009c20822574fd33171176bd14a1ff2dd5af8b0bb2820954974593a2a", + "tests/test_cluster_frozen_history.py": "0490ef3eb474f653e4a6a52b711999876bef061c07de3e7a6d327a8ba54acaf3", + "workplans/RMGR-WP-0019-historical-source-admission.md": "c09c685313de13ad4a31891fd67b8a92f3d9a085c37cee92257d15b485a32cde", + "tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md": "8d6f8533c119117686bc0d5bb9ed5349726aa6c3189ff98b53409c68ac685ca9", + "tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md": "4dc2f61e15adc3c5c81f9ecf8b933512275b95e8f829fac52ae7cde1385cea4a", + "tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md": "04f787078232395bd2d43861de16c521848559fa286f06e1caa9cb779aa71ac3" + }, + "receiving_gate_sha256": "d088c336d62c7bdde0e586b0f1b73c3aa3d4031a4debd9ac90206128728257f4", + "cluster_source_mutation": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-publication-readback.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-publication-readback.json new file mode 100644 index 00000000..f7bc6c7a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-publication-readback.json @@ -0,0 +1,136 @@ +{ + "status": "verified", + "scope": "RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots", + "writes_to_source_index_refs_or_Hub": false, + "rows": [ + { + "repo": "repo-manager", + "published_commit": "70cd754996870638848616e37819790a5c4d52b3", + "remote": { + "HEAD": "70cd754996870638848616e37819790a5c4d52b3", + "refs/heads/main": "70cd754996870638848616e37819790a5c4d52b3", + "symbolic_HEAD": "refs/heads/main" + }, + "workplan": { + "id": "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab", + "slug": "rmgr-wp-0019", + "status": "active" + }, + "source_record_id": "RMGR-WP-0019", + "tasks": [ + { + "id": "d78a622e-39f9-5923-b4e1-f70fdc17fb42", + "record_id": "RMGR-WP-0019-T01", + "status": "done" + }, + { + "id": "95240c81-1805-5365-9b35-d238621a16bf", + "record_id": "RMGR-WP-0019-T02", + "status": "done" + }, + { + "id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d", + "record_id": "RMGR-WP-0019-T03", + "status": "done" + }, + { + "id": "1ccb06c6-ad30-5847-8704-e5628ba81f35", + "record_id": "RMGR-WP-0019-T04", + "status": "done" + }, + { + "id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "record_id": "RMGR-WP-0019-T05", + "status": "done" + }, + { + "id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "record_id": "RMGR-WP-0019-T06", + "status": "wait" + } + ], + "external_source_declarations_not_projected": [ + { + "from_task_id": "95240c81-1805-5365-9b35-d238621a16bf", + "target_record_id": "STATE-WP-0095-T03", + "target_uuid": "e8566341-cf6e-5b9c-ad80-8564d14cd52a" + }, + { + "from_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "target_record_id": "STATE-WP-0095-T06", + "target_uuid": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4" + } + ], + "dependencies": [ + { + "from_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "to_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "relationship_type": "starts_after" + }, + { + "from_task_id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d", + "to_task_id": "95240c81-1805-5365-9b35-d238621a16bf", + "relationship_type": "starts_after" + } + ], + "source_file_sha256": "c09c685313de13ad4a31891fd67b8a92f3d9a085c37cee92257d15b485a32cde", + "source_file_unchanged": true, + "dependency_scope": "internal edges verified; external source target identities checked without claiming projected external edges", + "index_stat_unchanged": true + }, + { + "repo": "repo-manager", + "published_commit": "70cd754996870638848616e37819790a5c4d52b3", + "remote": { + "HEAD": "70cd754996870638848616e37819790a5c4d52b3", + "refs/heads/main": "70cd754996870638848616e37819790a5c4d52b3", + "symbolic_HEAD": "refs/heads/main" + }, + "workplan": { + "id": "5aa6f84a-c682-5996-ae26-96daef670833", + "slug": "rmgr-wp-0021", + "status": "active" + }, + "source_record_id": "RMGR-WP-0021", + "tasks": [ + { + "id": "d3d20c18-5a5f-5f8a-b5c4-a22b4b662ebe", + "record_id": "RMGR-WP-0021-T01", + "status": "done" + }, + { + "id": "e27817e6-b298-581f-b99a-05ec459be749", + "record_id": "RMGR-WP-0021-T02", + "status": "done" + }, + { + "id": "0ab44bd9-00d8-5470-ad45-7350e7868d0a", + "record_id": "RMGR-WP-0021-T03", + "status": "progress" + }, + { + "id": "44272818-db49-58a2-83b1-d2f9e9d5976c", + "record_id": "RMGR-WP-0021-T04", + "status": "todo" + }, + { + "id": "25fbe694-41d8-5232-bce0-4ed362387d5a", + "record_id": "RMGR-WP-0021-T05", + "status": "done" + } + ], + "external_source_declarations_not_projected": [], + "dependencies": [], + "source_file_sha256": "966d15ccdabc8edf98bc58f9422ea190566d05fe4208f4749f59a9731f4e108d", + "source_file_unchanged": true, + "dependency_scope": "internal edges verified; external source target identities checked without claiming projected external edges", + "index_stat_unchanged": true + } + ], + "hub_instance": { + "status": "ok", + "instance_role": "primary", + "instance_label": "railiance01" + }, + "verifier_sha256": "a7ea9793e5d31a1deddecf9422e57178cb8734aad9619dc1ec5c4d01cc8b53f7" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-sync.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-sync.json new file mode 100644 index 00000000..843158e1 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-sync.json @@ -0,0 +1,58 @@ +{ + "evidence_type": "normalized actual command output", + "command": [ + "/home/worsch/repo-manager/.venv/bin/rmgr", + "sync", + "--path", + "/home/worsch/repo-manager", + "--push" + ], + "exit_code": 0, + "ok": true, + "status": "applied", + "repo_slug": "repo-manager", + "commit": "70cd754996870638848616e37819790a5c4d52b3", + "requests": 2, + "elapsed_ms": 22911.0, + "git": { + "upstream": "origin/main", + "behind": 0, + "ahead": 0 + }, + "identifiers": { + "assignments": [], + "files_changed": [] + }, + "receipt": { + "schema": "state-hub.repository-projection-reconcile.v1", + "instance_role": "primary", + "instance_label": "railiance01", + "expected_commit": "70cd754996870638848616e37819790a5c4d52b3", + "derived_commit": "70cd754996870638848616e37819790a5c4d52b3", + "outcome": { + "status": "applied", + "counts": { + "created": 0, + "updated": 25, + "retired": 0, + "refused": 0, + "released": 0, + "created_tasks": 3, + "updated_tasks": 0, + "cancelled_tasks": 0, + "created_edges": 1, + "removed_edges": 0, + "unresolved_edges": 0, + "external_edges": 0 + }, + "created_tasks": [ + "RMGR-WP-0019-T04", + "RMGR-WP-0019-T05", + "RMGR-WP-0019-T06" + ], + "refused": [], + "retired": [], + "notes": [] + } + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/source-application.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/source-application.json new file mode 100644 index 00000000..66b4efbc --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/source-application.json @@ -0,0 +1,20 @@ +{ + "status": "applied-exact-local-registrar-source", + "base": "9ebde0a9bd60d5c82910494fbe6bd1b891455cee", + "frozen_patch_sha256": "232552c3d601d185984be5a8e5bc9937bc9ddda7327923b5f0440f6deb2c87fc", + "receiving_gate_sha256": "d088c336d62c7bdde0e586b0f1b73c3aa3d4031a4debd9ac90206128728257f4", + "files": { + "src/repo_manager/historical_sources.py": "838a0422b81e1215e3ec148c3104dd603d9dfc476610bb5617d98ccf5d3be218", + "src/repo_manager/identifiers.py": "4e35fcd009c20822574fd33171176bd14a1ff2dd5af8b0bb2820954974593a2a", + "tests/test_cluster_frozen_history.py": "0490ef3eb474f653e4a6a52b711999876bef061c07de3e7a6d327a8ba54acaf3", + "workplans/RMGR-WP-0019-historical-source-admission.md": "6378d96b70259ae81435b6ce8f97864698bdc5b6679cabbe9dc61a1fc1d09699", + "tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md": "8d6f8533c119117686bc0d5bb9ed5349726aa6c3189ff98b53409c68ac685ca9", + "tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md": "4dc2f61e15adc3c5c81f9ecf8b933512275b95e8f829fac52ae7cde1385cea4a", + "tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md": "04f787078232395bd2d43861de16c521848559fa286f06e1caa9cb779aa71ac3" + }, + "index_unchanged": true, + "allocator_executed": false, + "task_completion_applied": false, + "cluster_source_or_hub_mutation": false, + "commit_or_push_performed": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/source-review.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/source-review.json new file mode 100644 index 00000000..8895f707 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/source-review.json @@ -0,0 +1,55 @@ +{ + "state": "read-onlypreimagesverified; isolatedcandidatechecks only; notcanonicaladmission", + "owner_head": "9ebde0a9bd60d5c82910494fbe6bd1b891455cee", + "frozen_patch_sha256": "232552c3d601d185984be5a8e5bc9937bc9ddda7327923b5f0440f6deb2c87fc", + "preimages": [ + { + "path": "src/repo_manager/historical_sources.py", + "expected": "a465aa595867c5e80918168158f8a27bf429d469b2e5249eca98b4e5ef84ce03", + "actual": "a465aa595867c5e80918168158f8a27bf429d469b2e5249eca98b4e5ef84ce03", + "matched": true + }, + { + "path": "src/repo_manager/identifiers.py", + "expected": "68dbbd3f137f326a49d20ba3f5855d6b00b4d62eb01dc904b51a08d77552d2bf", + "actual": "68dbbd3f137f326a49d20ba3f5855d6b00b4d62eb01dc904b51a08d77552d2bf", + "matched": true + }, + { + "path": "tests/test_cluster_frozen_history.py", + "expected": null, + "actual": null, + "matched": true + }, + { + "path": "workplans/RMGR-WP-0019-historical-source-admission.md", + "expected": "638af4000aa442a57df8eddef2d8b5aa5dffb9dbc9ccf547d9e04cf25012ffe4", + "actual": "638af4000aa442a57df8eddef2d8b5aa5dffb9dbc9ccf547d9e04cf25012ffe4", + "matched": true + }, + { + "path": "tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md", + "expected": null, + "actual": null, + "matched": true + }, + { + "path": "tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md", + "expected": null, + "actual": null, + "matched": true + }, + { + "path": "tests/fixtures/railiance-cluster/workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md", + "expected": null, + "actual": null, + "matched": true + } + ], + "test_exit_code": 0, + "test_result": "............................................... [100%]\n47 passed in 5.34s", + "canonical_registrar_modified": false, + "actual_cluster_allocator_run": false, + "managed_cluster_UUIDs_applied": false, + "scanner_T05_preserved": true +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/verify_registrar_publication.py b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/verify_registrar_publication.py new file mode 100644 index 00000000..a990f039 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/verify_registrar_publication.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +"""Read-only Git+Hub task binding verifier; never syncs or changes source/index.""" +import hashlib +import json +import os +from pathlib import Path +import re +import subprocess +import urllib.request + +HERE=Path(__file__).resolve().parent +OWNERS=[ + {'repo':'repo-manager','commit':'70cd754996870638848616e37819790a5c4d52b3','path':'workplans/RMGR-WP-0019-historical-source-admission.md','id':'RMGR-WP-0019','tasks':6}, + {'repo':'repo-manager','commit':'70cd754996870638848616e37819790a5c4d52b3','path':'workplans/RMGR-WP-0021-secret-detection-controls.md','id':'RMGR-WP-0021','tasks':5}, +] +API=os.environ.get('API_BASE','http://127.0.0.1:8000').rstrip('/') +EXTERNAL={'STATE-WP-0095-T03':'e8566341-cf6e-5b9c-ad80-8564d14cd52a','STATE-WP-0095-T06':'6af973b4-1964-5d4d-a2f8-8dbd4c01fda4','NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'} + + +class Refused(Exception):pass + + +def git(root,*args): + result=subprocess.run(['git','--no-optional-locks','-C',str(root),*args], + capture_output=True,timeout=30,check=False) + if result.returncode:raise Refused('read-only-git-failed') + return result.stdout + + +def field(text,key): + values=re.findall(r'^'+re.escape(key)+r':\s*(.*?)\s*$',text,re.M) + if len(values)!=1:raise Refused('source-field-ambiguous') + return values[0].strip('"\'') + + +def source(text): + header=text.split('---',2)[1] + tasks=[] + for block in re.findall(r'```task\n(.*?)\n```',text,re.S): + deps=re.findall(r'^depends_on:\s*\[(.*?)\]',block,re.M) + tasks.append({'record_id':field(block,'id'),'id':field(block,'state_hub_task_id'), + 'status':field(block,'status'),'dependencies':[x.strip() for x in deps[0].split(',') if x.strip()] if deps else []}) + return {'id':field(header,'state_hub_workstream_id'),'source_record_id':field(header,'id'), + 'slug':field(header,'id').lower(), + 'status':field(header,'status'),'tasks':tasks} + + +def get(path): + class NoRedirect(urllib.request.HTTPRedirectHandler): + def redirect_request(self,*args,**kwargs):raise Refused('hub-redirect-refused') + opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect) + with opener.open(urllib.request.Request(API+path,method='GET'),timeout=20) as response: + data=response.read(8*1024**2+1) + if len(data)>8*1024**2:raise Refused('hub-read-limit') + return json.loads(data) + + +def index_stat(root): + raw=git(root,'rev-parse','--git-path','index').decode().strip();path=Path(raw) + if not path.is_absolute():path=root/path + try:item=path.lstat() + except FileNotFoundError:return None + return [item.st_dev,item.st_ino,item.st_size,item.st_mtime_ns,item.st_mode] + + +def remote(root,expected,repo): + if git(root,'remote','get-url','origin').decode().strip()!='forgejo-remote:coulomb/'+repo+'.git': + raise Refused('remote-route-drift') + lines=git(root,'ls-remote','--symref','origin','HEAD','refs/heads/main').decode().splitlines() + if set(lines)!={'ref: refs/heads/main\tHEAD',expected+'\tHEAD',expected+'\trefs/heads/main'}: + raise Refused('remote-head-mismatch') + return {'HEAD':expected,'refs/heads/main':expected,'symbolic_HEAD':'refs/heads/main'} + + +def verify(): + result={'status':'unverified','scope':'RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots', + 'writes_to_source_index_refs_or_Hub':False,'rows':[]} + try: + if API not in {'http://127.0.0.1:8000','http://127.0.0.1:18080','http://10.43.68.154:8000'}: + raise Refused('unrecognized-hub-endpoint') + health=get('/state/health') + result['hub_instance']={key:health.get(key) for key in ('status','instance_role','instance_label')} + if result['hub_instance']!={'status':'ok','instance_role':'primary','instance_label':'railiance01'}: + raise Refused('hub-identity-mismatch') + for owner in OWNERS: + root=Path('/home/worsch')/owner['repo'];before_index=index_stat(root) + if git(root,'rev-parse','HEAD').decode().strip()!=owner['commit']: + raise Refused('local-head-drift') + committed=git(root,'show',owner['commit']+':'+owner['path']) + local=(root/owner['path']).read_bytes() + if local!=committed:raise Refused('published-workplan-local-drift') + expected=source(committed.decode()) + if expected['source_record_id']!=owner['id'] or len(expected['tasks'])!=owner['tasks']: + raise Refused('source-task-denominator-mismatch') + snapshot=get('/repos/'+owner['repo']+'/work-record-projection/snapshot') + plans=[row for row in snapshot['workplans'] if row['id']==expected['id']] + if len(plans)!=1 or any(plans[0].get(key)!=expected[key] for key in ('id','slug','status')): + raise Refused('workplan-binding-mismatch') + projected=[row for row in snapshot['tasks'] + if row.get('workplan_id',row.get('workstream_id'))==expected['id']] + if len(projected)!=len(expected['tasks']):raise Refused('projected-task-denominator-mismatch') + byid={row['id']:row for row in projected} + if len(byid)!=len(projected):raise Refused('duplicate-projected-uuid') + observed=[] + for task in expected['tasks']: + row=byid.get(task['id'],{}) + if any(row.get(key)!=task[key] for key in ('id','record_id','status')): + raise Refused('task-id-uuid-status-mismatch') + observed.append({key:row[key] for key in ('id','record_id','status')}) + identifiers={task['record_id']:task['id'] for task in expected['tasks']} + edges={(task['id'],identifiers[dep],'starts_after') for task in expected['tasks'] for dep in task['dependencies'] if dep in identifiers} + actual=[edge for edge in snapshot['dependencies'] if edge['from_workplan_id']==expected['id']] + projected_edges={(edge.get('from_task_id'),edge.get('to_task_id'),edge['relationship_type']) for edge in actual} + if len(actual)!=len(edges) or projected_edges!=edges: + raise Refused('dependency-binding-mismatch') + if any(edge.get('source_commit') not in (None,owner['commit']) for edge in actual): + raise Refused('dependency-source-commit-mismatch') + for task in expected['tasks']: + for dep in task['dependencies']: + if dep in EXTERNAL: + target=get('/tasks/'+EXTERNAL[dep]) + if target.get('id')!=EXTERNAL[dep] or target.get('record_id')!=dep: + raise Refused('external-dependency-target-mismatch') + remote_readback=remote(root,owner['commit'],owner['repo']) + if index_stat(root)!=before_index or (root/owner['path']).read_bytes()!=local: + raise Refused('source-or-index-stat-changed') + result['rows'].append({'repo':owner['repo'],'published_commit':owner['commit'], + 'remote':remote_readback,'workplan':{key:plans[0][key] for key in ('id','slug','status')}, + 'source_record_id':expected['source_record_id'], + 'tasks':observed,'external_source_declarations_not_projected':[{'from_task_id':task['id'],'target_record_id':dep,'target_uuid':EXTERNAL[dep]} for task in expected['tasks'] for dep in task['dependencies'] if dep in EXTERNAL],'dependencies':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(edges)], + 'source_file_sha256':hashlib.sha256(local).hexdigest(),'source_file_unchanged':True,'dependency_scope':'internal edges verified; external source target identities checked without claiming projected external edges', + 'index_stat_unchanged':True}) + result['status']='verified' + except Exception as error: + result['reason']=error.args[0] if isinstance(error,Refused) else 'readback-unavailable' + result['verifier_sha256']=hashlib.sha256(Path(__file__).read_bytes()).hexdigest() + (HERE/'registrar-publication-readback.json').write_text(json.dumps(result,indent=2)+'\n') + print(json.dumps({'status':result['status'],'owners':len(result['rows'])})) + return 0 if result['status']=='verified' else 2 + + +if __name__=='__main__':raise SystemExit(verify()) diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/wp19-actual-projected-dependencies.json b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/wp19-actual-projected-dependencies.json new file mode 100644 index 00000000..a99f98ee --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/wp19-actual-projected-dependencies.json @@ -0,0 +1,28 @@ +[ + { + "id": "5f8d26dc-836c-40a0-92ad-409e0c03c9ba", + "from_workplan_id": "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab", + "from_task_id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d", + "to_workplan_id": null, + "to_task_id": "95240c81-1805-5365-9b35-d238621a16bf", + "relationship_type": "starts_after", + "description": "RMGR-WP-0019-T03 depends_on RMGR-WP-0019-T02", + "source_owner": null, + "source_commit": null, + "created_at": "2026-10-06T08:38:27.839836Z", + "updated_at": "2026-10-06T08:38:27.839836Z" + }, + { + "id": "6830cfe7-d935-4682-af36-b1f508cf73d6", + "from_workplan_id": "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab", + "from_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "to_workplan_id": null, + "to_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "relationship_type": "starts_after", + "description": "RMGR-WP-0019-T06 depends_on RMGR-WP-0019-T05", + "source_owner": "forge:repo-manager", + "source_commit": "70cd754996870638848616e37819790a5c4d52b3", + "created_at": "2026-10-17T00:11:55.880322Z", + "updated_at": "2026-10-17T00:11:55.880322Z" + } +] diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/WP19.candidate.md b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/WP19.candidate.md new file mode 100644 index 00000000..f4b92915 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/WP19.candidate.md @@ -0,0 +1,297 @@ +--- +id: RMGR-WP-0019 +type: workplan +title: "Admit exact historical source views after receiving preservation support" +domain: infotech +repo: repo-manager +status: active +owner: codex +created: "2026-10-04" +updated: "2026-10-17" +flavor: implementation +depends_on: [] +state_hub_workstream_id: "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab" +--- + +## Goal + +Unblock normal authoritative registration of the exact closed Activity legacy +source views and Custodian retired ADHOC source after receiving preserves their +existing records. Preserve every legacy source byte, label and UUID; do not +expand canonical syntax or the general grandfathering rules. CUST-WP-0077 owns +cross-owner coordination with STATE-WP-0095. + +## Review exact historical receiving contract + +```task +id: RMGR-WP-0019-T01 +status: done +priority: high +state_hub_task_id: "d78a622e-39f9-5923-b4e1-f70fdc17fb42" +``` + +Seven Activity sources yield four existing parents/64 closed bound tasks; +three split views repeat the archived parent. One Custodian retired source keeps +its existing parent/task IDs. Earlier /tmp/activity-core-bound-history-write.py +is superseded and must not be applied: registrar bypass alone would admit an +unsupported receiving projection. RMGR-WP-0014/0015 are finished and do not own +this new implementation demand; this workplan is not residual. + +## Enable exact frozen registrar exceptions after receiving deployment + +```task +id: RMGR-WP-0019-T02 +status: done +priority: high +depends_on: [STATE-WP-0095-T03] +state_hub_task_id: "95240c81-1805-5365-9b35-d238621a16bf" +``` + +Prepared code permits only source paths with reviewed full SHA256 digests in +repo_manager/historical_sources.py. Strict conformance scans retain their legacy +findings. Unknown/missing/altered source refuses before allocation. Source UUIDs +are neither changed nor allocated for these histories. Receiving and registrar +manifests must remain identical. Apply helper requires a deployment receipt. + +## Run normal owner sync and verify preserved identities + +```task +id: RMGR-WP-0019-T03 +status: done +priority: high +depends_on: [RMGR-WP-0019-T02] +state_hub_task_id: "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d" +``` + +Use rmgr sync --path --push. No deep-check repair or direct hub UUID +patch substitutes for receiving. Historical unrelated stale projections are not +retirement-authorized by this workplan. Feed receipts back to STATE-WP-0095-T04. + +## Offline evidence, 2026-10-04 + +Prepared registrar suite: 38 focused cases passed (identifiers, registrar, +Custodian legacy identity and exact frozen source cases). Read-only execute=False +against both current owning repos accepted exact histories without source writes. +Implementation is staged; deployment gate is unresolved. + +## Approved deployment and actual registrar verification, 2026-10-04 + +STATE-WP-0095-T03 returned verified main-5dd3df9 / Helm revision72. +Global task-holder refusal passed inside the delivered API against the retired +Custodian parent, with transaction rollback and no committed probe. Five +historical parents/65 tasks retained their entire row snapshots. The gated +three-file registrar patch committed as c41d36c2ef8930628221ef36ec81d8b5d2145ed6; +38 actual owning-source cases passed and Repo Manager primary sync applied. + +Normal owner sync admitted all exact frozen histories without changing their +source bytes, UUIDs, parent ownership or row content. Custodian receiving +applied. Activity receiving refused only three empty duplicate projections +that would be retired; no retirement acknowledgement was issued. Registrar +allocated four missing IDs in ordinary Activity ad-hoc sources through its +normal path; frozen historical source files stayed unchanged. T03 remains wait +for explicit disposition and bounded receiving support under STATE-WP-0095-T04 +(decision91b7c633-a66f-5d43-9f4b-6565aefb9356). +Evidence: docs/evidence/2026-10-04-historical-registrar-verification.json. + +## Ungated T03 preparation, 2026-10-06 + +Re-ran the registrar suite at 8a47a5c (registrar source unchanged since +c41d36c2): 89 focused registrar/identity/historical cases and the full suite +(226) passed. Read-only hub check: the three refused projections are +683724d9 (custodian-wp-0003), 644017c7 (custodian-wp-0003a) and a5806df9 +(custodian-wp-0003b), each with zero tasks; every custodian-WP-0003* source +file binds parent b4eb45a9, which holds the tasks and must not be retired. +Added repo_manager.retirement_disposition, a read-only check that an Activity +expected_retirement_uuids set equals exactly those three empty projections and +excludes the preserved parent. It authorizes nothing; retirement stays with +Activity receiving under STATE-WP-0095-T04. + +## Activity disposition received, 2026-10-06 + +activity-core returned the exact expected_retirement_uuids (message 17ba4201, +evidence activity-core 941fac0, ACTIVITY-WP-0045): 683724d9, 644017c7, +a5806df9. repo_manager.retirement_disposition accepted the set: it equals the +three projections the 2026-10-04 run refused, each holds zero tasks, and it +excludes preserved parent b4eb45a9. Nothing was applied. T03 stays wait: its +acceptance needs a successful Activity owner sync with receipts, which can run +only after the founder decides 91b7c633 and STATE-WP-0095-T04 retires exactly +this set in a reviewed live rollout. Then re-run rmgr sync --path +~/activity-core --push and feed the receipt back to STATE-WP-0095-T04. + +## Post-retirement owner sync attempt, 2026-10-06 + +State Hub reported decision 91b7c633 resolved, main-968a811 / Helm rev 74 +deployed, and Activity reconcile at 67a92d2 retiring exactly the three empty +projections (3 retired, 0 created, 0 refused; 4 historical parents / 64 tasks +unchanged). Evidence: state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. +`rmgr sync --path ~/activity-core --push` stopped before reconciliation with +status pending_commit: uncommitted `state_hub_workstream_id` / `state_hub_task_id` +writeback in activity-core workplans/ACTIVITY-WP-0045-stale-historical-projection-disposition.md +(plus WORK-RECORDS.md). No hub request was made. Repo Manager does not commit in +activity-core; T03 stays wait until Activity Core commits and the sync re-runs. + +Re-run 2026-10-06 08:42Z after Activity Core committed the writeback (e809fb2): +status applied, created 0 / updated 45 (ACTIVITY-WP only) / retired 0 / refused 0, +no task changes, notes preserve custodian-WP-0001..0004 UUIDs; hub shows 4 parents, +64 tasks. Not closed: historical parent b4eb45a9 (custodian-WP-0003, source +`status: archived`, evidence snapshot archived) now reads `finished` in the hub, +updated 08:42:03Z during this sync. Needs State Hub review before T03 closes. + +Closed 2026-10-06: State Hub traced the b4eb45a9 status change to its own C-04 +check, which ran once per file. The custodian-WP-0003a/b/c split views share the +parent UUID, so whichever view ran last set the row. The Forge reconcile did not +cause it. Fixed in state-hub 2b5d8f9 (STATE-WP-ADHOC-2026-10-06-T01); b4eb45a9 is +back to `archived`. Re-check: 4 parents (b4eb45a9 archived; 3a4f47d9, 759b1255, +e22516cc finished) holding 64 tasks (24+12+7+21). Receipt: Activity sync at e809fb2, +primary/railiance01, applied, 0 created / 45 updated (ACTIVITY-WP only) / 0 retired +/ 0 refused, 0 task changes, historical UUIDs preserved. Evidence: +state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. + + +## Cluster exact historical source successor, 2026-10-17 + +This scoped extension preserves the completed Activity/Custodian work above. +The cluster publisher now refuses three closed RAIL-BS source files containing +15 existing UUID-bound bare task labels. Preserve all three source bytes, IDs, +and UUIDs. No new alias or general syntax exemption is introduced. Evidence and +exact receiver-first proposal: cluster-historical-publication-r1 in the Custodian +NetKingdom change packet. The existing SHR-WP-0001 project driver owns the +Repo Manager / State Hub cross-owner wait; NK-WP-0049-T35 benefits from the +blocked cluster publication. No worker or human gate is woken here. + +## Prepare exact cluster registrar successor + +```task +id: RMGR-WP-0019-T04 +status: done +priority: high +state_hub_task_id: "1ccb06c6-ad30-5847-8704-e5628ba81f35" +``` + +Prepared full-file SHA256 bindings for three archives and 15 exact task +occurrences; strict scans still return 15 invalid labels and five collisions. +Unknown/live sources, changed/missing/symlinked histories, UUID drift and +qualified/global collisions refuse before allocation. Candidate tests pass 47; +canonical application remains a separate reviewed step. The read-only current +cluster preview proposes seven ordinary UUID bindings in two files and changes +no bytes. One pre-existing ADHOC field is included explicitly: task +RCLUSTER-WP-ADHOC-2026-07-27-T01 in workplans/ADHOC-2026-07-27.md receives +3e3f39d3-5070-5ba3-97db-19f5f361f264 through managed allocation only. + +## Admit cluster registrar successor only after receiving verification + +```task +id: RMGR-WP-0019-T05 +status: done +priority: high +depends_on: [STATE-WP-0095-T06] +state_hub_task_id: "36f47e21-42d0-5aef-b065-4a5dd3af0726" +``` + +Retain the current guard until exact reviewed receiving source has been delivered +and verified through State Hub's normal owner deployment. Match both manifests, +then integrate reviewed registrar source and verify ordinary allocator preview. +No direct API patch, history rename or bypass substitutes for this gate. + +## Run ordinary cluster owner publication and verify preservation + +```task +id: RMGR-WP-0019-T06 +status: wait +priority: high +depends_on: [RMGR-WP-0019-T05, STATE-WP-0095-T10] +blocking_reason: "Await State Hub T10 founder approval, delivered API guard verification and explicit current-baseline/historical-exception disposition; original parent hashes are not restored." +state_hub_task_id: "4d1675b6-f49f-5b01-8d76-bbf2030d1b34" +``` + +Only then run normal owner consistency/publication with the reviewed expected +file set: RCLUSTER-WP-0018 and the one-field ADHOC managed backfill, plus ordinary +generated indexes. Preserve all three archived files and all 18 existing +parent/task rows. Return actual receiving/publication receipts to STATE-WP-0095-T07. +Do not infer TLS recovery, credential custody or native acceptance from sync. + +Cluster publication returned, preservation acceptance failed, 2026-10-17: +normal owner publication at c562d7134c38679952a8ffd17a8a893a900aef0d +is applied on primary/railiance01 with expected and derived commits equal. +Read-only source/remote/Hub verification confirms WP0018's five task bindings +and three internal dependency edges. These publication results do not close T06. +The full-row guard after the required legacy deep consistency pass failed: +all three historical parent full-row hashes changed; all 15 historical task +full-row hashes remain equal. The entire pipeline therefore has no successful +18-row preservation acceptance. + +Custodian receipts under docs/changes/netkingdom-target-2026-10-17: +railiance-cluster-projection.json and cluster-publication-readback.json retain +the applied publication and bounded readback; receiver-rollout-r4/ +pre-publication-full-row-hashes.json retains the passing pre-publication guard; +receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json retains the +failed native comparison. Exact receipt digests are retained in +registrar-t06-preservation-failure-r1/manifest.json. Coordinator and recovery +source review identified the unguarded PUT /workplans/index/bindings path +writing backing_synced_at and ORM updated_at, outside the native forge +projection's preservation guard. Full baseline rows were not retained, only +full-row hashes; no guessed database restoration is authorized or claimed. + +The original rollout's pre-Cluster preservation/refusal verification remains +valid for that earlier stage, and T05 remains done. T06 stays wait pending +the reviewed exact-frozen binding guard, regression coverage and a verified +recovery/preservation disposition. No source or native gate is promoted by the +successful publication alone; no TLS or credential-custody acceptance follows. + +Verified installed-client successor, 2026-10-17: after verifying the installed +R6 checker module rather than assuming canonical source was loaded, the full +normal Cluster maintenance pipeline preserved all 18 CURRENT historical row +hashes. It synced 20/20 ordinary bindings while omitting the three exact frozen +histories. Cluster HEAD remained 6ae3f847c83da3402883453ee7110457bfb2d0d6; +the owner's original staged brief and dirty WORK-RECORDS content were preserved. +Passing CURRENT before/after snapshots are retained under the Custodian packet +receiver-rollout-r4/before-verified-client.json and after-verified-client.json; +verified-loaded-client.json, verified-client-cluster-consistency.json and +verified-client-cluster-projection.json retain the actual client/pipeline proof. +This new baseline pass does not restore or replace the earlier failed three +parent comparisons; those failures and unavailable original preimages remain. + +The new API guard artifact c103cbf3c8bed5dba87a03e320595ddded9301a3 at +image digest sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1 +has image-only server dry-run proof, not delivered-runtime acceptance. T06 +therefore also depends on STATE-WP-0095-T10. Founder decision +df703266-6719-4c04-ae1b-ba9afd3bca1c remains pending for exact proposal +STATE-WP-0095-T10-frozen-bindings-guard-r1 revision 1, metadata SHA256 +81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932, in +Custodian docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/. +That decision includes the proposed CURRENT-baseline acceptance with the +earlier mismatch retained as an exception; no baseline disposition is inferred +here. Await its approved scope and verified owner return before T06 closes. +T05 stays done; no runtime activation, guessed database restoration, worker +wakeup, TLS recovery or native private-admission acceptance follows. + + +## Receiver-first registrar source follow-through, 2026-10-17 + +The exact receiving return is retained in Custodian +`docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json`, +bound to the actual native rollout/preservation/refusal receipts. It verifies the +reviewed receiver source/image/module, API/MCP readiness, expected additive schema, +three existing historical parents/15 tasks and rolled-back safe refusal probes. +Only after that return was the exact registrar patch +`232552c3d601d185984be5a8e5bc9937bc9ddda7327923b5f0440f6deb2c87fc` +admitted in the Repo Manager owner source. T04 retains its source-preparation +outcome; T05 records this receiving-gated registrar admission, not a substitute +for receiving. Canonical focused registrar/identity checks passed 47 cases in 5.84 seconds. +The actual bounded read-only current Cluster allocator preview agreed with the +reviewed source: seven ordinary missing UUID bindings in exactly the new WP0018 and +one-field existing ADHOC backfill, with 15 invalid labels/five collisions still +reported by the strict conformance scan. The three historical file bytes, IDs, +UUIDs and ownership are unchanged. No broad syntax relaxation or direct Hub UUID +patch is introduced. Exact source application/test/preview receipts travel with +the same packet; source publication/projection is verified separately. + +T06 remains wait until actual ordinary Cluster owner publication and receiving +preservation are verified. Registrar source readiness alone does not mark that +publication complete. Preserve the 18 existing rows and all three archives; the +root coordinator owns the normal seven-field managed allocation and dirty-source +preservation. Own Repo Manager projection must show exactly T01–T05 done, T06 +wait and active workplan status, including the managed new T04/T05/T06 UUIDs and +unchanged earlier task UUIDs. The separate scanner RMGR-WP-0021-T05 completion +and unrelated owner work remain untouched. No native TLS recovery, custody, +current registration/private admission or NetKingdom target acceptance follows. diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/WP19.preimage.md b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/WP19.preimage.md new file mode 100644 index 00000000..98cc2d2a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/WP19.preimage.md @@ -0,0 +1,269 @@ +--- +id: RMGR-WP-0019 +type: workplan +title: "Admit exact historical source views after receiving preservation support" +domain: infotech +repo: repo-manager +status: active +owner: codex +created: "2026-10-04" +updated: "2026-10-17" +flavor: implementation +depends_on: [] +state_hub_workstream_id: "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab" +--- + +## Goal + +Unblock normal authoritative registration of the exact closed Activity legacy +source views and Custodian retired ADHOC source after receiving preserves their +existing records. Preserve every legacy source byte, label and UUID; do not +expand canonical syntax or the general grandfathering rules. CUST-WP-0077 owns +cross-owner coordination with STATE-WP-0095. + +## Review exact historical receiving contract + +```task +id: RMGR-WP-0019-T01 +status: done +priority: high +state_hub_task_id: "d78a622e-39f9-5923-b4e1-f70fdc17fb42" +``` + +Seven Activity sources yield four existing parents/64 closed bound tasks; +three split views repeat the archived parent. One Custodian retired source keeps +its existing parent/task IDs. Earlier /tmp/activity-core-bound-history-write.py +is superseded and must not be applied: registrar bypass alone would admit an +unsupported receiving projection. RMGR-WP-0014/0015 are finished and do not own +this new implementation demand; this workplan is not residual. + +## Enable exact frozen registrar exceptions after receiving deployment + +```task +id: RMGR-WP-0019-T02 +status: done +priority: high +depends_on: [STATE-WP-0095-T03] +state_hub_task_id: "95240c81-1805-5365-9b35-d238621a16bf" +``` + +Prepared code permits only source paths with reviewed full SHA256 digests in +repo_manager/historical_sources.py. Strict conformance scans retain their legacy +findings. Unknown/missing/altered source refuses before allocation. Source UUIDs +are neither changed nor allocated for these histories. Receiving and registrar +manifests must remain identical. Apply helper requires a deployment receipt. + +## Run normal owner sync and verify preserved identities + +```task +id: RMGR-WP-0019-T03 +status: done +priority: high +depends_on: [RMGR-WP-0019-T02] +state_hub_task_id: "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d" +``` + +Use rmgr sync --path --push. No deep-check repair or direct hub UUID +patch substitutes for receiving. Historical unrelated stale projections are not +retirement-authorized by this workplan. Feed receipts back to STATE-WP-0095-T04. + +## Offline evidence, 2026-10-04 + +Prepared registrar suite: 38 focused cases passed (identifiers, registrar, +Custodian legacy identity and exact frozen source cases). Read-only execute=False +against both current owning repos accepted exact histories without source writes. +Implementation is staged; deployment gate is unresolved. + +## Approved deployment and actual registrar verification, 2026-10-04 + +STATE-WP-0095-T03 returned verified main-5dd3df9 / Helm revision72. +Global task-holder refusal passed inside the delivered API against the retired +Custodian parent, with transaction rollback and no committed probe. Five +historical parents/65 tasks retained their entire row snapshots. The gated +three-file registrar patch committed as c41d36c2ef8930628221ef36ec81d8b5d2145ed6; +38 actual owning-source cases passed and Repo Manager primary sync applied. + +Normal owner sync admitted all exact frozen histories without changing their +source bytes, UUIDs, parent ownership or row content. Custodian receiving +applied. Activity receiving refused only three empty duplicate projections +that would be retired; no retirement acknowledgement was issued. Registrar +allocated four missing IDs in ordinary Activity ad-hoc sources through its +normal path; frozen historical source files stayed unchanged. T03 remains wait +for explicit disposition and bounded receiving support under STATE-WP-0095-T04 +(decision91b7c633-a66f-5d43-9f4b-6565aefb9356). +Evidence: docs/evidence/2026-10-04-historical-registrar-verification.json. + +## Ungated T03 preparation, 2026-10-06 + +Re-ran the registrar suite at 8a47a5c (registrar source unchanged since +c41d36c2): 89 focused registrar/identity/historical cases and the full suite +(226) passed. Read-only hub check: the three refused projections are +683724d9 (custodian-wp-0003), 644017c7 (custodian-wp-0003a) and a5806df9 +(custodian-wp-0003b), each with zero tasks; every custodian-WP-0003* source +file binds parent b4eb45a9, which holds the tasks and must not be retired. +Added repo_manager.retirement_disposition, a read-only check that an Activity +expected_retirement_uuids set equals exactly those three empty projections and +excludes the preserved parent. It authorizes nothing; retirement stays with +Activity receiving under STATE-WP-0095-T04. + +## Activity disposition received, 2026-10-06 + +activity-core returned the exact expected_retirement_uuids (message 17ba4201, +evidence activity-core 941fac0, ACTIVITY-WP-0045): 683724d9, 644017c7, +a5806df9. repo_manager.retirement_disposition accepted the set: it equals the +three projections the 2026-10-04 run refused, each holds zero tasks, and it +excludes preserved parent b4eb45a9. Nothing was applied. T03 stays wait: its +acceptance needs a successful Activity owner sync with receipts, which can run +only after the founder decides 91b7c633 and STATE-WP-0095-T04 retires exactly +this set in a reviewed live rollout. Then re-run rmgr sync --path +~/activity-core --push and feed the receipt back to STATE-WP-0095-T04. + +## Post-retirement owner sync attempt, 2026-10-06 + +State Hub reported decision 91b7c633 resolved, main-968a811 / Helm rev 74 +deployed, and Activity reconcile at 67a92d2 retiring exactly the three empty +projections (3 retired, 0 created, 0 refused; 4 historical parents / 64 tasks +unchanged). Evidence: state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. +`rmgr sync --path ~/activity-core --push` stopped before reconciliation with +status pending_commit: uncommitted `state_hub_workstream_id` / `state_hub_task_id` +writeback in activity-core workplans/ACTIVITY-WP-0045-stale-historical-projection-disposition.md +(plus WORK-RECORDS.md). No hub request was made. Repo Manager does not commit in +activity-core; T03 stays wait until Activity Core commits and the sync re-runs. + +Re-run 2026-10-06 08:42Z after Activity Core committed the writeback (e809fb2): +status applied, created 0 / updated 45 (ACTIVITY-WP only) / retired 0 / refused 0, +no task changes, notes preserve custodian-WP-0001..0004 UUIDs; hub shows 4 parents, +64 tasks. Not closed: historical parent b4eb45a9 (custodian-WP-0003, source +`status: archived`, evidence snapshot archived) now reads `finished` in the hub, +updated 08:42:03Z during this sync. Needs State Hub review before T03 closes. + +Closed 2026-10-06: State Hub traced the b4eb45a9 status change to its own C-04 +check, which ran once per file. The custodian-WP-0003a/b/c split views share the +parent UUID, so whichever view ran last set the row. The Forge reconcile did not +cause it. Fixed in state-hub 2b5d8f9 (STATE-WP-ADHOC-2026-10-06-T01); b4eb45a9 is +back to `archived`. Re-check: 4 parents (b4eb45a9 archived; 3a4f47d9, 759b1255, +e22516cc finished) holding 64 tasks (24+12+7+21). Receipt: Activity sync at e809fb2, +primary/railiance01, applied, 0 created / 45 updated (ACTIVITY-WP only) / 0 retired +/ 0 refused, 0 task changes, historical UUIDs preserved. Evidence: +state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. + + +## Cluster exact historical source successor, 2026-10-17 + +This scoped extension preserves the completed Activity/Custodian work above. +The cluster publisher now refuses three closed RAIL-BS source files containing +15 existing UUID-bound bare task labels. Preserve all three source bytes, IDs, +and UUIDs. No new alias or general syntax exemption is introduced. Evidence and +exact receiver-first proposal: cluster-historical-publication-r1 in the Custodian +NetKingdom change packet. The existing SHR-WP-0001 project driver owns the +Repo Manager / State Hub cross-owner wait; NK-WP-0049-T35 benefits from the +blocked cluster publication. No worker or human gate is woken here. + +## Prepare exact cluster registrar successor + +```task +id: RMGR-WP-0019-T04 +status: done +priority: high +state_hub_task_id: "1ccb06c6-ad30-5847-8704-e5628ba81f35" +``` + +Prepared full-file SHA256 bindings for three archives and 15 exact task +occurrences; strict scans still return 15 invalid labels and five collisions. +Unknown/live sources, changed/missing/symlinked histories, UUID drift and +qualified/global collisions refuse before allocation. Candidate tests pass 47; +canonical application remains a separate reviewed step. The read-only current +cluster preview proposes seven ordinary UUID bindings in two files and changes +no bytes. One pre-existing ADHOC field is included explicitly: task +RCLUSTER-WP-ADHOC-2026-07-27-T01 in workplans/ADHOC-2026-07-27.md receives +3e3f39d3-5070-5ba3-97db-19f5f361f264 through managed allocation only. + +## Admit cluster registrar successor only after receiving verification + +```task +id: RMGR-WP-0019-T05 +status: done +priority: high +depends_on: [STATE-WP-0095-T06] +state_hub_task_id: "36f47e21-42d0-5aef-b065-4a5dd3af0726" +``` + +Retain the current guard until exact reviewed receiving source has been delivered +and verified through State Hub's normal owner deployment. Match both manifests, +then integrate reviewed registrar source and verify ordinary allocator preview. +No direct API patch, history rename or bypass substitutes for this gate. + +## Run ordinary cluster owner publication and verify preservation + +```task +id: RMGR-WP-0019-T06 +status: wait +priority: high +depends_on: [RMGR-WP-0019-T05] +state_hub_task_id: "4d1675b6-f49f-5b01-8d76-bbf2030d1b34" +``` + +Only then run normal owner consistency/publication with the reviewed expected +file set: RCLUSTER-WP-0018 and the one-field ADHOC managed backfill, plus ordinary +generated indexes. Preserve all three archived files and all 18 existing +parent/task rows. Return actual receiving/publication receipts to STATE-WP-0095-T07. +Do not infer TLS recovery, credential custody or native acceptance from sync. + +Cluster publication returned, preservation acceptance failed, 2026-10-17: +normal owner publication at c562d7134c38679952a8ffd17a8a893a900aef0d +is applied on primary/railiance01 with expected and derived commits equal. +Read-only source/remote/Hub verification confirms WP0018's five task bindings +and three internal dependency edges. These publication results do not close T06. +The full-row guard after the required legacy deep consistency pass failed: +all three historical parent full-row hashes changed; all 15 historical task +full-row hashes remain equal. The entire pipeline therefore has no successful +18-row preservation acceptance. + +Custodian receipts under docs/changes/netkingdom-target-2026-10-17: +railiance-cluster-projection.json and cluster-publication-readback.json retain +the applied publication and bounded readback; receiver-rollout-r4/ +pre-publication-full-row-hashes.json retains the passing pre-publication guard; +receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json retains the +failed native comparison. Exact receipt digests are retained in +registrar-t06-preservation-failure-r1/manifest.json. Coordinator and recovery +source review identified the unguarded PUT /workplans/index/bindings path +writing backing_synced_at and ORM updated_at, outside the native forge +projection's preservation guard. Full baseline rows were not retained, only +full-row hashes; no guessed database restoration is authorized or claimed. + +The original rollout's pre-Cluster preservation/refusal verification remains +valid for that earlier stage, and T05 remains done. T06 stays wait pending +the reviewed exact-frozen binding guard, regression coverage and a verified +recovery/preservation disposition. No source or native gate is promoted by the +successful publication alone; no TLS or credential-custody acceptance follows. + + +## Receiver-first registrar source follow-through, 2026-10-17 + +The exact receiving return is retained in Custodian +`docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json`, +bound to the actual native rollout/preservation/refusal receipts. It verifies the +reviewed receiver source/image/module, API/MCP readiness, expected additive schema, +three existing historical parents/15 tasks and rolled-back safe refusal probes. +Only after that return was the exact registrar patch +`232552c3d601d185984be5a8e5bc9937bc9ddda7327923b5f0440f6deb2c87fc` +admitted in the Repo Manager owner source. T04 retains its source-preparation +outcome; T05 records this receiving-gated registrar admission, not a substitute +for receiving. Canonical focused registrar/identity checks passed 47 cases in 5.84 seconds. +The actual bounded read-only current Cluster allocator preview agreed with the +reviewed source: seven ordinary missing UUID bindings in exactly the new WP0018 and +one-field existing ADHOC backfill, with 15 invalid labels/five collisions still +reported by the strict conformance scan. The three historical file bytes, IDs, +UUIDs and ownership are unchanged. No broad syntax relaxation or direct Hub UUID +patch is introduced. Exact source application/test/preview receipts travel with +the same packet; source publication/projection is verified separately. + +T06 remains wait until actual ordinary Cluster owner publication and receiving +preservation are verified. Registrar source readiness alone does not mark that +publication complete. Preserve the 18 existing rows and all three archives; the +root coordinator owns the normal seven-field managed allocation and dirty-source +preservation. Own Repo Manager projection must show exactly T01–T05 done, T06 +wait and active workplan status, including the managed new T04/T05/T06 UUIDs and +unchanged earlier task UUIDs. The separate scanner RMGR-WP-0021-T05 completion +and unrelated owner work remain untouched. No native TLS recovery, custody, +current registration/private admission or NetKingdom target acceptance follows. diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-commit.json b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-commit.json new file mode 100644 index 00000000..b97cf9df --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-commit.json @@ -0,0 +1,14 @@ +{ + "status": "committed-exact-one-file", + "head": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "parent": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "path": "workplans/RMGR-WP-0019-historical-source-admission.md", + "source_sha256": "3c28ff7809a56a2096f58986f1b3d7e6f99d365d42d0e8a97ee786ae7d067cc1", + "scanner_sha256_unchanged": "e709c658f779534fcab093207b0a78e49d54fc584c515fdf7ac535ce75f6c400", + "task_statuses_and_UUIDs_unchanged": true, + "added_dependency": "STATE-WP-0095-T10", + "t05": "done", + "t06": "wait", + "commit_output": "[main 1dacdd4] Qualify Cluster preservation wait with verified client and API gate\n 1 file changed, 29 insertions(+), 1 deletion(-)\n", + "cluster_or_database_mutation": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-publication-readback.json b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-publication-readback.json new file mode 100644 index 00000000..34fc9715 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-publication-readback.json @@ -0,0 +1,149 @@ +{ + "status": "verified", + "scope": "RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots", + "writes_to_source_index_refs_or_Hub": false, + "rows": [ + { + "repo": "repo-manager", + "published_commit": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "remote": { + "HEAD": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "refs/heads/main": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "symbolic_HEAD": "refs/heads/main" + }, + "workplan": { + "id": "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab", + "slug": "rmgr-wp-0019", + "status": "active" + }, + "source_record_id": "RMGR-WP-0019", + "tasks": [ + { + "id": "d78a622e-39f9-5923-b4e1-f70fdc17fb42", + "record_id": "RMGR-WP-0019-T01", + "status": "done" + }, + { + "id": "95240c81-1805-5365-9b35-d238621a16bf", + "record_id": "RMGR-WP-0019-T02", + "status": "done" + }, + { + "id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d", + "record_id": "RMGR-WP-0019-T03", + "status": "done" + }, + { + "id": "1ccb06c6-ad30-5847-8704-e5628ba81f35", + "record_id": "RMGR-WP-0019-T04", + "status": "done" + }, + { + "id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "record_id": "RMGR-WP-0019-T05", + "status": "done" + }, + { + "id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "record_id": "RMGR-WP-0019-T06", + "status": "wait" + } + ], + "external_source_declarations_not_projected": [ + { + "from_task_id": "95240c81-1805-5365-9b35-d238621a16bf", + "target_record_id": "STATE-WP-0095-T03", + "target_uuid": "e8566341-cf6e-5b9c-ad80-8564d14cd52a" + }, + { + "from_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "target_record_id": "STATE-WP-0095-T06", + "target_uuid": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4" + } + ], + "projected_external_dependencies": [ + { + "from_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "target_record_id": "STATE-WP-0095-T10", + "target_uuid": "88585c69-d9b9-5e1f-a256-6416ff71e824" + } + ], + "dependencies": [ + { + "from_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "to_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "relationship_type": "starts_after" + }, + { + "from_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "to_task_id": "88585c69-d9b9-5e1f-a256-6416ff71e824", + "relationship_type": "starts_after" + }, + { + "from_task_id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d", + "to_task_id": "95240c81-1805-5365-9b35-d238621a16bf", + "relationship_type": "starts_after" + } + ], + "source_file_sha256": "3c28ff7809a56a2096f58986f1b3d7e6f99d365d42d0e8a97ee786ae7d067cc1", + "source_file_unchanged": true, + "dependency_scope": "exact internal and active-task external edges verified; closed-task external declarations retained separately", + "index_stat_unchanged": true + }, + { + "repo": "repo-manager", + "published_commit": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "remote": { + "HEAD": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "refs/heads/main": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "symbolic_HEAD": "refs/heads/main" + }, + "workplan": { + "id": "5aa6f84a-c682-5996-ae26-96daef670833", + "slug": "rmgr-wp-0021", + "status": "active" + }, + "source_record_id": "RMGR-WP-0021", + "tasks": [ + { + "id": "d3d20c18-5a5f-5f8a-b5c4-a22b4b662ebe", + "record_id": "RMGR-WP-0021-T01", + "status": "done" + }, + { + "id": "e27817e6-b298-581f-b99a-05ec459be749", + "record_id": "RMGR-WP-0021-T02", + "status": "done" + }, + { + "id": "0ab44bd9-00d8-5470-ad45-7350e7868d0a", + "record_id": "RMGR-WP-0021-T03", + "status": "progress" + }, + { + "id": "44272818-db49-58a2-83b1-d2f9e9d5976c", + "record_id": "RMGR-WP-0021-T04", + "status": "todo" + }, + { + "id": "25fbe694-41d8-5232-bce0-4ed362387d5a", + "record_id": "RMGR-WP-0021-T05", + "status": "done" + } + ], + "external_source_declarations_not_projected": [], + "projected_external_dependencies": [], + "dependencies": [], + "source_file_sha256": "966d15ccdabc8edf98bc58f9422ea190566d05fe4208f4749f59a9731f4e108d", + "source_file_unchanged": true, + "dependency_scope": "exact internal and active-task external edges verified; closed-task external declarations retained separately", + "index_stat_unchanged": true + } + ], + "hub_instance": { + "status": "ok", + "instance_role": "primary", + "instance_label": "railiance01" + }, + "verifier_sha256": "c794ce4e1b1672982a606dce9bd364de0754dd905d63fbaf3cf6b1b2c42f4764" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-sync.json b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-sync.json new file mode 100644 index 00000000..87ef1f29 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-sync.json @@ -0,0 +1,103 @@ +{ + "ok": true, + "status": "applied", + "repo_slug": "repo-manager", + "commit": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "requests": 2, + "elapsed_ms": 8706.5, + "git": { + "upstream": "origin/main", + "behind": 0, + "ahead": 0 + }, + "identifiers": { + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": true, + "repo": "repo-manager", + "namespace": "helixforge", + "assignments": [], + "historical_invalid_identifiers": [], + "historical_identity_collisions": [], + "files_changed": [] + }, + "receipt": { + "schema": "state-hub.repository-projection-reconcile.v1", + "instance_role": "primary", + "instance_label": "railiance01", + "expected_commit": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "derived_commit": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "outcome": { + "schema": "state-hub.projection-reset.v1", + "repo_slug": "repo-manager", + "commit": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "status": "applied", + "counts": { + "created": 0, + "updated": 25, + "retired": 0, + "refused": 0, + "released": 0, + "created_tasks": 0, + "updated_tasks": 1, + "cancelled_tasks": 0, + "created_edges": 1, + "removed_edges": 0, + "unresolved_edges": 0, + "external_edges": 0 + }, + "created": [], + "updated": [ + "RMGR-WP-0001", + "RMGR-WP-0002", + "RMGR-WP-0003", + "RMGR-WP-0004", + "RMGR-WP-0005", + "RMGR-WP-0006", + "RMGR-WP-0007", + "RMGR-WP-0008", + "RMGR-WP-0009", + "RMGR-WP-0010", + "RMGR-WP-0011", + "RMGR-WP-0012", + "RMGR-WP-0013", + "RMGR-WP-0014", + "RMGR-WP-0015", + "RMGR-WP-0016", + "RMGR-WP-0017", + "RMGR-WP-0018", + "RMGR-WP-0019", + "RMGR-WP-0020", + "RMGR-WP-0021", + "RMGR-WP-ADHOC-2026-09-06", + "RMGR-WP-ADHOC-2026-09-09", + "RMGR-WP-ADHOC-2026-09-11", + "RMGR-WP-ADHOC-2026-10-03" + ], + "retired": [], + "released": [], + "created_tasks": [], + "updated_tasks": [ + "RMGR-WP-0019-T06" + ], + "cancelled_tasks": [], + "created_edges": [ + { + "workplan": "RMGR-WP-0019", + "from": "RMGR-WP-0019-T06", + "target": "STATE-WP-0095-T10", + "relationship_type": "starts_after", + "from_workplan_id": "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab", + "from_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "to_workplan_id": null, + "to_task_id": "88585c69-d9b9-5e1f-a256-6416ff71e824" + } + ], + "removed_edges": [], + "unresolved_edges": [], + "external_edges": [], + "refused": [], + "notes": [] + } + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/manifest.json b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/manifest.json new file mode 100644 index 00000000..50be0045 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/manifest.json @@ -0,0 +1,23 @@ +{ + "status": "prepared-not-applied", + "base": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "path": "workplans/RMGR-WP-0019-historical-source-admission.md", + "preimage_sha256": "4ff763ea24b9948d59b4bdd4f5ef3e95bee72fef3016f0b6404b5db663cb83ff", + "candidate_sha256": "3c28ff7809a56a2096f58986f1b3d7e6f99d365d42d0e8a97ee786ae7d067cc1", + "patch_sha256": "8527c5fa953a86dea8bc3f3bcf783084608c6850dd323f3390cfa27157f9cd2a", + "t05": "done", + "t06": "wait", + "added_dependency": "STATE-WP-0095-T10", + "UUIDs_unchanged": true, + "runtime_activation": false, + "original_rows_restored": false, + "receipts": { + "receiver-rollout-r4/before-verified-client.json": "ee41be2d74085603abf2bfe2c91c1bb430b4ea0539a6cbf988528b18f3f5ef46", + "receiver-rollout-r4/after-verified-client.json": "8cd8921271cd647fe40dde0f00bc55b714313426e14091397d8fd11314c5e610", + "verified-loaded-client.json": "0745b5df92d2533714e2a87a43c73b3b685e7bab7bcf4444f7a5fbd82dd4722f", + "verified-client-cluster-consistency.json": "fd8a7d58d9e08b4866420ad77d01fbc7c28c0c2c9610ffbe95ddc77dddd9b1a6", + "verified-client-cluster-projection.json": "c25b43575273df0e648842d447979aca1b41ade16fcdaf9f5f870024e7ca06e9", + "guard-successor-review-r1/proposal-metadata.json": "81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932", + "guard-successor-review-r1/pending-decision.json": "b1dbd9b700555c0081231d49ca03522bd0af1a635b6e11ecbd72ff0797b27de5" + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/owner-amendment.patch b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/owner-amendment.patch new file mode 100644 index 00000000..cf2ba88a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/owner-amendment.patch @@ -0,0 +1,46 @@ +--- a/workplans/RMGR-WP-0019-historical-source-admission.md ++++ b/workplans/RMGR-WP-0019-historical-source-admission.md +@@ -199,7 +199,8 @@ + id: RMGR-WP-0019-T06 + status: wait + priority: high +-depends_on: [RMGR-WP-0019-T05] ++depends_on: [RMGR-WP-0019-T05, STATE-WP-0095-T10] ++blocking_reason: "Await State Hub T10 founder approval, delivered API guard verification and explicit current-baseline/historical-exception disposition; original parent hashes are not restored." + state_hub_task_id: "4d1675b6-f49f-5b01-8d76-bbf2030d1b34" + ``` + +@@ -236,6 +237,33 @@ + the reviewed exact-frozen binding guard, regression coverage and a verified + recovery/preservation disposition. No source or native gate is promoted by the + successful publication alone; no TLS or credential-custody acceptance follows. ++ ++Verified installed-client successor, 2026-10-17: after verifying the installed ++R6 checker module rather than assuming canonical source was loaded, the full ++normal Cluster maintenance pipeline preserved all 18 CURRENT historical row ++hashes. It synced 20/20 ordinary bindings while omitting the three exact frozen ++histories. Cluster HEAD remained 6ae3f847c83da3402883453ee7110457bfb2d0d6; ++the owner's original staged brief and dirty WORK-RECORDS content were preserved. ++Passing CURRENT before/after snapshots are retained under the Custodian packet ++receiver-rollout-r4/before-verified-client.json and after-verified-client.json; ++verified-loaded-client.json, verified-client-cluster-consistency.json and ++verified-client-cluster-projection.json retain the actual client/pipeline proof. ++This new baseline pass does not restore or replace the earlier failed three ++parent comparisons; those failures and unavailable original preimages remain. ++ ++The new API guard artifact c103cbf3c8bed5dba87a03e320595ddded9301a3 at ++image digest sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1 ++has image-only server dry-run proof, not delivered-runtime acceptance. T06 ++therefore also depends on STATE-WP-0095-T10. Founder decision ++df703266-6719-4c04-ae1b-ba9afd3bca1c remains pending for exact proposal ++STATE-WP-0095-T10-frozen-bindings-guard-r1 revision 1, metadata SHA256 ++81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932, in ++Custodian docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/. ++That decision includes the proposed CURRENT-baseline acceptance with the ++earlier mismatch retained as an exception; no baseline disposition is inferred ++here. Await its approved scope and verified owner return before T06 closes. ++T05 stays done; no runtime activation, guessed database restoration, worker ++wakeup, TLS recovery or native private-admission acceptance follows. + + + ## Receiver-first registrar source follow-through, 2026-10-17 diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/publication-final-manifest.json b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/publication-final-manifest.json new file mode 100644 index 00000000..8330a573 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/publication-final-manifest.json @@ -0,0 +1,32 @@ +{ + "status": "published-and-readback-verified", + "commit": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "scope": "one owner-record qualifier; no code/Cluster/rollout changes", + "t05": "done", + "t06": "wait", + "task_statuses_and_UUIDs_unchanged": true, + "scanner_unchanged": true, + "repo_worktree_clean": true, + "wp19_six_task_bindings_and_wp21_five_bindings_verified": true, + "new_actual_projected_external_edge": { + "from": "RMGR-WP-0019-T06", + "to": "STATE-WP-0095-T10", + "target_uuid": "88585c69-d9b9-5e1f-a256-6416ff71e824", + "target_identity_GET_verified": true + }, + "closed_task_external_declarations_not_claimed_as_projected": true, + "first_verifier_mismatch_retained": "R1 expected only internal edges; actual current wait-task external edge existed, R2 verifies exact three projected edges and target", + "original_parent_hash_failure_retained": true, + "new_runtime_approval_or_execution": false, + "files": { + "manifest.json": "5b5600ccc9611b86ef190895a39dca2bda6032caa37e664cd995a6ae36868c2f", + "owner-amendment.patch": "8527c5fa953a86dea8bc3f3bcf783084608c6850dd323f3390cfa27157f9cd2a", + "publish_amendment.py": "d30ea83e814b32ef603056a8338125e5a5cf49765d698adfda317e8a3f8e3435", + "amendment-commit.json": "c73ee532b9018808de14c03cf42ded7eeddf4589dd5521eeae052703644a2748", + "amendment-sync.json": "43467eb3ada96f3207ed97d3809e6b5230636280b400569660ece5813b1535ab", + "verify_amendment_publication.py": "c794ce4e1b1672982a606dce9bd364de0754dd905d63fbaf3cf6b1b2c42f4764", + "amendment-publication-readback.json": "ef1a342f12b2007480f7c3bf9039f257a238ebce921be076ce277641642e2f96", + "r1-verify_amendment_publication.py": "f1c08cf2912c894de4825291fc9d56c2813dfd21436a7596781967b139cd4ec8", + "r1-amendment-publication-readback.json": "e4478c48af15dac3a67b8514ce68cf50c4a6502c497dcb7d29e8873c97941737" + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/publish_amendment.py b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/publish_amendment.py new file mode 100644 index 00000000..9922b5af --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/publish_amendment.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +from pathlib import Path +import hashlib,json,subprocess +P=Path(__file__).resolve().parent +R=Path('/home/worsch/repo-manager') +m=json.loads((P/'manifest.json').read_text()); f=R/m['path'] +def h(p):return hashlib.sha256(p.read_bytes()).hexdigest() +def git(*args): + r=subprocess.run(['git',*args],cwd=R,text=True,capture_output=True,timeout=180) + if r.returncode: raise RuntimeError(json.dumps({'args':args,'stdout':r.stdout,'stderr':r.stderr,'code':r.returncode})) + return r.stdout +assert git('rev-parse','HEAD').strip()==m['base'] +assert h(f)==m['preimage_sha256'] +assert h(P/'owner-amendment.patch')==m['patch_sha256']=='8527c5fa953a86dea8bc3f3bcf783084608c6850dd323f3390cfa27157f9cd2a' +assert h(P/'WP19.candidate.md')==m['candidate_sha256'] +assert not git('diff','--cached','--name-only') +scanner=R/'src/repo_manager/secret_scan.py'; before=h(scanner) +assert before=='e709c658f779534fcab093207b0a78e49d54fc584c515fdf7ac535ce75f6c400' +git('apply','--check',str(P/'owner-amendment.patch')) +git('apply',str(P/'owner-amendment.patch')) +assert h(f)==m['candidate_sha256'] +git('add','--',m['path']) +assert git('diff','--cached','--name-only').splitlines()==[m['path']] +git('diff','--cached','--check') +output=git('commit','-m','Qualify Cluster preservation wait with verified client and API gate') +head=git('rev-parse','HEAD').strip() +assert git('diff-tree','--no-commit-id','--name-only','-r',head).splitlines()==[m['path']] +assert h(scanner)==before +receipt={'status':'committed-exact-one-file','head':head,'parent':m['base'],'path':m['path'],'source_sha256':h(f),'scanner_sha256_unchanged':before,'task_statuses_and_UUIDs_unchanged':True,'added_dependency':'STATE-WP-0095-T10','t05':'done','t06':'wait','commit_output':output,'cluster_or_database_mutation':False} +(P/'amendment-commit.json').write_text(json.dumps(receipt,indent=2)+'\n');print(json.dumps(receipt,indent=2)) diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/r1-amendment-publication-readback.json b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/r1-amendment-publication-readback.json new file mode 100644 index 00000000..4a6c433a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/r1-amendment-publication-readback.json @@ -0,0 +1,13 @@ +{ + "status": "unverified", + "scope": "RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots", + "writes_to_source_index_refs_or_Hub": false, + "rows": [], + "hub_instance": { + "status": "ok", + "instance_role": "primary", + "instance_label": "railiance01" + }, + "reason": "dependency-binding-mismatch", + "verifier_sha256": "f1c08cf2912c894de4825291fc9d56c2813dfd21436a7596781967b139cd4ec8" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/r1-verify_amendment_publication.py b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/r1-verify_amendment_publication.py new file mode 100644 index 00000000..cf950b1e --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/r1-verify_amendment_publication.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python3 +"""Read-only Git+Hub task binding verifier; never syncs or changes source/index.""" +import hashlib +import json +import os +from pathlib import Path +import re +import subprocess +import urllib.request + +HERE=Path(__file__).resolve().parent +OWNERS=[ + {'repo':'repo-manager','commit':'1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd','path':'workplans/RMGR-WP-0019-historical-source-admission.md','id':'RMGR-WP-0019','tasks':6}, + {'repo':'repo-manager','commit':'1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd','path':'workplans/RMGR-WP-0021-secret-detection-controls.md','id':'RMGR-WP-0021','tasks':5}, +] +API=os.environ.get('API_BASE','http://127.0.0.1:8000').rstrip('/') +EXTERNAL={'STATE-WP-0095-T10':'88585c69-d9b9-5e1f-a256-6416ff71e824','STATE-WP-0095-T03':'e8566341-cf6e-5b9c-ad80-8564d14cd52a','STATE-WP-0095-T06':'6af973b4-1964-5d4d-a2f8-8dbd4c01fda4','NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'} + + +class Refused(Exception):pass + + +def git(root,*args): + result=subprocess.run(['git','--no-optional-locks','-C',str(root),*args], + capture_output=True,timeout=30,check=False) + if result.returncode:raise Refused('read-only-git-failed') + return result.stdout + + +def field(text,key): + values=re.findall(r'^'+re.escape(key)+r':\s*(.*?)\s*$',text,re.M) + if len(values)!=1:raise Refused('source-field-ambiguous') + return values[0].strip('"\'') + + +def source(text): + header=text.split('---',2)[1] + tasks=[] + for block in re.findall(r'```task\n(.*?)\n```',text,re.S): + deps=re.findall(r'^depends_on:\s*\[(.*?)\]',block,re.M) + tasks.append({'record_id':field(block,'id'),'id':field(block,'state_hub_task_id'), + 'status':field(block,'status'),'dependencies':[x.strip() for x in deps[0].split(',') if x.strip()] if deps else []}) + return {'id':field(header,'state_hub_workstream_id'),'source_record_id':field(header,'id'), + 'slug':field(header,'id').lower(), + 'status':field(header,'status'),'tasks':tasks} + + +def get(path): + class NoRedirect(urllib.request.HTTPRedirectHandler): + def redirect_request(self,*args,**kwargs):raise Refused('hub-redirect-refused') + opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect) + with opener.open(urllib.request.Request(API+path,method='GET'),timeout=20) as response: + data=response.read(8*1024**2+1) + if len(data)>8*1024**2:raise Refused('hub-read-limit') + return json.loads(data) + + +def index_stat(root): + raw=git(root,'rev-parse','--git-path','index').decode().strip();path=Path(raw) + if not path.is_absolute():path=root/path + try:item=path.lstat() + except FileNotFoundError:return None + return [item.st_dev,item.st_ino,item.st_size,item.st_mtime_ns,item.st_mode] + + +def remote(root,expected,repo): + if git(root,'remote','get-url','origin').decode().strip()!='forgejo-remote:coulomb/'+repo+'.git': + raise Refused('remote-route-drift') + lines=git(root,'ls-remote','--symref','origin','HEAD','refs/heads/main').decode().splitlines() + if set(lines)!={'ref: refs/heads/main\tHEAD',expected+'\tHEAD',expected+'\trefs/heads/main'}: + raise Refused('remote-head-mismatch') + return {'HEAD':expected,'refs/heads/main':expected,'symbolic_HEAD':'refs/heads/main'} + + +def verify(): + result={'status':'unverified','scope':'RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots', + 'writes_to_source_index_refs_or_Hub':False,'rows':[]} + try: + if API not in {'http://127.0.0.1:8000','http://127.0.0.1:18080','http://10.43.68.154:8000'}: + raise Refused('unrecognized-hub-endpoint') + health=get('/state/health') + result['hub_instance']={key:health.get(key) for key in ('status','instance_role','instance_label')} + if result['hub_instance']!={'status':'ok','instance_role':'primary','instance_label':'railiance01'}: + raise Refused('hub-identity-mismatch') + for owner in OWNERS: + root=Path('/home/worsch')/owner['repo'];before_index=index_stat(root) + if git(root,'rev-parse','HEAD').decode().strip()!=owner['commit']: + raise Refused('local-head-drift') + committed=git(root,'show',owner['commit']+':'+owner['path']) + local=(root/owner['path']).read_bytes() + if local!=committed:raise Refused('published-workplan-local-drift') + expected=source(committed.decode()) + if expected['source_record_id']!=owner['id'] or len(expected['tasks'])!=owner['tasks']: + raise Refused('source-task-denominator-mismatch') + snapshot=get('/repos/'+owner['repo']+'/work-record-projection/snapshot') + plans=[row for row in snapshot['workplans'] if row['id']==expected['id']] + if len(plans)!=1 or any(plans[0].get(key)!=expected[key] for key in ('id','slug','status')): + raise Refused('workplan-binding-mismatch') + projected=[row for row in snapshot['tasks'] + if row.get('workplan_id',row.get('workstream_id'))==expected['id']] + if len(projected)!=len(expected['tasks']):raise Refused('projected-task-denominator-mismatch') + byid={row['id']:row for row in projected} + if len(byid)!=len(projected):raise Refused('duplicate-projected-uuid') + observed=[] + for task in expected['tasks']: + row=byid.get(task['id'],{}) + if any(row.get(key)!=task[key] for key in ('id','record_id','status')): + raise Refused('task-id-uuid-status-mismatch') + observed.append({key:row[key] for key in ('id','record_id','status')}) + identifiers={task['record_id']:task['id'] for task in expected['tasks']} + edges={(task['id'],identifiers[dep],'starts_after') for task in expected['tasks'] for dep in task['dependencies'] if dep in identifiers} + actual=[edge for edge in snapshot['dependencies'] if edge['from_workplan_id']==expected['id']] + projected_edges={(edge.get('from_task_id'),edge.get('to_task_id'),edge['relationship_type']) for edge in actual} + if len(actual)!=len(edges) or projected_edges!=edges: + raise Refused('dependency-binding-mismatch') + # An unchanged edge retains its original forge creation commit on description-only sync. + def valid_edge_commit(edge): + if edge.get('source_commit') in (None,owner['commit']):return True + return (owner['id']=='RMGR-WP-0019' and + edge.get('from_task_id')=='4d1675b6-f49f-5b01-8d76-bbf2030d1b34' and + edge.get('to_task_id')=='36f47e21-42d0-5aef-b065-4a5dd3af0726' and + edge.get('source_owner')=='forge:repo-manager' and + edge.get('source_commit')=='70cd754996870638848616e37819790a5c4d52b3') + if any(not valid_edge_commit(edge) for edge in actual): + raise Refused('dependency-source-commit-mismatch') + for task in expected['tasks']: + for dep in task['dependencies']: + if dep in EXTERNAL: + target=get('/tasks/'+EXTERNAL[dep]) + if target.get('id')!=EXTERNAL[dep] or target.get('record_id')!=dep: + raise Refused('external-dependency-target-mismatch') + remote_readback=remote(root,owner['commit'],owner['repo']) + if index_stat(root)!=before_index or (root/owner['path']).read_bytes()!=local: + raise Refused('source-or-index-stat-changed') + result['rows'].append({'repo':owner['repo'],'published_commit':owner['commit'], + 'remote':remote_readback,'workplan':{key:plans[0][key] for key in ('id','slug','status')}, + 'source_record_id':expected['source_record_id'], + 'tasks':observed,'external_source_declarations_not_projected':[{'from_task_id':task['id'],'target_record_id':dep,'target_uuid':EXTERNAL[dep]} for task in expected['tasks'] for dep in task['dependencies'] if dep in EXTERNAL],'dependencies':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(edges)], + 'source_file_sha256':hashlib.sha256(local).hexdigest(),'source_file_unchanged':True,'dependency_scope':'internal edges verified; external source target identities checked without claiming projected external edges', + 'index_stat_unchanged':True}) + result['status']='verified' + except Exception as error: + result['reason']=error.args[0] if isinstance(error,Refused) else 'readback-unavailable' + result['verifier_sha256']=hashlib.sha256(Path(__file__).read_bytes()).hexdigest() + (HERE/'amendment-publication-readback.json').write_text(json.dumps(result,indent=2)+'\n') + print(json.dumps({'status':result['status'],'owners':len(result['rows'])})) + return 0 if result['status']=='verified' else 2 + + +if __name__=='__main__':raise SystemExit(verify()) diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/verify_amendment_publication.py b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/verify_amendment_publication.py new file mode 100644 index 00000000..64d13a5f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/verify_amendment_publication.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python3 +"""Read-only Git+Hub task binding verifier; never syncs or changes source/index.""" +import hashlib +import json +import os +from pathlib import Path +import re +import subprocess +import urllib.request + +HERE=Path(__file__).resolve().parent +OWNERS=[ + {'repo':'repo-manager','commit':'1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd','path':'workplans/RMGR-WP-0019-historical-source-admission.md','id':'RMGR-WP-0019','tasks':6}, + {'repo':'repo-manager','commit':'1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd','path':'workplans/RMGR-WP-0021-secret-detection-controls.md','id':'RMGR-WP-0021','tasks':5}, +] +API=os.environ.get('API_BASE','http://127.0.0.1:8000').rstrip('/') +EXTERNAL={'STATE-WP-0095-T10':'88585c69-d9b9-5e1f-a256-6416ff71e824','STATE-WP-0095-T03':'e8566341-cf6e-5b9c-ad80-8564d14cd52a','STATE-WP-0095-T06':'6af973b4-1964-5d4d-a2f8-8dbd4c01fda4','NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'} + + +class Refused(Exception):pass + + +def git(root,*args): + result=subprocess.run(['git','--no-optional-locks','-C',str(root),*args], + capture_output=True,timeout=30,check=False) + if result.returncode:raise Refused('read-only-git-failed') + return result.stdout + + +def field(text,key): + values=re.findall(r'^'+re.escape(key)+r':\s*(.*?)\s*$',text,re.M) + if len(values)!=1:raise Refused('source-field-ambiguous') + return values[0].strip('"\'') + + +def source(text): + header=text.split('---',2)[1] + tasks=[] + for block in re.findall(r'```task\n(.*?)\n```',text,re.S): + deps=re.findall(r'^depends_on:\s*\[(.*?)\]',block,re.M) + tasks.append({'record_id':field(block,'id'),'id':field(block,'state_hub_task_id'), + 'status':field(block,'status'),'dependencies':[x.strip() for x in deps[0].split(',') if x.strip()] if deps else []}) + return {'id':field(header,'state_hub_workstream_id'),'source_record_id':field(header,'id'), + 'slug':field(header,'id').lower(), + 'status':field(header,'status'),'tasks':tasks} + + +def get(path): + class NoRedirect(urllib.request.HTTPRedirectHandler): + def redirect_request(self,*args,**kwargs):raise Refused('hub-redirect-refused') + opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect) + with opener.open(urllib.request.Request(API+path,method='GET'),timeout=20) as response: + data=response.read(8*1024**2+1) + if len(data)>8*1024**2:raise Refused('hub-read-limit') + return json.loads(data) + + +def index_stat(root): + raw=git(root,'rev-parse','--git-path','index').decode().strip();path=Path(raw) + if not path.is_absolute():path=root/path + try:item=path.lstat() + except FileNotFoundError:return None + return [item.st_dev,item.st_ino,item.st_size,item.st_mtime_ns,item.st_mode] + + +def remote(root,expected,repo): + if git(root,'remote','get-url','origin').decode().strip()!='forgejo-remote:coulomb/'+repo+'.git': + raise Refused('remote-route-drift') + lines=git(root,'ls-remote','--symref','origin','HEAD','refs/heads/main').decode().splitlines() + if set(lines)!={'ref: refs/heads/main\tHEAD',expected+'\tHEAD',expected+'\trefs/heads/main'}: + raise Refused('remote-head-mismatch') + return {'HEAD':expected,'refs/heads/main':expected,'symbolic_HEAD':'refs/heads/main'} + + +def verify(): + result={'status':'unverified','scope':'RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots', + 'writes_to_source_index_refs_or_Hub':False,'rows':[]} + try: + if API not in {'http://127.0.0.1:8000','http://127.0.0.1:18080','http://10.43.68.154:8000'}: + raise Refused('unrecognized-hub-endpoint') + health=get('/state/health') + result['hub_instance']={key:health.get(key) for key in ('status','instance_role','instance_label')} + if result['hub_instance']!={'status':'ok','instance_role':'primary','instance_label':'railiance01'}: + raise Refused('hub-identity-mismatch') + for owner in OWNERS: + root=Path('/home/worsch')/owner['repo'];before_index=index_stat(root) + if git(root,'rev-parse','HEAD').decode().strip()!=owner['commit']: + raise Refused('local-head-drift') + committed=git(root,'show',owner['commit']+':'+owner['path']) + local=(root/owner['path']).read_bytes() + if local!=committed:raise Refused('published-workplan-local-drift') + expected=source(committed.decode()) + if expected['source_record_id']!=owner['id'] or len(expected['tasks'])!=owner['tasks']: + raise Refused('source-task-denominator-mismatch') + snapshot=get('/repos/'+owner['repo']+'/work-record-projection/snapshot') + plans=[row for row in snapshot['workplans'] if row['id']==expected['id']] + if len(plans)!=1 or any(plans[0].get(key)!=expected[key] for key in ('id','slug','status')): + raise Refused('workplan-binding-mismatch') + projected=[row for row in snapshot['tasks'] + if row.get('workplan_id',row.get('workstream_id'))==expected['id']] + if len(projected)!=len(expected['tasks']):raise Refused('projected-task-denominator-mismatch') + byid={row['id']:row for row in projected} + if len(byid)!=len(projected):raise Refused('duplicate-projected-uuid') + observed=[] + for task in expected['tasks']: + row=byid.get(task['id'],{}) + if any(row.get(key)!=task[key] for key in ('id','record_id','status')): + raise Refused('task-id-uuid-status-mismatch') + observed.append({key:row[key] for key in ('id','record_id','status')}) + identifiers={task['record_id']:task['id'] for task in expected['tasks']}|EXTERNAL + edges={(task['id'],identifiers[dep],'starts_after') for task in expected['tasks'] for dep in task['dependencies'] if dep in identifiers and (dep not in EXTERNAL or task['status'] not in {'done','cancel'})} + actual=[edge for edge in snapshot['dependencies'] if edge['from_workplan_id']==expected['id']] + projected_edges={(edge.get('from_task_id'),edge.get('to_task_id'),edge['relationship_type']) for edge in actual} + if len(actual)!=len(edges) or projected_edges!=edges: + raise Refused('dependency-binding-mismatch') + # An unchanged edge retains its original forge creation commit on description-only sync. + def valid_edge_commit(edge): + if edge.get('source_commit') in (None,owner['commit']):return True + return (owner['id']=='RMGR-WP-0019' and + edge.get('from_task_id')=='4d1675b6-f49f-5b01-8d76-bbf2030d1b34' and + edge.get('to_task_id')=='36f47e21-42d0-5aef-b065-4a5dd3af0726' and + edge.get('source_owner')=='forge:repo-manager' and + edge.get('source_commit')=='70cd754996870638848616e37819790a5c4d52b3') + if any(not valid_edge_commit(edge) for edge in actual): + raise Refused('dependency-source-commit-mismatch') + for task in expected['tasks']: + for dep in task['dependencies']: + if dep in EXTERNAL: + target=get('/tasks/'+EXTERNAL[dep]) + if target.get('id')!=EXTERNAL[dep] or target.get('record_id')!=dep: + raise Refused('external-dependency-target-mismatch') + remote_readback=remote(root,owner['commit'],owner['repo']) + if index_stat(root)!=before_index or (root/owner['path']).read_bytes()!=local: + raise Refused('source-or-index-stat-changed') + result['rows'].append({'repo':owner['repo'],'published_commit':owner['commit'], + 'remote':remote_readback,'workplan':{key:plans[0][key] for key in ('id','slug','status')}, + 'source_record_id':expected['source_record_id'], + 'tasks':observed,'external_source_declarations_not_projected':[{'from_task_id':task['id'],'target_record_id':dep,'target_uuid':EXTERNAL[dep]} for task in expected['tasks'] for dep in task['dependencies'] if dep in EXTERNAL and task['status'] in {'done','cancel'}],'projected_external_dependencies':[{'from_task_id':task['id'],'target_record_id':dep,'target_uuid':EXTERNAL[dep]} for task in expected['tasks'] for dep in task['dependencies'] if dep in EXTERNAL and task['status'] not in {'done','cancel'}],'dependencies':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(edges)], + 'source_file_sha256':hashlib.sha256(local).hexdigest(),'source_file_unchanged':True,'dependency_scope':'exact internal and active-task external edges verified; closed-task external declarations retained separately', + 'index_stat_unchanged':True}) + result['status']='verified' + except Exception as error: + result['reason']=error.args[0] if isinstance(error,Refused) else 'readback-unavailable' + result['verifier_sha256']=hashlib.sha256(Path(__file__).read_bytes()).hexdigest() + (HERE/'amendment-publication-readback.json').write_text(json.dumps(result,indent=2)+'\n') + print(json.dumps({'status':result['status'],'owners':len(result['rows'])})) + return 0 if result['status']=='verified' else 2 + + +if __name__=='__main__':raise SystemExit(verify()) diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/RMGR-WP-0019.candidate.md b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/RMGR-WP-0019.candidate.md new file mode 100644 index 00000000..98cc2d2a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/RMGR-WP-0019.candidate.md @@ -0,0 +1,269 @@ +--- +id: RMGR-WP-0019 +type: workplan +title: "Admit exact historical source views after receiving preservation support" +domain: infotech +repo: repo-manager +status: active +owner: codex +created: "2026-10-04" +updated: "2026-10-17" +flavor: implementation +depends_on: [] +state_hub_workstream_id: "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab" +--- + +## Goal + +Unblock normal authoritative registration of the exact closed Activity legacy +source views and Custodian retired ADHOC source after receiving preserves their +existing records. Preserve every legacy source byte, label and UUID; do not +expand canonical syntax or the general grandfathering rules. CUST-WP-0077 owns +cross-owner coordination with STATE-WP-0095. + +## Review exact historical receiving contract + +```task +id: RMGR-WP-0019-T01 +status: done +priority: high +state_hub_task_id: "d78a622e-39f9-5923-b4e1-f70fdc17fb42" +``` + +Seven Activity sources yield four existing parents/64 closed bound tasks; +three split views repeat the archived parent. One Custodian retired source keeps +its existing parent/task IDs. Earlier /tmp/activity-core-bound-history-write.py +is superseded and must not be applied: registrar bypass alone would admit an +unsupported receiving projection. RMGR-WP-0014/0015 are finished and do not own +this new implementation demand; this workplan is not residual. + +## Enable exact frozen registrar exceptions after receiving deployment + +```task +id: RMGR-WP-0019-T02 +status: done +priority: high +depends_on: [STATE-WP-0095-T03] +state_hub_task_id: "95240c81-1805-5365-9b35-d238621a16bf" +``` + +Prepared code permits only source paths with reviewed full SHA256 digests in +repo_manager/historical_sources.py. Strict conformance scans retain their legacy +findings. Unknown/missing/altered source refuses before allocation. Source UUIDs +are neither changed nor allocated for these histories. Receiving and registrar +manifests must remain identical. Apply helper requires a deployment receipt. + +## Run normal owner sync and verify preserved identities + +```task +id: RMGR-WP-0019-T03 +status: done +priority: high +depends_on: [RMGR-WP-0019-T02] +state_hub_task_id: "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d" +``` + +Use rmgr sync --path --push. No deep-check repair or direct hub UUID +patch substitutes for receiving. Historical unrelated stale projections are not +retirement-authorized by this workplan. Feed receipts back to STATE-WP-0095-T04. + +## Offline evidence, 2026-10-04 + +Prepared registrar suite: 38 focused cases passed (identifiers, registrar, +Custodian legacy identity and exact frozen source cases). Read-only execute=False +against both current owning repos accepted exact histories without source writes. +Implementation is staged; deployment gate is unresolved. + +## Approved deployment and actual registrar verification, 2026-10-04 + +STATE-WP-0095-T03 returned verified main-5dd3df9 / Helm revision72. +Global task-holder refusal passed inside the delivered API against the retired +Custodian parent, with transaction rollback and no committed probe. Five +historical parents/65 tasks retained their entire row snapshots. The gated +three-file registrar patch committed as c41d36c2ef8930628221ef36ec81d8b5d2145ed6; +38 actual owning-source cases passed and Repo Manager primary sync applied. + +Normal owner sync admitted all exact frozen histories without changing their +source bytes, UUIDs, parent ownership or row content. Custodian receiving +applied. Activity receiving refused only three empty duplicate projections +that would be retired; no retirement acknowledgement was issued. Registrar +allocated four missing IDs in ordinary Activity ad-hoc sources through its +normal path; frozen historical source files stayed unchanged. T03 remains wait +for explicit disposition and bounded receiving support under STATE-WP-0095-T04 +(decision91b7c633-a66f-5d43-9f4b-6565aefb9356). +Evidence: docs/evidence/2026-10-04-historical-registrar-verification.json. + +## Ungated T03 preparation, 2026-10-06 + +Re-ran the registrar suite at 8a47a5c (registrar source unchanged since +c41d36c2): 89 focused registrar/identity/historical cases and the full suite +(226) passed. Read-only hub check: the three refused projections are +683724d9 (custodian-wp-0003), 644017c7 (custodian-wp-0003a) and a5806df9 +(custodian-wp-0003b), each with zero tasks; every custodian-WP-0003* source +file binds parent b4eb45a9, which holds the tasks and must not be retired. +Added repo_manager.retirement_disposition, a read-only check that an Activity +expected_retirement_uuids set equals exactly those three empty projections and +excludes the preserved parent. It authorizes nothing; retirement stays with +Activity receiving under STATE-WP-0095-T04. + +## Activity disposition received, 2026-10-06 + +activity-core returned the exact expected_retirement_uuids (message 17ba4201, +evidence activity-core 941fac0, ACTIVITY-WP-0045): 683724d9, 644017c7, +a5806df9. repo_manager.retirement_disposition accepted the set: it equals the +three projections the 2026-10-04 run refused, each holds zero tasks, and it +excludes preserved parent b4eb45a9. Nothing was applied. T03 stays wait: its +acceptance needs a successful Activity owner sync with receipts, which can run +only after the founder decides 91b7c633 and STATE-WP-0095-T04 retires exactly +this set in a reviewed live rollout. Then re-run rmgr sync --path +~/activity-core --push and feed the receipt back to STATE-WP-0095-T04. + +## Post-retirement owner sync attempt, 2026-10-06 + +State Hub reported decision 91b7c633 resolved, main-968a811 / Helm rev 74 +deployed, and Activity reconcile at 67a92d2 retiring exactly the three empty +projections (3 retired, 0 created, 0 refused; 4 historical parents / 64 tasks +unchanged). Evidence: state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. +`rmgr sync --path ~/activity-core --push` stopped before reconciliation with +status pending_commit: uncommitted `state_hub_workstream_id` / `state_hub_task_id` +writeback in activity-core workplans/ACTIVITY-WP-0045-stale-historical-projection-disposition.md +(plus WORK-RECORDS.md). No hub request was made. Repo Manager does not commit in +activity-core; T03 stays wait until Activity Core commits and the sync re-runs. + +Re-run 2026-10-06 08:42Z after Activity Core committed the writeback (e809fb2): +status applied, created 0 / updated 45 (ACTIVITY-WP only) / retired 0 / refused 0, +no task changes, notes preserve custodian-WP-0001..0004 UUIDs; hub shows 4 parents, +64 tasks. Not closed: historical parent b4eb45a9 (custodian-WP-0003, source +`status: archived`, evidence snapshot archived) now reads `finished` in the hub, +updated 08:42:03Z during this sync. Needs State Hub review before T03 closes. + +Closed 2026-10-06: State Hub traced the b4eb45a9 status change to its own C-04 +check, which ran once per file. The custodian-WP-0003a/b/c split views share the +parent UUID, so whichever view ran last set the row. The Forge reconcile did not +cause it. Fixed in state-hub 2b5d8f9 (STATE-WP-ADHOC-2026-10-06-T01); b4eb45a9 is +back to `archived`. Re-check: 4 parents (b4eb45a9 archived; 3a4f47d9, 759b1255, +e22516cc finished) holding 64 tasks (24+12+7+21). Receipt: Activity sync at e809fb2, +primary/railiance01, applied, 0 created / 45 updated (ACTIVITY-WP only) / 0 retired +/ 0 refused, 0 task changes, historical UUIDs preserved. Evidence: +state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. + + +## Cluster exact historical source successor, 2026-10-17 + +This scoped extension preserves the completed Activity/Custodian work above. +The cluster publisher now refuses three closed RAIL-BS source files containing +15 existing UUID-bound bare task labels. Preserve all three source bytes, IDs, +and UUIDs. No new alias or general syntax exemption is introduced. Evidence and +exact receiver-first proposal: cluster-historical-publication-r1 in the Custodian +NetKingdom change packet. The existing SHR-WP-0001 project driver owns the +Repo Manager / State Hub cross-owner wait; NK-WP-0049-T35 benefits from the +blocked cluster publication. No worker or human gate is woken here. + +## Prepare exact cluster registrar successor + +```task +id: RMGR-WP-0019-T04 +status: done +priority: high +state_hub_task_id: "1ccb06c6-ad30-5847-8704-e5628ba81f35" +``` + +Prepared full-file SHA256 bindings for three archives and 15 exact task +occurrences; strict scans still return 15 invalid labels and five collisions. +Unknown/live sources, changed/missing/symlinked histories, UUID drift and +qualified/global collisions refuse before allocation. Candidate tests pass 47; +canonical application remains a separate reviewed step. The read-only current +cluster preview proposes seven ordinary UUID bindings in two files and changes +no bytes. One pre-existing ADHOC field is included explicitly: task +RCLUSTER-WP-ADHOC-2026-07-27-T01 in workplans/ADHOC-2026-07-27.md receives +3e3f39d3-5070-5ba3-97db-19f5f361f264 through managed allocation only. + +## Admit cluster registrar successor only after receiving verification + +```task +id: RMGR-WP-0019-T05 +status: done +priority: high +depends_on: [STATE-WP-0095-T06] +state_hub_task_id: "36f47e21-42d0-5aef-b065-4a5dd3af0726" +``` + +Retain the current guard until exact reviewed receiving source has been delivered +and verified through State Hub's normal owner deployment. Match both manifests, +then integrate reviewed registrar source and verify ordinary allocator preview. +No direct API patch, history rename or bypass substitutes for this gate. + +## Run ordinary cluster owner publication and verify preservation + +```task +id: RMGR-WP-0019-T06 +status: wait +priority: high +depends_on: [RMGR-WP-0019-T05] +state_hub_task_id: "4d1675b6-f49f-5b01-8d76-bbf2030d1b34" +``` + +Only then run normal owner consistency/publication with the reviewed expected +file set: RCLUSTER-WP-0018 and the one-field ADHOC managed backfill, plus ordinary +generated indexes. Preserve all three archived files and all 18 existing +parent/task rows. Return actual receiving/publication receipts to STATE-WP-0095-T07. +Do not infer TLS recovery, credential custody or native acceptance from sync. + +Cluster publication returned, preservation acceptance failed, 2026-10-17: +normal owner publication at c562d7134c38679952a8ffd17a8a893a900aef0d +is applied on primary/railiance01 with expected and derived commits equal. +Read-only source/remote/Hub verification confirms WP0018's five task bindings +and three internal dependency edges. These publication results do not close T06. +The full-row guard after the required legacy deep consistency pass failed: +all three historical parent full-row hashes changed; all 15 historical task +full-row hashes remain equal. The entire pipeline therefore has no successful +18-row preservation acceptance. + +Custodian receipts under docs/changes/netkingdom-target-2026-10-17: +railiance-cluster-projection.json and cluster-publication-readback.json retain +the applied publication and bounded readback; receiver-rollout-r4/ +pre-publication-full-row-hashes.json retains the passing pre-publication guard; +receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json retains the +failed native comparison. Exact receipt digests are retained in +registrar-t06-preservation-failure-r1/manifest.json. Coordinator and recovery +source review identified the unguarded PUT /workplans/index/bindings path +writing backing_synced_at and ORM updated_at, outside the native forge +projection's preservation guard. Full baseline rows were not retained, only +full-row hashes; no guessed database restoration is authorized or claimed. + +The original rollout's pre-Cluster preservation/refusal verification remains +valid for that earlier stage, and T05 remains done. T06 stays wait pending +the reviewed exact-frozen binding guard, regression coverage and a verified +recovery/preservation disposition. No source or native gate is promoted by the +successful publication alone; no TLS or credential-custody acceptance follows. + + +## Receiver-first registrar source follow-through, 2026-10-17 + +The exact receiving return is retained in Custodian +`docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json`, +bound to the actual native rollout/preservation/refusal receipts. It verifies the +reviewed receiver source/image/module, API/MCP readiness, expected additive schema, +three existing historical parents/15 tasks and rolled-back safe refusal probes. +Only after that return was the exact registrar patch +`232552c3d601d185984be5a8e5bc9937bc9ddda7327923b5f0440f6deb2c87fc` +admitted in the Repo Manager owner source. T04 retains its source-preparation +outcome; T05 records this receiving-gated registrar admission, not a substitute +for receiving. Canonical focused registrar/identity checks passed 47 cases in 5.84 seconds. +The actual bounded read-only current Cluster allocator preview agreed with the +reviewed source: seven ordinary missing UUID bindings in exactly the new WP0018 and +one-field existing ADHOC backfill, with 15 invalid labels/five collisions still +reported by the strict conformance scan. The three historical file bytes, IDs, +UUIDs and ownership are unchanged. No broad syntax relaxation or direct Hub UUID +patch is introduced. Exact source application/test/preview receipts travel with +the same packet; source publication/projection is verified separately. + +T06 remains wait until actual ordinary Cluster owner publication and receiving +preservation are verified. Registrar source readiness alone does not mark that +publication complete. Preserve the 18 existing rows and all three archives; the +root coordinator owns the normal seven-field managed allocation and dirty-source +preservation. Own Repo Manager projection must show exactly T01–T05 done, T06 +wait and active workplan status, including the managed new T04/T05/T06 UUIDs and +unchanged earlier task UUIDs. The separate scanner RMGR-WP-0021-T05 completion +and unrelated owner work remain untouched. No native TLS recovery, custody, +current registration/private admission or NetKingdom target acceptance follows. diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/RMGR-WP-0019.preimage.md b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/RMGR-WP-0019.preimage.md new file mode 100644 index 00000000..5bc6b7d5 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/RMGR-WP-0019.preimage.md @@ -0,0 +1,241 @@ +--- +id: RMGR-WP-0019 +type: workplan +title: "Admit exact historical source views after receiving preservation support" +domain: infotech +repo: repo-manager +status: active +owner: codex +created: "2026-10-04" +updated: "2026-10-17" +flavor: implementation +depends_on: [] +state_hub_workstream_id: "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab" +--- + +## Goal + +Unblock normal authoritative registration of the exact closed Activity legacy +source views and Custodian retired ADHOC source after receiving preserves their +existing records. Preserve every legacy source byte, label and UUID; do not +expand canonical syntax or the general grandfathering rules. CUST-WP-0077 owns +cross-owner coordination with STATE-WP-0095. + +## Review exact historical receiving contract + +```task +id: RMGR-WP-0019-T01 +status: done +priority: high +state_hub_task_id: "d78a622e-39f9-5923-b4e1-f70fdc17fb42" +``` + +Seven Activity sources yield four existing parents/64 closed bound tasks; +three split views repeat the archived parent. One Custodian retired source keeps +its existing parent/task IDs. Earlier /tmp/activity-core-bound-history-write.py +is superseded and must not be applied: registrar bypass alone would admit an +unsupported receiving projection. RMGR-WP-0014/0015 are finished and do not own +this new implementation demand; this workplan is not residual. + +## Enable exact frozen registrar exceptions after receiving deployment + +```task +id: RMGR-WP-0019-T02 +status: done +priority: high +depends_on: [STATE-WP-0095-T03] +state_hub_task_id: "95240c81-1805-5365-9b35-d238621a16bf" +``` + +Prepared code permits only source paths with reviewed full SHA256 digests in +repo_manager/historical_sources.py. Strict conformance scans retain their legacy +findings. Unknown/missing/altered source refuses before allocation. Source UUIDs +are neither changed nor allocated for these histories. Receiving and registrar +manifests must remain identical. Apply helper requires a deployment receipt. + +## Run normal owner sync and verify preserved identities + +```task +id: RMGR-WP-0019-T03 +status: done +priority: high +depends_on: [RMGR-WP-0019-T02] +state_hub_task_id: "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d" +``` + +Use rmgr sync --path --push. No deep-check repair or direct hub UUID +patch substitutes for receiving. Historical unrelated stale projections are not +retirement-authorized by this workplan. Feed receipts back to STATE-WP-0095-T04. + +## Offline evidence, 2026-10-04 + +Prepared registrar suite: 38 focused cases passed (identifiers, registrar, +Custodian legacy identity and exact frozen source cases). Read-only execute=False +against both current owning repos accepted exact histories without source writes. +Implementation is staged; deployment gate is unresolved. + +## Approved deployment and actual registrar verification, 2026-10-04 + +STATE-WP-0095-T03 returned verified main-5dd3df9 / Helm revision72. +Global task-holder refusal passed inside the delivered API against the retired +Custodian parent, with transaction rollback and no committed probe. Five +historical parents/65 tasks retained their entire row snapshots. The gated +three-file registrar patch committed as c41d36c2ef8930628221ef36ec81d8b5d2145ed6; +38 actual owning-source cases passed and Repo Manager primary sync applied. + +Normal owner sync admitted all exact frozen histories without changing their +source bytes, UUIDs, parent ownership or row content. Custodian receiving +applied. Activity receiving refused only three empty duplicate projections +that would be retired; no retirement acknowledgement was issued. Registrar +allocated four missing IDs in ordinary Activity ad-hoc sources through its +normal path; frozen historical source files stayed unchanged. T03 remains wait +for explicit disposition and bounded receiving support under STATE-WP-0095-T04 +(decision91b7c633-a66f-5d43-9f4b-6565aefb9356). +Evidence: docs/evidence/2026-10-04-historical-registrar-verification.json. + +## Ungated T03 preparation, 2026-10-06 + +Re-ran the registrar suite at 8a47a5c (registrar source unchanged since +c41d36c2): 89 focused registrar/identity/historical cases and the full suite +(226) passed. Read-only hub check: the three refused projections are +683724d9 (custodian-wp-0003), 644017c7 (custodian-wp-0003a) and a5806df9 +(custodian-wp-0003b), each with zero tasks; every custodian-WP-0003* source +file binds parent b4eb45a9, which holds the tasks and must not be retired. +Added repo_manager.retirement_disposition, a read-only check that an Activity +expected_retirement_uuids set equals exactly those three empty projections and +excludes the preserved parent. It authorizes nothing; retirement stays with +Activity receiving under STATE-WP-0095-T04. + +## Activity disposition received, 2026-10-06 + +activity-core returned the exact expected_retirement_uuids (message 17ba4201, +evidence activity-core 941fac0, ACTIVITY-WP-0045): 683724d9, 644017c7, +a5806df9. repo_manager.retirement_disposition accepted the set: it equals the +three projections the 2026-10-04 run refused, each holds zero tasks, and it +excludes preserved parent b4eb45a9. Nothing was applied. T03 stays wait: its +acceptance needs a successful Activity owner sync with receipts, which can run +only after the founder decides 91b7c633 and STATE-WP-0095-T04 retires exactly +this set in a reviewed live rollout. Then re-run rmgr sync --path +~/activity-core --push and feed the receipt back to STATE-WP-0095-T04. + +## Post-retirement owner sync attempt, 2026-10-06 + +State Hub reported decision 91b7c633 resolved, main-968a811 / Helm rev 74 +deployed, and Activity reconcile at 67a92d2 retiring exactly the three empty +projections (3 retired, 0 created, 0 refused; 4 historical parents / 64 tasks +unchanged). Evidence: state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. +`rmgr sync --path ~/activity-core --push` stopped before reconciliation with +status pending_commit: uncommitted `state_hub_workstream_id` / `state_hub_task_id` +writeback in activity-core workplans/ACTIVITY-WP-0045-stale-historical-projection-disposition.md +(plus WORK-RECORDS.md). No hub request was made. Repo Manager does not commit in +activity-core; T03 stays wait until Activity Core commits and the sync re-runs. + +Re-run 2026-10-06 08:42Z after Activity Core committed the writeback (e809fb2): +status applied, created 0 / updated 45 (ACTIVITY-WP only) / retired 0 / refused 0, +no task changes, notes preserve custodian-WP-0001..0004 UUIDs; hub shows 4 parents, +64 tasks. Not closed: historical parent b4eb45a9 (custodian-WP-0003, source +`status: archived`, evidence snapshot archived) now reads `finished` in the hub, +updated 08:42:03Z during this sync. Needs State Hub review before T03 closes. + +Closed 2026-10-06: State Hub traced the b4eb45a9 status change to its own C-04 +check, which ran once per file. The custodian-WP-0003a/b/c split views share the +parent UUID, so whichever view ran last set the row. The Forge reconcile did not +cause it. Fixed in state-hub 2b5d8f9 (STATE-WP-ADHOC-2026-10-06-T01); b4eb45a9 is +back to `archived`. Re-check: 4 parents (b4eb45a9 archived; 3a4f47d9, 759b1255, +e22516cc finished) holding 64 tasks (24+12+7+21). Receipt: Activity sync at e809fb2, +primary/railiance01, applied, 0 created / 45 updated (ACTIVITY-WP only) / 0 retired +/ 0 refused, 0 task changes, historical UUIDs preserved. Evidence: +state-hub docs/evidence/2026-10-06-activity-stale-retirement-rollout.json. + + +## Cluster exact historical source successor, 2026-10-17 + +This scoped extension preserves the completed Activity/Custodian work above. +The cluster publisher now refuses three closed RAIL-BS source files containing +15 existing UUID-bound bare task labels. Preserve all three source bytes, IDs, +and UUIDs. No new alias or general syntax exemption is introduced. Evidence and +exact receiver-first proposal: cluster-historical-publication-r1 in the Custodian +NetKingdom change packet. The existing SHR-WP-0001 project driver owns the +Repo Manager / State Hub cross-owner wait; NK-WP-0049-T35 benefits from the +blocked cluster publication. No worker or human gate is woken here. + +## Prepare exact cluster registrar successor + +```task +id: RMGR-WP-0019-T04 +status: done +priority: high +state_hub_task_id: "1ccb06c6-ad30-5847-8704-e5628ba81f35" +``` + +Prepared full-file SHA256 bindings for three archives and 15 exact task +occurrences; strict scans still return 15 invalid labels and five collisions. +Unknown/live sources, changed/missing/symlinked histories, UUID drift and +qualified/global collisions refuse before allocation. Candidate tests pass 47; +canonical application remains a separate reviewed step. The read-only current +cluster preview proposes seven ordinary UUID bindings in two files and changes +no bytes. One pre-existing ADHOC field is included explicitly: task +RCLUSTER-WP-ADHOC-2026-07-27-T01 in workplans/ADHOC-2026-07-27.md receives +3e3f39d3-5070-5ba3-97db-19f5f361f264 through managed allocation only. + +## Admit cluster registrar successor only after receiving verification + +```task +id: RMGR-WP-0019-T05 +status: done +priority: high +depends_on: [STATE-WP-0095-T06] +state_hub_task_id: "36f47e21-42d0-5aef-b065-4a5dd3af0726" +``` + +Retain the current guard until exact reviewed receiving source has been delivered +and verified through State Hub's normal owner deployment. Match both manifests, +then integrate reviewed registrar source and verify ordinary allocator preview. +No direct API patch, history rename or bypass substitutes for this gate. + +## Run ordinary cluster owner publication and verify preservation + +```task +id: RMGR-WP-0019-T06 +status: wait +priority: high +depends_on: [RMGR-WP-0019-T05] +state_hub_task_id: "4d1675b6-f49f-5b01-8d76-bbf2030d1b34" +``` + +Only then run normal owner consistency/publication with the reviewed expected +file set: RCLUSTER-WP-0018 and the one-field ADHOC managed backfill, plus ordinary +generated indexes. Preserve all three archived files and all 18 existing +parent/task rows. Return actual receiving/publication receipts to STATE-WP-0095-T07. +Do not infer TLS recovery, credential custody or native acceptance from sync. + + +## Receiver-first registrar source follow-through, 2026-10-17 + +The exact receiving return is retained in Custodian +`docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json`, +bound to the actual native rollout/preservation/refusal receipts. It verifies the +reviewed receiver source/image/module, API/MCP readiness, expected additive schema, +three existing historical parents/15 tasks and rolled-back safe refusal probes. +Only after that return was the exact registrar patch +`232552c3d601d185984be5a8e5bc9937bc9ddda7327923b5f0440f6deb2c87fc` +admitted in the Repo Manager owner source. T04 retains its source-preparation +outcome; T05 records this receiving-gated registrar admission, not a substitute +for receiving. Canonical focused registrar/identity checks passed 47 cases in 5.84 seconds. +The actual bounded read-only current Cluster allocator preview agreed with the +reviewed source: seven ordinary missing UUID bindings in exactly the new WP0018 and +one-field existing ADHOC backfill, with 15 invalid labels/five collisions still +reported by the strict conformance scan. The three historical file bytes, IDs, +UUIDs and ownership are unchanged. No broad syntax relaxation or direct Hub UUID +patch is introduced. Exact source application/test/preview receipts travel with +the same packet; source publication/projection is verified separately. + +T06 remains wait until actual ordinary Cluster owner publication and receiving +preservation are verified. Registrar source readiness alone does not mark that +publication complete. Preserve the 18 existing rows and all three archives; the +root coordinator owns the normal seven-field managed allocation and dirty-source +preservation. Own Repo Manager projection must show exactly T01–T05 done, T06 +wait and active workplan status, including the managed new T04/T05/T06 UUIDs and +unchanged earlier task UUIDs. The separate scanner RMGR-WP-0021-T05 completion +and unrelated owner work remain untouched. No native TLS recovery, custody, +current registration/private admission or NetKingdom target acceptance follows. diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-commit.json b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-commit.json new file mode 100644 index 00000000..6d61620a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-commit.json @@ -0,0 +1,13 @@ +{ + "status": "committed-exact-one-file", + "head": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "parent": "70cd754996870638848616e37819790a5c4d52b3", + "path": "workplans/RMGR-WP-0019-historical-source-admission.md", + "source_sha256": "4ff763ea24b9948d59b4bdd4f5ef3e95bee72fef3016f0b6404b5db663cb83ff", + "scanner_sha256_unchanged": "e709c658f779534fcab093207b0a78e49d54fc584c515fdf7ac535ce75f6c400", + "task_blocks_and_UUIDs_unchanged": true, + "t05": "done", + "t06": "wait", + "commit_output": "[main 7c15c0e] Retain Cluster publication with failed historical row preservation\n 1 file changed, 28 insertions(+)\n", + "cluster_or_database_mutation": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-publication-readback.json b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-publication-readback.json new file mode 100644 index 00000000..674bdf24 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-publication-readback.json @@ -0,0 +1,136 @@ +{ + "status": "verified", + "scope": "RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots", + "writes_to_source_index_refs_or_Hub": false, + "rows": [ + { + "repo": "repo-manager", + "published_commit": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "remote": { + "HEAD": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "refs/heads/main": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "symbolic_HEAD": "refs/heads/main" + }, + "workplan": { + "id": "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab", + "slug": "rmgr-wp-0019", + "status": "active" + }, + "source_record_id": "RMGR-WP-0019", + "tasks": [ + { + "id": "d78a622e-39f9-5923-b4e1-f70fdc17fb42", + "record_id": "RMGR-WP-0019-T01", + "status": "done" + }, + { + "id": "95240c81-1805-5365-9b35-d238621a16bf", + "record_id": "RMGR-WP-0019-T02", + "status": "done" + }, + { + "id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d", + "record_id": "RMGR-WP-0019-T03", + "status": "done" + }, + { + "id": "1ccb06c6-ad30-5847-8704-e5628ba81f35", + "record_id": "RMGR-WP-0019-T04", + "status": "done" + }, + { + "id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "record_id": "RMGR-WP-0019-T05", + "status": "done" + }, + { + "id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "record_id": "RMGR-WP-0019-T06", + "status": "wait" + } + ], + "external_source_declarations_not_projected": [ + { + "from_task_id": "95240c81-1805-5365-9b35-d238621a16bf", + "target_record_id": "STATE-WP-0095-T03", + "target_uuid": "e8566341-cf6e-5b9c-ad80-8564d14cd52a" + }, + { + "from_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "target_record_id": "STATE-WP-0095-T06", + "target_uuid": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4" + } + ], + "dependencies": [ + { + "from_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "to_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "relationship_type": "starts_after" + }, + { + "from_task_id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d", + "to_task_id": "95240c81-1805-5365-9b35-d238621a16bf", + "relationship_type": "starts_after" + } + ], + "source_file_sha256": "4ff763ea24b9948d59b4bdd4f5ef3e95bee72fef3016f0b6404b5db663cb83ff", + "source_file_unchanged": true, + "dependency_scope": "internal edges verified; external source target identities checked without claiming projected external edges", + "index_stat_unchanged": true + }, + { + "repo": "repo-manager", + "published_commit": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "remote": { + "HEAD": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "refs/heads/main": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "symbolic_HEAD": "refs/heads/main" + }, + "workplan": { + "id": "5aa6f84a-c682-5996-ae26-96daef670833", + "slug": "rmgr-wp-0021", + "status": "active" + }, + "source_record_id": "RMGR-WP-0021", + "tasks": [ + { + "id": "d3d20c18-5a5f-5f8a-b5c4-a22b4b662ebe", + "record_id": "RMGR-WP-0021-T01", + "status": "done" + }, + { + "id": "e27817e6-b298-581f-b99a-05ec459be749", + "record_id": "RMGR-WP-0021-T02", + "status": "done" + }, + { + "id": "0ab44bd9-00d8-5470-ad45-7350e7868d0a", + "record_id": "RMGR-WP-0021-T03", + "status": "progress" + }, + { + "id": "44272818-db49-58a2-83b1-d2f9e9d5976c", + "record_id": "RMGR-WP-0021-T04", + "status": "todo" + }, + { + "id": "25fbe694-41d8-5232-bce0-4ed362387d5a", + "record_id": "RMGR-WP-0021-T05", + "status": "done" + } + ], + "external_source_declarations_not_projected": [], + "dependencies": [], + "source_file_sha256": "966d15ccdabc8edf98bc58f9422ea190566d05fe4208f4749f59a9731f4e108d", + "source_file_unchanged": true, + "dependency_scope": "internal edges verified; external source target identities checked without claiming projected external edges", + "index_stat_unchanged": true + } + ], + "hub_instance": { + "status": "ok", + "instance_role": "primary", + "instance_label": "railiance01" + }, + "verifier_sha256": "a2b7842c378a2fcaaecfd006d1549f6451f72e260d4b6fb8e193080fcfb7d472" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-sync.json b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-sync.json new file mode 100644 index 00000000..53881f9a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-sync.json @@ -0,0 +1,92 @@ +{ + "ok": true, + "status": "applied", + "repo_slug": "repo-manager", + "commit": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "requests": 2, + "elapsed_ms": 10556.3, + "git": { + "upstream": "origin/main", + "behind": 0, + "ahead": 0 + }, + "identifiers": { + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": true, + "repo": "repo-manager", + "namespace": "helixforge", + "assignments": [], + "historical_invalid_identifiers": [], + "historical_identity_collisions": [], + "files_changed": [] + }, + "receipt": { + "schema": "state-hub.repository-projection-reconcile.v1", + "instance_role": "primary", + "instance_label": "railiance01", + "expected_commit": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "derived_commit": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "outcome": { + "schema": "state-hub.projection-reset.v1", + "repo_slug": "repo-manager", + "commit": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "status": "applied", + "counts": { + "created": 0, + "updated": 25, + "retired": 0, + "refused": 0, + "released": 0, + "created_tasks": 0, + "updated_tasks": 1, + "cancelled_tasks": 0, + "created_edges": 0, + "removed_edges": 0, + "unresolved_edges": 0, + "external_edges": 0 + }, + "created": [], + "updated": [ + "RMGR-WP-0001", + "RMGR-WP-0002", + "RMGR-WP-0003", + "RMGR-WP-0004", + "RMGR-WP-0005", + "RMGR-WP-0006", + "RMGR-WP-0007", + "RMGR-WP-0008", + "RMGR-WP-0009", + "RMGR-WP-0010", + "RMGR-WP-0011", + "RMGR-WP-0012", + "RMGR-WP-0013", + "RMGR-WP-0014", + "RMGR-WP-0015", + "RMGR-WP-0016", + "RMGR-WP-0017", + "RMGR-WP-0018", + "RMGR-WP-0019", + "RMGR-WP-0020", + "RMGR-WP-0021", + "RMGR-WP-ADHOC-2026-09-06", + "RMGR-WP-ADHOC-2026-09-09", + "RMGR-WP-ADHOC-2026-09-11", + "RMGR-WP-ADHOC-2026-10-03" + ], + "retired": [], + "released": [], + "created_tasks": [], + "updated_tasks": [ + "RMGR-WP-0019-T06" + ], + "cancelled_tasks": [], + "created_edges": [], + "removed_edges": [], + "unresolved_edges": [], + "external_edges": [], + "refused": [], + "notes": [] + } + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/manifest.json b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/manifest.json new file mode 100644 index 00000000..3c5086b1 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/manifest.json @@ -0,0 +1,22 @@ +{ + "status": "prepared-source-only-not-applied", + "base_head": "70cd754996870638848616e37819790a5c4d52b3", + "owner_path": "workplans/RMGR-WP-0019-historical-source-admission.md", + "preimage_sha256": "c09c685313de13ad4a31891fd67b8a92f3d9a085c37cee92257d15b485a32cde", + "candidate_sha256": "4ff763ea24b9948d59b4bdd4f5ef3e95bee72fef3016f0b6404b5db663cb83ff", + "patch_sha256": "e8af90d6714b0545d8b78fcb43df42a9d9e6056a0491658b30514ab942a7f23e", + "task_blocks_and_UUIDs_unchanged": true, + "t05": "done", + "t06": "wait", + "changed_parent_full_hashes": 3, + "unchanged_task_full_hashes": 15, + "all_18_preserved_after_pipeline": false, + "canonical_mutation": false, + "receipts": { + "railiance-cluster-projection.json": "c92d96f54fe7afcdfdf54fd666ce0f697219e9864d331ccddff41a246179115e", + "cluster-publication-readback.json": "d3a6e4db0195416fdadcf94ba21b956ac74ccd23d71a5a4ce577cbe2fe1f923b", + "receiver-rollout-r4/verified-receiving-return.json": "d088c336d62c7bdde0e586b0f1b73c3aa3d4031a4debd9ac90206128728257f4", + "receiver-rollout-r4/pre-publication-full-row-hashes.json": "bf01a632d7185705bce44b96210f7376e7f94c65cc5b858924eb0bed19c73dfd", + "receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json": "ea08b8f5581e6fb335359427a4b24f990bc814b452d3733f7d4174bb1b6ed6df" + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/owner-amendment.patch b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/owner-amendment.patch new file mode 100644 index 00000000..78dc1b6b --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/owner-amendment.patch @@ -0,0 +1,37 @@ +--- a/workplans/RMGR-WP-0019-historical-source-admission.md ++++ b/workplans/RMGR-WP-0019-historical-source-admission.md +@@ -208,6 +208,34 @@ + generated indexes. Preserve all three archived files and all 18 existing + parent/task rows. Return actual receiving/publication receipts to STATE-WP-0095-T07. + Do not infer TLS recovery, credential custody or native acceptance from sync. ++ ++Cluster publication returned, preservation acceptance failed, 2026-10-17: ++normal owner publication at c562d7134c38679952a8ffd17a8a893a900aef0d ++is applied on primary/railiance01 with expected and derived commits equal. ++Read-only source/remote/Hub verification confirms WP0018's five task bindings ++and three internal dependency edges. These publication results do not close T06. ++The full-row guard after the required legacy deep consistency pass failed: ++all three historical parent full-row hashes changed; all 15 historical task ++full-row hashes remain equal. The entire pipeline therefore has no successful ++18-row preservation acceptance. ++ ++Custodian receipts under docs/changes/netkingdom-target-2026-10-17: ++railiance-cluster-projection.json and cluster-publication-readback.json retain ++the applied publication and bounded readback; receiver-rollout-r4/ ++pre-publication-full-row-hashes.json retains the passing pre-publication guard; ++receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json retains the ++failed native comparison. Exact receipt digests are retained in ++registrar-t06-preservation-failure-r1/manifest.json. Coordinator and recovery ++source review identified the unguarded PUT /workplans/index/bindings path ++writing backing_synced_at and ORM updated_at, outside the native forge ++projection's preservation guard. Full baseline rows were not retained, only ++full-row hashes; no guessed database restoration is authorized or claimed. ++ ++The original rollout's pre-Cluster preservation/refusal verification remains ++valid for that earlier stage, and T05 remains done. T06 stays wait pending ++the reviewed exact-frozen binding guard, regression coverage and a verified ++recovery/preservation disposition. No source or native gate is promoted by the ++successful publication alone; no TLS or credential-custody acceptance follows. + + + ## Receiver-first registrar source follow-through, 2026-10-17 diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/publication-final-manifest.json b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/publication-final-manifest.json new file mode 100644 index 00000000..6ae9a298 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/publication-final-manifest.json @@ -0,0 +1,24 @@ +{ + "status": "published-and-readback-verified", + "head": "7c15c0ea48981867fc1683d9b7576f6444c256da", + "path_count": 1, + "task_blocks_and_UUIDs_unchanged": true, + "t05": "done", + "t06": "wait", + "scanner_unchanged": true, + "cluster_or_database_changes": false, + "worktree_clean": true, + "all_18_historical_rows_preserved_after_cluster_pipeline": false, + "readback_verifier_refinement": "R1 retained; unchanged exact T06-to-T05 dependency preserves its known creation commit70cd on description-only sync", + "files": { + "manifest.json": "5d1989cb40f9206d928d023370bbcbd781b835a8e32925d1ce7e21d21d04a640", + "owner-amendment.patch": "e8af90d6714b0545d8b78fcb43df42a9d9e6056a0491658b30514ab942a7f23e", + "publish_amendment.py": "8521a46b5daed3e268b0569d69b608e9cefbbd87b5454e19eb6413e421ed89e3", + "amendment-commit.json": "fe3fa69da34257ec2f66fd4d659f925c17b0f80caedbb99092b0bade3de17f73", + "amendment-sync.json": "9bb18ad3881a3b8cb35595c7ddf92d2908a3c9e8fccde38f64546150174b1ef1", + "verify_amendment_publication.py": "a2b7842c378a2fcaaecfd006d1549f6451f72e260d4b6fb8e193080fcfb7d472", + "amendment-publication-readback.json": "8c78373a27d448ddb4dbd9374e389df040866a91d5be669ac23c09af8808f213", + "r1-verify_amendment_publication.py": "d13131f6f1179d082078e7fe87fec2fabf72e8931fa6a320120623869939e1c4", + "r1-amendment-publication-readback.json": "f4a1d44b4d73e4cd18e52295969d655c1519c93b39813eff1997c2dd7334700e" + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/publish_amendment.py b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/publish_amendment.py new file mode 100644 index 00000000..8c97e182 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/publish_amendment.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +from pathlib import Path +import hashlib,json,subprocess +P=Path(__file__).resolve().parent +R=Path('/home/worsch/repo-manager') +m=json.loads((P/'manifest.json').read_text()); f=R/m['owner_path'] +def h(p):return hashlib.sha256(p.read_bytes()).hexdigest() +def git(*args): + r=subprocess.run(['git',*args],cwd=R,text=True,capture_output=True,timeout=180) + if r.returncode: raise RuntimeError(json.dumps({'args':args,'stdout':r.stdout,'stderr':r.stderr,'code':r.returncode})) + return r.stdout +assert git('rev-parse','HEAD').strip()==m['base_head'] +assert h(f)==m['preimage_sha256'] +assert h(P/'owner-amendment.patch')==m['patch_sha256']=='e8af90d6714b0545d8b78fcb43df42a9d9e6056a0491658b30514ab942a7f23e' +assert h(P/'RMGR-WP-0019.candidate.md')==m['candidate_sha256'] +assert not git('diff','--cached','--name-only') +scanner=R/'src/repo_manager/secret_scan.py'; before=h(scanner) +assert before=='e709c658f779534fcab093207b0a78e49d54fc584c515fdf7ac535ce75f6c400' +git('apply','--check',str(P/'owner-amendment.patch')) +git('apply',str(P/'owner-amendment.patch')) +assert h(f)==m['candidate_sha256'] +git('add','--',m['owner_path']) +assert git('diff','--cached','--name-only').splitlines()==[m['owner_path']] +git('diff','--cached','--check') +output=git('commit','-m','Retain Cluster publication with failed historical row preservation') +head=git('rev-parse','HEAD').strip() +assert git('diff-tree','--no-commit-id','--name-only','-r',head).splitlines()==[m['owner_path']] +assert h(scanner)==before +receipt={'status':'committed-exact-one-file','head':head,'parent':m['base_head'],'path':m['owner_path'],'source_sha256':h(f),'scanner_sha256_unchanged':before,'task_blocks_and_UUIDs_unchanged':True,'t05':'done','t06':'wait','commit_output':output,'cluster_or_database_mutation':False} +(P/'amendment-commit.json').write_text(json.dumps(receipt,indent=2)+'\n');print(json.dumps(receipt,indent=2)) diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/r1-amendment-publication-readback.json b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/r1-amendment-publication-readback.json new file mode 100644 index 00000000..a45571f6 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/r1-amendment-publication-readback.json @@ -0,0 +1,13 @@ +{ + "status": "unverified", + "scope": "RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots", + "writes_to_source_index_refs_or_Hub": false, + "rows": [], + "hub_instance": { + "status": "ok", + "instance_role": "primary", + "instance_label": "railiance01" + }, + "reason": "dependency-source-commit-mismatch", + "verifier_sha256": "d13131f6f1179d082078e7fe87fec2fabf72e8931fa6a320120623869939e1c4" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/r1-verify_amendment_publication.py b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/r1-verify_amendment_publication.py new file mode 100644 index 00000000..2507e633 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/r1-verify_amendment_publication.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +"""Read-only Git+Hub task binding verifier; never syncs or changes source/index.""" +import hashlib +import json +import os +from pathlib import Path +import re +import subprocess +import urllib.request + +HERE=Path(__file__).resolve().parent +OWNERS=[ + {'repo':'repo-manager','commit':'7c15c0ea48981867fc1683d9b7576f6444c256da','path':'workplans/RMGR-WP-0019-historical-source-admission.md','id':'RMGR-WP-0019','tasks':6}, + {'repo':'repo-manager','commit':'7c15c0ea48981867fc1683d9b7576f6444c256da','path':'workplans/RMGR-WP-0021-secret-detection-controls.md','id':'RMGR-WP-0021','tasks':5}, +] +API=os.environ.get('API_BASE','http://127.0.0.1:8000').rstrip('/') +EXTERNAL={'STATE-WP-0095-T03':'e8566341-cf6e-5b9c-ad80-8564d14cd52a','STATE-WP-0095-T06':'6af973b4-1964-5d4d-a2f8-8dbd4c01fda4','NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'} + + +class Refused(Exception):pass + + +def git(root,*args): + result=subprocess.run(['git','--no-optional-locks','-C',str(root),*args], + capture_output=True,timeout=30,check=False) + if result.returncode:raise Refused('read-only-git-failed') + return result.stdout + + +def field(text,key): + values=re.findall(r'^'+re.escape(key)+r':\s*(.*?)\s*$',text,re.M) + if len(values)!=1:raise Refused('source-field-ambiguous') + return values[0].strip('"\'') + + +def source(text): + header=text.split('---',2)[1] + tasks=[] + for block in re.findall(r'```task\n(.*?)\n```',text,re.S): + deps=re.findall(r'^depends_on:\s*\[(.*?)\]',block,re.M) + tasks.append({'record_id':field(block,'id'),'id':field(block,'state_hub_task_id'), + 'status':field(block,'status'),'dependencies':[x.strip() for x in deps[0].split(',') if x.strip()] if deps else []}) + return {'id':field(header,'state_hub_workstream_id'),'source_record_id':field(header,'id'), + 'slug':field(header,'id').lower(), + 'status':field(header,'status'),'tasks':tasks} + + +def get(path): + class NoRedirect(urllib.request.HTTPRedirectHandler): + def redirect_request(self,*args,**kwargs):raise Refused('hub-redirect-refused') + opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect) + with opener.open(urllib.request.Request(API+path,method='GET'),timeout=20) as response: + data=response.read(8*1024**2+1) + if len(data)>8*1024**2:raise Refused('hub-read-limit') + return json.loads(data) + + +def index_stat(root): + raw=git(root,'rev-parse','--git-path','index').decode().strip();path=Path(raw) + if not path.is_absolute():path=root/path + try:item=path.lstat() + except FileNotFoundError:return None + return [item.st_dev,item.st_ino,item.st_size,item.st_mtime_ns,item.st_mode] + + +def remote(root,expected,repo): + if git(root,'remote','get-url','origin').decode().strip()!='forgejo-remote:coulomb/'+repo+'.git': + raise Refused('remote-route-drift') + lines=git(root,'ls-remote','--symref','origin','HEAD','refs/heads/main').decode().splitlines() + if set(lines)!={'ref: refs/heads/main\tHEAD',expected+'\tHEAD',expected+'\trefs/heads/main'}: + raise Refused('remote-head-mismatch') + return {'HEAD':expected,'refs/heads/main':expected,'symbolic_HEAD':'refs/heads/main'} + + +def verify(): + result={'status':'unverified','scope':'RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots', + 'writes_to_source_index_refs_or_Hub':False,'rows':[]} + try: + if API not in {'http://127.0.0.1:8000','http://127.0.0.1:18080','http://10.43.68.154:8000'}: + raise Refused('unrecognized-hub-endpoint') + health=get('/state/health') + result['hub_instance']={key:health.get(key) for key in ('status','instance_role','instance_label')} + if result['hub_instance']!={'status':'ok','instance_role':'primary','instance_label':'railiance01'}: + raise Refused('hub-identity-mismatch') + for owner in OWNERS: + root=Path('/home/worsch')/owner['repo'];before_index=index_stat(root) + if git(root,'rev-parse','HEAD').decode().strip()!=owner['commit']: + raise Refused('local-head-drift') + committed=git(root,'show',owner['commit']+':'+owner['path']) + local=(root/owner['path']).read_bytes() + if local!=committed:raise Refused('published-workplan-local-drift') + expected=source(committed.decode()) + if expected['source_record_id']!=owner['id'] or len(expected['tasks'])!=owner['tasks']: + raise Refused('source-task-denominator-mismatch') + snapshot=get('/repos/'+owner['repo']+'/work-record-projection/snapshot') + plans=[row for row in snapshot['workplans'] if row['id']==expected['id']] + if len(plans)!=1 or any(plans[0].get(key)!=expected[key] for key in ('id','slug','status')): + raise Refused('workplan-binding-mismatch') + projected=[row for row in snapshot['tasks'] + if row.get('workplan_id',row.get('workstream_id'))==expected['id']] + if len(projected)!=len(expected['tasks']):raise Refused('projected-task-denominator-mismatch') + byid={row['id']:row for row in projected} + if len(byid)!=len(projected):raise Refused('duplicate-projected-uuid') + observed=[] + for task in expected['tasks']: + row=byid.get(task['id'],{}) + if any(row.get(key)!=task[key] for key in ('id','record_id','status')): + raise Refused('task-id-uuid-status-mismatch') + observed.append({key:row[key] for key in ('id','record_id','status')}) + identifiers={task['record_id']:task['id'] for task in expected['tasks']} + edges={(task['id'],identifiers[dep],'starts_after') for task in expected['tasks'] for dep in task['dependencies'] if dep in identifiers} + actual=[edge for edge in snapshot['dependencies'] if edge['from_workplan_id']==expected['id']] + projected_edges={(edge.get('from_task_id'),edge.get('to_task_id'),edge['relationship_type']) for edge in actual} + if len(actual)!=len(edges) or projected_edges!=edges: + raise Refused('dependency-binding-mismatch') + if any(edge.get('source_commit') not in (None,owner['commit']) for edge in actual): + raise Refused('dependency-source-commit-mismatch') + for task in expected['tasks']: + for dep in task['dependencies']: + if dep in EXTERNAL: + target=get('/tasks/'+EXTERNAL[dep]) + if target.get('id')!=EXTERNAL[dep] or target.get('record_id')!=dep: + raise Refused('external-dependency-target-mismatch') + remote_readback=remote(root,owner['commit'],owner['repo']) + if index_stat(root)!=before_index or (root/owner['path']).read_bytes()!=local: + raise Refused('source-or-index-stat-changed') + result['rows'].append({'repo':owner['repo'],'published_commit':owner['commit'], + 'remote':remote_readback,'workplan':{key:plans[0][key] for key in ('id','slug','status')}, + 'source_record_id':expected['source_record_id'], + 'tasks':observed,'external_source_declarations_not_projected':[{'from_task_id':task['id'],'target_record_id':dep,'target_uuid':EXTERNAL[dep]} for task in expected['tasks'] for dep in task['dependencies'] if dep in EXTERNAL],'dependencies':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(edges)], + 'source_file_sha256':hashlib.sha256(local).hexdigest(),'source_file_unchanged':True,'dependency_scope':'internal edges verified; external source target identities checked without claiming projected external edges', + 'index_stat_unchanged':True}) + result['status']='verified' + except Exception as error: + result['reason']=error.args[0] if isinstance(error,Refused) else 'readback-unavailable' + result['verifier_sha256']=hashlib.sha256(Path(__file__).read_bytes()).hexdigest() + (HERE/'amendment-publication-readback.json').write_text(json.dumps(result,indent=2)+'\n') + print(json.dumps({'status':result['status'],'owners':len(result['rows'])})) + return 0 if result['status']=='verified' else 2 + + +if __name__=='__main__':raise SystemExit(verify()) diff --git a/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/verify_amendment_publication.py b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/verify_amendment_publication.py new file mode 100644 index 00000000..e4188846 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/verify_amendment_publication.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python3 +"""Read-only Git+Hub task binding verifier; never syncs or changes source/index.""" +import hashlib +import json +import os +from pathlib import Path +import re +import subprocess +import urllib.request + +HERE=Path(__file__).resolve().parent +OWNERS=[ + {'repo':'repo-manager','commit':'7c15c0ea48981867fc1683d9b7576f6444c256da','path':'workplans/RMGR-WP-0019-historical-source-admission.md','id':'RMGR-WP-0019','tasks':6}, + {'repo':'repo-manager','commit':'7c15c0ea48981867fc1683d9b7576f6444c256da','path':'workplans/RMGR-WP-0021-secret-detection-controls.md','id':'RMGR-WP-0021','tasks':5}, +] +API=os.environ.get('API_BASE','http://127.0.0.1:8000').rstrip('/') +EXTERNAL={'STATE-WP-0095-T03':'e8566341-cf6e-5b9c-ad80-8564d14cd52a','STATE-WP-0095-T06':'6af973b4-1964-5d4d-a2f8-8dbd4c01fda4','NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'} + + +class Refused(Exception):pass + + +def git(root,*args): + result=subprocess.run(['git','--no-optional-locks','-C',str(root),*args], + capture_output=True,timeout=30,check=False) + if result.returncode:raise Refused('read-only-git-failed') + return result.stdout + + +def field(text,key): + values=re.findall(r'^'+re.escape(key)+r':\s*(.*?)\s*$',text,re.M) + if len(values)!=1:raise Refused('source-field-ambiguous') + return values[0].strip('"\'') + + +def source(text): + header=text.split('---',2)[1] + tasks=[] + for block in re.findall(r'```task\n(.*?)\n```',text,re.S): + deps=re.findall(r'^depends_on:\s*\[(.*?)\]',block,re.M) + tasks.append({'record_id':field(block,'id'),'id':field(block,'state_hub_task_id'), + 'status':field(block,'status'),'dependencies':[x.strip() for x in deps[0].split(',') if x.strip()] if deps else []}) + return {'id':field(header,'state_hub_workstream_id'),'source_record_id':field(header,'id'), + 'slug':field(header,'id').lower(), + 'status':field(header,'status'),'tasks':tasks} + + +def get(path): + class NoRedirect(urllib.request.HTTPRedirectHandler): + def redirect_request(self,*args,**kwargs):raise Refused('hub-redirect-refused') + opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect) + with opener.open(urllib.request.Request(API+path,method='GET'),timeout=20) as response: + data=response.read(8*1024**2+1) + if len(data)>8*1024**2:raise Refused('hub-read-limit') + return json.loads(data) + + +def index_stat(root): + raw=git(root,'rev-parse','--git-path','index').decode().strip();path=Path(raw) + if not path.is_absolute():path=root/path + try:item=path.lstat() + except FileNotFoundError:return None + return [item.st_dev,item.st_ino,item.st_size,item.st_mtime_ns,item.st_mode] + + +def remote(root,expected,repo): + if git(root,'remote','get-url','origin').decode().strip()!='forgejo-remote:coulomb/'+repo+'.git': + raise Refused('remote-route-drift') + lines=git(root,'ls-remote','--symref','origin','HEAD','refs/heads/main').decode().splitlines() + if set(lines)!={'ref: refs/heads/main\tHEAD',expected+'\tHEAD',expected+'\trefs/heads/main'}: + raise Refused('remote-head-mismatch') + return {'HEAD':expected,'refs/heads/main':expected,'symbolic_HEAD':'refs/heads/main'} + + +def verify(): + result={'status':'unverified','scope':'RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots', + 'writes_to_source_index_refs_or_Hub':False,'rows':[]} + try: + if API not in {'http://127.0.0.1:8000','http://127.0.0.1:18080','http://10.43.68.154:8000'}: + raise Refused('unrecognized-hub-endpoint') + health=get('/state/health') + result['hub_instance']={key:health.get(key) for key in ('status','instance_role','instance_label')} + if result['hub_instance']!={'status':'ok','instance_role':'primary','instance_label':'railiance01'}: + raise Refused('hub-identity-mismatch') + for owner in OWNERS: + root=Path('/home/worsch')/owner['repo'];before_index=index_stat(root) + if git(root,'rev-parse','HEAD').decode().strip()!=owner['commit']: + raise Refused('local-head-drift') + committed=git(root,'show',owner['commit']+':'+owner['path']) + local=(root/owner['path']).read_bytes() + if local!=committed:raise Refused('published-workplan-local-drift') + expected=source(committed.decode()) + if expected['source_record_id']!=owner['id'] or len(expected['tasks'])!=owner['tasks']: + raise Refused('source-task-denominator-mismatch') + snapshot=get('/repos/'+owner['repo']+'/work-record-projection/snapshot') + plans=[row for row in snapshot['workplans'] if row['id']==expected['id']] + if len(plans)!=1 or any(plans[0].get(key)!=expected[key] for key in ('id','slug','status')): + raise Refused('workplan-binding-mismatch') + projected=[row for row in snapshot['tasks'] + if row.get('workplan_id',row.get('workstream_id'))==expected['id']] + if len(projected)!=len(expected['tasks']):raise Refused('projected-task-denominator-mismatch') + byid={row['id']:row for row in projected} + if len(byid)!=len(projected):raise Refused('duplicate-projected-uuid') + observed=[] + for task in expected['tasks']: + row=byid.get(task['id'],{}) + if any(row.get(key)!=task[key] for key in ('id','record_id','status')): + raise Refused('task-id-uuid-status-mismatch') + observed.append({key:row[key] for key in ('id','record_id','status')}) + identifiers={task['record_id']:task['id'] for task in expected['tasks']} + edges={(task['id'],identifiers[dep],'starts_after') for task in expected['tasks'] for dep in task['dependencies'] if dep in identifiers} + actual=[edge for edge in snapshot['dependencies'] if edge['from_workplan_id']==expected['id']] + projected_edges={(edge.get('from_task_id'),edge.get('to_task_id'),edge['relationship_type']) for edge in actual} + if len(actual)!=len(edges) or projected_edges!=edges: + raise Refused('dependency-binding-mismatch') + # An unchanged edge retains its original forge creation commit on description-only sync. + def valid_edge_commit(edge): + if edge.get('source_commit') in (None,owner['commit']):return True + return (owner['id']=='RMGR-WP-0019' and + edge.get('from_task_id')=='4d1675b6-f49f-5b01-8d76-bbf2030d1b34' and + edge.get('to_task_id')=='36f47e21-42d0-5aef-b065-4a5dd3af0726' and + edge.get('source_owner')=='forge:repo-manager' and + edge.get('source_commit')=='70cd754996870638848616e37819790a5c4d52b3') + if any(not valid_edge_commit(edge) for edge in actual): + raise Refused('dependency-source-commit-mismatch') + for task in expected['tasks']: + for dep in task['dependencies']: + if dep in EXTERNAL: + target=get('/tasks/'+EXTERNAL[dep]) + if target.get('id')!=EXTERNAL[dep] or target.get('record_id')!=dep: + raise Refused('external-dependency-target-mismatch') + remote_readback=remote(root,owner['commit'],owner['repo']) + if index_stat(root)!=before_index or (root/owner['path']).read_bytes()!=local: + raise Refused('source-or-index-stat-changed') + result['rows'].append({'repo':owner['repo'],'published_commit':owner['commit'], + 'remote':remote_readback,'workplan':{key:plans[0][key] for key in ('id','slug','status')}, + 'source_record_id':expected['source_record_id'], + 'tasks':observed,'external_source_declarations_not_projected':[{'from_task_id':task['id'],'target_record_id':dep,'target_uuid':EXTERNAL[dep]} for task in expected['tasks'] for dep in task['dependencies'] if dep in EXTERNAL],'dependencies':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(edges)], + 'source_file_sha256':hashlib.sha256(local).hexdigest(),'source_file_unchanged':True,'dependency_scope':'internal edges verified; external source target identities checked without claiming projected external edges', + 'index_stat_unchanged':True}) + result['status']='verified' + except Exception as error: + result['reason']=error.args[0] if isinstance(error,Refused) else 'readback-unavailable' + result['verifier_sha256']=hashlib.sha256(Path(__file__).read_bytes()).hexdigest() + (HERE/'amendment-publication-readback.json').write_text(json.dumps(result,indent=2)+'\n') + print(json.dumps({'status':result['status'],'owners':len(result['rows'])})) + return 0 if result['status']=='verified' else 2 + + +if __name__=='__main__':raise SystemExit(verify()) diff --git a/docs/changes/netkingdom-target-2026-10-17/rollout-checkpoint-commit-REFUSED-r1.json b/docs/changes/netkingdom-target-2026-10-17/rollout-checkpoint-commit-REFUSED-r1.json new file mode 100644 index 00000000..17a32590 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/rollout-checkpoint-commit-REFUSED-r1.json @@ -0,0 +1,202 @@ +{ + "status": "commit-refused", + "head": "f8c7dfa2a9c7919879b62c77eb39582b3e23654e", + "exit_code": 1, + "paths": [ + ".kaizen/agents/custodian-codex/supervision.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/conditional-T07-completion-overlay.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/manifest.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/state-hub-followthrough.patch", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/validation.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/conditional-T07-completion-overlay.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/generated-copy-exact-diff.patch", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/manifest.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/state-hub-followthrough.patch", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/validation.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/REVIEW.md", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/manifest.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/state-hub-followthrough.patch", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/validation.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/REVIEW.md", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/manifest.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/state-hub-followthrough.patch", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/validation.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/PUBLICATION.md", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/REVIEW.md", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/STATE95-final-reviewed-overlay.md", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/T09-completion-overlay.patch", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/apply_reviewed_overlay.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/canonical-validation.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/integrate_source.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/local-integration-result.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/manifest.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/publication-manifest.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/publish_followthrough_source.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/run_source_commit.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-commit-result.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-publication-readback.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/state-hub-followthrough.patch", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/test_publication_helper.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/validation.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/integrate_source.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/local-integration-result.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/manifest.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/normal-sync-result.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/run_normal_sync.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/run_source_commit.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-commit-result.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-publication-readback.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/state-hub-writeback.patch", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/validation.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/manifest.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/normal-sync-result.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/publish_workplan.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/run_normal_sync.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-commit-result.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-publication-readback.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/state-hub-workplan.patch", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/validation.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/README.md", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/api-baseline-receipt.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/compare_snapshots.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/manifest.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/native_rollback_refusal_probes.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/private-published-source-payload-receipt.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/snapshot_full_row_hashes.py", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/WP18.candidate.md", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/WP18.preimage.md", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/apply_forward_correction.py", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/brief.committed-preimage.md", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/brief.forward-restore.md", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/execution-plan.json", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/execution-start.json", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-commit.json", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-publication-readback.json", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-sync.json", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction.patch", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/manifest.json", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/publication-final-manifest.json", + "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/verify_forward_publication.py", + "docs/changes/netkingdom-target-2026-10-17/cluster-publication-readback.json", + "docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-consistency.json", + "docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-projection.json", + "docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/e9bc-reviewed-manifest.json", + "docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/intermediate-review.json", + "docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-final-review.json", + "docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-reviewed-manifest.json", + "docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-test-independent-review.py", + "docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/test_independent_review.py", + "docs/changes/netkingdom-target-2026-10-17/guard-image-a25b62f-inspection.json", + "docs/changes/netkingdom-target-2026-10-17/guard-image-c103cbf-inspection.json", + "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/FINAL-PROPOSAL.md", + "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/RECOVERY.md", + "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/exact-server-dryrun.json", + "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/fresh-readonly-preflight.json", + "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/native_binding_probes.py", + "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/pending-decision.json", + "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/probe-helper-preparation-check.json", + "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/proposal-metadata.json", + "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/reuse_values_dryrun.py", + "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/watch_rollout.py", + "docs/changes/netkingdom-target-2026-10-17/inspect_guard_image.py", + "docs/changes/netkingdom-target-2026-10-17/local-cli-refresh-r1.json", + "docs/changes/netkingdom-target-2026-10-17/publish_cluster_after_receiver.py", + "docs/changes/netkingdom-target-2026-10-17/r1-rollout-owner-bindings-failure.json", + "docs/changes/netkingdom-target-2026-10-17/r1-verify_rollout_owner_bindings.py", + "docs/changes/netkingdom-target-2026-10-17/railiance-cluster-commit.json", + "docs/changes/netkingdom-target-2026-10-17/railiance-cluster-consistency.json", + "docs/changes/netkingdom-target-2026-10-17/railiance-cluster-projection.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-corrected-client.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-full-row-hashes.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-verified-client.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/approval-decision.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-corrected-client.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-full-row-hashes.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-verified-client.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/delivered-runtime.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/exact-dryrun.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/execution.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/final-runtime-check.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/final_runtime_check.py", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/fresh-preflight.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/frozen-archives-after-publication.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/helm-return.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/helm-start.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/job-observation.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/native-refusal-probes.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/ordinary-pipeline-preservation-finding.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/pipeline-failure-progress.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/pre-publication-full-row-hashes.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/progress-receipt.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/snapshot_after_publication.py", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/snapshot_current_stage.py", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/staging-cleanup.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json", + "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/watch_rollout.py", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/PUBLISH-AFTER-RECEIVING.md", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.conditional-completion.md", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.verified-completion.md", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.wait.preimage.md", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/T05-conditional-completion.patch", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/actual-cluster-allocator-preview.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/apply_registrar_source.py", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/canonical-test-confirmation.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/isolated-47-tests.txt", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/manifest.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/own-managed-application.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/own-managed-preview.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/publication-final-manifest.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/publish_registrar.py", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/r1-registrar-publication-readback.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/r1-verify_registrar_publication.py", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.pending-template.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-commit.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-publication-readback.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-sync.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/source-application.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/source-review.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/verify_registrar_publication.py", + "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/wp19-actual-projected-dependencies.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/WP19.candidate.md", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/WP19.preimage.md", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-commit.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-publication-readback.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-sync.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/manifest.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/owner-amendment.patch", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/publication-final-manifest.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/publish_amendment.py", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/r1-amendment-publication-readback.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/r1-verify_amendment_publication.py", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/verify_amendment_publication.py", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/RMGR-WP-0019.candidate.md", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/RMGR-WP-0019.preimage.md", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-commit.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-publication-readback.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-sync.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/manifest.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/owner-amendment.patch", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/publication-final-manifest.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/publish_amendment.py", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/r1-amendment-publication-readback.json", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/r1-verify_amendment_publication.py", + "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/verify_amendment_publication.py", + "docs/changes/netkingdom-target-2026-10-17/rollout-coordination-receipts.json", + "docs/changes/netkingdom-target-2026-10-17/rollout-owner-bindings.json", + "docs/changes/netkingdom-target-2026-10-17/sync_cluster_after_binding_guard.py", + "docs/changes/netkingdom-target-2026-10-17/sync_cluster_with_verified_cli.py", + "docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-consistency.json", + "docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-projection.json", + "docs/changes/netkingdom-target-2026-10-17/verified-loaded-client.json", + "docs/changes/netkingdom-target-2026-10-17/verify_cluster_publication.py", + "docs/changes/netkingdom-target-2026-10-17/verify_rollout_owner_bindings.py", + "docs/netkingdom-target-implementation.md", + "workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md", + "docs/changes/netkingdom-target-2026-10-17/rollout-publication-inputs.json" + ], + "stdout": "", + "stderr": "{\"blocked_blob_ids\": [\"14ac31e924f280aa71dc14561d2b9014b743e6d6\", \"3e5339e79feb064f9cd1fb289970cf115eb53eee\", \"465af4282960c0dfd2ce36fce5d7cb27d26f486a\", \"cca84d470ed2de1a1a24142321d81c4ef042bba1\", \"e14b161ed327caa2f87f0d4034cedb32eb5cf607\", \"fa6b647e4a550d4f626fc09605dcc6fecc4f1f0b\"], \"scanned_blobs\": 187, \"scanner_sha256\": \"88f91962aa2f93ac6ab281d553b9e125f5197bbbce38f9f2437f7299c32e5509\", \"scanner_version\": \"8.30.1\", \"scope\": \"changed-staged-blobs\", \"status\": \"blocked\"}\n", + "unrelated_work_preserved": true +} diff --git a/docs/changes/netkingdom-target-2026-10-17/rollout-coordination-receipts.json b/docs/changes/netkingdom-target-2026-10-17/rollout-coordination-receipts.json new file mode 100644 index 00000000..d9a0b9c7 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/rollout-coordination-receipts.json @@ -0,0 +1,81 @@ +{ + "schema": "custodian.owner-wait-receipts.v1", + "receipts": [ + { + "case_id": "cluster-frozen-receiver-before-registrar-r1", + "state": "satisfied", + "id": "6703f61b-9209-427b-9f08-dc910186dbc3", + "detail": { + "scenario_type": "project_driver", + "case_id": "cluster-frozen-receiver-before-registrar-r1", + "driver_repo": "prj-state-hub-retirement", + "driver_workplan_id": "SHR-WP-0001", + "beneficiary_workplan_id": "RMGR-WP-0019", + "beneficiary_task_id": "RMGR-WP-0019-T05", + "obligor_workplan_id": "STATE-WP-0095", + "obligor_task_id": "STATE-WP-0095-T06", + "flavor": "implementation", + "state": "satisfied", + "reason": "Approved receiver T06 delivered/verified and registrar T05 published; later ordinary-pipeline failure remains a separate stopped successor case.", + "indirect_beneficiaries": [ + "RCLUSTER-WP-0018", + "NK-WP-0049-T35" + ], + "next_action": "Retain original passing and failed stage receipts; no worker wake.", + "runtime_worker_injection_enabled": false, + "human_gate_never_woken": true, + "observer": "codex", + "native_acceptance": false + }, + "central_publication": true + }, + { + "case_id": "nk49-t35-rcluster18", + "state": "waiting", + "id": "a2e5ed16-0da0-4ab9-bc0a-d82bd0a393f1", + "detail": { + "scenario_type": "cross_owner_wait", + "case_id": "nk49-t35-rcluster18", + "obligor_workplan_id": "RCLUSTER-WP-0018", + "obligor_task_id": "RCLUSTER-WP-0018-T02", + "beneficiary_workplan_id": "NK-WP-0049", + "beneficiary_task_id": "NK-WP-0049-T35", + "flavor": "implementation", + "state": "waiting", + "reason": "Cluster WP18 published and verified with five tasks; T02 still requires exact independent original TLS artifact/provider/custody metadata. Publication and current-baseline maintenance proof give no TLS/native assent.", + "coordination_context": "CUST-WP-0080", + "runtime_worker_injection_enabled": false, + "human_gate_never_woken": true, + "observer": "codex", + "native_acceptance": false + }, + "central_publication": true + }, + { + "case_id": "cluster-frozen-binding-guard-successor-r1", + "state": "stopped", + "id": "dba5dec5-d000-4ca0-af31-68990a0221bb", + "detail": { + "scenario_type": "project_driver", + "case_id": "cluster-frozen-binding-guard-successor-r1", + "driver_repo": "prj-state-hub-retirement", + "driver_workplan_id": "SHR-WP-0001", + "beneficiary_workplan_id": "RMGR-WP-0019", + "beneficiary_task_id": "RMGR-WP-0019-T06", + "obligor_workplan_id": "STATE-WP-0095", + "obligor_task_id": "STATE-WP-0095-T10", + "flavor": "implementation", + "state": "stopped", + "reason": "Human gate: exact new API guard rollout and current-baseline/historical-exception disposition pending founder decision df703266-6719-4c04-ae1b-ba9afd3bca1c. Source/local installed client proof passed; API runtime not delivered.", + "next_action": "Founder review of guard-successor-review-r1/FINAL-PROPOSAL.md; no worker wake or implicit reuse of receiver revision4 approval.", + "coordination_context": "CUST-WP-0080", + "runtime_worker_injection_enabled": false, + "human_gate_never_woken": true, + "observer": "codex", + "native_acceptance": false + }, + "central_publication": true + } + ], + "new_drivers_or_worker_injection": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/rollout-owner-bindings.json b/docs/changes/netkingdom-target-2026-10-17/rollout-owner-bindings.json new file mode 100644 index 00000000..3b11cb98 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/rollout-owner-bindings.json @@ -0,0 +1,305 @@ +{ + "schema": "custodian.rollout-owner-bindings.v1", + "status": "verified", + "primary": "primary/railiance01", + "task_bindings": 26, + "rows": [ + { + "repo": "state-hub", + "workplan_id": "STATE-WP-0095", + "commit": "4c03c9d2c6a47f5c7247473f74b2e2f188b787bd", + "remote_exact": true, + "source_sha256": "163acbdf8252f37e309f4cb0b51d48706c6bd43d439fdbf7802b953b78ae35ac", + "status": "active", + "tasks": [ + { + "id": "2dd9b04f-2250-5a8a-b5bc-c8a009872858", + "record_id": "STATE-WP-0095-T08", + "status": "done", + "needs_human": false + }, + { + "id": "339b9a37-181c-5599-9a89-0393e199bd4b", + "record_id": "STATE-WP-0095-T05", + "status": "done", + "needs_human": false + }, + { + "id": "3bbb311f-194e-5862-8aed-358a580f22b4", + "record_id": "STATE-WP-0095-T04", + "status": "done", + "needs_human": false + }, + { + "id": "6a5f87bb-e63d-5e20-b9fc-c1b5cd403ff7", + "record_id": "STATE-WP-0095-T01", + "status": "done", + "needs_human": false + }, + { + "id": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4", + "record_id": "STATE-WP-0095-T06", + "status": "done", + "needs_human": false + }, + { + "id": "88585c69-d9b9-5e1f-a256-6416ff71e824", + "record_id": "STATE-WP-0095-T10", + "status": "wait", + "needs_human": true + }, + { + "id": "8be8f13b-6352-5295-9755-de6fbfb13593", + "record_id": "STATE-WP-0095-T09", + "status": "done", + "needs_human": false + }, + { + "id": "cfd1ea99-e75b-542e-a434-acefb62f3c7d", + "record_id": "STATE-WP-0095-T07", + "status": "wait", + "needs_human": false + }, + { + "id": "e8566341-cf6e-5b9c-ad80-8564d14cd52a", + "record_id": "STATE-WP-0095-T03", + "status": "done", + "needs_human": false + }, + { + "id": "ebb24194-e4cc-5130-aaa6-663f2ea2c822", + "record_id": "STATE-WP-0095-T02", + "status": "done", + "needs_human": false + } + ], + "projected_edges": [ + { + "from_task_id": "88585c69-d9b9-5e1f-a256-6416ff71e824", + "to_task_id": "8be8f13b-6352-5295-9755-de6fbfb13593", + "relationship_type": "starts_after" + }, + { + "from_task_id": "cfd1ea99-e75b-542e-a434-acefb62f3c7d", + "to_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "relationship_type": "starts_after" + }, + { + "from_task_id": "cfd1ea99-e75b-542e-a434-acefb62f3c7d", + "to_task_id": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4", + "relationship_type": "starts_after" + }, + { + "from_task_id": "cfd1ea99-e75b-542e-a434-acefb62f3c7d", + "to_task_id": "88585c69-d9b9-5e1f-a256-6416ff71e824", + "relationship_type": "starts_after" + } + ], + "unprojected_source_declarations": [ + { + "from_task_id": "3bbb311f-194e-5862-8aed-358a580f22b4", + "to_task_id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d", + "relationship_type": "starts_after" + }, + { + "from_task_id": "3bbb311f-194e-5862-8aed-358a580f22b4", + "to_task_id": "e8566341-cf6e-5b9c-ad80-8564d14cd52a", + "relationship_type": "starts_after" + }, + { + "from_task_id": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4", + "to_task_id": "339b9a37-181c-5599-9a89-0393e199bd4b", + "relationship_type": "starts_after" + }, + { + "from_task_id": "8be8f13b-6352-5295-9755-de6fbfb13593", + "to_task_id": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4", + "relationship_type": "starts_after" + }, + { + "from_task_id": "e8566341-cf6e-5b9c-ad80-8564d14cd52a", + "to_task_id": "ebb24194-e4cc-5130-aaa6-663f2ea2c822", + "relationship_type": "starts_after" + } + ] + }, + { + "repo": "repo-manager", + "workplan_id": "RMGR-WP-0019", + "commit": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "remote_exact": true, + "source_sha256": "3c28ff7809a56a2096f58986f1b3d7e6f99d365d42d0e8a97ee786ae7d067cc1", + "status": "active", + "tasks": [ + { + "id": "1ccb06c6-ad30-5847-8704-e5628ba81f35", + "record_id": "RMGR-WP-0019-T04", + "status": "done", + "needs_human": false + }, + { + "id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "record_id": "RMGR-WP-0019-T05", + "status": "done", + "needs_human": false + }, + { + "id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "record_id": "RMGR-WP-0019-T06", + "status": "wait", + "needs_human": false + }, + { + "id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d", + "record_id": "RMGR-WP-0019-T03", + "status": "done", + "needs_human": false + }, + { + "id": "95240c81-1805-5365-9b35-d238621a16bf", + "record_id": "RMGR-WP-0019-T02", + "status": "done", + "needs_human": false + }, + { + "id": "d78a622e-39f9-5923-b4e1-f70fdc17fb42", + "record_id": "RMGR-WP-0019-T01", + "status": "done", + "needs_human": false + } + ], + "projected_edges": [ + { + "from_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "to_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "relationship_type": "starts_after" + }, + { + "from_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34", + "to_task_id": "88585c69-d9b9-5e1f-a256-6416ff71e824", + "relationship_type": "starts_after" + }, + { + "from_task_id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d", + "to_task_id": "95240c81-1805-5365-9b35-d238621a16bf", + "relationship_type": "starts_after" + } + ], + "unprojected_source_declarations": [ + { + "from_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726", + "to_task_id": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4", + "relationship_type": "starts_after" + }, + { + "from_task_id": "95240c81-1805-5365-9b35-d238621a16bf", + "to_task_id": "e8566341-cf6e-5b9c-ad80-8564d14cd52a", + "relationship_type": "starts_after" + } + ] + }, + { + "repo": "repo-manager", + "workplan_id": "RMGR-WP-0021", + "commit": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd", + "remote_exact": true, + "source_sha256": "966d15ccdabc8edf98bc58f9422ea190566d05fe4208f4749f59a9731f4e108d", + "status": "active", + "tasks": [ + { + "id": "0ab44bd9-00d8-5470-ad45-7350e7868d0a", + "record_id": "RMGR-WP-0021-T03", + "status": "progress", + "needs_human": false + }, + { + "id": "25fbe694-41d8-5232-bce0-4ed362387d5a", + "record_id": "RMGR-WP-0021-T05", + "status": "done", + "needs_human": false + }, + { + "id": "44272818-db49-58a2-83b1-d2f9e9d5976c", + "record_id": "RMGR-WP-0021-T04", + "status": "todo", + "needs_human": false + }, + { + "id": "d3d20c18-5a5f-5f8a-b5c4-a22b4b662ebe", + "record_id": "RMGR-WP-0021-T01", + "status": "done", + "needs_human": false + }, + { + "id": "e27817e6-b298-581f-b99a-05ec459be749", + "record_id": "RMGR-WP-0021-T02", + "status": "done", + "needs_human": false + } + ], + "projected_edges": [], + "unprojected_source_declarations": [] + }, + { + "repo": "railiance-cluster", + "workplan_id": "RCLUSTER-WP-0018", + "commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "remote_exact": true, + "source_sha256": "96d52b6dbae056399159632d50b32ccc6662e4f6d3677af154f7c8a3d618334b", + "status": "active", + "tasks": [ + { + "id": "021b07bb-65bc-5743-bac5-4294b4be74f6", + "record_id": "RCLUSTER-WP-0018-T04", + "status": "wait", + "needs_human": true + }, + { + "id": "5bc67a22-0991-5625-86a6-f749560d8a0e", + "record_id": "RCLUSTER-WP-0018-T05", + "status": "todo", + "needs_human": false + }, + { + "id": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a", + "record_id": "RCLUSTER-WP-0018-T03", + "status": "wait", + "needs_human": false + }, + { + "id": "7280193d-0d59-5b78-a2d3-96ebd127127f", + "record_id": "RCLUSTER-WP-0018-T01", + "status": "done", + "needs_human": false + }, + { + "id": "90836435-917f-504c-a711-3f29ece348e3", + "record_id": "RCLUSTER-WP-0018-T02", + "status": "todo", + "needs_human": false + } + ], + "projected_edges": [ + { + "from_task_id": "021b07bb-65bc-5743-bac5-4294b4be74f6", + "to_task_id": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a", + "relationship_type": "starts_after" + }, + { + "from_task_id": "021b07bb-65bc-5743-bac5-4294b4be74f6", + "to_task_id": "90836435-917f-504c-a711-3f29ece348e3", + "relationship_type": "starts_after" + }, + { + "from_task_id": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a", + "to_task_id": "90836435-917f-504c-a711-3f29ece348e3", + "relationship_type": "starts_after" + } + ], + "unprojected_source_declarations": [] + } + ], + "runtime_deployed_source": "51bc70d1ff8f25450a8650d8e50caf053093a02e", + "successor_runtime_source_not_deployed": "c103cbf3c8bed5dba87a03e320595ddded9301a3", + "native_target_gates_closed": 0 +} diff --git a/docs/changes/netkingdom-target-2026-10-17/rollout-publication-inputs.json b/docs/changes/netkingdom-target-2026-10-17/rollout-publication-inputs.json new file mode 100644 index 00000000..34388916 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/rollout-publication-inputs.json @@ -0,0 +1,1107 @@ +{ + "schema": "custodian.scoped-publication-inputs.v1", + "files": [ + { + "path": ".kaizen/agents/custodian-codex/supervision.json", + "sha256": "76c5b5d771425df2ef20ef11bdd5095480218b0873e13881f01c92ffd24b2fc8", + "bytes": 78705 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/conditional-T07-completion-overlay.json", + "sha256": "400666682a421ac35e0b347b19e43adfec8336f49dd2049f36e26f4fac708ec4", + "bytes": 1370 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/manifest.json", + "sha256": "2b167a638636b3e6b30c317d4ce48256c9915940942b0b581beb9a96fcc4b55f", + "bytes": 2398 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/state-hub-followthrough.patch", + "sha256": "3a2f8446262062a9183aff6f219fd6c300ed447624355cb778bb050cdb14a2b9", + "bytes": 9506 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/validation.json", + "sha256": "65ffdd0b9c1f755d96e9eaab2742279b6e2973b5ccaff8f4e7f8d48a8bc29e7a", + "bytes": 656 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/conditional-T07-completion-overlay.json", + "sha256": "81518c241d379633b5dc21b08b976d4a46d5f4e8d89772464dad0a2ea47a16a5", + "bytes": 1370 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/generated-copy-exact-diff.patch", + "sha256": "ef5d9f2373f491a23259417b33d5784b616557e714e8e05717c5b1c982301c91", + "bytes": 618 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/manifest.json", + "sha256": "2c02dd4953e0f0beb09d5b6450ab4912921d63e5090d42701f9bef37a013129c", + "bytes": 2898 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/state-hub-followthrough.patch", + "sha256": "12ee2ab6f4cc45ff8cfcb4c03ef84a7e207eff13fdaa194a7281734f5cbc4021", + "bytes": 10949 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/validation.json", + "sha256": "acdf8d11033a63e6076692d15b9ca3927e306a698c93b61ab1e3c0c7dd81ef4b", + "bytes": 807 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/REVIEW.md", + "sha256": "5d23da6a180e5b4a941217a2cc30403261122217deaada7e0bf44a4f4b3e8cab", + "bytes": 4317 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/manifest.json", + "sha256": "95fd49db49c5881a8c3674891e6448b5725d737ba4d5e4b186b35fcc6f4ba2ad", + "bytes": 3397 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/state-hub-followthrough.patch", + "sha256": "e9bc2ba9f81b6290945b6de6e0a00ba4c995478b17da786605f5a0466e300b3d", + "bytes": 33056 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/validation.json", + "sha256": "d435174a4539ef10dcd339b2f980787f6036c685eb6b5be7321dc3b345511ba8", + "bytes": 840 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/REVIEW.md", + "sha256": "8d8d8bb6e8020cb40e571fb4d88d7f3887087c7edb33d0d6bfeb3def8ab4ab88", + "bytes": 5974 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/manifest.json", + "sha256": "2a6345e1181262eed80ce5e5cf7b3e398396b208d014fb15602874e1018d63b0", + "bytes": 3397 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/state-hub-followthrough.patch", + "sha256": "c06bc0a3e667e9ae6407f60887ba8feddc66d19a2c21dfc86d1bbe3718361708", + "bytes": 39218 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/validation.json", + "sha256": "897f28d2b2f551cb5153c4b17c09d02538d48b66f16c2789fcb52395876e81e2", + "bytes": 840 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/PUBLICATION.md", + "sha256": "b4c192cb5b4dd79ef0ccf5400e8838dd8d6dbf289959d85f8a4cf940732f6d79", + "bytes": 1768 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/REVIEW.md", + "sha256": "3ea2b5c93c0201d256fd0c3f4c802802de98b67cacaf47d67331cef3decabbcc", + "bytes": 6599 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/STATE95-final-reviewed-overlay.md", + "sha256": "a9aa50f5772ac985dcee9b1b65228e5f909ab25209f80dea9d6f0248029855ca", + "bytes": 17286 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/T09-completion-overlay.patch", + "sha256": "0cf317f0187f631bce3eea4ba65bb70792f296105d19e3185179c736cb9dcd5b", + "bytes": 1184 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/apply_reviewed_overlay.py", + "sha256": "1e527d1e5b40a701f50283e59f8f690e2f08bb488f48362ba8d9ccccd9fec9a2", + "bytes": 909 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/canonical-validation.json", + "sha256": "18af55b66d8506c94236965ec1ba4ea5537caf569895534fc9254f09be148294", + "bytes": 445 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/integrate_source.py", + "sha256": "d881c1f829d9889ffb33c58b57cc76b8151eb6de8da61de6ac0dbe936b4addd5", + "bytes": 3103 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/local-integration-result.publication.json", + "sha256": "17a2f1c96dd4e6dc4c297f168ca21b8e2ec32a263494fb5a746f60752f8cfda2", + "bytes": 299036 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/manifest.json", + "sha256": "fc8656d53309199b6789d50351221428abfd9b2311d877723f42001926785bc4", + "bytes": 3397 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/publication-manifest.json", + "sha256": "31e000a5bfa02ba28b85ef99b737ff77ed65d22361e3e5ccfa05252fed87e212", + "bytes": 4000 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/publish_followthrough_source.py", + "sha256": "32b4509479845f8d29d7a9dbb3aaef5bbf237693e9312572b55b1afedb1b2668", + "bytes": 6333 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/run_source_commit.py", + "sha256": "28a9dd0608b0687f322f54c737076105fe331b0925752d44686089d64bf17db1", + "bytes": 597 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-commit-result.publication.json", + "sha256": "672bb4b714ca1a2530cf764ffb565630db57a82d3083840ca7fc76d529b3df8e", + "bytes": 298721 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-publication-readback.json", + "sha256": "4f63ce61983fd0c1bd2c7b206980fcdf9e6f4d3dd1ae588c2a73358b44b860b2", + "bytes": 2278 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/state-hub-followthrough.patch", + "sha256": "ad3d49b83435dd026118ee1e4a25779b5a7739473619bbda256f160c4eb0e56a", + "bytes": 40931 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/test_publication_helper.py", + "sha256": "349fc7a5b79cfaf5c11092088598dbbe5659b748c73e78e33c0234a9de2e53dd", + "bytes": 3462 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/validation.json", + "sha256": "5b086b2923b566edc32607a30b70c1e76a956014d94bb0df6466de04d10d7e11", + "bytes": 841 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/integrate_source.py", + "sha256": "be1dd9c69c682b004f8de143be2146873f94eba2e919a56fe7022a9bc250841e", + "bytes": 1494 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/local-integration-result.publication.json", + "sha256": "bb211f0693194e5bd5432517257b749fa9b5a19934bcabf8841ad762a0fee870", + "bytes": 300952 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/manifest.json", + "sha256": "f935e88f6d989cf7cf1bac1df954add9b0581b7e9b9c99ee930b454cfd552607", + "bytes": 1089 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/normal-sync-result.json", + "sha256": "a2210aa71db915634dc3282477562be4ba697d98992d796b4da0c55b8ae83840", + "bytes": 6046 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/run_normal_sync.py", + "sha256": "5f57998481b05d54f289dbe6a7740599c875c1310574de3d9c7b31d250b909a4", + "bytes": 889 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/run_source_commit.py", + "sha256": "d8a968bfa0df57009c9f25c936b2a96f68c8a8343497e10fef12b81b816933e2", + "bytes": 593 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-commit-result.publication.json", + "sha256": "c9e0a943eddc63c79a09b3c63229fb12a7d922f5777590691d36cae982c53dd6", + "bytes": 301313 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-publication-readback.json", + "sha256": "74faca6274af9a144774e6e25690daebcb6575feb5a45e1ef3d8129231aa20a6", + "bytes": 2274 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/state-hub-writeback.patch", + "sha256": "a99b02b2e2f745c23e7fb33821fdd17656ad22b0e040abe4ff7124f25487b825", + "bytes": 5858 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/validation.json", + "sha256": "72a95164574fa497195f133550041967ded4c9ab07be3ee6f024732b3c729924", + "bytes": 701 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/manifest.json", + "sha256": "340ec2084bd43f918187474bd6c75c3e908c0033f50af424ac9f354b0572f987", + "bytes": 624 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/normal-sync-result.json", + "sha256": "8baff941e79d37ab9587108f5eac8f8b5357231b13a0b4e283ceec9df5c694ab", + "bytes": 6472 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/publish_workplan.py", + "sha256": "1d35c8df48bc843b8048609d14d5b943c25719766bd7d032f346edee82c1cb13", + "bytes": 1372 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/run_normal_sync.py", + "sha256": "5f57998481b05d54f289dbe6a7740599c875c1310574de3d9c7b31d250b909a4", + "bytes": 889 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-commit-result.publication.json", + "sha256": "b5408c26abf16a4a585b7a2546ab4651d3b3832f2690f3e0378bc9c98387b327", + "bytes": 301925 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-publication-readback.json", + "sha256": "acbd10e9a9f54872cf57b5d299f77494764e462346cfbcf89e3072d9a36e60c2", + "bytes": 2631 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/state-hub-workplan.patch", + "sha256": "db6856796303234221b35c4c473822b14b591946c9283e0dfd1dd86a01a478ea", + "bytes": 2235 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/validation.json", + "sha256": "40d57504120d440a71f91d561a70dbd2be09284742fb025c253143b28ebca37a", + "bytes": 249 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r8/manifest.json", + "sha256": "d97892017291dac31d72dcdc33524edac0fa068e4f76ee53d49bff4c2e848091", + "bytes": 631 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r8/normal-sync-result.json", + "sha256": "8fdebbba377ca2933822f31aaea1b76d22f65317c9ee8785bd6ac03ab3fbbeaf", + "bytes": 6046 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r8/publish_workplan.py", + "sha256": "6539c361d9fa98187086524fca1134b7c075071d6e5bd01e9f820c6081802dd6", + "bytes": 1372 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r8/run_consistency_check.py", + "sha256": "443dca179252959b6efa4c2c9be72615e7cd147288c5fa4af6d286e0c8a00848", + "bytes": 921 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r8/run_normal_sync.py", + "sha256": "5f57998481b05d54f289dbe6a7740599c875c1310574de3d9c7b31d250b909a4", + "bytes": 889 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r8/source-commit-result.publication.json", + "sha256": "eece3a06542a7f7e708cabdede1ffc35670a14b89dfb65c775b113f43f0c991e", + "bytes": 301836 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r8/state-hub-workplan.patch", + "sha256": "83bf9a6d6f7dc9de6856aca30b3d10c5e715214132ab715f15a8f0caeef9c935", + "bytes": 2001 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r8/validation.json", + "sha256": "5a74460f2d6ddfba77a0c6dc4d36338c05ac717a6ef37559a3f2dbaf475050d3", + "bytes": 110 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/README.md", + "sha256": "f432c3bcb29ee0715ef8e72d5ae806a800f07338cd9b5faea9d71c470c51d699", + "bytes": 3233 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/api-baseline-receipt.json", + "sha256": "8f6da30c33482b552392d16584f704265750f3a0263fa6ec4f20f5175b7bd852", + "bytes": 448 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/compare_snapshots.py", + "sha256": "fe38d1268a8c4bb54f0941f87a9aab5ee24410cc0197b082dbebe71bc94b0b78", + "bytes": 1089 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/manifest.json", + "sha256": "ec5cdc0a5d6d757315f21f42045462dfcfb24a916fb80938b277e76a268e602f", + "bytes": 1211 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/native_rollback_refusal_probes.py", + "sha256": "839d90fd336fe56bbd73d101b0770e8eba3d7517a3953b8afd075feccdd0b94d", + "bytes": 9600 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/private-published-source-payload-receipt.json", + "sha256": "df2c438c455578d778b00363203b69aedd46e8bcdbdb3e0bd6650de6bde14bb9", + "bytes": 445 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/snapshot_full_row_hashes.py", + "sha256": "f01e93c0fcb4ca155bdf76813626c33e4343f6a8caec2870ab1d785243c60479", + "bytes": 5912 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/WP18.candidate.md", + "sha256": "96d52b6dbae056399159632d50b32ccc6662e4f6d3677af154f7c8a3d618334b", + "bytes": 7423 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/WP18.preimage.md", + "sha256": "ec6213ddedd82a872f727ba030268d253ffbc8363e56df8b0f85c8d2168f1a49", + "bytes": 6016 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/apply_forward_correction.py", + "sha256": "02b028822e07cc1612a2e5dea3c9f271f0020f9adfb656c0aac42555b0805502", + "bytes": 4158 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/brief.committed-preimage.md", + "sha256": "973c36a552854aa801708aecf45f80d07ce2215dfc7bfa58e1ab8c9e78b2de67", + "bytes": 1164 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/brief.forward-restore.md", + "sha256": "ce9a06a6e85437781f090615d989b82cb1fa2e8c509ed0dd99b6dc28152128b5", + "bytes": 912 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/execution-plan.json", + "sha256": "c374c9299bf30b5a746955e7ab3f883d76350a4eb0823f26ff5abccab1d5e69c", + "bytes": 1323 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/execution-start.json", + "sha256": "cb40396a81a9b1fe677f9c598f0afffc4d9ed4b71ed152071611e7729ccf4698", + "bytes": 13377 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-commit.json", + "sha256": "d93f1d84b052b786332bc2238301cecf9d68f5a73d5ddc1376f25c859a765ed8", + "bytes": 925 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-publication-readback.json", + "sha256": "cd1903b634511da269d19dd6d367482933ce06a175f8392db82b5655bd1b1de0", + "bytes": 2653 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-sync.json", + "sha256": "e022e5f8b92d154babe76de39dbc799d4cb04d4349f8642ed69f8587de18cb58", + "bytes": 7691 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction.patch", + "sha256": "a50c419c4ab3a35a6f953559546c88fe0cfb75605ef63b51fe30307180262610", + "bytes": 2882 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/manifest.json", + "sha256": "9ac8f5e43f84add61ec8560be78e4d10e55bdd2918467581f367e816a4592385", + "bytes": 1476 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/publication-final-manifest.json", + "sha256": "100bb4d225185ee876a7a03957517f0ab9024709cbd71cc2f00463af26394e4b", + "bytes": 1616 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/verify_forward_publication.py", + "sha256": "ccf1776a2a8b3de5b1cc75f90ba4c10fbf8ade1b79fa4ba721be1c908be11d7d", + "bytes": 8435 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/cluster-publication-readback.json", + "sha256": "d3a6e4db0195416fdadcf94ba21b956ac74ccd23d71a5a4ce577cbe2fe1f923b", + "bytes": 2652 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-consistency.json", + "sha256": "6af07b6b1bfb1a441cc6a41714ac212436bf681c6df4e687fc71d8b35834c33e", + "bytes": 23932 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-projection.json", + "sha256": "e4710a292cb68ef1ec1d7ade55ddb51b618b05e0fee205ca33f8a3d1a53ac386", + "bytes": 7653 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/e9bc-reviewed-manifest.json", + "sha256": "95fd49db49c5881a8c3674891e6448b5725d737ba4d5e4b186b35fcc6f4ba2ad", + "bytes": 3397 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/intermediate-review.json", + "sha256": "412e3dd579a5aafb9ceb09f91e5ad4c8bff56e6fe03d1e61446084c9d7d99387", + "bytes": 843 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-final-review.json", + "sha256": "8c702ae164886d8ce0c88e7fc4cbe752415af4f3548ccf860b9e30660ec13b50", + "bytes": 1436 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-reviewed-manifest.json", + "sha256": "fc8656d53309199b6789d50351221428abfd9b2311d877723f42001926785bc4", + "bytes": 3397 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-test-independent-review.py", + "sha256": "fa2a347d8a2f0a28f9e81752de42d151138f71f5d1e83adb86f7cfe3e530486f", + "bytes": 2667 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/test_independent_review.py", + "sha256": "6896ec48f02829cbc97954c78f29284024727330af38997149e7f03b01f36abc", + "bytes": 2085 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-image-a25b62f-inspection.json", + "sha256": "4fb84d331bbfcd618afaba9c5f62fedac71c58e06216efa4546fcf88c95d6dc5", + "bytes": 52116 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-image-c103cbf-inspection.json", + "sha256": "21b4ddd3fa65743bed5eae568e0c08f2d150fcecacb7949263cef06bab99a683", + "bytes": 52116 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/FINAL-PROPOSAL.md", + "sha256": "7addca35af1973be4a2f2c1aeec658a00b581108da03e6509e645045f2767ae4", + "bytes": 4253 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/RECOVERY.md", + "sha256": "dc72dea7cdf519a712ee8f6d28fc6aa5667b44655d948f2c0160869383f33cef", + "bytes": 2320 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/SUPERSEDED.md", + "sha256": "2f69102d598fd0687fa53abb99c7c9b0c6ac6944ef4b9cfbd0a9667bdc1e0321", + "bytes": 618 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/exact-server-dryrun.json", + "sha256": "2bfb02130876aeb71a773585dae8b446ad5c671050ebc14d0fc7bcce86dffea5", + "bytes": 5916 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/fresh-readonly-preflight.json", + "sha256": "01bbdc94ebd6fb266ab21bdc0851eac6eddeafbabcd7105cce23806931ebfbce", + "bytes": 1516 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/pending-decision.json", + "sha256": "b1dbd9b700555c0081231d49ca03522bd0af1a635b6e11ecbd72ff0797b27de5", + "bytes": 1687 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/probe-helper-preparation-check.json", + "sha256": "e11f48b18cdb57e1b8f2bddcf7e6ffc7473ab2ab2b031c3c1a26afae609f831c", + "bytes": 245 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/proposal-metadata.json", + "sha256": "81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932", + "bytes": 6950 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/reuse_values_dryrun.py", + "sha256": "5e653ae8439c773b27a167464b620805055e9d820a907761ab30652e65fae200", + "bytes": 7318 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/watch_rollout.py", + "sha256": "a496da3c9a415ac800921ce755446be4bb55bc17e4e6b913143a5d6baf48f815", + "bytes": 3274 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/FINAL-PROPOSAL.md", + "sha256": "5ff105f0eb66e85f6d5c64a496e5f1ce7b816a32fb93351f4cd07133b9a053fd", + "bytes": 4607 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/RECOVERY.md", + "sha256": "dc72dea7cdf519a712ee8f6d28fc6aa5667b44655d948f2c0160869383f33cef", + "bytes": 2320 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/exact-server-dryrun.json", + "sha256": "2bfb02130876aeb71a773585dae8b446ad5c671050ebc14d0fc7bcce86dffea5", + "bytes": 5916 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/fresh-readonly-preflight.json", + "sha256": "01bbdc94ebd6fb266ab21bdc0851eac6eddeafbabcd7105cce23806931ebfbce", + "bytes": 1516 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/native_binding_probes.py", + "sha256": "ce492d0713c987e47eefc991a6312c1c63ed72056a597e9e28aee959d06e71d5", + "bytes": 5653 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/pending-decision.json", + "sha256": "9ef8f61b4b89354cb199688bd57650202bbcc4c1d300394a1bacf725727b601e", + "bytes": 1904 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/probe-helper-preparation-check.json", + "sha256": "36feaa02e17850c56685ccaf78556d12447fdeddae9c483721cd996da848f400", + "bytes": 395 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/proposal-metadata.json", + "sha256": "5d0ddebc21bcb035809cc8b57f4c2e1ba8ed09204be5b965460e178a90913f1e", + "bytes": 7193 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/reuse_values_dryrun.py", + "sha256": "5e653ae8439c773b27a167464b620805055e9d820a907761ab30652e65fae200", + "bytes": 7318 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/revision1-preimage-reconstruction.json", + "sha256": "f29610da92f367fd8a4d2d2c99ea89fd404cd89cc2c7422f6506df177fc6b418", + "bytes": 239 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/verify_revision1_helper_preimage.py", + "sha256": "d7563ed0f36cb2fb46f8d8bb219f6bd0c0c2c5e4a16f3ebbc96042972253699b", + "bytes": 1424 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/watch_rollout.py", + "sha256": "a496da3c9a415ac800921ce755446be4bb55bc17e4e6b913143a5d6baf48f815", + "bytes": 3274 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/inspect_guard_image.py", + "sha256": "9d0c9ec14206872a0686daab5619eab81d537a45cd9dcf0cf9cd0b7a4e1ed590", + "bytes": 5485 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/local-cli-refresh-r1.json", + "sha256": "e79b34b8ac1ce02c94df254b29f8d0b475bcde9b22330239acf8f28e7360c74a", + "bytes": 621 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/publish_cluster_after_receiver.py", + "sha256": "ed9e423f82a31aad1a89721b42005575d1595b136f999859b2755e670d64f90f", + "bytes": 3123 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/publish_rollout_checkpoint.py", + "sha256": "5e1b5ffe2360351b4fd976ce19118100fe99ad5115da698a9f27eec5afa21696", + "bytes": 1839 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/r1-rollout-owner-bindings-failure.json", + "sha256": "35fc72dc89679fffcd5ec86c2d872c0ea1ff0b4e50078c40028973d1dfc4514f", + "bytes": 271 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/r1-verify_rollout_owner_bindings.py", + "sha256": "a349eeb1885b34f5d4c322ac4536591e45484b96db70023ecf73d8beb5abe875", + "bytes": 3951 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/r2-rollout-owner-bindings-9eaa.json", + "sha256": "98d333cf92d8c421542c0e129ea0bae54e4e0e2c12693b0df9662fd5aeb6409f", + "bytes": 9952 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/railiance-cluster-commit.json", + "sha256": "3dd5408936b2aebaefa1f439ab23a1607873c4567827c53e1ee4c80118b35ff4", + "bytes": 8307 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/railiance-cluster-consistency.json", + "sha256": "98ca209ad956702075e995bf9ffd5078781ecb9cb899db12ba43a95821d4e977", + "bytes": 23936 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/railiance-cluster-projection.json", + "sha256": "c92d96f54fe7afcdfdf54fd666ce0f697219e9864d331ccddff41a246179115e", + "bytes": 9520 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-corrected-client.json", + "sha256": "7ff14663180f308a55f4f3092d2091717f10b054d59f0a55913fca3e3f2572ec", + "bytes": 5195 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-full-row-hashes.json", + "sha256": "2156aad18f190384838c27e792706a156a7423391408afbc6107e6c28c5872d8", + "bytes": 4939 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-verified-client.json", + "sha256": "8cd8921271cd647fe40dde0f00bc55b714313426e14091397d8fd11314c5e610", + "bytes": 5193 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/approval-decision.json", + "sha256": "b51554c004daa882f3709f67bdae7f2e939d611120383e61be04ec6969878134", + "bytes": 1519 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-corrected-client.json", + "sha256": "0b1d9ef08eac72d71bde79c8e7e70a5f24ca0573d9a12b9fd018f3b7a45cb27d", + "bytes": 5154 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-full-row-hashes.json", + "sha256": "75cdd87eef79059ff3f484ed24ca69e285899cdf8d851cc4e472653c417eb0ee", + "bytes": 5086 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-verified-client.json", + "sha256": "ee41be2d74085603abf2bfe2c91c1bb430b4ea0539a6cbf988528b18f3f5ef46", + "bytes": 5153 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/delivered-runtime.json", + "sha256": "89681066e8fe139456163ebfafa3efe77ffae8534ea167219230b0a74367f129", + "bytes": 1551 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/exact-dryrun.json", + "sha256": "73f8ff4094a929c2ec87e28487aa0bc73faa6a02d9377a9ccaad40295d1a084d", + "bytes": 5916 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/execution.json", + "sha256": "45c1f402bd5fae457eb977e9aefbe5400525dff70775f2bb8226dde69198e226", + "bytes": 560 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/final-runtime-check.json", + "sha256": "cba0560dc39402afa532424e965c0af9b8d854b51628dee86df1e32a6def5e2c", + "bytes": 749 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/final_runtime_check.py", + "sha256": "245aa566f01bc2510890f7f0ce9ea3e4530da513e3d77dac3a4d4e3aa688a06f", + "bytes": 1877 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/fresh-preflight.json", + "sha256": "30bd1a7104850b9f7506b171095d76cb6165dd9423902f3bdeb96a9aee553567", + "bytes": 2255 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/frozen-archives-after-publication.json", + "sha256": "95995c0184c707238d531d5113ae3798ef66051a507bf5a0b70af2966900b217", + "bytes": 643 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/helm-return.json", + "sha256": "61727deacf22d37da2d28cbaf04f5a3ddee0f9ff7571c77f1e85dba97963b572", + "bytes": 804 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/helm-start.json", + "sha256": "ca4ce17ad9f11cd7b0ed13dbd4ab0c610caca79c9fe281428a28dba50f10da17", + "bytes": 699 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/job-observation.json", + "sha256": "b0db49a54f040142be46f0caa76bfd3f09e4ac060fbc1e88c74c4077eeb0552c", + "bytes": 1134 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/native-refusal-probes.json", + "sha256": "673ccef965c820704dc310a1bf7832b583c30c3edfeb814528cf892555199172", + "bytes": 2029 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/ordinary-pipeline-preservation-finding.json", + "sha256": "43d4adc0ffbf61345865eebb3f8948f82a3c33a28fd0436eccd08bc93ba973c1", + "bytes": 1810 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/pipeline-failure-progress.json", + "sha256": "4acbc9f6bf0d8a72a58eabe7cebaecfc418c383f2e55dd56e598ca77c6b29957", + "bytes": 1161 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json", + "sha256": "ea08b8f5581e6fb335359427a4b24f990bc814b452d3733f7d4174bb1b6ed6df", + "bytes": 5048 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/pre-publication-full-row-hashes.json", + "sha256": "bf01a632d7185705bce44b96210f7376e7f94c65cc5b858924eb0bed19c73dfd", + "bytes": 5073 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/progress-receipt.json", + "sha256": "59b6b9a4405c9a09399756d0b640df91b2fcd62fd7fe3738754613553487831e", + "bytes": 959 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/snapshot_after_publication.py", + "sha256": "14a3098ea4aacb3bee1a02144db5e4866a7f43ff83da9e94cf8028089ccf2f99", + "bytes": 2028 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/snapshot_current_stage.py", + "sha256": "d4e8f35ad128ac1ed511c8994a76b0ad1624c47a5fe4cd7dc1e5b5694f845e51", + "bytes": 2049 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/staging-cleanup.json", + "sha256": "3f7f674da48e3e883bf16476b97ff7c8e1c83ab45276fca707bee78e7810d9b8", + "bytes": 46 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json", + "sha256": "d088c336d62c7bdde0e586b0f1b73c3aa3d4031a4debd9ac90206128728257f4", + "bytes": 2064 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/watch_rollout.py", + "sha256": "e26234b14a103c07e947857e3e8adba73ded3bb43f3a14edaba197b93a2b6744", + "bytes": 3274 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/PUBLISH-AFTER-RECEIVING.md", + "sha256": "e7119344687a46de66b38814f31b87cc5f399af4496f9c1f972609f8ea409e54", + "bytes": 4609 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.conditional-completion.md", + "sha256": "4aa0aad970d31e9e08fd38a676c289e74d293b4484b3ae0fd2f40d7b72376183", + "bytes": 11958 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.verified-completion.md", + "sha256": "eb8bda226be2ad3cb91fe771b27fe106715aa5d61e44d43f4f534f9f5ee4ad83", + "bytes": 11981 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.wait.preimage.md", + "sha256": "6378d96b70259ae81435b6ce8f97864698bdc5b6679cabbe9dc61a1fc1d09699", + "bytes": 9882 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/T05-conditional-completion.patch", + "sha256": "b88efdd3b62b056ef53b9498a5c04e699593853a96332e4c86264825a9fbe1cb", + "bytes": 2622 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/actual-cluster-allocator-preview.json", + "sha256": "78725ea97b70b26eed0b0ac8c3b72161eacd893343f6b087548540e784a0e792", + "bytes": 6663 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/apply_registrar_source.py", + "sha256": "d54988c12263d4994a9e54b6e1d1e2423c485ca6055cbf2df89e5f93e02ebe4a", + "bytes": 4388 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/canonical-test-confirmation.json", + "sha256": "242a3eb25744a41c99646e69870cf85f395aaa543a2768815e6a71cb514471da", + "bytes": 406 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/isolated-47-tests.txt", + "sha256": "da4f11fa49d639096b0010461a642db91ebb31771671a8a0f9225e4c35d14d42", + "bytes": 99 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/manifest.json", + "sha256": "6c34afe49455b5e95da3b784d8c226dd62efe35fe2f7a2e87c15bcf5f910fbcc", + "bytes": 1527 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/own-managed-application.json", + "sha256": "6d5672786575cf6e13c27619d562b03fe23d2b82fd09b345a38c4e28dcaf4593", + "bytes": 928 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/own-managed-preview.json", + "sha256": "6989fd9e70cae86d7013e596d8182622e5eff4f58c59f73613b0c0fc797ca895", + "bytes": 929 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/publication-final-manifest.json", + "sha256": "2eab1c12b369e36519bf615a97c0e97d8af6148b32eab4c25d818a3660d3834f", + "bytes": 1883 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/publish_registrar.py", + "sha256": "afed552b62d432ba5e117d0474dd0f03cd5d9192f3131c53de66824de3761ea6", + "bytes": 3889 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/r1-registrar-publication-readback.json", + "sha256": "5570f34c598cc8e15459e450dc7b8ce8dffda900217584ce1ebc383d5c1f36bf", + "bytes": 450 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/r1-verify_registrar_publication.py", + "sha256": "3603e96dd0cec3ea1634561c28eac545d35ae8e4936b5d43d0305aa76094d389", + "bytes": 8047 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.json", + "sha256": "d088c336d62c7bdde0e586b0f1b73c3aa3d4031a4debd9ac90206128728257f4", + "bytes": 2064 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.pending-template.json", + "sha256": "0ef70ae4b57045b81d2b226ecc36788b1905cd0dbac84850f906e59e2340c0e6", + "bytes": 735 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-commit.json", + "sha256": "02adaa482d7bfbe4db165f071620a36a1e5d37ed01eb44dffa01eec756a528fb", + "bytes": 3101 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-publication-readback.json", + "sha256": "26e359c17a342c1155c6d1265398f8f89b43cd3597de567cf9591d73fc05a3cf", + "bytes": 4660 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-sync.json", + "sha256": "876c27d4b1464ff024268a8b53aa77767dbeaec110bf8afadb016fc9584f97cd", + "bytes": 1383 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/source-application.json", + "sha256": "333c12f9f21ec4113cee97711a661ab02bf967a39530f8d7a2d5bc2e18503aca", + "bytes": 1456 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/source-review.json", + "sha256": "b67463db89789aeae5a347bd09b221d74df0e8da2d0466392634b505902d1244", + "bytes": 2072 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/verify_registrar_publication.py", + "sha256": "a7ea9793e5d31a1deddecf9422e57178cb8734aad9619dc1ec5c4d01cc8b53f7", + "bytes": 8397 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/wp19-actual-projected-dependencies.json", + "sha256": "6f55ab18c74825a26a525ed0e5f3324fe6b2ec202f788f0eb99978d28bfd3292", + "bytes": 1111 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/WP19.candidate.md", + "sha256": "3c28ff7809a56a2096f58986f1b3d7e6f99d365d42d0e8a97ee786ae7d067cc1", + "bytes": 16101 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/WP19.preimage.md", + "sha256": "4ff763ea24b9948d59b4bdd4f5ef3e95bee72fef3016f0b6404b5db663cb83ff", + "bytes": 13991 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-commit.json", + "sha256": "c73ee532b9018808de14c03cf42ded7eeddf4589dd5521eeae052703644a2748", + "bytes": 725 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-publication-readback.json", + "sha256": "ef1a342f12b2007480f7c3bf9039f257a238ebce921be076ce277641642e2f96", + "bytes": 5157 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-sync.json", + "sha256": "43467eb3ada96f3207ed97d3809e6b5230636280b400569660ece5813b1535ab", + "bytes": 2803 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/manifest.json", + "sha256": "5b5600ccc9611b86ef190895a39dca2bda6032caa37e664cd995a6ae36868c2f", + "bytes": 1441 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/owner-amendment.patch", + "sha256": "8527c5fa953a86dea8bc3f3bcf783084608c6850dd323f3390cfa27157f9cd2a", + "bytes": 2785 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/publication-final-manifest.json", + "sha256": "06f9d9b1b1adf4e728606a45422e61b4897b86c8f0e6fd6cb9f8d1fc47099184", + "bytes": 1866 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/publish_amendment.py", + "sha256": "d30ea83e814b32ef603056a8338125e5a5cf49765d698adfda317e8a3f8e3435", + "bytes": 1895 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/r1-amendment-publication-readback.json", + "sha256": "e4478c48af15dac3a67b8514ce68cf50c4a6502c497dcb7d29e8873c97941737", + "bytes": 450 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/r1-verify_amendment_publication.py", + "sha256": "f1c08cf2912c894de4825291fc9d56c2813dfd21436a7596781967b139cd4ec8", + "bytes": 9047 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/verify_amendment_publication.py", + "sha256": "c794ce4e1b1672982a606dce9bd364de0754dd905d63fbaf3cf6b1b2c42f4764", + "bytes": 9406 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/RMGR-WP-0019.candidate.md", + "sha256": "4ff763ea24b9948d59b4bdd4f5ef3e95bee72fef3016f0b6404b5db663cb83ff", + "bytes": 13991 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/RMGR-WP-0019.preimage.md", + "sha256": "c09c685313de13ad4a31891fd67b8a92f3d9a085c37cee92257d15b485a32cde", + "bytes": 12155 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-commit.json", + "sha256": "fe3fa69da34257ec2f66fd4d659f925c17b0f80caedbb99092b0bade3de17f73", + "bytes": 664 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-publication-readback.json", + "sha256": "8c78373a27d448ddb4dbd9374e389df040866a91d5be669ac23c09af8808f213", + "bytes": 4660 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-sync.json", + "sha256": "9bb18ad3881a3b8cb35595c7ddf92d2908a3c9e8fccde38f64546150174b1ef1", + "bytes": 2380 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/manifest.json", + "sha256": "5d1989cb40f9206d928d023370bbcbd781b835a8e32925d1ce7e21d21d04a640", + "bytes": 1307 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/owner-amendment.patch", + "sha256": "e8af90d6714b0545d8b78fcb43df42a9d9e6056a0491658b30514ab942a7f23e", + "bytes": 2311 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/publication-final-manifest.json", + "sha256": "d83958396d09c248c14f46b17f69bffe4f38474145a750fe869baedf5eee4012", + "bytes": 1449 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/publish_amendment.py", + "sha256": "8521a46b5daed3e268b0569d69b608e9cefbbd87b5454e19eb6413e421ed89e3", + "bytes": 1901 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/r1-amendment-publication-readback.json", + "sha256": "f4a1d44b4d73e4cd18e52295969d655c1519c93b39813eff1997c2dd7334700e", + "bytes": 456 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/r1-verify_amendment_publication.py", + "sha256": "d13131f6f1179d082078e7fe87fec2fabf72e8931fa6a320120623869939e1c4", + "bytes": 8397 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/verify_amendment_publication.py", + "sha256": "a2b7842c378a2fcaaecfd006d1549f6451f72e260d4b6fb8e193080fcfb7d472", + "bytes": 8988 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/rollout-checkpoint-commit-REFUSED-r1.json", + "sha256": "5a28b6d3bd31ab115a3b5847a54484a956e4ba4e6413bd06db60ca4f001b8080", + "bytes": 21522 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/rollout-coordination-receipts.json", + "sha256": "e5af7cbe292057978a7954948c7ceadd0c9f6225dcf1cabf31c15e83d372c0e1", + "bytes": 3589 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/rollout-owner-bindings.json", + "sha256": "ab8e44ee08d3aba0ca2d70041734ebcdc514527fc5c0733343bd00af003692d1", + "bytes": 9952 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/rollout-publication-scanner-block-r1.json", + "sha256": "8c023934c91a097eb73c502ef105c0afc3f7fe7c21860cd61bb1cfc383c0ed98", + "bytes": 1851 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/rollout-scanner-publication-refinement-r2.json", + "sha256": "2363f3e2b044458332608c79570a751cab03f5768900aeff9ec2d5a9b8530d6e", + "bytes": 2538 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/rollout-scanner-redacted-diagnosis-r1.json", + "sha256": "e77353b7e78db0c21198981e618704e91630e3471814e1d656a1a6e737ba31fc", + "bytes": 48127 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/rollout-typed-metadata-scan-r2.json", + "sha256": "56246560e0ce96cd3afcc010be59293d5c1cd66e6422e2970f597fb4e5b92409", + "bytes": 1821 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/sync_cluster_after_binding_guard.py", + "sha256": "96821826ffa1d2b5e34b0db1611f2d74bfbc3403d8fc0bd3b14cc27eab6079bb", + "bytes": 2737 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/sync_cluster_with_verified_cli.py", + "sha256": "1798d14e9451254689ec15935032ff88d15c26abad8fcb830949aac00b30c4ef", + "bytes": 3784 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/sync_rollout_custodian.py", + "sha256": "82c5eace12fb54463fa376e87f5daa50f2498cf55f1d1caabe07ba0b3f7e5021", + "bytes": 1790 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-consistency.json", + "sha256": "fd8a7d58d9e08b4866420ad77d01fbc7c28c0c2c9610ffbe95ddc77dddd9b1a6", + "bytes": 22953 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-projection.json", + "sha256": "c25b43575273df0e648842d447979aca1b41ade16fcdaf9f5f870024e7ca06e9", + "bytes": 7691 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/verified-loaded-client.json", + "sha256": "0745b5df92d2533714e2a87a43c73b3b685e7bab7bcf4444f7a5fbd82dd4722f", + "bytes": 183 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/verify_cluster_publication.py", + "sha256": "a0687ae6e05a6faf4efd2122c9ebd9f9a25a8cfb936741c8971295bb029abb1f", + "bytes": 8207 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/verify_rollout_close.py", + "sha256": "7b15de9333bf0c83cb310e147c567a251f76e4d8c664749b187fe39cab289817", + "bytes": 3481 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/verify_rollout_owner_bindings.py", + "sha256": "b272f38c8778a2847c59797f1b5651d7dea82bb639496d5dae05235a18883789", + "bytes": 4247 + }, + { + "path": "docs/netkingdom-target-implementation.md", + "sha256": "07f81adbb419ee4a3384d17e64ee63f8f071d7be11b47717c1261be5a2ef99a8", + "bytes": 66010 + }, + { + "path": "workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md", + "sha256": "c944478b08ef4c4736553f7428516e4aee5fd3a9db84e3b2136af92e65cddc87", + "bytes": 73442 + } + ], + "excludes": "All pre-existing staged/dirty brief, WORK-RECORDS, six assessment JSONs, unrelated untracked work and private backup directories.", + "publication_refinement": "Normal scanner false positives resolved through explicitly typed SHA metadata; original preparatory blobs retained locally and reversible source receipt companions published. Pending proposal revision2, unchanged scope." +} diff --git a/docs/changes/netkingdom-target-2026-10-17/rollout-publication-scanner-block-r1.json b/docs/changes/netkingdom-target-2026-10-17/rollout-publication-scanner-block-r1.json new file mode 100644 index 00000000..30a25b2e --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/rollout-publication-scanner-block-r1.json @@ -0,0 +1,44 @@ +{ + "status": "blocked", + "files": [ + { + "oid": "fa6b647e4a550d4f626fc09605dcc6fecc4f1f0b", + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/local-integration-result.json" + }, + { + "oid": "cca84d470ed2de1a1a24142321d81c4ef042bba1", + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-commit-result.json" + }, + { + "oid": "3e5339e79feb064f9cd1fb289970cf115eb53eee", + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/local-integration-result.json" + }, + { + "oid": "14ac31e924f280aa71dc14561d2b9014b743e6d6", + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-commit-result.json" + }, + { + "oid": "e14b161ed327caa2f87f0d4034cedb32eb5cf607", + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-commit-result.json" + }, + { + "oid": "465af4282960c0dfd2ce36fce5d7cb27d26f486a", + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/native_binding_probes.py" + } + ], + "hook_output": { + "blocked_blob_ids": [ + "14ac31e924f280aa71dc14561d2b9014b743e6d6", + "3e5339e79feb064f9cd1fb289970cf115eb53eee", + "465af4282960c0dfd2ce36fce5d7cb27d26f486a", + "cca84d470ed2de1a1a24142321d81c4ef042bba1", + "e14b161ed327caa2f87f0d4034cedb32eb5cf607", + "fa6b647e4a550d4f626fc09605dcc6fecc4f1f0b" + ], + "scanned_blobs": 187, + "scanner_sha256": "88f91962aa2f93ac6ab281d553b9e125f5197bbbce38f9f2437f7299c32e5509", + "scanner_version": "8.30.1", + "scope": "changed-staged-blobs", + "status": "blocked" + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/rollout-scanner-publication-refinement-r2.json b/docs/changes/netkingdom-target-2026-10-17/rollout-scanner-publication-refinement-r2.json new file mode 100644 index 00000000..e9a21044 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/rollout-scanner-publication-refinement-r2.json @@ -0,0 +1,28 @@ +{ + "schema": "custodian.scanner-publication-refinement.v1", + "findings_classification": "251 generic-api-key findings on source SHA256 metadata; no secret identified", + "rules_or_scanner_changed": false, + "original_receipts_retained_locally": true, + "typed_receipts": [ + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/local-integration-result.publication.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-commit-result.publication.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/local-integration-result.publication.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-commit-result.publication.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-commit-result.publication.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r8/source-commit-result.publication.json" + ], + "pending_proposal_revision": 2, + "pending_proposal_sha256": "5d0ddebc21bcb035809cc8b57f4c2e1ba8ed09204be5b965460e178a90913f1e", + "excluded_original_paths": [ + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/local-integration-result.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-commit-result.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/local-integration-result.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-commit-result.json", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-commit-result.json", + "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/native_binding_probes.py", + "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r8/source-commit-result.json" + ], + "original_proposal_revision1_sha256": "81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932", + "runtime_not_executed": true, + "additional_receipt_typed_preemptively": "WP-only R8 publication uses the same verified typed representation; no scanner finding or failure is claimed for this later original." +} diff --git a/docs/changes/netkingdom-target-2026-10-17/rollout-scanner-redacted-diagnosis-r1.json b/docs/changes/netkingdom-target-2026-10-17/rollout-scanner-redacted-diagnosis-r1.json new file mode 100644 index 00000000..11e4ed34 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/rollout-scanner-redacted-diagnosis-r1.json @@ -0,0 +1,2046 @@ +[ + { + "oid": "fa6b647e4a550d4f626fc09605dcc6fecc4f1f0b", + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/local-integration-result.json", + "findings": [ + { + "RuleID": "generic-api-key", + "StartLine": 10, + "EndLine": 10, + "StartColumn": 23, + "EndColumn": 112, + "Entropy": 3.8120425 + }, + { + "RuleID": "generic-api-key", + "StartLine": 75, + "EndLine": 75, + "StartColumn": 20, + "EndColumn": 102, + "Entropy": 3.919148 + }, + { + "RuleID": "generic-api-key", + "StartLine": 84, + "EndLine": 84, + "StartColumn": 20, + "EndColumn": 112, + "Entropy": 3.8218737 + }, + { + "RuleID": "generic-api-key", + "StartLine": 118, + "EndLine": 118, + "StartColumn": 21, + "EndColumn": 104, + "Entropy": 3.8459103 + }, + { + "RuleID": "generic-api-key", + "StartLine": 155, + "EndLine": 155, + "StartColumn": 21, + "EndColumn": 103, + "Entropy": 3.738762 + }, + { + "RuleID": "generic-api-key", + "StartLine": 167, + "EndLine": 167, + "StartColumn": 22, + "EndColumn": 109, + "Entropy": 3.8244915 + }, + { + "RuleID": "generic-api-key", + "StartLine": 237, + "EndLine": 237, + "StartColumn": 28, + "EndColumn": 117, + "Entropy": 3.7740393 + }, + { + "RuleID": "generic-api-key", + "StartLine": 304, + "EndLine": 304, + "StartColumn": 23, + "EndColumn": 104, + "Entropy": 3.861437 + }, + { + "RuleID": "generic-api-key", + "StartLine": 337, + "EndLine": 337, + "StartColumn": 41, + "EndColumn": 148, + "Entropy": 3.880892 + }, + { + "RuleID": "generic-api-key", + "StartLine": 340, + "EndLine": 340, + "StartColumn": 35, + "EndColumn": 146, + "Entropy": 3.8550875 + }, + { + "RuleID": "generic-api-key", + "StartLine": 474, + "EndLine": 474, + "StartColumn": 14, + "EndColumn": 108, + "Entropy": 3.8653224 + }, + { + "RuleID": "generic-api-key", + "StartLine": 489, + "EndLine": 489, + "StartColumn": 14, + "EndColumn": 105, + "Entropy": 3.8859339 + }, + { + "RuleID": "generic-api-key", + "StartLine": 545, + "EndLine": 545, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.8142567 + }, + { + "RuleID": "generic-api-key", + "StartLine": 560, + "EndLine": 560, + "StartColumn": 29, + "EndColumn": 129, + "Entropy": 3.7561448 + }, + { + "RuleID": "generic-api-key", + "StartLine": 567, + "EndLine": 567, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.7779245 + }, + { + "RuleID": "generic-api-key", + "StartLine": 587, + "EndLine": 587, + "StartColumn": 17, + "EndColumn": 115, + "Entropy": 3.9114883 + }, + { + "RuleID": "generic-api-key", + "StartLine": 616, + "EndLine": 616, + "StartColumn": 31, + "EndColumn": 126, + "Entropy": 3.8257587 + }, + { + "RuleID": "generic-api-key", + "StartLine": 626, + "EndLine": 626, + "StartColumn": 17, + "EndColumn": 116, + "Entropy": 3.8331656 + }, + { + "RuleID": "generic-api-key", + "StartLine": 644, + "EndLine": 644, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.7124434 + }, + { + "RuleID": "generic-api-key", + "StartLine": 645, + "EndLine": 645, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.729498 + }, + { + "RuleID": "generic-api-key", + "StartLine": 721, + "EndLine": 721, + "StartColumn": 15, + "EndColumn": 112, + "Entropy": 3.7887025 + }, + { + "RuleID": "generic-api-key", + "StartLine": 741, + "EndLine": 741, + "StartColumn": 15, + "EndColumn": 103, + "Entropy": 3.825398 + }, + { + "RuleID": "generic-api-key", + "StartLine": 742, + "EndLine": 742, + "StartColumn": 15, + "EndColumn": 108, + "Entropy": 3.8455067 + }, + { + "RuleID": "generic-api-key", + "StartLine": 743, + "EndLine": 743, + "StartColumn": 15, + "EndColumn": 104, + "Entropy": 3.934172 + }, + { + "RuleID": "generic-api-key", + "StartLine": 751, + "EndLine": 751, + "StartColumn": 15, + "EndColumn": 117, + "Entropy": 3.7820573 + }, + { + "RuleID": "generic-api-key", + "StartLine": 865, + "EndLine": 865, + "StartColumn": 23, + "EndColumn": 112, + "Entropy": 3.8120425 + }, + { + "RuleID": "generic-api-key", + "StartLine": 930, + "EndLine": 930, + "StartColumn": 20, + "EndColumn": 102, + "Entropy": 3.919148 + }, + { + "RuleID": "generic-api-key", + "StartLine": 939, + "EndLine": 939, + "StartColumn": 20, + "EndColumn": 112, + "Entropy": 3.8218737 + }, + { + "RuleID": "generic-api-key", + "StartLine": 973, + "EndLine": 973, + "StartColumn": 21, + "EndColumn": 104, + "Entropy": 3.8459103 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1010, + "EndLine": 1010, + "StartColumn": 21, + "EndColumn": 103, + "Entropy": 3.738762 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1022, + "EndLine": 1022, + "StartColumn": 22, + "EndColumn": 109, + "Entropy": 3.8244915 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1092, + "EndLine": 1092, + "StartColumn": 28, + "EndColumn": 117, + "Entropy": 3.7740393 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1159, + "EndLine": 1159, + "StartColumn": 23, + "EndColumn": 104, + "Entropy": 3.861437 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1192, + "EndLine": 1192, + "StartColumn": 41, + "EndColumn": 148, + "Entropy": 3.880892 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1195, + "EndLine": 1195, + "StartColumn": 35, + "EndColumn": 146, + "Entropy": 3.8550875 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1329, + "EndLine": 1329, + "StartColumn": 14, + "EndColumn": 108, + "Entropy": 3.8653224 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1344, + "EndLine": 1344, + "StartColumn": 14, + "EndColumn": 105, + "Entropy": 3.8859339 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1400, + "EndLine": 1400, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.8142567 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1415, + "EndLine": 1415, + "StartColumn": 29, + "EndColumn": 129, + "Entropy": 3.7561448 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1422, + "EndLine": 1422, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.7779245 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1442, + "EndLine": 1442, + "StartColumn": 17, + "EndColumn": 115, + "Entropy": 3.9114883 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1471, + "EndLine": 1471, + "StartColumn": 31, + "EndColumn": 126, + "Entropy": 3.8257587 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1481, + "EndLine": 1481, + "StartColumn": 17, + "EndColumn": 116, + "Entropy": 3.8331656 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1499, + "EndLine": 1499, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.7124434 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1500, + "EndLine": 1500, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.729498 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1576, + "EndLine": 1576, + "StartColumn": 15, + "EndColumn": 112, + "Entropy": 3.7887025 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1596, + "EndLine": 1596, + "StartColumn": 15, + "EndColumn": 103, + "Entropy": 3.825398 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1597, + "EndLine": 1597, + "StartColumn": 15, + "EndColumn": 108, + "Entropy": 3.8455067 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1598, + "EndLine": 1598, + "StartColumn": 15, + "EndColumn": 104, + "Entropy": 3.934172 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1606, + "EndLine": 1606, + "StartColumn": 15, + "EndColumn": 117, + "Entropy": 3.7820573 + } + ] + }, + { + "oid": "cca84d470ed2de1a1a24142321d81c4ef042bba1", + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-commit-result.json", + "findings": [ + { + "RuleID": "generic-api-key", + "StartLine": 22, + "EndLine": 22, + "StartColumn": 23, + "EndColumn": 112, + "Entropy": 3.8120425 + }, + { + "RuleID": "generic-api-key", + "StartLine": 87, + "EndLine": 87, + "StartColumn": 20, + "EndColumn": 102, + "Entropy": 3.919148 + }, + { + "RuleID": "generic-api-key", + "StartLine": 96, + "EndLine": 96, + "StartColumn": 20, + "EndColumn": 112, + "Entropy": 3.8218737 + }, + { + "RuleID": "generic-api-key", + "StartLine": 130, + "EndLine": 130, + "StartColumn": 21, + "EndColumn": 104, + "Entropy": 3.8459103 + }, + { + "RuleID": "generic-api-key", + "StartLine": 167, + "EndLine": 167, + "StartColumn": 21, + "EndColumn": 103, + "Entropy": 3.738762 + }, + { + "RuleID": "generic-api-key", + "StartLine": 179, + "EndLine": 179, + "StartColumn": 22, + "EndColumn": 109, + "Entropy": 3.8244915 + }, + { + "RuleID": "generic-api-key", + "StartLine": 249, + "EndLine": 249, + "StartColumn": 28, + "EndColumn": 117, + "Entropy": 3.7740393 + }, + { + "RuleID": "generic-api-key", + "StartLine": 316, + "EndLine": 316, + "StartColumn": 23, + "EndColumn": 104, + "Entropy": 3.861437 + }, + { + "RuleID": "generic-api-key", + "StartLine": 349, + "EndLine": 349, + "StartColumn": 41, + "EndColumn": 148, + "Entropy": 3.880892 + }, + { + "RuleID": "generic-api-key", + "StartLine": 352, + "EndLine": 352, + "StartColumn": 35, + "EndColumn": 146, + "Entropy": 3.8550875 + }, + { + "RuleID": "generic-api-key", + "StartLine": 486, + "EndLine": 486, + "StartColumn": 14, + "EndColumn": 108, + "Entropy": 3.8653224 + }, + { + "RuleID": "generic-api-key", + "StartLine": 501, + "EndLine": 501, + "StartColumn": 14, + "EndColumn": 105, + "Entropy": 3.8859339 + }, + { + "RuleID": "generic-api-key", + "StartLine": 557, + "EndLine": 557, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.8142567 + }, + { + "RuleID": "generic-api-key", + "StartLine": 572, + "EndLine": 572, + "StartColumn": 29, + "EndColumn": 129, + "Entropy": 3.7561448 + }, + { + "RuleID": "generic-api-key", + "StartLine": 579, + "EndLine": 579, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.7779245 + }, + { + "RuleID": "generic-api-key", + "StartLine": 599, + "EndLine": 599, + "StartColumn": 17, + "EndColumn": 115, + "Entropy": 3.9114883 + }, + { + "RuleID": "generic-api-key", + "StartLine": 628, + "EndLine": 628, + "StartColumn": 31, + "EndColumn": 126, + "Entropy": 3.8257587 + }, + { + "RuleID": "generic-api-key", + "StartLine": 638, + "EndLine": 638, + "StartColumn": 17, + "EndColumn": 116, + "Entropy": 3.8331656 + }, + { + "RuleID": "generic-api-key", + "StartLine": 656, + "EndLine": 656, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.7124434 + }, + { + "RuleID": "generic-api-key", + "StartLine": 657, + "EndLine": 657, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.729498 + }, + { + "RuleID": "generic-api-key", + "StartLine": 733, + "EndLine": 733, + "StartColumn": 15, + "EndColumn": 112, + "Entropy": 3.7887025 + }, + { + "RuleID": "generic-api-key", + "StartLine": 753, + "EndLine": 753, + "StartColumn": 15, + "EndColumn": 103, + "Entropy": 3.825398 + }, + { + "RuleID": "generic-api-key", + "StartLine": 754, + "EndLine": 754, + "StartColumn": 15, + "EndColumn": 108, + "Entropy": 3.8455067 + }, + { + "RuleID": "generic-api-key", + "StartLine": 755, + "EndLine": 755, + "StartColumn": 15, + "EndColumn": 104, + "Entropy": 3.934172 + }, + { + "RuleID": "generic-api-key", + "StartLine": 763, + "EndLine": 763, + "StartColumn": 15, + "EndColumn": 117, + "Entropy": 3.7820573 + }, + { + "RuleID": "generic-api-key", + "StartLine": 853, + "EndLine": 853, + "StartColumn": 23, + "EndColumn": 112, + "Entropy": 3.8120425 + }, + { + "RuleID": "generic-api-key", + "StartLine": 918, + "EndLine": 918, + "StartColumn": 20, + "EndColumn": 102, + "Entropy": 3.919148 + }, + { + "RuleID": "generic-api-key", + "StartLine": 927, + "EndLine": 927, + "StartColumn": 20, + "EndColumn": 112, + "Entropy": 3.8218737 + }, + { + "RuleID": "generic-api-key", + "StartLine": 961, + "EndLine": 961, + "StartColumn": 21, + "EndColumn": 104, + "Entropy": 3.8459103 + }, + { + "RuleID": "generic-api-key", + "StartLine": 998, + "EndLine": 998, + "StartColumn": 21, + "EndColumn": 103, + "Entropy": 3.738762 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1010, + "EndLine": 1010, + "StartColumn": 22, + "EndColumn": 109, + "Entropy": 3.8244915 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1080, + "EndLine": 1080, + "StartColumn": 28, + "EndColumn": 117, + "Entropy": 3.7740393 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1147, + "EndLine": 1147, + "StartColumn": 23, + "EndColumn": 104, + "Entropy": 3.861437 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1180, + "EndLine": 1180, + "StartColumn": 41, + "EndColumn": 148, + "Entropy": 3.880892 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1183, + "EndLine": 1183, + "StartColumn": 35, + "EndColumn": 146, + "Entropy": 3.8550875 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1317, + "EndLine": 1317, + "StartColumn": 14, + "EndColumn": 108, + "Entropy": 3.8653224 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1332, + "EndLine": 1332, + "StartColumn": 14, + "EndColumn": 105, + "Entropy": 3.8859339 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1388, + "EndLine": 1388, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.8142567 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1403, + "EndLine": 1403, + "StartColumn": 29, + "EndColumn": 129, + "Entropy": 3.7561448 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1410, + "EndLine": 1410, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.7779245 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1430, + "EndLine": 1430, + "StartColumn": 17, + "EndColumn": 115, + "Entropy": 3.9114883 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1459, + "EndLine": 1459, + "StartColumn": 31, + "EndColumn": 126, + "Entropy": 3.8257587 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1469, + "EndLine": 1469, + "StartColumn": 17, + "EndColumn": 116, + "Entropy": 3.8331656 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1487, + "EndLine": 1487, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.7124434 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1488, + "EndLine": 1488, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.729498 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1564, + "EndLine": 1564, + "StartColumn": 15, + "EndColumn": 112, + "Entropy": 3.7887025 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1584, + "EndLine": 1584, + "StartColumn": 15, + "EndColumn": 103, + "Entropy": 3.825398 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1585, + "EndLine": 1585, + "StartColumn": 15, + "EndColumn": 108, + "Entropy": 3.8455067 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1586, + "EndLine": 1586, + "StartColumn": 15, + "EndColumn": 104, + "Entropy": 3.934172 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1594, + "EndLine": 1594, + "StartColumn": 15, + "EndColumn": 117, + "Entropy": 3.7820573 + } + ] + }, + { + "oid": "3e5339e79feb064f9cd1fb289970cf115eb53eee", + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/local-integration-result.json", + "findings": [ + { + "RuleID": "generic-api-key", + "StartLine": 7, + "EndLine": 7, + "StartColumn": 23, + "EndColumn": 112, + "Entropy": 3.8120425 + }, + { + "RuleID": "generic-api-key", + "StartLine": 73, + "EndLine": 73, + "StartColumn": 20, + "EndColumn": 102, + "Entropy": 3.919148 + }, + { + "RuleID": "generic-api-key", + "StartLine": 82, + "EndLine": 82, + "StartColumn": 20, + "EndColumn": 112, + "Entropy": 3.8218737 + }, + { + "RuleID": "generic-api-key", + "StartLine": 116, + "EndLine": 116, + "StartColumn": 21, + "EndColumn": 104, + "Entropy": 3.8459103 + }, + { + "RuleID": "generic-api-key", + "StartLine": 154, + "EndLine": 154, + "StartColumn": 21, + "EndColumn": 103, + "Entropy": 3.738762 + }, + { + "RuleID": "generic-api-key", + "StartLine": 166, + "EndLine": 166, + "StartColumn": 22, + "EndColumn": 109, + "Entropy": 3.8244915 + }, + { + "RuleID": "generic-api-key", + "StartLine": 237, + "EndLine": 237, + "StartColumn": 28, + "EndColumn": 117, + "Entropy": 3.7740393 + }, + { + "RuleID": "generic-api-key", + "StartLine": 304, + "EndLine": 304, + "StartColumn": 23, + "EndColumn": 104, + "Entropy": 3.861437 + }, + { + "RuleID": "generic-api-key", + "StartLine": 340, + "EndLine": 340, + "StartColumn": 41, + "EndColumn": 148, + "Entropy": 3.880892 + }, + { + "RuleID": "generic-api-key", + "StartLine": 343, + "EndLine": 343, + "StartColumn": 35, + "EndColumn": 146, + "Entropy": 3.8550875 + }, + { + "RuleID": "generic-api-key", + "StartLine": 478, + "EndLine": 478, + "StartColumn": 14, + "EndColumn": 108, + "Entropy": 3.8653224 + }, + { + "RuleID": "generic-api-key", + "StartLine": 493, + "EndLine": 493, + "StartColumn": 14, + "EndColumn": 105, + "Entropy": 3.8859339 + }, + { + "RuleID": "generic-api-key", + "StartLine": 549, + "EndLine": 549, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.8142567 + }, + { + "RuleID": "generic-api-key", + "StartLine": 564, + "EndLine": 564, + "StartColumn": 29, + "EndColumn": 129, + "Entropy": 3.7561448 + }, + { + "RuleID": "generic-api-key", + "StartLine": 571, + "EndLine": 571, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.7779245 + }, + { + "RuleID": "generic-api-key", + "StartLine": 591, + "EndLine": 591, + "StartColumn": 17, + "EndColumn": 115, + "Entropy": 3.9114883 + }, + { + "RuleID": "generic-api-key", + "StartLine": 620, + "EndLine": 620, + "StartColumn": 31, + "EndColumn": 126, + "Entropy": 3.8257587 + }, + { + "RuleID": "generic-api-key", + "StartLine": 630, + "EndLine": 630, + "StartColumn": 17, + "EndColumn": 116, + "Entropy": 3.8331656 + }, + { + "RuleID": "generic-api-key", + "StartLine": 648, + "EndLine": 648, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.7124434 + }, + { + "RuleID": "generic-api-key", + "StartLine": 649, + "EndLine": 649, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.729498 + }, + { + "RuleID": "generic-api-key", + "StartLine": 726, + "EndLine": 726, + "StartColumn": 15, + "EndColumn": 112, + "Entropy": 3.7887025 + }, + { + "RuleID": "generic-api-key", + "StartLine": 746, + "EndLine": 746, + "StartColumn": 15, + "EndColumn": 103, + "Entropy": 3.825398 + }, + { + "RuleID": "generic-api-key", + "StartLine": 747, + "EndLine": 747, + "StartColumn": 15, + "EndColumn": 108, + "Entropy": 3.8455067 + }, + { + "RuleID": "generic-api-key", + "StartLine": 748, + "EndLine": 748, + "StartColumn": 15, + "EndColumn": 104, + "Entropy": 3.934172 + }, + { + "RuleID": "generic-api-key", + "StartLine": 756, + "EndLine": 756, + "StartColumn": 15, + "EndColumn": 117, + "Entropy": 3.7820573 + }, + { + "RuleID": "generic-api-key", + "StartLine": 843, + "EndLine": 843, + "StartColumn": 23, + "EndColumn": 112, + "Entropy": 3.8120425 + }, + { + "RuleID": "generic-api-key", + "StartLine": 909, + "EndLine": 909, + "StartColumn": 20, + "EndColumn": 102, + "Entropy": 3.919148 + }, + { + "RuleID": "generic-api-key", + "StartLine": 918, + "EndLine": 918, + "StartColumn": 20, + "EndColumn": 112, + "Entropy": 3.8218737 + }, + { + "RuleID": "generic-api-key", + "StartLine": 952, + "EndLine": 952, + "StartColumn": 21, + "EndColumn": 104, + "Entropy": 3.8459103 + }, + { + "RuleID": "generic-api-key", + "StartLine": 990, + "EndLine": 990, + "StartColumn": 21, + "EndColumn": 103, + "Entropy": 3.738762 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1002, + "EndLine": 1002, + "StartColumn": 22, + "EndColumn": 109, + "Entropy": 3.8244915 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1073, + "EndLine": 1073, + "StartColumn": 28, + "EndColumn": 117, + "Entropy": 3.7740393 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1140, + "EndLine": 1140, + "StartColumn": 23, + "EndColumn": 104, + "Entropy": 3.861437 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1176, + "EndLine": 1176, + "StartColumn": 41, + "EndColumn": 148, + "Entropy": 3.880892 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1179, + "EndLine": 1179, + "StartColumn": 35, + "EndColumn": 146, + "Entropy": 3.8550875 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1314, + "EndLine": 1314, + "StartColumn": 14, + "EndColumn": 108, + "Entropy": 3.8653224 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1329, + "EndLine": 1329, + "StartColumn": 14, + "EndColumn": 105, + "Entropy": 3.8859339 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1385, + "EndLine": 1385, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.8142567 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1400, + "EndLine": 1400, + "StartColumn": 29, + "EndColumn": 129, + "Entropy": 3.7561448 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1407, + "EndLine": 1407, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.7779245 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1427, + "EndLine": 1427, + "StartColumn": 17, + "EndColumn": 115, + "Entropy": 3.9114883 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1456, + "EndLine": 1456, + "StartColumn": 31, + "EndColumn": 126, + "Entropy": 3.8257587 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1466, + "EndLine": 1466, + "StartColumn": 17, + "EndColumn": 116, + "Entropy": 3.8331656 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1484, + "EndLine": 1484, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.7124434 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1485, + "EndLine": 1485, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.729498 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1562, + "EndLine": 1562, + "StartColumn": 15, + "EndColumn": 112, + "Entropy": 3.7887025 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1582, + "EndLine": 1582, + "StartColumn": 15, + "EndColumn": 103, + "Entropy": 3.825398 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1583, + "EndLine": 1583, + "StartColumn": 15, + "EndColumn": 108, + "Entropy": 3.8455067 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1584, + "EndLine": 1584, + "StartColumn": 15, + "EndColumn": 104, + "Entropy": 3.934172 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1592, + "EndLine": 1592, + "StartColumn": 15, + "EndColumn": 117, + "Entropy": 3.7820573 + } + ] + }, + { + "oid": "14ac31e924f280aa71dc14561d2b9014b743e6d6", + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-commit-result.json", + "findings": [ + { + "RuleID": "generic-api-key", + "StartLine": 15, + "EndLine": 15, + "StartColumn": 23, + "EndColumn": 112, + "Entropy": 3.8120425 + }, + { + "RuleID": "generic-api-key", + "StartLine": 81, + "EndLine": 81, + "StartColumn": 20, + "EndColumn": 102, + "Entropy": 3.919148 + }, + { + "RuleID": "generic-api-key", + "StartLine": 90, + "EndLine": 90, + "StartColumn": 20, + "EndColumn": 112, + "Entropy": 3.8218737 + }, + { + "RuleID": "generic-api-key", + "StartLine": 124, + "EndLine": 124, + "StartColumn": 21, + "EndColumn": 104, + "Entropy": 3.8459103 + }, + { + "RuleID": "generic-api-key", + "StartLine": 162, + "EndLine": 162, + "StartColumn": 21, + "EndColumn": 103, + "Entropy": 3.738762 + }, + { + "RuleID": "generic-api-key", + "StartLine": 174, + "EndLine": 174, + "StartColumn": 22, + "EndColumn": 109, + "Entropy": 3.8244915 + }, + { + "RuleID": "generic-api-key", + "StartLine": 245, + "EndLine": 245, + "StartColumn": 28, + "EndColumn": 117, + "Entropy": 3.7740393 + }, + { + "RuleID": "generic-api-key", + "StartLine": 312, + "EndLine": 312, + "StartColumn": 23, + "EndColumn": 104, + "Entropy": 3.861437 + }, + { + "RuleID": "generic-api-key", + "StartLine": 348, + "EndLine": 348, + "StartColumn": 41, + "EndColumn": 148, + "Entropy": 3.880892 + }, + { + "RuleID": "generic-api-key", + "StartLine": 351, + "EndLine": 351, + "StartColumn": 35, + "EndColumn": 146, + "Entropy": 3.8550875 + }, + { + "RuleID": "generic-api-key", + "StartLine": 486, + "EndLine": 486, + "StartColumn": 14, + "EndColumn": 108, + "Entropy": 3.8653224 + }, + { + "RuleID": "generic-api-key", + "StartLine": 501, + "EndLine": 501, + "StartColumn": 14, + "EndColumn": 105, + "Entropy": 3.8859339 + }, + { + "RuleID": "generic-api-key", + "StartLine": 557, + "EndLine": 557, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.8142567 + }, + { + "RuleID": "generic-api-key", + "StartLine": 572, + "EndLine": 572, + "StartColumn": 29, + "EndColumn": 129, + "Entropy": 3.7561448 + }, + { + "RuleID": "generic-api-key", + "StartLine": 579, + "EndLine": 579, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.7779245 + }, + { + "RuleID": "generic-api-key", + "StartLine": 599, + "EndLine": 599, + "StartColumn": 17, + "EndColumn": 115, + "Entropy": 3.9114883 + }, + { + "RuleID": "generic-api-key", + "StartLine": 628, + "EndLine": 628, + "StartColumn": 31, + "EndColumn": 126, + "Entropy": 3.8257587 + }, + { + "RuleID": "generic-api-key", + "StartLine": 638, + "EndLine": 638, + "StartColumn": 17, + "EndColumn": 116, + "Entropy": 3.8331656 + }, + { + "RuleID": "generic-api-key", + "StartLine": 656, + "EndLine": 656, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.7124434 + }, + { + "RuleID": "generic-api-key", + "StartLine": 657, + "EndLine": 657, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.729498 + }, + { + "RuleID": "generic-api-key", + "StartLine": 734, + "EndLine": 734, + "StartColumn": 15, + "EndColumn": 112, + "Entropy": 3.7887025 + }, + { + "RuleID": "generic-api-key", + "StartLine": 754, + "EndLine": 754, + "StartColumn": 15, + "EndColumn": 103, + "Entropy": 3.825398 + }, + { + "RuleID": "generic-api-key", + "StartLine": 755, + "EndLine": 755, + "StartColumn": 15, + "EndColumn": 108, + "Entropy": 3.8455067 + }, + { + "RuleID": "generic-api-key", + "StartLine": 756, + "EndLine": 756, + "StartColumn": 15, + "EndColumn": 104, + "Entropy": 3.934172 + }, + { + "RuleID": "generic-api-key", + "StartLine": 764, + "EndLine": 764, + "StartColumn": 15, + "EndColumn": 117, + "Entropy": 3.7820573 + }, + { + "RuleID": "generic-api-key", + "StartLine": 854, + "EndLine": 854, + "StartColumn": 23, + "EndColumn": 112, + "Entropy": 3.8120425 + }, + { + "RuleID": "generic-api-key", + "StartLine": 920, + "EndLine": 920, + "StartColumn": 20, + "EndColumn": 102, + "Entropy": 3.919148 + }, + { + "RuleID": "generic-api-key", + "StartLine": 929, + "EndLine": 929, + "StartColumn": 20, + "EndColumn": 112, + "Entropy": 3.8218737 + }, + { + "RuleID": "generic-api-key", + "StartLine": 963, + "EndLine": 963, + "StartColumn": 21, + "EndColumn": 104, + "Entropy": 3.8459103 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1001, + "EndLine": 1001, + "StartColumn": 21, + "EndColumn": 103, + "Entropy": 3.738762 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1013, + "EndLine": 1013, + "StartColumn": 22, + "EndColumn": 109, + "Entropy": 3.8244915 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1084, + "EndLine": 1084, + "StartColumn": 28, + "EndColumn": 117, + "Entropy": 3.7740393 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1151, + "EndLine": 1151, + "StartColumn": 23, + "EndColumn": 104, + "Entropy": 3.861437 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1187, + "EndLine": 1187, + "StartColumn": 41, + "EndColumn": 148, + "Entropy": 3.880892 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1190, + "EndLine": 1190, + "StartColumn": 35, + "EndColumn": 146, + "Entropy": 3.8550875 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1325, + "EndLine": 1325, + "StartColumn": 14, + "EndColumn": 108, + "Entropy": 3.8653224 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1340, + "EndLine": 1340, + "StartColumn": 14, + "EndColumn": 105, + "Entropy": 3.8859339 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1396, + "EndLine": 1396, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.8142567 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1411, + "EndLine": 1411, + "StartColumn": 29, + "EndColumn": 129, + "Entropy": 3.7561448 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1418, + "EndLine": 1418, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.7779245 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1438, + "EndLine": 1438, + "StartColumn": 17, + "EndColumn": 115, + "Entropy": 3.9114883 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1467, + "EndLine": 1467, + "StartColumn": 31, + "EndColumn": 126, + "Entropy": 3.8257587 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1477, + "EndLine": 1477, + "StartColumn": 17, + "EndColumn": 116, + "Entropy": 3.8331656 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1495, + "EndLine": 1495, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.7124434 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1496, + "EndLine": 1496, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.729498 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1573, + "EndLine": 1573, + "StartColumn": 15, + "EndColumn": 112, + "Entropy": 3.7887025 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1593, + "EndLine": 1593, + "StartColumn": 15, + "EndColumn": 103, + "Entropy": 3.825398 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1594, + "EndLine": 1594, + "StartColumn": 15, + "EndColumn": 108, + "Entropy": 3.8455067 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1595, + "EndLine": 1595, + "StartColumn": 15, + "EndColumn": 104, + "Entropy": 3.934172 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1603, + "EndLine": 1603, + "StartColumn": 15, + "EndColumn": 117, + "Entropy": 3.7820573 + } + ] + }, + { + "oid": "e14b161ed327caa2f87f0d4034cedb32eb5cf607", + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-commit-result.json", + "findings": [ + { + "RuleID": "generic-api-key", + "StartLine": 13, + "EndLine": 13, + "StartColumn": 23, + "EndColumn": 112, + "Entropy": 3.8120425 + }, + { + "RuleID": "generic-api-key", + "StartLine": 79, + "EndLine": 79, + "StartColumn": 20, + "EndColumn": 102, + "Entropy": 3.919148 + }, + { + "RuleID": "generic-api-key", + "StartLine": 88, + "EndLine": 88, + "StartColumn": 20, + "EndColumn": 112, + "Entropy": 3.8218737 + }, + { + "RuleID": "generic-api-key", + "StartLine": 122, + "EndLine": 122, + "StartColumn": 21, + "EndColumn": 104, + "Entropy": 3.8459103 + }, + { + "RuleID": "generic-api-key", + "StartLine": 160, + "EndLine": 160, + "StartColumn": 21, + "EndColumn": 103, + "Entropy": 3.738762 + }, + { + "RuleID": "generic-api-key", + "StartLine": 172, + "EndLine": 172, + "StartColumn": 22, + "EndColumn": 109, + "Entropy": 3.8244915 + }, + { + "RuleID": "generic-api-key", + "StartLine": 243, + "EndLine": 243, + "StartColumn": 28, + "EndColumn": 117, + "Entropy": 3.7740393 + }, + { + "RuleID": "generic-api-key", + "StartLine": 310, + "EndLine": 310, + "StartColumn": 23, + "EndColumn": 104, + "Entropy": 3.861437 + }, + { + "RuleID": "generic-api-key", + "StartLine": 346, + "EndLine": 346, + "StartColumn": 41, + "EndColumn": 148, + "Entropy": 3.880892 + }, + { + "RuleID": "generic-api-key", + "StartLine": 349, + "EndLine": 349, + "StartColumn": 35, + "EndColumn": 146, + "Entropy": 3.8550875 + }, + { + "RuleID": "generic-api-key", + "StartLine": 484, + "EndLine": 484, + "StartColumn": 14, + "EndColumn": 108, + "Entropy": 3.8653224 + }, + { + "RuleID": "generic-api-key", + "StartLine": 499, + "EndLine": 499, + "StartColumn": 14, + "EndColumn": 105, + "Entropy": 3.8859339 + }, + { + "RuleID": "generic-api-key", + "StartLine": 555, + "EndLine": 555, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.8142567 + }, + { + "RuleID": "generic-api-key", + "StartLine": 570, + "EndLine": 570, + "StartColumn": 29, + "EndColumn": 129, + "Entropy": 3.7561448 + }, + { + "RuleID": "generic-api-key", + "StartLine": 577, + "EndLine": 577, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.7779245 + }, + { + "RuleID": "generic-api-key", + "StartLine": 597, + "EndLine": 597, + "StartColumn": 17, + "EndColumn": 115, + "Entropy": 3.9114883 + }, + { + "RuleID": "generic-api-key", + "StartLine": 627, + "EndLine": 627, + "StartColumn": 31, + "EndColumn": 126, + "Entropy": 3.8257587 + }, + { + "RuleID": "generic-api-key", + "StartLine": 637, + "EndLine": 637, + "StartColumn": 17, + "EndColumn": 116, + "Entropy": 3.8331656 + }, + { + "RuleID": "generic-api-key", + "StartLine": 655, + "EndLine": 655, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.7124434 + }, + { + "RuleID": "generic-api-key", + "StartLine": 656, + "EndLine": 656, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.729498 + }, + { + "RuleID": "generic-api-key", + "StartLine": 733, + "EndLine": 733, + "StartColumn": 15, + "EndColumn": 112, + "Entropy": 3.7887025 + }, + { + "RuleID": "generic-api-key", + "StartLine": 753, + "EndLine": 753, + "StartColumn": 15, + "EndColumn": 103, + "Entropy": 3.825398 + }, + { + "RuleID": "generic-api-key", + "StartLine": 754, + "EndLine": 754, + "StartColumn": 15, + "EndColumn": 108, + "Entropy": 3.8455067 + }, + { + "RuleID": "generic-api-key", + "StartLine": 755, + "EndLine": 755, + "StartColumn": 15, + "EndColumn": 104, + "Entropy": 3.934172 + }, + { + "RuleID": "generic-api-key", + "StartLine": 763, + "EndLine": 763, + "StartColumn": 15, + "EndColumn": 117, + "Entropy": 3.7820573 + }, + { + "RuleID": "generic-api-key", + "StartLine": 854, + "EndLine": 854, + "StartColumn": 23, + "EndColumn": 112, + "Entropy": 3.8120425 + }, + { + "RuleID": "generic-api-key", + "StartLine": 920, + "EndLine": 920, + "StartColumn": 20, + "EndColumn": 102, + "Entropy": 3.919148 + }, + { + "RuleID": "generic-api-key", + "StartLine": 929, + "EndLine": 929, + "StartColumn": 20, + "EndColumn": 112, + "Entropy": 3.8218737 + }, + { + "RuleID": "generic-api-key", + "StartLine": 963, + "EndLine": 963, + "StartColumn": 21, + "EndColumn": 104, + "Entropy": 3.8459103 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1001, + "EndLine": 1001, + "StartColumn": 21, + "EndColumn": 103, + "Entropy": 3.738762 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1013, + "EndLine": 1013, + "StartColumn": 22, + "EndColumn": 109, + "Entropy": 3.8244915 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1084, + "EndLine": 1084, + "StartColumn": 28, + "EndColumn": 117, + "Entropy": 3.7740393 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1151, + "EndLine": 1151, + "StartColumn": 23, + "EndColumn": 104, + "Entropy": 3.861437 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1187, + "EndLine": 1187, + "StartColumn": 41, + "EndColumn": 148, + "Entropy": 3.880892 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1190, + "EndLine": 1190, + "StartColumn": 35, + "EndColumn": 146, + "Entropy": 3.8550875 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1325, + "EndLine": 1325, + "StartColumn": 14, + "EndColumn": 108, + "Entropy": 3.8653224 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1340, + "EndLine": 1340, + "StartColumn": 14, + "EndColumn": 105, + "Entropy": 3.8859339 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1396, + "EndLine": 1396, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.8142567 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1411, + "EndLine": 1411, + "StartColumn": 29, + "EndColumn": 129, + "Entropy": 3.7561448 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1418, + "EndLine": 1418, + "StartColumn": 29, + "EndColumn": 135, + "Entropy": 3.7779245 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1438, + "EndLine": 1438, + "StartColumn": 17, + "EndColumn": 115, + "Entropy": 3.9114883 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1468, + "EndLine": 1468, + "StartColumn": 31, + "EndColumn": 126, + "Entropy": 3.8257587 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1478, + "EndLine": 1478, + "StartColumn": 17, + "EndColumn": 116, + "Entropy": 3.8331656 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1496, + "EndLine": 1496, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.7124434 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1497, + "EndLine": 1497, + "StartColumn": 17, + "EndColumn": 103, + "Entropy": 3.729498 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1574, + "EndLine": 1574, + "StartColumn": 15, + "EndColumn": 112, + "Entropy": 3.7887025 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1594, + "EndLine": 1594, + "StartColumn": 15, + "EndColumn": 103, + "Entropy": 3.825398 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1595, + "EndLine": 1595, + "StartColumn": 15, + "EndColumn": 108, + "Entropy": 3.8455067 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1596, + "EndLine": 1596, + "StartColumn": 15, + "EndColumn": 104, + "Entropy": 3.934172 + }, + { + "RuleID": "generic-api-key", + "StartLine": 1604, + "EndLine": 1604, + "StartColumn": 15, + "EndColumn": 117, + "Entropy": 3.7820573 + } + ] + }, + { + "oid": "465af4282960c0dfd2ce36fce5d7cb27d26f486a", + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/native_binding_probes.py", + "findings": [ + { + "RuleID": "generic-api-key", + "StartLine": 5, + "EndLine": 5, + "StartColumn": 117, + "EndColumn": 207, + "Entropy": 3.871672 + } + ] + } +] diff --git a/docs/changes/netkingdom-target-2026-10-17/rollout-typed-metadata-scan-r2.json b/docs/changes/netkingdom-target-2026-10-17/rollout-typed-metadata-scan-r2.json new file mode 100644 index 00000000..bc7ea5ba --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/rollout-typed-metadata-scan-r2.json @@ -0,0 +1,41 @@ +{ + "scanner_unchanged": true, + "results": [ + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/local-integration-result.publication.json", + "sha256": "17a2f1c96dd4e6dc4c297f168ca21b8e2ec32a263494fb5a746f60752f8cfda2", + "scanner_exit_code": 0, + "findings": 0 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-commit-result.publication.json", + "sha256": "672bb4b714ca1a2530cf764ffb565630db57a82d3083840ca7fc76d529b3df8e", + "scanner_exit_code": 0, + "findings": 0 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/local-integration-result.publication.json", + "sha256": "bb211f0693194e5bd5432517257b749fa9b5a19934bcabf8841ad762a0fee870", + "scanner_exit_code": 0, + "findings": 0 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-commit-result.publication.json", + "sha256": "c9e0a943eddc63c79a09b3c63229fb12a7d922f5777590691d36cae982c53dd6", + "scanner_exit_code": 0, + "findings": 0 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-commit-result.publication.json", + "sha256": "b5408c26abf16a4a585b7a2546ab4651d3b3832f2690f3e0378bc9c98387b327", + "scanner_exit_code": 0, + "findings": 0 + }, + { + "path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/native_binding_probes.py", + "sha256": "ce492d0713c987e47eefc991a6312c1c63ed72056a597e9e28aee959d06e71d5", + "scanner_exit_code": 0, + "findings": 0 + } + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/sync_cluster_after_binding_guard.py b/docs/changes/netkingdom-target-2026-10-17/sync_cluster_after_binding_guard.py new file mode 100644 index 00000000..30a87051 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/sync_cluster_after_binding_guard.py @@ -0,0 +1,31 @@ +"""Run authorized normal Cluster maintenance with exact client source and retained baseline.""" +from pathlib import Path +import hashlib,json,subprocess +here=Path(__file__).resolve().parent;root=Path('/home/worsch/railiance-cluster') +packet=here.parent/'netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5' +manifest=json.loads((packet/'manifest.json').read_text()) +for name in ['scripts/consistency_check.py','api/services/historical_projection.py']: + pin=next(x['candidate_sha256'] for x in manifest['files'] if x['path']==name) + assert hashlib.sha256((Path('/home/worsch/state-hub')/name).read_bytes()).hexdigest()==pin,'fixed-client-source-drift' +assert json.loads((here/'receiver-rollout-r4/before-corrected-client.json').read_text())['stage']=='before-corrected-client' +backup=here/'railiance-cluster-publication-backup';originals=json.loads((backup/'originals.json').read_text()) +def git(*a):return subprocess.check_output(['git','-C',str(root),*a],stderr=subprocess.PIPE) +for name,index in originals.items(): + assert (root/name).read_bytes()==(backup/(name+'.worktree')).read_bytes() + assert git('ls-files','--stage','--',name).decode()==index +try: + for label,argv,limit in [('corrected-client-cluster-consistency',['statehub','fix-consistency','--repo','railiance-cluster','--json'],300),('corrected-client-cluster-projection',['/home/worsch/repo-manager/.venv/bin/rmgr','sync','--path',str(root),'--push'],180)]: + r=subprocess.run(argv,cwd=root,capture_output=True,text=True,timeout=limit) + (here/(label+'.json')).write_text(r.stdout);(here/(label+'.stderr.txt')).write_text(r.stderr) + assert r.returncode==0,label+'-refused-receipt-retained' +finally: + for name,index in originals.items(): + (root/name).write_bytes((backup/(name+'.worktree')).read_bytes()) + mode,oid,stage,path=index.split();assert stage=='0';git('update-index','--cacheinfo',mode,oid,path) + assert git('ls-files','--stage','--',name).decode()==index +c=json.loads((here/'corrected-client-cluster-consistency.json').read_text());assert c['summary']['fail']==c['summary']['automation_error']==0 +p=json.loads((here/'corrected-client-cluster-projection.json').read_text());assert p['status']=='applied' +assert p['commit']==p['receipt']['expected_commit']==p['receipt']['derived_commit']=='c562d7134c38679952a8ffd17a8a893a900aef0d' +assert p['receipt']['instance_role']=='primary' and p['receipt']['instance_label']=='railiance01' +assert not p['receipt']['outcome']['refused'] and not p['receipt']['outcome']['retired'] +print(json.dumps({'status':'applied','commit':p['commit'],'fixed_client_source_verified':True,'current_hash_comparison':'pending','original_failed_comparison_retained':True,'unrelated_work_preserved':True})) diff --git a/docs/changes/netkingdom-target-2026-10-17/sync_cluster_with_verified_cli.py b/docs/changes/netkingdom-target-2026-10-17/sync_cluster_with_verified_cli.py new file mode 100644 index 00000000..8628f804 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/sync_cluster_with_verified_cli.py @@ -0,0 +1,40 @@ +"""Run authorized normal Cluster maintenance with exact client source and retained baseline.""" +from pathlib import Path +import hashlib,json,subprocess +here=Path(__file__).resolve().parent;root=Path('/home/worsch/railiance-cluster') +packet=here.parent/'netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6' +manifest=json.loads((packet/'manifest.json').read_text()) +for name in ['scripts/consistency_check.py']: + pin=next(x['candidate_sha256'] for x in manifest['files'] if x['path']==name) + assert hashlib.sha256((Path('/home/worsch/state-hub')/name).read_bytes()).hexdigest()==pin,'fixed-client-source-drift' +assert json.loads((here/'receiver-rollout-r4/before-verified-client.json').read_text())['stage']=='before-verified-client' +# Verify the installed entrypoint's actual packaged checker, not just checkout bytes. +probe=subprocess.run(['/home/worsch/state-hub/.venv/bin/python','-c',"import custodian_cli,hashlib,json; p=custodian_cli.STATE_HUB_DIR/'scripts/consistency_check.py'; print(json.dumps({'path':str(p),'sha256':hashlib.sha256(p.read_bytes()).hexdigest()}))"],cwd=root,capture_output=True,text=True,timeout=10) +assert probe.returncode==0;loaded=json.loads(probe.stdout);assert loaded['sha256']==next(x['candidate_sha256'] for x in manifest['files'] if x['path']=='scripts/consistency_check.py') +(here/'verified-loaded-client.json').write_text(json.dumps(loaded,indent=2)+'\n') +baseline_head=subprocess.check_output(['git','-C',str(root),'rev-parse','HEAD'],text=True).strip();assert baseline_head=='6ae3f847c83da3402883453ee7110457bfb2d0d6' +backup=here/'railiance-cluster-publication-backup';originals=json.loads((backup/'originals.json').read_text()) +def git(*a):return subprocess.check_output(['git','-C',str(root),*a],stderr=subprocess.PIPE) +for name,index in originals.items(): + assert (root/name).read_bytes()==(backup/(name+'.worktree')).read_bytes() + assert git('ls-files','--stage','--',name).decode()==index +# Shield original staged generated content from any legacy writeback index. +for name in originals: + raw=git('ls-tree','HEAD','--',name).decode().split();git('update-index','--cacheinfo',raw[0],raw[2],name) +try: + for label,argv,limit in [('verified-client-cluster-consistency',['statehub','fix-consistency','--repo','railiance-cluster','--json'],300),('verified-client-cluster-projection',['/home/worsch/repo-manager/.venv/bin/rmgr','sync','--path',str(root),'--push'],180)]: + r=subprocess.run(argv,cwd=root,capture_output=True,text=True,timeout=limit) + (here/(label+'.json')).write_text(r.stdout);(here/(label+'.stderr.txt')).write_text(r.stderr) + assert r.returncode==0,label+'-refused-receipt-retained' +finally: + for name,index in originals.items(): + (root/name).write_bytes((backup/(name+'.worktree')).read_bytes()) + mode,oid,stage,path=index.split();assert stage=='0';git('update-index','--cacheinfo',mode,oid,path) + assert git('ls-files','--stage','--',name).decode()==index +c=json.loads((here/'verified-client-cluster-consistency.json').read_text());assert c['summary']['fail']==c['summary']['automation_error']==0 +assert 'bindings: synced 20/20' in c['fixes_applied'],'frozen-binding-omission-not-observed' +p=json.loads((here/'verified-client-cluster-projection.json').read_text());assert p['status']=='applied' +assert p['commit']==p['receipt']['expected_commit']==p['receipt']['derived_commit']==baseline_head +assert p['receipt']['instance_role']=='primary' and p['receipt']['instance_label']=='railiance01' +assert not p['receipt']['outcome']['refused'] and not p['receipt']['outcome']['retired'] +print(json.dumps({'status':'applied','commit':p['commit'],'fixed_client_source_verified':True,'current_hash_comparison':'pending','original_failed_comparison_retained':True,'unrelated_work_preserved':True})) diff --git a/docs/changes/netkingdom-target-2026-10-17/sync_rollout_custodian.py b/docs/changes/netkingdom-target-2026-10-17/sync_rollout_custodian.py new file mode 100644 index 00000000..1663426e --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/sync_rollout_custodian.py @@ -0,0 +1,33 @@ +"""Required consistency/projection with exact restoration of unrelated work.""" +from pathlib import Path +import hashlib +import json +import subprocess + +ROOT = Path('/home/worsch/the-custodian') +BASE = Path(__file__).resolve().parent +BACKUP = BASE / 'custodian-publication-backup' +originals = json.loads((BACKUP / 'originals.json').read_text()) +other = json.loads((BACKUP / 'other-dirty-hashes.json').read_text()) +def git(*argv): + return subprocess.check_output(['git', '-C', str(ROOT), *argv], stderr=subprocess.PIPE) +try: + for label, argv, timeout in [ + ('consistency', ['statehub', 'fix-consistency', '--repo', 'the-custodian', '--json'], 300), + ('projection', ['/home/worsch/repo-manager/.venv/bin/rmgr', 'sync', '--path', str(ROOT), '--push'], 180), + ]: + result = subprocess.run(argv, cwd=ROOT, capture_output=True, text=True, timeout=timeout) + (BASE / ('rollout-custodian-' + label + '.json')).write_text(result.stdout) + (BASE / ('rollout-custodian-' + label + '.stderr.txt')).write_text(result.stderr) + assert result.returncode == 0, label + ' failed; receipt retained' +finally: + for name, entry in originals.items(): + (ROOT / name).write_bytes((BACKUP / (name + '.worktree')).read_bytes()) + mode, oid, stage, path = entry.split() + assert stage == '0' + git('update-index', '--cacheinfo', mode, oid, path) + assert git('ls-files', '--stage', '--', name).decode() == entry + assert all(hashlib.sha256((ROOT / name).read_bytes()).hexdigest() == pin for name, pin in other.items()) +receipt = json.loads((BASE / 'rollout-custodian-projection.json').read_text()) +assert receipt['status'] == 'applied' +print(json.dumps({'status': 'applied', 'commit': receipt['commit'], 'other_work_preserved': True})) diff --git a/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-consistency.json b/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-consistency.json new file mode 100644 index 00000000..dc89bcfb --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-consistency.json @@ -0,0 +1,531 @@ +{ + "repo_slug": "railiance-cluster", + "repo_path": "/home/worsch/railiance-cluster", + "source_revision": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "source_revision_reason": null, + "issues": [ + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager warning: .repo-classification.yaml: category is project but slug is not prj-*; not every category:project is a prj- repo", + "file_path": ".repo-classification.yaml", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1: task id 'T01' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2: task id 'T02' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3: task id 'T03' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4: task id 'T04' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5: task id 'T05' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1: task id 'T01' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2: task id 'T02' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3: task id 'T03' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4: task id 'T04' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1: task id 'T01' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2: task id 'T02' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3: task id 'T03' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4: task id 'T04' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5: task id 'T05' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6: task id 'T06' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1: task 'T01' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1', 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1']", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2: task 'T02' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2', 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2']", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3: task 'T03' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3', 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3']", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4: task 'T04' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4', 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4']", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5: task 'T05' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5']", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-33", + "message": "WORK-RECORDS.md is missing or stale \u2014 regenerate via fix-consistency (CUST-WP-0061-T04 generated work-record index)", + "file_path": "WORK-RECORDS.md", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": true + }, + { + "severity": "WARN", + "check_id": "C-39", + "message": "Human wait task 'RCLUSTER-WP-0018-T04' in workplan 'RCLUSTER-WP-0018' has needs_human: true without decision_id \u2014 unrouted human gate", + "file_path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md#RCLUSTER-WP-0018-T04", + "db_id": "", + "file_value": "needs_human: true", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'rail-bs-wp-0008-activity-core-wp0016-triage-output-deploy@retired-20260828' (id=f2ca1a5d\u2026, status=archived) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "f2ca1a5d-4dd6-42ea-8003-969c7265f891", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'rail-bs-wp-0009-activity-core-admin-sync-smoke@retired-20260828' (id=366eec46\u2026, status=archived) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "366eec46-3139-4810-ace6-ea75750fe821", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Closed DB workstream 'rail-bs-wp-0008' (id=5032c55c\u2026, status=finished) has no backing workplan file", + "file_path": "", + "db_id": "5032c55c-2ee2-4b7e-b1eb-157f0f8ac647", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0014@retired-20260826' (id=a152ddda\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "a152ddda-d60a-4a65-9b9c-59e2db9ff2b7", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0012@retired-20260826' (id=6434f7cb\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "6434f7cb-e13c-4c05-839b-197bb239d5cd", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0013@retired-20260826' (id=a3abb83a\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "a3abb83a-2d42-40f9-a5f6-1dbc36903436", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'rail-bs-rcluster-wp-adhoc-2026-07-27@retired-20260828' (id=b37f3c6e\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "b37f3c6e-a9e5-58c2-84ec-77ef2a2978a7", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'rail-bs-adhoc-2026-07-27@retired-20260828' (id=9a77bc91\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "9a77bc91-f457-5545-996f-04f49707f54b", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-28", + "message": "8 unread inbox message(s) older than 3 day(s): railiance-platform:0c1023ce, railiance-platform:f643ce05, prj-forgejo-org-refactor:be06609c, prj-forgejo-org-refactor:6eac8c3f, prj-forgejo-org-refactor:82225aca, ...", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-28", + "message": "8 unread message(s) lack thread_id for supersession tracking: railiance-platform:0c1023ce, railiance-platform:f643ce05, prj-forgejo-org-refactor:be06609c, prj-forgejo-org-refactor:6eac8c3f, prj-forgejo-org-refactor:82225aca", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-29", + "message": "Unread work request from railiance-platform (f643ce05) may need a workplan file: RPF56: implement native JWT consumer-group mapping for Playwright", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-29", + "message": "Unread work request from the-custodian (a1368d99) may need a workplan file: Workplan 'three-phoenix-ha-cluster' is blocked with no wait task", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0007' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/RCLUSTER-WP-0007-threephoenix-ha-cluster.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0007", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0014' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/RCLUSTER-WP-0014-capacity-utilization-and-allocation-evidence.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0014", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0016' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/RCLUSTER-WP-0016-forgejo-upload-timeout.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0016", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0017' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/RCLUSTER-WP-0017-netkingdom-signer-runtime-storage-review.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0017", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0018' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0018", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0001' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/archived/260622-RCLUSTER-WP-0001-activity-core-cluster-owned-deploy-verify.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0001", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0002' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/archived/260622-RCLUSTER-WP-0002-activity-core-verifier-evidence-hardening.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0002", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RCLUSTER-WP-0003' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform", + "file_path": "workplans/archived/260701-RCLUSTER-WP-0003-activity-core-llm-connect-live-reconcile.md", + "db_id": "", + "file_value": "RCLUSTER-WP-0003", + "db_value": "RAIL-BS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0008' collides across repos: railiance-bootstrap/RAIL-BS-WP-0008-activity-core-wp0016-triage-output-deploy.md, railiance-cluster/RAIL-BS-WP-0008-activity-core-wp0016-triage-output-deploy.md", + "file_path": "workplans/RAIL-BS-WP-0008-activity-core-wp0016-triage-output-deploy.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0008", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0009' collides across repos: railiance-bootstrap/RAIL-BS-WP-0009-activity-core-admin-sync-smoke.md, railiance-cluster/RAIL-BS-WP-0009-activity-core-admin-sync-smoke.md", + "file_path": "workplans/RAIL-BS-WP-0009-activity-core-admin-sync-smoke.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0009", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0001' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0001-dependency-management.md, railiance-cluster/260622-RAIL-BS-WP-0001-dependency-management.md", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0001-dependency-management.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0001", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0002' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0002-k3s-baseline.md, railiance-cluster/260622-RAIL-BS-WP-0002-k3s-baseline.md", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0002", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0003' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md, railiance-cluster/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0003", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0004' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0004-safety-net.md, railiance-cluster/260622-RAIL-BS-WP-0004-safety-net.md", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0004", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0005' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0005-kubeconfig-delivery.md, railiance-cluster/260622-RAIL-BS-WP-0005-kubeconfig-delivery.md", + "file_path": "workplans/archived/260622-RAIL-BS-WP-0005-kubeconfig-delivery.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0005", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-27", + "message": "Workplan id 'RAIL-BS-WP-0006' collides across repos: railiance-bootstrap/260627-RAIL-BS-WP-0006-staged-promotion-lifecycle.md, railiance-cluster/260627-RAIL-BS-WP-0006-staged-promotion-lifecycle.md", + "file_path": "workplans/archived/260627-RAIL-BS-WP-0006-staged-promotion-lifecycle.md", + "db_id": "", + "file_value": "RAIL-BS-WP-0006", + "db_value": "", + "fixable": false + } + ], + "fixes_applied": [ + "bindings: synced 20/20", + "C-33 fixed: regenerated WORK-RECORDS.md", + "brief: .custodian-brief.md updated", + "push: pushed" + ], + "summary": { + "fail": 0, + "automation_error": 0, + "warn": 43, + "info": 8 + }, + "result": "warn" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-projection.json b/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-projection.json new file mode 100644 index 00000000..21c39ad8 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-projection.json @@ -0,0 +1,246 @@ +{ + "ok": true, + "status": "applied", + "repo_slug": "railiance-cluster", + "commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "requests": 2, + "elapsed_ms": 1369.2, + "git": { + "upstream": "origin/main", + "behind": 0, + "ahead": 0 + }, + "identifiers": { + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": true, + "repo": "railiance-cluster", + "namespace": "helixforge", + "assignments": [], + "historical_invalid_identifiers": [ + { + "kind": "task", + "id": "T01", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1" + }, + { + "kind": "task", + "id": "T02", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2" + }, + { + "kind": "task", + "id": "T03", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3" + }, + { + "kind": "task", + "id": "T04", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4" + }, + { + "kind": "task", + "id": "T05", + "source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5" + }, + { + "kind": "task", + "id": "T01", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1" + }, + { + "kind": "task", + "id": "T02", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2" + }, + { + "kind": "task", + "id": "T03", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3" + }, + { + "kind": "task", + "id": "T04", + "source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4" + }, + { + "kind": "task", + "id": "T01", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1" + }, + { + "kind": "task", + "id": "T02", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2" + }, + { + "kind": "task", + "id": "T03", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3" + }, + { + "kind": "task", + "id": "T04", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4" + }, + { + "kind": "task", + "id": "T05", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5" + }, + { + "kind": "task", + "id": "T06", + "source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6" + } + ], + "historical_identity_collisions": [ + { + "kind": "task", + "id": "T01", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "3f042630-eab0-4c6a-9167-e2b28ff20e40", + "4526a842-ea31-4874-9231-92ab556cfe7b", + "6841c93a-f146-47eb-9f7c-8fa0e02c1bbc" + ] + }, + { + "kind": "task", + "id": "T02", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "a6313e06-1976-46a7-8e31-df4eb2eca880", + "ab166073-30a7-4702-a037-4091e8706e20", + "e8510646-46ed-4697-a345-f3d3009eea78" + ] + }, + { + "kind": "task", + "id": "T03", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "05d42a55-921f-4aa7-bb76-e8af9c7e0ac3", + "140da396-8e30-4f4d-b88c-c42c0cd46c01", + "dab2c07f-8aa0-4635-8df6-857e87e93fc5" + ] + }, + { + "kind": "task", + "id": "T04", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4", + "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "08233868-d522-4117-bc4e-6c0f52545665", + "5c3d40e4-239b-488e-9519-6f7a38d2325f", + "d8a3ba40-fda0-4c1f-a9f1-ffcd621a5b3d" + ] + }, + { + "kind": "task", + "id": "T05", + "uuid": null, + "sources": [ + "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5", + "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5" + ], + "parent_id": "RAIL-BS-WP-0002", + "uuids": [ + "2d5acff7-4a4e-4ddd-ad06-08237ad3dac8", + "7f9e0e58-a130-467a-a2d0-b3f2564e496f" + ] + } + ], + "files_changed": [] + }, + "receipt": { + "schema": "state-hub.repository-projection-reconcile.v1", + "outcome": { + "notes": [ + "Preserved bound historical row and task UUIDs: RAIL-BS-WP-0002", + "Preserved bound historical row and task UUIDs: RAIL-BS-WP-0003", + "Preserved bound historical row and task UUIDs: RAIL-BS-WP-0004" + ], + "commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "counts": { + "created": 0, + "refused": 0, + "retired": 0, + "updated": 20, + "released": 0, + "created_edges": 0, + "created_tasks": 0, + "removed_edges": 0, + "updated_tasks": 1, + "external_edges": 0, + "cancelled_tasks": 0, + "unresolved_edges": 0 + }, + "schema": "state-hub.projection-reset.v1", + "status": "applied", + "created": [], + "refused": [], + "retired": [], + "updated": [ + "RAIL-BS-WP-0001", + "RAIL-BS-WP-0005", + "RAIL-BS-WP-0006", + "RAIL-BS-WP-0008", + "RAIL-BS-WP-0009", + "RAIL-BS-WP-0010", + "RAIL-BS-WP-0011", + "RAIL-BS-WP-0012", + "RAIL-BS-WP-0013", + "RAIL-BS-WP-0014", + "RAIL-BS-WP-0015", + "RCLUSTER-WP-0001", + "RCLUSTER-WP-0002", + "RCLUSTER-WP-0003", + "RCLUSTER-WP-0007", + "RCLUSTER-WP-0014", + "RCLUSTER-WP-0016", + "RCLUSTER-WP-0017", + "RCLUSTER-WP-0018", + "RCLUSTER-WP-ADHOC-2026-07-27" + ], + "released": [], + "repo_slug": "railiance-cluster", + "created_edges": [], + "created_tasks": [], + "removed_edges": [], + "updated_tasks": [ + "RCLUSTER-WP-0018-T01" + ], + "external_edges": [], + "cancelled_tasks": [], + "unresolved_edges": [] + }, + "instance_role": "primary", + "derived_commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6", + "instance_label": "railiance01", + "expected_commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6" + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/verified-loaded-client.json b/docs/changes/netkingdom-target-2026-10-17/verified-loaded-client.json new file mode 100644 index 00000000..5a54f8fa --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/verified-loaded-client.json @@ -0,0 +1,4 @@ +{ + "path": "/home/worsch/state-hub/.venv/lib/python3.12/site-packages/scripts/consistency_check.py", + "sha256": "1bfbc89d3ff5c621ec541fd32384083cc7dcf96a639b217d62b6fc34de238efd" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/verify_cluster_publication.py b/docs/changes/netkingdom-target-2026-10-17/verify_cluster_publication.py new file mode 100644 index 00000000..0f5f58f0 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/verify_cluster_publication.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +"""Read-only Git+Hub task binding verifier; never syncs or changes source/index.""" +import hashlib +import json +import os +from pathlib import Path +import re +import subprocess +import urllib.request + +HERE=Path(__file__).resolve().parent +OWNERS=[{'repo':'railiance-cluster','commit':'c562d7134c38679952a8ffd17a8a893a900aef0d','path':'workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md','id':'RCLUSTER-WP-0018','tasks':5}] +API=os.environ.get('API_BASE','http://127.0.0.1:8000').rstrip('/') +EXTERNAL={'STATE-WP-0095-T03':'e8566341-cf6e-5b9c-ad80-8564d14cd52a','STATE-WP-0095-T06':'6af973b4-1964-5d4d-a2f8-8dbd4c01fda4','NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'} + + +class Refused(Exception):pass + + +def git(root,*args): + result=subprocess.run(['git','--no-optional-locks','-C',str(root),*args], + capture_output=True,timeout=30,check=False) + if result.returncode:raise Refused('read-only-git-failed') + return result.stdout + + +def field(text,key): + values=re.findall(r'^'+re.escape(key)+r':\s*(.*?)\s*$',text,re.M) + if len(values)!=1:raise Refused('source-field-ambiguous') + return values[0].strip('"\'') + + +def source(text): + header=text.split('---',2)[1] + tasks=[] + for block in re.findall(r'```task\n(.*?)\n```',text,re.S): + deps=re.findall(r'^depends_on:\s*\[(.*?)\]',block,re.M) + tasks.append({'record_id':field(block,'id'),'id':field(block,'state_hub_task_id'), + 'status':field(block,'status'),'dependencies':[x.strip() for x in deps[0].split(',') if x.strip()] if deps else []}) + return {'id':field(header,'state_hub_workstream_id'),'source_record_id':field(header,'id'), + 'slug':field(header,'id').lower(), + 'status':field(header,'status'),'tasks':tasks} + + +def get(path): + class NoRedirect(urllib.request.HTTPRedirectHandler): + def redirect_request(self,*args,**kwargs):raise Refused('hub-redirect-refused') + opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect) + with opener.open(urllib.request.Request(API+path,method='GET'),timeout=20) as response: + data=response.read(8*1024**2+1) + if len(data)>8*1024**2:raise Refused('hub-read-limit') + return json.loads(data) + + +def index_stat(root): + raw=git(root,'rev-parse','--git-path','index').decode().strip();path=Path(raw) + if not path.is_absolute():path=root/path + try:item=path.lstat() + except FileNotFoundError:return None + return [item.st_dev,item.st_ino,item.st_size,item.st_mtime_ns,item.st_mode] + + +def remote(root,expected,repo): + if git(root,'remote','get-url','origin').decode().strip()!='forgejo-remote:coulomb/'+repo+'.git': + raise Refused('remote-route-drift') + lines=git(root,'ls-remote','--symref','origin','HEAD','refs/heads/main').decode().splitlines() + if set(lines)!={'ref: refs/heads/main\tHEAD',expected+'\tHEAD',expected+'\trefs/heads/main'}: + raise Refused('remote-head-mismatch') + return {'HEAD':expected,'refs/heads/main':expected,'symbolic_HEAD':'refs/heads/main'} + + +def verify(): + result={'status':'unverified','scope':'Cluster WP18 owner publication; read-only Git remote and Hub snapshots', + 'writes_to_source_index_refs_or_Hub':False,'rows':[]} + try: + if API not in {'http://127.0.0.1:8000','http://127.0.0.1:18080','http://10.43.68.154:8000'}: + raise Refused('unrecognized-hub-endpoint') + health=get('/state/health') + result['hub_instance']={key:health.get(key) for key in ('status','instance_role','instance_label')} + if result['hub_instance']!={'status':'ok','instance_role':'primary','instance_label':'railiance01'}: + raise Refused('hub-identity-mismatch') + for owner in OWNERS: + root=Path('/home/worsch')/owner['repo'];before_index=index_stat(root) + if git(root,'rev-parse','HEAD').decode().strip()!=owner['commit']: + raise Refused('local-head-drift') + committed=git(root,'show',owner['commit']+':'+owner['path']) + local=(root/owner['path']).read_bytes() + if local!=committed:raise Refused('published-workplan-local-drift') + expected=source(committed.decode()) + if expected['source_record_id']!=owner['id'] or len(expected['tasks'])!=owner['tasks']: + raise Refused('source-task-denominator-mismatch') + snapshot=get('/repos/'+owner['repo']+'/work-record-projection/snapshot') + plans=[row for row in snapshot['workplans'] if row['id']==expected['id']] + if len(plans)!=1 or any(plans[0].get(key)!=expected[key] for key in ('id','slug','status')): + raise Refused('workplan-binding-mismatch') + projected=[row for row in snapshot['tasks'] + if row.get('workplan_id',row.get('workstream_id'))==expected['id']] + if len(projected)!=len(expected['tasks']):raise Refused('projected-task-denominator-mismatch') + byid={row['id']:row for row in projected} + if len(byid)!=len(projected):raise Refused('duplicate-projected-uuid') + observed=[] + for task in expected['tasks']: + row=byid.get(task['id'],{}) + if any(row.get(key)!=task[key] for key in ('id','record_id','status')): + raise Refused('task-id-uuid-status-mismatch') + observed.append({key:row[key] for key in ('id','record_id','status')}) + identifiers={task['record_id']:task['id'] for task in expected['tasks']} + edges={(task['id'],identifiers[dep],'starts_after') for task in expected['tasks'] for dep in task['dependencies'] if dep in identifiers} + actual=[edge for edge in snapshot['dependencies'] if edge['from_workplan_id']==expected['id']] + projected_edges={(edge.get('from_task_id'),edge.get('to_task_id'),edge['relationship_type']) for edge in actual} + if len(actual)!=len(edges) or projected_edges!=edges: + raise Refused('dependency-binding-mismatch') + if any(edge.get('source_commit') not in (None,owner['commit']) for edge in actual): + raise Refused('dependency-source-commit-mismatch') + for task in expected['tasks']: + for dep in task['dependencies']: + if dep in EXTERNAL: + target=get('/tasks/'+EXTERNAL[dep]) + if target.get('id')!=EXTERNAL[dep] or target.get('record_id')!=dep: + raise Refused('external-dependency-target-mismatch') + remote_readback=remote(root,owner['commit'],owner['repo']) + if index_stat(root)!=before_index or (root/owner['path']).read_bytes()!=local: + raise Refused('source-or-index-stat-changed') + result['rows'].append({'repo':owner['repo'],'published_commit':owner['commit'], + 'remote':remote_readback,'workplan':{key:plans[0][key] for key in ('id','slug','status')}, + 'source_record_id':expected['source_record_id'], + 'tasks':observed,'external_source_declarations_not_projected':[{'from_task_id':task['id'],'target_record_id':dep,'target_uuid':EXTERNAL[dep]} for task in expected['tasks'] for dep in task['dependencies'] if dep in EXTERNAL],'dependencies':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(edges)], + 'source_file_sha256':hashlib.sha256(local).hexdigest(),'source_file_unchanged':True,'dependency_scope':'internal edges verified; external source target identities checked without claiming projected external edges', + 'index_stat_unchanged':True}) + result['status']='verified' + except Exception as error: + result['reason']=error.args[0] if isinstance(error,Refused) else 'readback-unavailable' + result['verifier_sha256']=hashlib.sha256(Path(__file__).read_bytes()).hexdigest() + (HERE/'cluster-publication-readback.json').write_text(json.dumps(result,indent=2)+'\n') + print(json.dumps({'status':result['status'],'owners':len(result['rows'])})) + return 0 if result['status']=='verified' else 2 + + +if __name__=='__main__':raise SystemExit(verify()) diff --git a/docs/changes/netkingdom-target-2026-10-17/verify_rollout_close.py b/docs/changes/netkingdom-target-2026-10-17/verify_rollout_close.py new file mode 100644 index 00000000..e295e3c1 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/verify_rollout_close.py @@ -0,0 +1,60 @@ +"""Read back committed Custodian bindings and retain unrelated-work checks.""" +from pathlib import Path +import hashlib +import json +import re +import subprocess +import urllib.request +import yaml + +ROOT = Path('/home/worsch/the-custodian') +BASE = Path(__file__).resolve().parent +BACKUP = BASE / 'custodian-publication-backup' + +def git(*args): + return subprocess.check_output(['git', '-C', str(ROOT), *args], stderr=subprocess.PIPE).decode().strip() + +def get(path): + return json.load(urllib.request.urlopen('http://127.0.0.1:8000' + path, timeout=20)) + +head = git('rev-parse', 'HEAD') +assert git('ls-remote', 'origin', 'refs/heads/main').split()[0] == head +projection = json.loads((BASE / 'rollout-custodian-projection.json').read_text()) +receipt = projection['receipt'] +assert projection['status'] == 'applied' and projection['commit'] == head +assert receipt['instance_role'] == 'primary' and receipt['instance_label'] == 'railiance01' +assert receipt['expected_commit'] == receipt['derived_commit'] == head +health = get('/state/health') +assert health['instance_role'] == 'primary' and health['instance_label'] == 'railiance01' +path = ROOT / 'workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md' +raw = path.read_text() +assert git('show', head + ':' + str(path.relative_to(ROOT))) == raw.strip() +front = yaml.safe_load(raw.split('---', 2)[1]) +tasks = [yaml.safe_load(value) for value in re.findall(r'```task\n(.*?)\n```', raw, re.S)] +snapshot = get('/repos/the-custodian/work-record-projection/snapshot') +plan = next(p for p in snapshot['workplans'] if p['id'] == front['state_hub_workstream_id']) +assert plan['status'] == front['status'] == 'active' +actual = {t['id']: t for t in snapshot['tasks'] if t.get('workplan_id', t.get('workstream_id')) == plan['id']} +assert len(actual) == len(tasks) == 6 +for task in tasks: + row = actual[task['state_hub_task_id']] + assert row['record_id'] == task['id'] and row['status'] == task['status'] +for name, entry in json.loads((BACKUP / 'originals.json').read_text()).items(): + assert (ROOT / name).read_bytes() == (BACKUP / (name + '.worktree')).read_bytes() + assert git('ls-files', '--stage', '--', name) == entry.strip() +assert all(hashlib.sha256((ROOT / name).read_bytes()).hexdigest() == pin + for name, pin in json.loads((BACKUP / 'other-dirty-hashes.json').read_text()).items()) +proposal = BASE / 'guard-successor-review-r2/proposal-metadata.json' +assert hashlib.sha256(proposal.read_bytes()).hexdigest() == '5d0ddebc21bcb035809cc8b57f4c2e1ba8ed09204be5b965460e178a90913f1e' +for bound in json.loads(proposal.read_text())['bound_receipts']: + assert hashlib.sha256(Path(bound['path']).read_bytes()).hexdigest() == bound['sha256'] +pending = get('/decisions/df703266-6719-4c04-ae1b-ba9afd3bca1c') +assert pending['decision_type'] == 'pending' and pending['status'] == 'open' +assert pending['decided_by'] is None and pending['decided_at'] is None +result = {'status': 'verified', 'commit': head, 'remote_exact': True, + 'primary': 'primary/railiance01', 'projection_expected_equals_derived': True, + 'custodian_task_bindings': len(tasks), 'unrelated_index_and_worktree_preserved': True, + 'pending_proposal_revision': 2, 'pending_proposal_not_approved_or_executed': True, + 'proposal_bound_receipts_unchanged': True, 'native_target_gates_closed': 0} +(BASE / 'rollout-close-verification.json').write_text(json.dumps(result, indent=2) + '\n') +print(json.dumps(result)) diff --git a/docs/changes/netkingdom-target-2026-10-17/verify_rollout_owner_bindings.py b/docs/changes/netkingdom-target-2026-10-17/verify_rollout_owner_bindings.py new file mode 100644 index 00000000..6e7f9176 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/verify_rollout_owner_bindings.py @@ -0,0 +1,34 @@ +"""Read-only final source/remote/Hub binding check, retaining only public identifiers.""" +from pathlib import Path +import hashlib,json,re,subprocess,urllib.request,yaml +here=Path(__file__).resolve().parent +specs=[('state-hub','STATE-WP-0095','4c03c9d2c6a47f5c7247473f74b2e2f188b787bd',10),('repo-manager','RMGR-WP-0019','1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd',6),('repo-manager','RMGR-WP-0021','1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd',5),('railiance-cluster','RCLUSTER-WP-0018','6ae3f847c83da3402883453ee7110457bfb2d0d6',5)] +def git(root,*a):return subprocess.check_output(['git','--no-optional-locks','-C',str(root),*a],stderr=subprocess.PIPE,timeout=30).decode().strip() +def get(path):return json.load(urllib.request.urlopen('http://127.0.0.1:8000'+path,timeout=20)) +health=get('/state/health');assert health['instance_role']=='primary' and health['instance_label']=='railiance01' +rows=[];snapshots={};targets={'NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'} +for repo,wp,head,count in specs: + root=Path('/home/worsch')/repo;assert git(root,'rev-parse','HEAD')==head + paths=list((root/'workplans').glob(wp+'-*.md'));assert len(paths)==1;path=paths[0];raw=path.read_text();assert git(root,'show',head+':'+str(path.relative_to(root)))==raw.strip() + front=yaml.safe_load(raw.split('---',2)[1]);tasks=[yaml.safe_load(v) for v in re.findall(r'```task\n(.*?)\n```',raw,re.S)];assert len(tasks)==count + for task in tasks:targets[task['id']]=task['state_hub_task_id'] + rows.append(dict(repo=repo,wp=wp,head=head,source_path=str(path),front=front,tasks=tasks,source_sha256=hashlib.sha256(path.read_bytes()).hexdigest())) +result=[] +for item in rows: + repo=item['repo'];root=Path('/home/worsch')/repo + remote=git(root,'ls-remote','origin','refs/heads/main').split()[0];assert remote==item['head'] + snapshot=snapshots.setdefault(repo,get('/repos/'+repo+'/work-record-projection/snapshot')) + plan=next(p for p in snapshot['workplans'] if p['id']==item['front']['state_hub_workstream_id']);assert plan['status']==item['front']['status'] + actual=[t for t in snapshot['tasks'] if t.get('workplan_id',t.get('workstream_id'))==plan['id']];assert len(actual)==len(item['tasks']);byid={t['id']:t for t in actual} + for task in item['tasks']: + t=byid[task['state_hub_task_id']];assert t['record_id']==task['id'] and t['status']==task['status'] + if 'needs_human' in task:assert bool(t.get('needs_human'))==task['needs_human'] + expected={(t['state_hub_task_id'],targets[d],'starts_after') for t in item['tasks'] for d in t.get('depends_on',[]) if d in targets} + edges=[e for e in snapshot['dependencies'] if e['from_workplan_id']==plan['id'] and e.get('from_task_id')] + observed={(e['from_task_id'],e.get('to_task_id'),e['relationship_type']) for e in edges} + assert observed<=expected,'undeclared-projected-edge' + required_pairs={'RMGR-WP-0019':[('RMGR-WP-0019-T06','STATE-WP-0095-T10')],'STATE-WP-0095':[('STATE-WP-0095-T07','STATE-WP-0095-T10')],'RCLUSTER-WP-0018':[('RCLUSTER-WP-0018-T03','RCLUSTER-WP-0018-T02'),('RCLUSTER-WP-0018-T04','RCLUSTER-WP-0018-T02'),('RCLUSTER-WP-0018-T04','RCLUSTER-WP-0018-T03')]} + assert all((targets[a],targets[b],'starts_after') in observed for a,b in required_pairs.get(item['wp'],[])),'required-current-edge-missing' + result.append({'repo':repo,'workplan_id':item['wp'],'commit':item['head'],'remote_exact':True,'source_sha256':item['source_sha256'],'status':plan['status'],'tasks':[{k:t[k] for k in ['id','record_id','status','needs_human'] if k in t} for t in actual],'projected_edges':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(observed)],'unprojected_source_declarations':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(expected-observed)]}) +v={'schema':'custodian.rollout-owner-bindings.v1','status':'verified','primary':'primary/railiance01','task_bindings':sum(len(r['tasks']) for r in result),'rows':result,'runtime_deployed_source':'51bc70d1ff8f25450a8650d8e50caf053093a02e','successor_runtime_source_not_deployed':'c103cbf3c8bed5dba87a03e320595ddded9301a3','native_target_gates_closed':0} +(here/'rollout-owner-bindings.json').write_text(json.dumps(v,indent=2)+'\n');print(json.dumps({'status':'verified','task_bindings':v['task_bindings']})) diff --git a/docs/netkingdom-target-implementation.md b/docs/netkingdom-target-implementation.md index 091aaca9..46123d0e 100644 --- a/docs/netkingdom-target-implementation.md +++ b/docs/netkingdom-target-implementation.md @@ -772,3 +772,134 @@ driver, external message or worker wake was created. The verifies all 58 NetKingdom and eight State Hub task IDs/UUIDs/statuses against source, plus exact remote heads. Earlier Repo Manager/Secrets readback verifies nine more owner bindings and the two Secrets dependency edges. + + +## Approved coordination receiver execution, 2026-10-17 + +This checkpoint supersedes the pending-rollout state recorded above. The founder's +“good, go ahead” approved exact revision 4 of +`STATE-WP-0095-T06-cluster-frozen-receiving-r1`, digest +`63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32`. +Decision `e3798419-8aa9-5425-8c08-20df6bd82a19` records +`ADMINISTER @ realm:kubernetes/railiance01`, `activation=APPROVED` for that +proposal and its exact conditional recovery, with no autonomy grant. + +The owner Helm upgrade succeeded as revision 76. API and MCP are Ready on the +approved image digest `c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015`; +primary/railiance01 reports applied and expected schema `c4d5e6f7a8b9`. +Delivered historical projection module hash matches the reviewed image. Full-row +hashes and column sets of all three historical workplans and fifteen tasks are +identical before and after deployment. Five actual native receiving cases pass: +preserve, foreign holder, missing task, nonterminal parent and nonterminal task. +Every probe rolled back; zero commits and a fresh-transaction full-row comparison +confirm preservation. Helm succeeded and the migration Job disappeared after +its exact UID and owned Pod were observed; no Job Succeeded event is claimed. +No recovery was needed. The exact owned staging archive/directory was removed. + +Only after these observations was the frozen seven-file registrar source applied. +Canonical focused checks pass 47; the actual read-only Cluster allocator preview +proposes exactly seven missing UUID fields in the new WP0018 and one existing +ADHOC task. Fifteen invalid historical labels and five collisions remain reported; +no archive rewrite, direct database UUID repair or broad syntax exception occurred. +Owner publication and receiving follow-through are recorded separately below. + +Evidence: `docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json` +and its hash-bound actual native receipts; registrar source/application and preview +receipts in `registrar-followthrough-r1/`. The same original supervision trial +retains all preparation revisions and failures; accepted-revised execution earns +no unchanged-success credit. All sixteen native target gates remain open. + + +## Ordinary Cluster publication and retained acceptance failure, 2026-10-17 + +Cluster owner commit `c562d7134c38679952a8ffd17a8a893a900aef0d` is published and +reconciled on primary/railiance01 at the exact expected/derived revision. WP0018's +five task ID/UUID/status bindings and three internal edges match source and the +remote. Exactly seven missing fields were assigned by the normal managed path, +including one existing ADHOC task field. All three frozen archive hashes remain +unchanged, and original staged/dirty generated files were restored exactly. +Registrar source admission `70cd7549` is published and verified, with T05 done; +source preparation and actual Cluster acceptance remain separate outcomes. + +The stronger full-row guard FAILED after the required legacy deep consistency +pass: the three historical parent hashes changed, while all fifteen task full +rows remain identical. The native forge projection reports preservation, but +that does not establish preservation for the whole pipeline. Source review found +that `PUT /workplans/index/bindings` writes backing fields and a new sync timestamp +without consulting the frozen-history guard; ORM update timestamps also advance. +The checker calls this route even during checks. Only whole-row baseline hashes +were retained, so exact changed columns/values cannot be reconstructed from the +baseline. No guessed timestamp or database restoration is performed. + +This later failure does not erase the earlier passing rollout and rollback-only +probe results. It prevents RMGR-WP-0019-T06 and STATE-WP-0095-T07 completion. +The existing State Hub owner record carries the source guard and regression +follow-up plus its separate reviewed runtime-delivery obligation. Source edits, +fixtures and successful publication do not stand in for that new native return. +No further production rollout is authorized by the earlier revision-4 approval. + +Evidence: `docs/changes/netkingdom-target-2026-10-17/cluster-publication-readback.json`, +`railiance-cluster-projection.json`, and +`receiver-rollout-r4/ordinary-pipeline-preservation-finding.json`, including the +retained `post-publication-full-row-hashes-FAILED.json` and exact archive checks. +All sixteen native target gates remain open. + + +## Verified installed-client repair and exact runtime successor, 2026-10-17 + +State Hub source guards and real writeback regression are published through +`c103cbf3c8bed5dba87a03e320595ddded9301a3`; the later WP-only checkpoint is +`9eaa36143ea18111c522ea14d32978495b4e5030`. Canonical guard checks pass 102, +independent review passes 109, and five actual disposable Git checks verify +file-scoped commits with unrelated staged/dirty state and hook refusal preserved. +Normal chart rendering and classification checks pass. The first attempted +client rerun loaded an older installed package and failed again; its actual +receipts stay retained. The installed owner package was then refreshed and its +loaded checker hash verified against R6 source before the next run. + +The corrected actual ordinary Cluster maintenance passes: 20/20 ordinary +bindings, three frozen bindings omitted, and all eighteen CURRENT full-row +hashes unchanged before/after. Original failed parent hashes are not restored +or relabeled as successes. The old writeback helper also included an unrelated +staged brief during legitimate C23 activation. Forward correction +`6ae3f847c83da3402883453ee7110457bfb2d0d6` preserves active WP18, restores the +prior committed brief, and reinstates its exact original staged/worktree bytes; +dirty WORK-RECORDS and archive hashes are preserved. No history was rewritten. +Repo Manager `1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd` retains T05 done/T06 wait +and projects T06's actual dependency on STATE-WP-0095-T10. State Hub T07 also +waits on T10; all ten own task UUIDs remain exact, T09 done/T10 human wait. + +The normal CI guard image at +`sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1` +is inspected read-only against runtime source `c103cbf`. Selected guard/receiver/ +migration/build files match; package metadata and hub-core source hashes equal +the deployed image's observations. Exact pinned-package reuse-values server +dry-run passes eight identities and only three image changes. Fresh explicit +target/headroom/schema checks pass. The prepared eight native cases enforce +commit interception and rollback; their actual schema/interception contracts +are checked without a DB connection, but these new native cases are not executed. + +Exact successor `STATE-WP-0095-T10-frozen-bindings-guard-r1` revision 1 is pending, +metadata digest `81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932`, +decision `df703266-6719-4c04-ae1b-ba9afd3bca1c`. It requests scoped new-image +approval, current-baseline acceptance with the old failure retained as an +exception, and exact conditional recovery/rollback to Helm 76. Unknown EUR +cost/risk or Job/DB mapping is not a free or bounded exposure. The prior +revision-4 approval does not approve this successor. Current runtime remains +healthy Helm 76 on the approved `51bc70d` image; no new API guard delivery or +native security-gate closure is inferred. The original supervision record +retains successful earlier-stage execution plus later failures; its new request +is pending/not executed and grants no authority. + +Evidence: `docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/`, +`receiver-rollout-r4/before-verified-client.json`, `after-verified-client.json`, +`verified-loaded-client.json`, `verified-client-cluster-consistency.json`, +`verified-client-cluster-projection.json`, the exact owner publication packets +and `rollout-owner-bindings.json`. The original receiver/registrar case is +satisfied; the successor attaches to the existing retirement driver and stops +at the human gate. TLS metadata work remains an owner wait. No worker was woken. +All sixteen native target gates remain open. + +The same pending API guard proposal now has revision 2, SHA256 `5d0ddebc21bcb035809cc8b57f4c2e1ba8ed09204be5b965460e178a90913f1e`, at `docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/FINAL-PROPOSAL.md`. Only the probe source-hash metadata representation changed after the normal scanner flagged hashes as generic API keys. Revision 1 remains unapproved and unexecuted; the runtime image, probe case logic, acceptance exception and recovery scope are unchanged. Source-publication receipt hashes are exposed through reversible typed metadata companions; original bytes and the refused scan remain retained. + +The owner’s WP-only revision-2 reference amendment is published at State Hub `4c03c9d2c6a47f5c7247473f74b2e2f188b787bd`. Final source/remote/primary readback verifies all 26 affected owner task bindings; runtime source remains `51bc70d` and the proposed guard image remains `c103cbf`. diff --git a/workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md b/workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md index b4301b5a..d01ba58f 100644 --- a/workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md +++ b/workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md @@ -961,3 +961,134 @@ action is approved or executed. Four coordination receipts attach foreign waits without messages or worker wakes. Source/remote/Hub readback verifies 66 new checkpoint owner bindings plus the nine Repo Manager/Secrets bindings; source counts and native acceptance remain separate. + + +## Approved receiver execution, 2026-10-17 + +This checkpoint supersedes the pending-rollout state recorded above. The founder's +“good, go ahead” approved exact revision 4 of +`STATE-WP-0095-T06-cluster-frozen-receiving-r1`, digest +`63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32`. +Decision `e3798419-8aa9-5425-8c08-20df6bd82a19` records +`ADMINISTER @ realm:kubernetes/railiance01`, `activation=APPROVED` for that +proposal and its exact conditional recovery, with no autonomy grant. + +The owner Helm upgrade succeeded as revision 76. API and MCP are Ready on the +approved image digest `c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015`; +primary/railiance01 reports applied and expected schema `c4d5e6f7a8b9`. +Delivered historical projection module hash matches the reviewed image. Full-row +hashes and column sets of all three historical workplans and fifteen tasks are +identical before and after deployment. Five actual native receiving cases pass: +preserve, foreign holder, missing task, nonterminal parent and nonterminal task. +Every probe rolled back; zero commits and a fresh-transaction full-row comparison +confirm preservation. Helm succeeded and the migration Job disappeared after +its exact UID and owned Pod were observed; no Job Succeeded event is claimed. +No recovery was needed. The exact owned staging archive/directory was removed. + +Only after these observations was the frozen seven-file registrar source applied. +Canonical focused checks pass 47; the actual read-only Cluster allocator preview +proposes exactly seven missing UUID fields in the new WP0018 and one existing +ADHOC task. Fifteen invalid historical labels and five collisions remain reported; +no archive rewrite, direct database UUID repair or broad syntax exception occurred. +Owner publication and receiving follow-through are recorded separately below. + +Evidence: `docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json` +and its hash-bound actual native receipts; registrar source/application and preview +receipts in `registrar-followthrough-r1/`. The same original supervision trial +retains all preparation revisions and failures; accepted-revised execution earns +no unchanged-success credit. All sixteen native target gates remain open. + + +## Ordinary Cluster publication and retained acceptance failure, 2026-10-17 + +Cluster owner commit `c562d7134c38679952a8ffd17a8a893a900aef0d` is published and +reconciled on primary/railiance01 at the exact expected/derived revision. WP0018's +five task ID/UUID/status bindings and three internal edges match source and the +remote. Exactly seven missing fields were assigned by the normal managed path, +including one existing ADHOC task field. All three frozen archive hashes remain +unchanged, and original staged/dirty generated files were restored exactly. +Registrar source admission `70cd7549` is published and verified, with T05 done; +source preparation and actual Cluster acceptance remain separate outcomes. + +The stronger full-row guard FAILED after the required legacy deep consistency +pass: the three historical parent hashes changed, while all fifteen task full +rows remain identical. The native forge projection reports preservation, but +that does not establish preservation for the whole pipeline. Source review found +that `PUT /workplans/index/bindings` writes backing fields and a new sync timestamp +without consulting the frozen-history guard; ORM update timestamps also advance. +The checker calls this route even during checks. Only whole-row baseline hashes +were retained, so exact changed columns/values cannot be reconstructed from the +baseline. No guessed timestamp or database restoration is performed. + +This later failure does not erase the earlier passing rollout and rollback-only +probe results. It prevents RMGR-WP-0019-T06 and STATE-WP-0095-T07 completion. +The existing State Hub owner record carries the source guard and regression +follow-up plus its separate reviewed runtime-delivery obligation. Source edits, +fixtures and successful publication do not stand in for that new native return. +No further production rollout is authorized by the earlier revision-4 approval. + +Evidence: `docs/changes/netkingdom-target-2026-10-17/cluster-publication-readback.json`, +`railiance-cluster-projection.json`, and +`receiver-rollout-r4/ordinary-pipeline-preservation-finding.json`, including the +retained `post-publication-full-row-hashes-FAILED.json` and exact archive checks. +All sixteen native target gates remain open. + + +## Verified installed-client repair and exact runtime successor, 2026-10-17 + +State Hub source guards and real writeback regression are published through +`c103cbf3c8bed5dba87a03e320595ddded9301a3`; the later WP-only checkpoint is +`9eaa36143ea18111c522ea14d32978495b4e5030`. Canonical guard checks pass 102, +independent review passes 109, and five actual disposable Git checks verify +file-scoped commits with unrelated staged/dirty state and hook refusal preserved. +Normal chart rendering and classification checks pass. The first attempted +client rerun loaded an older installed package and failed again; its actual +receipts stay retained. The installed owner package was then refreshed and its +loaded checker hash verified against R6 source before the next run. + +The corrected actual ordinary Cluster maintenance passes: 20/20 ordinary +bindings, three frozen bindings omitted, and all eighteen CURRENT full-row +hashes unchanged before/after. Original failed parent hashes are not restored +or relabeled as successes. The old writeback helper also included an unrelated +staged brief during legitimate C23 activation. Forward correction +`6ae3f847c83da3402883453ee7110457bfb2d0d6` preserves active WP18, restores the +prior committed brief, and reinstates its exact original staged/worktree bytes; +dirty WORK-RECORDS and archive hashes are preserved. No history was rewritten. +Repo Manager `1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd` retains T05 done/T06 wait +and projects T06's actual dependency on STATE-WP-0095-T10. State Hub T07 also +waits on T10; all ten own task UUIDs remain exact, T09 done/T10 human wait. + +The normal CI guard image at +`sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1` +is inspected read-only against runtime source `c103cbf`. Selected guard/receiver/ +migration/build files match; package metadata and hub-core source hashes equal +the deployed image's observations. Exact pinned-package reuse-values server +dry-run passes eight identities and only three image changes. Fresh explicit +target/headroom/schema checks pass. The prepared eight native cases enforce +commit interception and rollback; their actual schema/interception contracts +are checked without a DB connection, but these new native cases are not executed. + +Exact successor `STATE-WP-0095-T10-frozen-bindings-guard-r1` revision 1 is pending, +metadata digest `81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932`, +decision `df703266-6719-4c04-ae1b-ba9afd3bca1c`. It requests scoped new-image +approval, current-baseline acceptance with the old failure retained as an +exception, and exact conditional recovery/rollback to Helm 76. Unknown EUR +cost/risk or Job/DB mapping is not a free or bounded exposure. The prior +revision-4 approval does not approve this successor. Current runtime remains +healthy Helm 76 on the approved `51bc70d` image; no new API guard delivery or +native security-gate closure is inferred. The original supervision record +retains successful earlier-stage execution plus later failures; its new request +is pending/not executed and grants no authority. + +Evidence: `docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/`, +`receiver-rollout-r4/before-verified-client.json`, `after-verified-client.json`, +`verified-loaded-client.json`, `verified-client-cluster-consistency.json`, +`verified-client-cluster-projection.json`, the exact owner publication packets +and `rollout-owner-bindings.json`. The original receiver/registrar case is +satisfied; the successor attaches to the existing retirement driver and stops +at the human gate. TLS metadata work remains an owner wait. No worker was woken. +All sixteen native target gates remain open. + +The same pending API guard proposal now has revision 2, SHA256 `5d0ddebc21bcb035809cc8b57f4c2e1ba8ed09204be5b965460e178a90913f1e`, at `docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/FINAL-PROPOSAL.md`. Only the probe source-hash metadata representation changed after the normal scanner flagged hashes as generic API keys. Revision 1 remains unapproved and unexecuted; the runtime image, probe case logic, acceptance exception and recovery scope are unchanged. Source-publication receipt hashes are exposed through reversible typed metadata companions; original bytes and the refused scan remain retained. + +The owner’s WP-only revision-2 reference amendment is published at State Hub `4c03c9d2c6a47f5c7247473f74b2e2f188b787bd`. Final source/remote/primary readback verifies all 26 affected owner task bindings; runtime source remains `51bc70d` and the proposed guard image remains `c103cbf`.