Problem
runProgram(session, …) in agent-runner receives the session snapshot captured at the start of the run (bin.ts passes tui.store.session). During the run, nanostore's setKey replaces the atom's top-level object on every store mutation, so that captured reference goes stale — anything written to the store during the run isn't visible on it at the end.
Symptoms:
- events-audit dashboard URL: the agent emits
[DASHBOARD_URL] → InkUI.setDashboardUrl writes it to the store atom, but events-audit's buildOutroData reads sess.dashboardUrl from the stale snapshot → falls back to the generic /dashboard instead of the created dashboard. (src/lib/programs/events-audit/index.ts ~70-74)
session.skillId (and similar direct session.X = mutations in the runner) land on the stale ref; safe today only because they're read back through the same local ref, not the UI — a latent landmine for any future UI-visible field.
posthog-integration is unaffected: it reads its dashboard link from frameworkContext, which is shared by reference across the spread.
Proposed fix
Have the runner operate on the live session rather than a captured snapshot — e.g. pass the store (or a live accessor) into runProgram, or route post-run fields through store setters / getUI(). #595 already did this for the outroData delivery half (via getUI().outro(message, data), which also repaired reportFile/changes/dashboard rendering that was silently dropped). This issue tracks the remaining input half — buildOutroData reading stale session fields — across all programs.
Context
Surfaced by codex + multi-agent review on #595 and the chatgpt-codex-connector review. Deliberately deferred there to keep the handoff PR focused.
Problem
runProgram(session, …)inagent-runnerreceives thesessionsnapshot captured at the start of the run (bin.tspassestui.store.session). During the run, nanostore'ssetKeyreplaces the atom's top-level object on every store mutation, so that captured reference goes stale — anything written to the store during the run isn't visible on it at the end.Symptoms:
[DASHBOARD_URL]→InkUI.setDashboardUrlwrites it to the store atom, butevents-audit'sbuildOutroDatareadssess.dashboardUrlfrom the stale snapshot → falls back to the generic/dashboardinstead of the created dashboard. (src/lib/programs/events-audit/index.ts~70-74)session.skillId(and similar directsession.X =mutations in the runner) land on the stale ref; safe today only because they're read back through the same local ref, not the UI — a latent landmine for any future UI-visible field.posthog-integrationis unaffected: it reads its dashboard link fromframeworkContext, which is shared by reference across the spread.Proposed fix
Have the runner operate on the live session rather than a captured snapshot — e.g. pass the store (or a live accessor) into
runProgram, or route post-run fields through store setters /getUI(). #595 already did this for theoutroDatadelivery half (viagetUI().outro(message, data), which also repairedreportFile/changes/dashboardrendering that was silently dropped). This issue tracks the remaining input half —buildOutroDatareading stale session fields — across all programs.Context
Surfaced by codex + multi-agent review on #595 and the chatgpt-codex-connector review. Deliberately deferred there to keep the handoff PR focused.