pub async fn start_session(
state: &Arc<ServerState>,
args: StartArgs,
generator: Arc<dyn TurnGenerator>,
) -> Result<Value, String>Expand description
Provision worktree + derive contract + register the session. Returns the start response value.
The work runs on a daemon-owned task (ServerState::spawn_durable_operation),
not on the caller’s future, and this wrapper only awaits its result. That is
load-bearing, not tidiness: coder.start is dispatched on the per-connection
conn_tasks JoinSet, which abort_all()s the instant the WebSocket
closes. [start_session_inner] registers the session and provisions its
worktree before the multi-minute contract derivation, so a board that quit
during drafting used to cancel the very run the board had just told the
operator would keep going — leaving a drafting session row, a leaked
worktree, no contract and no driver until the daemon restarted. A caller
that stays connected sees the identical response, at the identical time; a
caller that disappears now loses only its own response waiter.