Make environment setup completion observable to the task and platform#333
Conversation
Repository setup commands run in the background for environment tasks, but nothing told the agent (or the platform) when they finished: - Write <workspace>/.roomote/setup-status.json with live per-command state (pending/running/succeeded/failed) and mirror each command's stdout/stderr to .roomote/setup-logs/<repo>/<command>.log - Fix the sandbox instruction that unconditionally claimed setup commands "were already executed"; in background mode it now points the agent at the status file and logs instead - Inject an in-session notification via the harness when background setup settles while the task is actively running - Track the real setup lifecycle on task_runs (environment_setup_state / environment_setup_completed_at), written when setup settles rather than when the blocking phase returns, and record one task-run phase event per repository command
|
No code issues found. See task
Reviewed 418fce2 |
executeStartNewTask flips the phase to running before the StartNewTask command carrying the initial prompt reaches the harness, so a fast-settling background setup could inject its notification into that window and replace the initial user prompt as the session's first message. Buffer the settled outcome and deliver it only after the runtime emits taskStarted.
- Replace a literal NUL byte in commandKey with the \u0000 escape so Git stops treating setup-status.ts as a binary blob - Fold background Docker project warnings into the setup status file so it cannot report a clean 'completed' when Docker setup failed
|
Addressed review feedback in de6322f:
|
The sandbox instruction and the settle notification point the agent at .roomote/setup-status.json, but Docker-only or command-less environments never created it. Initialize the writer for every environment workspace and finalize it even when there are no repository commands to run, so the file's existence is an invariant the agent can rely on.
|
Addressed in fdc2131: |
The environment schema allows repeated command names within a repo, but the (repository, name) map kept only the first entry, so later duplicates vanished from the published plan and their callbacks overwrote the first entry's lifecycle. Each key now maps to all matching entries in plan order; since commands run sequentially per repository, callbacks target the earliest entry still in the expected state, and duplicate log files get an occurrence suffix.
|
Addressed in 418fce2: the |
Adds a compact badge next to the task status indicator that surfaces the live environmentSetupState from the task run: a spinner while background repository setup commands and Docker projects are still running, a warning badge when setup finished with warnings, and a failure badge when it failed. Renders nothing when setup never ran in the background or completed cleanly. Stacks on #333, which introduced the environmentSetupState column and keeps it updated while background setup settles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nner verification loop (#340) * Feed environment setup ground truth into the verification loop The environment-setup workflow already launches a verification task and revises the environment when verification fails, but both ends of that loop ran blind to the setup ground truth #333 introduced: - The verification task's prompt told it to "be patient" instead of reading .roomote/setup-status.json, so it could judge the environment before background setup settled or fail to name the broken command. - The task summary the setup agent polls (manage_tasks get_summary) did not surface environmentSetupState, so setup failures only reached the fix loop when the verification agent happened to describe them. Expose environmentSetupState through the summary API and render it as an Environment Setup line in get_summary, and update the skill so the verification prompt consults setup-status.json / setup-logs and the monitoring steps treat a failed or completed-with-warnings line as direct, fixable evidence. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Verify environments with the proof runner instead of re-provisioning The environment-setup fix loop iterated by relaunching a full environment-backed verification task per config revision, so every retry paid provisioning time and inherited compute failure modes unrelated to the config under test. Give environment-setup tasks the hidden proof-runner subagent in brief-supplied-target mode (they discover the app URL mid-task, so no target exists to bake at config-generation time; detection keys off the $environment-setup prompt invocation via the new isEnvironmentSetupTaskPrompt helper). The skill now iterates in-workspace: after loopback validation and on every install/start-affecting revision it delegates a one-item proof brief to the proof runner and treats the Blocked verdict, observed port state, and visible browser errors as the fix-loop evidence. The spawned environment-backed task becomes the single final end-to-end confirmation, and its prompt now relays its own proof runner's verdict and screenshot URLs instead of judging the page itself. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Update browser containment policy test for delegated proof-runner wording Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Prefer brief-targeted proof runner for env-setup tasks with an environment An environment-setup task launched against an existing environment carries that environment's initialUrl, but that URL is the thing under revision — baking it would pin the proof runner to a possibly stale surface and make it reject the freshly validated target the setup workflow needs to verify. Addresses the roomote review finding on run-task.ts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Problem
For environment-backed tasks, repository setup commands run in the background while the agent starts concurrently — and nothing closes the loop:
setupCompletedAtis stamped when the blocking portion of setup returns, i.e. before background commands actually finish, so even the DB couldn't say when setup really completed.flush()), so a running agent never learned that setup finished or failed mid-task.Changes
Observable ground truth in the workspace
EnvironmentSetupStatusWritermaintains<workspace>/.roomote/setup-status.json(atomic writes): overall state (running→completed/completed_with_warnings/failed) plus per-command state, exit code, duration, and error..roomote/setup-logs/<repo>/<command>.log; detached commands record their PM2 logfile instead.Honest agent instructions
buildSandboxInstructionnow branches on whether background setup is still pending at instruction-build time: pending → "may still be executing, check.roomote/setup-status.json, you'll be notified when it finishes, don't re-run running commands"; settled/blocking → the previous wording plus a pointer to the recorded results.In-session notification when setup settles
BackgroundEnvironmentSetupControllergains anonSettlednotifier that fires when the background promise actually settles (not at flush time).runTaskregisters a listener that injects an outcome-specific message into the harness session (visibleInTranscript: false,source: 'environment-setup') — only while the task phase isrunning, so an idle or settled-early task is never woken. Delivery is recorded as a task-run decision event.Truthful lifecycle in the DB (powers future UI)
task_runs.environment_setup_state/environment_setup_completed_atcolumns (migration0010), written via a new run-scopedtaskRuns.updateEnvironmentSetupmutation:runningright after setup returns when background work remains, terminal state when it settles. AnIS NULLguard prevents a replay from regressing a terminal state back torunning.phasetask-run event (environmentRepositoryCommand: <repo> <name>) through the existing phase pipeline.setupCompletedAtsemantics are unchanged (blocking-setup milestone).Follow-up (not in this PR)
Web UI: split the
Preparingstartup step into per-command progress and add an interactive-phase "environment setup running / complete" indicator driven by the newtaskRunsfields and phase events.Testing
EnvironmentSetupStatusWriterlifecycle,BackgroundEnvironmentSetupControllersettle/notify/persist paths (including rejection), sandbox-instruction wording for pending vs. settled background setup, and execute-task-run assertions that the notifier is passed to the runtime andrunning→completed_with_warningsstates are persisted.