Skip to content

Verify launched-session kickoff + allow early interjection (read-back + message-in) #9

Description

@RyanSeanPhillips

Summary

After the control plane launches a session, it should be able to see how that session kicked off and inject clarifying context at the start if it went wrong.

Motivation

Today launch_session is fire-and-forget: control can start a session and seed a prompt, but it cannot observe whether the session actually received the context or started on-task. We just hit a case (see #8) where the seed prompt was silently truncated to a single word and nobody knew until the operator manually checked the new window.

Proposed capability

Two underlying primitives, with a verify/interject UX on top:

  1. Read back the launched session. Let control read the opening turn(s) of a session it launched — the prompt the session actually received plus its first response — so it can confirm the kickoff is correct. Cheap sanity check: does the received prompt match what was sent?

  2. Send a message into a running session. Let control inject a follow-up message into an existing session (not just launch a new one), so it can add or clarify context at the start rather than making the operator retype it.

  3. Verify + interject UX. Right after launch, control auto-checks the kickoff. If the prompt was dropped/garbled or the session started off-task, control interjects a correction automatically (or flags it to the operator to confirm).

Notes / current gaps

  • Control can launch_session and later read session summaries, and get_active_sessions gives status — but there is no live read-back of a session's transcript and no way to message into an already-running session.
  • This feature depends on those two new primitives (read-session-transcript, send-to-session); the verification/interjection behavior is built on them.

Related: #8 (this feature would have caught that truncation immediately).

Activity

  1. RyanSeanPhillips commented on Jun 24, 2026

    @RyanSeanPhillips
    OwnerAuthor

    Design note + feasibility, framed around a concrete use case (coordinating a change in physiometrics that the analytics app must handle).

    Two delivery methods, both worth having:

    Method A — deferred queue (always works, robust).
    A send_project_feedback({ project, note, context? }) MCP tool (or a kind:'feedback' task) writes to the target project's queue in the control workspace, keyed by project path. Surfaced as: a 📥 count on that project in the dashboard, a nudge ("project X has N unaddressed notes"), and — on the next launch_session for that project — an offer to inject the pending notes into the kickoff prompt (confirm-first). Works whether or not the target session is running, and for external sessions too.

    Method B — live inject into a running conversation (cockpit only).
    The control plane / any conversation can drop a message into an already-running session. Feasible specifically for cockpit sessions because the browser holds the WebSocket to each tile's PTY: MCP writes the note to the bridge queue → the dashboard poll reads it → if a cockpit tile for that project is open, it types the note into that tile's PTY (the same input channel keystrokes use) → otherwise it falls back to Method A. This reuses the exact cockpit-launch bridge pattern (just hardened into a queue). External terminal sessions can't be injected (no stdin IPC into another window) → they fall back to Method A.

    Read-back / kickoff verify (primitive #1 in the issue): the MCP server can read a launched session's opening turns from its JSONL (correlate via get_active_sessions → newest session in the project) to confirm the prompt arrived and the session is on-task. This is the cheap verification layer on top of A/B.

    Note: #8 (prompt truncation) is now fixed (f33089c), which removes the silent-failure that motivated the auto-verify urgency — but read-back is still valuable.

    Open UX decisions before building: should a live-injected message auto-submit or just pre-fill for the operator to confirm? And should injection always be confirm-first? (Leaning: pre-fill + confirm, matching the drafts-only/handoff model.)

  2. RyanSeanPhillips commented on Jun 24, 2026

    @RyanSeanPhillips
    OwnerAuthor

    Session-persistence progress (June 2026). Restoring the dashboard now auto-resumes conversations without manual /resume:

    • resume: tiles already carried a sessionId (auto-resumed).
    • new: tiles now get their real sessionId discovered server-side: fillDiscoveredSessions() lazily matches each live new terminal to the newest session JSONL in its cwd's slug dir (per overview poll, since an idle agent writes nothing until the first turn); exposed as overview.terminalSessions[tileId], persisted on the tile, and on restore a discovered new tile is converted to a resume: tile. Verified end-to-end by a fresh-context review agent. Commits b8ba608 + 490b7f7 (+ prompt-strip f405662/e03657b stops the divergent-duplicate regression).

    Remaining (the faithful read-back this issue is about):

    • Worktree resume: a worktree new tile's session lives under the worktree's slug, and the resume WS only accepts known-project cwds — so worktree tiles currently fall back (no faithful resume). Needs the resume path to support a worktree cwd.
    • Stronger spawn->session link: discovery is mtime-heuristic (best-effort; can defer/misattribute with many concurrent same-cwd tiles). A more authoritative link (agent-written marker, or read claude's own session-index keyed by PTY/cwd) would make it exact.
    • Connects to the original ask: read back a launched session's opening turns to verify the kickoff, and message into a running session.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions