the-custodian/docs/changes/CUST-WP-0080/verify_forge_expansion.py
codex a3b56d689f
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Reject generated-only commits / generated-commit-guard (push) Successful in 7s
security: verify forge scanner expansion across 166 repositories
2026-10-13 17:59:50 +02:00

67 lines
4.2 KiB
Python

#!/usr/bin/env python3
"""Independent read-only final inventory and cleanup audit for the exact cohort."""
import argparse
import datetime
import hashlib
import importlib.util
import json
from pathlib import Path
import shlex
import subprocess
import sys
HERE=Path(__file__).parent
s=importlib.util.spec_from_file_location('expand',HERE/'expand_forge_profiles.py')
m=importlib.util.module_from_spec(s)
s.loader.exec_module(m)
def main():
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('--inventory',type=Path,required=True)
parser.add_argument('--fresh-inventory',type=Path,required=True)
parser.add_argument('--inventory-receipt',type=Path,required=True)
parser.add_argument('--receipt',type=Path,required=True)
args=parser.parse_args()
p=json.loads((HERE/'forge-expansion-proposal.json').read_text())
activation=Path('docs/evidence/2026-10-13-netkingdom-security/forge-expansion-activation.json')
a=json.loads(activation.read_text())
assert a['result']=='verified' and a['ownership_markers_removed'] and a['vetoes_removed'],'activation-not-complete'
assert a['proposal_sha256']==hashlib.sha256((HERE/'forge-expansion-proposal.json').read_bytes()).hexdigest()
assert len(a['verified_ids'])==len(set(a['verified_ids']))==p['target_count']
assert set(a['verified_ids'])==set(a['attempted_ids'])==set(p['target_ids'])
assert hashlib.sha256(args.inventory.read_bytes()).hexdigest()==p['inventory_sha256']
old=json.loads(args.inventory.read_text());baseline={r['id'] for r in old['repositories'] if r['profile']=='admitted'}
process=subprocess.run([sys.executable,str(HERE/'inventory_forge_coverage.py'),
'--private-output',str(args.fresh_inventory),'--receipt',str(args.inventory_receipt)],capture_output=True,timeout=180)
if process.returncode:raise ValueError('fresh-inventory-incomplete')
fresh=json.loads(args.fresh_inventory.read_text());by_id={r['id']:r for r in fresh['repositories']}
expected=baseline|set(p['target_ids'])
assert all(by_id[i]['profile']=='admitted' for i in expected),'profile-not-preserved'
assert not any(r['profile']=='unknown' for r in by_id.values()),'unknown-hook-profile'
original=json.loads((HERE/'receive-hook-proposal.json').read_text())
pod=m.t.target_pod(m.t.deployment(),original)
assert pod['pod_uid']==fresh['pod_uid'],'pod-changed-during-final-audit'
commands=['set -euo pipefail']
for i in p['target_ids']:
path=m.repo_path(by_id[i])
commands += ['repo='+shlex.quote(path),
'test ! -e "$repo/hooks/pre-receive.d/'+p['veto_name']+'"',
'test ! -e "$repo/.custodian-expand-'+original['hook_name']+'"',
'test ! -e "$repo/.custodian-expand-'+p['veto_name']+'"',
'test -z "$(git --git-dir="$repo" for-each-ref --format=\'%(refname)\' '+shlex.quote(p['probe_ref'])+')"']
m.t.native.execute(pod,'bash','-s',payload=('\n'.join(commands)+'\n').encode(),timeout=180)
summary=json.loads(args.inventory_receipt.read_text())
receipt={'result':'verified','observed_at':datetime.datetime.now(datetime.timezone.utc).isoformat(),
'proposal_id':p['proposal_id'],'activation_receipt_sha256':hashlib.sha256(activation.read_bytes()).hexdigest(),
'baseline_profiles_preserved':len(baseline),'expanded_profiles_verified':len(p['target_ids']),
'current_profiles':summary['profiles'],'current_repositories':summary['repositories'],
'no_probe_refs_or_vetoes_or_ownership_markers':True,
'blocked_synthetic_commits_absent':'Verified separately by every native SSH probe in the activation receipt.',
'remaining_builtin_only_ids':[r['id'] for r in by_id.values() if r['profile']=='builtin-only'],
'api_route':'Unverified: protected route did not hand off; current capabilities check denied; attended login required.',
'scope':'Exact native SSH scanner verdicts under ref-specific vetoes plus fresh hook/directory/custody and cleanup audit. Ordinary source acceptance remains separate; no full DSM conformance claimed.'}
args.receipt.write_text(json.dumps(receipt,indent=2)+'\n');print(json.dumps(receipt))
if __name__=='__main__':main()