38 lines
7.2 KiB
Python
38 lines
7.2 KiB
Python
from pathlib import Path
|
|
from collections import Counter
|
|
import datetime,hashlib,json,re,subprocess,urllib.request
|
|
import yaml
|
|
p=Path(__file__).resolve().parent;owner=Path('/home/worsch/net-kingdom');backup=p/'publication-backup';manifest=json.loads((p/'manifest.json').read_text());wp='e31f3f9d-0748-5137-b0a3-7b3ca46a66eb'
|
|
sha=lambda data:'sha256:'+hashlib.sha256(data).hexdigest();git=lambda *args:subprocess.check_output(['git','-C',str(owner),*args]);get=lambda path:json.load(urllib.request.urlopen('http://127.0.0.1:8000'+path,timeout=10))
|
|
syncs={}
|
|
for name in ('normal-source','normal-final'):
|
|
value=json.loads((p/(name+'.stdout.json')).read_text());exit_code=json.loads((p/(name+'.exit.json')).read_text())['exit_code']
|
|
if exit_code or value['summary']['fail'] or value['summary']['automation_error']:raise SystemExit('sync failure '+name)
|
|
syncs[name]={'exit_code':exit_code,'summary':value['summary'],'result':value['result'],'stderr':(p/(name+'.stderr.txt')).read_text(),'fixes_applied':value.get('fixes_applied')}
|
|
rel='workplans/NK-WP-0048-security-case-types.md';source=(owner/rel).read_text();blocks=[yaml.safe_load(t) for t in re.findall(r'```task\n(.*?)```',source,re.S)];by_source={b['id']:b for b in blocks};rows=get('/tasks/?workplan_id='+wp);by_uuid={r['id']:r for r in rows}
|
|
if len(blocks)!=18 or len(rows)!=18:raise SystemExit('task counts differ')
|
|
for b in blocks:
|
|
if b['state_hub_task_id'] not in by_uuid or by_uuid[b['state_hub_task_id']]['status']!=b['status']:raise SystemExit('task projection differs '+b['id'])
|
|
old={b['id']:b for b in [yaml.safe_load(t) for t in re.findall(r'```task\n(.*?)```',(p/'preimages'/rel).read_text(),re.S)]}
|
|
for name,b in old.items():
|
|
if by_source[name]['state_hub_task_id']!=b['state_hub_task_id']:raise SystemExit('prior UUID changed '+name)
|
|
deps=get('/workplans/'+wp+'/dependencies/');verified=[]
|
|
for b in blocks:
|
|
if b['status'] in ('done','cancel'):continue
|
|
for target in b.get('depends_on',[]):
|
|
expected_uuid=by_source[target]['state_hub_task_id'] if target in by_source else None
|
|
if not any(d['from_task_id']==b['state_hub_task_id'] and d['relationship_type']=='starts_after' and (d['to_task_id']==expected_uuid if expected_uuid else d.get('description')==b['id']+' depends_on '+target) for d in deps):raise SystemExit('dependency missing '+target)
|
|
verified.append(b['id']+' -> '+target)
|
|
if git('show',':.custodian-brief.md')!=(backup/'brief.index').read_bytes() or (owner/'.custodian-brief.md').read_bytes()!=(backup/'brief.worktree').read_bytes():raise SystemExit('brief preservation failed')
|
|
for name,h in manifest['postimages'].items():
|
|
if not name.startswith('workplans/') and sha((owner/name).read_bytes())!=h:raise SystemExit('reviewed source drift '+name)
|
|
current=git('rev-parse','HEAD').decode().strip();published=git('rev-parse','origin/main').decode().strip();source_commit='916ba4b33e03179274d03b78bd898a4843e8653f'
|
|
if current!=published or not current.startswith('cbabb6d'):raise SystemExit('publication differs')
|
|
if git('diff','--name-only','--',rel).strip():raise SystemExit('workplan left dirty')
|
|
(p/'projection-tasks.json').write_text(json.dumps([{'id':b['id'],'uuid':b['state_hub_task_id'],'status':b['status'],'depends_on':b.get('depends_on',[])} for b in blocks],indent=2)+'\n');(p/'projection-dependencies.json').write_text(json.dumps(deps,indent=2)+'\n')
|
|
summary='NetKingdom source checker boundary fix published '+source_commit+' and task-publication receipt '+current+'. Checker gets absolute selected path and env={}; predecessor URL/PATH counterexamples retained. 39 affected tests plus11 actual-artifact/helper/kernel scenarios pass; exact be377 artifact reproduced from pinned source/tree. All18task UUID/status projections and all open-task dependency edges verified; original staged/working brief restored. Native callbacks/type/identity admission remain open. Stopping at requested pause point.'
|
|
request=urllib.request.Request('http://127.0.0.1:8000/progress/',data=json.dumps({'summary':summary,'event_type':'note','author':'codex','workplan_id':wp,'task_id':by_source['NK-WP-0048-T18']['state_hub_task_id']}).encode(),headers={'Content-Type':'application/json'},method='POST');progress=json.load(urllib.request.urlopen(request,timeout=10));(p/'owner-progress.json').write_text(json.dumps(progress,indent=2)+'\n')
|
|
resume={'schema':'netkingdom.checker-boundary-resume.v1','stopped_at':datetime.datetime.now(datetime.timezone.utc).isoformat(),'reason':'user requested good pause point; current publication and sync finished','owner_revision':current,'no_running_child_operation':True,'source_tasks_done':['NK-WP-0048-T13','NK-WP-0048-T17','NK-WP-0048-T18'],'remaining_todo':{'NK-WP-0048-T12':'env/config/restart source adapters','NK-WP-0048-T14':'created-only group/membership provenance','NK-WP-0048-T15':'authenticated durable registration recovery','NK-WP-0048-T16':'exact owner/native executable storage and callback/type composition admission'},'native_reference_gate':'NK-WP-0048-T06 remains wait','next_action':'At resume, read current owner records and exact review/native prerequisites before choosing one remaining source task. No current native authority is granted.','historical_packets_preserved':['browser-adapter-next','browser-checker-artifact-next'],'no_production_config_or_credential_access':True}
|
|
(p/'resume-points.json').write_text(json.dumps(resume,indent=2)+'\n')
|
|
receipt={'schema':'custodian.netkingdom.checker-boundary-source-integration.v1','source_commit':source_commit,'publication_record_commit':current,'published_origin':published,'source_review':'coordinator-review.json','reviewed_postimages':manifest['postimages'],'final_source_hashes':{name:sha((owner/name).read_bytes()) for name in manifest['postimages']},'normal_syncs':syncs,'file_task_count':len(blocks),'projected_task_count':len(rows),'status_counts':dict(Counter(b['status'] for b in blocks)),'all_prior_UUIDs_preserved':True,'dependency_edges_verified':verified,'dependency_audit_scope':'all open task dependencies; completed historical-task edges were outside this current admission audit','retained_verification_refinement':'initial broader audit refused absent completed T03->T01 historical edge; current T06/T07 open acceptance edges are verified individually','exact_original_staged_brief_preserved':True,'exact_original_working_brief_preserved':True,'post_sync_race_observation':'brief-post-sync-observation.json','status_after':git('status','--porcelain=v1').decode(),'tests':{'affected':39,'real_artifact_scenarios':11,'producer_pins_overridden':False,'checker_mocked':False},'checker_artifact':manifest['checker_artifact'],'retained_predecessor_failures':'pre-fix-counterexample.txt','publication_failure':{'action':'initial git commit --only','reason':'new regression test not staged; pathspec refusal before commit','recovery':'staged only four reviewed files; normal scanner and source commit/push passed'},'historical_descriptors_unchanged':True,'native_acceptance':False,'new_credential_or_live_action':False,'progress_id':progress.get('id'),'pause_point':'publication and normal final sync complete; no new work begun'}
|
|
(p/'canonical-integration.json').write_text(json.dumps(receipt,indent=2)+'\n');print(json.dumps({'source':source_commit,'final':current,'counts':receipt['status_counts'],'dependencies':len(verified),'progress_id':progress.get('id')}))
|