Recover exact task cleanup after executor process loss
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
This commit is contained in:
codex 2026-10-16 16:43:20 +02:00
parent d870596cc7
commit b9eaa20060
6 changed files with 774 additions and 2 deletions

View file

@ -3,7 +3,8 @@
This adapter deliberately admits only a disposable loopback fixture. It supplies
real native primitive coverage while production grant schema, identity/consume and
origin/source admission are unfinished. It cannot open an estate backend. Owner
credentials/handles stay in memory; no subprocess, redirects or ambient proxy.
bearer credentials stay in memory; optional owner-private fixture custody persists
accessors for independently admitted cleanup recovery; no redirects or ambient proxy.
Python privacy is not credential isolation; production needs the owner runtime.
"""
from __future__ import annotations
@ -41,7 +42,7 @@ class FixtureAdmission:
class NativeFixtureAdapter:
def __init__(self, compiler: Compiler, plan: Plan, journal: Journal,
binding: Binding, admission: FixtureAdmission):
binding: Binding, admission: FixtureAdmission, *, recovery_custody=None):
if type(admission) is not FixtureAdmission or type(admission.descriptor) is not bytes:
raise Refused('independent fixture admission required')
self.compiler,self.plan,self.journal,self.binding=compiler,plan,journal,binding
@ -100,6 +101,12 @@ class NativeFixtureAdapter:
if self.meta['cleanup'] != cleanup_specs(binding.operation_id): raise Refused('cleanup plan mismatch')
self.task=None; self._mint_attempted=False; self._policy_attempted=False; self._ordinal=0; self._next_metadata=0
self._cleanup_steps={item.kind:0 for item in self.cleanup}
self.recovery_custody=recovery_custody
if recovery_custody is not None:
from task_execution_recovery import FixtureRecoveryCustody
if type(recovery_custody) is not FixtureRecoveryCustody or journal.observe(binding) is not None:
raise Refused('fresh independent fixture recovery custody required')
recovery_custody.prepare(binding,self.cleanup,self.port,self.hcl,admission.identity_session.accessor)
def _live(self):
if not self.journal._held or self.journal._admission!=self.binding or self.journal._consumed_admission!=self.binding:
@ -177,6 +184,8 @@ class NativeFixtureAdapter:
'type':'service','display_name':'task-exec-'+self.binding.operation_id,'no_parent':False}
if body!=self.meta['execution_grant']['openbao']['token_create_body']:
raise Refused('native token body differs from bound owner projection')
if self.recovery_custody is not None:
self.recovery_custody.checkpoint(self.binding,'mint-intent')
self._mint_attempted=True
status,data=self._business('POST','auth/token/create',root,encoded(body));self._ok(status,data,{200})
auth=data.get('auth',{})
@ -185,6 +194,8 @@ class NativeFixtureAdapter:
# Retain handles before validation so finally cleanup can revoke even a
# malformed overbroad issue response. Never return token-bearing metadata.
self.task=PrivateSession(auth['client_token'],auth['accessor'])
if self.recovery_custody is not None:
self.recovery_custody.checkpoint(self.binding,'issued',self.task.accessor)
status,data=self._business('POST','auth/token/lookup',root,encoded({'token':self.task.token}));self._ok(status,data,{200})
info=data.get('data',{})
if (info.get('policies')!=[self.policy_name] or info.get('identity_policies',[]) or info.get('renewable') is not False