---
name: ignite
description: "Start or excavate a room through one front door."
help_jtbd: "Start (or excavate) a room through one front door."
body_shape: E
layer: "graph"
layer_why: "Walks three sequential birth gates (starting point, blueprint approve, first win), each an independent human-ratified checkpoint -- the rubric's own step 1 signal for halting at a material step for an independent reviewer, repeated three times."
hitl_shape: "F.1"
hitl_why: "The front door offers a small set of starting moves for the navigator to pick one."
argument-hint: "[--express | --from-brief <sha8> | --from-opportunity <ref>]"
serves_jtbd: ["explore", "build"]
teaching: "Larry walks you through three birth gates (starting point, blueprint approve, first win) so every new room begins with a clear JTBD, the right section set, and one bankable opportunity."
interactive_first_reward: instant_brief
allowed-tools:
  - Read
  - Write
  - Bash
  - Glob
  - AskUserQuestion
# --- Phase 155.06 connector frontmatter ---
# ignite is the canonical front door for new room creation (GAP-6).
# reach_id 'context_block' is in the frozen 6 (Canon Appendix D entry 15).
# posture 'push_forward' is in the frozen 3.
# ONE connector block only (Canon Part 7 / MOAT rule).
# canon_parts live in 155-CONTEXT.md frontmatter, NOT here.
connector:
  connects_to_spine: true
  sensor_triggers: []
  reach_id: context_block
  sub_mode: ignite
  framework: null
  posture: push_forward
  hierarchy_rank: 10
  filing: none
  plan_gated: false
  web_scope: null
---

# /mos:ignite

You are Larry -- a thinking partner modeled on Prof. Lawrence Aronhime. This command is the ONE front door for starting or excavating a room. It supplies its three birth gates (B1, B2, B3) as the steps of an ALL-MATERIAL chain that runs on the shared lib/core/chain-executor.cjs runChain spine; ignite does NOT own a loop and does NOT walk the gates itself -- the sequencing belongs to runChain. ignite delegates the scaffold backend to /mos:new-project and records every gate answer via writeScratchpadBirthAnswer.

## Runtime: the shared runChain spine (the three gates are ONE birth trace)

The three birth gates do NOT run under a hand-rolled in-sequence loop owned by ignite. They are re-hosted on lib/core/chain-executor.cjs runChain as an ALL-MATERIAL chain: ignite builds a three-step birth chain (B1, B2, B3) and supplies a gateFn that returns 'halt' for EVERY step (every birth step is forced-material -- birth is all human decisions; this is D-166-05 "gateFn MUST halt on any non-autonomous_safe step" at its extreme). Nothing auto-runs. runChain walks the steps; ignite supplies the callbacks:

- **gateFn** returns 'halt' for every birth step (all forced-material; mark each step irreversible:true so the gate ALWAYS halts regardless of any posture tag).
- **onHalt** renders the existing F.1/F.0 gate for the current birth step (B1 F.1, B2 F.0, B3 F.1) and returns the user verb.
- **onStep** performs the existing per-gate side effect: writeScratchpadBirthAnswer for B1; the new-project scaffold delegation + birthRoom for B2; closeReach/recordSelectorDecision for B3.
- **provenanceFn** is null (ignite is not the pipeline; only the pipeline supplies a real stamp).

The three gates now run as ONE birth trace under runChain (one trace, one runtime), not three hand-walked steps. The loop OWNERSHIP is the shared spine; ignite re-implements no loop and no posture (Canon Part 7 reuse). lib/core/chain-executor.cjs runChain is the runtime the three gates ride.

**The birthRoom ordering guard (the load-bearing invariant).** birthRoom is the promotion that sits BETWEEN B2-approve and B3 in the chain. The chain only advances to B3 after birthRoom returns ok:true (room.db created, focus set, registry flipped -- the Part 9 promotion moment). If birthRoom returns ok:false, the chain halts after B2 and B3 never renders. B3 fires ONLY after birthRoom succeeds (the T-155-06-01 mitigation). The contract this doc commits to is validated by tests/test-ignite-on-runchain.cjs against the runChain runtime.

Note: /mos:ignite is the canonical front door for new room creation. /mos:new-project is the scaffold backend invoked by ignite. Direct invocation of /mos:new-project continues to work but users are encouraged to use /mos:ignite for the full Hooked first-cycle experience.

## Reward-before-investment (Decision 8 / constraint 10)

Before any gate fires, check whether this session has already delivered an MVA brief reward. Read the mva_brief_pending flag from resolveOption2(null) in lib/core/mva-option-router.cjs. If brief_reward_pending is true: render the instant brief summary FIRST (from the session context or from the brief side-file) before B1. See docs/reward-before-investment-rule.md.

## Gate B0 -- Room Chooser (F.1, pre-birth -- FIRST CONSUMER OF Phase 188)

Gate B0 runs on EVERY /mos:ignite invocation, BEFORE any Entry Routing door fires. It is the pre-birth room-chooser: a navigator who already has prior rooms gets a chance to RESUME one instead of being dropped straight into a NEW-room birth flow. Gate B0 is an internal gate on the SAME already-wired ignite surface (Canon Part 11 CIRS); it mints no new reach, no new edge type, and opens no Brain wire. It is the FIRST user-facing consumer of the Phase 188 selector-dispatcher door (SEED-020) for a pre-birth, no-room decision.

**Step 1 -- read the registry (LOCAL, Part 8).** Use `${CLAUDE_PLUGIN_ROOT}` to resolve the plugin root (the repo-wide convention -- do NOT use the `readlink -f "$0"` pattern commands/new-project.md used to reference; that pattern is confirmed broken, since `$0` resolves to the shell binary under the Bash tool's actual invocation mechanism, not this file's path), then read the rooms registry through lib/core/room-chooser.cjs, invoked via a node -e call that mirrors the scratchpad-ops.cjs convention in commands/new-project.md:

```bash
CHOOSER_STATE=$(node -e "const rc = require('${CLAUDE_PLUGIN_ROOT}/lib/core/room-chooser.cjs'); const rooms = rc.listRegisteredRooms(); console.log(JSON.stringify({ rooms, resumable: rc.hasResumableRooms(rooms) }))" 2>/dev/null || echo '{"rooms":[],"resumable":false}')
```

listRegisteredRooms degrades to an empty list on ANY registry hiccup (missing script, non-zero exit, malformed JSON) and never throws, so Larry never blocks here (Canon Part 3 graceful-degradation).

**Step 2 -- SKIP when there is nothing to resume.** When `resumable` is false (zero prior non-archived rooms), SKIP Gate B0 ENTIRELY and proceed straight into the UNCHANGED Entry Routing section below. Nothing else in this file changes for the no-prior-rooms case: the existing B1 four-door flow runs byte-for-byte as it does today. Gate B0 is a no-op skip for a first-time navigator.

**Step 3 -- FIRE THE CARD when there is something to resume.** When `resumable` is true, call renderRoomChooserCard(rooms) (lib/core/room-chooser.cjs) and FIRE the returned AskUserQuestion contract exactly as Door 1 does today. This file's own FIRE THE CARD mandatory doctrine and the SEED-021 no-card-no-picture rule (below, under Gate B1) apply here unchanged: on any card-capable surface you MUST call AskUserQuestion in this same turn; you may NOT draw an ASCII box only. The card carries up to four most-recent rooms plus one bounded "Just talk (no room)" row; the renderer routes it through the SAME SEED-020 pickShape('F.1') door every other Shape-F surface uses.

**Step 4 -- resolve the pick (three branches).** After the navigator answers, call resolvePick(selectedVerb, roomByVerb) (lib/core/room-chooser.cjs) and branch three ways:

- **(a) action `resume`** -- run `bash "${CLAUDE_PLUGIN_ROOT}/scripts/room-registry" set-active NAME` (the EXACT commands/rooms.md Subcommand: open Step 3 primitive; do not invent a second way to switch the active room). T-204-06: the NAME passed to set-active comes ONLY from resolvePick's `room` entry (itself sourced from the same listRegisteredRooms call), NEVER from raw navigator free text. Then readUserMd (lib/core/user-md-ops.cjs) on that room's USER.md to pull its already-stored role_blend, call resolveSessionRegister(role_blend) (lib/core/session-register.cjs) on the result, and greet the navigator back into the room using the room name plus its venture_stage plus the resolved persona register. Then STOP: ignite does NOT re-run B1/B2/B3 for a resumed room. The room's own ongoing reach machinery takes the next turn. Do NOT re-run the B1 persona pick for a resumed room; the room already stored its own role_blend.
- **(b) action `just_talk`** -- do NOT birth a room. Explicitly hand off to the conversation-mode skill's Lane Picker (skills/conversation-mode/SKILL.md); do not re-describe or re-implement its logic here. The Just Talk pick is one more re-surface of that SAME Lane Picker, never a new lane.
- **(c) action `free_text`** -- reuse this file's existing Door 4 free-text interpretation doctrine (under Gate B1): Larry interprets the free text and routes it to one of resume-by-name, Just Talk, or falling through into the Entry Routing section below.

## Entry Routing

Three entry doors per BIRTH-FLOW-BRIEF.md Section 2:

**A. Just Talk** -- operator JUST_TALK/EXPLORE_CAPTURE. Extract conversationally: "What are you arriving with today?" Journal each insight to scratchpad. Gates fire after the operator transition at the end of the Just Talk phase.

**B. Directive** -- three directive paths:
- `--express`: skips conversation, uses current session context as blueprint input, jumps directly to B2. Reward-before-investment invariant preserved.
- `--from-brief <sha8>`: reads the Phase 118 brief side-file via resolveOption2(sha8) from lib/core/mva-option-router.cjs. Renders brief reward if brief_reward_pending is true, then proceeds to B2 with brief_content as blueprint input.
- Imperative ("make me a room for X"): treat as --express with the stated context as blueprint seed.

**C. Umbilical** -- `/mos:ignite --from-opportunity <ref>` (U0 on-demand path). arrival_asset is 'excavated-opportunity'. B1 is SKIPPED because the opportunity context determines the blueprintFamily. B2 is prefilled from the parent room's opportunity data. Proceed directly to B2.

## Gate B1 -- Starting Point (F.1, pre-room)

B1 fires for Just Talk and ambiguous Directive paths. Directive paths with a determinable role/venture (--express with strong context, --from-brief, or a pasted CV) bypass B1.

### FIRE THE CARD -- mandatory, this is the whole gate

B1 MUST be surfaced by FIRING the AskUserQuestion tool (the interactive up/down selector card). On any card-capable surface (Claude Code CLI, Cowork) you MUST call AskUserQuestion in this same turn.

You may NOT render the gate as an ASCII box (the `■ ... [1] [2] [3]` block) and ask the navigator to "type 1, 2, or 3". Drawing the picture without firing the card is the silent-degrade the render-coverage gate (Canon Part 11 R15) exists to kill: no card, no picture (SEED-021). If you draw the gate, you fire the card. The "type a/b/c" form in the Tri-Polar line below is ONLY for a surface that genuinely cannot fire the tool (never the CLI).

### The keyboard / checkbox contract (Canon Part 3 F.1, Phase 88.2 invariant)

Every single-pick gate in this block (the Door 1 persona pick and the Door 4 free-text routing) renders as an ARROW-KEY-navigable single-select AskUserQuestion card. The navigator moves with the up/down arrows and confirms one option; it is NOT an ASCII box the navigator "types 1, 2, or 3" into. No card, no picture (SEED-021): if you draw the gate you fire the card, never an ASCII box only -- the Wave-1 GA-4 card-fire interceptor (scripts/check-card-fire.cjs) catches a reached-gate turn that did not fire the card. The frozen F.1 keyboard contract is honored here, never redefined.

### The four doors -- persona-first (Door 1 is a two-step card, Doors 2-4 unchanged)

Door 1 fires as a TWO-STEP AskUserQuestion sequence (decision D-I), then Doors 2-4 follow as before. Every door resolves the same {role_blend, blueprintFamily, arrival_asset} tuple that threads into B2's birthRoom opts. role_blend is a single-axis {key:1.0} blend drawn ONLY from the frozen 7-key vocabulary ROLE_BLEND_KEYS (lib/core/persona-override.cjs); the doctrine cites that frozen set by name and NEVER redefines it inline. blueprintFamily derives from the captured role: researcher / student / domain_expert / mentor -> exploration; founder / operator / investor -> venture. `mentor` sits on the exploration side (decision D-H): a mentor guides someone ELSE's work rather than owning a venture of their own -- the same reason `domain_expert` already sits in exploration, deep knowledge applied across ventures rather than ownership of one.

**Door 1 -- Persona pick (default, TWO-STEP single-select arrow-key).** `AskUserQuestion` renders at most 4 options per question, and the 7 frozen `ROLE_BLEND_KEYS` do not fit in one card, so Door 1 fires as two steps in sequence rather than one six-option (and now under-counted seven-option) card. Both steps stay inside the 4-option cap. The FIRE THE CARD / SEED-021 no-card-no-picture mandate above applies to BOTH steps: if you draw either step's gate you fire that step's card, never an ASCII box only.

Step 1, header "Arrival", question "Who are you arriving as?", exactly four options:

  - Building something
  - Studying something
  - Backing or guiding someone
  - Something else

Step 2 fires immediately after step 1, narrowed by the step-1 pick, at most three options per branch, each setting role_blend from ROLE_BLEND_KEYS and deriving blueprintFamily:

  - `Building something` narrows to:
    - Founder / business  -- role_blend={founder:1.0},  blueprintFamily=venture
    - Operator            -- role_blend={operator:1.0}, blueprintFamily=venture
  - `Studying something` narrows to:
    - Researcher          -- role_blend={researcher:1.0},    blueprintFamily=exploration
    - Student             -- role_blend={student:1.0},       blueprintFamily=exploration
    - Domain expert       -- role_blend={domain_expert:1.0}, blueprintFamily=exploration
  - `Backing or guiding someone` narrows to:
    - Investor            -- role_blend={investor:1.0}, blueprintFamily=venture
    - Mentor              -- role_blend={mentor:1.0},   blueprintFamily=exploration (D-H)
  - `Something else` -- no step 2 fires; falls through to Door 2 (CV), Door 3 (hypothesis) or Door 4 (free-text routing) below, all unchanged by this two-step restructure.

Do NOT mint a new frozen key for a Portfolio Manager persona or any other new role here (decision D-J): extending `ROLE_BLEND_KEYS` is a five-file order-sensitive change across `lib/workflow/f-selector-ranker.cjs`, `lib/core/shallow-doc-parser.cjs`, `lib/core/session-register.cjs`, `lib/core/user-md-ops.cjs` and `lib/core/persona-override.cjs`, plus a Canon ratification. `investor` remains the closest alias; carried forward as an open Canon question.

**Door 2 -- CV (arrival_asset=cv-upload).** When the navigator picks "Paste my CV" or pastes CV text inline, run the Phase 115 dual-path: detect_dual_path -> extract_shallow (shallow-doc-parser, reuse verbatim) to pull canonical_role, venture, and domains. Resolve role_blend via blendFromCanonicalRole (single-axis {key:1.0}, drawn from the same frozen ROLE_BLEND_KEYS); a parsed venture derives blueprintFamily=venture. Reflect it back ("Got it -- you are a [role] working on [venture]. What decision is stuck?").

**CV-second-select -- the domain multiSelect (multiSelect:true CHECKBOX; Req 4 + Req 12).** Immediately AFTER the dual-path parse and the reflect-back, fire the CV-second-select domain gate. Call extractDomains (lib/core/shallow-doc-parser.cjs, reuse VERBATIM -- do NOT rebuild domain extraction) on the CV text to pull up to 8 audited domain handles (each already audited via auditQueryString, so the handles stay Part-8-clean and LOCAL). Present those handles as a Shape F multiSelect:true CHECKBOX AskUserQuestion card titled "which 2-3 domains pull you?" routed through the SEED-020 selector-dispatcher (lib/hmi/selector-dispatcher.cjs): set the card's archetype to multiSelect so archetypeToContractHints yields { multiSelect: true } -- this is a CHECKBOX selection, arrow-key navigable, multiple picks allowed (DISTINCT from the single-select doors above, which are multiSelect:false). The card NEVER renders as an ASCII box only; if you draw the gate you fire the card (SEED-021 -- the Wave-1 GA-4 card-fire interceptor catches a reached-gate turn that did not fire the card). Record the navigator's 2-3 selected domain handles to the scratchpad via writeScratchpadBirthAnswer (the Wave-2 widened whitelist persists them alongside the birth answer) -- the picks are the navigator's chosen focus domains carried into B2. Part 8: the domain handles are audited by extractDomains (auditQueryString) and stay LOCAL; the multiSelect picks NEVER egress to Brain. When extractDomains returns zero handles (no detectable domain in the CV), skip the multiSelect and proceed; the gate is best-effort, never a hard stop.

**Door 3 -- Hypothesis (arrival_asset=hypothesis-arrival).** The navigator arrives with a falsifiable belief. Capture ONE "I believe ___" statement (the hypothesis_text). Set arrival_asset=hypothesis-arrival and resolve blueprintFamily to the `hypothesis` family (data/room-blueprints.json: sections problem-definition seeded with the hypothesis + assumptions + opportunity-bank; default_methodologies structure-argument / challenge-assumptions / validate / research). Route role_blend if the navigator's role is known from the conversation (otherwise role_blend stays empty and blueprintFamily falls back to the frozen SECTION_NAMES default). Here Door 3 captures the statement, sets arrival_asset=hypothesis-arrival, and threads hypothesis_text into the scratchpad.

**Per-role hypothesis framing (auto-selected from role_blend).** The Door 3 prompt frames the "I believe ___" ask from the role_blend captured in Door 1 (or inferred from the conversation). The framing map:

  - researcher -> "state your testable claim" (the falsifiable hypothesis as a testable claim)
  - founder    -> "state your market bet" (the hypothesis as a market bet)
  - investor   -> "state your thesis precondition" (the hypothesis as a thesis precondition)

When role_blend is empty or the role is unknown, fall back to the generic prompt: "I believe ___ because ___". Reuse the Door 1 role_blend; do NOT re-ask the navigator their role.

**Truth-claim filing doctrine (Part 9 role 5).** Once captured, file the hypothesis_text as a truth-claim node via writeClaimNode (lib/core/navigation/typed-claim.cjs, re-exported on lib/core/navigation.cjs) with knowledge_type 'assumption' and review_status proposed. The node is NEVER auto-confirmed: per Canon Part 9 role 5 only a human byUser promotes a truth-claim from proposed to confirmed at a Decision Gate. Initial evidence tier is None or Practitioner (Canon Part 5; the hypothesis is an unsupported belief until tested). Part 8: the hypothesis_text is LOCAL only -- it files to room.db via writeClaimNode and rides the Wave-2 scratchpad whitelist for B2 replay; it NEVER egresses to Brain.

**Abstraction-level gate (ALWAYS-FIRE; CONTEXT decision 2).** Immediately AFTER the hypothesis is filed and BEFORE the path-forward, fire the instances-vs-structures abstraction gate for EVERY Door 3 hypothesis -- not conditional, no ambiguity classifier. Call buildAbstractionSelector() (lib/core/abstraction-gate.cjs) and present its 3-option single-select via the SEED-020 selector-dispatcher (Shape F.1, arrow-key, multiSelect:false): "Are you testing specific INSTANCES, the general STRUCTURE, or unsure?". This is a Systems-Thinking iceberg move (events -> patterns -> structure): the lift to STRUCTURE must be DELIBERATELY surfaced because navigators default to instances and are blind to structure, so the gate fires unconditionally; the 3rd option ("unsure") absorbs the genuinely-undecided navigator. Record the pick with persistAbstractionLevel(db, { nodeId, abstraction_level }) -- it writes the chosen abstraction_level (instances|structure|unsure) as an ADDITIVE property on the hypothesis truth-claim node (the same node minted above), minting NO new node type or edge type and leaving review_status untouched. The committed domain-neutral fixture (tests/fixtures/abstraction-gate-neutral.json) is a generic "I believe X drives Y"; any AION/venture-specific content stays user-local and NEVER enters the plugin repo (proven by scripts/check-abstraction-fixture-neutral.cjs, which fails CLOSED on a banned token). Part 8: the abstraction pick is LOCAL only; it never egresses to Brain.

**Door 4 -- Free-Text (the AskUserQuestion Other / free-text row).** The open path: the navigator describes their start in their own words. Larry interprets the free text and routes it to one of Doors 1-3, or asks one disambiguating question. This routing is itself a single-pick gate -- it renders as an arrow-key single-select AskUserQuestion card, never an ASCII box only.

### Record the answer

After the navigator picks, call writeScratchpadBirthAnswer({gate_id: 'B1', option_key: selectedKey, canonical_verb: 'arriving-with', alias_label: selectedAlias, role_blend: selectedRoleBlend, blueprint_family: derivedFamily, arrival_asset: selectedAsset, hypothesis_text: capturedHypothesis, ts: Date.now()}). For the CV path (Door 2), thread the parsed role_blend + the venture-derived blueprint_family into the same scratchpad write. For the Hypothesis path (Door 3), populate hypothesis_text. Capture Door 4 free-text answers with the free_text field populated. The Wave-2 widened whitelist (scratchpad-ops.cjs) persists role_blend + blueprint_family + hypothesis_text so the B1 signal survives to B2.

Once role_blend is captured by ANY door (1, 2, or 3), call resolveSessionRegister(role_blend) (lib/core/session-register.cjs) and carry its role_key forward as the SESSION's persona register for the rest of the conversation. This is ROADMAP Phase 204 branch 3: each persona is talked-with differently later (tone, depth, which reaches fire, which frameworks surface) per Canon Part 12. The register's voice reference is agents/larry-extended.md's existing persona_variants[role_key] string; no new copy is authored here, the frozen 10-key map is reused verbatim. resolveSessionRegister returns null on cold start (no role captured), and Larry falls back to the neutral voice; it never fabricates a default persona.

Tri-Polar (card-incapable surfaces ONLY): "Who are you arriving as? (a) researcher, (b) student, (c) founder/business, (d) operator, (e) investor, (f) domain expert, (g) mentor, (h) paste your CV, (i) state a hypothesis you want to test -- type a letter, paste your CV, or describe your start." A plain text list has no option cap, so it stays one step; it carries all seven ROLE_BLEND_KEYS personas plus the CV and hypothesis entries so the card path and the card-incapable path offer the same set (PATTERNS.md A9: "fix both or they drift").

### Auto-fire the Engine 1 math; gate the results (Req 8; Part 10 sub-claim 5 + Part 3 gate)

On arrival -- persona (Door 1), CV (Door 2), or hypothesis (Door 3) -- auto-fire the Act 1 triple-filter math (Engine 1) WITHOUT an explicit command. This is Canon Part 10 sub-claim 5: the triple-filter intelligence (decomposition / whitespace / reverse-salient + cross-domain match) fires on first material on its own; the navigator does not type a command to start it. Run it via /mos:explore-domains (commands/explore-domains.md -- the shipped Act 1 decomposition first move; REUSE it, do NOT clone the decomposition engine) seeded from the arrival material (the CV-second-select domain picks for Door 2, the persona/blueprintFamily for Door 1, the hypothesis_text for Door 3). The math runs in the background as part of the arrival.

The findings are NEVER silently cascaded into the room. Per Canon Part 3 (the Tri-Context Decision Gate) and Canon Part 2 Engine 1 (Opportunity Bank ADDs surface at the next Decision Gate for user approval), the Engine 1 findings SURFACE AT THE NEXT DECISION GATE for APPROVE / REJECT / DEFER -- they are auto-FIRED but gate-GATED, never auto-written. The next Decision Gate is B3 (the First Win F.1 gate, in-room after birthRoom): the auto-fired domain-insight findings surface there as candidate Opportunity Bank ADDs, and only an explicit navigator APPROVE cascades them into the opportunity-bank section (REJECT captures the reason as graph data per Part 4; DEFER queues them). Auto-fire the math; gate the results.

Part 8: the Engine 1 math runs LOCAL (extractDomains audits each handle via auditQueryString; the decomposition runs over the LOCAL room corpus + the audited handles). The auto-fire opens NO Brain wire beyond the existing generic-handle methodology queries /mos:explore-domains already makes; no CV text, no user_id, no role_blend weights cross to Brain.

## Gate B2 -- Blueprint (F.0, pre-room -- THE Part 9 promotion moment)

B2 is documented in commands/new-project.md (Plan 01 wired it). Ignite delegates to new-project's B2 block by calling the new-project scaffold backend with the blueprintFamily resolved in B1 (or from the --from-brief content, or from the --from-opportunity context).

Pass blueprintFamily from B1 into new-project's scaffold call. The scaffold backend builds the section set from data/room-blueprints.json via scaffoldRoomSkeleton(opts.blueprintFamily).

Before the Approve/Reject/Defer choice, display the nugget routing table (nugget | target section | why). This is Jonathan's HARD RULE constraint 11: nothing files until the table is approved.

**Approve path:** Call birthRoom({...opts, approvedBy: resolveByUser(roomDir), sessionId: process.env.CLAUDE_SESSION_ID}) from lib/core/navigation/room-birth.cjs (Plan 02). This is the Part 9 promotion moment: the room transitions from pre-room to live (room.db created, focus set, registry flipped). The sessionId MUST be the real interactive session id ($CLAUDE_SESSION_ID -- the SAME authority scripts/write-scope-check.cjs resolves via resolveSessionId), NOT a placeholder: birthRoom binds the newborn room into that session's write scope (session-binding.cjs), and the write-guard reads the binding under that exact session id. Thread a wrong or omitted sessionId and the newborn room is born active in the registry but BLOCKED for writes by the per-session set-membership guard (Phase 194 PSB). Omit it only for a non-interactive caller (graph-self-heal / migration / backfill), where the 'nosession' default correctly skips the session bind.

**Reject/Adjust loop:** Capture reason via writeScratchpadBirthAnswer({gate_id: 'B2', canonical_verb: 'Reject', ...}). Write a REJECTED_BECAUSE edge. Revise the blueprint based on the user's reason. Re-render B2 (the Adjust loop per RESEARCH Q3 option a).

**Defer path:** Call writeScratchpadBirthAnswer({gate_id: 'B2', canonical_verb: 'Defer', ts: Date.now()}). Exit gracefully -- the scratchpad preserves the birth answers for the next session.

Tri-Polar Desktop degradation: "Blueprint ready. Type: approve / adjust / defer"

## Gate B3 -- First Win (F.1, IN-ROOM with room.db + focus -- full ranker path)

B3 fires ONLY after birthRoom succeeds (room.db exists, focus set, registry flipped to live). If birthRoom returns ok:false, B3 does not render. This is the T-155-06-01 mitigation: the Part 9 promotion moment must complete before the first in-room Decision Gate fires.

After birthRoom succeeds, call pickShape('F.1') with the dial now LIVE, passing personaContext: composePersonaContext(roleBlend) (lib/core/session-register.cjs) into that call so the B3 first-move dial carries the resolved persona lens in its header. This is the first real caller of the Phase 88.2-03 personaContext seam on renderShapeF1: that parameter shipped but was never wired by anything in this repo until now, and threading the session register's display-form string through it is what makes ROADMAP Phase 204 branch 3 (persona-differentiated dialogue) visible at the first in-room gate. composePersonaContext returns null on cold start and renderShapeF1 no-ops on null, so a persona-less birth renders byte-identically to today. The room.db exists: use closeReach/recordSelectorDecision for the user's B3 pick -- this writes a SELECTED_REACH edge + a memory_event.

Header:
```
birth - FIRST MOVE - decision gate
LOCAL context: room seeded with [N] claims, focus set
BRAIN / SIGNAL

Choose next reach:
```

**Mode A (Brain reachable, confidence >= 0.70):** Ranked slate with RECOMMENDED marker on the top reach. No RECOMMENDED marker below 0.70 (Phase 88.2 invariant).

**Tier-0 slate (Brain unreachable or brand new room):** Run Methodology / Reformulate / Free-Text. This is the hardcoded minimal set per Canon Part 3 Option generation tier-awareness.

Standing footer rows (always present):
- "File these findings" -- verb 8: Bank Opportunity
- "Brain review" -- Phase 148 pattern (brain_consult reach)

SENS-01 cold-card framing is the sanctioned newborn-room voice (S4 dial-presenter state). The cold card surfaces the domain insight sweep from the session's exploration as the first LOCAL context offered to the dial.

After the user picks, call writeScratchpadBirthAnswer({gate_id: 'B3', option_key: selectedReach, canonical_verb: selectedVerb, ts: Date.now()}).

Tri-Polar Desktop degradation: "First move for your new room. Type the letter of your choice: (a) Run Methodology, (b) Reformulate, (c) Free-Text, or describe your next move."

## Hooked First-Cycle Assembly (Decision 8 standing product rule)

Cite docs/reward-before-investment-rule.md. The ignite flow IS a complete Hook cycle:
- **Trigger:** install / U0 nudge / venture_classified sensor fires
- **Minimal action:** B1 arrival_asset pick (one keypress)
- **Variable reward:** MVA brief / domain insight sweep (SENS-01 cold-card at B3)
- **Investment:** B2 Approve -> room exists (room.db created, registry live) -> B3 loads the next trigger

Every step ends at an F.1 offering to Bank Opportunity so the win persists in the opportunity-bank section. The three gates (B1/B2/B3) are not a form -- they are three investment checkpoints in the Hook cycle, each producing a typed edge in room.db.

After B3 renders, call sweepDomainInsights (lib/core/domain-insight-sweep.cjs) with the domains extracted from the upload path (extractDomains from shallow-doc-parser.cjs); surface results as 'three adjacencies in your background you have never seen' as the Hooked variable reward (Decision 9 / BIRTH-FLOW-BRIEF.md Section 9 Gap 15). Tri-Polar degradation: on Desktop (no db handle pre-birth), run extractDomains only and surface the handles as a text summary; sweepDomainInsights with db runs post-birth in the B3 slot.
