diff --git a/CHANGELOG.md b/CHANGELOG.md index 57a8fb89..9148e469 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -139,6 +139,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). settle the claimed row under its ownership guard instead of escaping with a run left running. Regression tests also exercise the retryable write fence and observer-before-persistence ordering directly. + +- **Agent executor documentation describes the existing interactive lease.** The request and resume comments explain the shared failure result and distinguish approval-bound write continuations from remote writes that can execute in the initial leased segment. + - **Public tool-loop continuations preserve uncertainty about prior calls (ADR-216).** Skipping prompt assembly or seeding any resumed counter without authoritative invocation history now marks that history incomplete, so a rule requiring complete history refuses execution. Explicitly supplied history keeps its completeness flag. - **Invocation-rule denials have their own governance decision (ADR-216).** The governance chart and run timeline show `invocation_denied` with the bounded rule reason; the original tool-denial reason counts remain limited to offering-gate decisions. - **Write tools read page TSconfig as the run's acting user (#1017).** `update_content_element`, `create_content_element_draft`, `create_record_draft` and `copy_record` built their approval preview and their permission checks from page TSconfig as core resolves it for the ambient backend user: that user's workspace overlaid the rootline, their user TSconfig `page.` overrides were merged in, and their identity fed the `[backend.user…]` conditions. A run approved by another user, or resumed in a worker without one, could therefore bounce its approval or be checked against the approver's TSconfig. They now read it for the acting user, like `get_tsconfig`, which shows the acting user's view as well. diff --git a/Classes/Service/Agent/AgentRunExecutor.php b/Classes/Service/Agent/AgentRunExecutor.php index c492a779..726a8530 100644 --- a/Classes/Service/Agent/AgentRunExecutor.php +++ b/Classes/Service/Agent/AgentRunExecutor.php @@ -76,9 +76,10 @@ public function __construct( * * A queued run passes its worker identity as $leaseOwner (so each step * boundary renews the lease and detects a reaper reclaim, ADR-104) and a - * $recover closure that decides retry-vs-dead-letter for a failure. An - * interactive run() passes neither: it holds no lease and surfaces failures - * to its caller unchanged. + * $recover closure that decides retry-vs-dead-letter for a failure. + * An interactive run() passes its own lease when the run was persisted + * (ADR-141). It passes no recovery closure; loop failures use the shared + * lifecycle's default failure result. * * @param (Closure(RunStep): void)|null $onStep * @param (Closure(Throwable, list): ?AgentRunResult)|null $recover @@ -132,12 +133,12 @@ public function executeRequest( * factory over the context and the trace keeps the ordering here, where it * is stated once, instead of in each caller. * - * A resume carries no recovery: it is the continuation of a suspended run - * driven by a request, so a failure surfaces to its caller exactly as an - * interactive run's does. It DOES hold a lease (ADR-141). This is the - * segment a writing tool executes in — a write suspends before it runs - * (ADR-134), so the first pass never reaches the tool — and an unleased - * segment cannot arm the ADR-111 fence around it. + * A resume carries no queued recovery and uses the shared lifecycle's + * default failure result, like an interactive run. It holds a lease + * (ADR-141), so an approval-bound write can execute fenced in this + * continuation. A remote write that requires no approval can execute in + * the initial segment, which also holds a lease (ADR-134/141). An unleased + * segment cannot arm the ADR-111 fence around a write. * * @param (Closure(RunStep): void)|null $onStep * @param Closure(ToolExecutionContext, RunTrace): ToolLoopResult $loopCall