# Wall-E External Action Approval Boundary

## Problem

Wall-E can stage external actions such as sending email or creating calendar events. A real session showed the failure mode:

1. Wall-E staged three external actions and returned approval envelopes.
2. The user replied `go head`.
3. CTM did not convert that message into structured approvals.
4. CTM sent a normal model turn to Wall-E.
5. The model claimed the email and calendar events were done without any tool calls.

The bug is not provider-specific. Any model can claim a side effect happened if the host treats approval as prose instead of execution state.

## Architecture

External side effects must be controlled by the host, not by model narration.

- `wall-e/external-action-controller.js` creates a deterministic action envelope with `id`, `payloadHash`, exact payload, validation, and confirmation requirements.
- `wall-e/chat.js` executes only approved envelopes through `_executeApprovedExternalActions()`. It validates the approval against the staged payload, applies idempotency, runs the exact tool input, and emits tool events.
- `claude-task-manager/lib/walle-external-actions.js` maps the latest staged envelopes in the transcript to CTM approval payloads.
- `claude-task-manager/server.js` sends `externalActionApprovals` to Wall-E before a normal model turn. If approved actions exist, Wall-E's controller handles the turn and does not ask the model to improvise.

This matches the OpenCode-style permission boundary: the agent may request a tool action, but the runtime owns `allow`, `ask`, and `deny` decisions. It also matches MCP elicitation's structured outcome model: user confirmation is an explicit host result, not free-form text for the model to reinterpret.

## Fix

The CTM boundary now has two protections:

1. Pending-action-aware approval parsing.
   - Exact confirmations still work (`approve`, `go ahead`, `send it`).
   - Short typo-tolerant confirmations only work when the previous assistant turn has pending external action envelopes.
   - Coding/task text such as `go ahead with the fix` is rejected.

2. Post-turn honesty guard.
   - If pending external actions existed, no structured approval was sent, no successful side-effect tool result was observed, and the model claims completion, CTM replaces the reply with a deterministic "not executed" response.
   - This prevents persisted transcript lies such as "Email Sent" without a matching `mail_send` success event.

## Product Direction

The current text confirmation path is a compatibility fallback. The better UI is an explicit approval card for each staged external action:

- Show action summary, account, recipients/calendar, and payload hash-backed details.
- Buttons: `Approve`, `Cancel`, and eventually `Approve all`.
- Button clicks send the envelope approval directly to CTM instead of relying on natural-language confirmation.
- The transcript still records the tool result so the user can audit whether the action really executed.

## Test Strategy

- Unit tests cover exact approvals, typo-tolerant approvals with pending state, coding-task false positives, staged action extraction, and the unverified-completion guard.
- Live smoke testing should exercise the real controller path against a safe self-send email:
  1. Build a `mail_send` external action envelope.
  2. Approve the exact envelope through Wall-E chat's `externalActionApprovals` option.
  3. Verify a successful `mail_send` tool result.
  4. Search sent mail for the unique subject.

The live test validates the boundary that matters: a user approval becomes one real side effect, and the transcript contains proof.
