## Seed Desk\:&#32;reservations on the active branch

Mara wants the agent to help hold fictional packets while she works through a conversation\.&#32;Her obstacle is no longer retrieval\.&#32;It is stale decisions\:&#32;a reservation based on an old availability view must not silently overwrite a newer one\.

She chooses&#32;**current\-branch reconstruction plus revision\-checked actions**\.

This is still not a stock system\.&#32;Separate sessions and processes do not coordinate physical inventory\.

### Milestone\:&#32;a confirmed human reservation

**Starting state\:**&#32;the stage\-3 fixture has eight basil packets\,&#32;five bean packets and three marigold packets\.&#32;Reservations are empty\.&#32;Agent actions are disabled\.

Files\:

- [Stage 3 entry](<https://present-sketch-tp94.here.now/examples/seed-desk/03-reservations/index.ts>)
- [Reservation domain and reconstruction](<https://present-sketch-tp94.here.now/examples/seed-desk/03-reservations/desk.ts>)
- [Inventory](<https://present-sketch-tp94.here.now/examples/seed-desk/03-reservations/inventory.json>)
- [Package manifest](<https://present-sketch-tp94.here.now/examples/seed-desk/03-reservations/package.json>)
- [Tool description](<https://present-sketch-tp94.here.now/examples/seed-desk/03-reservations/tool.txt>)

For a standalone download\,&#32;install the matching dependencies in this stage\.&#32;This is package\-manager work and may access your registry\.&#32;If those custom versions are unavailable\,&#32;use the matching installed source workspace instead\.

**Terminal shell—dependency installation\,&#32;then launch\:**

~~~sh
cd "$EXAMPLES/seed-desk/03-reservations"
bun install
cd "$LAB/work"
omp --no-extensions --no-skills -e "$EXAMPLES/seed-desk/03-reservations/index.ts" --session "$LAB/seed-session.jsonl"
~~~

**Human OMP slash commands\:**

~~~text
/seeds query
/seeds reserve basil-genovese 2
~~~

Cancel the first confirmation\.&#32;Then repeat the reservation command and confirm\.

**Expected state after confirmation on a fresh branch\:**

~~~text
basil-genovese: 6 available, 2 reserved
~~~

The query also supplies a revision\.&#32;Its concrete value comes from your session\,&#32;so it will not match a printed workbook token\.

#### What changed in the code\?

The domain separates\:

- the immutable fictional fixture\;
- a persisted snapshot containing&#32;`version`\,&#32;`agentEnabled`&#32;and reservation&#32;`quantities`\;
- a derived revision\;
- domain validation in&#32;`changeReservation()`\.

A successful change appends a custom entry named&#32;`seed-desk-state-v1`\.&#32;It then reconstructs state\,&#32;refreshes the status and emits&#32;`workbook:seed-desk:changed`\.

The extension does not write a separate inventory file\.

#### Why the second revision check matters

A confirmation dialog is an&#32;`await`\.&#32;During that wait\,&#32;another action or a session\-tree movement may occur\.

**Exact excerpt—post\-dialog check in&#32;[stage 3’s entry](<https://present-sketch-tp94.here.now/examples/seed-desk/03-reservations/index.ts>)\;&#32;read in its surrounding command handler\:**

~~~ts
// Re-read after the dialog: another action or tree navigation may have happened.
const current = reconstruct(ctx);
if (current.revision !== initial.revision) throw new DeskRefusal("stale-revision", "The branch changed during confirmation; try again.");
const snapshot: Snapshot = grant
    ? { version: 1, quantities: current.quantities, agentEnabled: value === "on" }
    : changeReservation(current, verb, value ?? "", Number(count), initial.revision, "human");
const saved = commit(ctx, snapshot, grant ? `agent-${value}` : verb);
~~~

After validation\,&#32;the commit path has no asynchronous gap before&#32;`appendEntry()`\.&#32;That prevents JavaScript invocations from interleaving inside this small validation\-and\-append segment\.&#32;It is not a cross\-process transaction or a durable database lock\.

**Observed\:**&#32;cancellation appended no state entry\.&#32;A confirmation\-race scenario changed state while the dialog was open\;&#32;the waiting human reservation was then refused\,&#32;leaving bean reservations at zero\.

**Exercise\:**&#32;reserve two basil packets\,&#32;then cancel a request to release one\.

**Checkpoint\:**&#32;basil remains at two reserved\.&#32;Cancellation before commit is not a release\.

### Milestone\:&#32;grant the agent a bounded domain capability

Mara now wants the agent to make fictional reservations without opening a dialog for every domain decision\.&#32;She does not want the tool to grant itself that authority\.

**Human OMP slash command\:**

~~~text
/seeds agent on
~~~

Confirm the scoped dialog\.

The model\-facing interface is now&#32;`seed_desk`\.

**Model tool arguments—call&#32;`seed_desk`\:**

~~~json
{"op":"discover"}
~~~

~~~json
{"op":"query"}
~~~

~~~json
{"op":"inspect","id":"basil-genovese"}
~~~

The tool supports\:

| Operation | Purpose |
| --- | --- |
| `discover` | Explain supported operations\,&#32;action prerequisites and the current state revision |
| `query` | Return valid IDs\,&#32;available\/reserved quantities and a revision\;&#32;optionally filter by exact family |
| `inspect` | Read one exact seed ID |
| `act` | Reserve or release a positive integer quantity using the current revision and a human\-granted permission |

The structured response includes&#32;`ok`\,&#32;`scope`\,&#32;and\,&#32;when available\,&#32;`revision`\,&#32;`agentEnabled`\,&#32;`code`&#32;and&#32;`data`\.

The text response includes the domain outcome and revision\.&#32;Do not assume every field in&#32;`details`\,&#32;including permission status\,&#32;is automatically sent to the model\;&#32;a host exposing structured details has more information than ordinary text\-only model replay\.

#### Ask the agent for the right sequence

**Agent request—use in an authorized model session\:**

~~~text
Use seed_desk to query current fictional availability.
Choose bean-scarlet only if at least one packet is available.
Reserve one packet using the exact revision returned by that query.
If the operation is refused, explain the refusal and query again before
deciding whether another action is appropriate. Do not retry blindly.
~~~

A model session requires your normal provider configuration and may incur charges\.&#32;The recorded example checks did not use provider inference\.

For readers inspecting the schema\,&#32;this is the action shape\:

**Illustrative model\-tool argument template—not usable until the revision is replaced with the actual latest returned value\:**

~~~json
{
  "op": "act",
  "action": "reserve",
  "id": "bean-scarlet",
  "packets": 1,
  "expectedRevision": "COPY_THE_LATEST_RETURNED_REVISION"
}
~~~

A successful action returns a new revision\.&#32;Reusing the old one is a refusal\,&#32;not a second reservation\.

#### Refusals are part of the interface

| Condition | Domain code | Correct next action |
| --- | --- | --- |
| No human grant | `agent-disabled` | Ask the human whether to enable the domain capability |
| Old revision | `stale-revision` | Query again\;&#32;reconsider the intended action |
| Invented ID | `invalid-target` | Use an ID from query results |
| Zero\,&#32;negative or unsafe quantity | `invalid-quantity` | Supply a positive safe integer |
| More than available | `insufficient-availability` | Reduce the quantity or choose another item |
| Release exceeds this branch’s holding | `insufficient-reservation` | Inspect current reservations |
| Incompatible or invalid persisted snapshot | `corrupt-state` | Stop and navigate to a valid earlier branch |
| Human mutation without UI | `ui-required` | Use a supported interactive confirmation path |

The schema can reject malformed inputs before the domain runs\.&#32;The domain also validates action\,&#32;quantity and target\.&#32;These are complementary checks\.

Seed Desk returns ordinary domain refusals as&#32;`details.ok: false`&#32;with explanatory text\.&#32;It does not mark every such refusal as a thrown transport\/tool error\.&#32;An SDK caller must inspect&#32;`ok`\,&#32;not merely whether a promise resolved\.

**Observed\:**&#32;the recorded checks covered disabled authority\,&#32;stale revision\,&#32;invalid target\,&#32;invalid quantity\,&#32;insufficient availability and excess release without appending state\.

#### Host approval is a separate gate

The mixed read\/write&#32;`seed_desk`&#32;tool is conservatively declared&#32;`approval: "write"`&#32;for all operations\.

That host approval tier and Mara’s&#32;`/seeds agent on`&#32;grant are different\:

- Host approval controls whether the wrapped tool call may execute under the configured approval policy\.
- Seed Desk’s grant controls whether its own&#32;`act`&#32;operation may mutate this domain state\.
- Neither prevents other extension JavaScript or independently permitted tools from acting elsewhere\.

Do not weaken a host’s approval configuration merely to make a test pass\.

### Milestone\:&#32;reconstruct the branch\,&#32;not the whole file

Mara tries a different plan from an earlier point in the conversation\.&#32;Her first instinct is to scan all saved entries and select the latest snapshot\.&#32;That would mix sibling branches\.

Instead\,&#32;`reconstruct()`&#32;walks&#32;`ctx.sessionManager.getBranch()`\.

Its revision is\:

- session ID plus&#32;`root`\,&#32;before any Seed Desk state entry\;
- session ID plus the latest Seed Desk state entry’s ID afterward\.

Consequences\:

- Ordinary conversation does not stale the domain revision\.
- A reservation or permission change does\.
- A sibling state snapshot cannot be reused as the current branch’s revision\.
- A new session has a distinct identity\.
- A branch inherits the reservations and grants in its ancestry\.

The domain validates every matching stored snapshot it encounters\.&#32;It does not skip a corrupt Seed Desk entry and silently trust a later one\.

#### Inspect the journal

**Terminal shell—inspect only the lab’s Seed Desk state records\:**

~~~sh
grep '"customType":"seed-desk-state-v1"' "$LAB/seed-session.jsonl"
~~~

This is a journal inspection\,&#32;not a request to edit the journal while OMP owns it\.

Exit and reopen with the same launch command and session path\.&#32;Then query again\.

**Observed\:**

- Real JSONL entries survived reopen\.
- The restored reservation was two packets\.
- The revision was preserved\.
- Rewinding before a reservation showed zero reserved\.
- A sibling branch could hold one packet while the original branch retained two\.
- A sibling revision token was rejected\.
- A fresh session had no carried reservation and agent authority was off\.

A plain leaf movement is not the same thing as a newly appended branch record\.&#32;The session loader reconstructs its position from journal structure\;&#32;do not assume every transient UI navigation choice is independently durable without a subsequent journal change\.&#32;Always query after reopen\.

#### Revoke deliberately

**Human OMP slash command\:**

~~~text
/seeds agent off
~~~

This also asks for confirmation and appends a new snapshot\.

Unlike Review Desk’s in\-memory revocation later\,&#32;**Seed Desk refuses both grant and revoke commands without UI**\.&#32;A persisted grant may therefore still permit tool acts after headless reopen\,&#32;subject to host approval\.&#32;That is the supplied stage’s exact policy\,&#32;not a general recommendation for all applications\.

### Persistence and cancellation limits

`appendEntry()`&#32;stores extension state outside model\-visible conversation\.&#32;It returns no persistence receipt\.

The current file session manager normally hands completed appends to the OS synchronously once persistence is materialized\,&#32;but it does not provide a power\-loss\/fsync guarantee through this extension API\.&#32;Storage failures can be latched and surfaced by the host\.&#32;The Seed Desk checks did not exercise disk\-failure recovery\.

Before commit\,&#32;cancellation changes nothing\.&#32;After commit\,&#32;cancellation cannot undo a reservation\.&#32;Query before retrying\.

Status notifications and bus events do not start an agent turn\.&#32;The optional&#32;`renderResult()`&#32;is presentation only\;&#32;it does not replace the result’s text and structured details\.

**Exercise\:**&#32;should a real multi\-user seed library use this journal as its stock database\?

**Answer\:**&#32;no\.&#32;It would need a shared authoritative store\,&#32;atomic stock operations\,&#32;durable request identity and coordination across users and processes\.&#32;This stage deliberately teaches fictional branch\-local reservations\.

*Source\,&#32;snapshot 2026\-08\-29\:&#32;linked stage\-3 files\;&#32;`packages/coding-agent/src/session/session-manager.ts`\,&#32;`ReadonlySessionManager`\,&#32;`appendCustomEntry`\,&#32;`getBranch`\;&#32;`packages/coding-agent/src/tools/approval.ts`\,&#32;`resolveApproval`\.*
