Sandcastle loop: open PRs for human review instead of self-merging #7

Closed
opened 2026-07-05 02:57:17 +08:00 by weiwen · 0 comments
Owner

Problem

The .sandcastle loop currently self-merges completed branches into the base and closes the originating issues (Phase 3, merge-prompt.md). We want a human gate: the loop should push each completed branch, open a PR via tea, label it for human action, and leave the issue open (linked from the PR) rather than merging and closing autonomously.

Behavioral change

  • Loop stops merging/closing. Each completed issue -> pushed branch + PR labeled ready-for-human.
  • Convergence comes from label transitions, not merges.

Label lifecycle

  • Planner selects only ready-for-agent issues.
  • On successful PR open: issue ready-for-agent -> in-review (drops out of the planner; "handled, tracked in a PR, no action on the issue itself").
  • PR gets ready-for-human (the surface the human reviews/merges).
  • in-review is a new label -> add to the canonical triage vocabulary.

Per-issue PR step

Folded into Phase 2 (after the reviewer, only when commits > 0); Phase 3 deleted.

  1. Idempotency guard: if an open PR for sandcastle/issue-{id} exists -> reconcile labels, done.
  2. Push via token-HTTPS: git push https://${FORGEJO_USER}:${FORGEJO_TOKEN}@forge.weiwen.dev/weiwen/evie.git HEAD:<branch>.
  3. tea pulls create --login forge --repo weiwen/evie --base main --head <branch> --title ... --description ... -- real summary, body contains Closes #{id} (auto-closes only on human merge).
  4. Label PR ready-for-human.
  5. Last: relabel issue ready-for-agent -> in-review. Strict ordering -- any earlier failure leaves the issue ready-for-agent for retry.

Merge cleanliness deferred to squash-merge by the human (no in-agent history reshaping).

File changes

  • main.mts: delete Phase-3 merge block + {{BRANCHES}}/{{ISSUES}}/completedBranches plumbing; add a pr-opener sandbox.run after the reviewer; update header comment.
  • New pr-prompt.md (per-issue: TASK_ID/ISSUE_TITLE/BRANCH) with idempotent guard + strict ordering; delete merge-prompt.md.
  • plan-prompt.md: filter tea issue list to ready-for-agent (fetch labels).
  • docs/agents/triage-labels.md: add in-review row.
  • docs/agents/issue-tracker.md: add PR-creation conventions; refine the "PRs as a request surface" note to distinguish consuming PRs (no) from the loop creating them (yes).

Out of band

Set the Forgejo repo default merge style to "squash".

## Problem The `.sandcastle` loop currently self-merges completed branches into the base and closes the originating issues (Phase 3, `merge-prompt.md`). We want a human gate: the loop should push each completed branch, open a PR via `tea`, label it for human action, and leave the issue open (linked from the PR) rather than merging and closing autonomously. ## Behavioral change - Loop stops merging/closing. Each completed issue -> pushed branch + PR labeled `ready-for-human`. - Convergence comes from label transitions, not merges. ## Label lifecycle - Planner selects only `ready-for-agent` issues. - On successful PR open: issue `ready-for-agent` -> `in-review` (drops out of the planner; "handled, tracked in a PR, no action on the issue itself"). - PR gets `ready-for-human` (the surface the human reviews/merges). - `in-review` is a new label -> add to the canonical triage vocabulary. ## Per-issue PR step Folded into Phase 2 (after the reviewer, only when commits > 0); Phase 3 deleted. 1. Idempotency guard: if an open PR for `sandcastle/issue-{id}` exists -> reconcile labels, done. 2. Push via token-HTTPS: `git push https://${FORGEJO_USER}:${FORGEJO_TOKEN}@forge.weiwen.dev/weiwen/evie.git HEAD:<branch>`. 3. `tea pulls create --login forge --repo weiwen/evie --base main --head <branch> --title ... --description ...` -- real summary, body contains `Closes #{id}` (auto-closes only on human merge). 4. Label PR `ready-for-human`. 5. Last: relabel issue `ready-for-agent` -> `in-review`. Strict ordering -- any earlier failure leaves the issue `ready-for-agent` for retry. Merge cleanliness deferred to squash-merge by the human (no in-agent history reshaping). ## File changes - `main.mts`: delete Phase-3 merge block + `{{BRANCHES}}`/`{{ISSUES}}`/`completedBranches` plumbing; add a `pr-opener` `sandbox.run` after the reviewer; update header comment. - New `pr-prompt.md` (per-issue: `TASK_ID`/`ISSUE_TITLE`/`BRANCH`) with idempotent guard + strict ordering; delete `merge-prompt.md`. - `plan-prompt.md`: filter `tea issue list` to `ready-for-agent` (fetch labels). - `docs/agents/triage-labels.md`: add `in-review` row. - `docs/agents/issue-tracker.md`: add PR-creation conventions; refine the "PRs as a request surface" note to distinguish consuming PRs (no) from the loop creating them (yes). ## Out of band Set the Forgejo repo default merge style to "squash".
weiwen 2026-07-05 03:04:32 +08:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
weiwen/evie#7
No description provided.