feat: sandcastle reworks PRs with failing CI #29
No reviewers
Labels
No labels
in-review
ready-for-agent
ready-for-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
weiwen/evie!29
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "sandcastle/issue-20"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #20
What changed and why
The sandcastle loop now handles two classes of work: PR reworks (open PRs whose CI is red) and new issues (the existing path). PR-rework items are prioritized — they claim concurrency slots before new issues are scheduled.
New components
.sandcastle/pr-fixer-prompt.md— drives a newpr-fixeragent stage that reproduces the CI failure locally (nix develop .#ci -c just check), fixes it minimally, pushes to the existing branch, and posts a comment. It explicitly must not open a new PR or change any labels.plan-prompt.md— extended to querytea pulls listfor PRs withci == "failure"and include them in the plan output as aprReworksarray, listed beforeissues.main.mts— the work-item list is now aWorkItemunion (PrReworkItem | NewIssueItem). AMAX_CONCURRENCY = 5cap slices the combined list; excess items defer to the next iteration. Dispatch branches onitem.kind.Key design decisions
ready-for-humanthroughout rework. No relabelling happens — the livecifield in the Forgejo API governs re-pick on each iteration.pendingis a no-op: onlyfailuretriggers a rework attempt. After a fix push CI re-runs; if it fails again the PR is re-picked on a later iteration.MAX_CONCURRENCYprevents runaway parallelism. PR-rework items are slotted first so a busy backlog of new issues never starves CI fixes.Plan,PrReworkItem, andNewIssueItemare now derived from the zod schema rather than maintained as parallel hand-written types.Documentation
docs/agents/triage-labels.mdnow documents the CI-rework path so it's discoverable alongside the label lifecycle.Reviewer checklist
pr-fixer-prompt.md: are the push command and comment command correct? Does the "STOP on push failure" rule prevent half-done state?plan-prompt.md: does thejqfilter (select(.ci == "failure")) correctly excludependingandsuccessPRs?main.mts: concurrency slice — does PR-rework-first ordering hold whenMAX_CONCURRENCY < prReworks.length? (It does —prReworksare mapped first beforeissues.)MAX_CONCURRENCY = 5: reasonable default?