#257 shipped its history half — loadRepoTimeline, migration 0077, repo-scoped fetch in the
console. Good fix. The session-lifecycle half was raised in a comment after that issue closed,
so it is currently untracked. This is that half.
Delegation is single-use
Two facts, both still true at 5f28af8:
// lib/loop-drivers.ts:117 — the driver REQUIRES a live session
const session = await getActiveSessionForRepo(env, instanceId, userId, repo.id);
if (!session) return { ok: false, status: 409, error: `${repo.name} has no live coding session…` };
// workflows/coding-session.ts:447 — the Pilot ENDS the session when its run completes
await endSession(env, instanceId, userId, sessionId, status);
So every delegated job consumes the session it needed:
open a session by hand → ask for work → start_work → Pilot completes → Pilot ends session
→ ask again → 409 → open another by hand
Verified three times today on FAS platform (964594b6), runner online throughout:
|
|
| 03:44:50 |
session opened (by hand) |
| 03:45:23 |
start_work → Pilot ran git pull — worked |
| 03:45:36 |
Pilot ended the session |
| ~05:40 |
asked again → 409 no live coding session |
| ~06:05 |
asked again after confirming → 409 again |
Also why the Coder Lead could not delegate to any of four subordinates (#259).
The error message tells the user to fix the wrong thing
loop-drivers.ts:122:
${repo.name} has no live coding session — start one on its Coding tab (and run \pags up`), then try again.`
The (and run \pags up`)is unconditional. It fires when the runner is **already connected** — verified at the moment of the 409:runnerOnline: true, relayConnected: true, reachable: true,
runnerVersion 0.4.32, lastSeenAt` current.
So a perfectly-behaved agent relays it faithfully and misinforms the user. Both retests above ended
with the agent telling the user to start a runner that was running. That is not the agent's fault —
it is repeating platform text that conflates two independent conditions.
Suggested shape
The design question first: should a completed Pilot run end the session, or only mark the run
done? Ending it is what makes delegation single-use, forces a fresh empty timeline per job, and
means a supervisor cannot supervise without a human opening a session first. Leaving the session
idle-but-live for the next goal removes all three at once.
If ending stays, the driver must be able to start a session itself when none is live and a
runner is connected — otherwise delegate_goal is only ever usable by someone sitting in the
console.
Either way, split the error by actual cause:
- runner not connected → say so, name the machine,
pags up
- runner connected, no session → say that, and (once the above lands) just start one
Verification
- Two consecutive delegated jobs succeed without a human opening a session between them.
- With the runner online and no session, the message never mentions
pags up.
- With the runner offline, it does — and names the node.
- The Coder Lead can delegate to an idle subordinate whose runner is connected.
Adjacent observation
The #256 run-history injection changed behaviour in a way worth watching: asked "Pull latest
changes" (an imperative), the agent answered about the 2-hour-old pull run and asked for
confirmation rather than acting. Grounded and honest — a clear improvement on denial — but it is
now possible for injected history to satisfy a request for new work. Worth a look if it recurs.
#257 shipped its history half —
loadRepoTimeline, migration0077, repo-scoped fetch in theconsole. Good fix. The session-lifecycle half was raised in a comment after that issue closed,
so it is currently untracked. This is that half.
Delegation is single-use
Two facts, both still true at
5f28af8:So every delegated job consumes the session it needed:
Verified three times today on FAS platform (
964594b6), runner online throughout:start_work→ Pilot rangit pull— worked409 no live coding session409againAlso why the Coder Lead could not delegate to any of four subordinates (#259).
The error message tells the user to fix the wrong thing
loop-drivers.ts:122:The
(and run \pags up`)is unconditional. It fires when the runner is **already connected** — verified at the moment of the 409:runnerOnline: true, relayConnected: true, reachable: true,runnerVersion 0.4.32, lastSeenAt` current.
So a perfectly-behaved agent relays it faithfully and misinforms the user. Both retests above ended
with the agent telling the user to start a runner that was running. That is not the agent's fault —
it is repeating platform text that conflates two independent conditions.
Suggested shape
The design question first: should a completed Pilot run end the session, or only mark the run
done? Ending it is what makes delegation single-use, forces a fresh empty timeline per job, and
means a supervisor cannot supervise without a human opening a session first. Leaving the session
idle-but-live for the next goal removes all three at once.
If ending stays, the driver must be able to start a session itself when none is live and a
runner is connected — otherwise
delegate_goalis only ever usable by someone sitting in theconsole.
Either way, split the error by actual cause:
pags upVerification
pags up.Adjacent observation
The #256 run-history injection changed behaviour in a way worth watching: asked "Pull latest
changes" (an imperative), the agent answered about the 2-hour-old pull run and asked for
confirmation rather than acting. Grounded and honest — a clear improvement on denial — but it is
now possible for injected history to satisfy a request for new work. Worth a look if it recurs.