Files
jobtrackingapp/automation/qualify_assessment.py
T

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()