Repository navigation
F: publish a finished task's pull request in production #103
Copy link
Copy link
Closed
Description
Why
After #91, the runner can execute a task, but nothing opens the task's pull request. PullRequestPublisher (runner/publish.ts) and GitBranchPusher (runner/branch-push.ts, #98, PR #101) are built and tested, but no production code constructs them or calls publish(). #91 part 1 (PR #102) builds the execution deps in runner/production.ts. #91 part 2 adds start and resume. Neither mentions publishing. So a task that finishes its last item stays running and has no PR.
Needed
- In
runner/production.ts, buildPullRequestPublisherwith the real gateways:GhAlreadyFixedGateway, theghpull request gateway, and aGitBranchPusher.- The pusher pushes from the runner-owned repository and uses the URL from
pushUrl(config.github.repository,GH_HOST). Never passurlin production (F2d: push the task head to its branch with a real BranchPusher (#98) #101 review, finding 6). ownedCommits(identity)gives the task ledger'sorigin: 'owned'SHAs. Before Add pre-merge rebase and head-bound command checks #22 adds rebasing, decide whether this set must also include heads that codeboost pushed but the ledger marks as foreign (F2d: push the task head to its branch with a real BranchPusher (#98) #101 review, finding 4).
- The pusher pushes from the runner-owned repository and uses the URL from
- Publish when a task's run ends:
- All items done, task
running, no active attempt:publish(identity)(ready). - The task moved to needs human:
publish(identity, { problems })(draft). - Run the publish after the run settles, with no attempt active, because
assertPublishablerefuses while an attempt is active.
- All items done, task
- Shutdown: track each in-flight publish like an
ItemExecutorrun. Abort it and await it before the Store closes (AGENTS.md: track an in-flight irreversible subprocess as part of shutdown).PullRequestPublisher.close()already aborts its runs. - Add an
/api/runneractionpublishto retry a publish that failed or was refused (for exampleOpeningUnsettled,BranchPushRefused, or a GitHub error). It takesexpectedStateVersionand an action ID, like the other runner actions. Show the last publish outcome inGET /api/runner. - Keep publishing off in demo mode, even when a
githubblock exists (AGENTS.md: keep irreversible integrations disabled in demo mode).
Tests
- A real Git remote (local bare repository) and fake
ghgateways: a task that completes opens one PR, and the branch is at the task head. - A needs-human task opens a draft PR with its problems.
- Shutdown during the push or during the PR opening: the Store closes only after the publish has settled, and the next start recovers the opening by its marker.
- A refused publish (
BranchPushRefused) leaves the taskrunning. Thepublishaction retries it once a person has fixed the branch.
Depends on #91 (PR #102) and #98 (PR #101).
🤖 Generated with Claude Code
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
mchwang commentedon Oct 3, 2026
Decisions for this issue, made 2026-10-03. Implemented in PR #110.
github.baseBranch, required when a runner block exists. The CLI checks it before the lock, andsetUpRunnerchecks it before anything is created.runningtask with every plan item done gets a ready publish;needs human, by any path (safety finding, time limit, budget expiry at admission), gets a draft publish. Its problems say what sent it there.publish_outcomes, andGET /api/runnershows it aspublish.last.Defaults I chose:
ownedCommits: the ledger'sorigin: 'owned'SHAs only. Before Add pre-merge rebase and head-bound command checks #22, foreign entries come only fromrecordRebase, which production never calls. Add pre-merge rebase and head-bound command checks #22 must revisit this (finding 4 of the F2d: push the task head to its branch with a real BranchPusher (#98) #101 review).publishaction: runs in the background, and its replay reports the settled outcome.not published, so the first start opens no PR that nobody asked for.Follow-ups, deliberately not done in #110:
snapshot.head, which may contain commits the ledger does not record. This belongs with Add pre-merge rebase and head-bound command checks #22.mchwang commentedon Oct 3, 2026
Follow-up issues for the deferred findings: #111 (close the draft on cancel), #112 (track the push's process group across a crash), #113 (publish only ledger-recorded commits; with #22), #114 (outcome version stamp, low confidence).
F: review fixes for publishing (#103): finding before budget, one gh …
F: settle a publish action whose process stopped before its outcome (#…
F: record every publish as in flight before it starts; settle a lefto…
F: pay what an earlier run owes before publishing; check the github b…
F: fixes from an independent crash-point review of publishing (#103)
F: fixes from round 2 of the independent review of publishing (#103)
F: fixes from round 3 of the independent review of publishing (#103)
F: fixes from round 4 of the independent review of publishing (#103)
F: fixes from round 5 of the independent review of publishing (#103)
F: fixes from round 6 of the independent review of publishing (#103)
F: fixes from round 7 of the independent review of publishing (#103)
F: fixes from round 8 of the independent review of publishing (#103)
F: fixes from round 9 of the independent review of publishing (#103)
F: publish a finished task's pull request in production (#103) (#110)
D: show a push left running by a crash is harmless; document it (#112) (
F: test and document that a published head carries the branch's own c…
F: stamp a publish outcome with the state version the publish last saw (
F: close a cancelled task's pull requests (#111) (#115)