feat(runtime): bind process and job resources to authority

This commit is contained in:
Alexandre Teixeira
2026-10-02 18:54:09 +01:00
parent 7b8ac6f631
commit db41d7e822
36 changed files with 2251 additions and 174 deletions
+36
View File
@@ -6,6 +6,7 @@ import json
import signal
import sys
import types
import os
from pathlib import Path
# Launch by absolute script path, so a task workspace cannot shadow src.
@@ -39,6 +40,40 @@ async def supervise(payload: dict) -> None:
loop.add_signal_handler(signal.SIGTERM, task.cancel)
loop.add_signal_handler(signal.SIGINT, task.cancel)
try:
# The supervisor is held on stdin until *all* publication succeeds.
# No legacy payload can reconstruct ownership from its PID or receipt.
job = json.loads(Path(payload["job_store"]).read_text())[payload["job_id"]]
published = json.loads(Path(payload["launch_path"]).read_text())
sidecar = json.loads(Path(payload["authority_path"]).read_text())
resource = payload["resource_identity"]
launch = payload["launch_resource"]
from src.agent_runtime.resources import ProcessLaunchResource, BackgroundJobResource
from src.agent_runtime.process_resources import validate_launch_spec, validate_job_receipt
typed_launch = ProcessLaunchResource.from_dict(launch)
typed_job = BackgroundJobResource.from_dict(resource)
typed_launch.validate()
validate_launch_spec(typed_launch, spec)
supervisor = typed_job.processes[0]
supervisor.validate()
receipt = containment._load_records().get(grant.id)
validate_job_receipt(typed_job, receipt)
if (supervisor.identity.pid != os.getpid()
or (typed_job.owner, typed_job.request_id, typed_job.thread_id) !=
(typed_launch.owner, typed_launch.request_id, typed_launch.thread_id)
or (published["authority"]["owner"], published["authority"]["request_id"], published["authority"]["session_id"]) !=
(typed_job.owner, typed_job.request_id, typed_job.thread_id)):
raise ValueError("Detached producer ownership changed")
if (job.get("resource_identity") != resource or job.get("launch_resource") != launch
or published.get("job") != resource or published.get("launch") != launch
or sidecar.get("job") != resource or sidecar.get("authority") != published.get("authority")
or published.get("containment_id") != grant.id
or (receipt.get("owner"), receipt.get("mechanism"), receipt.get("mode"), receipt.get("workspace")) !=
(grant.owner, grant.mechanism, grant.mode, spec.workspace)
or info.get("external") is True
or resource["containment_id"] != grant.id
or resource["generation"] != launch["generation"]
or receipt.get("launch_generation") != launch["generation"]):
raise ValueError("Detached launch authority linkage mismatch")
with open(payload["log_path"], "w", encoding="utf-8") as log:
def capture(text):
log.write(text)
@@ -75,6 +110,7 @@ async def supervise(payload: dict) -> None:
except OSError:
# A failed log initialization must not hide completion metadata.
sys.stderr.write(output)
report["resource_identity"] = payload.get("resource_identity")
atomic_write_json(payload["result_path"], report)
# Publish completion last: refresh must never see an exit without metadata.
atomic_write_text(payload["exit_path"], str(code if code is not None else 1))