Admit reviewed receiver evidence batch 5

This commit is contained in:
codex 2026-10-17 03:41:45 +02:00
parent 62d6e67e42
commit 4af966c2fa
24 changed files with 1165 additions and 0 deletions

View file

@ -0,0 +1,46 @@
{
"schema": "state95.guard-successor-readonly-preflight.v1",
"observed_at": "2026-10-17T00:33:19.687847+00:00",
"target": "railiance01/92.205.62.239",
"node_identity_verified": true,
"kubeconfig": "/home/worsch/.kube/config-railiance01",
"helm_revision": 76,
"current_image_manifest": "sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015",
"health": {
"status": "ok",
"db": "connected",
"instance_role": "primary",
"instance_label": "railiance01",
"schema": {
"status": "ok",
"applied": "c4d5e6f7a8b9",
"expected": "c4d5e6f7a8b9"
}
},
"headroom": {
"schema": "state-hub.release-headroom-preflight.v1",
"ok": true,
"observed_at": "2026-10-17T00:33:19.561580+00:00",
"freshness_seconds": 0,
"remaining_cpu_m": 420,
"remaining_memory_bytes": 6535979008,
"pending_unrelated_cpu_m": 0,
"api_surge_cpu_m": 100,
"mcp_surge_cpu_m": 10,
"migrate_cpu_m": 50,
"atomic": true,
"reasons": [],
"notes": [
"Aggregate remaining millicores is not a kube-scheduler guarantee.",
"Preflight does not lower requests and does not start Helm."
],
"hook_order": [
"pre-upgrade migrate job (helm.sh/hook-weight -5)",
"API RollingUpdate maxSurge=1 maxUnavailable=0",
"MCP RollingUpdate maxSurge=1 maxUnavailable=0"
]
},
"migration_job_and_pods_absent": true,
"runtime_readback_ref": "../receiver-rollout-r4/final-runtime-check.json",
"live_changes": false
}

View file

@ -0,0 +1,18 @@
{
"workplan_id": "79579572-8120-5d3b-aca5-dd4aff60d058",
"id": "df703266-6719-4c04-ae1b-ba9afd3bca1c",
"topic_id": null,
"title": "Review exact frozen-binding API guard successor and retained baseline exception",
"description": "Pending proposal STATE-WP-0095-T10-frozen-bindings-guard-r1 revision1 SHA25681d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932. Image main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1; frozen chart b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4. Eight-identity image-only server dry-run and explicit target/headroom/schema pass. Verified installed checker maintenance preserves all18 CURRENT rows; prior three-parent hash failures remain historical exceptions, never restored or backfilled. Requested ADMINISTER @ realm:kubernetes/railiance01 activation=APPROVED includes exact new Job conditional recovery, rollback76 after verified quiescence, current-baseline successor acceptance, unpriced cost/risk and attended stop for unknown mapping. Full review: the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/FINAL-PROPOSAL.md. No new runtime is approved or executed.",
"decision_type": "pending",
"status": "open",
"rationale": "Agent-prepared exact new-code proposal. Only the founder may resolve approval; prior receiver revision4 approval does not cover this new image.",
"decided_by": null,
"decided_at": null,
"deadline": null,
"escalation_note": null,
"superseded_by": null,
"created_at": "2026-10-17T00:37:26.205185Z",
"updated_at": "2026-10-17T00:37:26.205185Z",
"workstream_id": "79579572-8120-5d3b-aca5-dd4aff60d058"
}

View file

@ -0,0 +1,7 @@
{
"status": "prepared-helper-contract-checked",
"actual_workplan_binding_schema_accepts_exact_three": true,
"commit_interception_checked_with_actual_unbound_AsyncSession": true,
"DB_connected": false,
"native_probes_executed": false
}

View file

@ -0,0 +1,103 @@
{
"schema": "custodian.supervised-runtime-proposal.v1",
"proposal_id": "STATE-WP-0095-T10-frozen-bindings-guard-r1",
"revision": 1,
"status": "pending_supervisor_approval_not_executed",
"prepared_at": "2026-10-17T00:37:11.095872+00:00",
"owner_task_id": "STATE-WP-0095-T10",
"owner_task_uuid": "88585c69-d9b9-5e1f-a256-6416ff71e824",
"target": "railiance01/92.205.62.239 state-hub release API/MCP and exact-new-trial migration Job",
"authority_requested": "ADMINISTER @ realm:kubernetes/railiance01 activation=APPROVED",
"source_commit": "c103cbf3c8bed5dba87a03e320595ddded9301a3",
"image": "forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1",
"image_digest": "sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1",
"chart_archive": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/state-hub-0.1.0.tgz",
"chart_sha256": "b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4",
"remote_owned_chart": "/tmp/statehub-binding-guard-b5c0663d830f/state-hub-0.1.0.tgz",
"expected_prior_helm_revision": 76,
"expected_schema": "c4d5e6f7a8b9",
"migration_files_changed_since_deployed_source": false,
"exact_upgrade_argv": [
"ssh",
"railiance01",
"KUBECONFIG=/etc/rancher/k3s/k3s.yaml helm -n state-hub upgrade state-hub /tmp/statehub-binding-guard-b5c0663d830f/state-hub-0.1.0.tgz --reuse-values --set-string image.tag=main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1 --atomic --timeout 3m"
],
"staging": "Create exact new private owned directory, refuse unexpected existing ownership/content, copy only frozen chart, verify remote SHA before execution and remove only owned exact archive/directory after proof.",
"readiness_refresh_required_before_execution": true,
"native_probe_cases": 8,
"verification": [
"Delivered manifest and guard module hashes, API/MCP Ready, primary/railiance01 and expected schema.",
"Fresh CURRENT full historical-row hashes before and after; enforce rollback and commit interception for eight exact native cases, then fresh-transaction comparison including ordinary parent.",
"Verified installed local CLI guard, ordinary consistency/fast projection between current snapshots, archive bytes and unrelated staged work preserved; source/remote/Hub IDs/statuses read back."
],
"acceptance_disposition_requested": "Use current hashed baseline for successor acceptance; retain the earlier three-parent mismatch as a historical exception, without guessed restoration or backfilling its failed result. T07/RMGR19T06 close only after new receiving and corrected pipeline pass with exception recorded.",
"conditional_recovery_included": true,
"rollback_helm_revision": 76,
"recovery_limits": "Exact observed new Job UID/image/ownership and bound Pods only; foreground UID-precondition cancellation after revalidation. Verify private owner DB connection/transaction/lock quiescence; unknown mapping/mixed state stops for attended recovery. No schema downgrade or broad backend termination.",
"cost_estimate_eur": null,
"risk_estimate_eur": null,
"cost_and_risk_disposition": "Unpriced attributable cost and credible loss/outage exposure on existing infrastructure require supervised founder acceptance. Helm timeout is not Job/outage bound.",
"autopilot_grant": false,
"bound_receipts": [
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/FINAL-PROPOSAL.md",
"sha256": "7addca35af1973be4a2f2c1aeec658a00b581108da03e6509e645045f2767ae4"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/RECOVERY.md",
"sha256": "dc72dea7cdf519a712ee8f6d28fc6aa5667b44655d948f2c0160869383f33cef"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/native_binding_probes.py",
"sha256": "ef5c07affb15d20b4194edda68fd14b4d0fee1e9dab857e3242c3a1a1e49046f"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/probe-helper-preparation-check.json",
"sha256": "e11f48b18cdb57e1b8f2bddcf7e6ffc7473ab2ab2b031c3c1a26afae609f831c"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/watch_rollout.py",
"sha256": "a496da3c9a415ac800921ce755446be4bb55bc17e4e6b913143a5d6baf48f815"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/reuse_values_dryrun.py",
"sha256": "5e653ae8439c773b27a167464b620805055e9d820a907761ab30652e65fae200"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/exact-server-dryrun.json",
"sha256": "2bfb02130876aeb71a773585dae8b446ad5c671050ebc14d0fc7bcce86dffea5"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r1/fresh-readonly-preflight.json",
"sha256": "01bbdc94ebd6fb266ab21bdc0851eac6eddeafbabcd7105cce23806931ebfbce"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-image-c103cbf-inspection.json",
"sha256": "21b4ddd3fa65743bed5eae568e0c08f2d150fcecacb7949263cef06bab99a683"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-verified-client.json",
"sha256": "ee41be2d74085603abf2bfe2c91c1bb430b4ea0539a6cbf988528b18f3f5ef46"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-verified-client.json",
"sha256": "8cd8921271cd647fe40dde0f00bc55b714313426e14091397d8fd11314c5e610"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/verified-loaded-client.json",
"sha256": "0745b5df92d2533714e2a87a43c73b3b685e7bab7bcf4444f7a5fbd82dd4722f"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-projection.json",
"sha256": "c25b43575273df0e648842d447979aca1b41ade16fcdaf9f5f870024e7ca06e9"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-consistency.json",
"sha256": "fd8a7d58d9e08b4866420ad77d01fbc7c28c0c2c9610ffbe95ddc77dddd9b1a6"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/ordinary-pipeline-preservation-finding.json",
"sha256": "43d4adc0ffbf61345865eebb3f8948f82a3c33a28fd0436eccd08bc93ba973c1"
}
]
}

View file

@ -0,0 +1,121 @@
#!/usr/bin/env python3
"""Read-only exact owner Helm reuse-values render/diff; no raw output retained."""
import copy
import hashlib
import json
import os
from pathlib import Path
import re
import subprocess
import yaml
OWNER=Path('/home/worsch/state-hub')
KUBE='/home/worsch/.kube/config-railiance01'
CHART='/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/state-hub-0.1.0.tgz'
CHART_SHA256='b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4'
TAG='main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1'
HELM=['helm','--kubeconfig',KUBE,'-n','state-hub']
DRYRUN=HELM+['upgrade','state-hub',CHART,'--reuse-values','--set-string','image.tag='+TAG,
'--dry-run=server','--hide-secret','--no-hooks','--timeout','3m']
PUBLIC_COORDINATES={'OPENBAO_K8S_TOKEN_PATH':'/var/run/secrets/openbao/token',
'FORGE_READ_SECRET_PATH':'platform/data/workloads/state-hub/forge-derivation',
'FORGE_READ_SECRET_KEY':'FORGE_READ_TOKEN'}
ALLOWED={'ConfigMap','Deployment','Job','Service','ServiceAccount','Namespace','Ingress'}
LIMIT=2*1024*1024
class Refusal(RuntimeError):pass
def digest(obj):return 'sha256:'+hashlib.sha256(json.dumps(obj,sort_keys=True,separators=(',',':')).encode()).hexdigest()
def parse(raw):
if len(raw)>LIMIT:raise Refusal('render_size_refused')
result=[]
for obj in yaml.safe_load_all(raw):
if not obj:continue
if not isinstance(obj,dict) or obj.get('kind') not in ALLOWED:raise Refusal('unexpected_or_secret_resource_refused')
result.append(obj)
return result
def sections(raw):
text=raw.decode()
if '\nMANIFEST:\n' not in text:raise Refusal('helm_render_sections_unrecognized')
before,manifest=text.split('\nMANIFEST:\n',1)
manifest=manifest.split('\nNOTES:',1)[0]
hooks=before.split('\nHOOKS:\n',1)[1] if '\nHOOKS:\n' in before else ''
return parse(hooks)+parse(manifest)
def identity(obj):
meta=obj.get('metadata') or {}
return (obj['apiVersion'],obj['kind'],meta.get('namespace') or ('' if obj['kind']=='Namespace' else 'state-hub'),meta['name'])
def diff_paths(a,b,prefix=''):
if type(a)!=type(b):return [prefix]
if isinstance(a,dict):
paths=[]
for key in sorted(set(a)|set(b)):
path=prefix+'/'+key.replace('~','~0').replace('/','~1')
paths.extend([path] if key not in a or key not in b else diff_paths(a[key],b[key],path))
return paths
if isinstance(a,list):
if len(a)!=len(b):return [prefix]
return [p for i,(x,y) in enumerate(zip(a,b)) for p in diff_paths(x,y,prefix+'/'+str(i))]
return [] if a==b else [prefix]
def compare(old,new):
baseline={identity(o):o for o in old};intended={identity(o):o for o in new}
if len(baseline)!=len(old) or len(intended)!=len(new):raise Refusal('duplicate_object_identity')
rows=[]
for key in sorted(set(baseline)|set(intended)):
a=baseline.get(key);b=intended.get(key);paths=diff_paths(a,b)
images=[]
if b and b['kind'] in {'Deployment','Job'}:
spec=b.get('spec',{}).get('template',{}).get('spec',{})
for container in (spec.get('containers',[])+spec.get('initContainers',[])):
image=container.get('image','')
if not re.fullmatch(r'forgejo\.coulomb\.social/coulomb/state-hub:main-[0-9a-f]{7}(?:@sha256:[0-9a-f]{64})?',image):raise Refusal('unexpected_image_refused')
images.append(image)
for env in container.get('env',[]):
if 'value' in env and re.search(r'PASSWORD|TOKEN|SECRET|DATABASE_URL',env.get('name',''),re.I):
if env.get('name') not in PUBLIC_COORDINATES or env['value']!=PUBLIC_COORDINATES[env['name']]:raise Refusal('literal_sensitive_env_refused')
rows.append({'api_version':key[0],'kind':key[1],'namespace':key[2],'name':key[3],
'intended_images':images,'intended_spec_sha256':digest(b.get('spec',{})) if b else None,
'baseline_object_sha256':digest(a) if a else None,'intended_object_sha256':digest(b) if b else None,
'changed_paths':paths})
image_path=re.compile(r'^/spec/template/spec/(?:initContainers|containers)/[0-9]+/image$')
only_images=all(image_path.fullmatch(p) for row in rows for p in row['changed_paths'])
return {'objects':rows,'changed_object_count':sum(bool(r['changed_paths']) for r in rows),
'intended_diff_only_images':only_images,'object_identity_set_unchanged':set(baseline)==set(intended)}
def command(args):
env=dict(os.environ);env['KUBECONFIG']=KUBE
p=subprocess.run(args,cwd=OWNER,env=env,capture_output=True,timeout=45)
if len(p.stdout)>LIMIT:raise Refusal('command_output_size_refused')
if p.returncode:
lower=p.stderr.decode(errors='replace').lower()
label=next((label for marker,label in [('reject-secret-last-applied','secret_annotation_policy_refused'),('forbidden','admission_or_auth_refused'),('cannot patch','patch_validation_refused'),('is invalid','resource_validation_refused'),('timeout','bounded_timeout'),('connection refused','api_unavailable')] if marker in lower),'unknown_refusal')
raise Refusal(label)
return p.stdout
def main():
result={'schema':'statehub.exact-reuse-values-readonly-diff.v1','status':'failed',
'dryrun_argv':DRYRUN,'production_mutations':False,'hooks_executed':False,
'raw_helm_values_release_content_logs_retained':False,
'limitations':['Dry-run admission/render only, not an actual image pull/migration/deployment.',
'Helm timeout does not stop a later live migration Job; exact scoped cancellation/quiescence remains required.']}
try:
archive=Path(CHART)
if archive.is_symlink() or not archive.is_file() or hashlib.sha256(archive.read_bytes()).hexdigest()!=CHART_SHA256:raise Refusal('reviewed_chart_archive_drift')
result['chart_archive_sha256']='sha256:'+CHART_SHA256
nodes=json.loads(command(['kubectl','--kubeconfig',KUBE,'get','nodes','-o','json']))
if not any(a.get('address')=='92.205.62.239' for n in nodes.get('items',[]) for a in n.get('status',{}).get('addresses',[])):raise Refusal('target_identity_refused')
result['stage']='baseline_release_manifest'
old=parse(command(HELM+['get','manifest','state-hub']))
result['stage']='baseline_release_hooks'
old+=parse(command(HELM+['get','hooks','state-hub']))
result['stage']='exact_upgrade_server_dryrun'
new=sections(command(DRYRUN))
result.update(compare(old,new));result['status']='passed_images_only' if result['intended_diff_only_images'] and result['object_identity_set_unchanged'] else 'review_nonimage_delta_required'
except (Refusal,subprocess.TimeoutExpired,ValueError,yaml.YAMLError) as error:
result['error_class']=type(error).__name__
result['error_label']=str(error) if isinstance(error,Refusal) else 'bounded_parse_or_command_failure'
print(json.dumps(result,indent=2))
return int(result['status']!='passed_images_only')
if __name__=='__main__':raise SystemExit(main())

View file

@ -0,0 +1,57 @@
"""Observe the approved release Job and owned Pods; never mutate resources."""
from pathlib import Path
from datetime import datetime, timezone
import json
import subprocess
import time
BASE = Path(__file__).resolve().parent
KUBE = ['kubectl', '--kubeconfig', '/home/worsch/.kube/config-railiance01', '-n', 'state-hub']
IMAGE = 'forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1'
def get(args):
result = subprocess.run(KUBE + args, capture_output=True, timeout=10)
if result.returncode:
return None
return json.loads(result.stdout) if result.stdout.strip() else {}
result = {'schema': 'state95.approved-job-observation.v1', 'mutation': False,
'started_at': datetime.now(timezone.utc).isoformat(), 'jobs': {}, 'poll_failures': 0}
deadline = time.monotonic() + 240
while time.monotonic() < deadline:
try:
job = get(['get', 'job', 'state-hub-migrate', '--ignore-not-found', '-o', 'json'])
if job is None:
result['poll_failures'] += 1
elif job:
meta = job['metadata']
images = [c['image'] for c in job['spec']['template']['spec']['containers']]
if (images != [IMAGE] or meta.get('labels', {}).get('app.kubernetes.io/instance') != 'state-hub'
or meta.get('labels', {}).get('app.kubernetes.io/managed-by') != 'Helm'
or meta.get('annotations', {}).get('helm.sh/hook') != 'pre-install,pre-upgrade'):
result['unexpected_job_identity'] = True
break
entry = result['jobs'].setdefault(meta['uid'], {'uid': meta['uid'], 'name': meta['name'],
'created_at': meta['creationTimestamp'], 'image': IMAGE, 'managed_by': 'Helm',
'release': 'state-hub', 'hook': 'pre-install,pre-upgrade', 'pods': {}})
entry['last_status'] = {k: job.get('status', {}).get(k) for k in ['active', 'succeeded', 'failed']}
pods = get(['get', 'pods', '-l', 'job-name=state-hub-migrate', '-o', 'json'])
if pods:
for pod in pods['items']:
owners = pod['metadata'].get('ownerReferences', [])
if not any(o['uid'] == meta['uid'] and o['kind'] == 'Job' for o in owners):
continue
entry['pods'][pod['metadata']['uid']] = {'name': pod['metadata']['name'],
'uid': pod['metadata']['uid'], 'owner_job_uid': meta['uid'],
'pod_ip': pod.get('status', {}).get('podIP'), 'phase': pod.get('status', {}).get('phase')}
elif result['jobs']:
result['job_absent_after_observation'] = True
(BASE / 'job-observation.json').write_text(json.dumps(result, indent=2) + '\n')
if (BASE / 'helm-return.json').exists():
result['helm_return_observed'] = True
break
except (subprocess.TimeoutExpired, ValueError, KeyError):
result['poll_failures'] += 1
time.sleep(0.7)
result['ended_at'] = datetime.now(timezone.utc).isoformat()
(BASE / 'job-observation.json').write_text(json.dumps(result, indent=2) + '\n')
print(json.dumps({'observed_trial_jobs': len(result['jobs']), 'mutation': False}))

View file

@ -0,0 +1,25 @@
# Deploy the frozen-binding API guard
Proposal **STATE-WP-0095-T10-frozen-bindings-guard-r1**, revision 2. Pending founder approval for `ADMINISTER @ realm:kubernetes/railiance01`, `activation=APPROVED`.
The approved receiver rollout is healthy at Helm 76. Its later ordinary maintenance path exposed a separate defect: the legacy binding endpoint refreshed three frozen parent rows. All fifteen task rows and the archive bytes stayed unchanged. The original failed full-row comparison is retained; the original parent preimages were not saved and will not be guessed.
The source fixes are published in State Hub c103cbf3c8bed5dba87a03e320595ddded9301a3. They protect the exact three bound parents and fifteen task UUIDs in the checker, repair engine and API binding endpoint. Ordinary inbound dependencies remain allowed. The installed checker is now hash-verified against that source. Its actual maintenance rerun omitted all three frozen bindings and preserved all eighteen **current** full rows. The unrelated staged brief accidentally included by the old writeback helper was restored through a forward commit; its original index/worktree state is preserved. Five real Git tests verify the corrected file-scoped commit behavior. Independent guard review passed 109 isolated cases; canonical guard tests passed 102. These are separate from new runtime acceptance.
Promote this verified CI artifact through the owner Helm path:
`forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1`
Use the already frozen chart archive with SHA256 b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4, preserving release values. Its fresh server dry-run passes: eight identities, three image changes. Public read-only image inspection verifies the selected guard/receiver/migration files and CI build ID; package metadata and hub-core source hashes match the deployed image. Fresh target/schema/readiness/headroom checks pass. All are refreshed before actual execution. Floating build origins and complete application/concurrent-writer acceptance remain outside these byte checks.
The exact upgrade is bound in proposal-metadata.json: stage the hash-verified archive in the specified owned remote directory, then use `--reuse-values --set-string image.tag=<the exact reference above> --atomic --timeout 3m`. Observe the exact new Job and owned Pods. Schema is already c4d5e6f7a8b9, and no migration file changed, but the existing migration hook and its recovery limitations still apply.
Verify delivered digest and module hashes, API/MCP readiness, schema and full-row preservation from a fresh **current** baseline. Run the eight prepared native cases only inside rollback transactions with commit interception enforced, then compare a fresh transaction. The prepared probe helper covers all three parents, ordinary-first invalid batches and expected-task/ownership/status refusals; its actual schema and commit-interception contracts are checked without a database connection. New probes are not yet executed. Rerun the verified-client ordinary maintenance path between current hash snapshots, preserve archive bytes and unrelated staged files, and read back source/remote/Hub bindings.
Approval includes using the current hashed rows for successor acceptance while retaining the prior parent-row mismatch as an explicit historical exception. It does not turn that failed comparison into a pass or restore its unavailable preimages. T07 and RMGR19T06 close only after the new receiving and corrected whole-pipeline checks pass with that exception recorded. All sixteen NetKingdom native target gates remain separate.
Approval must also cover [the exact conditional recovery](RECOVERY.md): only the newly observed owned Job may be cancelled with a UID precondition; verify database connection/lock quiescence before rollback to Helm **76**. Unknown mapping or mixed state stops for attended owner recovery. Helm timeout is not an outage or Job-lifetime bound; rollback retains schema.
Attributable EUR cost and credible loss exposure remain unpriced on the existing cluster. This needs scoped supervised approval and creates no autopilot, credential or monetary grant.
Revision 2 changes only the probe helper’s representation of verified source hashes to explicit module/SHA256 records, resolving the normal scanner’s hash-metadata false positive. Runtime image, commands, case logic, acceptance and recovery scope are unchanged. Original revision 1 and its digest remain recorded; it was never approved or executed.

View file

@ -0,0 +1,17 @@
# Guard successor: conditional recovery
Proposal STATE-WP-0095-T10-frozen-bindings-guard-r1, revision 1.
The prior deployed release is Helm 76, with image manifest c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015 and schema c4d5e6f7a8b9. Refresh this baseline before execution. The successor's migration files are unchanged, but its existing pre-upgrade migration hook still runs. Its three-minute Helm wait does not stop the Job or bound outage, and the Job has no active deadline.
Observe the new Job UID, creation timestamp, exact successor image, Helm release/hook ownership and owned Pod UIDs/IPs using watch_rollout.py. If Helm fails or times out with this trial Job active, revalidate all identities immediately. Approval includes deleting only this exact new Job with a UID precondition and foreground propagation, and observing its bound Pods terminate. A reused name, foreign ownership, unexpected image, unobserved UID or ambiguous mapping stops automatic recovery. No name-only or blanket deletion, finalizer removal or broad database cancellation is authorized.
Through the existing private database-owner execution path, bind migration connections to the captured Pod/IP and start window, and verify those exact connections, transactions and locks are gone. Retain only connection-identity/state/lock-count metadata. Query text, parameters, credentials and DSNs remain private. If pooling/NAT, missing observation or access makes this mapping unknown, stop for attended database-owner recovery. Pod disappearance alone is insufficient.
After verified quiescence, inspect actual schema and release state. If application rollback is needed, the approved prior target is **76**, retaining frozen Forge receiving support. Use the normal owner SSH path, KUBECONFIG=/etc/rancher/k3s/k3s.yaml, and:
```
helm -n state-hub rollback state-hub 76 --no-hooks --wait --timeout 3m
```
Verify image, readiness, schema, full-row hashes and remaining Job/Pod state. The database retains its additive schema; do not downgrade or invent old parent values. The verified installed client guard remains in use. Removing receiving support or reverting the client guard is outside this recovery. Unknown/mixed state stops for attended handling; a failed or rescued attempt remains a failed/refined outcome.

View file

@ -0,0 +1,136 @@
{
"schema": "statehub.exact-reuse-values-readonly-diff.v1",
"status": "passed_images_only",
"dryrun_argv": [
"helm",
"--kubeconfig",
"/home/worsch/.kube/config-railiance01",
"-n",
"state-hub",
"upgrade",
"state-hub",
"/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/state-hub-0.1.0.tgz",
"--reuse-values",
"--set-string",
"image.tag=main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1",
"--dry-run=server",
"--hide-secret",
"--no-hooks",
"--timeout",
"3m"
],
"production_mutations": false,
"hooks_executed": false,
"raw_helm_values_release_content_logs_retained": false,
"limitations": [
"Dry-run admission/render only, not an actual image pull/migration/deployment.",
"Helm timeout does not stop a later live migration Job; exact scoped cancellation/quiescence remains required."
],
"chart_archive_sha256": "sha256:b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4",
"stage": "exact_upgrade_server_dryrun",
"objects": [
{
"api_version": "apps/v1",
"kind": "Deployment",
"namespace": "state-hub",
"name": "state-hub",
"intended_images": [
"forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1"
],
"intended_spec_sha256": "sha256:df32d106c28b270c67aa683c8a4f20b26c430b121420c4023d34d23ede0eaed9",
"baseline_object_sha256": "sha256:01e7278447f3204ec8abfd9a7b5b6be61850995b3e792fc1f97fbc3207536d69",
"intended_object_sha256": "sha256:7b7c78921b071732c8e7c4c062bdbd26787498581102ea9916b07c1f57887a73",
"changed_paths": [
"/spec/template/spec/containers/0/image"
]
},
{
"api_version": "apps/v1",
"kind": "Deployment",
"namespace": "state-hub",
"name": "state-hub-mcp",
"intended_images": [
"forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1"
],
"intended_spec_sha256": "sha256:50ae88c8c57919bf745a772a8ff34ea7e469751a403ac39d1d01ab2e9d3a27db",
"baseline_object_sha256": "sha256:9a4376e004060a4ec2c76784fd50ec6ce05f61b3793f6458625d88122a7b8713",
"intended_object_sha256": "sha256:b78c66a3e27bca60ff4dd4f51c1bbe789a4e246be3d1e7e6fb9659ffdce80127",
"changed_paths": [
"/spec/template/spec/containers/0/image"
]
},
{
"api_version": "batch/v1",
"kind": "Job",
"namespace": "state-hub",
"name": "state-hub-migrate",
"intended_images": [
"forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1"
],
"intended_spec_sha256": "sha256:2eb273b5e2ca5538fa1b13a8cf8cd10d259ad7cd3510bce1e86075f8c4c4a915",
"baseline_object_sha256": "sha256:6909dca9acd5e1b816491b91b6a32ef6d934e288e2d8d0d3d66fac9fe67468ec",
"intended_object_sha256": "sha256:208b52d9b958b9d4490182bda4d0da27b4a6f0961f6bf182c34ef4b640fcbb5e",
"changed_paths": [
"/spec/template/spec/containers/0/image"
]
},
{
"api_version": "v1",
"kind": "ConfigMap",
"namespace": "state-hub",
"name": "state-hub-classification-allowed",
"intended_images": [],
"intended_spec_sha256": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
"baseline_object_sha256": "sha256:924d16a0a6b4ba8a46b59f0990dcc2adc6dd813cf5d7d83bdb389844068d7cfd",
"intended_object_sha256": "sha256:924d16a0a6b4ba8a46b59f0990dcc2adc6dd813cf5d7d83bdb389844068d7cfd",
"changed_paths": []
},
{
"api_version": "v1",
"kind": "ConfigMap",
"namespace": "state-hub",
"name": "state-hub-config",
"intended_images": [],
"intended_spec_sha256": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
"baseline_object_sha256": "sha256:26707b20933b4f6de78f9059c0efec6df7f0e90c8f1a67db6d2f1ac72e674560",
"intended_object_sha256": "sha256:26707b20933b4f6de78f9059c0efec6df7f0e90c8f1a67db6d2f1ac72e674560",
"changed_paths": []
},
{
"api_version": "v1",
"kind": "Service",
"namespace": "state-hub",
"name": "state-hub",
"intended_images": [],
"intended_spec_sha256": "sha256:da5895e6aee1f619d16c07dafd4342cf7ec8f9de0944a84979c624a4e9eea22a",
"baseline_object_sha256": "sha256:62098bbc3ef6265e072f416ecb11de85d59fce7e2e0d22b2616bd233e720dafe",
"intended_object_sha256": "sha256:62098bbc3ef6265e072f416ecb11de85d59fce7e2e0d22b2616bd233e720dafe",
"changed_paths": []
},
{
"api_version": "v1",
"kind": "Service",
"namespace": "state-hub",
"name": "state-hub-mcp",
"intended_images": [],
"intended_spec_sha256": "sha256:4e04175b03bcd75833109d6843e282cee79d73eae2bc85e36097264b832ba26f",
"baseline_object_sha256": "sha256:ab096d239c9cd72e6177a260d9b4d548a7d5b7c0a285c3a11b7267193e336bba",
"intended_object_sha256": "sha256:ab096d239c9cd72e6177a260d9b4d548a7d5b7c0a285c3a11b7267193e336bba",
"changed_paths": []
},
{
"api_version": "v1",
"kind": "ServiceAccount",
"namespace": "state-hub",
"name": "state-hub",
"intended_images": [],
"intended_spec_sha256": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a",
"baseline_object_sha256": "sha256:750594b51a534d603f50640d02a3c4eec79cc52fe07d5f442102d37b7299adb8",
"intended_object_sha256": "sha256:750594b51a534d603f50640d02a3c4eec79cc52fe07d5f442102d37b7299adb8",
"changed_paths": []
}
],
"changed_object_count": 3,
"intended_diff_only_images": true,
"object_identity_set_unchanged": true
}

View file

@ -0,0 +1,46 @@
{
"schema": "state95.guard-successor-readonly-preflight.v1",
"observed_at": "2026-10-17T00:33:19.687847+00:00",
"target": "railiance01/92.205.62.239",
"node_identity_verified": true,
"kubeconfig": "/home/worsch/.kube/config-railiance01",
"helm_revision": 76,
"current_image_manifest": "sha256:c802690ee1811b3d77df4077936f9cdced1385514e8673fcbc9232b84d645015",
"health": {
"status": "ok",
"db": "connected",
"instance_role": "primary",
"instance_label": "railiance01",
"schema": {
"status": "ok",
"applied": "c4d5e6f7a8b9",
"expected": "c4d5e6f7a8b9"
}
},
"headroom": {
"schema": "state-hub.release-headroom-preflight.v1",
"ok": true,
"observed_at": "2026-10-17T00:33:19.561580+00:00",
"freshness_seconds": 0,
"remaining_cpu_m": 420,
"remaining_memory_bytes": 6535979008,
"pending_unrelated_cpu_m": 0,
"api_surge_cpu_m": 100,
"mcp_surge_cpu_m": 10,
"migrate_cpu_m": 50,
"atomic": true,
"reasons": [],
"notes": [
"Aggregate remaining millicores is not a kube-scheduler guarantee.",
"Preflight does not lower requests and does not start Helm."
],
"hook_order": [
"pre-upgrade migrate job (helm.sh/hook-weight -5)",
"API RollingUpdate maxSurge=1 maxUnavailable=0",
"MCP RollingUpdate maxSurge=1 maxUnavailable=0"
]
},
"migration_job_and_pods_absent": true,
"runtime_readback_ref": "../receiver-rollout-r4/final-runtime-check.json",
"live_changes": false
}

View file

@ -0,0 +1,82 @@
"""Prepared owner in-pod probes. Requires separate approval; commits are intercepted."""
import asyncio,hashlib,json,logging,uuid
from pathlib import Path
logging.disable(logging.CRITICAL)
EXPECTED = [
{
"module": "api.services.historical_projection",
"sha256": "e24e57c58f4aaa4ec9d9bf088009ac69006e53f75b9477ee53dc26c4e850b975"
},
{
"module": "api.routers.workstreams",
"sha256": "9c9bf4376dd323b52109912bb3f615949e89ac02c8b88b4720f569f8565ad1d6"
}
]
ORDINARY='e0a7813d-c916-5e49-84b2-5e5b30441891'
class UnexpectedCommit(Exception):pass
class NoCommit:
def __init__(self,session):self.session=session;self.attempts=0
async def execute(self,*args,**kwargs):return await self.session.execute(*args,**kwargs)
async def commit(self):self.attempts+=1;raise UnexpectedCommit()
def digest(v):return 'sha256:'+hashlib.sha256(json.dumps(v,sort_keys=True,separators=(',',':'),ensure_ascii=False).encode()).hexdigest()
async def main():
import importlib
from sqlalchemy import text
from fastapi import HTTPException
for entry in EXPECTED:
name,pin=entry["module"],entry["sha256"]
module=importlib.import_module(name);assert hashlib.sha256(Path(module.__file__).read_bytes()).hexdigest()==pin
from api.database import async_session_factory,engine
from api.services.historical_projection import FROZEN_CLUSTER_BINDINGS
from api.routers.workstreams import sync_workplan_bindings
from api.schemas.workplan import WorkplanBindingsSync
engine.echo=False
entries=FROZEN_CLUSTER_BINDINGS;assert len(entries)==3
parents=[v['uuid'] for v in entries];task_ids=[t['uuid'] for v in entries for t in v['tasks']];assert len(task_ids)==15
def body(ordinary=False):
values=[dict(workplan_id=v['uuid'],repo_slug=v['repo'],filename=Path(v['path']).name,relative_path=v['path'],archived=True,status='finished') for v in entries]
if ordinary:values.insert(0,dict(workplan_id=ORDINARY,repo_slug='railiance-cluster',filename='RCLUSTER-WP-0018-keycape-original-tls-recovery.md',relative_path='workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md',archived=False,status='active'))
return values
async def snapshot(session):
result={}
for table,ids in [('workplans',parents+[ORDINARY]),('tasks',task_ids)]:
rows=(await session.execute(text('SELECT to_jsonb(row) FROM '+table+' AS row WHERE row.id=ANY(:ids) ORDER BY row.id'),{'ids':[uuid.UUID(v) for v in ids]})).scalars().all()
assert len(rows)==len(ids) and {v['id'] for v in rows}==set(ids)
result[table]=digest(rows)
return result
cases={};before=None
async with async_session_factory() as session:
try:
await session.execute(text("SET LOCAL statement_timeout='5s'"));await session.execute(text("SET LOCAL lock_timeout='1s'"));await session.execute(text("SET LOCAL idle_in_transaction_session_timeout='10s'"))
before=await snapshot(session)
for name in ['preserve-three','invalid-path-mixed','foreign-repo-mixed','missing-task-mixed','foreign-holder-mixed','nonterminal-parent-mixed','nonterminal-task-mixed','invalid-last-binding-mixed']:
nested=await session.begin_nested();proxy=NoCommit(session);outcome='unverified'
try:
values=body(ordinary=name!='preserve-three')
if name=='invalid-path-mixed':values[1]['relative_path']='workplans/incorrect.md'
if name=='foreign-repo-mixed':values[1]['repo_slug']='foreign'
if name=='missing-task-mixed':await session.execute(text('DELETE FROM tasks WHERE id=:id'),{'id':uuid.UUID(task_ids[0])})
if name=='foreign-holder-mixed':await session.execute(text('UPDATE tasks SET workplan_id=:parent WHERE id=:id'),{'id':uuid.UUID(task_ids[0]),'parent':uuid.UUID(ORDINARY)})
if name=='nonterminal-parent-mixed':await session.execute(text("UPDATE workplans SET status='active' WHERE id=:id"),{'id':uuid.UUID(parents[0])})
if name=='nonterminal-task-mixed':await session.execute(text("UPDATE tasks SET status='progress' WHERE id=:id"),{'id':uuid.UUID(task_ids[0])})
if name=='invalid-last-binding-mixed':values[-1]['archived']=False
try:
answer=await sync_workplan_bindings(WorkplanBindingsSync(bindings=values),proxy)
assert name=='preserve-three' and answer=={'updated':0,'received':3,'preserved':3}
outcome='preserved'
except HTTPException as exc:
assert name!='preserve-three' and exc.status_code==409;outcome='refused'
assert proxy.attempts==0
finally:
await nested.rollback();session.expire_all()
restored=await snapshot(session);assert restored==before
cases[name]={'status':'passed','outcome':outcome,'commit_attempts':proxy.attempts,'rolled_back':True,'full_rows_restored':True}
finally:await session.rollback()
async with async_session_factory() as fresh:
try:after=await snapshot(fresh);assert before==after
finally:await fresh.rollback()
await engine.dispose()
print(json.dumps({'schema':'state95.native-guard-probes.v1','status':'passed','cases':cases,'before_full_row_hashes':before,'after_full_row_hashes':after,'historical_parents':3,'historical_tasks':15,'ordinary_parent_also_preserved':True,'fresh_transaction_full_rows_equal':True,'commits_performed':0,'commit_interception_enforced':True,'raw_rows_or_credentials_retained':False,'limits':['No claim of restoring pre-legacy-refresh parent preimages.','Missing actual parent/repo rows and full concurrent-writer behavior remain source-test coverage, not claimed as these native cases.']},sort_keys=True))
if __name__=='__main__':
try:asyncio.run(main())
except BaseException:print(json.dumps({'schema':'state95.native-guard-probes.v1','status':'refused-or-unverified','raw_rows_or_credentials_retained':False}));raise SystemExit(1)

View file

@ -0,0 +1,18 @@
{
"workplan_id": "79579572-8120-5d3b-aca5-dd4aff60d058",
"id": "df703266-6719-4c04-ae1b-ba9afd3bca1c",
"topic_id": null,
"title": "Review exact frozen-binding API guard successor and retained baseline exception",
"description": "Pending proposal STATE-WP-0095-T10-frozen-bindings-guard-r1 revision2 SHA2565d0ddebc21bcb035809cc8b57f4c2e1ba8ed09204be5b965460e178a90913f1e. Image main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1; frozen chart b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4. Eight-identity image-only server dry-run and explicit target/headroom/schema pass. Verified installed checker maintenance preserves all18 CURRENT rows; prior three-parent hash failures remain historical exceptions, never restored or backfilled. Requested ADMINISTER @ realm:kubernetes/railiance01 activation=APPROVED includes exact new Job conditional recovery, rollback76 after verified quiescence, current-baseline successor acceptance, unpriced cost/risk and attended stop for unknown mapping. Full review: the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/FINAL-PROPOSAL.md. No new runtime is approved or executed. Original revision1 remains retained and unexecuted. Revision2 only represents source hashes as typed metadata after the normal scanner false positive; runtime, case logic, acceptance and recovery scope are unchanged.",
"decision_type": "pending",
"status": "open",
"rationale": "Agent-prepared exact new-code proposal. Only the founder may resolve approval; prior receiver revision4 approval does not cover this new image.",
"decided_by": null,
"decided_at": null,
"deadline": null,
"escalation_note": null,
"superseded_by": null,
"created_at": "2026-10-17T00:37:26.205185Z",
"updated_at": "2026-10-17T00:48:51.550636Z",
"workstream_id": "79579572-8120-5d3b-aca5-dd4aff60d058"
}

View file

@ -0,0 +1,11 @@
{
"status": "prepared-helper-contract-checked",
"actual_workplan_binding_schema_accepts_exact_three": true,
"commit_interception_checked_with_actual_unbound_AsyncSession": true,
"DB_connected": false,
"native_probes_executed": false,
"revision": 2,
"expected_module_hashes_equal_revision1": true,
"probe_logic_after_hash_loading_byte_identical": true,
"syntax_checked": true
}

View file

@ -0,0 +1,108 @@
{
"schema": "custodian.supervised-runtime-proposal.v1",
"proposal_id": "STATE-WP-0095-T10-frozen-bindings-guard-r1",
"revision": 2,
"status": "pending_supervisor_approval_not_executed",
"prepared_at": "2026-10-17T00:48:23.064918+00:00",
"owner_task_id": "STATE-WP-0095-T10",
"owner_task_uuid": "88585c69-d9b9-5e1f-a256-6416ff71e824",
"target": "railiance01/92.205.62.239 state-hub release API/MCP and exact-new-trial migration Job",
"authority_requested": "ADMINISTER @ realm:kubernetes/railiance01 activation=APPROVED",
"source_commit": "c103cbf3c8bed5dba87a03e320595ddded9301a3",
"image": "forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1",
"image_digest": "sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1",
"chart_archive": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/state-hub-0.1.0.tgz",
"chart_sha256": "b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4",
"remote_owned_chart": "/tmp/statehub-binding-guard-b5c0663d830f/state-hub-0.1.0.tgz",
"expected_prior_helm_revision": 76,
"expected_schema": "c4d5e6f7a8b9",
"migration_files_changed_since_deployed_source": false,
"exact_upgrade_argv": [
"ssh",
"railiance01",
"KUBECONFIG=/etc/rancher/k3s/k3s.yaml helm -n state-hub upgrade state-hub /tmp/statehub-binding-guard-b5c0663d830f/state-hub-0.1.0.tgz --reuse-values --set-string image.tag=main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1 --atomic --timeout 3m"
],
"staging": "Create exact new private owned directory, refuse unexpected existing ownership/content, copy only frozen chart, verify remote SHA before execution and remove only owned exact archive/directory after proof.",
"readiness_refresh_required_before_execution": true,
"native_probe_cases": 8,
"verification": [
"Delivered manifest and guard module hashes, API/MCP Ready, primary/railiance01 and expected schema.",
"Fresh CURRENT full historical-row hashes before and after; enforce rollback and commit interception for eight exact native cases, then fresh-transaction comparison including ordinary parent.",
"Verified installed local CLI guard, ordinary consistency/fast projection between current snapshots, archive bytes and unrelated staged work preserved; source/remote/Hub IDs/statuses read back."
],
"acceptance_disposition_requested": "Use current hashed baseline for successor acceptance; retain the earlier three-parent mismatch as a historical exception, without guessed restoration or backfilling its failed result. T07/RMGR19T06 close only after new receiving and corrected pipeline pass with exception recorded.",
"conditional_recovery_included": true,
"rollback_helm_revision": 76,
"recovery_limits": "Exact observed new Job UID/image/ownership and bound Pods only; foreground UID-precondition cancellation after revalidation. Verify private owner DB connection/transaction/lock quiescence; unknown mapping/mixed state stops for attended recovery. No schema downgrade or broad backend termination.",
"cost_estimate_eur": null,
"risk_estimate_eur": null,
"cost_and_risk_disposition": "Unpriced attributable cost and credible loss/outage exposure on existing infrastructure require supervised founder acceptance. Helm timeout is not Job/outage bound.",
"autopilot_grant": false,
"bound_receipts": [
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/FINAL-PROPOSAL.md",
"sha256": "5ff105f0eb66e85f6d5c64a496e5f1ce7b816a32fb93351f4cd07133b9a053fd"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/RECOVERY.md",
"sha256": "dc72dea7cdf519a712ee8f6d28fc6aa5667b44655d948f2c0160869383f33cef"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/native_binding_probes.py",
"sha256": "ce492d0713c987e47eefc991a6312c1c63ed72056a597e9e28aee959d06e71d5"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/probe-helper-preparation-check.json",
"sha256": "36feaa02e17850c56685ccaf78556d12447fdeddae9c483721cd996da848f400"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/watch_rollout.py",
"sha256": "a496da3c9a415ac800921ce755446be4bb55bc17e4e6b913143a5d6baf48f815"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/reuse_values_dryrun.py",
"sha256": "5e653ae8439c773b27a167464b620805055e9d820a907761ab30652e65fae200"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/exact-server-dryrun.json",
"sha256": "2bfb02130876aeb71a773585dae8b446ad5c671050ebc14d0fc7bcce86dffea5"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-successor-review-r2/fresh-readonly-preflight.json",
"sha256": "01bbdc94ebd6fb266ab21bdc0851eac6eddeafbabcd7105cce23806931ebfbce"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/guard-image-c103cbf-inspection.json",
"sha256": "21b4ddd3fa65743bed5eae568e0c08f2d150fcecacb7949263cef06bab99a683"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/before-verified-client.json",
"sha256": "ee41be2d74085603abf2bfe2c91c1bb430b4ea0539a6cbf988528b18f3f5ef46"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/after-verified-client.json",
"sha256": "8cd8921271cd647fe40dde0f00bc55b714313426e14091397d8fd11314c5e610"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/verified-loaded-client.json",
"sha256": "0745b5df92d2533714e2a87a43c73b3b685e7bab7bcf4444f7a5fbd82dd4722f"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-projection.json",
"sha256": "c25b43575273df0e648842d447979aca1b41ade16fcdaf9f5f870024e7ca06e9"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/verified-client-cluster-consistency.json",
"sha256": "fd8a7d58d9e08b4866420ad77d01fbc7c28c0c2c9610ffbe95ddc77dddd9b1a6"
},
{
"path": "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/receiver-rollout-r4/ordinary-pipeline-preservation-finding.json",
"sha256": "43d4adc0ffbf61345865eebb3f8948f82a3c33a28fd0436eccd08bc93ba973c1"
}
],
"supersedes": {
"revision": 1,
"sha256": "81d365926fc585a186955d8c98ee83501fd3cec12135b2256d71b46a75097932",
"reason": "Explicit module/SHA256 metadata representation in probe helper; no runtime/acceptance/recovery change."
}
}

View file

@ -0,0 +1,121 @@
#!/usr/bin/env python3
"""Read-only exact owner Helm reuse-values render/diff; no raw output retained."""
import copy
import hashlib
import json
import os
from pathlib import Path
import re
import subprocess
import yaml
OWNER=Path('/home/worsch/state-hub')
KUBE='/home/worsch/.kube/config-railiance01'
CHART='/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r4-rollout-review/state-hub-0.1.0.tgz'
CHART_SHA256='b5c0663d830fc8d3b65080f237a0be8d01f8b2f7fec9dc33aeba91b1b6b281d4'
TAG='main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1'
HELM=['helm','--kubeconfig',KUBE,'-n','state-hub']
DRYRUN=HELM+['upgrade','state-hub',CHART,'--reuse-values','--set-string','image.tag='+TAG,
'--dry-run=server','--hide-secret','--no-hooks','--timeout','3m']
PUBLIC_COORDINATES={'OPENBAO_K8S_TOKEN_PATH':'/var/run/secrets/openbao/token',
'FORGE_READ_SECRET_PATH':'platform/data/workloads/state-hub/forge-derivation',
'FORGE_READ_SECRET_KEY':'FORGE_READ_TOKEN'}
ALLOWED={'ConfigMap','Deployment','Job','Service','ServiceAccount','Namespace','Ingress'}
LIMIT=2*1024*1024
class Refusal(RuntimeError):pass
def digest(obj):return 'sha256:'+hashlib.sha256(json.dumps(obj,sort_keys=True,separators=(',',':')).encode()).hexdigest()
def parse(raw):
if len(raw)>LIMIT:raise Refusal('render_size_refused')
result=[]
for obj in yaml.safe_load_all(raw):
if not obj:continue
if not isinstance(obj,dict) or obj.get('kind') not in ALLOWED:raise Refusal('unexpected_or_secret_resource_refused')
result.append(obj)
return result
def sections(raw):
text=raw.decode()
if '\nMANIFEST:\n' not in text:raise Refusal('helm_render_sections_unrecognized')
before,manifest=text.split('\nMANIFEST:\n',1)
manifest=manifest.split('\nNOTES:',1)[0]
hooks=before.split('\nHOOKS:\n',1)[1] if '\nHOOKS:\n' in before else ''
return parse(hooks)+parse(manifest)
def identity(obj):
meta=obj.get('metadata') or {}
return (obj['apiVersion'],obj['kind'],meta.get('namespace') or ('' if obj['kind']=='Namespace' else 'state-hub'),meta['name'])
def diff_paths(a,b,prefix=''):
if type(a)!=type(b):return [prefix]
if isinstance(a,dict):
paths=[]
for key in sorted(set(a)|set(b)):
path=prefix+'/'+key.replace('~','~0').replace('/','~1')
paths.extend([path] if key not in a or key not in b else diff_paths(a[key],b[key],path))
return paths
if isinstance(a,list):
if len(a)!=len(b):return [prefix]
return [p for i,(x,y) in enumerate(zip(a,b)) for p in diff_paths(x,y,prefix+'/'+str(i))]
return [] if a==b else [prefix]
def compare(old,new):
baseline={identity(o):o for o in old};intended={identity(o):o for o in new}
if len(baseline)!=len(old) or len(intended)!=len(new):raise Refusal('duplicate_object_identity')
rows=[]
for key in sorted(set(baseline)|set(intended)):
a=baseline.get(key);b=intended.get(key);paths=diff_paths(a,b)
images=[]
if b and b['kind'] in {'Deployment','Job'}:
spec=b.get('spec',{}).get('template',{}).get('spec',{})
for container in (spec.get('containers',[])+spec.get('initContainers',[])):
image=container.get('image','')
if not re.fullmatch(r'forgejo\.coulomb\.social/coulomb/state-hub:main-[0-9a-f]{7}(?:@sha256:[0-9a-f]{64})?',image):raise Refusal('unexpected_image_refused')
images.append(image)
for env in container.get('env',[]):
if 'value' in env and re.search(r'PASSWORD|TOKEN|SECRET|DATABASE_URL',env.get('name',''),re.I):
if env.get('name') not in PUBLIC_COORDINATES or env['value']!=PUBLIC_COORDINATES[env['name']]:raise Refusal('literal_sensitive_env_refused')
rows.append({'api_version':key[0],'kind':key[1],'namespace':key[2],'name':key[3],
'intended_images':images,'intended_spec_sha256':digest(b.get('spec',{})) if b else None,
'baseline_object_sha256':digest(a) if a else None,'intended_object_sha256':digest(b) if b else None,
'changed_paths':paths})
image_path=re.compile(r'^/spec/template/spec/(?:initContainers|containers)/[0-9]+/image$')
only_images=all(image_path.fullmatch(p) for row in rows for p in row['changed_paths'])
return {'objects':rows,'changed_object_count':sum(bool(r['changed_paths']) for r in rows),
'intended_diff_only_images':only_images,'object_identity_set_unchanged':set(baseline)==set(intended)}
def command(args):
env=dict(os.environ);env['KUBECONFIG']=KUBE
p=subprocess.run(args,cwd=OWNER,env=env,capture_output=True,timeout=45)
if len(p.stdout)>LIMIT:raise Refusal('command_output_size_refused')
if p.returncode:
lower=p.stderr.decode(errors='replace').lower()
label=next((label for marker,label in [('reject-secret-last-applied','secret_annotation_policy_refused'),('forbidden','admission_or_auth_refused'),('cannot patch','patch_validation_refused'),('is invalid','resource_validation_refused'),('timeout','bounded_timeout'),('connection refused','api_unavailable')] if marker in lower),'unknown_refusal')
raise Refusal(label)
return p.stdout
def main():
result={'schema':'statehub.exact-reuse-values-readonly-diff.v1','status':'failed',
'dryrun_argv':DRYRUN,'production_mutations':False,'hooks_executed':False,
'raw_helm_values_release_content_logs_retained':False,
'limitations':['Dry-run admission/render only, not an actual image pull/migration/deployment.',
'Helm timeout does not stop a later live migration Job; exact scoped cancellation/quiescence remains required.']}
try:
archive=Path(CHART)
if archive.is_symlink() or not archive.is_file() or hashlib.sha256(archive.read_bytes()).hexdigest()!=CHART_SHA256:raise Refusal('reviewed_chart_archive_drift')
result['chart_archive_sha256']='sha256:'+CHART_SHA256
nodes=json.loads(command(['kubectl','--kubeconfig',KUBE,'get','nodes','-o','json']))
if not any(a.get('address')=='92.205.62.239' for n in nodes.get('items',[]) for a in n.get('status',{}).get('addresses',[])):raise Refusal('target_identity_refused')
result['stage']='baseline_release_manifest'
old=parse(command(HELM+['get','manifest','state-hub']))
result['stage']='baseline_release_hooks'
old+=parse(command(HELM+['get','hooks','state-hub']))
result['stage']='exact_upgrade_server_dryrun'
new=sections(command(DRYRUN))
result.update(compare(old,new));result['status']='passed_images_only' if result['intended_diff_only_images'] and result['object_identity_set_unchanged'] else 'review_nonimage_delta_required'
except (Refusal,subprocess.TimeoutExpired,ValueError,yaml.YAMLError) as error:
result['error_class']=type(error).__name__
result['error_label']=str(error) if isinstance(error,Refusal) else 'bounded_parse_or_command_failure'
print(json.dumps(result,indent=2))
return int(result['status']!='passed_images_only')
if __name__=='__main__':raise SystemExit(main())

View file

@ -0,0 +1,6 @@
{
"status": "original_draft_bytes_reconstructed_in_memory",
"original_helper_sha256": "ef5c07affb15d20b4194edda68fd14b4d0fee1e9dab857e3242c3a1a1e49046f",
"native_probes_executed": false,
"source_or_private_values_printed": false
}

View file

@ -0,0 +1,28 @@
"""Reconstruct the unexecuted draft's bytes in memory from published revision 2.
This audits the retained original proposal digest without executing a probe or
printing source. Only the source-hash metadata representation was refined.
"""
from pathlib import Path
import ast
import hashlib
import json
base = Path(__file__).resolve().parent
source = (base / 'native_binding_probes.py').read_text()
assignment = next(n for n in ast.parse(source).body if isinstance(n, ast.Assign)
and any(isinstance(t, ast.Name) and t.id == 'EXPECTED' for t in n.targets))
records = ast.literal_eval(assignment.value)
lines = source.splitlines()
lines[assignment.lineno - 1:assignment.end_lineno] = [
'EXPECTED={' + ','.join(repr(r['module']) + ':' + repr(r['sha256']) for r in records) + '}']
original = ('\n'.join(lines) + '\n').replace(
' for entry in EXPECTED:\n name,pin=entry["module"],entry["sha256"]',
' for name,pin in EXPECTED.items():')
digest = hashlib.sha256(original.encode()).hexdigest()
assert digest == 'ef5c07affb15d20b4194edda68fd14b4d0fee1e9dab857e3242c3a1a1e49046f'
result = {'status': 'original_draft_bytes_reconstructed_in_memory',
'original_helper_sha256': digest, 'native_probes_executed': False,
'source_or_private_values_printed': False}
(base / 'revision1-preimage-reconstruction.json').write_text(json.dumps(result, indent=2) + '\n')
print(json.dumps(result))

View file

@ -0,0 +1,57 @@
"""Observe the approved release Job and owned Pods; never mutate resources."""
from pathlib import Path
from datetime import datetime, timezone
import json
import subprocess
import time
BASE = Path(__file__).resolve().parent
KUBE = ['kubectl', '--kubeconfig', '/home/worsch/.kube/config-railiance01', '-n', 'state-hub']
IMAGE = 'forgejo.coulomb.social/coulomb/state-hub:main-c103cbf@sha256:4cc4ce17bbcdb1b66132d07c5b7b741f46df83124ef1c8403ffabdafba6993d1'
def get(args):
result = subprocess.run(KUBE + args, capture_output=True, timeout=10)
if result.returncode:
return None
return json.loads(result.stdout) if result.stdout.strip() else {}
result = {'schema': 'state95.approved-job-observation.v1', 'mutation': False,
'started_at': datetime.now(timezone.utc).isoformat(), 'jobs': {}, 'poll_failures': 0}
deadline = time.monotonic() + 240
while time.monotonic() < deadline:
try:
job = get(['get', 'job', 'state-hub-migrate', '--ignore-not-found', '-o', 'json'])
if job is None:
result['poll_failures'] += 1
elif job:
meta = job['metadata']
images = [c['image'] for c in job['spec']['template']['spec']['containers']]
if (images != [IMAGE] or meta.get('labels', {}).get('app.kubernetes.io/instance') != 'state-hub'
or meta.get('labels', {}).get('app.kubernetes.io/managed-by') != 'Helm'
or meta.get('annotations', {}).get('helm.sh/hook') != 'pre-install,pre-upgrade'):
result['unexpected_job_identity'] = True
break
entry = result['jobs'].setdefault(meta['uid'], {'uid': meta['uid'], 'name': meta['name'],
'created_at': meta['creationTimestamp'], 'image': IMAGE, 'managed_by': 'Helm',
'release': 'state-hub', 'hook': 'pre-install,pre-upgrade', 'pods': {}})
entry['last_status'] = {k: job.get('status', {}).get(k) for k in ['active', 'succeeded', 'failed']}
pods = get(['get', 'pods', '-l', 'job-name=state-hub-migrate', '-o', 'json'])
if pods:
for pod in pods['items']:
owners = pod['metadata'].get('ownerReferences', [])
if not any(o['uid'] == meta['uid'] and o['kind'] == 'Job' for o in owners):
continue
entry['pods'][pod['metadata']['uid']] = {'name': pod['metadata']['name'],
'uid': pod['metadata']['uid'], 'owner_job_uid': meta['uid'],
'pod_ip': pod.get('status', {}).get('podIP'), 'phase': pod.get('status', {}).get('phase')}
elif result['jobs']:
result['job_absent_after_observation'] = True
(BASE / 'job-observation.json').write_text(json.dumps(result, indent=2) + '\n')
if (BASE / 'helm-return.json').exists():
result['helm_return_observed'] = True
break
except (subprocess.TimeoutExpired, ValueError, KeyError):
result['poll_failures'] += 1
time.sleep(0.7)
result['ended_at'] = datetime.now(timezone.utc).isoformat()
(BASE / 'job-observation.json').write_text(json.dumps(result, indent=2) + '\n')
print(json.dumps({'observed_trial_jobs': len(result['jobs']), 'mutation': False}))

View file

@ -0,0 +1,59 @@
"""Resolve and inspect public guard image bytes; no pull, install or execution."""
from pathlib import Path,PurePosixPath
import argparse,hashlib,io,json,re,tarfile,time,urllib.request,urllib.parse
p=argparse.ArgumentParser();p.add_argument('--commit',required=True);a=p.parse_args();assert re.fullmatch('[0-9a-f]{40}',a.commit)
here=Path(__file__).resolve().parent;owner=Path('/home/worsch/state-hub');short=a.commit[:7]
host='https://forgejo.coulomb.social';base='/v2/coulomb/state-hub/';deadline=time.monotonic()+180
class NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self,*args,**kwargs):raise RuntimeError('redirect-refused')
opener=urllib.request.build_opener(urllib.request.ProxyHandler({}),NoRedirect)
def get(path,limit,token=None,accept=None):
assert time.monotonic()<deadline
headers={}
if token:headers['Authorization']='Bearer '+token
if accept:headers['Accept']=accept
with opener.open(urllib.request.Request(host+path,headers=headers),timeout=30) as r:raw=r.read(limit+1)
assert len(raw)<=limit
return raw
query=urllib.parse.urlencode({'service':'container_registry','scope':'repository:coulomb/state-hub:pull'})
auth=json.loads(get('/v2/token?'+query,65536));token=auth.get('token',auth.get('access_token'));assert isinstance(token,str) and len(token)<60000
raw=get(base+'manifests/main-'+short,1048576,token,'application/vnd.docker.distribution.manifest.v2+json');digest='sha256:'+hashlib.sha256(raw).hexdigest()
assert get(base+'manifests/'+digest,1048576,token,'application/vnd.docker.distribution.manifest.v2+json')==raw
m=json.loads(raw);assert m['schemaVersion']==2 and len(m['layers'])<=80 and sum(v['size'] for v in m['layers'])<=500*1024**2
selected=['api/services/historical_projection.py','api/routers/workstreams.py','scripts/consistency_check.py','api/services/forge_projection.py','migrations/versions/c4d5e6f7a8b9_inbox_feed_revision.py']
expected={'app/'+rel:'sha256:'+hashlib.sha256((owner/rel).read_bytes()).hexdigest() for rel in selected}
expected['tmp/.ci-build-id']='sha256:'+hashlib.sha256((short+'\n').encode()).hexdigest()
files={};packages={};layers=[]
for layer in m['layers']:
pin=layer['digest'];assert re.fullmatch('sha256:[0-9a-f]{64}',pin) and 0<=layer['size']<=160*1024**2
blob=get(base+'blobs/'+pin,layer['size'],token);assert len(blob)==layer['size'] and 'sha256:'+hashlib.sha256(blob).hexdigest()==pin
layer_files={};layer_packages={};whiteouts=[]
with tarfile.open(fileobj=io.BytesIO(blob),mode='r|*') as tar:
count=0
for entry in tar:
count+=1;assert count<=100000 and time.monotonic()<deadline
path=entry.name.removeprefix('./');assert not path.startswith('/') and '..' not in PurePosixPath(path).parts
parent,_,name=path.rpartition('/')
if name.startswith('.wh.'):
whiteouts.append((parent,name));continue
code=path in expected or '/site-packages/hub_core/' in path and path.endswith('.py') or path.startswith('tmp/hub-core/hub_core/') and path.endswith('.py')
meta='/site-packages/' in path and path.endswith('.dist-info/METADATA')
if not code and not meta:continue
assert entry.isfile() and entry.size<=2*1024**2;data=tar.extractfile(entry).read(2*1024**2+1);assert len(data)==entry.size
if code:layer_files[path]='sha256:'+hashlib.sha256(data).hexdigest()
if meta:
text=data.decode();names=re.findall(r'^Name: ([A-Za-z0-9_.-]+)$',text,re.M);versions=re.findall(r'^Version: ([A-Za-z0-9_.+!-]+)$',text,re.M);assert len(names)==len(versions)==1
layer_packages[path]={'name':names[0],'version':versions[0],'metadata_sha256':'sha256:'+hashlib.sha256(data).hexdigest()}
for parent,name in whiteouts:
erased=str(PurePosixPath(parent)/name[4:])
for view in [files,packages]:
for key in list(view):
opaque=name=='.wh..wh..opq' and (not parent or key.startswith(parent+'/'))
if opaque or key==erased or key.startswith(erased+'/'):del view[key]
files.update(layer_files);packages.update(layer_packages)
layers.append({'digest':pin,'compressed_bytes':len(blob),'archive_entries':count,'whiteouts':len(whiteouts)});del blob
assert all(files.get(k)==v for k,v in expected.items()),'selected-source-or-build-id-mismatch'
old=json.loads((here/'statehub-public-image-inspection.json').read_text());old_packages=old['python_package_metadata'];old_hub={k:v for k,v in old['files'].items() if '/hub_core/' in k};new_hub={k:v for k,v in files.items() if '/hub_core/' in k}
r={'schema':'statehub.guard-image-inspection.v1','status':'verified-selected-public-image-bytes','source_commit':a.commit,'tag':'main-'+short,'image_digest':digest,'selected_source_hashes':expected,'observed_files':files,'layers':layers,'python_package_metadata':packages,'package_metadata_equal_to_deployed_image':packages==old_packages,'hub_core_source_hashes_equal_to_deployed_image':new_hub==old_hub,'image_executed':False,'image_installed_or_daemon_pulled':False,'anonymous_protocol_only':True,'token_retained':False,'limitations':['Selected code hashes and package inventory do not prove full application acceptance or hermetic provenance.','Floating dependency origins remain unknown; observed byte changes require explicit review.','New API behavior is not deployed or natively accepted.']}
del token,auth
(here/('guard-image-'+short+'-inspection.json')).write_text(json.dumps(r,indent=2)+'\n');print(json.dumps({k:r[k] for k in ['status','source_commit','image_digest','package_metadata_equal_to_deployed_image','hub_core_source_hashes_equal_to_deployed_image']}))

View file

@ -0,0 +1,9 @@
{
"cli_module": "/home/worsch/state-hub/.venv/lib/python3.12/site-packages/custodian_cli.py",
"checker_path": "/home/worsch/state-hub/.venv/lib/python3.12/site-packages/scripts/consistency_check.py",
"loaded_checker_sha256": "eaee916f46a11f49d2621fc9386717d73b7fd517acbe4b695e7b551d67bfa8f7",
"source_checker_sha256": "eaee916f46a11f49d2621fc9386717d73b7fd517acbe4b695e7b551d67bfa8f7",
"historical_module": "/home/worsch/state-hub/api/services/historical_projection.py",
"historical_module_sha256": "e24e57c58f4aaa4ec9d9bf088009ac69006e53f75b9477ee53dc26c4e850b975",
"loaded_checker_matches_source": true
}

View file

@ -0,0 +1,33 @@
from pathlib import Path
import json,hashlib,subprocess,sys
here=Path(__file__).resolve().parent;root=Path('/home/worsch/railiance-cluster');backup=here/'railiance-cluster-publication-backup'
sys.path.insert(0,'/home/worsch/repo-manager/src')
from repo_manager.identifiers import ensure_missing_work_record_identifiers
sha=lambda p:'sha256:'+hashlib.sha256(p.read_bytes()).hexdigest()
def git(*a):return subprocess.check_output(['git','-C',str(root),*a],stderr=subprocess.PIPE)
manifest=json.loads((here/'cluster-integration.json').read_text());assert git('rev-parse','HEAD').decode().strip()==manifest['base_revision']
originals=json.loads((backup/'originals.json').read_text())
for name,index in originals.items():
assert (root/name).read_bytes()==(backup/(name+'.worktree')).read_bytes()
assert git('ls-files','--stage','--',name).decode()==index
for name,h in manifest['files'].items():assert sha(root/name)==h
preview=json.loads((here/'registrar-followthrough-r1/actual-cluster-allocator-preview.json').read_text())
plan=ensure_missing_work_record_identifiers(root,execute=False);assert plan==preview
assert len(plan['assignments'])==7 and len(plan['historical_invalid_identifiers'])==15 and len(plan['historical_identity_collisions'])==5
assert set(plan['files_changed'])=={'workplans/ADHOC-2026-07-27.md','workplans/RCLUSTER-WP-0018-keycape-original-tls-recovery.md'}
frozen={p:sha(root/p) for p in ['workplans/archived/260622-RAIL-BS-WP-0002-k3s-baseline.md','workplans/archived/260622-RAIL-BS-WP-0003-pgpool-ha-failover-fix.md','workplans/archived/260622-RAIL-BS-WP-0004-safety-net.md']}
for name in plan['files_changed']:(backup/(Path(name).name+'.before-allocation')).write_bytes((root/name).read_bytes())
assigned=ensure_missing_work_record_identifiers(root,execute=True)
assert assigned['assignments']==plan['assignments']
assert {p:sha(root/p) for p in frozen}==frozen
# Existing ad-hoc file receives one normal managed UUID field only.
ad=root/'workplans/ADHOC-2026-07-27.md';before=(backup/(ad.name+'.before-allocation')).read_text();after=ad.read_text();assert after.replace('state_hub_task_id: "3e3f39d3-5070-5ba3-97db-19f5f361f264"\n','')==before
paths=[*manifest['files'],'workplans/ADHOC-2026-07-27.md']
git('add','--',*paths)
r=subprocess.run(['git','-C',str(root),'commit','--only','-m','feat(recovery): prepare owner-bound offline TLS continuity preflight','--',*paths],capture_output=True,text=True,timeout=180)
receipt={'owner':'railiance-cluster','status':'committed' if r.returncode==0 else 'commit-refused','exit_code':r.returncode,'head':git('rev-parse','HEAD').decode().strip(),'managed_identifier_assignments':assigned,'frozen_archives_unchanged':True,'files':{p:sha(root/p) for p in paths},'stdout':r.stdout,'stderr':r.stderr}
(here/'railiance-cluster-commit.json').write_text(json.dumps(receipt,indent=2)+'\n')
for name,index in originals.items():
assert (root/name).read_bytes()==(backup/(name+'.worktree')).read_bytes()
assert git('ls-files','--stage','--',name).decode()==index
print(json.dumps({k:receipt[k] for k in ['status','exit_code','head']}));raise SystemExit(r.returncode)

View file

@ -0,0 +1,19 @@
"""Publish explicit rollout/repair evidence while retaining all unrelated work."""
from pathlib import Path
import hashlib,json,subprocess
root=Path('/home/worsch/the-custodian');base=Path(__file__).resolve().parent;backup=base/'custodian-publication-backup'
def git(*a):return subprocess.check_output(['git','-C',str(root),*a],stderr=subprocess.PIPE)
manifest=json.loads((base/'rollout-publication-inputs.json').read_text());paths=[r['path'] for r in manifest['files']]+[str((base/'rollout-publication-inputs.json').relative_to(root))]
assert git('rev-parse','HEAD').decode().strip()=='f8c7dfa2a9c7919879b62c77eb39582b3e23654e'
for r in manifest['files']:assert hashlib.sha256((root/r['path']).read_bytes()).hexdigest()==r['sha256'],r['path']
originals=json.loads((backup/'originals.json').read_text());other=json.loads((backup/'other-dirty-hashes.json').read_text())
def check():
for name,index in originals.items():
assert (root/name).read_bytes()==(backup/(name+'.worktree')).read_bytes()
assert git('ls-files','--stage','--',name).decode()==index
assert all(hashlib.sha256((root/name).read_bytes()).hexdigest()==pin for name,pin in other.items())
check();git('add','--',*paths)
r=subprocess.run(['git','-C',str(root),'commit','--only','-m','Record verified receiver rollout and frozen-binding guard successor','--',*paths],capture_output=True,text=True,timeout=240)
head=git('rev-parse','HEAD').decode().strip();receipt={'status':'committed' if r.returncode==0 else 'commit-refused','head':head,'exit_code':r.returncode,'paths':paths,'stdout':r.stdout,'stderr':r.stderr,'unrelated_work_preserved':True}
(base/'rollout-checkpoint-commit.json').write_text(json.dumps(receipt,indent=2)+'\n');check()
print(json.dumps({k:receipt[k] for k in ['status','head','exit_code','unrelated_work_preserved']}));raise SystemExit(r.returncode)

View file

@ -0,0 +1,5 @@
{
"status": "verifier-expectation-failed",
"reason": "Incorrectly required every closed source dependency to be materialized; existing projection retains/creates selected open-task edges. No source or Hub mutation occurred.",
"assertion": "missing-internal-edge"
}

View file

@ -0,0 +1,33 @@
"""Read-only final source/remote/Hub binding check, retaining only public identifiers."""
from pathlib import Path
import hashlib,json,re,subprocess,urllib.request,yaml
here=Path(__file__).resolve().parent
specs=[('state-hub','STATE-WP-0095','9eaa36143ea18111c522ea14d32978495b4e5030',10),('repo-manager','RMGR-WP-0019','1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd',6),('repo-manager','RMGR-WP-0021','1dacdd4a31c8e9b1bb1ddfb0c349dfb87e29e8cd',5),('railiance-cluster','RCLUSTER-WP-0018','6ae3f847c83da3402883453ee7110457bfb2d0d6',5)]
def git(root,*a):return subprocess.check_output(['git','--no-optional-locks','-C',str(root),*a],stderr=subprocess.PIPE,timeout=30).decode().strip()
def get(path):return json.load(urllib.request.urlopen('http://127.0.0.1:8000'+path,timeout=20))
health=get('/state/health');assert health['instance_role']=='primary' and health['instance_label']=='railiance01'
rows=[];snapshots={};targets={'NK-WP-0049-T33':'56c8d469-7a10-5d50-a30e-95cbf3cd4756'}
for repo,wp,head,count in specs:
root=Path('/home/worsch')/repo;assert git(root,'rev-parse','HEAD')==head
paths=list((root/'workplans').glob(wp+'-*.md'));assert len(paths)==1;path=paths[0];raw=path.read_text();assert git(root,'show',head+':'+str(path.relative_to(root)))==raw.strip()
front=yaml.safe_load(raw.split('---',2)[1]);tasks=[yaml.safe_load(v) for v in re.findall(r'```task\n(.*?)\n```',raw,re.S)];assert len(tasks)==count
for task in tasks:targets[task['id']]=task['state_hub_task_id']
rows.append(dict(repo=repo,wp=wp,head=head,source_path=str(path),front=front,tasks=tasks,source_sha256=hashlib.sha256(path.read_bytes()).hexdigest()))
result=[]
for item in rows:
repo=item['repo'];root=Path('/home/worsch')/repo
remote=git(root,'ls-remote','origin','refs/heads/main').split()[0];assert remote==item['head']
snapshot=snapshots.setdefault(repo,get('/repos/'+repo+'/work-record-projection/snapshot'))
plan=next(p for p in snapshot['workplans'] if p['id']==item['front']['state_hub_workstream_id']);assert plan['status']==item['front']['status']
actual=[t for t in snapshot['tasks'] if t.get('workplan_id',t.get('workstream_id'))==plan['id']];assert len(actual)==len(item['tasks']);byid={t['id']:t for t in actual}
for task in item['tasks']:
t=byid[task['state_hub_task_id']];assert t['record_id']==task['id'] and t['status']==task['status']
if 'needs_human' in task:assert bool(t.get('needs_human'))==task['needs_human']
expected={(t['state_hub_task_id'],targets[d],'starts_after') for t in item['tasks'] for d in t.get('depends_on',[]) if d in targets}
edges=[e for e in snapshot['dependencies'] if e['from_workplan_id']==plan['id'] and e.get('from_task_id')]
observed={(e['from_task_id'],e.get('to_task_id'),e['relationship_type']) for e in edges}
assert observed<=expected,'undeclared-projected-edge'
ownids={t['state_hub_task_id'] for t in item['tasks']};assert {(a,b,c) for a,b,c in expected if b in ownids}<=observed,'missing-internal-edge'
result.append({'repo':repo,'workplan_id':item['wp'],'commit':item['head'],'remote_exact':True,'source_sha256':item['source_sha256'],'status':plan['status'],'tasks':[{k:t[k] for k in ['id','record_id','status','needs_human'] if k in t} for t in actual],'projected_edges':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(observed)],'unprojected_external_declarations':[{'from_task_id':a,'to_task_id':b,'relationship_type':c} for a,b,c in sorted(expected-observed)]})
v={'schema':'custodian.rollout-owner-bindings.v1','status':'verified','primary':'primary/railiance01','task_bindings':sum(len(r['tasks']) for r in result),'rows':result,'runtime_deployed_source':'51bc70d1ff8f25450a8650d8e50caf053093a02e','successor_runtime_source_not_deployed':'c103cbf3c8bed5dba87a03e320595ddded9301a3','native_target_gates_closed':0}
(here/'rollout-owner-bindings.json').write_text(json.dumps(v,indent=2)+'\n');print(json.dumps({'status':'verified','task_bindings':v['task_bindings']}))