T-QMGC-session-list-session-attach-across-hosts-sessions-config
State: closed/done · Impact: medium · Complexity: medium
session list/session attach read session records across hosts; a sessions: config sets
defaults per workflow.
Approach
Section titled “Approach”There is one session-record location, not one per host: every launch — headless or interactive,
whichever host it opened on — writes a SessionRecord to
.sdlc/sessions/<id>/record.json under the project root
(solutions/ontological/lib/services/session/record.ts). SessionRecord gained a
hostSessionId: string | null field (the host’s own id, threaded through from
T-QO8E’s HostParts.session contract) and logPath became string | null (an
interactive launch captures no output, per hosts/terminal.ts’s @sdlc:ignore-spawn
exception). sdlc session launch’s interactive path
(solutions/ontological/lib/services/session/ops/launch.ts) previously wrote no record at
all; it now writes exactly one, right after launchInteractive returns (that call is
synchronous, so the session has already ended and its exit code is already known — no
separate in-flight write like the headless path’s).
-
sdlc session list(lib/services/session/ops/list.ts, new): lists.sdlc/sessions/, reads eachrecord.jsonviareadSessionRecord, skips one that fails to parse, and renders a table (renderTablefromlib/util/table.ts, the same helperlease listre-exports) sorted most-recently-started first.--host <name>filters to one host. Empty case prints(no sessions). -
sdlc session attach <id>(lib/services/session/ops/attach.ts, new): looks up the record by id and dispatches onrecord.host:record.hostCommand when hostSessionIdcapturedFallback null(headless)— (nothing interactive to attach to) Prints where the captured log landed, or that none was captured. terminal/orca/cmux— (no attach mechanism today) Prints a how-to pointing at the host’s own tooling. Building one is out of scope. claudeclaude attach <hostSessionId>How-to pointing at claude attach’s own interactive picker.codexcodex resume <hostSessionId>Best-effort codex resume --last(may resume the wrong session if another has launched since).cursorcursor-agent --resume <hostSessionId>(only whencursor-agentis also on PATH)How-to. The actual resume/attach spawn is a raw, blocking,
stdio: "inherit"child (same documented exception ashosts/terminal.ts), reached through an injectablespawnSyncFnseam so tests never launch a realclaude/codex/cursor-agent. -
sessions:config (lib/config/load.ts, next tohost:):sessions.workflows.<name>. {engine,host}— a per-workflow-name default consulted ONLY bysession launch --workflow <name>(not--skill/--prompt, which have no workflow name to key off), below--engine/--hostbut above the hardcoded'claude'/host.defaultfallbacks. Distinct from the existingorchestrator.workflows.<name>.{engine,host}, which stays scoped to the orchestrator’s own tick dispatch — same shape, deliberately not shared.
| Area | Note |
|---|---|
solutions/ontological/lib/services/session/ops/list.ts | new: session list |
solutions/ontological/lib/services/session/ops/attach.ts | new: session attach |
solutions/ontological/lib/services/session/ops/launch.ts | interactive path now writes a SessionRecord; sessions.workflows resolution |
solutions/ontological/lib/services/session/record.ts | SessionRecord.hostSessionId added, logPath is now nullable |
solutions/ontological/lib/services/host/index.ts | re-exports onPath for session attach’s cursor-agent PATH guard |
solutions/ontological/lib/config/load.ts | sessions: config block |
Acceptance criteria
Section titled “Acceptance criteria”- AC-1:
sdlc session listshows sessions launched on at least two different hosts in one listing. Verified inlib/services/session/list.test.ts(“shows sessions launched on two different hosts in one listing”). - AC-2: A sessions: default for a workflow is applied when no host is explicitly given.
Verified in
lib/services/session/launch.test.ts(“session launch: sessions.workflows config default”).
Out of scope
Section titled “Out of scope”- Building an attach mechanism for the
terminal/orca/cmuxwrapper hosts —session attachreports how to reopen the work through each host’s own tooling instead. session listreading anything other than.sdlc/sessions/under the project root — there is one record location for every host, not one per host.
Dependencies
Section titled “Dependencies”T-QO8E—session attach’sclaude/codex/cursorbranches consume thehostSessionIdthose hosts’HostParts.sessionimplementations return.