## Decision Desk refusals and failures

The successful path tells you what an operation is for\.&#32;Refusals and partial failures tell you when not to trust a convenient status message\.

This chapter uses failure cards\.&#32;Do not manufacture a live stream\,&#32;run a foreground job\,&#32;install a cancelling extension\,&#32;or trigger a provider failure for the exercise\.

### Milestone\:&#32;Classify the boundary before retrying

**Need\.**&#32;Eli sees a warning\,&#32;a blank\-looking UI region\,&#32;or an error after a transition\.

**Obstacle\.**&#32;“It did not finish normally” does not have one universal meaning\.

**Exact action\:**&#32;stop submitting work\,&#32;identify the operation and failure phase\,&#32;then inspect session information\,&#32;directories\,&#32;retained messages\,&#32;and relevant journal files\.

| Situation | What the current implementation does | Safe response |
| --- | --- | --- |
| `/fresh`&#32;while streaming | Refuses the refresh\. | Wait or abort normally\,&#32;then retry if refreshing provider state is still the goal\. |
| Interactive&#32;`/fork`&#32;while streaming | Controller refuses the fork\. | Do not assume it is queued to run later\. |
| `/clear`&#32;during streaming or foreground bash\/Python work | Reset method refuses\. | Let work settle or abort it normally\;&#32;inspect any file effects separately\. |
| `/clear`&#32;during compaction | Controller aborts and waits for compaction before attempting reset\. | A later refusal does not mean no maintenance action happened\. |
| `/new` | Offers a veto point\,&#32;then aborts current work and transitions\. | Do not treat it as a streaming\-guard equivalent\. |
| Fork in an in\-memory session | Returns failure\;&#32;controller reports “not persisted or cancelled\.” | Use the persistent fictional lab\,&#32;not a guessed save flag\. |
| Mode\-specific transition restriction | Some modes can block new\/fork transitions\. | Respect the restriction\;&#32;do not bypass it to make the workbook pass\. |

A refusal at the guarded method’s entry can preserve conversation state while the surrounding controller has already cleared editor text\,&#32;stopped a status indicator\,&#32;or cancelled maintenance\.

**Recorded check\.**&#32;Synthetic streaming and foreground predicates exercised the actual guards without running a real stream or foreground executable\.&#32;The tested conversation ledger remained unchanged\.

**Self\-check\.**&#32;Does “wait or abort” mean the refused command will automatically execute after the response ends\?

**Answer\:**&#32;No\.&#32;Inspect the settled state and deliberately retry the intended command\.

### Hooks can veto new\,&#32;fork\,&#32;and resume

An installed extension can return a cancellation result from&#32;`session_before_switch`&#32;for the reasons&#32;`new`\,&#32;`fork`\,&#32;or&#32;`resume`\.

You do not need to author a hook to understand the consequence\:

- Before\-event cancellation is a legitimate refusal\.
- A transient UI clear is not an identity measurement\.
- Ordinary queues that survived a veto still belong to the unchanged session\.
- A generic fork failure message does not distinguish every cause\.

**Recorded check\.**&#32;A real SDK extension vetoed fork\,&#32;new\,&#32;and resume\.&#32;Identity\,&#32;messages\,&#32;journal bytes\,&#32;and ordinary steering\/follow\-up queues were preserved in those checks\.

The native public lab disables extension discovery\.&#32;It is not intended to reproduce that hook scenario interactively\.

### The resume success\-status caveat

The supplied&#32;`SelectorController.handleResumeSession()`&#32;awaits&#32;`session.switchSession()`&#32;but does not check its boolean result before repainting and reporting success\.

Two separate checks establish the relevant boundaries\:

1. A controller test supplied a&#32;`false`&#32;switch result and observed a&#32;`Resumed session`&#32;status despite unchanged identity\.
2. The Decision Desk SDK test used a real hook cancellation and verified that underlying session state stayed unchanged\.

Those are complementary checks\,&#32;not a claim that a physical TUI with a real cancelling hook was exercised end to end\.

**Practical rule\:**&#32;after a questionable resume\,&#32;trust the actual session file\,&#32;identity\,&#32;and directories—not the success wording alone\.

### A failed switch has phases

The resume controller first flushes pending settings\.&#32;In the recorded preflight failure\,&#32;switching never began\.

Inside&#32;`AgentSession.switchSession`\,&#32;the operation then includes a veto point\,&#32;abort\/flush preparation\,&#32;a captured local\-state snapshot\,&#32;target loading\,&#32;context replacement\,&#32;restoration of available model\/thinking\/service\-tier information\,&#32;and reconciliation\.

The guarded target\-load block has rollback handling for many captured local fields\.

**Recorded check\.**&#32;Failure injected after actual target loading restored prior identity\,&#32;messages\,&#32;provider\-facing identity\,&#32;and ordinary queues\,&#32;then rethrew\.

Do not extend that result into any of these claims\:

- Every failure before the captured snapshot is rolled back\.
- Closed physical provider handles are recreated\.
- External effects or completed file edits are undone\.
- `/new`\,&#32;`/fork`\,&#32;and&#32;`/clear`&#32;share the same transaction boundary\.
- A mode or prompt\-refresh error always means the session switch was rolled back\.

The supplied switch path catches some post\-switch reconciliation and prompt\-refresh errors and logs them without undoing an otherwise committed switch\.&#32;The interactive cwd adapter is also a separate layer\.

A resumed interrupted conversation can receive a synthetic abort record\.&#32;Resume is not a promise that opening and closing every journal is byte\-for\-byte read\-only\.

### Warning only\:&#32;drop is not an erasure exercise

**Do not run&#32;`/drop`&#32;in this workbook\.**

The inspected command path requests best\-effort deletion of the previous session file and its artifact directory\,&#32;then starts a new session\.&#32;It has no confirmation dialog in that path\.

`AgentSession.newSession({ drop: true })`&#32;catches and logs a deletion failure and can still proceed\.&#32;The UI can consequently show&#32;`Session dropped`&#32;after incomplete deletion\.

That status does not establish secure erasure\.&#32;Forks\,&#32;exports\,&#32;backups\,&#32;temporary sidecars\,&#32;clipboard history\,&#32;workspace files\,&#32;and provider\-held copies may remain\.&#32;A session without a file is refused by the drop controller\.

Drop was not executed in the supplied proof\.&#32;Its warning is source inspection\,&#32;not a deletion result\.

**Self\-check\.**&#32;Which is stronger evidence\:&#32;`Session dropped`\,&#32;or an appropriately scoped retention\/deletion audit\?

**Answer\:**&#32;The audit\.&#32;The status label is not an erasure receipt\.

**Source anchors\:**&#32;`packages/coding-agent/src/session/agent-session.ts`&#32;—&#32;`newSession`\,&#32;`fork`\,&#32;`switchSession`\,&#32;`resetSessionContext`\;&#32;`packages/coding-agent/src/modes/controllers/selector-controller.ts`&#32;—&#32;`handleResumeSession`\;&#32;`packages/coding-agent/src/modes/controllers/command-controller.ts`&#32;—&#32;`handleDropCommand`\,&#32;`#runNewSessionFlow`\;&#32;`packages/coding-agent/src/slash-commands/builtin-lifecycle.ts`&#32;— lifecycle command routes\.
