Skip to content

FE-1124: Session orientation domain layer + dialog fn (card 1, boot wiring blocked)#289

Draft
lunelson wants to merge 11 commits into
ln/fe-1124-walkthrough-batch-2from
ln/fe-1134-session-orientation
Draft

FE-1124: Session orientation domain layer + dialog fn (card 1, boot wiring blocked)#289
lunelson wants to merge 11 commits into
ln/fe-1124-walkthrough-batch-2from
ln/fe-1134-session-orientation

Conversation

@lunelson

@lunelson lunelson commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

FE-1124: Session orientation domain layer + dialog fn (card 1, boot wiring blocked)

Builds the session-entry-orientation choice schema, append-only fold with
kick-staleness guarding, context-seed orientation section, and the
ctx.ui.select-shaped dialog function with entry/degraded-mode rules — all
green and reused by future junctures (J2-J6).

The J1 boot-path wiring is not landed: tracing Pi's ExtensionRunner shows
ctx.ui/hasUI stay no-op until InteractiveMode.bindCurrentSessionExtensions
runs, which is later than any point brunch-tui.ts's runtime factory can
reach — the card's stated boot-reorder mitigation is insufficient. Finding
and two candidate resolutions are recorded on the scope card for the next
build pass.

Co-authored-by: Cursor cursoragent@cursor.com

FE-1124: Session-orientation junctures J2/J3/J4/J6 + live-kick helper (card 2, partial)

Builds the juncture orchestrator (dialog → entry → live-kick) and Pi
event/command registrar. session_start (new/resume), session_tree, agent_end
esc-abort (C3 tail-message stopReason probe), and /brunch:consult all route
through one seam; non-continue choices at no-pending-kick junctures fire a
real assistant turn via a fresh orientation-carrying seed. Adds forceSeed to
originateAssistantTurn so a mid-session kick lays down a seed even when the
graph LSN has not moved.

Deferred to follow-up slices (recorded on the scope card, not silently
narrowed): J5 mode-switch (SPEC-side menu wiring in commands/index.ts),
option-2 J1 boot rework (requires reordering brunch-tui boot around
bindCurrentSessionExtensions), and outer-loop RPC round-trip verification.

C3 finding: extension AgentEndEvent does not carry willRetry — compaction-
overflow retries are collapsed by the 750ms debounce ceiling, not a real
guard; upgrade if it surfaces in outer walkthroughs.

Co-authored-by: Cursor cursoragent@cursor.com

FE-1124: option-2 J1 boot rework — session_start(startup) handler owns dialog + origination + kick

Binding-order verified against @earendil-works/pi-coding-agent
(agent-session.js:1644-1665): bindExtensions applies the UI context then
emits session_start, so a session_start handler with reason 'startup'
runs with ctx.hasUI true and ctx.ui.select live. This retires the fork
that Card 1's earlier finding opened.

  • runOrientationJuncture gains mode: 'follow-choice' | 'boot'.
    'boot' always originates+kicks (resumeOrigin: 'resume_debt' so
    a resumed session with no debt still idles correctly; forceSeed only
    when a real orientation choice was recorded), preserving "never a wall"
    through degraded mode and escape (both still fire the boot kick).
  • Registrar handles session_start reason 'startup' with trigger 'entry'
    and mode 'boot'; new/resume continue on 'follow-choice'.
  • brunch-tui.ts deletes the pre-session-binding originateAssistantTurn +
    fire-and-forget completeAssistantKick. The debug-cache mirror (D97-L)
    and kick-status chrome carry forward via new onOriginationDecision /
    onKickOutcome callbacks on KickContext, so nothing observable is lost.
  • Tests: juncture 'boot' mode covers degraded, escape, and non-continue;
    registrar covers session_start(startup) firing dialog + boot kick.
  • Topology + Card 1 acceptance updated (boot order landed).

Co-authored-by: Cursor cursoragent@cursor.com

FE-1134: Sync ship-gate lanes after orientation boot rework

FE-1134: Entry chrome — welcome box, working-message kick, resume state block (card 3)

  • F13: BrunchStartupHeader renders the welcome intro inside a bordered
    rounded-box element after the identity block, visually separated from
    the header.
  • F14: kick activity now drives ctx.ui.setWorkingMessage("Opening
    assistant turn…") from brunch-tui.ts's origination-decision callback;
    chrome resets the message to the default in turn_end so it does not
    leak into a later turn. Retired the BRUNCH_KICK_ACTIVITY_STATUS_KEY
    constant, footer status carrier, and message_start clear — no dual
    carrier.
  • F16a: openSession activations render a rounded-box resume state/status
    block driven by startupHeader.resumeFacts (spec title, node/edge
    counts, mode label), sampled once at chrome-state assembly from
    graph.queryGraph + projectBrunchAgentState.
  • F15a dropped (would fight F14's global working-message reset).

Chrome TOPOLOGY.md updated for the new header composition and retired
status-key policy. Full-verify blocked on a pre-existing better-sqlite3
NODE_MODULE_VERSION mismatch in brunch-tui.ts's DB-touching boot tests
(unrelated to this scope); chrome + startup-header tests + build green.

Co-authored-by: Cursor cursoragent@cursor.com

lunelson and others added 8 commits July 3, 2026 17:07
…iring blocked)

Builds the session-entry-orientation choice schema, append-only fold with
kick-staleness guarding, context-seed orientation section, and the
ctx.ui.select-shaped dialog function with entry/degraded-mode rules — all
green and reused by future junctures (J2-J6).

The J1 boot-path wiring is not landed: tracing Pi's ExtensionRunner shows
ctx.ui/hasUI stay no-op until InteractiveMode.bindCurrentSessionExtensions
runs, which is later than any point brunch-tui.ts's runtime factory can
reach — the card's stated boot-reorder mitigation is insufficient. Finding
and two candidate resolutions are recorded on the scope card for the next
build pass.

Co-authored-by: Cursor <cursoragent@cursor.com>
… (card 2, partial)

Builds the juncture orchestrator (dialog → entry → live-kick) and Pi
event/command registrar. session_start (new/resume), session_tree, agent_end
esc-abort (C3 tail-message stopReason probe), and /brunch:consult all route
through one seam; non-continue choices at no-pending-kick junctures fire a
real assistant turn via a fresh orientation-carrying seed. Adds forceSeed to
originateAssistantTurn so a mid-session kick lays down a seed even when the
graph LSN has not moved.

Deferred to follow-up slices (recorded on the scope card, not silently
narrowed): J5 mode-switch (SPEC-side menu wiring in commands/index.ts),
option-2 J1 boot rework (requires reordering brunch-tui boot around
bindCurrentSessionExtensions), and outer-loop RPC round-trip verification.

C3 finding: extension AgentEndEvent does not carry willRetry — compaction-
overflow retries are collapsed by the 750ms debounce ceiling, not a real
guard; upgrade if it surfaces in outer walkthroughs.

Co-authored-by: Cursor <cursoragent@cursor.com>
…s dialog + origination + kick

Binding-order verified against @earendil-works/pi-coding-agent
(agent-session.js:1644-1665): bindExtensions applies the UI context then
emits session_start, so a session_start handler with reason 'startup'
runs with ctx.hasUI true and ctx.ui.select live. This retires the fork
that Card 1's earlier finding opened.

- runOrientationJuncture gains mode: 'follow-choice' | 'boot'.
  'boot' always originates+kicks (resumeOrigin: 'resume_debt' so
  a resumed session with no debt still idles correctly; forceSeed only
  when a real orientation choice was recorded), preserving "never a wall"
  through degraded mode and escape (both still fire the boot kick).
- Registrar handles session_start reason 'startup' with trigger 'entry'
  and mode 'boot'; new/resume continue on 'follow-choice'.
- brunch-tui.ts deletes the pre-session-binding originateAssistantTurn +
  fire-and-forget completeAssistantKick. The debug-cache mirror (D97-L)
  and kick-status chrome carry forward via new onOriginationDecision /
  onKickOutcome callbacks on KickContext, so nothing observable is lost.
- Tests: juncture 'boot' mode covers degraded, escape, and non-continue;
  registrar covers session_start(startup) firing dialog + boot kick.
- Topology + Card 1 acceptance updated (boot order landed).

Co-authored-by: Cursor <cursoragent@cursor.com>
…te block (card 3)

- F13: BrunchStartupHeader renders the welcome intro inside a bordered
  rounded-box element after the identity block, visually separated from
  the header.
- F14: kick activity now drives ctx.ui.setWorkingMessage("Opening
  assistant turn…") from brunch-tui.ts's origination-decision callback;
  chrome resets the message to the default in turn_end so it does not
  leak into a later turn. Retired the BRUNCH_KICK_ACTIVITY_STATUS_KEY
  constant, footer status carrier, and message_start clear — no dual
  carrier.
- F16a: openSession activations render a rounded-box resume state/status
  block driven by startupHeader.resumeFacts (spec title, node/edge
  counts, mode label), sampled once at chrome-state assembly from
  graph.queryGraph + projectBrunchAgentState.
- F15a dropped (would fight F14's global working-message reset).

Chrome TOPOLOGY.md updated for the new header composition and retired
status-key policy. Full-verify blocked on a pre-existing better-sqlite3
NODE_MODULE_VERSION mismatch in brunch-tui.ts's DB-touching boot tests
(unrelated to this scope); chrome + startup-header tests + build green.

Co-authored-by: Cursor <cursoragent@cursor.com>
kickTurnMessage is now origin-aware. Resume-origin kicks (resume_debt)
carry an assessment directive — a compact reading of the graph facts
and a forecast of what looks TODO — grounded in the D101-L/D102-L seed
already carried, before returning to elicitation. new_session content
is unchanged (guard-locked). manual_trigger kicks share the
new-session content because those kicks are already directed by the
SESSION ORIENTATION section in the seed.

Unit tests cover the resume directive and the manual/new equivalence.
Outer walkthrough resume beat + system-prompt/origination debug oracles
remain the conduct-quality lens.

Co-authored-by: Cursor <cursoragent@cursor.com>
…imeout

Adds two shared helpers in session-orientation/juncture.ts and rewires the
registrar and the mode-switch command path to consume them, so J1/J2/J3/J4/J6
(registrar) and J5 (mode-switch command) share one entry point:

- runJunctureForContext(): folds the sessionManagerCanAppend guard, the RPC
  UI adaptation, and the kick-context plumbing that the registrar was doing
  inline. The registrar delegates to it; the mode-picker path invokes it
  when the target mode is 'elicit' (SPEC-side), preserving the
  execute-entry-readiness ownership boundary for CODE-side switches.

- adaptOrientationUi(): when ctx.mode === 'rpc', wraps ctx.ui.select with
  { timeout: ORIENTATION_RPC_DIALOG_TIMEOUT_MS } (60 s). A mute or missing
  RPC dialog client can no longer wedge orientation; on timeout, select
  returns undefined which the choice schema already maps to 'continue',
  and the entry rule still writes the resolution.

- sendCustomMessageViaExtensionApi(): bridges ExtensionAPI.sendMessage
  (void return) to the promise-shaped LiveKickDeps['sendCustomMessage']
  the live-kick helper expects, so command handlers can kick without
  holding an AgentSession reference.

Tests: two new unit tests in session-orientation/__tests__/juncture.test.ts
cover the RPC timeout injection and the J5 delegation shape.

Co-authored-by: Cursor <cursoragent@cursor.com>
Harness boots via createAgentSessionRuntime never enter a Pi run mode, so
bindExtensions() never fired and the J1 session_start(startup) handler
hung every automated boot on the orientation dialog. New
emitStartupOrientationForHarness helper binds extensions with no
uiContext, taking the pinned degraded row of the decision-flow chart
(hasUI=false => no dialog, boot kick still fires) — no blanket TUI
timeout, no product-behavior change. Wired into all tier-2 boot helpers
and the five web-driver streaming suites.

Unmasks (does not cause) two FE-1124 boot-rework regressions, diagnosed
and recorded on the card: the post-creation seed append never reaches
agent.state.messages, and a session-creation thinking_level_change entry
shadows resume debt. Fixes land next on this branch.

Co-authored-by: Cursor <cursoragent@cursor.com>
@lunelson lunelson force-pushed the ln/fe-1134-session-orientation branch from a0fa7c7 to 092261f Compare July 3, 2026 15:13
lunelson and others added 3 commits July 3, 2026 17:34
…ard retirement

- SPEC: new D109-L decision row for the deterministic orientation-dialog
  seam (event + pointers to the co-located TOPOLOGY homes; disambiguated
  from D102-L's prompt-guided asking-agenda orientation) and an
  "Orientation dialog" lexicon entry.
- PLAN: archived the done exchange-rendering and elicitation-gap-guidance
  frontier definitions to docs/archive/PLAN_HISTORY.md; repaired stale
  card references (deleted sweep ledger, consumed walkthrough card);
  execution pointer now names the live judo-cleanup card.
- Cards GC: deleted the exhausted exchange-rendering--closeout and
  dev--provider-payload-prompt-contract cards (both Status: done).
- TOPOLOGY: src/.pi/extensions/TOPOLOGY.md J5 sentence updated — the
  mode-switch juncture is landed, not a follow-up slice.

Consolidated into one docs-only commit at the branch tip to minimize
graphite restack churn.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant