81 lines
3.9 KiB
Python
81 lines
3.9 KiB
Python
"""Synthetic native assessment qualification only. Never starts the development queue."""
|
|
import json
|
|
from pathlib import Path
|
|
import shutil
|
|
import sys
|
|
import uuid
|
|
import controller as c
|
|
import local_mode
|
|
|
|
|
|
def main():
|
|
root, worker, report_path = map(Path,sys.argv[1:])
|
|
config=c.read_json(root/'config.json')
|
|
policy=c.read_json(root/'proposed-p10-assessment.json')
|
|
config['repository']=str(worker.resolve())
|
|
engine=c.Engine(root,policy,config)
|
|
if c.read_json(root/'backlog.json')['executionEnabled'] or any(s['sessions'] for s in engine.store.read()['stages'].values()):
|
|
raise c.GateError('Qualification requires an unused disabled queue')
|
|
with c.RepoLock(worker):
|
|
prior=(root/'qualification.json').read_bytes() if (root/'qualification.json').exists() else None
|
|
try:
|
|
native=local_mode.qualify(engine)
|
|
finally:
|
|
if prior is not None:
|
|
(root/'qualification.json').write_bytes(prior)
|
|
else:
|
|
(root/'qualification.json').unlink(missing_ok=True)
|
|
if native['status'] != 'PASS':
|
|
c.atomic(report_path,dict(native=native,actualQueueStarted=False,assessment='NOT_RUN'))
|
|
raise c.GateError('Native signing isolation qualification failed; no further child launched')
|
|
token=uuid.uuid4().hex
|
|
probe=worker/'.artifacts/orchestrator-probes'/token
|
|
probe.mkdir(parents=True)
|
|
canary=worker/('.assessment-readonly-'+token)
|
|
canary.write_text('SYNTHETIC READ-ONLY CANARY')
|
|
output=worker/'docs/automation/stages/PHASE-10'/('native-probe-'+token+'.md')
|
|
output.parent.mkdir(parents=True,exist_ok=True)
|
|
logs=root/'probe'/('assessment-'+token)
|
|
receipt=root/'assessment-activation-01'
|
|
try:
|
|
shutil.copytree(receipt,probe/'receipt')
|
|
shutil.copyfile(Path(__file__).with_name('assessment_adapter.py'),probe/'assessment_adapter.py')
|
|
plan=dict(worker=str(worker.resolve()),receipt=str(probe/'receipt/receipt.json'),
|
|
pin=c.sha_file(receipt/'receipt.json'),canary=str(canary),output=str(output))
|
|
c.atomic(probe/'plan.json',plan)
|
|
(probe/'run.py').write_text('''import json, pathlib
|
|
import assessment_adapter
|
|
p=json.loads(pathlib.Path(__file__).with_name('plan.json').read_text())
|
|
r=assessment_adapter.verify(p['worker'],p['receipt'],p['pin'])
|
|
canary=pathlib.Path(p['canary'])
|
|
assert canary.read_text()=='SYNTHETIC READ-ONLY CANARY'
|
|
try:
|
|
with canary.open('r+b'): pass
|
|
except PermissionError: write_denied=True
|
|
else: write_denied=False
|
|
try: canary.unlink()
|
|
except PermissionError: delete_denied=True
|
|
else: delete_denied=False
|
|
pathlib.Path(p['output']).write_text('Synthetic native report creation')
|
|
assert write_denied and delete_denied
|
|
print(json.dumps(dict(evidenceIntegrity='PASS',sourceWriteDenied=write_denied,sourceDeleteDenied=delete_denied,reportWrite=True,kind=r['kind'],nativeReports=len(r['nativeReports']))))
|
|
''',encoding='utf-8')
|
|
argv=[config['codexExecutable'],'sandbox','-C',str(worker),
|
|
*local_mode.permission_args(root,engine.config,'sandbox'),
|
|
config['pythonExecutable'],'-B',str(probe/'run.py')]
|
|
engine.runner.supervise(engine,argv,logs,180)
|
|
observation=json.loads((logs/'stdout.log').read_text())
|
|
c.atomic(report_path,dict(native=native,assessment=observation,
|
|
candidateCommit=engine.git('rev-parse','HEAD'),actualQueueStarted=False,
|
|
compositeRuntime='BLOCKED_DOCKER_AND_SERVICE_BOUNDARY_UNQUALIFIED',logs=str(logs)))
|
|
finally:
|
|
canary.unlink(missing_ok=True)
|
|
output.unlink(missing_ok=True)
|
|
if probe.resolve().is_relative_to(worker.resolve()/'.artifacts/orchestrator-probes'):
|
|
shutil.rmtree(probe)
|
|
print('Synthetic native assessment checks complete; composite command runtime remains BLOCKED')
|
|
|
|
|
|
if __name__=='__main__':
|
|
main()
|