feat(automation): enforce assessment scope and document activation blockers
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user