Repository navigation
Say how each build ended, let a decision's write-up survive unrelated edits, and stop an archived document's runs - #889
Merged
Merged
Conversation
… the connector
A person pressing Stop on a running build showed "Returned for changes" in the Build tab, the
same as a task its agent blocked, and the connector printed "Failed: Chopin ended this run
(build-forbidden)" for it. A build whose agent blocked a task ("Missing source") printed
"Finished" in the connector while Chopin said it was blocked. Chopin released the run of every
ended build as a revision request with the build's error, and nothing kept who stopped it; the
connector only ever heard a refusal, or nothing about how the build ended.
A person's Stop now records who pressed it (stoppedBy). The run's recorded reason says "Stopped
in Chopin by @login.", a blocked task's says "“Task” is blocked: reason", and Chat's end line
says "Build stopped by @login.", "Build blocked on “Task”: reason." or "Build failed: error.".
The machine's next heartbeat is refused with build-stopped and that sentence, so the connector
prints "✗ Stopped in Chopin by @login." and journals the run as stopped, with nothing failed and
nothing reported back. The answer to a build's last report now carries how it ended, so the
connector prints "✗ Blocked: …" or "✓ Finished: 1 task, <pull request>" and journals a blocked
run as blocked. The Build tab's card says Stopped by @login with the time, Blocked with the task
and reason, Build failed with the error, or Returned for changes with the reason.
Assistant-model: Claude Opus 5.5
Assistant-workflow: inline (subagent)
Assistant-verification: bun run types
Assistant-verification: bun test apps/server/src/tasks apps/connector apps/web/src/build-model.test.ts (684 pass; the one failure, workspace.test.ts's spike commit, is this machine's commit signing and passes with signing off)
Assistant-verification: new route, connector and build-model tests fail on origin/main 16c55ff
User-preference: things should be polished like the Slack UX and beautiful and elegant animations
Co-authored-by: Alex Lavaee <lavaman131@github.com>
Archiving the scratch document left its workflow run card live, still waiting on a question, after the Planner was released. Archiving ended runs only through the Planner's link: the link closing marks its cards stopped. A Planner that was disconnected with its work kept, or a link closed while a deploy was handing over (which reports nothing, as nothing was stopped), left the cards as last reported, and nothing could end them afterwards because attaching to an archived document is refused. Opening the document again brought them back live when a Planner hold still claimed them. Archiving now stops every live run card itself, with no question waiting, and saves that before it releases the link. An archived document always opens with its runs stopped, whatever a Planner hold says. Assistant-model: Claude Opus 5.5 Assistant-workflow: inline (subagent) Assistant-verification: bun run types Assistant-verification: bun test apps/server/src/chat/archive-runs.test.ts (the reopen test fails on origin/main's plan service; endRuns is new) User-preference: things should be polished like the Slack UX and beautiful and elegant animations Co-authored-by: Alex Lavaee <lavaman131@github.com>
…and say why one failed One decision's write-up showed "Couldn't write this up", and Retry failed again, while the two decisions answered beside it wrote up. Its job had failed both times with "The Planner's write_decision_scope failed twice." The scoped write refused any write whose revision was not the document's current one, so every edit anywhere between the job reading its passage and writing it refused it as stale. A workflow run was publishing its plan into the document and the other decisions' write-ups were landing, so the revision moved under it on its re-read too, and the turn ended after its second refusal. Retry ran into the same churn. A decision-followup turn now keeps what it read of its scope. A write naming an older revision lands when that turn read it at that revision and the passage, its headings and the saved answers are unchanged; a change to any of them still refuses. When a write-up does fail, its reason says why in plain words (the document changed while it was being written, another answer changed, the passage was removed, it needs a diagram or table, a build is running) without echoing the tool's arguments, and the card shows it beside Retry. Assistant-model: Claude Opus 5.5 Assistant-workflow: inline (subagent) Assistant-verification: bun run types Assistant-verification: bun test apps/server/src/questions apps/server/src/chat apps/server/src/conversation-plan apps/server/src/agent apps/server/src/harness packages/editor/src/widgets (3671 pass, 0 fail) Assistant-verification: the new scoped-write test refuses with "stale; read_decision_scope again" on origin/main eec9491; the reason tests fail there too Assistant-verification: the hosted job record for the failed card: decision-followup, failed, 2 attempts, "The Planner's write_decision_scope failed twice." Assistant-verification: bun run ci Assistant-verification: bun run design:behavior (106 passed) Assistant-verification: playwright implementation-launcher, build-restart, connector, decision-prose, planner-decisions, harness-decisions-deck (39 passed, 1 skipped) Assistant-verification: bun run build (initial JS 259,958 B raw, initial CSS 184,465 B raw) User-preference: things should be polished like the Slack UX and beautiful and elegant animations Co-authored-by: Alex Lavaee <lavaman131@github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What the maintainer saw
A live end-to-end run on a hosted deployment (plan, then Build, then archive) found three problems.
Causes
build-forbidden, which the connector reports as a failure. When an agent ended its turn, the connector reportedstoppedand printed "Finished" without asking Chopin how the build ended.What changed
1. One ending, said the same way everywhere. A new
build-endingmodule on the server decides how a first build ended. The same wording is used for the run record, Chat, the Build tab and the connector.stoppedBy(the login of the person who pressed it). The build's error stays "Stopped in Chopin." for builds stored before this change.build-stoppedand that sentence, after a restart too. The connector prints it as a stop, journals the run as{ state: "stopped", reason }, and sends no failure report.ending. The connector prints Blocked or Finished with pull requests, and journals a blocked run as{ state: "blocked", reason }. An older server sends noending, and the connector prints plain "Finished" as before.2. Write-ups land when the document moved on elsewhere, and say why when they fail.
3. Archiving ends the document's runs itself.
Evidence
Build tab before and after, from the browser spec's real Stop and block flows (desktop and phone):
Each change is copy inside existing components, with no new colours or CSS. The card title and detail keep their tokens, so contrast is unchanged and there are no new colour pairs to measure. In my dark-mode attempts the page stayed in its light theme, so I kept only the light shots. The critique notes are in
critique.md.Checks
bun run types: passbun run ci: passbun test apps/server/src/tasks apps/connector apps/web/src/build-model.test.ts apps/server/src/chat/archive-runs.test.ts: 699 pass, 0 fail. Run with commit signing off: on this machine,workspace.test.ts's spike fixture commit fails under signing, both here and on main.bun test apps/server/src/questions apps/server/src/chat apps/server/src/conversation-plan apps/server/src/agent apps/server/src/harness packages/editor/src/widgets: 3671 pass, 0 failbun run design:behavior: 106 passed--workers=2: implementation-launcher, build-restart, connector, decision-prose, planner-decisions and harness-decisions-deck: 39 passed, 1 skipped (the opt-in live ACP case)bun run build: initial JavaScript 259,958 B raw / 82,492 B gzip; initial stylesheet 184,465 B raw / 32,681 B gzip (budget 185,000 B). This change adds no CSS.endedCardtestsJudgement calls
stoppedBy. Existing records and specs keep their meaning, and only the owner can press Stop anyway.✗ …on stdout, not a red failure), because nothing failed.write_decision_prose, the conversation-decision write-up, has the same exact-revision check, but no evidence shows it failing. Its target can be an insertion point, so loosening that check needs its own care. I left it for a follow-up.Needs a change in the Planner client (not in this repository)
The hosted Planner client treats a
document-archivedrefusal as a crash. It exits with code 1, andchopin connectstarts it again only to be told to stop. It also records its runs as paused "link lost" rather than ending them. An archived document's refusal is final and deliberate. The client should exit cleanly, as it does for the deliberate stops it already recognises, and end those runs rather than keep them for a resume that cannot happen.