Repository navigation
Start a Build from the commit that holds its plan's files, which the Planner records - #888
Merged
Merged
Conversation
A remote Planner's backend writes a plan's formal files in its own worktree, but a build started
from the builder's checkout, or the default branch's head, so its agent never saw them and stopped
on missing sources. A plan revision carried no branch or commit to start from.
The backend now records where a revision's files are with a new /mcp tool, record_plan_source
({ id, revision, branch, commit }), after it pushes them. Chopin checks the branch name and the
40-hex SHA, asks GitHub for the commit with the caller's grant (a launch's machine grant for an MCP
token), refuses a revision the document has not reached with revision-conflict, and keeps one
source per revision, the newest 20, in the document's sidecar. A build of tasks drafted against
revision R starts from the source recorded for the newest revision at or before R: its checkout is
that commit on that branch, checked again on GitHub with the building machine's grant as Build is
pressed (refused with plan-source-unavailable when it is gone). The build records the source, its
run's read_implementation and MCP read_implementation return it as planSource, the Planner's
read_implementation_graph as plan_source, and the Build tab's card says "Built from plan revision
N · branch@short". A rebuild keeps today's base unless a source was recorded for a revision after
the one last built. A document with no source builds exactly as before. A connector that cannot
fetch a run's commit now fails naming the commit, branch and repository.
Assistant-model: Claude Opus 5.5
Assistant-workflow: inline (subagent)
Assistant-verification: bun run types
Assistant-verification: bun run ci
Assistant-verification: bun test apps/connector apps/server/src/tasks apps/server/src/mcp apps/server/src/mcp.test.ts apps/server/src/tool-schemas.test.ts apps/server/src/agent apps/server/src/plan apps/server/src/experiments apps/server/src/harness apps/web/src/build-model.test.ts (2230 pass, 0 fail)
Assistant-verification: playwright implementation-launcher and build-restart (28 passed, 1 skipped: the opt-in live ACP mode)
Assistant-verification: bun run build (initial JS 259,958 B raw / 82,484 B gzip, CSS 184,420 B raw / 32,675 B gzip)
Assistant-verification: after rebasing onto 16c55ff: bun run types; bun run ci; bun test apps/server/src/tasks apps/server/src/mcp apps/server/src/mcp.test.ts apps/connector/src/workspace.test.ts apps/web/src/build-model.test.ts (435 pass, 0 fail)
User-preference: a Build must start from the commit that holds the plan's files, not just the person's checkout
Co-authored-by: Alex Lavaee <lavaman131@github.com>
The no-middot rule forbids " · " as an inline separator; the Build card now reads "Built from plan revision N at branch@short".
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.
Start a build from the commit that holds the plan's files
What was seen
On a hosted deployment, the remote Planner's backend wrote the plan's formal files in its own
worktree. Build plan then ran on the person's machine and the coding agent stopped with "Missing
source": the files it was asked to build from were not in its worktree.
Cause
A build started from
sourceFor(connection, document): the commit of the person's own checkout,else the head of the default branch. The Planner's files lived only on the Planner's branch, and a
plan revision carried no branch or commit that would let a build find them.
Fix
Chopin now learns a plan source for a document revision: a branch the Planner pushed and the
commit on it that holds the revision's files.
/mcptoolrecord_plan_source{ id, revision, branch, commit }. The backend calls itafter it pushes, with the launch's MCP token. Chopin checks the branch name against git's branch
rules (no
refs/prefix) and the full 40-hex SHA (invalid-plan-source), asks GitHub for thecommit with the caller's grant, which for an MCP token is the machine's own
(
plan-source-unavailable), and refuses a revision the document has not reached(
revision-conflictwith the currentrevision). It answers{ recorded: true, revision, branch, commit }. The same triple again changes nothing; a new commitfor the same revision replaces the old one.
planSources),validated on restore like the other durable fields: ordered, unique, no newer than the document.
It is written under the document lock before the tool answers.
the newest revision at or before R. Its checkout is
{ repository, branch, commit }from thatsource. As Build is pressed, the server checks the commit again on GitHub with the building
machine's grant. If GitHub no longer has it, the press is refused with
plan-source-unavailableand nothing is queued. The browser says "The plan's commit isn't on GitHub. Ask chopin to push it
again". If a source is recorded between the check and the queue, the press is refused ("The plan's
files changed. Try again") so the build never pairs a stale base with a newer revision. With no
source, the build starts from the same checkout as before.
BuildRequest.planSource. The run'sread_implementationand MCPread_implementationreturn it asplanSource, and the Planner'sread_implementation_graphreturns it as
plan_source, so a builder can name it if something is still missing.from… while the build runs, with the full SHA in its title.
a source recorded for a revision after the one last built (
live.baseRevision): pressing Build,or a live rebuild, approves that revision, and the rebuild starts from that source.
() of <owner/repo> to start from (fatal: …)." It used to fail with git's raw "Command
failed".
hasCommit, which treats GitHub's 422 ("No commit found for SHA") and404 as "absent". The shared request path stays as it was: the new answered-status list is
per call.
The contract was agreed with the backend's author on the Planner side: the tool name, the
arguments, the error codes, and that an older server answers
-32601("tool not found"), which thebackend treats as "unsupported" and ignores.
Docs: Plan sources in the agent connection contract, and a
paragraph in Hosted agent.
Evidence
The new browser spec records a source through
/mcpand presses Build plan with the fakeconnector. It then checks the build's checkout and
planSource, and checks that the run's worktreeHEADis the Planner's commit with the plan's file in it. Last, it checks the Build card's line.The commit sits on a branch the person's checkout never checked out. An unknown commit is refused
first.
Chopin has one theme (
.darkreads the same tokens; seeassistant-ui.css), so there is no darkshot. Before this change the card had no source line. The shots show the new state only.
Contrast: the line uses
--color-text-secondary(gray-700,#47453f) on the card's--color-inset(gray-100,#f8f8f6). That is 9.01:1, computed with a script from the twotokens' sRGB values, above AA's 4.5:1. The line adds no non-text UI.
Impeccable:
impeccable contextonbuild-view.tsx, the craft floor read before the UI edit, andimpeccable detect --jsononbuild-view.tsxandbuild-source.cssreturned no findings. Thecritique in brief: one quiet line in the footer's secondary ink beside the machine, no icon (the
icon set has no branch glyph, and a stand-in glyph would be decoration), and an ellipsis rather
than wrapping so it never pushes the footer's action. Its new state appears with the footer, so it
adds no motion.
Checks
bun run types: pass, after rebasing onto 16c55ff.bun run ci: pass.bun test apps/server/src/tasks apps/server/src/mcp apps/server/src/mcp.test.ts apps/connector/src/workspace.test.ts apps/web/src/build-model.test.tsgave 435 pass and 0 fail.bun test apps/connector apps/server/src/tasks apps/server/src/mcp apps/server/src/mcp.test.ts apps/server/src/tool-schemas.test.ts apps/server/src/agent apps/server/src/plan apps/server/src/experiments apps/server/src/harness apps/web/src/build-model.test.tsgave 2230 pass and 0 fail.
experiments/routes.test.tsmakes git commits, so it needscommit.gpgsign=falseon a machine that signs by default. That is the environment, not thischange.
implementation-launcherandbuild-restart(--workers=2): 28 passed, 1 skipped(the opt-in live ACP mode).
bun run build: initial JS 259,958 B raw / 82,484 B gzip. The initial stylesheet is184,420 B raw / 32,675 B gzip, under its 185,000 B budget. The new rule is in
build-source.css,loaded with the Build view's lazy chunk.
New unit tests:
(
plan-source.test.ts)(
mcp/hosted.test.ts)rule (
tasks/routes.test.ts)tasks/builds.test.ts)workspace.test.ts)build-model.test.ts)Judgement calls
/mcptool, not a field onedit_implementation_graphorupdate_document. The codethat knows the commit is the backend's deterministic publish step, not the model. It already
reaches
/mcpwith its launch's MCP token.sentence) keep the last pushed files rather than dropping back to the person's checkout.
pressed (with the building machine's grant, which is what the connector fetches with). An
automatic rebuild is not re-checked. Its connector fails with the clear fetch error instead.
builder's own checkout stays hidden as before. A pushed branch of the repository is not private
to the builder.
Open
unreachable. GitHub usually still serves a dangling commit by SHA until garbage collection. A
build of an older revision whose commit is gone is refused clearly at the press, not built from
the wrong base.
source, for example on a backend or server that predates this change.