refactor: unify impl operation gates and correction verification

This commit is contained in:
2026-10-13 16:35:52 +00:00
parent 4e9c46bba2
commit bd73c97a97
24 changed files with 1992 additions and 682 deletions
@@ -0,0 +1,148 @@
#!/usr/bin/env python3
"""Pure input-bound verifier for the narrowly approved comment correction."""
from __future__ import annotations
import argparse, hashlib, importlib.util, json, re, sys
from pathlib import Path
class Bad(ValueError): pass
def canonical(v):
return json.dumps(v,sort_keys=True,ensure_ascii=False,allow_nan=False,separators=(',',':')).encode()
def sha(b): return hashlib.sha256(b).hexdigest()
def load(path, digest):
directory = str(Path(__file__).resolve().parent)
if directory not in sys.path:
sys.path.insert(0, directory)
from rework_readback_cli import read_bound_json
try:
return read_bound_json(path, expected_sha256=digest)
except Exception:
raise Bad('bounded input or digest rejected') from None
def core_module():
p=Path(__file__).with_name('rework_comment.py')
spec=importlib.util.spec_from_file_location('correction_comment_core',p)
if not spec or not spec.loader: raise Bad('canonical planner unavailable')
m=importlib.util.module_from_spec(spec); sys.modules[spec.name]=m; spec.loader.exec_module(m); return m
def verify_correction(plan, before, after, old_comment, new_comment, approval, *, approval_sha256, historical_failure_sha256, profile='strict'):
if type(approval) is not dict or sha(canonical(approval))!=approval_sha256: raise Bad('approval digest binding')
if not re.fullmatch('[0-9a-f]{64}',historical_failure_sha256 or ''): raise Bad('historical failure digest required')
if approval.get('historical_failure_baseline_sha256')!=historical_failure_sha256 or approval.get('approved') is not True or approval.get('operation')!='same_comment_correction': raise Bad('correction approval mismatch')
if profile not in ('strict','observed-comment-ref-neutralization'): raise Bad('unsupported profile')
if approval.get('timeline_profile') != profile: raise Bad('timeline profile not approved')
if approval.get('ordinary_patch') is not True: raise Bad('ordinary PATCH approval required')
if type(plan) is not dict or plan.get('schema')!='gitea-rework-correction-plan/v1' or plan.get('approval_required') is not True: raise Bad('invalid correction plan')
if plan.get('prior_handoff_verified') is not False or plan.get('external_write_performed') is not False: raise Bad('historical failure cannot be promoted')
# Both snapshots must bind the same expected render and pass the canonical provider normalizer.
if type(before) is not dict or type(after) is not dict: raise Bad('snapshot object required')
if before.get('schema')!='gitea-agent.rework-readback/v1' or after.get('schema')!=before.get('schema'): raise Bad('snapshot schema')
target=before.get('target')
if target!=after.get('target') or before.get('provider')!=after.get('provider') or before.get('actor_id')!=after.get('actor_id'): raise Bad('snapshot identity drift')
expected=approval.get('new_expected_document'); previous=approval.get('old_expected_document')
if type(expected) is not dict or type(previous) is not dict: raise Bad('approval must bind both expected documents')
planner=core_module()
reconstructed=planner.prepare_correction(previous,expected,comment_id=plan.get('comment_id'),actor_id=plan.get('actor_id'))
if reconstructed!=plan: raise Bad('plan does not reconstruct from canonical planner')
try:
rb=Path(__file__).with_name('rework_readback.py'); s=importlib.util.spec_from_file_location('correction_readback_core',rb); m=importlib.util.module_from_spec(s); sys.modules[s.name]=m; s.loader.exec_module(m)
adapter=m.ReworkReadbackAdapter(lambda _:None,origin=m.ORIGIN,credential_source=m.CREDENTIAL_SOURCE,actor_id=before['actor_id'],provider_contract=before['provider'])
bound_before = previous if before.get('expected_sha256') == m.digest(previous) else expected
raw_before=adapter.validate_snapshot(bound_before,before); raw_after=adapter.validate_snapshot(expected,after)
if approval.get('provider_version') != before['provider']['version']: raise Bad('provider version not approved')
if profile != 'strict' and before['provider']['version'] != '1.27.3': raise Bad('unsupported reference profile version')
except Exception as e: raise Bad('provider snapshot validation failed') from e
if old_comment!=plan['old_body'] or new_comment!=plan['new_body']: raise Bad('exact comment bodies mismatch')
cid=plan['comment_id']; aid=plan['actor_id']
if aid != before['actor_id']: raise Bad('plan actor mismatch')
for collected in (raw_before['comments']['rows'], raw_after['comments']['rows']):
if len([row for row in collected if plan['correlation'] in row['body']]) != 1: raise Bad('correlation cardinality')
def comment_match(c,b):
return type(c) is dict and c.get('id')==cid and c.get('body')==b and type(c.get('user')) is dict and c['user'].get('id')==aid and c['user'].get('login')=='gitea-impl-agent'
olds=[x for x in raw_before['comments']['rows'] if x.get('id')==cid]; news=[x for x in raw_after['comments']['rows'] if x.get('id')==cid]
if len(olds)!=1 or len(news)!=1 or not comment_match(olds[0],old_comment) or not comment_match(news[0],new_comment): raise Bad('target comment/actor cardinality mismatch')
if m.timestamp(news[0]['updated_at']) < m.timestamp(olds[0]['updated_at']): raise Bad('comment update timestamp regressed')
for field in ('id','html_url','pull_request_url','issue_url','user','created_at','assets'):
if olds[0].get(field)!=news[0].get(field): raise Bad('comment identity metadata changed')
# Every non-target top-level comment is immutable; target metadata is exact except body/update time.
old_rows={r['id']:r for r in raw_before['comments']['rows']}; new_rows={r['id']:r for r in raw_after['comments']['rows']}
if set(old_rows)!=set(new_rows): raise Bad('top-level comment collection changed')
for ident, row in old_rows.items():
updated=new_rows[ident]
if ident!=cid and row!=updated: raise Bad('unrelated top-level comment changed')
if ident==cid:
left=dict(row); right=dict(updated)
left.pop('body',None); right.pop('body',None); left.pop('updated_at',None); right.pop('updated_at',None)
if left!=right: raise Bad('target comment metadata changed')
for name in ('identity','version','repository','source_issue','source_comments','pr','pr_issue','reviews','inline'):
x,y=raw_before[name],raw_after[name]
if x!=y: raise Bad('protected source or collection changed: '+name)
# Timeline is separately supplied by snapshots at top level or within raw; no lossy masks accepted.
tb=before.get('source_issue_timeline',raw_before.get('source_issue_timeline')); ta=after.get('source_issue_timeline',raw_after.get('source_issue_timeline'))
if (type(tb) is not dict or type(ta) is not dict or tb.get('complete') is not True or ta.get('complete') is not True
or type(tb.get('rows')) is not list or type(ta.get('rows')) is not list): raise Bad('complete timeline collection required')
for timeline in (tb,ta):
pages=timeline.get('pages')
if type(pages) is not list or not pages or any(type(p) is not dict for p in pages): raise Bad('timeline pagination metadata required')
if any(type(p.get('count')) is not int or p['count']<0 for p in pages) or sum(p['count'] for p in pages)!=len(timeline['rows']): raise Bad('timeline pagination incomplete')
headers=pages[-1].get('headers')
if type(headers) is not dict or headers.get('X-Total-Count')!=str(len(timeline['rows'])): raise Bad('timeline declared total mismatch')
for row in tb['rows'] + ta['rows']:
if type(row) is not dict or type(row.get('id')) is not int or row['id'] <= 0: raise Bad('invalid timeline ID')
m.timestamp(row.get('created_at')); m.timestamp(row.get('updated_at'))
br={r.get('id'):r for r in tb['rows'] if type(r) is dict}; ar={r.get('id'):r for r in ta['rows'] if type(r) is dict}
if len(br)!=len(tb['rows']) or len(ar)!=len(ta['rows']) or None in br or None in ar or len(br)!=len(tb['rows']) or len(ar)!=len(ta['rows']): raise Bad('malformed timeline rows')
if set(br)!=set(ar): raise Bad('timeline additions/deletions')
changed=[]
for eid,brow in br.items():
arow=ar[eid]
if brow==arow: continue
if profile!='observed-comment-ref-neutralization' or brow.get('type')!='comment_ref' or brow.get('id')!=eid: raise Bad('timeline change outside approved profile')
immutable=('id','type','html_url','pull_request_url','issue_url','user','created_at','ref_commit_sha','review_id')
if brow.get('user',{}).get('id')!=aid or any(brow.get(k)!=arow.get(k) for k in immutable): raise Bad('comment_ref identity changed')
if brow.get('ref_action')!='none' or arow.get('ref_action')!='neutered': raise Bad('invalid comment_ref transition')
# Only event update time/action and the embedded exact comment projection may move.
allowed={'ref_action','updated_at','ref_comment'}
if {k:v for k,v in brow.items() if k not in allowed} != {k:v for k,v in arow.items() if k not in allowed}: raise Bad('unapproved timeline field mutation')
if brow.get('issue_url') != raw_before['source_issue']['html_url']: raise Bad('reference source Issue mismatch')
if m.timestamp(arow.get('updated_at')) <= m.timestamp(brow.get('updated_at')): raise Bad('reference update timestamp did not advance')
x,y=brow.get('ref_issue'),arow.get('ref_issue')
if type(x) is not dict or type(y) is not dict: raise Bad('missing linked PR projection')
if set(x)!=set(y): raise Bad('linked PR projection fields changed')
for k in x:
if k!='ref_comment' and x[k]!=y[k]: raise Bad('linked PR projection changed')
xc,yc=brow.get('ref_comment'),arow.get('ref_comment')
if x.get('number')!=plan['target']['pr'] or x.get('html_url')!='https://gitea.jsfamily.quest/'+plan['target']['owner']+'/'+plan['target']['repository']+'/pulls/'+str(plan['target']['pr']): raise Bad('comment_ref linked PR mismatch')
if type(xc) is not dict or type(yc) is not dict or xc.get('id')!=cid or yc.get('id')!=cid: raise Bad('linked comment identity mismatch')
if set(xc)!=set(yc): raise Bad('linked comment projection fields changed')
for k in xc:
if k not in ('body','updated_at') and xc[k]!=yc[k]: raise Bad('linked comment projection changed')
if xc != olds[0] or yc != news[0]: raise Bad('timeline body projection mismatch')
changed.append(eid)
if profile=='strict' and changed: raise Bad('strict timeline preservation failed')
if profile!='strict' and len(changed)>1: raise Bad('reference profile cardinality')
bindings = {'plan_sha256':sha(canonical(plan)), 'before_sha256':sha(canonical(before)), 'after_sha256':sha(canonical(after)), 'approval_sha256':approval_sha256}
return {**bindings, 'schema':'gitea-rework-correction-receipt/v1','status':'verified','operation':'same_comment_correction','target':plan['target'],'comment_id':cid,'actor_id':aid,'head':plan['head'],'correlation':plan['correlation'],'old_body_sha256':plan['old_body_sha256'],'new_body_sha256':plan['new_body_sha256'],'historical_failure_baseline_sha256':historical_failure_sha256,'historical_handoff_status':'partial_unchanged','timeline_profile':profile,'changed_timeline_ids':changed,'atomic_client_precondition':False,'assurance_limitations':['input-bound readback comparison; not causal event attestation','no claim of live provider/build equivalence','ordinary PATCH residual race remains unless separately evidenced']}
def main():
p=argparse.ArgumentParser(); sp=p.add_subparsers(dest='cmd',required=True); v=sp.add_parser('verify')
for n in ('plan','before','after','old-comment','new-comment','approval'): v.add_argument('--'+n,required=True); v.add_argument('--'+n+'-sha256',required=True)
v.add_argument('--historical-failure-sha256',required=True); v.add_argument('--profile',choices=('strict','observed-comment-ref-neutralization'),default='strict'); v.add_argument('--output',required=True)
a=p.parse_args()
try:
from rework_readback_cli import OutputFile
paths=[Path(getattr(a,n.replace('-','_'))) for n in ('plan','before','after','old_comment','new_comment','approval')]
out=Path(a.output)
if any(out==x or out.resolve()==x.resolve() for x in paths): raise Bad('output aliases input')
vals={n:load(getattr(a,n.replace('-','_')),getattr(a,n.replace('-','_')+'_sha256')) for n in ('plan','before','after','old_comment','new_comment','approval')}
if 'source_snapshot' in vals['before']:
envelope=vals['before']; vals['before']=dict(envelope['source_snapshot'],source_issue_timeline=envelope.get('source_issue_timeline'))
if envelope.get('plan') != vals['plan']: raise Bad('envelope plan mismatch')
if 'source_snapshot' in vals['after']:
envelope=vals['after']; vals['after']=dict(envelope['source_snapshot'],source_issue_timeline=envelope.get('source_issue_timeline'))
approval_digest=sha(canonical(vals['approval']))
receipt=verify_correction(vals['plan'],vals['before'],vals['after'],vals['old_comment'].get('body'),vals['new_comment'].get('body'),vals['approval'],approval_sha256=approval_digest,historical_failure_sha256=a.historical_failure_sha256,profile=a.profile)
with OutputFile(out,initial_only=True) as f: f.write(receipt)
except Exception as e: print('error: '+str(e),file=sys.stderr); return 2
return 0
if __name__=='__main__': raise SystemExit(main())
@@ -0,0 +1,136 @@
"""Main-owned, bounded publication operations for implementation rework.
Adapters are trusted provider-specific contracts. This module deliberately
contains no transport code; it validates operation payloads and delegates one
approved attempt to the shared process-local coordinator.
"""
from __future__ import annotations
import copy
import sys
from pathlib import Path
_ROOT = Path(__file__).resolve().parents[6]
if str(_ROOT) not in sys.path:
sys.path.insert(0, str(_ROOT))
from harness.lib import impl_operation as _ops
from harness.lib.delegation_adoption import require_adoption
_SCRIPTS = str(Path(__file__).resolve().parent)
if _SCRIPTS not in sys.path:
sys.path.insert(0, _SCRIPTS)
from rework_comment import _correction_expected, prepare_correction
OPERATIONS = frozenset(("push", "pr.patch", "comment.create", "correction"))
def _payload(intent):
p = intent.payload
if type(p) is not dict:
raise ValueError("operation payload must be an object")
return p
def _validate(intent, approval):
_ops.validate(intent, approval)
op = intent.operation
if op not in OPERATIONS:
raise ValueError("operation is not a rework publication operation")
p = _payload(intent)
if op == "push":
if type(p.get("head")) is not str or p["head"] != intent.source_sha:
raise ValueError("push requires explicit intended full head")
elif op == "pr.patch":
if type(p.get("body")) is not str or not p["body"] or len(p["body"].encode()) > 1_000_000:
raise ValueError("bounded PR body required")
if "closing" not in p or type(p["closing"]) is not str:
raise ValueError("adapter contract must bind intended closing")
if p["closing"] not in p["body"]:
raise ValueError("PR body does not preserve intended closing")
elif op == "comment.create":
expected = p.get("expected")
canonical = _correction_expected(expected, legacy=False)
if canonical["head"] != intent.source_sha:
raise ValueError("comment head differs from intended source")
if intent.target != canonical["owner"] + "/" + canonical["repository"] or intent.target_id != int(canonical["pr"]):
raise ValueError("comment intent scope mismatch")
target = p.get("target")
if target != {"owner": canonical["owner"], "repository": canonical["repository"],
"issue": int(canonical["issue"]), "pr": int(canonical["pr"])}:
raise ValueError("comment target differs from canonical expected target")
else:
required = {"old_expected", "new_expected", "comment_id", "actor_id"}
if set(p) != required:
raise ValueError("correction payload fields must be exact")
canonical = prepare_correction(p["old_expected"], p["new_expected"],
comment_id=p["comment_id"], actor_id=p["actor_id"])
if canonical["head"] != intent.source_sha:
raise ValueError("correction head differs from intended source")
target = canonical["target"]
if intent.target != target["owner"] + "/" + target["repository"] or intent.target_id != canonical["comment_id"]:
raise ValueError("correction intent scope mismatch")
if not approval.correction:
raise ValueError("separate correction approval required")
return copy.deepcopy(intent)
def execute_rework_operation(adapter, *, intent, approval, declaration, coordinator, on_attempt):
"""Execute one validated publication operation through a coordinator.
The adapter must implement the shared trusted preflight/capability/mutate/
readback/verify contract and enforce exact provider scope at each boundary.
Adoption is rechecked immediately before the sole mutate callback.
"""
stable = _validate(intent, approval)
if stable.operation == "correction" and (adapter.capability != "ordinary_patch" or not approval.ordinary_patch):
raise ValueError("client-CAS correction is unsupported; explicit ordinary-PATCH exception required")
if not isinstance(coordinator, _ops.Coordinator):
raise ValueError("process-local coordinator required")
if not callable(on_attempt):
raise ValueError("attempt recorder required")
original_mutate = adapter.mutate
adoption_failed = {"value": False}
def guarded_mutate(candidate):
if candidate.operation == "push":
revision = candidate.payload["head"]
else:
revision = candidate.source_sha
try:
require_adoption(declaration, expected_source={"kind": "git_tree", "revision": revision},
expected_stage="implementation-delivery")
except Exception as exc:
adoption_failed["value"] = True
return {"acknowledgement": "failed", "error": type(exc).__name__}
return original_mutate(copy.deepcopy(candidate))
def guarded_verify(candidate, pre, observed):
if adoption_failed["value"]:
return False
return adapter.verify(copy.deepcopy(candidate), copy.deepcopy(pre), copy.deepcopy(observed))
wrapped = _ops.Adapter(preflight=adapter.preflight, capability=adapter.capability,
mutate=guarded_mutate, readback=adapter.readback, verify=guarded_verify)
return coordinator.execute(stable, approval, wrapped, on_attempt)
def verify_rework_reuse(adapter, *, intent, approval, declaration):
"""Fresh read-only reuse proof; supplied snapshots cannot authorize reuse."""
stable = _validate(intent, approval)
if stable.operation != "comment.create":
raise ValueError("reuse is only supported for canonical comment publication")
for name in ("preflight", "readback", "verify_reuse"):
if not callable(getattr(adapter, name, None)):
raise ValueError("trusted read-only reuse adapter required")
require_adoption(declaration, expected_source={"kind": "git_tree", "revision":stable.source_sha},
expected_stage="implementation-delivery")
snapshot = adapter.preflight(copy.deepcopy(stable))
if type(snapshot) is not dict or snapshot.get("fresh") is not True:
raise ValueError("fresh reuse snapshot required")
observed = adapter.readback(copy.deepcopy(stable))
if adapter.verify_reuse(copy.deepcopy(stable),copy.deepcopy(snapshot),copy.deepcopy(observed)) is not True:
raise ValueError("reuse verification incomplete")
return {"status":"verified", "action":"reuse", "external_write_performed":False}
__all__ = ["execute_rework_operation", "verify_rework_reuse", "OPERATIONS"]