fix(runtime): isolate nested invocation ownership

This commit is contained in:
Alexandre Teixeira
2026-10-01 02:11:53 +01:00
parent 4c122de880
commit aedec7d005
6 changed files with 691 additions and 64 deletions
+5 -3
View File
@@ -181,8 +181,9 @@ def with_completion_gate(func):
trusted_workspace = vet_workspace(bound.get('workspace')) if bound.get('workspace') else ''
requirements = replace(requirements, workspace_root=trusted_workspace or '')
parent = current_journal()
journal = parent if parent is not None and parent.workspace == requirements.workspace_root else ActionJournal(
workspace=requirements.workspace_root, observed_artifacts=requirements.required_artifacts)
journal = ActionJournal(
workspace=requirements.workspace_root, observed_artifacts=requirements.required_artifacts,
parent_run_id=bound.get('_parent_run_id') or (parent.run_id if parent is not None else None))
answer_events: list[dict] = []
metrics_events: list[dict] = []
answer = ''
@@ -308,7 +309,8 @@ def with_completion_gate(func):
for event in metrics_events:
metadata = event.setdefault('data', {})
metadata.update(completion_decision=decision.to_dict(), evidence_events=ledger.to_list(),
action_receipts=journal.to_list(), completion_requirements=requirements.to_dict())
action_receipts=journal.to_list(), completion_requirements=requirements.to_dict(),
run_id=journal.run_id, parent_run_id=journal.parent_run_id)
metadata['completion_gate'] = {
'buffer_seconds': released_at - first_answer_at if first_answer_at is not None else 0,
'first_visible_answer_seconds': released_at - started,
+3
View File
@@ -66,6 +66,7 @@ class ActionJournal:
actions: list[ActionReceipt] = field(default_factory=list)
workspace: str = ''
observed_artifacts: tuple[str, ...] = ()
parent_run_id: str | None = None
def capture_versions(self, action: ActionReceipt) -> None:
if self.workspace:
@@ -111,9 +112,11 @@ _ACTION: ContextVar[ActionReceipt | None] = ContextVar('runtime_current_action',
@contextmanager
def bind_journal(journal: ActionJournal):
token = _JOURNAL.set(journal)
action_token = _ACTION.set(None)
try:
yield journal
finally:
_ACTION.reset(action_token)
_JOURNAL.reset(token)