diff --git a/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json new file mode 100644 index 00000000..26c73115 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json @@ -0,0 +1,149 @@ +{ + "credential_values_exposed": false, + "historical_module_sha256": "sha256:e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2", + "raw_rows_retained": false, + "schema": "state95.full-db-row-hash-snapshot.v1", + "status": "captured_readonly", + "tables": { + "tasks": { + "all_rows_sha256": "sha256:7f42dea1cabd2f5802aab5e2b1535a530192a1f35721ca1ca2cddc2fb5319cc9", + "columns": [ + "assignee", + "blocked_on", + "blocking_reason", + "created_at", + "decision_id", + "description", + "due_date", + "flavor", + "id", + "intervention_note", + "needs_human", + "parent_task_id", + "priority", + "record_id", + "status", + "title", + "updated_at", + "wait_until", + "workplan_id" + ], + "row_count": 15, + "rows": [ + { + "sha256": "sha256:89b3be69fbaf5ad60f5aefa6f2b630e1d6124e0fca7b01a5e9ce1ff41a451106", + "uuid": "05d42a55-921f-4aa7-bb76-e8af9c7e0ac3" + }, + { + "sha256": "sha256:3aa20e9695e110468d13baa3c813ac5b474896d89eeb6edc56e9ea00d9199fd7", + "uuid": "08233868-d522-4117-bc4e-6c0f52545665" + }, + { + "sha256": "sha256:72fb54d9a271067a62f33377d56e0bb9e6874a3f9c475b9ae049609b93d1f643", + "uuid": "140da396-8e30-4f4d-b88c-c42c0cd46c01" + }, + { + "sha256": "sha256:15198017e5c7d31b4e8ce1d5c0ef0de99ac1c50d3bffd0ea0ee807bef70ce5d1", + "uuid": "2d5acff7-4a4e-4ddd-ad06-08237ad3dac8" + }, + { + "sha256": "sha256:29a6f1e50db6a7b4ba5b98a2f7d8d109b4df1720fce58777c21f7538084f8cda", + "uuid": "3f042630-eab0-4c6a-9167-e2b28ff20e40" + }, + { + "sha256": "sha256:2e00141f0d7382dd34859b686a500dc740a543efe81e23f5805754cbc6761f2e", + "uuid": "4526a842-ea31-4874-9231-92ab556cfe7b" + }, + { + "sha256": "sha256:7b3ecacb7be3c1a24a100d7b732b7f60e1a99329a6847612264cd01d13c7ecf0", + "uuid": "5c3d40e4-239b-488e-9519-6f7a38d2325f" + }, + { + "sha256": "sha256:71107455d1d453d69d65466ca66da1fd4ee4aa95ecdf7920b9acdce767f0c55c", + "uuid": "6841c93a-f146-47eb-9f7c-8fa0e02c1bbc" + }, + { + "sha256": "sha256:f8e44ea79125870ab3ade44afab8752c126c424e2b751f48b9fe555e00b5b708", + "uuid": "7f9e0e58-a130-467a-a2d0-b3f2564e496f" + }, + { + "sha256": "sha256:435e39ffee3a59eae3b890739a6ed8e06801fb23dead15073653d8650f9d5ff5", + "uuid": "a6313e06-1976-46a7-8e31-df4eb2eca880" + }, + { + "sha256": "sha256:2fcda8440a166fc628f8fadf91a4a23ba7728ccac2e629248c6eccd00d5d4345", + "uuid": "ab166073-30a7-4702-a037-4091e8706e20" + }, + { + "sha256": "sha256:b2e11b8fdc580e6cb7ec20c7e90018ba9fb468893b6eda5b9519dc68737a0ca0", + "uuid": "d8a3ba40-fda0-4c1f-a9f1-ffcd621a5b3d" + }, + { + "sha256": "sha256:788862d9cc5015b927d27303585431a0db4af6077178ab3bfdde37f900cee821", + "uuid": "dab2c07f-8aa0-4635-8df6-857e87e93fc5" + }, + { + "sha256": "sha256:f7bc1f3acf187301430df0623417fb90b6af1869c0383a0bff9ec25f79ffe4af", + "uuid": "e8510646-46ed-4697-a345-f3d3009eea78" + }, + { + "sha256": "sha256:f2760deded2f7136a60fba0156c4956ba373fbcf5eda986f5c380d7ee9c925ff", + "uuid": "f8e4a094-c367-40eb-b895-da17bc144b07" + } + ] + }, + "workplans": { + "all_rows_sha256": "sha256:7e063b4dc5de4169f3133b8ba52bd467b2a7c64ed3cd8f40297cc5e4706745b3", + "columns": [ + "backing_archived", + "backing_filename", + "backing_relative_path", + "backing_synced_at", + "concurrency_mode", + "created_at", + "derived_from_commit", + "description", + "due_date", + "execution_group", + "execution_state", + "flavor", + "flavor_promoted_from", + "flavor_promotion_reason", + "id", + "launch_mode", + "owner", + "planning_order", + "planning_priority", + "projection_retired_at", + "projection_retired_reason", + "queue_rank", + "repo_goal_id", + "repo_id", + "scheduled_for", + "slug", + "status", + "title", + "topic_id", + "updated_at" + ], + "row_count": 3, + "rows": [ + { + "sha256": "sha256:9ec13ef62b82f6e33fbcebc6f524d7d905ce4f9bdf1f462e48d070ebdb79c97a", + "uuid": "4c63dfc6-9eac-4e79-9f77-8f644ad7147d" + }, + { + "sha256": "sha256:506eceaef492d164624268de51b6a72b2d02048311def7ec7a2985a95ee34489", + "uuid": "7e8b0c20-51eb-40c9-9e3b-85dd380d7625" + }, + { + "sha256": "sha256:bf1c238774ed27caf23a88fd40df3fe0a67805b1a82c9f9a4ff628ecdc2e1d47", + "uuid": "7ee9ee22-1fae-4567-9194-8d70a9e0f45b" + } + ] + } + }, + "full_rows_equal_to_pre_rollout": false, + "source": "post-cluster-publication", + "comparison": "failed" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/pre-publication-full-row-hashes.json b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/pre-publication-full-row-hashes.json new file mode 100644 index 00000000..654a8024 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/pre-publication-full-row-hashes.json @@ -0,0 +1,149 @@ +{ + "credential_values_exposed": false, + "historical_module_sha256": "sha256:e3c4bf965764b32a6df5d61c71272ee22569df9a9ddae2a3fc3df97ec554e0b2", + "raw_rows_retained": false, + "schema": "state95.full-db-row-hash-snapshot.v1", + "status": "captured_readonly", + "tables": { + "tasks": { + "all_rows_sha256": "sha256:7f42dea1cabd2f5802aab5e2b1535a530192a1f35721ca1ca2cddc2fb5319cc9", + "columns": [ + "assignee", + "blocked_on", + "blocking_reason", + "created_at", + "decision_id", + "description", + "due_date", + "flavor", + "id", + "intervention_note", + "needs_human", + "parent_task_id", + "priority", + "record_id", + "status", + "title", + "updated_at", + "wait_until", + "workplan_id" + ], + "row_count": 15, + "rows": [ + { + "sha256": "sha256:89b3be69fbaf5ad60f5aefa6f2b630e1d6124e0fca7b01a5e9ce1ff41a451106", + "uuid": "05d42a55-921f-4aa7-bb76-e8af9c7e0ac3" + }, + { + "sha256": "sha256:3aa20e9695e110468d13baa3c813ac5b474896d89eeb6edc56e9ea00d9199fd7", + "uuid": "08233868-d522-4117-bc4e-6c0f52545665" + }, + { + "sha256": "sha256:72fb54d9a271067a62f33377d56e0bb9e6874a3f9c475b9ae049609b93d1f643", + "uuid": "140da396-8e30-4f4d-b88c-c42c0cd46c01" + }, + { + "sha256": "sha256:15198017e5c7d31b4e8ce1d5c0ef0de99ac1c50d3bffd0ea0ee807bef70ce5d1", + "uuid": "2d5acff7-4a4e-4ddd-ad06-08237ad3dac8" + }, + { + "sha256": "sha256:29a6f1e50db6a7b4ba5b98a2f7d8d109b4df1720fce58777c21f7538084f8cda", + "uuid": "3f042630-eab0-4c6a-9167-e2b28ff20e40" + }, + { + "sha256": "sha256:2e00141f0d7382dd34859b686a500dc740a543efe81e23f5805754cbc6761f2e", + "uuid": "4526a842-ea31-4874-9231-92ab556cfe7b" + }, + { + "sha256": "sha256:7b3ecacb7be3c1a24a100d7b732b7f60e1a99329a6847612264cd01d13c7ecf0", + "uuid": "5c3d40e4-239b-488e-9519-6f7a38d2325f" + }, + { + "sha256": "sha256:71107455d1d453d69d65466ca66da1fd4ee4aa95ecdf7920b9acdce767f0c55c", + "uuid": "6841c93a-f146-47eb-9f7c-8fa0e02c1bbc" + }, + { + "sha256": "sha256:f8e44ea79125870ab3ade44afab8752c126c424e2b751f48b9fe555e00b5b708", + "uuid": "7f9e0e58-a130-467a-a2d0-b3f2564e496f" + }, + { + "sha256": "sha256:435e39ffee3a59eae3b890739a6ed8e06801fb23dead15073653d8650f9d5ff5", + "uuid": "a6313e06-1976-46a7-8e31-df4eb2eca880" + }, + { + "sha256": "sha256:2fcda8440a166fc628f8fadf91a4a23ba7728ccac2e629248c6eccd00d5d4345", + "uuid": "ab166073-30a7-4702-a037-4091e8706e20" + }, + { + "sha256": "sha256:b2e11b8fdc580e6cb7ec20c7e90018ba9fb468893b6eda5b9519dc68737a0ca0", + "uuid": "d8a3ba40-fda0-4c1f-a9f1-ffcd621a5b3d" + }, + { + "sha256": "sha256:788862d9cc5015b927d27303585431a0db4af6077178ab3bfdde37f900cee821", + "uuid": "dab2c07f-8aa0-4635-8df6-857e87e93fc5" + }, + { + "sha256": "sha256:f7bc1f3acf187301430df0623417fb90b6af1869c0383a0bff9ec25f79ffe4af", + "uuid": "e8510646-46ed-4697-a345-f3d3009eea78" + }, + { + "sha256": "sha256:f2760deded2f7136a60fba0156c4956ba373fbcf5eda986f5c380d7ee9c925ff", + "uuid": "f8e4a094-c367-40eb-b895-da17bc144b07" + } + ] + }, + "workplans": { + "all_rows_sha256": "sha256:6e5fc0c243600c76fe855637597c7050a59cd6c0241af2ce5a96099db35682a5", + "columns": [ + "backing_archived", + "backing_filename", + "backing_relative_path", + "backing_synced_at", + "concurrency_mode", + "created_at", + "derived_from_commit", + "description", + "due_date", + "execution_group", + "execution_state", + "flavor", + "flavor_promoted_from", + "flavor_promotion_reason", + "id", + "launch_mode", + "owner", + "planning_order", + "planning_priority", + "projection_retired_at", + "projection_retired_reason", + "queue_rank", + "repo_goal_id", + "repo_id", + "scheduled_for", + "slug", + "status", + "title", + "topic_id", + "updated_at" + ], + "row_count": 3, + "rows": [ + { + "sha256": "sha256:0073dbc05e31666e6bfdfba93e4957b258d099e31c2a4313c6b7c4c2b8f6070b", + "uuid": "4c63dfc6-9eac-4e79-9f77-8f644ad7147d" + }, + { + "sha256": "sha256:d1a042ea89826254bf961233329e5b72e37db0a60c7f2db8c1bd34a1da6bc2af", + "uuid": "7e8b0c20-51eb-40c9-9e3b-85dd380d7625" + }, + { + "sha256": "sha256:6ec93cb522c322cbe3247d77f9e28f39e783e134335fdad77f00fc35bef146da", + "uuid": "7ee9ee22-1fae-4567-9194-8d70a9e0f45b" + } + ] + } + }, + "full_rows_equal_to_pre_rollout": true, + "source": "pre-cluster-publication", + "pod_uid": "77173cfd-14a9-4e30-a26e-08f8a8fbb369" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/progress-receipt.json b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/progress-receipt.json new file mode 100644 index 00000000..b1971504 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/progress-receipt.json @@ -0,0 +1,14 @@ +{ + "workplan_id": "dfadb19b-445e-59c6-bcd6-48e87b912c52", + "id": "e54ff15a-3b54-4a7b-b03f-1a4789a287fe", + "topic_id": null, + "task_id": null, + "decision_id": null, + "event_type": "note", + "summary": "CUST-WP-0080 approved receiver revision4 executed: Helm76 API/MCP exact c802 digest Ready, schema c4d5e6f7a8b9; three full historical workplan and fifteen task rows unchanged, five actual rollback-only receiving probes passed with zero commits. Recovery unnecessary; exact staging removed. Registrar source applied only after verified return; canonical47 checks and Cluster seven-field read-only preview pass. Cluster publication still pending; no native NetKingdom gate closed. Evidence: docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json", + "detail": null, + "author": "codex", + "session_id": null, + "created_at": "2026-10-17T00:10:09.715488Z", + "workstream_id": "dfadb19b-445e-59c6-bcd6-48e87b912c52" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/snapshot_after_publication.py b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/snapshot_after_publication.py new file mode 100644 index 00000000..17cb10fa --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/snapshot_after_publication.py @@ -0,0 +1,24 @@ +from pathlib import Path +import subprocess,json,shlex,hashlib +here=Path(__file__).resolve().parent +pod=json.loads((here/'delivered-runtime.json').read_text())['api_pod'] +prefix=['kubectl','-n','state-hub'] +remote=lambda a:'KUBECONFIG=/etc/rancher/k3s/k3s.yaml '+shlex.join(a) +r=subprocess.run(['ssh','railiance01',remote(prefix+['get','pod',pod['name'],'-o','json'])],capture_output=True,text=True,timeout=30) +assert r.returncode==0,'pod-read-refused';d=json.loads(r.stdout);assert d['metadata']['uid']==pod['uid'] +# Resolve the exact reviewed helper under the sibling dated packet. +f=here.parent.parent/'netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/snapshot_full_row_hashes.py' +assert hashlib.sha256(f.read_bytes()).hexdigest()=='f01e93c0fcb4ca155bdf76813626c33e4343f6a8caec2870ab1d785243c60479' +r=subprocess.run(['ssh','railiance01',remote(prefix+['exec','-i',pod['name'],'-c','state-hub','--','python','-'])],input=f.read_text(),text=True,capture_output=True,timeout=45) +assert r.returncode==0,'private-snapshot-refused';result=json.loads(r.stdout);assert result['status']=='captured_readonly' +before=json.loads((here/'before-full-row-hashes.json').read_text()) +if before['tables']!=result['tables']: + result.update(full_rows_equal_to_pre_rollout=False,source='post-cluster-publication',comparison='failed') + (here/'post-publication-full-row-hashes-FAILED.json').write_text(json.dumps(result,indent=2)+'\n') + for table in ['workplans','tasks']: + old={v['uuid']:v['sha256'] for v in before['tables'][table]['rows']} + print(json.dumps({'table':table,'changed_rows':[v['uuid'] for v in result['tables'][table]['rows'] if old[v['uuid']]!=v['sha256']]})) + raise SystemExit(2) +result.update(full_rows_equal_to_pre_rollout=True,source='post-cluster-publication',pod_uid=pod['uid']) +(here/'post-publication-full-row-hashes.json').write_text(json.dumps(result,indent=2)+'\n') +print(json.dumps({'status':'verified','historical_parents':3,'historical_tasks':15,'all_columns_equal':True})) diff --git a/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/snapshot_current_stage.py b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/snapshot_current_stage.py new file mode 100644 index 00000000..dc2db23d --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/snapshot_current_stage.py @@ -0,0 +1,20 @@ +"""Read-only current-stage hashes; preserve original failed comparison separately.""" +from pathlib import Path +import subprocess,json,shlex,hashlib,argparse,datetime +p=argparse.ArgumentParser();p.add_argument('stage',choices=['before-corrected-client','after-corrected-client','before-verified-client','after-verified-client']);a=p.parse_args() +here=Path(__file__).resolve().parent +pod=json.loads((here/'delivered-runtime.json').read_text())['api_pod'] +def command(argv,input=None): + r=subprocess.run(['ssh','railiance01','KUBECONFIG=/etc/rancher/k3s/k3s.yaml '+shlex.join(argv)],input=input,capture_output=True,text=True,timeout=45) + assert r.returncode==0,'private-owner-read-refused' + return json.loads(r.stdout) +d=command(['kubectl','-n','state-hub','get','pod',pod['name'],'-o','json']);assert d['metadata']['uid']==pod['uid'] +f=here.parent.parent/'netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/snapshot_full_row_hashes.py';assert hashlib.sha256(f.read_bytes()).hexdigest()=='f01e93c0fcb4ca155bdf76813626c33e4343f6a8caec2870ab1d785243c60479' +r=command(['kubectl','-n','state-hub','exec','-i',pod['name'],'-c','state-hub','--','python','-'],f.read_text());assert r['status']=='captured_readonly' +original=json.loads((here/'before-full-row-hashes.json').read_text()) +r.update(stage=a.stage,observed_at=datetime.datetime.now(datetime.timezone.utc).isoformat(),original_full_rows_equal=r['tables']==original['tables'],original_failed_comparison_retained=True,original_preimages_restored=False) +if a.stage.startswith('after-'): + before=json.loads((here/(a.stage.replace('after-','before-',1)+'.json')).read_text());r['current_stage_full_rows_equal']=r['tables']==before['tables'] +(here/(a.stage+'.json')).write_text(json.dumps(r,indent=2)+'\n') +print(json.dumps({'stage':a.stage,'original_full_rows_equal':r['original_full_rows_equal'],'current_stage_full_rows_equal':r.get('current_stage_full_rows_equal')})) +if a.stage.startswith('after-') and not r['current_stage_full_rows_equal']:raise SystemExit(2) diff --git a/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/staging-cleanup.json b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/staging-cleanup.json new file mode 100644 index 00000000..650763a9 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/staging-cleanup.json @@ -0,0 +1,3 @@ +{ + "status": "exact_owned_staging_removed" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json new file mode 100644 index 00000000..afa6e6fd --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-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/receiver-rollout-r4/watch_rollout.py b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/watch_rollout.py new file mode 100644 index 00000000..a02e3c5c --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/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-51bc70d@sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015' +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/registrar-followthrough-r1/PUBLISH-AFTER-RECEIVING.md b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/PUBLISH-AFTER-RECEIVING.md new file mode 100644 index 00000000..bdad5ea8 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/PUBLISH-AFTER-RECEIVING.md @@ -0,0 +1,62 @@ +# Receiver-first registrar source follow-through + +Review preparation only. Current Repo Manager base is +`9ebde0a9bd60d5c82910494fbe6bd1b891455cee`; all seven frozen preimages match and +exact patch `232552c3d601d185984be5a8e5bc9937bc9ddda7327923b5f0440f6deb2c87fc` +applies in check-only mode. Rebuilt isolated candidate checks pass 47/47 on the +current source/config base. No canonical registrar edit or actual Cluster +allocator call occurred here; scanner WP21-T05 completion is untouched. + +1. Root completes the approved receiver rollout and verifies actual delivered + module/image/schema, API/MCP readiness, three historical parents/15 tasks and + rolled-back safe refusal probes. Bind the exact actual native receipts and + their hashes in `receiving-return.json`, using the pending template's known + source/image/schema fields. Pending fields must refuse. This binding records + observations; it grants no authority. Root's explicit go remains required. +2. Root reviews the applier hash in `manifest.json` and invokes + `python3 .../apply_registrar_source.py --execute --gate --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())