You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current standing-rule mediation can turn ApprovalRequired into Allow and then call the generic action dispatcher. A catalogued action without a registered handler returns a successful stub response. This is not safe for reusable delegation:
email.create_draft is deliberately absent from the allowed-action handler registry because the working Gmail write lives in the separate post-approval path;
a standing rule for email.create_draft can therefore reserve/finalize budget and report success without creating a Gmail draft;
future actions could repeat the same false-success pattern.
Approval source must not choose a different implementation. Per-instance approval and reusable delegated authority must converge on the same kernel-owned effect executor and immutable request semantics.
Scope
1. Effect executor registry
Introduce a catalog/registry-owned effect executor contract for effectful actions. A delegatable action must have exactly one executable adapter that accepts the kernel-built action request/resolved context.
The registry must distinguish:
catalogued but intentionally unavailable actions;
actions handled on the ordinary allowed path;
actions requiring per-instance approval or standing-rule mediation before the same executor runs;
internal/non-effect actions.
A missing executor MUST be a fail-closed typed error. It must never return stub: true as successful execution for an effectful or delegatable action.
2. Shared Gmail draft executor
Extract the existing approved Gmail draft write into one kernel-owned email.create_draft executor. Both paths must call it:
exact digest-bound per-instance approval;
a future scope-matched, budget-reserved standing-rule admission.
The executor must re-use the existing immutable payload/target re-derivation, recipient/thread/account checks, connector breaker, delivery-unknown fencing, audit, and idempotency behavior. The standing-rule path must not reconstruct those semantics from a shell payload.
3. Reservation correctness
No executor available: cancel any pre-effect standing-rule reservation.
Confirmed pre-effect failure: cancel reservation.
Confirmed success: finalize once.
Delivery unknown after an external write may have landed: retain/finalize and fence retry, matching the existing Gmail contract.
A successful result must mean the real effect executor ran or an explicitly non-effect action completed; never merely that an ID was known.
4. Delegation readiness
Action proposal/review must be able to ask the registry whether an action is execution-backed for reusable delegation. email.create_draft is not marked ready until the shared executor is wired.
TDD sequence
Characterize the current failure with a test showing that standing-rule mediation for email.create_draft reaches the missing-handler stub and consumes budget without a Gmail write.
Add a contract test that any effectful action missing an executor fails before reservation finalization.
Extract the Gmail draft executor while preserving all current per-instance approval tests.
Add tests proving per-instance approval and delegated admission call the same executor with the same target/payload semantics.
Add delivery-unknown and audit-failure tests on both admission sources.
Invariants
The shell still sends intents; it never selects the executor or trusted target.
gate() and current policy precedence remain unchanged.
email.send remains denied.
Standing rules remain composition inputs; they do not become an alternate connector API.
No connector write happens without durable gate/audit evidence.
Done when
dispatch_allowed_action cannot report a successful stub for an effectful/delegatable action.
email.create_draft has one real executor used by both approval sources.
A standing-rule reservation is finalized only when the executor ran or the write outcome is truthfully delivery-unknown.
All existing digest-bound approval and Gmail mutation tests remain green.
Why
The current standing-rule mediation can turn
ApprovalRequiredintoAllowand then call the generic action dispatcher. A catalogued action without a registered handler returns a successful stub response. This is not safe for reusable delegation:email.create_draftis deliberately absent from the allowed-action handler registry because the working Gmail write lives in the separate post-approval path;email.create_draftcan therefore reserve/finalize budget and report success without creating a Gmail draft;Approval source must not choose a different implementation. Per-instance approval and reusable delegated authority must converge on the same kernel-owned effect executor and immutable request semantics.
Scope
1. Effect executor registry
Introduce a catalog/registry-owned effect executor contract for effectful actions. A delegatable action must have exactly one executable adapter that accepts the kernel-built action request/resolved context.
The registry must distinguish:
A missing executor MUST be a fail-closed typed error. It must never return
stub: trueas successful execution for an effectful or delegatable action.2. Shared Gmail draft executor
Extract the existing approved Gmail draft write into one kernel-owned
email.create_draftexecutor. Both paths must call it:The executor must re-use the existing immutable payload/target re-derivation, recipient/thread/account checks, connector breaker, delivery-unknown fencing, audit, and idempotency behavior. The standing-rule path must not reconstruct those semantics from a shell payload.
3. Reservation correctness
4. Delegation readiness
Action proposal/review must be able to ask the registry whether an action is execution-backed for reusable delegation.
email.create_draftis not marked ready until the shared executor is wired.TDD sequence
email.create_draftreaches the missing-handler stub and consumes budget without a Gmail write.Invariants
gate()and current policy precedence remain unchanged.email.sendremains denied.Done when
dispatch_allowed_actioncannot report a successful stub for an effectful/delegatable action.email.create_drafthas one real executor used by both approval sources.Relationship
Parent: #123.
Requires: #126.
Blocks the scoped matching and Gmail end-to-end proof slices.