fix(case2): row 227 R4 source overlay as reviewed (packet 4eb60915, #1728)

Commits the 5 product paths and 7 gate helpers of the row 227 R4 source overlay on top of HEAD 5a0c801cb. scripts/case2/console.mjs is already committed at HEAD and is not part of this commit. The R4 independent review is sha256 6667baaa6af9d6d78a3ec7c64d9f3163ecbc350b94050f62899d9c01deabe002, verdict APPROVE source-only. Packet hashes: PACKET.sha256 4eb60915b2144137df9b5a42afd0c5b266718d71de051fb8be53a27430a2cad4, CURRENT-SOURCE.sha256 0cfd47c2073bc18a3ba7bff1ce6fdf39fe33a64b7fca209be71517b9feb89020. The 12 committed files match the review hash table, the applied overlay JSON (size, mode, hash) and the saved overlay tar. No scripts/test-case2.sh run exists on these bytes.
This commit is contained in:
jason.woltje committed 2026-11-02 13:39:29 -06:00
1 parent 5a0c801cb8
commit 4ac6f13bcf
12 files changed
+760 -34

No files matched your search

@@ -0,0 +1,203 @@
# Role/run claims are checked against owned kernel facts and real launcher runtime records.
import os,time,json,hashlib
from pathlib import Path
class Association:
def __init__(self,root,private,control,nonce,boot,inputs,owned,evidence):
self.root=root;self.private=private;self.control=control;self.nonce=nonce;self.boot=boot;self.inputs=inputs;self.o=owned;self.e=evidence
self.preload=str(root/'agents/steelbeak/work/queue-227/gate/priority.mjs');self.driver=str(root/'scripts/case2/e2e.mjs');self.runner=str(root/'packages/harness/src/runner.mjs');self.adapter=str(root/'scripts/case2/citation-adapter.mjs')
self.launches={};self.registries={};self.accepted={};self.producers={};self.paths={};self.pending={};self.ends={};self.observed_raw=set();self.node_seen=set();self.proven_launches={};self.exited_launches={}
def pending_failure(self,key,code):
self.pending.setdefault(key,time.monotonic())
if time.monotonic()-self.pending[key]>=5:self.e.fail(code)
def archive_directory(self,directory,category):
try:
for path in directory.iterdir():
if path.is_file() or path.is_symlink():self.e.raw(path,category,missing_ok=True)
except FileNotFoundError:pass
def host_role(self,key,row):
if row['exe']!=self.inputs.execs['node']:return None
a=row['argv'];node=self.inputs.execs['node']
if len(a)<2 or a[0] not in [node,'node']:return None
def module_path(value):return str((Path(row['cwd'])/value).resolve())
if len(a)==3 and a[1]=='--check' and module_path(a[2])==self.driver:return dict(kind='host',role='host-syntax',run=None,module=self.driver,argv=[node,self.driver],execArgv=['--check'])
if len(a)==3 and module_path(a[1])==self.driver:
base=Path(a[2]).resolve()
if not base.is_relative_to(self.private) or base.name!='root':return None
return dict(kind='host',role='host-main',run=None,module=self.driver,argv=[node,self.driver,str(base)],execArgv=[])
return None
def live_host(self,fresh):
return [(k,b) for k,b in self.accepted.items() if b['role']=='host-main' and k in fresh and self.o.valid(k)]
def load_launches(self,fresh):
self.archive_directory(self.control/'launches','launch-control')
for path in (self.control/'launches').glob('*.json'):
raw=self.e.raw(path,'launch-control',missing_ok=True)
if raw is None:continue
digest=hashlib.sha256(raw).hexdigest()
if str(path) in self.paths and self.paths[str(path)]!=digest:self.e.fail('launch-announcement-conflict');continue
self.paths[str(path)]=digest
try:r=json.loads(raw);key=(r['wrapperPid'],r['wrapperStart']);run=Path(r['run'])
except Exception as exc:self.e.fail('parse-launch-'+type(exc).__name__);continue
if r.get('version')!=1 or r.get('nonce')!=self.nonce or path.name!=f'{key[0]}-{key[1]}.json':self.e.fail('launch-record-invalid');continue
proven=self.proven_launches.get(str(path))
if proven and proven['digest']==digest and proven['binding']['wrapper']==list(key) and proven['binding']['run']==str(run):
current=self.o.valid(key)
if current is None or current['state']=='Z':
# This is historical attribution, not new authority. Final closure/survivor checks
# must still prove normal managed exit; a dead wrapper never repeats startup proof.
self.exited_launches[str(run)]=proven['binding']
continue
hosts=self.live_host(fresh);native=fresh.get(key)
if not native or native['exe']!=self.inputs.execs['bwrap']:
self.pending_failure(('launch',str(path)),'launch-kernel-unattributed');continue
self.pending.pop(('launch',str(path)),None)
a=native['argv'];owners=[(hk,hb) for hk,hb in hosts if self.o.descends(key,hk,fresh)]
if len(owners)!=1:self.pending_failure(('owner',str(path)),'launch-host-lineage-refused');continue
self.pending.pop(('owner',str(path)),None)
hk,hb=owners[0];base=Path(hb['argv'][2]);expected=base/'data/launches/acme'/run.name
if run!=expected or run.is_symlink() or a[-3:]!=[self.inputs.execs['node'],self.runner,str(run)] or '--chdir' not in a or a[a.index('--chdir')+1]!=str(run):self.e.fail('launch-kernel-argv-run-refused');continue
def contains(seq):return any(a[i:i+len(seq)]==seq for i in range(len(a)-len(seq)+1))
if not contains(['--setenv','NODE_OPTIONS','--import='+self.preload]) or not contains(['--ro-bind',self.preload,self.preload]):self.e.fail('launch-preload-route-missing');continue
binding=dict(wrapper=list(key),host=list(hk),run=str(run),registry=str(base/'data/control/runtimes'))
if str(run) in self.launches and self.launches[str(run)]!=binding:self.e.fail('launch-association-conflict');continue
self.launches[str(run)]=binding
self.proven_launches[str(path)]=dict(digest=digest,binding=binding)
def load_registries(self):
# Raw retained first; this host-only path is derived from actual kernel host/wrapper argv.
for launch in self.launches.values():
directory=Path(launch['registry']);self.archive_directory(directory,'runtime-control')
for path in directory.glob('*.json'):
r=self.e.parse(path,'runtime-control',missing_ok=True)
if r is not None:self.registries[str(path)]=r
def reconcile(self,fresh):
self.load_registries()
# A publication may have followed the initial snapshot. Drain fresh ancestry BEFORE
# classification, then allow further fresh passes within the unchanged5s ceiling.
fresh=self.o.traverse()
for path,r in self.registries.items():
if r.get('phase')=='ended':continue
for pf,sf in [('pid','startTime'),('runnerPid','runnerStartTime')]:
if r.get(pf) and r.get(sf) and (r[pf],r[sf]) not in self.o.rows:
self.pending_failure(('registry',path,pf,r[pf],r[sf]),'runtime-identity-unattributed')
elif r.get(pf) and r.get(sf):self.pending.pop(('registry',path,pf,r[pf],r[sf]),None)
return fresh
def runtime_for(self,launch,fresh):
wk=tuple(launch['wrapper']);matches=[]
for r in self.registries.values():
if r.get('kind')!='session' or r.get('business')!='acme' or r.get('run')!=Path(launch['run']).name or r.get('boot')!=self.boot:continue
if (r.get('pid'),r.get('startTime'))!=wk:continue
rk=(r.get('runnerPid'),r.get('runnerStartTime'))
if rk in fresh and self.o.descends(rk,wk,fresh):matches.append((rk,r))
unique={k:row for k,row in matches}
return next(iter(unique.items())) if len(unique)==1 else None
def derive(self,key,native,directory,fresh):
if native['exe']!=self.inputs.execs['node']:return None
env=self.o.selected_env(key)
if not env or env.get('NODE_OPTIONS')!='--import='+self.preload:return None
if directory==self.control/'host':
role=self.host_role(key,native)
if role:return dict(**role,wrapper=None,runner=None,host=list(key))
return None
for launch in self.launches.values():
run=launch['run']
if directory!=Path(run)/'.row227-native':continue
actual=self.runtime_for(launch,fresh)
if not actual:return None
rk,registry=actual;node=self.inputs.execs['node'];a=native['argv']
common=dict(wrapper=launch['wrapper'],runner=list(rk),host=launch['host'],run=run)
if key==rk and a==[node,self.runner,run]:return dict(**common,kind='runner',role='runner',module=self.runner,argv=a,execArgv=[])
if key!=rk and self.o.descends(key,rk,fresh) and a==[node,'--import',self.preload,self.adapter] and str(Path(env.get('MOSAIC_TURN_MARKER','/')).parent)==run:
return dict(**common,kind='adapter',role='adapter',module=self.adapter,argv=[node,self.adapter],execArgv=['--import',self.preload])
return None
def receipt(self,path,directory,fresh):
raw=self.e.raw(path,'native-control',missing_ok=True)
if raw is None:return
digest=hashlib.sha256(raw).hexdigest()
if str(path) in self.paths and self.paths[str(path)]!=digest:self.e.fail('native-receipt-rewritten');return
self.paths[str(path)]=digest
try:r=json.loads(raw)
except Exception as exc:self.e.fail('parse-native-'+type(exc).__name__);return
if set(r)!=set(['version','nonce','kind','pid','start','boot','nice','argv','module','execArgv','run']):self.e.fail('native-receipt-shape');return
if r.get('version')!=1 or r.get('nonce')!=self.nonce or r.get('boot')!=self.boot or r.get('nice')!=19:self.e.fail('native-receipt-invalid');return
matches=[(k,v) for k,v in fresh.items() if v['exe']==self.inputs.execs['node'] and v['start']==r.get('start') and v['nspid'] and v['nspid'][-1]==r.get('pid')]
# Previously released producer may have exited; unchanged bytes alone preserve prior
# attribution, never release a new record or conceal conflicts after its exit.
old=[(k,p) for k,p in self.producers.items() if p==(str(path),digest)]
if not matches and len(old)==1:return
if len(matches)!=1:self.pending_failure(('receipt',str(path)),'native-innermost-identity-unattributed');return
self.pending.pop(('receipt',str(path)),None)
key,native=matches[0]
if key in self.producers and self.producers[key]!=(str(path),digest):self.e.fail('native-producer-conflict-or-replay');return
self.producers[key]=(str(path),digest)
role=self.derive(key,native,directory,fresh)
if role is None:self.pending_failure(('role',str(path)),'native-kernel-role-run-unattributed');return
self.pending.pop(('role',str(path)),None)
expected={k:role[k] for k in ['kind','run','module','argv','execArgv']}
if any(r.get(k)!=v for k,v in expected.items()) or path.name!=f"{role['kind']}-{r['pid']}-{r['start']}.json":self.e.fail('native-role-module-run-argv-conflict');return
if native['nice']!=19:self.e.fail('native-release-priority-refused');return
binding=dict(**role,hostPid=key[0],hostStart=key[1],namespacePid=r['pid'],boot=self.boot,receiptSha256=digest)
if key in self.accepted and self.accepted[key]!=binding:self.e.fail('native-release-association-conflict');return
release=dict(receipt=r,binding=binding,receiptSha256=digest)
ack=path.with_suffix('.release')
if ack.exists():
prior=self.e.parse(ack,'native-release')
if prior!=release:self.e.fail('native-release-conflict');return
else:
# Revalidate latest association and ownership immediately before this exact release.
latest=self.o.observe(key)
if not latest or latest['nice']!=19 or self.derive(key,latest,directory,fresh)!=role:self.e.fail('native-release-latest-refused');return
temp=ack.with_suffix('.pending')
if temp.exists():self.e.raw(temp,'native-release-conflict');self.e.fail('native-release-pending-conflict');return
with temp.open('x') as f:f.write(json.dumps(release)+'\n')
temp.rename(ack)
self.accepted[key]=binding
if role['role']=='runner':
permit=self.control/'authorizations'/f"{role['wrapper'][0]}-{role['wrapper'][1]}.json"
authorization=dict(nonce=self.nonce,binding=binding)
if permit.exists():
if self.e.parse(permit,'host-authorization')!=authorization:self.e.fail('host-authorization-conflict');return
else:
temp=permit.with_suffix('.pending')
if temp.exists():self.e.raw(temp,'authorization-conflict');self.e.fail('authorization-publication-conflict');return
with temp.open('x') as f:f.write(json.dumps(authorization)+'\n')
temp.rename(permit)
self.e.write('native/'+f'{key[0]}-{key[1]}.json',dict(receipt=r,binding=binding))
def poll(self,fresh):
self.node_seen.update(k for k,r in fresh.items() if r['exe']==self.inputs.execs['node'])
self.archive_directory(self.control/'host','host-control')
for path in (self.control/'host').glob('*.json'):
if not path.name.endswith('.end.json'):self.receipt(path,self.control/'host',fresh)
self.load_launches(fresh);fresh=self.reconcile(fresh)
for run in self.launches:
directory=Path(run)/'.row227-native';self.archive_directory(directory,'sandbox-control')
for path in directory.glob('*.json'):
if not path.name.endswith('.end.json'):self.receipt(path,directory,fresh)
return fresh
def complete(self):
if self.exited_launches:
closure=self.e.parse(self.control/'fixture-cleanup.json','fixture-closure')
for run,binding in self.exited_launches.items():
if not isinstance(closure,dict) or closure.get('runtimeEntries')!=[] or not any(
r.get('run')==Path(run).name and [r.get('pid'),r.get('startTime')]==binding['wrapper']
for r in closure.get('runs',[]) if isinstance(r,dict)):
self.e.fail('proven-launch-exit-closure-unverified');continue
for key,accepted in self.accepted.items():
if accepted['run']==run:
current=self.o.valid(key)
if current and current['state']!='Z':self.e.fail('proven-launch-exit-still-live')
for directory in [self.control,self.control/'launches',self.control/'authorizations']+[Path(v['registry']) for v in self.launches.values()]:
self.archive_directory(directory,'completion-control')
if directory.exists() and any(p.name.endswith('.pending') or p.name.startswith('.receipt-') for p in directory.iterdir()):self.e.fail('control-publication-incomplete')
if self.pending:self.e.fail('unresolved-association-input')
if not any(b['role']=='host-main' for b in self.accepted.values()):self.e.fail('required-host-main-native-missing')
if not self.launches:self.e.fail('required-real-launch-missing')
for launch in self.launches.values():
for role in ['runner','adapter']:
if not any(b['role']==role and b['run']==launch['run'] and b['wrapper']==launch['wrapper'] for b in self.accepted.values()):self.e.fail('required-associated-'+role+'-missing')
for key in self.node_seen:
if key not in self.accepted:self.e.fail('observed-node-associated-receipt-missing')
for directory in [self.control/'host']+[Path(run)/'.row227-native' for run in self.launches]:
self.archive_directory(directory,'final-native-control')
for path in directory.glob('*.pending'):self.e.fail('native-publication-incomplete')
for path in directory.glob('*.json'):
if path.name.endswith('.end.json'):continue
if not path.with_suffix('.release').exists():self.e.fail('native-unreleased-input')
@@ -0,0 +1,24 @@
#!/usr/bin/python3
# Existing createLauncher bwrap test seam only: original sandbox args/mount policy retained.
import os,sys,json,time
from pathlib import Path
control=Path(sys.argv[1]).resolve(); preload=Path(sys.argv[2]).resolve(); args=sys.argv[3:]
if not control.is_dir() or not preload.is_file(): raise RuntimeError('native-wrapper-input')
os.setpriority(os.PRIO_PROCESS,0,19)
if os.getpriority(os.PRIO_PROCESS,0)!=19: raise RuntimeError('native-wrapper-priority')
config=json.loads((control/'control.json').read_text())
# sandboxProblem's true probe has no runner effects; it retains the real bwrap probe unchanged.
if len(args)>=3 and args[-2].endswith('/packages/harness/src/runner.mjs'):
run=Path(args[-1]).resolve()
if not run.is_relative_to(Path(config['private']).resolve()): raise RuntimeError('native-run-outside-owned-root')
directory=run/'.row227-native'; directory.mkdir(mode=0o700)
(run/'.row227-native-control.json').write_text(json.dumps(config)+'\n');os.chmod(run/'.row227-native-control.json',0o600)
stat=Path('/proc/self/stat').read_text();start=stat[stat.rfind(')')+2:].split()[19]
row=dict(version=1,nonce=config['nonce'],wrapperPid=os.getpid(),wrapperStart=start,run=str(run))
pending=control/'launches'/f'{os.getpid()}-{start}.pending'
with pending.open('x') as f: json.dump(row,f)
os.chmod(pending,0o600);pending.rename(pending.with_suffix('.json'))
# Invocation-only sandbox environment preserves isRunner's exact node/runner argv identity.
separator=args.index('--')
args=args[:separator]+['--setenv','NODE_OPTIONS','--import='+str(preload)]+args[separator:]
os.execv('/usr/bin/bwrap',['/usr/bin/bwrap',*args])
@@ -0,0 +1,75 @@
# Owned gate evidence only; raw bytes are retained before any control/registry parse.
import os,json,time,hashlib,stat
from pathlib import Path
class Evidence:
def __init__(self,root):
self.root=Path(root);self.root.mkdir(parents=True,exist_ok=False)
(self.root/'raw-inputs').mkdir();self.failures=[];self.unknown=False;self.inventory=[];self.saved=set()
self.journal=(self.root/'failure-journal.jsonl').open('x',buffering=1)
self.final=(self.root/'result.json').open('x');self.cleanup=(self.root/'cleanup.json').open('x')
def fail(self,code,unknown=True):
if code not in self.failures:self.failures.append(code)
self.unknown=self.unknown or unknown
try:self.journal.write(json.dumps(dict(at=time.time(),code=code))+'\n');self.journal.flush();os.fsync(self.journal.fileno())
except Exception:
try:os.write(2,b'gate-evidence-journal-failed\n')
except Exception:pass
def write(self,name,data):
try:
p=self.root/name;p.parent.mkdir(parents=True,exist_ok=True)
if not isinstance(data,bytes):data=(json.dumps(data,indent=2)+'\n').encode()
with p.open('wb') as f:f.write(data);f.flush();os.fsync(f.fileno())
return True
except Exception as exc:self.fail('evidence-write-'+type(exc).__name__);return False
def raw(self,path,category,missing_ok=False):
path=Path(path);fd=None
# Private capture limits, not product/API limits. The full admitted dependency manifest
# gets128MiB; admission8MiB and changing run logs64MiB; native/control records1MiB.
limit={'frozen-manifest':128*1024*1024,'admission':8*1024*1024,'run-control':64*1024*1024}.get(category,1024*1024)
def refuse(reason,info=None):
row=dict(path=str(path),category=category,disposition=reason,limit=limit,
mode=info.st_mode if info else None,size=info.st_size if info else None)
name=hashlib.sha256(json.dumps(row,sort_keys=True).encode()).hexdigest()
self.write('raw-refusals/'+name+'.json',row);self.inventory.append(row);self.fail('raw-'+reason)
try:
# Nonblocking open cannot wait for a FIFO writer; descriptor validation precedes READ.
fd=os.open(path,os.O_RDONLY|os.O_NOFOLLOW|os.O_NONBLOCK|os.O_CLOEXEC)
info=os.fstat(fd)
if not stat.S_ISREG(info.st_mode):refuse('nonregular-refused',info);return None
if info.st_size<0 or info.st_size>limit:refuse('size-refused',info);return None
# Read only the descriptor's initial finite size, never a growing stream through EOF.
chunks=[];remaining=info.st_size
while remaining:
block=os.read(fd,min(remaining,65536))
if not block:break
chunks.append(block);remaining-=len(block)
data=b''.join(chunks);after=os.fstat(fd)
sha=hashlib.sha256(data).hexdigest();key=(str(path),sha)
if key not in self.saved:
if self.write('raw-inputs/'+category+'/'+sha+'.raw',data):
self.saved.add(key);self.inventory.append(dict(path=str(path),category=category,sha256=sha,bytes=len(data),
initialSize=info.st_size,observedSizeAfter=after.st_size,
disposition='snapshot' if len(data)==info.st_size==after.st_size else 'finite-prefix-snapshot'))
return data
except FileNotFoundError:
if not missing_ok:self.fail('required-raw-input-missing')
except Exception as exc:refuse('capture-'+type(exc).__name__)
finally:
if fd is not None:
try:os.close(fd)
except Exception as exc:self.fail('raw-close-'+type(exc).__name__)
return None
def parse(self,path,category,missing_ok=False):
raw=self.raw(path,category,missing_ok)
if raw is None:return None
try:return json.loads(raw)
except Exception as exc:self.fail('parse-'+category+'-'+type(exc).__name__);return None
def inventory_write(self):return self.write('raw-inventory.json',self.inventory)
def reserved(self,handle,data):
try:
handle.seek(0);handle.truncate();handle.write(json.dumps(data,indent=2)+'\n');handle.flush();os.fsync(handle.fileno());return True
except Exception as exc:
self.fail('final-receipt-'+type(exc).__name__)
try:os.write(2,b'gate-final-receipt-failed; nonacceptance\n')
except Exception:pass
return False
@@ -0,0 +1,75 @@
# Admitted parent freeze, never a newly generated partial baseline.
import os,json,re,hashlib
from pathlib import Path
class Inputs:
def __init__(self,root,admission,expected_sha,evidence):
self.root=Path(root).resolve();self.e=evidence;self.admission=Path(admission);self.expected_sha=expected_sha
raw=evidence.raw(self.admission,'admission')
if raw is None or hashlib.sha256(raw).hexdigest()!=expected_sha:raise RuntimeError('admission-digest-refused')
self.profile=json.loads(raw)
if self.profile.get('version')!=1 or self.profile.get('admitted') is not True or self.profile.get('noRenicingDaemon') is not True or not self.profile.get('identity') or not self.profile.get('joinedIdentity'):raise RuntimeError('target-profile-unadmitted')
if Path(self.profile['root']).resolve()!=self.root:raise RuntimeError('admitted-root-refused')
self.manifest=Path(self.profile['inputManifest']['path']);content=evidence.raw(self.manifest,'frozen-manifest')
if content is None or hashlib.sha256(content).hexdigest()!=self.profile['inputManifest']['sha256']:raise RuntimeError('frozen-manifest-digest-refused')
self.expected={}
for line in content.decode().splitlines():
digest,name=line.split(' ',1);path=Path(name)
if not re.fullmatch('[a-f0-9]{64}',digest) or path.is_absolute() or '..' in path.parts or name in self.expected:raise RuntimeError('frozen-manifest-entry-refused')
self.expected[name]=digest
self.manifest_sha=hashlib.sha256(content).hexdigest()
self.execs={}
for kind in ['node','bwrap','python']:
row=self.profile['executables'][kind];p=Path(row['path']).resolve()
if hashlib.sha256(p.read_bytes()).hexdigest()!=row['sha256']:raise RuntimeError('admitted-executable-changed')
self.execs[kind]=str(p)
self.required=self.required_files()
if not self.required.issubset(self.expected):raise RuntimeError('frozen-execution-inputs-omitted')
def required_files(self):
root=self.root
required={'packages/seat/src/sandbox.mjs','packages/harness/src/runner.mjs','packages/harness/src/git-tools.mjs','packages/harness/src/first-output.mjs','scripts/test-case2.sh','package.json','package-lock.json','packages/webui/package.json','packages/webui/package-lock.json','RELEASE'}
sandbox=(root/'packages/seat/src/sandbox.mjs').read_text();block=sandbox.split('export const RUNNER_FILES = Object.freeze([',1)[1].split('].map',1)[0]
required.update(re.findall(r'"(packages/[^"\n]+)"',block))
# Real argv-launched and plugin/dynamic assets are seeds, not assumed literal host imports.
for directory in ['scripts/case2','agents/steelbeak/work/queue-227/gate','packages/harness/src','packages/seat/src','packages/plugins','packages/webui/src/public','roles','contracts','skills','tools/unslop-hook']:
p=root/directory
if p.exists():required.update(str(f.relative_to(root)) for f in p.rglob('*') if f.is_file() and 'node_modules' not in f.parts and '__pycache__' not in f.parts)
# Dependencies are mandatory own installed inputs; source-walk exclusions must not
# filter every file from these separately admitted trees.
for directory in ['node_modules','packages/webui/node_modules']:
tree=root/directory
if not tree.is_dir() or tree.is_symlink() or not tree.resolve().is_relative_to(root):raise RuntimeError('required-installed-dependency-tree-missing')
installed={str(f.relative_to(root)) for f in tree.rglob('*') if f.is_file() and '__pycache__' not in f.parts}
if not installed:raise RuntimeError('required-installed-dependency-tree-empty')
required.update(installed)
for p in (root/'packages').glob('*/tests/fixtures'):
required.update(str(f.relative_to(root)) for f in p.rglob('*') if f.is_file())
todo=list(required);seen=set()
while todo:
name=todo.pop()
if name in seen:continue
seen.add(name);p=root/name
if p.suffix not in ['.mjs','.js']:continue
for ref in re.findall(r'''(?:from\s*|import\s*\(\s*|new URL\(\s*)['"](\.[^'"]+)['"]''',p.read_text()):
q=(p.parent/ref).resolve()
if q.is_file() and q.is_relative_to(root):
relative=str(q.relative_to(root))
if relative not in required:required.add(relative);todo.append(relative)
return required
def measure(self):
result={}
for name in sorted(self.expected):
try:
path=self.root/name
if not path.resolve().is_relative_to(self.root):raise RuntimeError('input-outside-admitted-root')
result[name]=hashlib.sha256(path.read_bytes()).hexdigest()
except Exception as exc:result[name]='ERROR:'+type(exc).__name__;self.e.fail('pinned-input-unreadable')
for label,path,expected in [('@admission',self.admission,self.expected_sha),('@manifest',self.manifest,self.manifest_sha)]:
try:result[label]=hashlib.sha256(path.read_bytes()).hexdigest()
except Exception as exc:result[label]='ERROR:'+type(exc).__name__
if result[label]!=expected:self.e.fail('consumed-list-or-admission-changed')
for kind,row in self.profile['executables'].items():
try:result['@exe:'+kind]=hashlib.sha256(Path(row['path']).resolve().read_bytes()).hexdigest()
except Exception as exc:result['@exe:'+kind]='ERROR:'+type(exc).__name__
if result['@exe:'+kind]!=row['sha256']:self.e.fail('admitted-executable-changed')
if any(result.get(name)!=digest for name,digest in self.expected.items()):self.e.fail('admitted-frozen-input-changed')
return result
@@ -0,0 +1,73 @@
# No global PID census. JSON can neither create ownership nor select signals.
import os,time
from pathlib import Path
class Owned:
def __init__(self,boot,evidence):self.boot=boot;self.e=evidence;self.rows={};self.parents={};self.history={};self.first={}
def identity(self,pid):
try:
text=Path(f'/proc/{pid}/stat').read_text();v=text[text.rfind(')')+2:].split()
return dict(pid=pid,start=v[19],ppid=int(v[1]),state=v[0],boot=self.boot)
except FileNotFoundError:return None
def valid(self,key):
row=self.identity(key[0]);return row if row and row['start']==key[1] else None
def root(self,pid,parent):
row=self.identity(pid)
if not row or row['ppid']!=parent:raise RuntimeError('root-identity-refused')
key=(pid,row['start']);self.rows[key]=row;self.parents[key]=None;return key
def observe(self,key):
before=self.valid(key)
if not before:return None
# Only already owned PID/start may be inspected here.
directory=Path(f'/proc/{key[0]}');nice=os.getpriority(os.PRIO_PROCESS,key[0]);argv=(directory/'cmdline').read_bytes().split(b'\0')
argv=[s.decode(errors='strict') for s in argv if s];exe=os.readlink(directory/'exe') if before['state']!='Z' else ''
status=(directory/'status').read_text();cwd=os.readlink(directory/'cwd') if before['state']!='Z' else '';after=self.valid(key)
if not after:return None
ns=next((list(map(int,line.split()[1:])) for line in status.splitlines() if line.startswith('NSpid:')),[])
row=dict(**after,nice=nice,argv=argv,exe=exe,nspid=ns,cwd=cwd)
self.history[key]=row;self.first.setdefault(key,time.monotonic())
if row['state']!='Z' and nice!=19:self.e.fail('owned-native-priority-drift')
return row
def traverse(self):
# Drain newly discovered generations in this pass, with bounded work. More passes follow
# inside the same existing5s attribution window, never an extended acceptance deadline.
fresh={}
for depth in range(32):
added=False
for key in list(self.rows):
try:row=self.observe(key)
except (FileNotFoundError,ProcessLookupError):continue
if not row:continue
fresh[key]=row
if row['state']=='Z':continue
candidates=set()
try:
for task in Path(f'/proc/{key[0]}/task').iterdir():
try:candidates.update(int(v) for v in (task/'children').read_text().split())
except FileNotFoundError:pass
except FileNotFoundError:continue
if not self.valid(key):continue
for pid in candidates:
child=self.identity(pid)
if child and child['ppid']==key[0] and self.valid(key):
ck=(pid,child['start'])
if ck not in self.rows:self.rows[ck]=child;self.parents[ck]=key;added=True
if not added:break
return fresh
def descends(self,key,parent,fresh):
walked=set()
while key in fresh and key not in walked:
if key==parent:return True
walked.add(key);pk=self.parents.get(key);current=self.valid(key)
if pk is None or pk not in fresh or not current or current['ppid']!=pk[0] or not self.valid(pk):return False
key=pk
return False
def selected_env(self,key):
if not self.valid(key):return None
# Never dump provider credentials or the whole environment.
raw=Path(f'/proc/{key[0]}/environ').read_bytes();out={}
for value in raw.split(b'\0'):
name,sep,val=value.partition(b'=')
if name in [b'NODE_OPTIONS',b'MOSAIC_TURN_MARKER']:out[name.decode()]=val.decode()
return out if self.valid(key) else None
def fresh_survivors(self):
return [row for key in list(self.rows) if (row:=self.observe(key)) and row['state']!='Z']
@@ -0,0 +1,43 @@
// Private invocation/fixture barrier. Labels alone never authorize the controller's release.
import { setPriority, getPriority } from 'node:os';
import { readFileSync, writeFileSync, existsSync, renameSync } from 'node:fs';
import { dirname, join, resolve } from 'node:path';
import { createHash } from 'node:crypto';
const stat = readFileSync('/proc/self/stat', 'utf8');
const start = stat.slice(stat.lastIndexOf(')') + 2).split(/\s+/)[19];
const boot = readFileSync('/proc/sys/kernel/random/boot_id', 'utf8').trim();
const host = process.env.ROW227_CONTROL_ROOT;
const runDir = process.env.MOSAIC_TURN_MARKER ? dirname(process.env.MOSAIC_TURN_MARKER)
: process.argv[1]?.endsWith('/packages/harness/src/runner.mjs') ? resolve(process.argv[2]) : null;
const control = host ? JSON.parse(readFileSync(join(host, 'control.json'), 'utf8'))
: runDir ? JSON.parse(readFileSync(join(runDir, '.row227-native-control.json'), 'utf8')) : null;
if (!control || control.version !== 1 || !/^[a-f0-9]{32}$/.test(control.nonce)) throw Error('native-control-missing');
const kind = host ? 'host' : process.env.MOSAIC_TURN_MARKER ? 'adapter' : 'runner';
const role = host ? process.execArgv.includes('--check') ? 'host-syntax' : 'host-main' : kind;
const directory = host ? join(host, 'host') : join(runDir, '.row227-native');
setPriority(0, 19);
const nice = getPriority(0);
if (nice !== 19) throw Error('native-priority-refused');
const row = { version: 1, nonce: control.nonce, kind, pid: process.pid, start, boot, nice,
argv: process.argv, module: process.argv[1] ?? null, execArgv: process.execArgv, run: host ? null : resolve(runDir) };
const name = `${kind}-${process.pid}-${start}`;
const bytes = JSON.stringify(row) + '\n';
const digest = createHash('sha256').update(bytes).digest('hex');
const pending = join(directory, name + '.pending');
writeFileSync(pending, bytes, { flag: 'wx', mode: 0o600 });
renameSync(pending, join(directory, name + '.json'));
const stop = () => process.exit(143);
process.once('SIGTERM', stop); process.once('SIGINT', stop);
const end = Date.now() + 5000;
while (!existsSync(join(directory, name + '.release'))) {
if (Date.now() >= end) throw Error('native-release-timeout');
await new Promise(r => setTimeout(r, 10));
}
const release = JSON.parse(readFileSync(join(directory, name + '.release'), 'utf8'));
const binding = release.binding;
if (release.receiptSha256 !== digest || JSON.stringify(release.receipt) !== JSON.stringify(row)
|| binding?.receiptSha256 !== digest || binding.kind !== kind || binding.role !== role
|| binding.namespacePid !== process.pid || binding.hostStart !== start || binding.boot !== boot
|| binding.run !== row.run || binding.module !== row.module || JSON.stringify(binding.argv) !== JSON.stringify(row.argv)
|| JSON.stringify(binding.execArgv) !== JSON.stringify(row.execArgv) || getPriority(0) !== 19) throw Error('native-release-association-refused');
process.removeListener('SIGTERM', stop); process.removeListener('SIGINT', stop);
@@ -0,0 +1,166 @@
# Static-prepared admitted1014-only gate. No local execution; existing900/-k10 ceiling.
import sys
sys.dont_write_bytecode=True
import os,json,time,hashlib,subprocess,signal,secrets,shutil,re
from pathlib import Path
from evidence import Evidence
from inputs import Inputs
from owned import Owned
from association import Association
ROOT=Path.cwd().resolve();BASE=ROOT/'agents/steelbeak/work/queue-227';GATE=BASE/'gate'
E=Evidence(Path(sys.argv[1]).resolve());private=None;child=None;root_key=None;owner=None;control=None;assoc=None;frozen=None
handles={};pins_before=None;rc=None;sent=False;start=time.monotonic();cleanup=dict(disposition='not-started',private=None,survivors=None)
def guarded(code,fn,default=None):
try:return fn()
except Exception as exc:E.fail(code+'-'+type(exc).__name__);return default
def preserve_control():
if control is None:return
directories=[(control,'root-control'),(control/'host','host-control'),(control/'launches','launch-control'),(control/'authorizations','host-authorization')]
if assoc:
for run in assoc.launches:
path=Path(run)
for name in ['.row227-native-control.json','session.json','runner.log']:
E.raw(path/name,'run-control',missing_ok=True)
for pending in path.glob('*.pending'):E.raw(pending,'run-control',missing_ok=True)
directories += [(Path(run)/'.row227-native','sandbox-control') for run in assoc.launches]
directories += [(Path(launch['registry']),'runtime-control') for launch in assoc.launches.values()]
for directory,category in directories:
def capture_directory():
for path in directory.iterdir():
if path.is_file() or path.is_symlink():E.raw(path,category,missing_ok=True)
if directory.exists():guarded('raw-directory-capture',capture_directory)
def capture_driver():
if private is None:return
for sandbox in (private/'T').glob('tmp.*'):
if sandbox.is_symlink():E.fail('sandbox-symlink');continue
for name in ['steps.txt','stderr.txt']:
if name not in handles:
try:handles[name]=(sandbox/name).open('rb')
except FileNotFoundError:pass
def stop_owned():
global sent
if child is None or child.poll() is not None or sent:return
# No PID or signal selection from a JSON record.
if owner is None or root_key is None or not owner.valid(root_key):E.fail('root-stop-identity-unresolved');return
os.killpg(root_key[0],signal.SIGTERM);sent=True
try:
os.setpriority(os.PRIO_PROCESS,0,19)
if os.getpriority(os.PRIO_PROCESS,0)!=19:raise RuntimeError('driver-native-priority-refused')
if len(sys.argv)!=4:raise RuntimeError('admitted-run-needs-output-admission-and-sha')
# Copies raw admission/list before parsing. Checks already admitted joined identities,
# complete execution closure and consumed manifest digest before any test process exists.
frozen=Inputs(ROOT,sys.argv[2],sys.argv[3],E)
pins_before=frozen.measure();E.write('pins.before.json',pins_before)
if E.failures:raise RuntimeError('admitted-source-inputs-refused')
private=Path(subprocess.check_output(['mktemp','-d','/tmp/R227XXXXXX'],text=True).strip());cleanup.update(private=str(private),disposition='retained-until-verified')
for name in ['H','C','T','G']:(private/name).mkdir(mode=0o700)
control=private/'G'
for name in ['host','launches','authorizations']:(control/name).mkdir(mode=0o700)
nonce=secrets.token_hex(16);boot=Path('/proc/sys/kernel/random/boot_id').read_text().strip()
config=dict(version=1,nonce=nonce,private=str(private));(control/'control.json').write_text(json.dumps(config)+'\n');os.chmod(control/'control.json',0o600)
env=dict(os.environ)
for key in list(env):
if any(word in key for word in ['TOKEN','SECRET','PASSWORD','API_KEY','AUTH_SOCK','BUS_CAP','CREDENTIAL']):env.pop(key)
env.update(HOME=str(private/'H'),XDG_CONFIG_HOME=str(private/'C'),TMPDIR=str(private/'T'),MOSAIC_CONFIG=str(private/'C/config.json'),NO_COLOR='1',NODE_OPTIONS='--import='+str(GATE/'priority.mjs'),ROW227_CONTROL_ROOT=str(control),ROW227_CONTROLLER_CLEANUP='1')
os.setpriority(os.PRIO_PROCESS,0,19)
if os.getpriority(os.PRIO_PROCESS,0)!=19:raise RuntimeError('driver-native-priority-refused')
def preexec():
os.setpriority(os.PRIO_PROCESS,0,19)
if os.getpriority(os.PRIO_PROCESS,0)!=19:os._exit(125)
os.setsid()
owner=Owned(boot,E);assoc=Association(ROOT,private,control,nonce,boot,frozen,owner,E)
argv=['timeout','-k','10','900','bash','scripts/test-case2.sh']
E.write('command.json',dict(argv=argv,private=str(private),driverNice=os.getpriority(os.PRIO_PROCESS,0),controllerOwnsScratchRemoval=True,admissionSha256=sys.argv[3],joinedIdentity=frozen.profile['joinedIdentity']))
with (E.root/'stdout.raw').open('wb') as out,(E.root/'stderr.raw').open('wb') as err:
child=subprocess.Popen(argv,cwd=ROOT,env=env,stdout=out,stderr=err,preexec_fn=preexec);root_key=owner.root(child.pid,os.getpid())
while True:
try:
if os.getpriority(os.PRIO_PROCESS,0)!=19:E.fail('driver-native-priority-drift')
fresh=owner.traverse();preserve_control();fresh=assoc.poll(fresh);capture_driver()
for key,row in fresh.items():
if row['state']!='Z' and row['exe']==frozen.execs['node'] and key not in assoc.accepted and time.monotonic()-owner.first[key]>=5:E.fail('required-associated-node-timeout')
except Exception as exc:E.fail('monitor-error-'+type(exc).__name__)
if E.failures:guarded('owned-stop',stop_owned)
if child.poll() is not None:break
time.sleep(.01)
rc=child.wait()
except Exception as exc:E.fail('gate-error-'+str(exc) if isinstance(exc,RuntimeError) else 'gate-error-'+type(exc).__name__)
finally:
# Each action is separately guarded; malformed control, pins, observation or cleanup may
# never bypass the best-effort raw/failure/cleanup/result records below.
final_nice=guarded('driver-final-native-readback',lambda:os.getpriority(os.PRIO_PROCESS,0))
E.write('driver-final-native.json',dict(nice=final_nice))
if final_nice!=19:E.fail('driver-final-native-priority-refused')
guarded('final-raw-capture',preserve_control)
if child is not None and child.poll() is None:
guarded('final-owned-stop',stop_owned)
rc=guarded('child-not-reaped',lambda:child.wait(timeout=10),rc)
if child is not None and child.poll() is None:E.fail('owned-child-still-live')
for name,handle in handles.items():
def finish_stream(name=name,handle=handle):
handle.seek(0);data=handle.read();E.write('driver-'+name,data);handle.close()
guarded('driver-capture-finalization',finish_stream)
if child is not None and set(handles)!=set(['steps.txt','stderr.txt']):E.fail('required-driver-capture-missing')
if frozen:
measured=guarded('pin-finalization',frozen.measure)
E.write('pins.after.json',measured)
if measured!=pins_before:E.fail('source-input-pins-changed')
if assoc:
guarded('association-finalization',assoc.complete)
E.write('association.json',dict(accepted=[dict(pid=k[0],start=k[1],binding=v) for k,v in assoc.accepted.items()],pending=[repr(k) for k in assoc.pending],launches=assoc.launches,registries=assoc.registries))
if control:
def verify_closure():
closure=E.parse(control/'fixture-cleanup.json','fixture-closure')
if not isinstance(closure,dict) or closure.get('runtimeEntries')!=[]:E.fail('fixture-closure-unresolved')
elif not Path(closure.get('dataRoot','/')).resolve().is_relative_to(private):E.fail('fixture-closure-root-refused')
if (control/'fixture-cleanup.pending').exists():E.fail('fixture-closure-publication-incomplete')
guarded('fixture-closure-finalization',verify_closure)
if owner:
survivors=guarded('survivor-observation',owner.fresh_survivors)
cleanup['survivors']=survivors
if survivors is None or survivors:E.fail('owned-cleanup-unresolved')
E.write('process-history.json',list(owner.history.values()))
guarded('final-raw-capture',preserve_control)
if assoc:
for registry in set(v['registry'] for v in assoc.launches.values()):
def verify_registry(registry=registry):
path=Path(registry)
if path.exists() and list(path.iterdir()):E.fail('runtime-registry-cleanup-unresolved')
guarded('registry-cleanup-observation',verify_registry)
def hashes():
rows=[]
for p in sorted(E.root.iterdir()):
if p.is_file() and (p.suffix=='.raw' or p.name.startswith('driver-')):
data=p.read_bytes();rows.append(dict(path=p.name,bytes=len(data),sha256=hashlib.sha256(data).hexdigest()))
E.write('raw-hashes.json',rows)
guarded('raw-hash-finalization',hashes);E.inventory_write()
def leak_guard():
values=[]
for source in [ROOT/'scripts/case2/e2e.mjs',ROOT/'scripts/case2/fixture-credentials.mjs']:
values+=re.findall(r"const (?:FETCH_TOKEN|SEAT_TOKEN|HUMAN_TOKEN|FAKE_ZAI_KEY) = '([^']+)'",source.read_text())
# Raw-control bytes may include private fixture data; retain them as evidence, but no token
# is permitted in user-facing streams or metadata/history output.
for p in E.root.rglob('*'):
if p.is_file() and 'raw-inputs' not in p.parts and p.suffix in ['.raw','.json','.jsonl']:
if any(v.encode() in p.read_bytes() for v in values):E.fail('fixture-value-in-output-history')
guarded('leak-guard-finalization',leak_guard)
if rc!=0:E.fail('whole-script-nonzero',unknown=False)
cleanup['disposition']='retained-unresolved' if E.failures or E.unknown else 'verified-ready-to-remove'
# Commit failure/ownership disposition before removal. All failures retain the private root.
E.reserved(E.cleanup,cleanup);E.reserved(E.final,dict(exit=rc,acceptance=False,stage='before-cleanup',failures=E.failures,cleanup=cleanup))
if private is not None and not E.failures and not E.unknown:
try:shutil.rmtree(private);cleanup['disposition']='removed';cleanup['privateRootRemoved']=not private.exists()
except Exception as exc:E.fail('private-removal-'+type(exc).__name__);cleanup['disposition']='removal-error-retain-remainder';cleanup['privateRootRemoved']=False
elif private is not None:
cleanup['privateRootRemoved']=guarded('private-root-observation',lambda:not private.exists(),False)
E.reserved(E.cleanup,cleanup)
ok=rc==0 and not E.failures and cleanup.get('privateRootRemoved') is True
if not E.reserved(E.final,dict(exit=rc,acceptance=ok,elapsed=time.monotonic()-start,failures=E.failures,cleanup=cleanup)):ok=False
try:print(json.dumps(dict(exit=rc,acceptance=ok,failures=E.failures,cleanupDisposition=cleanup['disposition'])))
except Exception:ok=False
sys.exit(0 if ok else 1)
+15
View File
@@ -0,0 +1,15 @@
// C2-14 adds an observed real library tool read before C2-06's scripted reply adapter.
// The reply plan is fixture input, never evidence that a lookup or guard actually ran.
import '../../agents/steelbeak/work/queue-227/gate/priority.mjs';
import { appendFileSync, existsSync, readFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { callTool } from '../../packages/harness/src/tools.mjs';
const root = dirname(process.env.MOSAIC_TURN_MARKER);
const count = join(root, 'fixture-count');
const n = existsSync(count) ? Number(readFileSync(count, 'utf8')) : 0;
const step = JSON.parse(readFileSync(join(root, 'fixture-steps.json'), 'utf8'))[n];
for (const args of step?.lookups ?? []) {
const result = await callTool(process.env.MOSAIC_TOOL_SOCKET, 'library_get', args);
appendFileSync(join(root, 'fixture-lookups.jsonl'), JSON.stringify(result) + '\n');
}
await import('../../packages/harness/tests/fixtures/citation-adapter.mjs');
+28 -18
View File
@@ -1,7 +1,7 @@
// C2-14 (#1728): one scratch-root acceptance driver. No live host or real model.
// The human uses bindHuman in-process because a development agent cannot prove human CLI ancestry.
// The creative session is real createLauncher -> runner -> C2-06's scripted citation adapter.
// S6-S10 are drafted against row288's brief; do not run/request a slot until288 lands (sage-4167).
// All 17 steps run against landed APIs. Execution is serialized by Sage (Mos1961).
import { mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
import { dirname, join, resolve } from 'node:path';
import { DatabaseSync } from 'node:sqlite';
@@ -10,15 +10,17 @@ import { BASE, MARKER, git, mappingEntry } from '../../packages/library/tests/he
import * as library from '../../packages/library/src/index.mjs';
import { launchFixture } from './launch.mjs';
import { consoleAcceptance } from './console.mjs';
import { FAKE_ZAI_KEY } from './fixture-credentials.mjs';
const FETCH_TOKEN = 'fx227-fetch-q7';
const SEAT_TOKEN = 'fx227-seat-q7';
const FETCH_TOKEN = 'fx227-fetch-q7-2270';
const SEAT_TOKEN = 'fx227-seat-q7-2270';
const HUMAN_TOKEN = 'fx227-human-q7-2270';
const USER = 'books-bot', BUSINESS = 'acme';
const CHARACTER = 'Book One/Characters/Mara Vell.md';
const SUPPORT = 'Book One/Notes/Eyes.md';
const WRITE = 'Book One/Notes/Agent.md';
const EDITOR = { name: 'Fixture author', email: '[email protected]' };
const secrets = [FETCH_TOKEN, SEAT_TOKEN];
const EDITOR = { name: 'Fixture author', email: '[email protected]', user: 'writer' };
const secrets = [FETCH_TOKEN, SEAT_TOKEN, HUMAN_TOKEN, FAKE_ZAI_KEY];
const redact = value => secrets.reduce((s, token) => s.replaceAll(token, '[fixture credential]'), String(value));
let failures = 0;
const out = line => process.stdout.write(redact(line) + '\n');
@@ -74,7 +76,7 @@ async function main(root) {
const first = git(work, 'rev-parse', 'HEAD');
const tls = scratchCa(join(root, 'ca'));
const gitea = await fakeGitea({ dir: join(root, 'gitea'), tls, user: USER, token: FETCH_TOKEN,
users: { [USER]: FETCH_TOKEN, 'acme-bean': SEAT_TOKEN } });
users: { [USER]: FETCH_TOKEN, 'acme-bean': SEAT_TOKEN, [EDITOR.user]: HUMAN_TOKEN } });
cleanups.push(() => gitea.close());
const remote = gitea.repo('writer', 'books');
mkdirSync(dirname(remote), { recursive: true });
@@ -91,7 +93,7 @@ async function main(root) {
const remoteHead = () => git(remote, 'rev-parse', 'refs/heads/main');
const entry = { ...mappingEntry(), remote: `${gitea.origin}/writer/books.git`, user: USER, editor: EDITOR };
entry.universes.harbor.supporting = ['Book One/Notes/'];
const f = await launchFixture(root, entry, { fetchToken: FETCH_TOKEN, seatToken: SEAT_TOKEN, ca: tls.ca });
const f = await launchFixture(root, entry, { fetchToken: FETCH_TOKEN, seatToken: SEAT_TOKEN, humanToken: HUMAN_TOKEN, ca: tls.ca });
cleanups.push(() => f.close());
const { runtime: bus, dataRoot } = f, broker = bus.broker;
const human = broker.bindHuman({ business: BUSINESS, human: 'jason', via: 'cli', outsideAgent: true });
@@ -149,14 +151,14 @@ async function main(root) {
thread = (await humanCall('thread.create', { project, name: 'Book One', instance: 'bean' })).id;
const looked = await library.get(await source(), { universe: 'harbor', path: CHARACTER });
expect(looked && looked.scope === 'canon', 'lookup missing');
const index = looked.lines.findIndex(line => line.includes('Grey eyes.'));
const index = looked.lines.findIndex(([line, text]) => Number.isSafeInteger(line) && text.includes('Grey eyes.'));
expect(index >= 0, 'lookup quote missing');
citedCommit = looked.commit;
const cite = { path: CHARACTER, commit: citedCommit, lines: [index + 1, index + 1], quote: 'Grey eyes.', as: 'canon' };
const cite = { path: CHARACTER, commit: citedCommit, lines: [looked.lines[index][0], looked.lines[index][0]], quote: 'Grey eyes.', as: 'canon' };
const valid = text => JSON.stringify({ text, citations: [cite] });
const bad = JSON.stringify({ text: 'Playground is canon.', citations: [{ path: 'Book One/Playground/What If.md',
commit: citedCommit, lines: [4, 4], quote: MARKER, as: 'canon' }] });
f.setPlan([{ text: valid('Grey eyes.') }, { text: bad }, { text: valid('The playground cannot establish canon.') }]);
f.setPlan([{ lookups: [{ universe: 'harbor', path: CHARACTER }], text: valid('Grey eyes.') }, { text: bad }, { text: valid('The playground cannot establish canon.') }]);
asked = (await humanCall('thread.send', { thread, body: "What colour are Mara Vell's eyes?" })).id;
});
await step('S3b', 'the real launcher runs the C2-06 fake harness and stores its reply in her thread', async () => {
@@ -170,6 +172,10 @@ async function main(root) {
await step('S3c', 'her stored reply carries a verified lookup citation at the served commit', () => {
const body = JSON.parse(reply.body);
expect(body.text === 'Grey eyes.' && body.citations[0].commit === citedCommit, 'wrong reply');
const record = f.records.find(r => r.thread === thread);
const lookups = readFileSync(join(dataRoot, 'launches', BUSINESS, record.run, 'fixture-lookups.jsonl'), 'utf8').trim().split('\n').map(line => JSON.parse(line));
expect(lookups.length === 1 && lookups[0].path === CHARACTER && lookups[0].commit === citedCommit
&& lookups[0].scope === 'canon' && lookups[0].lines.some(([line, text]) => line === body.citations[0].lines[0] && text.includes('Grey eyes.')), 'managed harness lookup did not supply the cited source');
expect(reply.check?.citations?.length === 1 && reply.check.citations[0].scope === 'canon', 'missing stored guard check');
const events = readEvents(dataRoot, "kind='action.allowed'");
expect(events.some(e => e.action === 'message.checked' && e.message === reply.id && e.check.citations[0].scope === 'canon'), 'no stored check event');
@@ -198,16 +204,17 @@ async function main(root) {
expect(state.served === tip && state.diverged === null, 'tip not accepted');
});
// Pending on row288, not stubs or accepted skips. These calls become runnable only after its landing.
// Write assertions are measured here, after divergence acceptance; setup is never write evidence.
await step('S6', 'the fixture-granted seat writes one supporting commit with its trailer and a thread notice', async () => {
const before = remoteHead();
await call(f.cap(thread), 'library.doc.write', { universe: 'harbor', path: WRITE, base: null, content: '# Agent note\nA supporting observation.\n' });
const before = remoteHead(), requestsBefore = gitea.requests.length;
const result = await call(f.cap(thread), 'library.doc.write', { universe: 'harbor', path: WRITE, base: null, content: '# Agent note\nA supporting observation.\n' });
writeCommit = remoteHead();
expect(result.commit === writeCommit && result.path === WRITE, 'write result');
expect(writeCommit !== before && git(remote, 'rev-list', '--count', `${before}..${writeCommit}`) === '1', 'write must add exactly one commit');
expect(git(remote, 'show', '-s', '--format=%P', writeCommit) === before, 'write parent');
expect(git(remote, 'show', '-s', '--format=%B', writeCommit).includes('Mosaic-Agent: acme/bean'), 'missing agent trailer');
expect(git(remote, 'show', '-s', '--format=%an <%ae>', writeCommit) === 'Bean fixture <[email protected]>', 'seat author');
expect(gitea.requests.some(r => r.method === 'POST' && r.user === 'acme-bean' && r.path.endsWith('/git-receive-pack')), 'seat credential not used for push');
expect(gitea.requests.slice(requestsBefore).some(r => r.method === 'POST' && r.user === 'acme-bean' && r.path.endsWith('/git-receive-pack')), 'seat credential not used for push');
writeNotice = (await humanCall('thread.messages', { thread })).find(m => {
try { const body = JSON.parse(m.body); return body.notice === 'library-write' && body.commit === writeCommit; } catch { return false; }
});
@@ -222,28 +229,31 @@ async function main(root) {
expect(remoteHead() === before && (await status()).served === served, 'refusal moved a ref');
});
await step('S8', 'her revert of the agent write adds exactly one editor-authored commit', async () => {
const before = remoteHead();
const before = remoteHead(), requestsBefore = gitea.requests.length;
// A2 (sage-3596): revert names the business project key as well as the commit.
const result = await humanCall('library.revert', { project: 'books', commit: writeCommit });
const after = remoteHead();
expect(after !== before && git(remote, 'rev-list', '--count', `${before}..${after}`) === '1', 'revert commit count');
expect(git(remote, 'show', '-s', '--format=%P', after) === before, 'revert must have exactly one parent');
expect(gitea.requests.slice(requestsBefore).some(r => r.method === 'POST' && r.user === EDITOR.user && r.path.endsWith('/git-receive-pack')), 'revert did not use her credential');
expect(result.reverted === writeCommit && result.commit === after, 'revert result');
expect(!git(remote, 'ls-tree', '-r', '--name-only', after).split('\n').includes(WRITE), 'revert did not remove the newly created note');
expect(git(remote, 'show', '-s', '--format=%an <%ae>', after) === `${EDITOR.name} <${EDITOR.email}>`, 'revert editor');
});
await step('S9', 'her library.file.save adds one commit with her editor as author', async () => {
const before = remoteHead(), base = git(remote, 'rev-parse', `${before}:${CHARACTER}`);
const before = remoteHead(), requestsBefore = gitea.requests.length, base = git(remote, 'rev-parse', `${before}:${CHARACTER}`);
const content = git(remote, 'show', `${before}:${CHARACTER}`) + '\nHer saved note.\n';
await humanCall('library.file.save', { path: CHARACTER, base, content });
const result = await humanCall('library.file.save', { project: 'books', path: CHARACTER, base, content });
const after = remoteHead();
expect(after !== before && git(remote, 'rev-list', '--count', `${before}..${after}`) === '1', 'save commit count');
expect(git(remote, 'show', '-s', '--format=%P', after) === before, 'save must have exactly one parent');
expect(git(remote, 'show', '-s', '--format=%an <%ae>', after) === `${EDITOR.name} <${EDITOR.email}>`, 'save editor');
expect(git(remote, 'show', `${after}:${CHARACTER}`).endsWith('Her saved note.'), 'save content');
expect(result.commit === after && result.path === CHARACTER, 'save result');
expect(gitea.requests.slice(requestsBefore).some(r => r.method === 'POST' && r.user === EDITOR.user && r.path.endsWith('/git-receive-pack')), 'save did not use her credential');
});
await step('S10', 'the real Console renders her checked reply and the broker write notice', async () => {
expect(writeNotice && writeCommit, 'row288 write notice is required');
expect(writeNotice && writeCommit, 'actual write notice is required');
await consoleAcceptance({ humanCall, thread, reply, writeNotice, writeCommit, cleanups });
});
expect(holdsToken(dataRoot) === null, 'credential persisted during the later steps');
+2
View File
@@ -0,0 +1,2 @@
// Made up and confined to the nonproxy fake pi/zai fixture. Never a live credential.
export const FAKE_ZAI_KEY = 'fx227-zai-q7-2270';
+45 -12
View File
@@ -1,5 +1,5 @@
// C2-14 fixture: the real host/launcher with C2-06's scripted citation adapter. No model binary runs.
import { chmodSync, mkdirSync, writeFileSync } from 'node:fs';
import { chmodSync, mkdirSync, writeFileSync, existsSync, readdirSync, readFileSync, renameSync } from 'node:fs';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { BusError, writeGrantEvent } from '../../packages/bus/src/broker.mjs';
@@ -12,8 +12,10 @@ import { bootConfig, loadSystem } from '../../packages/cli/src/config.mjs';
import { createLauncher } from '../../packages/cli/src/launcher.mjs';
import { SESSION_CREDENTIALS } from '../../packages/seat/src/session.mjs';
import * as library from '../../packages/library/src/index.mjs';
import { FAKE_ZAI_KEY } from './fixture-credentials.mjs';
const ADAPTER = fileURLToPath(new URL('../../packages/harness/tests/fixtures/citation-adapter.mjs', import.meta.url));
const ADAPTER = fileURLToPath(new URL('./citation-adapter.mjs', import.meta.url));
const REPLY_ADAPTER = fileURLToPath(new URL('../../packages/harness/tests/fixtures/citation-adapter.mjs', import.meta.url));
const ROTATE = '2099-01-01';
const AT = '2026-10-24T00:00:00.000Z';
const shell = value => "'" + String(value).replaceAll("'", "'\\''") + "'";
@@ -40,12 +42,27 @@ function seedGrant(dataRoot, storeRoot, token) {
} finally { store.close(); }
}
export async function launchFixture(root, entry, { fetchToken, seatToken, ca }) {
export async function launchFixture(root, entry, { fetchToken, seatToken, humanToken, ca }) {
const control = process.env.ROW227_CONTROL_ROOT;
if (!control) throw new Error('row227-native-control-required');
const nativeNonce = JSON.parse(readFileSync(join(control, 'control.json'), 'utf8')).nonce;
const nativePermit = async record => {
const file = join(control, 'authorizations', `${record.pid}-${record.startTime}.json`);
const end = Date.now() + 5000;
while (!existsSync(file)) {
if (Date.now() >= end) throw Object.assign(new Error('native-host-permit-timeout'), { code: 'native-host-permit-timeout' });
await new Promise(resolve => setTimeout(resolve, 10));
}
const permit = JSON.parse(readFileSync(file, 'utf8'));
if (permit.nonce !== nativeNonce || permit.binding?.role !== 'runner'
|| permit.binding.wrapper?.[0] !== record.pid || permit.binding.wrapper?.[1] !== record.startTime
|| permit.binding.run?.split('/').at(-1) !== record.run) throw Object.assign(new Error('native-host-permit-refused'), { code: 'native-host-permit-refused' });
};
const configDir = join(root, 'config'), storeRoot = join(configDir, 'secrets', 'agents');
const slotDir = join(configDir, 'secrets', 'acme');
mkdirSync(slotDir, { recursive: true, mode: 0o700 });
for (const slot of [library.SLOT, library.HUMAN_SLOT])
writeFileSync(join(slotDir, slot), fetchToken + '\n', { mode: 0o600 });
for (const [slot, token] of [[library.SLOT, fetchToken], [library.HUMAN_SLOT, humanToken]])
writeFileSync(join(slotDir, slot), token + '\n', { mode: 0o600 });
const plan = join(root, 'citation-plan.json');
writeFileSync(plan, '[]\n', { mode: 0o600 });
const f = fixture(root, 'acme', doc => {
@@ -64,6 +81,9 @@ export async function launchFixture(root, entry, { fetchToken, seatToken, ca })
});
chmodSync(configDir, 0o700);
for (const key of SESSION_CREDENTIALS.flat()) delete f.env[key];
// Joined P3 keeps its real preflight; this fake route owns only its made-up ZAI key.
for (const key of ['OPENAI_API_KEY', 'OPENROUTER_API_KEY', 'ZAI_API_KEY']) delete f.env[key];
f.env.ZAI_API_KEY = FAKE_ZAI_KEY;
seedGrant(f.dataRoot, storeRoot, seatToken);
const system = loadSystem({ env: f.env });
const { trackers, ...boot } = bootConfig({ system, businessId: 'acme', env: f.env });
@@ -79,7 +99,15 @@ export async function launchFixture(root, entry, { fetchToken, seatToken, ca })
try { for (const hook of hooks) await hook(0); }
finally {
try { await runtime.close(); }
finally { for (const cleanup of cleanups.reverse()) await cleanup(); }
finally {
for (const cleanup of cleanups.reverse()) await cleanup();
const directory = join(f.dataRoot, 'control', 'runtimes');
const remaining = existsSync(directory) ? readdirSync(directory) : [];
writeFileSync(join(control, 'fixture-cleanup.pending'), JSON.stringify({ version: 1, dataRoot: f.dataRoot, runtimeEntries: remaining,
runs: records.map(({ pid, startTime, run }) => ({ pid, startTime, run })) }) + '\n', { mode: 0o600 });
renameSync(join(control, 'fixture-cleanup.pending'), join(control, 'fixture-cleanup.json'));
if (remaining.length) throw new Error('owned-runtime-cleanup-incomplete');
}
}
})());
try {
@@ -93,12 +121,13 @@ export async function launchFixture(root, entry, { fetchToken, seatToken, ca })
lifecycleRequests: m => runtime.lifecycleRequests(m.business),
};
const wrap = fn => async value => {
try { return fn(value); }
catch (e) { throw Object.assign(new Error('fixture host refused'), { code: e instanceof BusError ? e.code : 'fixture-host-refused' }); }
try { return await fn(value); }
catch (e) { throw Object.assign(new Error('fixture host refused'), { code: e instanceof BusError || /^[a-z-]+$/.test(e?.code ?? '') ? e.code : 'fixture-host-refused' }); }
};
const host = { business: 'acme', path: runtime.path, dataRoot: f.dataRoot,
op: wrap(m => { if (!Object.hasOwn(ops, m.op)) throw new BusError('invalid-host-request'); return ops[m.op](m); }),
bindLaunch: wrap(record => {
bindLaunch: wrap(async record => {
await nativePermit(record);
const bound = runtime.bindLaunch(record);
records.push(record); caps.set(record.thread, bound.cap);
return bound;
@@ -106,11 +135,15 @@ export async function launchFixture(root, entry, { fetchToken, seatToken, ca })
beforeClose: fn => void hooks.push(fn),
};
const adapter = join(root, 'citation-adapter.sh');
writeFileSync(adapter, `cp ${shell(plan)} "$(dirname "$MOSAIC_TURN_MARKER")/fixture-steps.json"\nexec ${shell(process.execPath)} ${shell(ADAPTER)}\n`, { mode: 0o644 });
const launcher = createLauncher({ host, system, env: f.env,
writeFileSync(adapter, `cp ${shell(plan)} "$(dirname "$MOSAIC_TURN_MARKER")/fixture-steps.json"\nexec ${shell(process.execPath)} --import ${shell(fileURLToPath(new URL('../../agents/steelbeak/work/queue-227/gate/priority.mjs', import.meta.url)))} ${shell(ADAPTER)}\n`, { mode: 0o644 });
const priority = fileURLToPath(new URL('../../agents/steelbeak/work/queue-227/gate/priority.mjs', import.meta.url));
const wrapper = fileURLToPath(new URL('../../agents/steelbeak/work/queue-227/gate/bwrap.py', import.meta.url));
const bwrap = join(root, 'owned-bwrap.sh');
writeFileSync(bwrap, `#!/bin/sh\nexec /usr/bin/python3 ${shell(wrapper)} ${shell(control)} ${shell(priority)} \"$@\"\n`, { mode: 0o700 });
const launcher = createLauncher({ host, system, env: f.env, bwrap,
makeLoader: await fakeHarnesses({ after: fn => cleanups.push(fn) }, { pi: adapter }, write =>
write('channel', 'webui', `export * from ${JSON.stringify(new URL('../../packages/plugins/channel/webui/index.mjs', import.meta.url).href)};`)),
readOnly: [ADAPTER, plan], harnessVersion: '0.85.1',
readOnly: [ADAPTER, REPLY_ADAPTER, plan, priority], harnessVersion: '0.85.1',
sessionDefaults: { pollInterval: 50 }, threadTickMs: 50, log: line => logs.push(line),
});
await launcher.listen();
+11 -4
View File
@@ -1,12 +1,15 @@
#!/usr/bin/env bash
# C2-14 (#1728, row227): one acceptance run on a scratch root, no skipped steps.
# Entry point for the real launcher/runner, C2-06 scripted adapter, fake TLS Gitea and Console DOM.
# S6-S10 wait on row288's landing; do not execute this draft before Sage's CLEAR (sage-4167).
# Run only in the serialized target slot (Mos1961); full gates/review/landing belong to the parent.
# The only human stand-in is bindHuman in-process; a development agent cannot prove human CLI ancestry.
set -uo pipefail
cd "$(dirname "$0")/.."
SANDBOX="$(mktemp -d)"
DRIVER_PID=''
CASE2_HOME="$SANDBOX/home"
CASE2_CONFIG="$SANDBOX/root/config/config.json"
mkdir -p "$CASE2_HOME"
cleanup() {
local result=$?
trap - EXIT INT TERM
@@ -14,7 +17,11 @@ cleanup() {
kill -TERM "$DRIVER_PID" 2>/dev/null || true
wait "$DRIVER_PID" 2>/dev/null || true
fi
rm -rf "$SANDBOX"
# The private controlled invocation delegates removal to the controller only after
# its source/native/capture/closure checks. Unset marker retains standalone cleanup.
if [ "${ROW227_CONTROLLER_CLEANUP:-}" != 1 ]; then
rm -rf "$SANDBOX"
fi
exit "$result"
}
trap cleanup EXIT
@@ -35,7 +42,7 @@ STEPS='S1a S1b S2a S2b S2c S2d S3a S3b S3c S4 S5a S5b S6 S7 S8 S9 S10'
node --check "$DRIVER" >/dev/null 2>&1
check "syntax: $DRIVER" "$?"
OUT="$SANDBOX/steps.txt" ERR="$SANDBOX/stderr.txt"
GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 node "$DRIVER" "$SANDBOX/root" >"$OUT" 2>"$ERR" &
env HOME="$CASE2_HOME" XDG_CONFIG_HOME="$CASE2_HOME/.config" MOSAIC_CONFIG="$CASE2_CONFIG" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 node "$DRIVER" "$SANDBOX/root" >"$OUT" 2>"$ERR" &
DRIVER_PID=$!
wait "$DRIVER_PID"
RC=$?
@@ -53,7 +60,7 @@ while IFS= read -r line; do
done <"$OUT"
[ "${seen# }" = "$STEPS" ]
check 'every acceptance step ran once, in order, with nothing skipped' "$?"
if grep -qF -e 'fx227-fetch-q7' -e 'fx227-seat-q7' "$OUT" "$ERR"; then
if grep -qF -e 'fx227-fetch-q7-2270' -e 'fx227-seat-q7-2270' -e 'fx227-human-q7-2270' -e 'fx227-zai-q7-2270' "$OUT" "$ERR"; then
check 'fixture credentials are in no driver output' 1
else
check 'fixture credentials are in no driver output' 0