Admit reviewed receiver evidence batch 9
This commit is contained in:
parent
33e49e7a26
commit
163aa98d8e
24 changed files with 4477 additions and 0 deletions
|
|
@ -0,0 +1,136 @@
|
|||
{
|
||||
"status": "verified",
|
||||
"scope": "RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots",
|
||||
"writes_to_source_index_refs_or_Hub": false,
|
||||
"rows": [
|
||||
{
|
||||
"repo": "repo-manager",
|
||||
"published_commit": "7c15c0ea48981867fc1683d9b7576f6444c256da",
|
||||
"remote": {
|
||||
"HEAD": "7c15c0ea48981867fc1683d9b7576f6444c256da",
|
||||
"refs/heads/main": "7c15c0ea48981867fc1683d9b7576f6444c256da",
|
||||
"symbolic_HEAD": "refs/heads/main"
|
||||
},
|
||||
"workplan": {
|
||||
"id": "efe0ecb2-2f3f-5f49-baee-b90ad1d353ab",
|
||||
"slug": "rmgr-wp-0019",
|
||||
"status": "active"
|
||||
},
|
||||
"source_record_id": "RMGR-WP-0019",
|
||||
"tasks": [
|
||||
{
|
||||
"id": "d78a622e-39f9-5923-b4e1-f70fdc17fb42",
|
||||
"record_id": "RMGR-WP-0019-T01",
|
||||
"status": "done"
|
||||
},
|
||||
{
|
||||
"id": "95240c81-1805-5365-9b35-d238621a16bf",
|
||||
"record_id": "RMGR-WP-0019-T02",
|
||||
"status": "done"
|
||||
},
|
||||
{
|
||||
"id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d",
|
||||
"record_id": "RMGR-WP-0019-T03",
|
||||
"status": "done"
|
||||
},
|
||||
{
|
||||
"id": "1ccb06c6-ad30-5847-8704-e5628ba81f35",
|
||||
"record_id": "RMGR-WP-0019-T04",
|
||||
"status": "done"
|
||||
},
|
||||
{
|
||||
"id": "36f47e21-42d0-5aef-b065-4a5dd3af0726",
|
||||
"record_id": "RMGR-WP-0019-T05",
|
||||
"status": "done"
|
||||
},
|
||||
{
|
||||
"id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34",
|
||||
"record_id": "RMGR-WP-0019-T06",
|
||||
"status": "wait"
|
||||
}
|
||||
],
|
||||
"external_source_declarations_not_projected": [
|
||||
{
|
||||
"from_task_id": "95240c81-1805-5365-9b35-d238621a16bf",
|
||||
"target_record_id": "STATE-WP-0095-T03",
|
||||
"target_uuid": "e8566341-cf6e-5b9c-ad80-8564d14cd52a"
|
||||
},
|
||||
{
|
||||
"from_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726",
|
||||
"target_record_id": "STATE-WP-0095-T06",
|
||||
"target_uuid": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4"
|
||||
}
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"from_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34",
|
||||
"to_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d",
|
||||
"to_task_id": "95240c81-1805-5365-9b35-d238621a16bf",
|
||||
"relationship_type": "starts_after"
|
||||
}
|
||||
],
|
||||
"source_file_sha256": "4ff763ea24b9948d59b4bdd4f5ef3e95bee72fef3016f0b6404b5db663cb83ff",
|
||||
"source_file_unchanged": true,
|
||||
"dependency_scope": "internal edges verified; external source target identities checked without claiming projected external edges",
|
||||
"index_stat_unchanged": true
|
||||
},
|
||||
{
|
||||
"repo": "repo-manager",
|
||||
"published_commit": "7c15c0ea48981867fc1683d9b7576f6444c256da",
|
||||
"remote": {
|
||||
"HEAD": "7c15c0ea48981867fc1683d9b7576f6444c256da",
|
||||
"refs/heads/main": "7c15c0ea48981867fc1683d9b7576f6444c256da",
|
||||
"symbolic_HEAD": "refs/heads/main"
|
||||
},
|
||||
"workplan": {
|
||||
"id": "5aa6f84a-c682-5996-ae26-96daef670833",
|
||||
"slug": "rmgr-wp-0021",
|
||||
"status": "active"
|
||||
},
|
||||
"source_record_id": "RMGR-WP-0021",
|
||||
"tasks": [
|
||||
{
|
||||
"id": "d3d20c18-5a5f-5f8a-b5c4-a22b4b662ebe",
|
||||
"record_id": "RMGR-WP-0021-T01",
|
||||
"status": "done"
|
||||
},
|
||||
{
|
||||
"id": "e27817e6-b298-581f-b99a-05ec459be749",
|
||||
"record_id": "RMGR-WP-0021-T02",
|
||||
"status": "done"
|
||||
},
|
||||
{
|
||||
"id": "0ab44bd9-00d8-5470-ad45-7350e7868d0a",
|
||||
"record_id": "RMGR-WP-0021-T03",
|
||||
"status": "progress"
|
||||
},
|
||||
{
|
||||
"id": "44272818-db49-58a2-83b1-d2f9e9d5976c",
|
||||
"record_id": "RMGR-WP-0021-T04",
|
||||
"status": "todo"
|
||||
},
|
||||
{
|
||||
"id": "25fbe694-41d8-5232-bce0-4ed362387d5a",
|
||||
"record_id": "RMGR-WP-0021-T05",
|
||||
"status": "done"
|
||||
}
|
||||
],
|
||||
"external_source_declarations_not_projected": [],
|
||||
"dependencies": [],
|
||||
"source_file_sha256": "966d15ccdabc8edf98bc58f9422ea190566d05fe4208f4749f59a9731f4e108d",
|
||||
"source_file_unchanged": true,
|
||||
"dependency_scope": "internal edges verified; external source target identities checked without claiming projected external edges",
|
||||
"index_stat_unchanged": true
|
||||
}
|
||||
],
|
||||
"hub_instance": {
|
||||
"status": "ok",
|
||||
"instance_role": "primary",
|
||||
"instance_label": "railiance01"
|
||||
},
|
||||
"verifier_sha256": "a2b7842c378a2fcaaecfd006d1549f6451f72e260d4b6fb8e193080fcfb7d472"
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"ok": true,
|
||||
"status": "applied",
|
||||
"repo_slug": "repo-manager",
|
||||
"commit": "7c15c0ea48981867fc1683d9b7576f6444c256da",
|
||||
"requests": 2,
|
||||
"elapsed_ms": 10556.3,
|
||||
"git": {
|
||||
"upstream": "origin/main",
|
||||
"behind": 0,
|
||||
"ahead": 0
|
||||
},
|
||||
"identifiers": {
|
||||
"schema": "repo-manager.identifier-assignment.v1",
|
||||
"ok": true,
|
||||
"executed": true,
|
||||
"repo": "repo-manager",
|
||||
"namespace": "helixforge",
|
||||
"assignments": [],
|
||||
"historical_invalid_identifiers": [],
|
||||
"historical_identity_collisions": [],
|
||||
"files_changed": []
|
||||
},
|
||||
"receipt": {
|
||||
"schema": "state-hub.repository-projection-reconcile.v1",
|
||||
"instance_role": "primary",
|
||||
"instance_label": "railiance01",
|
||||
"expected_commit": "7c15c0ea48981867fc1683d9b7576f6444c256da",
|
||||
"derived_commit": "7c15c0ea48981867fc1683d9b7576f6444c256da",
|
||||
"outcome": {
|
||||
"schema": "state-hub.projection-reset.v1",
|
||||
"repo_slug": "repo-manager",
|
||||
"commit": "7c15c0ea48981867fc1683d9b7576f6444c256da",
|
||||
"status": "applied",
|
||||
"counts": {
|
||||
"created": 0,
|
||||
"updated": 25,
|
||||
"retired": 0,
|
||||
"refused": 0,
|
||||
"released": 0,
|
||||
"created_tasks": 0,
|
||||
"updated_tasks": 1,
|
||||
"cancelled_tasks": 0,
|
||||
"created_edges": 0,
|
||||
"removed_edges": 0,
|
||||
"unresolved_edges": 0,
|
||||
"external_edges": 0
|
||||
},
|
||||
"created": [],
|
||||
"updated": [
|
||||
"RMGR-WP-0001",
|
||||
"RMGR-WP-0002",
|
||||
"RMGR-WP-0003",
|
||||
"RMGR-WP-0004",
|
||||
"RMGR-WP-0005",
|
||||
"RMGR-WP-0006",
|
||||
"RMGR-WP-0007",
|
||||
"RMGR-WP-0008",
|
||||
"RMGR-WP-0009",
|
||||
"RMGR-WP-0010",
|
||||
"RMGR-WP-0011",
|
||||
"RMGR-WP-0012",
|
||||
"RMGR-WP-0013",
|
||||
"RMGR-WP-0014",
|
||||
"RMGR-WP-0015",
|
||||
"RMGR-WP-0016",
|
||||
"RMGR-WP-0017",
|
||||
"RMGR-WP-0018",
|
||||
"RMGR-WP-0019",
|
||||
"RMGR-WP-0020",
|
||||
"RMGR-WP-0021",
|
||||
"RMGR-WP-ADHOC-2026-09-06",
|
||||
"RMGR-WP-ADHOC-2026-09-09",
|
||||
"RMGR-WP-ADHOC-2026-09-11",
|
||||
"RMGR-WP-ADHOC-2026-10-03"
|
||||
],
|
||||
"retired": [],
|
||||
"released": [],
|
||||
"created_tasks": [],
|
||||
"updated_tasks": [
|
||||
"RMGR-WP-0019-T06"
|
||||
],
|
||||
"cancelled_tasks": [],
|
||||
"created_edges": [],
|
||||
"removed_edges": [],
|
||||
"unresolved_edges": [],
|
||||
"external_edges": [],
|
||||
"refused": [],
|
||||
"notes": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"status": "prepared-source-only-not-applied",
|
||||
"base_head": "70cd754996870638848616e37819790a5c4d52b3",
|
||||
"owner_path": "workplans/RMGR-WP-0019-historical-source-admission.md",
|
||||
"preimage_sha256": "c09c685313de13ad4a31891fd67b8a92f3d9a085c37cee92257d15b485a32cde",
|
||||
"candidate_sha256": "4ff763ea24b9948d59b4bdd4f5ef3e95bee72fef3016f0b6404b5db663cb83ff",
|
||||
"patch_sha256": "e8af90d6714b0545d8b78fcb43df42a9d9e6056a0491658b30514ab942a7f23e",
|
||||
"task_blocks_and_UUIDs_unchanged": true,
|
||||
"t05": "done",
|
||||
"t06": "wait",
|
||||
"changed_parent_full_hashes": 3,
|
||||
"unchanged_task_full_hashes": 15,
|
||||
"all_18_preserved_after_pipeline": false,
|
||||
"canonical_mutation": false,
|
||||
"receipts": {
|
||||
"railiance-cluster-projection.json": "c92d96f54fe7afcdfdf54fd666ce0f697219e9864d331ccddff41a246179115e",
|
||||
"cluster-publication-readback.json": "d3a6e4db0195416fdadcf94ba21b956ac74ccd23d71a5a4ce577cbe2fe1f923b",
|
||||
"receiver-rollout-r4/verified-receiving-return.json": "d088c336d62c7bdde0e586b0f1b73c3aa3d4031a4debd9ac90206128728257f4",
|
||||
"receiver-rollout-r4/pre-publication-full-row-hashes.json": "bf01a632d7185705bce44b96210f7376e7f94c65cc5b858924eb0bed19c73dfd",
|
||||
"receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json": "ea08b8f5581e6fb335359427a4b24f990bc814b452d3733f7d4174bb1b6ed6df"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
--- a/workplans/RMGR-WP-0019-historical-source-admission.md
|
||||
+++ b/workplans/RMGR-WP-0019-historical-source-admission.md
|
||||
@@ -208,6 +208,34 @@
|
||||
generated indexes. Preserve all three archived files and all 18 existing
|
||||
parent/task rows. Return actual receiving/publication receipts to STATE-WP-0095-T07.
|
||||
Do not infer TLS recovery, credential custody or native acceptance from sync.
|
||||
+
|
||||
+Cluster publication returned, preservation acceptance failed, 2026-10-17:
|
||||
+normal owner publication at c562d7134c38679952a8ffd17a8a893a900aef0d
|
||||
+is applied on primary/railiance01 with expected and derived commits equal.
|
||||
+Read-only source/remote/Hub verification confirms WP0018's five task bindings
|
||||
+and three internal dependency edges. These publication results do not close T06.
|
||||
+The full-row guard after the required legacy deep consistency pass failed:
|
||||
+all three historical parent full-row hashes changed; all 15 historical task
|
||||
+full-row hashes remain equal. The entire pipeline therefore has no successful
|
||||
+18-row preservation acceptance.
|
||||
+
|
||||
+Custodian receipts under docs/changes/netkingdom-target-2026-10-17:
|
||||
+railiance-cluster-projection.json and cluster-publication-readback.json retain
|
||||
+the applied publication and bounded readback; receiver-rollout-r4/
|
||||
+pre-publication-full-row-hashes.json retains the passing pre-publication guard;
|
||||
+receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json retains the
|
||||
+failed native comparison. Exact receipt digests are retained in
|
||||
+registrar-t06-preservation-failure-r1/manifest.json. Coordinator and recovery
|
||||
+source review identified the unguarded PUT /workplans/index/bindings path
|
||||
+writing backing_synced_at and ORM updated_at, outside the native forge
|
||||
+projection's preservation guard. Full baseline rows were not retained, only
|
||||
+full-row hashes; no guessed database restoration is authorized or claimed.
|
||||
+
|
||||
+The original rollout's pre-Cluster preservation/refusal verification remains
|
||||
+valid for that earlier stage, and T05 remains done. T06 stays wait pending
|
||||
+the reviewed exact-frozen binding guard, regression coverage and a verified
|
||||
+recovery/preservation disposition. No source or native gate is promoted by the
|
||||
+successful publication alone; no TLS or credential-custody acceptance follows.
|
||||
|
||||
|
||||
## Receiver-first registrar source follow-through, 2026-10-17
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"status": "published-and-readback-verified",
|
||||
"head": "7c15c0ea48981867fc1683d9b7576f6444c256da",
|
||||
"path_count": 1,
|
||||
"task_blocks_and_UUIDs_unchanged": true,
|
||||
"t05": "done",
|
||||
"t06": "wait",
|
||||
"scanner_unchanged": true,
|
||||
"cluster_or_database_changes": false,
|
||||
"worktree_clean": true,
|
||||
"all_18_historical_rows_preserved_after_cluster_pipeline": false,
|
||||
"readback_verifier_refinement": "R1 retained; unchanged exact T06-to-T05 dependency preserves its known creation commit70cd on description-only sync",
|
||||
"files": {
|
||||
"manifest.json": "5d1989cb40f9206d928d023370bbcbd781b835a8e32925d1ce7e21d21d04a640",
|
||||
"owner-amendment.patch": "e8af90d6714b0545d8b78fcb43df42a9d9e6056a0491658b30514ab942a7f23e",
|
||||
"publish_amendment.py": "8521a46b5daed3e268b0569d69b608e9cefbbd87b5454e19eb6413e421ed89e3",
|
||||
"amendment-commit.json": "fe3fa69da34257ec2f66fd4d659f925c17b0f80caedbb99092b0bade3de17f73",
|
||||
"amendment-sync.json": "9bb18ad3881a3b8cb35595c7ddf92d2908a3c9e8fccde38f64546150174b1ef1",
|
||||
"verify_amendment_publication.py": "a2b7842c378a2fcaaecfd006d1549f6451f72e260d4b6fb8e193080fcfb7d472",
|
||||
"amendment-publication-readback.json": "8c78373a27d448ddb4dbd9374e389df040866a91d5be669ac23c09af8808f213",
|
||||
"r1-verify_amendment_publication.py": "d13131f6f1179d082078e7fe87fec2fabf72e8931fa6a320120623869939e1c4",
|
||||
"r1-amendment-publication-readback.json": "f4a1d44b4d73e4cd18e52295969d655c1519c93b39813eff1997c2dd7334700e"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env python3
|
||||
from pathlib import Path
|
||||
import hashlib,json,subprocess
|
||||
P=Path(__file__).resolve().parent
|
||||
R=Path('/home/worsch/repo-manager')
|
||||
m=json.loads((P/'manifest.json').read_text()); f=R/m['owner_path']
|
||||
def h(p):return hashlib.sha256(p.read_bytes()).hexdigest()
|
||||
def git(*args):
|
||||
r=subprocess.run(['git',*args],cwd=R,text=True,capture_output=True,timeout=180)
|
||||
if r.returncode: raise RuntimeError(json.dumps({'args':args,'stdout':r.stdout,'stderr':r.stderr,'code':r.returncode}))
|
||||
return r.stdout
|
||||
assert git('rev-parse','HEAD').strip()==m['base_head']
|
||||
assert h(f)==m['preimage_sha256']
|
||||
assert h(P/'owner-amendment.patch')==m['patch_sha256']=='e8af90d6714b0545d8b78fcb43df42a9d9e6056a0491658b30514ab942a7f23e'
|
||||
assert h(P/'RMGR-WP-0019.candidate.md')==m['candidate_sha256']
|
||||
assert not git('diff','--cached','--name-only')
|
||||
scanner=R/'src/repo_manager/secret_scan.py'; before=h(scanner)
|
||||
assert before=='e709c658f779534fcab093207b0a78e49d54fc584c515fdf7ac535ce75f6c400'
|
||||
git('apply','--check',str(P/'owner-amendment.patch'))
|
||||
git('apply',str(P/'owner-amendment.patch'))
|
||||
assert h(f)==m['candidate_sha256']
|
||||
git('add','--',m['owner_path'])
|
||||
assert git('diff','--cached','--name-only').splitlines()==[m['owner_path']]
|
||||
git('diff','--cached','--check')
|
||||
output=git('commit','-m','Retain Cluster publication with failed historical row preservation')
|
||||
head=git('rev-parse','HEAD').strip()
|
||||
assert git('diff-tree','--no-commit-id','--name-only','-r',head).splitlines()==[m['owner_path']]
|
||||
assert h(scanner)==before
|
||||
receipt={'status':'committed-exact-one-file','head':head,'parent':m['base_head'],'path':m['owner_path'],'source_sha256':h(f),'scanner_sha256_unchanged':before,'task_blocks_and_UUIDs_unchanged':True,'t05':'done','t06':'wait','commit_output':output,'cluster_or_database_mutation':False}
|
||||
(P/'amendment-commit.json').write_text(json.dumps(receipt,indent=2)+'\n');print(json.dumps(receipt,indent=2))
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"status": "unverified",
|
||||
"scope": "RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots",
|
||||
"writes_to_source_index_refs_or_Hub": false,
|
||||
"rows": [],
|
||||
"hub_instance": {
|
||||
"status": "ok",
|
||||
"instance_role": "primary",
|
||||
"instance_label": "railiance01"
|
||||
},
|
||||
"reason": "dependency-source-commit-mismatch",
|
||||
"verifier_sha256": "d13131f6f1179d082078e7fe87fec2fabf72e8931fa6a320120623869939e1c4"
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Read-only Git+Hub task binding verifier; never syncs or changes source/index."""
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
import urllib.request
|
||||
|
||||
HERE=Path(__file__).resolve().parent
|
||||
OWNERS=[
|
||||
{'repo':'repo-manager','commit':'7c15c0ea48981867fc1683d9b7576f6444c256da','path':'workplans/RMGR-WP-0019-historical-source-admission.md','id':'RMGR-WP-0019','tasks':6},
|
||||
{'repo':'repo-manager','commit':'7c15c0ea48981867fc1683d9b7576f6444c256da','path':'workplans/RMGR-WP-0021-secret-detection-controls.md','id':'RMGR-WP-0021','tasks':5},
|
||||
]
|
||||
API=os.environ.get('API_BASE','http://127.0.0.1:8000').rstrip('/')
|
||||
EXTERNAL={'STATE-WP-0095-T03':'e8566341-cf6e-5b9c-ad80-8564d14cd52a','STATE-WP-0095-T06':'6af973b4-1964-5d4d-a2f8-8dbd4c01fda4','NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'}
|
||||
|
||||
|
||||
class Refused(Exception):pass
|
||||
|
||||
|
||||
def git(root,*args):
|
||||
result=subprocess.run(['git','--no-optional-locks','-C',str(root),*args],
|
||||
capture_output=True,timeout=30,check=False)
|
||||
if result.returncode:raise Refused('read-only-git-failed')
|
||||
return result.stdout
|
||||
|
||||
|
||||
def field(text,key):
|
||||
values=re.findall(r'^'+re.escape(key)+r':\s*(.*?)\s*$',text,re.M)
|
||||
if len(values)!=1:raise Refused('source-field-ambiguous')
|
||||
return values[0].strip('"\'')
|
||||
|
||||
|
||||
def source(text):
|
||||
header=text.split('---',2)[1]
|
||||
tasks=[]
|
||||
for block in re.findall(r'```task\n(.*?)\n```',text,re.S):
|
||||
deps=re.findall(r'^depends_on:\s*\[(.*?)\]',block,re.M)
|
||||
tasks.append({'record_id':field(block,'id'),'id':field(block,'state_hub_task_id'),
|
||||
'status':field(block,'status'),'dependencies':[x.strip() for x in deps[0].split(',') if x.strip()] if deps else []})
|
||||
return {'id':field(header,'state_hub_workstream_id'),'source_record_id':field(header,'id'),
|
||||
'slug':field(header,'id').lower(),
|
||||
'status':field(header,'status'),'tasks':tasks}
|
||||
|
||||
|
||||
def get(path):
|
||||
class NoRedirect(urllib.request.HTTPRedirectHandler):
|
||||
def redirect_request(self,*args,**kwargs):raise Refused('hub-redirect-refused')
|
||||
opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect)
|
||||
with opener.open(urllib.request.Request(API+path,method='GET'),timeout=20) as response:
|
||||
data=response.read(8*1024**2+1)
|
||||
if len(data)>8*1024**2:raise Refused('hub-read-limit')
|
||||
return json.loads(data)
|
||||
|
||||
|
||||
def index_stat(root):
|
||||
raw=git(root,'rev-parse','--git-path','index').decode().strip();path=Path(raw)
|
||||
if not path.is_absolute():path=root/path
|
||||
try:item=path.lstat()
|
||||
except FileNotFoundError:return None
|
||||
return [item.st_dev,item.st_ino,item.st_size,item.st_mtime_ns,item.st_mode]
|
||||
|
||||
|
||||
def remote(root,expected,repo):
|
||||
if git(root,'remote','get-url','origin').decode().strip()!='forgejo-remote:coulomb/'+repo+'.git':
|
||||
raise Refused('remote-route-drift')
|
||||
lines=git(root,'ls-remote','--symref','origin','HEAD','refs/heads/main').decode().splitlines()
|
||||
if set(lines)!={'ref: refs/heads/main\tHEAD',expected+'\tHEAD',expected+'\trefs/heads/main'}:
|
||||
raise Refused('remote-head-mismatch')
|
||||
return {'HEAD':expected,'refs/heads/main':expected,'symbolic_HEAD':'refs/heads/main'}
|
||||
|
||||
|
||||
def verify():
|
||||
result={'status':'unverified','scope':'RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots',
|
||||
'writes_to_source_index_refs_or_Hub':False,'rows':[]}
|
||||
try:
|
||||
if API not in {'http://127.0.0.1:8000','http://127.0.0.1:18080','http://10.43.68.154:8000'}:
|
||||
raise Refused('unrecognized-hub-endpoint')
|
||||
health=get('/state/health')
|
||||
result['hub_instance']={key:health.get(key) for key in ('status','instance_role','instance_label')}
|
||||
if result['hub_instance']!={'status':'ok','instance_role':'primary','instance_label':'railiance01'}:
|
||||
raise Refused('hub-identity-mismatch')
|
||||
for owner in OWNERS:
|
||||
root=Path('/home/worsch')/owner['repo'];before_index=index_stat(root)
|
||||
if git(root,'rev-parse','HEAD').decode().strip()!=owner['commit']:
|
||||
raise Refused('local-head-drift')
|
||||
committed=git(root,'show',owner['commit']+':'+owner['path'])
|
||||
local=(root/owner['path']).read_bytes()
|
||||
if local!=committed:raise Refused('published-workplan-local-drift')
|
||||
expected=source(committed.decode())
|
||||
if expected['source_record_id']!=owner['id'] or len(expected['tasks'])!=owner['tasks']:
|
||||
raise Refused('source-task-denominator-mismatch')
|
||||
snapshot=get('/repos/'+owner['repo']+'/work-record-projection/snapshot')
|
||||
plans=[row for row in snapshot['workplans'] if row['id']==expected['id']]
|
||||
if len(plans)!=1 or any(plans[0].get(key)!=expected[key] for key in ('id','slug','status')):
|
||||
raise Refused('workplan-binding-mismatch')
|
||||
projected=[row for row in snapshot['tasks']
|
||||
if row.get('workplan_id',row.get('workstream_id'))==expected['id']]
|
||||
if len(projected)!=len(expected['tasks']):raise Refused('projected-task-denominator-mismatch')
|
||||
byid={row['id']:row for row in projected}
|
||||
if len(byid)!=len(projected):raise Refused('duplicate-projected-uuid')
|
||||
observed=[]
|
||||
for task in expected['tasks']:
|
||||
row=byid.get(task['id'],{})
|
||||
if any(row.get(key)!=task[key] for key in ('id','record_id','status')):
|
||||
raise Refused('task-id-uuid-status-mismatch')
|
||||
observed.append({key:row[key] for key in ('id','record_id','status')})
|
||||
identifiers={task['record_id']:task['id'] for task in expected['tasks']}
|
||||
edges={(task['id'],identifiers[dep],'starts_after') for task in expected['tasks'] for dep in task['dependencies'] if dep in identifiers}
|
||||
actual=[edge for edge in snapshot['dependencies'] if edge['from_workplan_id']==expected['id']]
|
||||
projected_edges={(edge.get('from_task_id'),edge.get('to_task_id'),edge['relationship_type']) for edge in actual}
|
||||
if len(actual)!=len(edges) or projected_edges!=edges:
|
||||
raise Refused('dependency-binding-mismatch')
|
||||
if any(edge.get('source_commit') not in (None,owner['commit']) for edge in actual):
|
||||
raise Refused('dependency-source-commit-mismatch')
|
||||
for task in expected['tasks']:
|
||||
for dep in task['dependencies']:
|
||||
if dep in EXTERNAL:
|
||||
target=get('/tasks/'+EXTERNAL[dep])
|
||||
if target.get('id')!=EXTERNAL[dep] or target.get('record_id')!=dep:
|
||||
raise Refused('external-dependency-target-mismatch')
|
||||
remote_readback=remote(root,owner['commit'],owner['repo'])
|
||||
if index_stat(root)!=before_index or (root/owner['path']).read_bytes()!=local:
|
||||
raise Refused('source-or-index-stat-changed')
|
||||
result['rows'].append({'repo':owner['repo'],'published_commit':owner['commit'],
|
||||
'remote':remote_readback,'workplan':{key:plans[0][key] for key in ('id','slug','status')},
|
||||
'source_record_id':expected['source_record_id'],
|
||||
'tasks':observed,'external_source_declarations_not_projected':[{'from_task_id':task['id'],'target_record_id':dep,'target_uuid':EXTERNAL[dep]} for task in expected['tasks'] for dep in task['dependencies'] if dep in EXTERNAL],'dependencies':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(edges)],
|
||||
'source_file_sha256':hashlib.sha256(local).hexdigest(),'source_file_unchanged':True,'dependency_scope':'internal edges verified; external source target identities checked without claiming projected external edges',
|
||||
'index_stat_unchanged':True})
|
||||
result['status']='verified'
|
||||
except Exception as error:
|
||||
result['reason']=error.args[0] if isinstance(error,Refused) else 'readback-unavailable'
|
||||
result['verifier_sha256']=hashlib.sha256(Path(__file__).read_bytes()).hexdigest()
|
||||
(HERE/'amendment-publication-readback.json').write_text(json.dumps(result,indent=2)+'\n')
|
||||
print(json.dumps({'status':result['status'],'owners':len(result['rows'])}))
|
||||
return 0 if result['status']=='verified' else 2
|
||||
|
||||
|
||||
if __name__=='__main__':raise SystemExit(verify())
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Read-only Git+Hub task binding verifier; never syncs or changes source/index."""
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
import urllib.request
|
||||
|
||||
HERE=Path(__file__).resolve().parent
|
||||
OWNERS=[
|
||||
{'repo':'repo-manager','commit':'7c15c0ea48981867fc1683d9b7576f6444c256da','path':'workplans/RMGR-WP-0019-historical-source-admission.md','id':'RMGR-WP-0019','tasks':6},
|
||||
{'repo':'repo-manager','commit':'7c15c0ea48981867fc1683d9b7576f6444c256da','path':'workplans/RMGR-WP-0021-secret-detection-controls.md','id':'RMGR-WP-0021','tasks':5},
|
||||
]
|
||||
API=os.environ.get('API_BASE','http://127.0.0.1:8000').rstrip('/')
|
||||
EXTERNAL={'STATE-WP-0095-T03':'e8566341-cf6e-5b9c-ad80-8564d14cd52a','STATE-WP-0095-T06':'6af973b4-1964-5d4d-a2f8-8dbd4c01fda4','NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'}
|
||||
|
||||
|
||||
class Refused(Exception):pass
|
||||
|
||||
|
||||
def git(root,*args):
|
||||
result=subprocess.run(['git','--no-optional-locks','-C',str(root),*args],
|
||||
capture_output=True,timeout=30,check=False)
|
||||
if result.returncode:raise Refused('read-only-git-failed')
|
||||
return result.stdout
|
||||
|
||||
|
||||
def field(text,key):
|
||||
values=re.findall(r'^'+re.escape(key)+r':\s*(.*?)\s*$',text,re.M)
|
||||
if len(values)!=1:raise Refused('source-field-ambiguous')
|
||||
return values[0].strip('"\'')
|
||||
|
||||
|
||||
def source(text):
|
||||
header=text.split('---',2)[1]
|
||||
tasks=[]
|
||||
for block in re.findall(r'```task\n(.*?)\n```',text,re.S):
|
||||
deps=re.findall(r'^depends_on:\s*\[(.*?)\]',block,re.M)
|
||||
tasks.append({'record_id':field(block,'id'),'id':field(block,'state_hub_task_id'),
|
||||
'status':field(block,'status'),'dependencies':[x.strip() for x in deps[0].split(',') if x.strip()] if deps else []})
|
||||
return {'id':field(header,'state_hub_workstream_id'),'source_record_id':field(header,'id'),
|
||||
'slug':field(header,'id').lower(),
|
||||
'status':field(header,'status'),'tasks':tasks}
|
||||
|
||||
|
||||
def get(path):
|
||||
class NoRedirect(urllib.request.HTTPRedirectHandler):
|
||||
def redirect_request(self,*args,**kwargs):raise Refused('hub-redirect-refused')
|
||||
opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect)
|
||||
with opener.open(urllib.request.Request(API+path,method='GET'),timeout=20) as response:
|
||||
data=response.read(8*1024**2+1)
|
||||
if len(data)>8*1024**2:raise Refused('hub-read-limit')
|
||||
return json.loads(data)
|
||||
|
||||
|
||||
def index_stat(root):
|
||||
raw=git(root,'rev-parse','--git-path','index').decode().strip();path=Path(raw)
|
||||
if not path.is_absolute():path=root/path
|
||||
try:item=path.lstat()
|
||||
except FileNotFoundError:return None
|
||||
return [item.st_dev,item.st_ino,item.st_size,item.st_mtime_ns,item.st_mode]
|
||||
|
||||
|
||||
def remote(root,expected,repo):
|
||||
if git(root,'remote','get-url','origin').decode().strip()!='forgejo-remote:coulomb/'+repo+'.git':
|
||||
raise Refused('remote-route-drift')
|
||||
lines=git(root,'ls-remote','--symref','origin','HEAD','refs/heads/main').decode().splitlines()
|
||||
if set(lines)!={'ref: refs/heads/main\tHEAD',expected+'\tHEAD',expected+'\trefs/heads/main'}:
|
||||
raise Refused('remote-head-mismatch')
|
||||
return {'HEAD':expected,'refs/heads/main':expected,'symbolic_HEAD':'refs/heads/main'}
|
||||
|
||||
|
||||
def verify():
|
||||
result={'status':'unverified','scope':'RepoManager registrar WP19 and preserved scanner WP21; read-only Git ls-remote and Hub GET snapshots',
|
||||
'writes_to_source_index_refs_or_Hub':False,'rows':[]}
|
||||
try:
|
||||
if API not in {'http://127.0.0.1:8000','http://127.0.0.1:18080','http://10.43.68.154:8000'}:
|
||||
raise Refused('unrecognized-hub-endpoint')
|
||||
health=get('/state/health')
|
||||
result['hub_instance']={key:health.get(key) for key in ('status','instance_role','instance_label')}
|
||||
if result['hub_instance']!={'status':'ok','instance_role':'primary','instance_label':'railiance01'}:
|
||||
raise Refused('hub-identity-mismatch')
|
||||
for owner in OWNERS:
|
||||
root=Path('/home/worsch')/owner['repo'];before_index=index_stat(root)
|
||||
if git(root,'rev-parse','HEAD').decode().strip()!=owner['commit']:
|
||||
raise Refused('local-head-drift')
|
||||
committed=git(root,'show',owner['commit']+':'+owner['path'])
|
||||
local=(root/owner['path']).read_bytes()
|
||||
if local!=committed:raise Refused('published-workplan-local-drift')
|
||||
expected=source(committed.decode())
|
||||
if expected['source_record_id']!=owner['id'] or len(expected['tasks'])!=owner['tasks']:
|
||||
raise Refused('source-task-denominator-mismatch')
|
||||
snapshot=get('/repos/'+owner['repo']+'/work-record-projection/snapshot')
|
||||
plans=[row for row in snapshot['workplans'] if row['id']==expected['id']]
|
||||
if len(plans)!=1 or any(plans[0].get(key)!=expected[key] for key in ('id','slug','status')):
|
||||
raise Refused('workplan-binding-mismatch')
|
||||
projected=[row for row in snapshot['tasks']
|
||||
if row.get('workplan_id',row.get('workstream_id'))==expected['id']]
|
||||
if len(projected)!=len(expected['tasks']):raise Refused('projected-task-denominator-mismatch')
|
||||
byid={row['id']:row for row in projected}
|
||||
if len(byid)!=len(projected):raise Refused('duplicate-projected-uuid')
|
||||
observed=[]
|
||||
for task in expected['tasks']:
|
||||
row=byid.get(task['id'],{})
|
||||
if any(row.get(key)!=task[key] for key in ('id','record_id','status')):
|
||||
raise Refused('task-id-uuid-status-mismatch')
|
||||
observed.append({key:row[key] for key in ('id','record_id','status')})
|
||||
identifiers={task['record_id']:task['id'] for task in expected['tasks']}
|
||||
edges={(task['id'],identifiers[dep],'starts_after') for task in expected['tasks'] for dep in task['dependencies'] if dep in identifiers}
|
||||
actual=[edge for edge in snapshot['dependencies'] if edge['from_workplan_id']==expected['id']]
|
||||
projected_edges={(edge.get('from_task_id'),edge.get('to_task_id'),edge['relationship_type']) for edge in actual}
|
||||
if len(actual)!=len(edges) or projected_edges!=edges:
|
||||
raise Refused('dependency-binding-mismatch')
|
||||
# An unchanged edge retains its original forge creation commit on description-only sync.
|
||||
def valid_edge_commit(edge):
|
||||
if edge.get('source_commit') in (None,owner['commit']):return True
|
||||
return (owner['id']=='RMGR-WP-0019' and
|
||||
edge.get('from_task_id')=='4d1675b6-f49f-5b01-8d76-bbf2030d1b34' and
|
||||
edge.get('to_task_id')=='36f47e21-42d0-5aef-b065-4a5dd3af0726' and
|
||||
edge.get('source_owner')=='forge:repo-manager' and
|
||||
edge.get('source_commit')=='70cd754996870638848616e37819790a5c4d52b3')
|
||||
if any(not valid_edge_commit(edge) for edge in actual):
|
||||
raise Refused('dependency-source-commit-mismatch')
|
||||
for task in expected['tasks']:
|
||||
for dep in task['dependencies']:
|
||||
if dep in EXTERNAL:
|
||||
target=get('/tasks/'+EXTERNAL[dep])
|
||||
if target.get('id')!=EXTERNAL[dep] or target.get('record_id')!=dep:
|
||||
raise Refused('external-dependency-target-mismatch')
|
||||
remote_readback=remote(root,owner['commit'],owner['repo'])
|
||||
if index_stat(root)!=before_index or (root/owner['path']).read_bytes()!=local:
|
||||
raise Refused('source-or-index-stat-changed')
|
||||
result['rows'].append({'repo':owner['repo'],'published_commit':owner['commit'],
|
||||
'remote':remote_readback,'workplan':{key:plans[0][key] for key in ('id','slug','status')},
|
||||
'source_record_id':expected['source_record_id'],
|
||||
'tasks':observed,'external_source_declarations_not_projected':[{'from_task_id':task['id'],'target_record_id':dep,'target_uuid':EXTERNAL[dep]} for task in expected['tasks'] for dep in task['dependencies'] if dep in EXTERNAL],'dependencies':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(edges)],
|
||||
'source_file_sha256':hashlib.sha256(local).hexdigest(),'source_file_unchanged':True,'dependency_scope':'internal edges verified; external source target identities checked without claiming projected external edges',
|
||||
'index_stat_unchanged':True})
|
||||
result['status']='verified'
|
||||
except Exception as error:
|
||||
result['reason']=error.args[0] if isinstance(error,Refused) else 'readback-unavailable'
|
||||
result['verifier_sha256']=hashlib.sha256(Path(__file__).read_bytes()).hexdigest()
|
||||
(HERE/'amendment-publication-readback.json').write_text(json.dumps(result,indent=2)+'\n')
|
||||
print(json.dumps({'status':result['status'],'owners':len(result['rows'])}))
|
||||
return 0 if result['status']=='verified' else 2
|
||||
|
||||
|
||||
if __name__=='__main__':raise SystemExit(verify())
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
{
|
||||
"status": "commit-refused",
|
||||
"head": "f8c7dfa2a9c7919879b62c77eb39582b3e23654e",
|
||||
"exit_code": 1,
|
||||
"paths": [
|
||||
".kaizen/agents/custodian-codex/supervision.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/conditional-T07-completion-overlay.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/state-hub-followthrough.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r1/validation.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/conditional-T07-completion-overlay.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/generated-copy-exact-diff.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/state-hub-followthrough.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r2/validation.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/REVIEW.md",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/state-hub-followthrough.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r3/validation.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/REVIEW.md",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/state-hub-followthrough.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r4/validation.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/PUBLICATION.md",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/REVIEW.md",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/STATE95-final-reviewed-overlay.md",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/T09-completion-overlay.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/apply_reviewed_overlay.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/canonical-validation.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/integrate_source.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/local-integration-result.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/publication-manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/publish_followthrough_source.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/run_source_commit.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-commit-result.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-publication-readback.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/state-hub-followthrough.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/test_publication_helper.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/validation.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/integrate_source.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/local-integration-result.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/normal-sync-result.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/run_normal_sync.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/run_source_commit.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-commit-result.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-publication-readback.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/state-hub-writeback.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/validation.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/normal-sync-result.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/publish_workplan.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/run_normal_sync.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-commit-result.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-publication-readback.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/state-hub-workplan.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/validation.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/README.md",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/api-baseline-receipt.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/compare_snapshots.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/native_rollback_refusal_probes.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/private-published-source-payload-receipt.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/postdeployment-verifier-r1/snapshot_full_row_hashes.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/WP18.candidate.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/WP18.preimage.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/apply_forward_correction.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/brief.committed-preimage.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/brief.forward-restore.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/execution-plan.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/execution-start.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-commit.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-publication-readback.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction-sync.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/forward-correction.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/publication-final-manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-forward-correction-r1/verify_forward_publication.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/cluster-publication-readback.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-consistency.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-projection.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/e9bc-reviewed-manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/intermediate-review.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-final-review.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-reviewed-manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/r5-test-independent-review.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/frozen-binding-independent-review-r1/test_independent_review.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-image-a25b62f-inspection.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-image-c103cbf-inspection.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/FINAL-PROPOSAL.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/RECOVERY.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/exact-server-dryrun.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/fresh-readonly-preflight.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/native_binding_probes.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/pending-decision.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/probe-helper-preparation-check.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/proposal-metadata.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/reuse_values_dryrun.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/watch_rollout.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/inspect_guard_image.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/local-cli-refresh-r1.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/publish_cluster_after_receiver.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/r1-rollout-owner-bindings-failure.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/r1-verify_rollout_owner_bindings.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/railiance-cluster-commit.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/railiance-cluster-consistency.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/railiance-cluster-projection.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-corrected-client.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-full-row-hashes.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-verified-client.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/approval-decision.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-corrected-client.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-full-row-hashes.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-verified-client.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/delivered-runtime.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/exact-dryrun.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/execution.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/final-runtime-check.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/final_runtime_check.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/fresh-preflight.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/frozen-archives-after-publication.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/helm-return.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/helm-start.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/job-observation.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/native-refusal-probes.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/ordinary-pipeline-preservation-finding.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/pipeline-failure-progress.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/post-publication-full-row-hashes-FAILED.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/pre-publication-full-row-hashes.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/progress-receipt.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/snapshot_after_publication.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/snapshot_current_stage.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/staging-cleanup.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/verified-receiving-return.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/watch_rollout.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/PUBLISH-AFTER-RECEIVING.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.conditional-completion.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.verified-completion.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/RMGR-WP-0019.wait.preimage.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/T05-conditional-completion.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/actual-cluster-allocator-preview.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/apply_registrar_source.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/canonical-test-confirmation.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/isolated-47-tests.txt",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/own-managed-application.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/own-managed-preview.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/publication-final-manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/publish_registrar.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/r1-registrar-publication-readback.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/r1-verify_registrar_publication.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/receiving-return.pending-template.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-commit.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-publication-readback.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/registrar-sync.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/source-application.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/source-review.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/verify_registrar_publication.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-followthrough-r1/wp19-actual-projected-dependencies.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/WP19.candidate.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/WP19.preimage.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-commit.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-publication-readback.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/amendment-sync.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/owner-amendment.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/publication-final-manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/publish_amendment.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/r1-amendment-publication-readback.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/r1-verify_amendment_publication.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-current-client-r1/verify_amendment_publication.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/RMGR-WP-0019.candidate.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/RMGR-WP-0019.preimage.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-commit.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-publication-readback.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/amendment-sync.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/owner-amendment.patch",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/publication-final-manifest.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/publish_amendment.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/r1-amendment-publication-readback.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/r1-verify_amendment_publication.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/registrar-t06-preservation-failure-r1/verify_amendment_publication.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/rollout-coordination-receipts.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/rollout-owner-bindings.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/sync_cluster_after_binding_guard.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/sync_cluster_with_verified_cli.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-consistency.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-projection.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/verified-loaded-client.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/verify_cluster_publication.py",
|
||||
"docs/changes/netkingdom-target-2026-10-17/verify_rollout_owner_bindings.py",
|
||||
"docs/netkingdom-target-implementation.md",
|
||||
"workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md",
|
||||
"docs/changes/netkingdom-target-2026-10-17/rollout-publication-inputs.json"
|
||||
],
|
||||
"stdout": "",
|
||||
"stderr": "{\"blocked_blob_ids\": [\"14ac31e924f280aa71dc14561d2b9014b743e6d6\", \"3e5339e79feb064f9cd1fb289970cf115eb53eee\", \"465af4282960c0dfd2ce36fce5d7cb27d26f486a\", \"cca84d470ed2de1a1a24142321d81c4ef042bba1\", \"e14b161ed327caa2f87f0d4034cedb32eb5cf607\", \"fa6b647e4a550d4f626fc09605dcc6fecc4f1f0b\"], \"scanned_blobs\": 187, \"scanner_sha256\": \"88f91962aa2f93ac6ab281d553b9e125f5197bbbce38f9f2437f7299c32e5509\", \"scanner_version\": \"8.30.1\", \"scope\": \"changed-staged-blobs\", \"status\": \"blocked\"}\n",
|
||||
"unrelated_work_preserved": true
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
"schema": "custodian.owner-wait-receipts.v1",
|
||||
"receipts": [
|
||||
{
|
||||
"case_id": "cluster-frozen-receiver-before-registrar-r1",
|
||||
"state": "satisfied",
|
||||
"id": "6703f61b-9209-427b-9f08-dc910186dbc3",
|
||||
"detail": {
|
||||
"scenario_type": "project_driver",
|
||||
"case_id": "cluster-frozen-receiver-before-registrar-r1",
|
||||
"driver_repo": "prj-state-hub-retirement",
|
||||
"driver_workplan_id": "SHR-WP-0001",
|
||||
"beneficiary_workplan_id": "RMGR-WP-0019",
|
||||
"beneficiary_task_id": "RMGR-WP-0019-T05",
|
||||
"obligor_workplan_id": "STATE-WP-0095",
|
||||
"obligor_task_id": "STATE-WP-0095-T06",
|
||||
"flavor": "implementation",
|
||||
"state": "satisfied",
|
||||
"reason": "Approved receiver T06 delivered/verified and registrar T05 published; later ordinary-pipeline failure remains a separate stopped successor case.",
|
||||
"indirect_beneficiaries": [
|
||||
"RCLUSTER-WP-0018",
|
||||
"NK-WP-0049-T35"
|
||||
],
|
||||
"next_action": "Retain original passing and failed stage receipts; no worker wake.",
|
||||
"runtime_worker_injection_enabled": false,
|
||||
"human_gate_never_woken": true,
|
||||
"observer": "codex",
|
||||
"native_acceptance": false
|
||||
},
|
||||
"central_publication": true
|
||||
},
|
||||
{
|
||||
"case_id": "nk49-t35-rcluster18",
|
||||
"state": "waiting",
|
||||
"id": "a2e5ed16-0da0-4ab9-bc0a-d82bd0a393f1",
|
||||
"detail": {
|
||||
"scenario_type": "cross_owner_wait",
|
||||
"case_id": "nk49-t35-rcluster18",
|
||||
"obligor_workplan_id": "RCLUSTER-WP-0018",
|
||||
"obligor_task_id": "RCLUSTER-WP-0018-T02",
|
||||
"beneficiary_workplan_id": "NK-WP-0049",
|
||||
"beneficiary_task_id": "NK-WP-0049-T35",
|
||||
"flavor": "implementation",
|
||||
"state": "waiting",
|
||||
"reason": "Cluster WP18 published and verified with five tasks; T02 still requires exact independent original TLS artifact/provider/custody metadata. Publication and current-baseline maintenance proof give no TLS/native assent.",
|
||||
"coordination_context": "CUST-WP-0080",
|
||||
"runtime_worker_injection_enabled": false,
|
||||
"human_gate_never_woken": true,
|
||||
"observer": "codex",
|
||||
"native_acceptance": false
|
||||
},
|
||||
"central_publication": true
|
||||
},
|
||||
{
|
||||
"case_id": "cluster-frozen-binding-guard-successor-r1",
|
||||
"state": "stopped",
|
||||
"id": "dba5dec5-d000-4ca0-af31-68990a0221bb",
|
||||
"detail": {
|
||||
"scenario_type": "project_driver",
|
||||
"case_id": "cluster-frozen-binding-guard-successor-r1",
|
||||
"driver_repo": "prj-state-hub-retirement",
|
||||
"driver_workplan_id": "SHR-WP-0001",
|
||||
"beneficiary_workplan_id": "RMGR-WP-0019",
|
||||
"beneficiary_task_id": "RMGR-WP-0019-T06",
|
||||
"obligor_workplan_id": "STATE-WP-0095",
|
||||
"obligor_task_id": "STATE-WP-0095-T10",
|
||||
"flavor": "implementation",
|
||||
"state": "stopped",
|
||||
"reason": "Human gate: exact new API guard rollout and current-baseline/historical-exception disposition pending founder decision df703266-6719-4c04-ae1b-ba9afd3bca1c. Source/local installed client proof passed; API runtime not delivered.",
|
||||
"next_action": "Founder review of guard-successor-review-r1/FINAL-PROPOSAL.md; no worker wake or implicit reuse of receiver revision4 approval.",
|
||||
"coordination_context": "CUST-WP-0080",
|
||||
"runtime_worker_injection_enabled": false,
|
||||
"human_gate_never_woken": true,
|
||||
"observer": "codex",
|
||||
"native_acceptance": false
|
||||
},
|
||||
"central_publication": true
|
||||
}
|
||||
],
|
||||
"new_drivers_or_worker_injection": false
|
||||
}
|
||||
|
|
@ -0,0 +1,305 @@
|
|||
{
|
||||
"schema": "custodian.rollout-owner-bindings.v1",
|
||||
"status": "verified",
|
||||
"primary": "primary/railiance01",
|
||||
"task_bindings": 26,
|
||||
"rows": [
|
||||
{
|
||||
"repo": "state-hub",
|
||||
"workplan_id": "STATE-WP-0095",
|
||||
"commit": "4c03c9d2c6a47f5c7247473f74b2e2f188b787bd",
|
||||
"remote_exact": true,
|
||||
"source_sha256": "163acbdf8252f37e309f4cb0b51d48706c6bd43d439fdbf7802b953b78ae35ac",
|
||||
"status": "active",
|
||||
"tasks": [
|
||||
{
|
||||
"id": "2dd9b04f-2250-5a8a-b5bc-c8a009872858",
|
||||
"record_id": "STATE-WP-0095-T08",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "339b9a37-181c-5599-9a89-0393e199bd4b",
|
||||
"record_id": "STATE-WP-0095-T05",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "3bbb311f-194e-5862-8aed-358a580f22b4",
|
||||
"record_id": "STATE-WP-0095-T04",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "6a5f87bb-e63d-5e20-b9fc-c1b5cd403ff7",
|
||||
"record_id": "STATE-WP-0095-T01",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4",
|
||||
"record_id": "STATE-WP-0095-T06",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "88585c69-d9b9-5e1f-a256-6416ff71e824",
|
||||
"record_id": "STATE-WP-0095-T10",
|
||||
"status": "wait",
|
||||
"needs_human": true
|
||||
},
|
||||
{
|
||||
"id": "8be8f13b-6352-5295-9755-de6fbfb13593",
|
||||
"record_id": "STATE-WP-0095-T09",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "cfd1ea99-e75b-542e-a434-acefb62f3c7d",
|
||||
"record_id": "STATE-WP-0095-T07",
|
||||
"status": "wait",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "e8566341-cf6e-5b9c-ad80-8564d14cd52a",
|
||||
"record_id": "STATE-WP-0095-T03",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "ebb24194-e4cc-5130-aaa6-663f2ea2c822",
|
||||
"record_id": "STATE-WP-0095-T02",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
}
|
||||
],
|
||||
"projected_edges": [
|
||||
{
|
||||
"from_task_id": "88585c69-d9b9-5e1f-a256-6416ff71e824",
|
||||
"to_task_id": "8be8f13b-6352-5295-9755-de6fbfb13593",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "cfd1ea99-e75b-542e-a434-acefb62f3c7d",
|
||||
"to_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "cfd1ea99-e75b-542e-a434-acefb62f3c7d",
|
||||
"to_task_id": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "cfd1ea99-e75b-542e-a434-acefb62f3c7d",
|
||||
"to_task_id": "88585c69-d9b9-5e1f-a256-6416ff71e824",
|
||||
"relationship_type": "starts_after"
|
||||
}
|
||||
],
|
||||
"unprojected_source_declarations": [
|
||||
{
|
||||
"from_task_id": "3bbb311f-194e-5862-8aed-358a580f22b4",
|
||||
"to_task_id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "3bbb311f-194e-5862-8aed-358a580f22b4",
|
||||
"to_task_id": "e8566341-cf6e-5b9c-ad80-8564d14cd52a",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4",
|
||||
"to_task_id": "339b9a37-181c-5599-9a89-0393e199bd4b",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "8be8f13b-6352-5295-9755-de6fbfb13593",
|
||||
"to_task_id": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "e8566341-cf6e-5b9c-ad80-8564d14cd52a",
|
||||
"to_task_id": "ebb24194-e4cc-5130-aaa6-663f2ea2c822",
|
||||
"relationship_type": "starts_after"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "repo-manager",
|
||||
"workplan_id": "RMGR-WP-0019",
|
||||
"commit": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd",
|
||||
"remote_exact": true,
|
||||
"source_sha256": "3c28ff7809a56a2096f58986f1b3d7e6f99d365d42d0e8a97ee786ae7d067cc1",
|
||||
"status": "active",
|
||||
"tasks": [
|
||||
{
|
||||
"id": "1ccb06c6-ad30-5847-8704-e5628ba81f35",
|
||||
"record_id": "RMGR-WP-0019-T04",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "36f47e21-42d0-5aef-b065-4a5dd3af0726",
|
||||
"record_id": "RMGR-WP-0019-T05",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34",
|
||||
"record_id": "RMGR-WP-0019-T06",
|
||||
"status": "wait",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d",
|
||||
"record_id": "RMGR-WP-0019-T03",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "95240c81-1805-5365-9b35-d238621a16bf",
|
||||
"record_id": "RMGR-WP-0019-T02",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "d78a622e-39f9-5923-b4e1-f70fdc17fb42",
|
||||
"record_id": "RMGR-WP-0019-T01",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
}
|
||||
],
|
||||
"projected_edges": [
|
||||
{
|
||||
"from_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34",
|
||||
"to_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "4d1675b6-f49f-5b01-8d76-bbf2030d1b34",
|
||||
"to_task_id": "88585c69-d9b9-5e1f-a256-6416ff71e824",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "682eea14-a4a8-5f33-9a9f-8f2f1ac8288d",
|
||||
"to_task_id": "95240c81-1805-5365-9b35-d238621a16bf",
|
||||
"relationship_type": "starts_after"
|
||||
}
|
||||
],
|
||||
"unprojected_source_declarations": [
|
||||
{
|
||||
"from_task_id": "36f47e21-42d0-5aef-b065-4a5dd3af0726",
|
||||
"to_task_id": "6af973b4-1964-5d4d-a2f8-8dbd4c01fda4",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "95240c81-1805-5365-9b35-d238621a16bf",
|
||||
"to_task_id": "e8566341-cf6e-5b9c-ad80-8564d14cd52a",
|
||||
"relationship_type": "starts_after"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"repo": "repo-manager",
|
||||
"workplan_id": "RMGR-WP-0021",
|
||||
"commit": "1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd",
|
||||
"remote_exact": true,
|
||||
"source_sha256": "966d15ccdabc8edf98bc58f9422ea190566d05fe4208f4749f59a9731f4e108d",
|
||||
"status": "active",
|
||||
"tasks": [
|
||||
{
|
||||
"id": "0ab44bd9-00d8-5470-ad45-7350e7868d0a",
|
||||
"record_id": "RMGR-WP-0021-T03",
|
||||
"status": "progress",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "25fbe694-41d8-5232-bce0-4ed362387d5a",
|
||||
"record_id": "RMGR-WP-0021-T05",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "44272818-db49-58a2-83b1-d2f9e9d5976c",
|
||||
"record_id": "RMGR-WP-0021-T04",
|
||||
"status": "todo",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "d3d20c18-5a5f-5f8a-b5c4-a22b4b662ebe",
|
||||
"record_id": "RMGR-WP-0021-T01",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "e27817e6-b298-581f-b99a-05ec459be749",
|
||||
"record_id": "RMGR-WP-0021-T02",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
}
|
||||
],
|
||||
"projected_edges": [],
|
||||
"unprojected_source_declarations": []
|
||||
},
|
||||
{
|
||||
"repo": "railiance-cluster",
|
||||
"workplan_id": "RCLUSTER-WP-0018",
|
||||
"commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6",
|
||||
"remote_exact": true,
|
||||
"source_sha256": "96d52b6dbae056399159632d50b32ccc6662e4f6d3677af154f7c8a3d618334b",
|
||||
"status": "active",
|
||||
"tasks": [
|
||||
{
|
||||
"id": "021b07bb-65bc-5743-bac5-4294b4be74f6",
|
||||
"record_id": "RCLUSTER-WP-0018-T04",
|
||||
"status": "wait",
|
||||
"needs_human": true
|
||||
},
|
||||
{
|
||||
"id": "5bc67a22-0991-5625-86a6-f749560d8a0e",
|
||||
"record_id": "RCLUSTER-WP-0018-T05",
|
||||
"status": "todo",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a",
|
||||
"record_id": "RCLUSTER-WP-0018-T03",
|
||||
"status": "wait",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "7280193d-0d59-5b78-a2d3-96ebd127127f",
|
||||
"record_id": "RCLUSTER-WP-0018-T01",
|
||||
"status": "done",
|
||||
"needs_human": false
|
||||
},
|
||||
{
|
||||
"id": "90836435-917f-504c-a711-3f29ece348e3",
|
||||
"record_id": "RCLUSTER-WP-0018-T02",
|
||||
"status": "todo",
|
||||
"needs_human": false
|
||||
}
|
||||
],
|
||||
"projected_edges": [
|
||||
{
|
||||
"from_task_id": "021b07bb-65bc-5743-bac5-4294b4be74f6",
|
||||
"to_task_id": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "021b07bb-65bc-5743-bac5-4294b4be74f6",
|
||||
"to_task_id": "90836435-917f-504c-a711-3f29ece348e3",
|
||||
"relationship_type": "starts_after"
|
||||
},
|
||||
{
|
||||
"from_task_id": "5dfa9a3a-2639-5cf6-b0a4-13eef417d47a",
|
||||
"to_task_id": "90836435-917f-504c-a711-3f29ece348e3",
|
||||
"relationship_type": "starts_after"
|
||||
}
|
||||
],
|
||||
"unprojected_source_declarations": []
|
||||
}
|
||||
],
|
||||
"runtime_deployed_source": "51bc70d1ff8f25450a8650d8e50caf053093a02e",
|
||||
"successor_runtime_source_not_deployed": "c103cbf3c8bed5dba87a03e320595ddded9301a3",
|
||||
"native_target_gates_closed": 0
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"status": "blocked",
|
||||
"files": [
|
||||
{
|
||||
"oid": "fa6b647e4a550d4f626fc09605dcc6fecc4f1f0b",
|
||||
"path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/local-integration-result.json"
|
||||
},
|
||||
{
|
||||
"oid": "cca84d470ed2de1a1a24142321d81c4ef042bba1",
|
||||
"path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-commit-result.json"
|
||||
},
|
||||
{
|
||||
"oid": "3e5339e79feb064f9cd1fb289970cf115eb53eee",
|
||||
"path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/local-integration-result.json"
|
||||
},
|
||||
{
|
||||
"oid": "14ac31e924f280aa71dc14561d2b9014b743e6d6",
|
||||
"path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-commit-result.json"
|
||||
},
|
||||
{
|
||||
"oid": "e14b161ed327caa2f87f0d4034cedb32eb5cf607",
|
||||
"path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-commit-result.json"
|
||||
},
|
||||
{
|
||||
"oid": "465af4282960c0dfd2ce36fce5d7cb27d26f486a",
|
||||
"path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/native_binding_probes.py"
|
||||
}
|
||||
],
|
||||
"hook_output": {
|
||||
"blocked_blob_ids": [
|
||||
"14ac31e924f280aa71dc14561d2b9014b743e6d6",
|
||||
"3e5339e79feb064f9cd1fb289970cf115eb53eee",
|
||||
"465af4282960c0dfd2ce36fce5d7cb27d26f486a",
|
||||
"cca84d470ed2de1a1a24142321d81c4ef042bba1",
|
||||
"e14b161ed327caa2f87f0d4034cedb32eb5cf607",
|
||||
"fa6b647e4a550d4f626fc09605dcc6fecc4f1f0b"
|
||||
],
|
||||
"scanned_blobs": 187,
|
||||
"scanner_sha256": "88f91962aa2f93ac6ab281d553b9e125f5197bbbce38f9f2437f7299c32e5509",
|
||||
"scanner_version": "8.30.1",
|
||||
"scope": "changed-staged-blobs",
|
||||
"status": "blocked"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"schema": "custodian.scanner-publication-refinement.v1",
|
||||
"findings_classification": "251 generic-api-key findings on source SHA256 metadata; no secret identified",
|
||||
"rules_or_scanner_changed": false,
|
||||
"original_receipts_retained_locally": true,
|
||||
"typed_receipts": [
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/local-integration-result.publication.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-commit-result.publication.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/local-integration-result.publication.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-commit-result.publication.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-commit-result.publication.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r8/source-commit-result.publication.json"
|
||||
],
|
||||
"pending_proposal_revision": 2,
|
||||
"pending_proposal_sha256": "5d0ddebc21bcb035809cc8b57f4c2e1ba8ed09204be5b965460e178a90913f1e",
|
||||
"excluded_original_paths": [
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/local-integration-result.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-commit-result.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/local-integration-result.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-commit-result.json",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-commit-result.json",
|
||||
"docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/native_binding_probes.py",
|
||||
"docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r8/source-commit-result.json"
|
||||
],
|
||||
"original_proposal_revision1_sha256": "81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932",
|
||||
"runtime_not_executed": true,
|
||||
"additional_receipt_typed_preemptively": "WP-only R8 publication uses the same verified typed representation; no scanner finding or failure is claimed for this later original."
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"scanner_unchanged": true,
|
||||
"results": [
|
||||
{
|
||||
"path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/local-integration-result.publication.json",
|
||||
"sha256": "17a2f1c96dd4e6dc4c297f168ca21b8e2ec32a263494fb5a746f60752f8cfda2",
|
||||
"scanner_exit_code": 0,
|
||||
"findings": 0
|
||||
},
|
||||
{
|
||||
"path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5/source-commit-result.publication.json",
|
||||
"sha256": "672bb4b714ca1a2530cf764ffb565630db57a82d3083840ca7fc76d529b3df8e",
|
||||
"scanner_exit_code": 0,
|
||||
"findings": 0
|
||||
},
|
||||
{
|
||||
"path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/local-integration-result.publication.json",
|
||||
"sha256": "bb211f0693194e5bd5432517257b749fa9b5a19934bcabf8841ad762a0fee870",
|
||||
"scanner_exit_code": 0,
|
||||
"findings": 0
|
||||
},
|
||||
{
|
||||
"path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6/source-commit-result.publication.json",
|
||||
"sha256": "c9e0a943eddc63c79a09b3c63229fb12a7d922f5777590691d36cae982c53dd6",
|
||||
"scanner_exit_code": 0,
|
||||
"findings": 0
|
||||
},
|
||||
{
|
||||
"path": "docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r7/source-commit-result.publication.json",
|
||||
"sha256": "b5408c26abf16a4a585b7a2546ab4651d3b3832f2690f3e0378bc9c98387b327",
|
||||
"scanner_exit_code": 0,
|
||||
"findings": 0
|
||||
},
|
||||
{
|
||||
"path": "docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/native_binding_probes.py",
|
||||
"sha256": "ce492d0713c987e47eefc991a6312c1c63ed72056a597e9e28aee959d06e71d5",
|
||||
"scanner_exit_code": 0,
|
||||
"findings": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
"""Run authorized normal Cluster maintenance with exact client source and retained baseline."""
|
||||
from pathlib import Path
|
||||
import hashlib,json,subprocess
|
||||
here=Path(__file__).resolve().parent;root=Path('/home/worsch/railiance-cluster')
|
||||
packet=here.parent/'netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r5'
|
||||
manifest=json.loads((packet/'manifest.json').read_text())
|
||||
for name in ['scripts/consistency_check.py','api/services/historical_projection.py']:
|
||||
pin=next(x['candidate_sha256'] for x in manifest['files'] if x['path']==name)
|
||||
assert hashlib.sha256((Path('/home/worsch/state-hub')/name).read_bytes()).hexdigest()==pin,'fixed-client-source-drift'
|
||||
assert json.loads((here/'receiver-rollout-r4/before-corrected-client.json').read_text())['stage']=='before-corrected-client'
|
||||
backup=here/'railiance-cluster-publication-backup';originals=json.loads((backup/'originals.json').read_text())
|
||||
def git(*a):return subprocess.check_output(['git','-C',str(root),*a],stderr=subprocess.PIPE)
|
||||
for name,index in originals.items():
|
||||
assert (root/name).read_bytes()==(backup/(name+'.worktree')).read_bytes()
|
||||
assert git('ls-files','--stage','--',name).decode()==index
|
||||
try:
|
||||
for label,argv,limit in [('corrected-client-cluster-consistency',['statehub','fix-consistency','--repo','railiance-cluster','--json'],300),('corrected-client-cluster-projection',['/home/worsch/repo-manager/.venv/bin/rmgr','sync','--path',str(root),'--push'],180)]:
|
||||
r=subprocess.run(argv,cwd=root,capture_output=True,text=True,timeout=limit)
|
||||
(here/(label+'.json')).write_text(r.stdout);(here/(label+'.stderr.txt')).write_text(r.stderr)
|
||||
assert r.returncode==0,label+'-refused-receipt-retained'
|
||||
finally:
|
||||
for name,index in originals.items():
|
||||
(root/name).write_bytes((backup/(name+'.worktree')).read_bytes())
|
||||
mode,oid,stage,path=index.split();assert stage=='0';git('update-index','--cacheinfo',mode,oid,path)
|
||||
assert git('ls-files','--stage','--',name).decode()==index
|
||||
c=json.loads((here/'corrected-client-cluster-consistency.json').read_text());assert c['summary']['fail']==c['summary']['automation_error']==0
|
||||
p=json.loads((here/'corrected-client-cluster-projection.json').read_text());assert p['status']=='applied'
|
||||
assert p['commit']==p['receipt']['expected_commit']==p['receipt']['derived_commit']=='c562d7134c38679952a8ffd17a8a893a900aef0d'
|
||||
assert p['receipt']['instance_role']=='primary' and p['receipt']['instance_label']=='railiance01'
|
||||
assert not p['receipt']['outcome']['refused'] and not p['receipt']['outcome']['retired']
|
||||
print(json.dumps({'status':'applied','commit':p['commit'],'fixed_client_source_verified':True,'current_hash_comparison':'pending','original_failed_comparison_retained':True,'unrelated_work_preserved':True}))
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
"""Run authorized normal Cluster maintenance with exact client source and retained baseline."""
|
||||
from pathlib import Path
|
||||
import hashlib,json,subprocess
|
||||
here=Path(__file__).resolve().parent;root=Path('/home/worsch/railiance-cluster')
|
||||
packet=here.parent/'netkingdom-target-2026-10-16/cluster-historical-publication-r1/owner-followthrough-r6'
|
||||
manifest=json.loads((packet/'manifest.json').read_text())
|
||||
for name in ['scripts/consistency_check.py']:
|
||||
pin=next(x['candidate_sha256'] for x in manifest['files'] if x['path']==name)
|
||||
assert hashlib.sha256((Path('/home/worsch/state-hub')/name).read_bytes()).hexdigest()==pin,'fixed-client-source-drift'
|
||||
assert json.loads((here/'receiver-rollout-r4/before-verified-client.json').read_text())['stage']=='before-verified-client'
|
||||
# Verify the installed entrypoint's actual packaged checker, not just checkout bytes.
|
||||
probe=subprocess.run(['/home/worsch/state-hub/.venv/bin/python','-c',"import custodian_cli,hashlib,json; p=custodian_cli.STATE_HUB_DIR/'scripts/consistency_check.py'; print(json.dumps({'path':str(p),'sha256':hashlib.sha256(p.read_bytes()).hexdigest()}))"],cwd=root,capture_output=True,text=True,timeout=10)
|
||||
assert probe.returncode==0;loaded=json.loads(probe.stdout);assert loaded['sha256']==next(x['candidate_sha256'] for x in manifest['files'] if x['path']=='scripts/consistency_check.py')
|
||||
(here/'verified-loaded-client.json').write_text(json.dumps(loaded,indent=2)+'\n')
|
||||
baseline_head=subprocess.check_output(['git','-C',str(root),'rev-parse','HEAD'],text=True).strip();assert baseline_head=='6ae3f847c83da3402883453ee7110457bfb2d0d6'
|
||||
backup=here/'railiance-cluster-publication-backup';originals=json.loads((backup/'originals.json').read_text())
|
||||
def git(*a):return subprocess.check_output(['git','-C',str(root),*a],stderr=subprocess.PIPE)
|
||||
for name,index in originals.items():
|
||||
assert (root/name).read_bytes()==(backup/(name+'.worktree')).read_bytes()
|
||||
assert git('ls-files','--stage','--',name).decode()==index
|
||||
# Shield original staged generated content from any legacy writeback index.
|
||||
for name in originals:
|
||||
raw=git('ls-tree','HEAD','--',name).decode().split();git('update-index','--cacheinfo',raw[0],raw[2],name)
|
||||
try:
|
||||
for label,argv,limit in [('verified-client-cluster-consistency',['statehub','fix-consistency','--repo','railiance-cluster','--json'],300),('verified-client-cluster-projection',['/home/worsch/repo-manager/.venv/bin/rmgr','sync','--path',str(root),'--push'],180)]:
|
||||
r=subprocess.run(argv,cwd=root,capture_output=True,text=True,timeout=limit)
|
||||
(here/(label+'.json')).write_text(r.stdout);(here/(label+'.stderr.txt')).write_text(r.stderr)
|
||||
assert r.returncode==0,label+'-refused-receipt-retained'
|
||||
finally:
|
||||
for name,index in originals.items():
|
||||
(root/name).write_bytes((backup/(name+'.worktree')).read_bytes())
|
||||
mode,oid,stage,path=index.split();assert stage=='0';git('update-index','--cacheinfo',mode,oid,path)
|
||||
assert git('ls-files','--stage','--',name).decode()==index
|
||||
c=json.loads((here/'verified-client-cluster-consistency.json').read_text());assert c['summary']['fail']==c['summary']['automation_error']==0
|
||||
assert 'bindings: synced 20/20' in c['fixes_applied'],'frozen-binding-omission-not-observed'
|
||||
p=json.loads((here/'verified-client-cluster-projection.json').read_text());assert p['status']=='applied'
|
||||
assert p['commit']==p['receipt']['expected_commit']==p['receipt']['derived_commit']==baseline_head
|
||||
assert p['receipt']['instance_role']=='primary' and p['receipt']['instance_label']=='railiance01'
|
||||
assert not p['receipt']['outcome']['refused'] and not p['receipt']['outcome']['retired']
|
||||
print(json.dumps({'status':'applied','commit':p['commit'],'fixed_client_source_verified':True,'current_hash_comparison':'pending','original_failed_comparison_retained':True,'unrelated_work_preserved':True}))
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
"""Required consistency/projection with exact restoration of unrelated work."""
|
||||
from pathlib import Path
|
||||
import hashlib
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
ROOT = Path('/home/worsch/the-custodian')
|
||||
BASE = Path(__file__).resolve().parent
|
||||
BACKUP = BASE / 'custodian-publication-backup'
|
||||
originals = json.loads((BACKUP / 'originals.json').read_text())
|
||||
other = json.loads((BACKUP / 'other-dirty-hashes.json').read_text())
|
||||
def git(*argv):
|
||||
return subprocess.check_output(['git', '-C', str(ROOT), *argv], stderr=subprocess.PIPE)
|
||||
try:
|
||||
for label, argv, timeout in [
|
||||
('consistency', ['statehub', 'fix-consistency', '--repo', 'the-custodian', '--json'], 300),
|
||||
('projection', ['/home/worsch/repo-manager/.venv/bin/rmgr', 'sync', '--path', str(ROOT), '--push'], 180),
|
||||
]:
|
||||
result = subprocess.run(argv, cwd=ROOT, capture_output=True, text=True, timeout=timeout)
|
||||
(BASE / ('rollout-custodian-' + label + '.json')).write_text(result.stdout)
|
||||
(BASE / ('rollout-custodian-' + label + '.stderr.txt')).write_text(result.stderr)
|
||||
assert result.returncode == 0, label + ' failed; receipt retained'
|
||||
finally:
|
||||
for name, entry in originals.items():
|
||||
(ROOT / name).write_bytes((BACKUP / (name + '.worktree')).read_bytes())
|
||||
mode, oid, stage, path = entry.split()
|
||||
assert stage == '0'
|
||||
git('update-index', '--cacheinfo', mode, oid, path)
|
||||
assert git('ls-files', '--stage', '--', name).decode() == entry
|
||||
assert all(hashlib.sha256((ROOT / name).read_bytes()).hexdigest() == pin for name, pin in other.items())
|
||||
receipt = json.loads((BASE / 'rollout-custodian-projection.json').read_text())
|
||||
assert receipt['status'] == 'applied'
|
||||
print(json.dumps({'status': 'applied', 'commit': receipt['commit'], 'other_work_preserved': True}))
|
||||
|
|
@ -0,0 +1,531 @@
|
|||
{
|
||||
"repo_slug": "railiance-cluster",
|
||||
"repo_path": "/home/worsch/railiance-cluster",
|
||||
"source_revision": "6ae3f847c83da3402883453ee7110457bfb2d0d6",
|
||||
"source_revision_reason": null,
|
||||
"issues": [
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager warning: .repo-classification.yaml: category is project but slug is not prj-*; not every category:project is a prj- repo",
|
||||
"file_path": ".repo-classification.yaml",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1: task id 'T01' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2: task id 'T02' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3: task id 'T03' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4: task id 'T04' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5: task id 'T05' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1: task id 'T01' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2: task id 'T02' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3: task id 'T03' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4: task id 'T04' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1: task id 'T01' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2: task id 'T02' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3: task id 'T03' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4: task id 'T04' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5: task id 'T05' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6: task id 'T06' is not accepted by the canon kind registry",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1: task 'T01' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1', 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1']",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2: task 'T02' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2', 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2']",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3: task 'T03' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3', 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3']",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4: task 'T04' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4', 'workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4']",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-35",
|
||||
"message": "Repo Manager contradictory: workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5: task 'T05' has conflicting UUID assignments at ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5', 'workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5']",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-33",
|
||||
"message": "WORK-RECORDS.md is missing or stale \u2014 regenerate via fix-consistency (CUST-WP-0061-T04 generated work-record index)",
|
||||
"file_path": "WORK-RECORDS.md",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": true
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-39",
|
||||
"message": "Human wait task 'RCLUSTER-WP-0018-T04' in workplan 'RCLUSTER-WP-0018' has needs_human: true without decision_id \u2014 unrouted human gate",
|
||||
"file_path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md#RCLUSTER-WP-0018-T04",
|
||||
"db_id": "",
|
||||
"file_value": "needs_human: true",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Retired DB workstream 'rail-bs-wp-0008-activity-core-wp0016-triage-output-deploy@retired-20260828' (id=f2ca1a5d\u2026, status=archived) has no backing workplan file \u2014 projection tombstone, not live work",
|
||||
"file_path": "",
|
||||
"db_id": "f2ca1a5d-4dd6-42ea-8003-969c7265f891",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Retired DB workstream 'rail-bs-wp-0009-activity-core-admin-sync-smoke@retired-20260828' (id=366eec46\u2026, status=archived) has no backing workplan file \u2014 projection tombstone, not live work",
|
||||
"file_path": "",
|
||||
"db_id": "366eec46-3139-4810-ace6-ea75750fe821",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Closed DB workstream 'rail-bs-wp-0008' (id=5032c55c\u2026, status=finished) has no backing workplan file",
|
||||
"file_path": "",
|
||||
"db_id": "5032c55c-2ee2-4b7e-b1eb-157f0f8ac647",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Retired DB workstream 'railiance-wp-0014@retired-20260826' (id=a152ddda\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work",
|
||||
"file_path": "",
|
||||
"db_id": "a152ddda-d60a-4a65-9b9c-59e2db9ff2b7",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Retired DB workstream 'railiance-wp-0012@retired-20260826' (id=6434f7cb\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work",
|
||||
"file_path": "",
|
||||
"db_id": "6434f7cb-e13c-4c05-839b-197bb239d5cd",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Retired DB workstream 'railiance-wp-0013@retired-20260826' (id=a3abb83a\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work",
|
||||
"file_path": "",
|
||||
"db_id": "a3abb83a-2d42-40f9-a5f6-1dbc36903436",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Retired DB workstream 'rail-bs-rcluster-wp-adhoc-2026-07-27@retired-20260828' (id=b37f3c6e\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work",
|
||||
"file_path": "",
|
||||
"db_id": "b37f3c6e-a9e5-58c2-84ec-77ef2a2978a7",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "INFO",
|
||||
"check_id": "C-08",
|
||||
"message": "Retired DB workstream 'rail-bs-adhoc-2026-07-27@retired-20260828' (id=9a77bc91\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work",
|
||||
"file_path": "",
|
||||
"db_id": "9a77bc91-f457-5545-996f-04f49707f54b",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-28",
|
||||
"message": "8 unread inbox message(s) older than 3 day(s): railiance-platform:0c1023ce, railiance-platform:f643ce05, prj-forgejo-org-refactor:be06609c, prj-forgejo-org-refactor:6eac8c3f, prj-forgejo-org-refactor:82225aca, ...",
|
||||
"file_path": "",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-28",
|
||||
"message": "8 unread message(s) lack thread_id for supersession tracking: railiance-platform:0c1023ce, railiance-platform:f643ce05, prj-forgejo-org-refactor:be06609c, prj-forgejo-org-refactor:6eac8c3f, prj-forgejo-org-refactor:82225aca",
|
||||
"file_path": "",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-29",
|
||||
"message": "Unread work request from railiance-platform (f643ce05) may need a workplan file: RPF56: implement native JWT consumer-group mapping for Playwright",
|
||||
"file_path": "",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-29",
|
||||
"message": "Unread work request from the-custodian (a1368d99) may need a workplan file: Workplan 'three-phoenix-ha-cluster' is blocked with no wait task",
|
||||
"file_path": "",
|
||||
"db_id": "",
|
||||
"file_value": "",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'RCLUSTER-WP-0007' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/RCLUSTER-WP-0007-threephoenix-ha-cluster.md",
|
||||
"db_id": "",
|
||||
"file_value": "RCLUSTER-WP-0007",
|
||||
"db_value": "RAIL-BS-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'RCLUSTER-WP-0014' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/RCLUSTER-WP-0014-capacity-utilization-and-allocation-evidence.md",
|
||||
"db_id": "",
|
||||
"file_value": "RCLUSTER-WP-0014",
|
||||
"db_value": "RAIL-BS-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'RCLUSTER-WP-0016' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/RCLUSTER-WP-0016-forgejo-upload-timeout.md",
|
||||
"db_id": "",
|
||||
"file_value": "RCLUSTER-WP-0016",
|
||||
"db_value": "RAIL-BS-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'RCLUSTER-WP-0017' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/RCLUSTER-WP-0017-netkingdom-signer-runtime-storage-review.md",
|
||||
"db_id": "",
|
||||
"file_value": "RCLUSTER-WP-0017",
|
||||
"db_value": "RAIL-BS-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'RCLUSTER-WP-0018' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md",
|
||||
"db_id": "",
|
||||
"file_value": "RCLUSTER-WP-0018",
|
||||
"db_value": "RAIL-BS-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'RCLUSTER-WP-0001' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/archived/260622-RCLUSTER-WP-0001-activity-core-cluster-owned-deploy-verify.md",
|
||||
"db_id": "",
|
||||
"file_value": "RCLUSTER-WP-0001",
|
||||
"db_value": "RAIL-BS-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'RCLUSTER-WP-0002' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/archived/260622-RCLUSTER-WP-0002-activity-core-verifier-evidence-hardening.md",
|
||||
"db_id": "",
|
||||
"file_value": "RCLUSTER-WP-0002",
|
||||
"db_value": "RAIL-BS-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-26",
|
||||
"message": "Workplan id 'RCLUSTER-WP-0003' uses prefix 'RCLUSTER-WP' but repo canonical prefix is 'RAIL-BS-WP' \u2014 new plans must conform",
|
||||
"file_path": "workplans/archived/260701-RCLUSTER-WP-0003-activity-core-llm-connect-live-reconcile.md",
|
||||
"db_id": "",
|
||||
"file_value": "RCLUSTER-WP-0003",
|
||||
"db_value": "RAIL-BS-WP",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-27",
|
||||
"message": "Workplan id 'RAIL-BS-WP-0008' collides across repos: railiance-bootstrap/RAIL-BS-WP-0008-activity-core-wp0016-triage-output-deploy.md, railiance-cluster/RAIL-BS-WP-0008-activity-core-wp0016-triage-output-deploy.md",
|
||||
"file_path": "workplans/RAIL-BS-WP-0008-activity-core-wp0016-triage-output-deploy.md",
|
||||
"db_id": "",
|
||||
"file_value": "RAIL-BS-WP-0008",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-27",
|
||||
"message": "Workplan id 'RAIL-BS-WP-0009' collides across repos: railiance-bootstrap/RAIL-BS-WP-0009-activity-core-admin-sync-smoke.md, railiance-cluster/RAIL-BS-WP-0009-activity-core-admin-sync-smoke.md",
|
||||
"file_path": "workplans/RAIL-BS-WP-0009-activity-core-admin-sync-smoke.md",
|
||||
"db_id": "",
|
||||
"file_value": "RAIL-BS-WP-0009",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-27",
|
||||
"message": "Workplan id 'RAIL-BS-WP-0001' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0001-dependency-management.md, railiance-cluster/260622-RAIL-BS-WP-0001-dependency-management.md",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0001-dependency-management.md",
|
||||
"db_id": "",
|
||||
"file_value": "RAIL-BS-WP-0001",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-27",
|
||||
"message": "Workplan id 'RAIL-BS-WP-0002' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0002-k3s-baseline.md, railiance-cluster/260622-RAIL-BS-WP-0002-k3s-baseline.md",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md",
|
||||
"db_id": "",
|
||||
"file_value": "RAIL-BS-WP-0002",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-27",
|
||||
"message": "Workplan id 'RAIL-BS-WP-0003' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md, railiance-cluster/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md",
|
||||
"db_id": "",
|
||||
"file_value": "RAIL-BS-WP-0003",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-27",
|
||||
"message": "Workplan id 'RAIL-BS-WP-0004' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0004-safety-net.md, railiance-cluster/260622-RAIL-BS-WP-0004-safety-net.md",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md",
|
||||
"db_id": "",
|
||||
"file_value": "RAIL-BS-WP-0004",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-27",
|
||||
"message": "Workplan id 'RAIL-BS-WP-0005' collides across repos: railiance-bootstrap/260622-RAIL-BS-WP-0005-kubeconfig-delivery.md, railiance-cluster/260622-RAIL-BS-WP-0005-kubeconfig-delivery.md",
|
||||
"file_path": "workplans/archived/260622-RAIL-BS-WP-0005-kubeconfig-delivery.md",
|
||||
"db_id": "",
|
||||
"file_value": "RAIL-BS-WP-0005",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
},
|
||||
{
|
||||
"severity": "WARN",
|
||||
"check_id": "C-27",
|
||||
"message": "Workplan id 'RAIL-BS-WP-0006' collides across repos: railiance-bootstrap/260627-RAIL-BS-WP-0006-staged-promotion-lifecycle.md, railiance-cluster/260627-RAIL-BS-WP-0006-staged-promotion-lifecycle.md",
|
||||
"file_path": "workplans/archived/260627-RAIL-BS-WP-0006-staged-promotion-lifecycle.md",
|
||||
"db_id": "",
|
||||
"file_value": "RAIL-BS-WP-0006",
|
||||
"db_value": "",
|
||||
"fixable": false
|
||||
}
|
||||
],
|
||||
"fixes_applied": [
|
||||
"bindings: synced 20/20",
|
||||
"C-33 fixed: regenerated WORK-RECORDS.md",
|
||||
"brief: .custodian-brief.md updated",
|
||||
"push: pushed"
|
||||
],
|
||||
"summary": {
|
||||
"fail": 0,
|
||||
"automation_error": 0,
|
||||
"warn": 43,
|
||||
"info": 8
|
||||
},
|
||||
"result": "warn"
|
||||
}
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
{
|
||||
"ok": true,
|
||||
"status": "applied",
|
||||
"repo_slug": "railiance-cluster",
|
||||
"commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6",
|
||||
"requests": 2,
|
||||
"elapsed_ms": 1369.2,
|
||||
"git": {
|
||||
"upstream": "origin/main",
|
||||
"behind": 0,
|
||||
"ahead": 0
|
||||
},
|
||||
"identifiers": {
|
||||
"schema": "repo-manager.identifier-assignment.v1",
|
||||
"ok": true,
|
||||
"executed": true,
|
||||
"repo": "railiance-cluster",
|
||||
"namespace": "helixforge",
|
||||
"assignments": [],
|
||||
"historical_invalid_identifiers": [
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T01",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T02",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T03",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T04",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T05",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T01",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T02",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T03",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T04",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T01",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T02",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T03",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T04",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T05",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5"
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T06",
|
||||
"source": "workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-6"
|
||||
}
|
||||
],
|
||||
"historical_identity_collisions": [
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T01",
|
||||
"uuid": null,
|
||||
"sources": [
|
||||
"workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-1",
|
||||
"workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-1",
|
||||
"workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-1"
|
||||
],
|
||||
"parent_id": "RAIL-BS-WP-0002",
|
||||
"uuids": [
|
||||
"3f042630-eab0-4c6a-9167-e2b28ff20e40",
|
||||
"4526a842-ea31-4874-9231-92ab556cfe7b",
|
||||
"6841c93a-f146-47eb-9f7c-8fa0e02c1bbc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T02",
|
||||
"uuid": null,
|
||||
"sources": [
|
||||
"workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-2",
|
||||
"workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-2",
|
||||
"workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-2"
|
||||
],
|
||||
"parent_id": "RAIL-BS-WP-0002",
|
||||
"uuids": [
|
||||
"a6313e06-1976-46a7-8e31-df4eb2eca880",
|
||||
"ab166073-30a7-4702-a037-4091e8706e20",
|
||||
"e8510646-46ed-4697-a345-f3d3009eea78"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T03",
|
||||
"uuid": null,
|
||||
"sources": [
|
||||
"workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-3",
|
||||
"workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-3",
|
||||
"workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-3"
|
||||
],
|
||||
"parent_id": "RAIL-BS-WP-0002",
|
||||
"uuids": [
|
||||
"05d42a55-921f-4aa7-bb76-e8af9c7e0ac3",
|
||||
"140da396-8e30-4f4d-b88c-c42c0cd46c01",
|
||||
"dab2c07f-8aa0-4635-8df6-857e87e93fc5"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T04",
|
||||
"uuid": null,
|
||||
"sources": [
|
||||
"workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-4",
|
||||
"workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md#task-block-4",
|
||||
"workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-4"
|
||||
],
|
||||
"parent_id": "RAIL-BS-WP-0002",
|
||||
"uuids": [
|
||||
"08233868-d522-4117-bc4e-6c0f52545665",
|
||||
"5c3d40e4-239b-488e-9519-6f7a38d2325f",
|
||||
"d8a3ba40-fda0-4c1f-a9f1-ffcd621a5b3d"
|
||||
]
|
||||
},
|
||||
{
|
||||
"kind": "task",
|
||||
"id": "T05",
|
||||
"uuid": null,
|
||||
"sources": [
|
||||
"workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md#task-block-5",
|
||||
"workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md#task-block-5"
|
||||
],
|
||||
"parent_id": "RAIL-BS-WP-0002",
|
||||
"uuids": [
|
||||
"2d5acff7-4a4e-4ddd-ad06-08237ad3dac8",
|
||||
"7f9e0e58-a130-467a-a2d0-b3f2564e496f"
|
||||
]
|
||||
}
|
||||
],
|
||||
"files_changed": []
|
||||
},
|
||||
"receipt": {
|
||||
"schema": "state-hub.repository-projection-reconcile.v1",
|
||||
"outcome": {
|
||||
"notes": [
|
||||
"Preserved bound historical row and task UUIDs: RAIL-BS-WP-0002",
|
||||
"Preserved bound historical row and task UUIDs: RAIL-BS-WP-0003",
|
||||
"Preserved bound historical row and task UUIDs: RAIL-BS-WP-0004"
|
||||
],
|
||||
"commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6",
|
||||
"counts": {
|
||||
"created": 0,
|
||||
"refused": 0,
|
||||
"retired": 0,
|
||||
"updated": 20,
|
||||
"released": 0,
|
||||
"created_edges": 0,
|
||||
"created_tasks": 0,
|
||||
"removed_edges": 0,
|
||||
"updated_tasks": 1,
|
||||
"external_edges": 0,
|
||||
"cancelled_tasks": 0,
|
||||
"unresolved_edges": 0
|
||||
},
|
||||
"schema": "state-hub.projection-reset.v1",
|
||||
"status": "applied",
|
||||
"created": [],
|
||||
"refused": [],
|
||||
"retired": [],
|
||||
"updated": [
|
||||
"RAIL-BS-WP-0001",
|
||||
"RAIL-BS-WP-0005",
|
||||
"RAIL-BS-WP-0006",
|
||||
"RAIL-BS-WP-0008",
|
||||
"RAIL-BS-WP-0009",
|
||||
"RAIL-BS-WP-0010",
|
||||
"RAIL-BS-WP-0011",
|
||||
"RAIL-BS-WP-0012",
|
||||
"RAIL-BS-WP-0013",
|
||||
"RAIL-BS-WP-0014",
|
||||
"RAIL-BS-WP-0015",
|
||||
"RCLUSTER-WP-0001",
|
||||
"RCLUSTER-WP-0002",
|
||||
"RCLUSTER-WP-0003",
|
||||
"RCLUSTER-WP-0007",
|
||||
"RCLUSTER-WP-0014",
|
||||
"RCLUSTER-WP-0016",
|
||||
"RCLUSTER-WP-0017",
|
||||
"RCLUSTER-WP-0018",
|
||||
"RCLUSTER-WP-ADHOC-2026-07-27"
|
||||
],
|
||||
"released": [],
|
||||
"repo_slug": "railiance-cluster",
|
||||
"created_edges": [],
|
||||
"created_tasks": [],
|
||||
"removed_edges": [],
|
||||
"updated_tasks": [
|
||||
"RCLUSTER-WP-0018-T01"
|
||||
],
|
||||
"external_edges": [],
|
||||
"cancelled_tasks": [],
|
||||
"unresolved_edges": []
|
||||
},
|
||||
"instance_role": "primary",
|
||||
"derived_commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6",
|
||||
"instance_label": "railiance01",
|
||||
"expected_commit": "6ae3f847c83da3402883453ee7110457bfb2d0d6"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"path": "/home/worsch/state-hub/.venv/lib/python3.12/site-packages/scripts/consistency_check.py",
|
||||
"sha256": "1bfbc89d3ff5c621ec541fd32384083cc7dcf96a639b217d62b6fc34de238efd"
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Read-only Git+Hub task binding verifier; never syncs or changes source/index."""
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import subprocess
|
||||
import urllib.request
|
||||
|
||||
HERE=Path(__file__).resolve().parent
|
||||
OWNERS=[{'repo':'railiance-cluster','commit':'c562d7134c38679952a8ffd17a8a893a900aef0d','path':'workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md','id':'RCLUSTER-WP-0018','tasks':5}]
|
||||
API=os.environ.get('API_BASE','http://127.0.0.1:8000').rstrip('/')
|
||||
EXTERNAL={'STATE-WP-0095-T03':'e8566341-cf6e-5b9c-ad80-8564d14cd52a','STATE-WP-0095-T06':'6af973b4-1964-5d4d-a2f8-8dbd4c01fda4','NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'}
|
||||
|
||||
|
||||
class Refused(Exception):pass
|
||||
|
||||
|
||||
def git(root,*args):
|
||||
result=subprocess.run(['git','--no-optional-locks','-C',str(root),*args],
|
||||
capture_output=True,timeout=30,check=False)
|
||||
if result.returncode:raise Refused('read-only-git-failed')
|
||||
return result.stdout
|
||||
|
||||
|
||||
def field(text,key):
|
||||
values=re.findall(r'^'+re.escape(key)+r':\s*(.*?)\s*$',text,re.M)
|
||||
if len(values)!=1:raise Refused('source-field-ambiguous')
|
||||
return values[0].strip('"\'')
|
||||
|
||||
|
||||
def source(text):
|
||||
header=text.split('---',2)[1]
|
||||
tasks=[]
|
||||
for block in re.findall(r'```task\n(.*?)\n```',text,re.S):
|
||||
deps=re.findall(r'^depends_on:\s*\[(.*?)\]',block,re.M)
|
||||
tasks.append({'record_id':field(block,'id'),'id':field(block,'state_hub_task_id'),
|
||||
'status':field(block,'status'),'dependencies':[x.strip() for x in deps[0].split(',') if x.strip()] if deps else []})
|
||||
return {'id':field(header,'state_hub_workstream_id'),'source_record_id':field(header,'id'),
|
||||
'slug':field(header,'id').lower(),
|
||||
'status':field(header,'status'),'tasks':tasks}
|
||||
|
||||
|
||||
def get(path):
|
||||
class NoRedirect(urllib.request.HTTPRedirectHandler):
|
||||
def redirect_request(self,*args,**kwargs):raise Refused('hub-redirect-refused')
|
||||
opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect)
|
||||
with opener.open(urllib.request.Request(API+path,method='GET'),timeout=20) as response:
|
||||
data=response.read(8*1024**2+1)
|
||||
if len(data)>8*1024**2:raise Refused('hub-read-limit')
|
||||
return json.loads(data)
|
||||
|
||||
|
||||
def index_stat(root):
|
||||
raw=git(root,'rev-parse','--git-path','index').decode().strip();path=Path(raw)
|
||||
if not path.is_absolute():path=root/path
|
||||
try:item=path.lstat()
|
||||
except FileNotFoundError:return None
|
||||
return [item.st_dev,item.st_ino,item.st_size,item.st_mtime_ns,item.st_mode]
|
||||
|
||||
|
||||
def remote(root,expected,repo):
|
||||
if git(root,'remote','get-url','origin').decode().strip()!='forgejo-remote:coulomb/'+repo+'.git':
|
||||
raise Refused('remote-route-drift')
|
||||
lines=git(root,'ls-remote','--symref','origin','HEAD','refs/heads/main').decode().splitlines()
|
||||
if set(lines)!={'ref: refs/heads/main\tHEAD',expected+'\tHEAD',expected+'\trefs/heads/main'}:
|
||||
raise Refused('remote-head-mismatch')
|
||||
return {'HEAD':expected,'refs/heads/main':expected,'symbolic_HEAD':'refs/heads/main'}
|
||||
|
||||
|
||||
def verify():
|
||||
result={'status':'unverified','scope':'Cluster WP18 owner publication; read-only Git remote and Hub snapshots',
|
||||
'writes_to_source_index_refs_or_Hub':False,'rows':[]}
|
||||
try:
|
||||
if API not in {'http://127.0.0.1:8000','http://127.0.0.1:18080','http://10.43.68.154:8000'}:
|
||||
raise Refused('unrecognized-hub-endpoint')
|
||||
health=get('/state/health')
|
||||
result['hub_instance']={key:health.get(key) for key in ('status','instance_role','instance_label')}
|
||||
if result['hub_instance']!={'status':'ok','instance_role':'primary','instance_label':'railiance01'}:
|
||||
raise Refused('hub-identity-mismatch')
|
||||
for owner in OWNERS:
|
||||
root=Path('/home/worsch')/owner['repo'];before_index=index_stat(root)
|
||||
if git(root,'rev-parse','HEAD').decode().strip()!=owner['commit']:
|
||||
raise Refused('local-head-drift')
|
||||
committed=git(root,'show',owner['commit']+':'+owner['path'])
|
||||
local=(root/owner['path']).read_bytes()
|
||||
if local!=committed:raise Refused('published-workplan-local-drift')
|
||||
expected=source(committed.decode())
|
||||
if expected['source_record_id']!=owner['id'] or len(expected['tasks'])!=owner['tasks']:
|
||||
raise Refused('source-task-denominator-mismatch')
|
||||
snapshot=get('/repos/'+owner['repo']+'/work-record-projection/snapshot')
|
||||
plans=[row for row in snapshot['workplans'] if row['id']==expected['id']]
|
||||
if len(plans)!=1 or any(plans[0].get(key)!=expected[key] for key in ('id','slug','status')):
|
||||
raise Refused('workplan-binding-mismatch')
|
||||
projected=[row for row in snapshot['tasks']
|
||||
if row.get('workplan_id',row.get('workstream_id'))==expected['id']]
|
||||
if len(projected)!=len(expected['tasks']):raise Refused('projected-task-denominator-mismatch')
|
||||
byid={row['id']:row for row in projected}
|
||||
if len(byid)!=len(projected):raise Refused('duplicate-projected-uuid')
|
||||
observed=[]
|
||||
for task in expected['tasks']:
|
||||
row=byid.get(task['id'],{})
|
||||
if any(row.get(key)!=task[key] for key in ('id','record_id','status')):
|
||||
raise Refused('task-id-uuid-status-mismatch')
|
||||
observed.append({key:row[key] for key in ('id','record_id','status')})
|
||||
identifiers={task['record_id']:task['id'] for task in expected['tasks']}
|
||||
edges={(task['id'],identifiers[dep],'starts_after') for task in expected['tasks'] for dep in task['dependencies'] if dep in identifiers}
|
||||
actual=[edge for edge in snapshot['dependencies'] if edge['from_workplan_id']==expected['id']]
|
||||
projected_edges={(edge.get('from_task_id'),edge.get('to_task_id'),edge['relationship_type']) for edge in actual}
|
||||
if len(actual)!=len(edges) or projected_edges!=edges:
|
||||
raise Refused('dependency-binding-mismatch')
|
||||
if any(edge.get('source_commit') not in (None,owner['commit']) for edge in actual):
|
||||
raise Refused('dependency-source-commit-mismatch')
|
||||
for task in expected['tasks']:
|
||||
for dep in task['dependencies']:
|
||||
if dep in EXTERNAL:
|
||||
target=get('/tasks/'+EXTERNAL[dep])
|
||||
if target.get('id')!=EXTERNAL[dep] or target.get('record_id')!=dep:
|
||||
raise Refused('external-dependency-target-mismatch')
|
||||
remote_readback=remote(root,owner['commit'],owner['repo'])
|
||||
if index_stat(root)!=before_index or (root/owner['path']).read_bytes()!=local:
|
||||
raise Refused('source-or-index-stat-changed')
|
||||
result['rows'].append({'repo':owner['repo'],'published_commit':owner['commit'],
|
||||
'remote':remote_readback,'workplan':{key:plans[0][key] for key in ('id','slug','status')},
|
||||
'source_record_id':expected['source_record_id'],
|
||||
'tasks':observed,'external_source_declarations_not_projected':[{'from_task_id':task['id'],'target_record_id':dep,'target_uuid':EXTERNAL[dep]} for task in expected['tasks'] for dep in task['dependencies'] if dep in EXTERNAL],'dependencies':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(edges)],
|
||||
'source_file_sha256':hashlib.sha256(local).hexdigest(),'source_file_unchanged':True,'dependency_scope':'internal edges verified; external source target identities checked without claiming projected external edges',
|
||||
'index_stat_unchanged':True})
|
||||
result['status']='verified'
|
||||
except Exception as error:
|
||||
result['reason']=error.args[0] if isinstance(error,Refused) else 'readback-unavailable'
|
||||
result['verifier_sha256']=hashlib.sha256(Path(__file__).read_bytes()).hexdigest()
|
||||
(HERE/'cluster-publication-readback.json').write_text(json.dumps(result,indent=2)+'\n')
|
||||
print(json.dumps({'status':result['status'],'owners':len(result['rows'])}))
|
||||
return 0 if result['status']=='verified' else 2
|
||||
|
||||
|
||||
if __name__=='__main__':raise SystemExit(verify())
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
"""Read back committed Custodian bindings and retain unrelated-work checks."""
|
||||
from pathlib import Path
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
import urllib.request
|
||||
import yaml
|
||||
|
||||
ROOT = Path('/home/worsch/the-custodian')
|
||||
BASE = Path(__file__).resolve().parent
|
||||
BACKUP = BASE / 'custodian-publication-backup'
|
||||
|
||||
def git(*args):
|
||||
return subprocess.check_output(['git', '-C', str(ROOT), *args], stderr=subprocess.PIPE).decode().strip()
|
||||
|
||||
def get(path):
|
||||
return json.load(urllib.request.urlopen('http://127.0.0.1:8000' + path, timeout=20))
|
||||
|
||||
head = git('rev-parse', 'HEAD')
|
||||
assert git('ls-remote', 'origin', 'refs/heads/main').split()[0] == head
|
||||
projection = json.loads((BASE / 'rollout-custodian-projection.json').read_text())
|
||||
receipt = projection['receipt']
|
||||
assert projection['status'] == 'applied' and projection['commit'] == head
|
||||
assert receipt['instance_role'] == 'primary' and receipt['instance_label'] == 'railiance01'
|
||||
assert receipt['expected_commit'] == receipt['derived_commit'] == head
|
||||
health = get('/state/health')
|
||||
assert health['instance_role'] == 'primary' and health['instance_label'] == 'railiance01'
|
||||
path = ROOT / 'workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md'
|
||||
raw = path.read_text()
|
||||
assert git('show', head + ':' + str(path.relative_to(ROOT))) == raw.strip()
|
||||
front = yaml.safe_load(raw.split('---', 2)[1])
|
||||
tasks = [yaml.safe_load(value) for value in re.findall(r'```task\n(.*?)\n```', raw, re.S)]
|
||||
snapshot = get('/repos/the-custodian/work-record-projection/snapshot')
|
||||
plan = next(p for p in snapshot['workplans'] if p['id'] == front['state_hub_workstream_id'])
|
||||
assert plan['status'] == front['status'] == 'active'
|
||||
actual = {t['id']: t for t in snapshot['tasks'] if t.get('workplan_id', t.get('workstream_id')) == plan['id']}
|
||||
assert len(actual) == len(tasks) == 6
|
||||
for task in tasks:
|
||||
row = actual[task['state_hub_task_id']]
|
||||
assert row['record_id'] == task['id'] and row['status'] == task['status']
|
||||
for name, entry in json.loads((BACKUP / 'originals.json').read_text()).items():
|
||||
assert (ROOT / name).read_bytes() == (BACKUP / (name + '.worktree')).read_bytes()
|
||||
assert git('ls-files', '--stage', '--', name) == entry.strip()
|
||||
assert all(hashlib.sha256((ROOT / name).read_bytes()).hexdigest() == pin
|
||||
for name, pin in json.loads((BACKUP / 'other-dirty-hashes.json').read_text()).items())
|
||||
proposal = BASE / 'guard-successor-review-r2/proposal-metadata.json'
|
||||
assert hashlib.sha256(proposal.read_bytes()).hexdigest() == '5d0ddebc21bcb035809cc8b57f4c2e1ba8ed09204be5b965460e178a90913f1e'
|
||||
for bound in json.loads(proposal.read_text())['bound_receipts']:
|
||||
assert hashlib.sha256(Path(bound['path']).read_bytes()).hexdigest() == bound['sha256']
|
||||
pending = get('/decisions/df703266-6719-4c04-ae1b-ba9afd3bca1c')
|
||||
assert pending['decision_type'] == 'pending' and pending['status'] == 'open'
|
||||
assert pending['decided_by'] is None and pending['decided_at'] is None
|
||||
result = {'status': 'verified', 'commit': head, 'remote_exact': True,
|
||||
'primary': 'primary/railiance01', 'projection_expected_equals_derived': True,
|
||||
'custodian_task_bindings': len(tasks), 'unrelated_index_and_worktree_preserved': True,
|
||||
'pending_proposal_revision': 2, 'pending_proposal_not_approved_or_executed': True,
|
||||
'proposal_bound_receipts_unchanged': True, 'native_target_gates_closed': 0}
|
||||
(BASE / 'rollout-close-verification.json').write_text(json.dumps(result, indent=2) + '\n')
|
||||
print(json.dumps(result))
|
||||
Loading…
Add table
Add a link
Reference in a new issue