Multi-milestone work and documents on the new loop (M2.4) #103

Merged
dev-agent merged 1 commits from loop-milestones into main 2026-10-05 23:56:30 +00:00
Collaborator

M2.4 of the Development Plan (D1, D2, D4).

What changes

  • Milestones start from the latest default branch. Every milestone branch is cut from origin/<base> after a fetch. So milestone 2 builds on the merged milestone 1, and a redo after a closed PR doesn't carry the rejected work. Uncommitted work carries over; if git would conflict, the driver is told.
  • The next milestone waits for the merge. While the item's own PR (loop.pr) is open, start_milestone is refused and the driver is pointed at wait_for_review. The PR's state is read from Gitea when the call is made, not taken from the last watch round.
  • "Part of #N" vs "Closes #N". finish_milestone takes final: earlier PRs are part of the issue and the last one closes it. If final is missing it counts as final, as before. An issue that others depend on keeps them blocked until its last PR merges.
  • close_item with the item's PR still open waits for the merge, then closes. The walk reached this once milestones could follow a live-read merge.
  • Documents (D2), in the driver's instructions only:
    • read ARCHITECTURE.md and docs/plans/ before restating;
    • work longer than about one PR gets a build plan (goal, interfaces, edge cases, and tests as acceptance criteria per milestone), committed with the first milestone and marked done in each PR;
    • a design change updates ARCHITECTURE.md in the same PR.
  • A parking fix, found by the walk.
    • The bug: a half-done review fix was parked by committing it onto the item's branch. The PR had merged meanwhile, so the work sat on a merged branch, and the next milestone, cut fresh from main, didn't have it.
    • The fix: parking now stashes uncommitted work, untracked files included, and pushes the snapshot to <item>-parked. Resuming puts it back uncommitted, so it goes wherever the work goes next, and deletes the side branch. A closed item's side branch is dropped. The item's branch is pushed only when it has commits of its own.
    • Architecture change, please check: D4's parking line now reads "Parking pushes the item's work: its branch, and anything uncommitted to a side branch of its own, never onto a PR's branch."

Tests

  • test_loop_multi.py:
    • milestone 2 is cut from main with milestone 1 merged, and carries only its own files;
    • a start while the PR is open is refused;
    • a merge no watch round has seen yet is read from Gitea;
    • a redo after a closed PR drops the rejected work;
    • Part of / Closes;
    • close_item waits for an open PR.
  • test_loop_queue.py: the parking test is updated for the side branch, plus a regression test for the parked half-done fix.
  • Walk: new property milestones_start_fresh. Reverting to fork-from-current fails it in 9 seeds. parked_work_safe now reads full history, since a stash keeps new files in its third parent.
  • E2E: a two-milestone feature. PR 1 has the plan under docs/plans/ and says "Part of"; PR 2 builds on the merged PR 1 and says "Closes"; the item closes after both merge. scripts/e2e.sh passed 6 of 6 in one run.

Deferred

  • An empty milestone that wasn't expected to change code still gets raised with you (D4).

🤖 Generated with Claude Code

https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE

M2.4 of the Development Plan (D1, D2, D4). ## What changes - **Milestones start from the latest default branch.** Every milestone branch is cut from `origin/<base>` after a fetch. So milestone 2 builds on the merged milestone 1, and a redo after a closed PR doesn't carry the rejected work. Uncommitted work carries over; if git would conflict, the driver is told. - **The next milestone waits for the merge.** While the item's own PR (`loop.pr`) is open, `start_milestone` is refused and the driver is pointed at `wait_for_review`. The PR's state is read from Gitea when the call is made, not taken from the last watch round. - **"Part of #N" vs "Closes #N".** `finish_milestone` takes `final`: earlier PRs are part of the issue and the last one closes it. If `final` is missing it counts as final, as before. An issue that others depend on keeps them blocked until its last PR merges. - **`close_item` with the item's PR still open waits for the merge,** then closes. The walk reached this once milestones could follow a live-read merge. - **Documents (D2), in the driver's instructions only:** - read `ARCHITECTURE.md` and `docs/plans/` before restating; - work longer than about one PR gets a build plan (goal, interfaces, edge cases, and tests as acceptance criteria per milestone), committed with the first milestone and marked done in each PR; - a design change updates `ARCHITECTURE.md` in the same PR. - **A parking fix, found by the walk.** - **The bug:** a half-done review fix was parked by committing it onto the item's branch. The PR had merged meanwhile, so the work sat on a merged branch, and the next milestone, cut fresh from main, didn't have it. - **The fix:** parking now stashes uncommitted work, untracked files included, and pushes the snapshot to `<item>-parked`. Resuming puts it back uncommitted, so it goes wherever the work goes next, and deletes the side branch. A closed item's side branch is dropped. The item's branch is pushed only when it has commits of its own. - **Architecture change, please check:** D4's parking line now reads "Parking pushes the item's work: its branch, and anything uncommitted to a side branch of its own, never onto a PR's branch." ## Tests - **`test_loop_multi.py`:** - milestone 2 is cut from main with milestone 1 merged, and carries only its own files; - a start while the PR is open is refused; - a merge no watch round has seen yet is read from Gitea; - a redo after a closed PR drops the rejected work; - Part of / Closes; - `close_item` waits for an open PR. - **`test_loop_queue.py`:** the parking test is updated for the side branch, plus a regression test for the parked half-done fix. - **Walk:** new property `milestones_start_fresh`. Reverting to fork-from-current fails it in 9 seeds. `parked_work_safe` now reads full history, since a stash keeps new files in its third parent. - **E2E:** a two-milestone feature. PR 1 has the plan under `docs/plans/` and says "Part of"; PR 2 builds on the merged PR 1 and says "Closes"; the item closes after both merge. `scripts/e2e.sh` passed 6 of 6 in one run. ## Deferred - An empty milestone that wasn't expected to change code still gets raised with you (D4). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
dev-agent added 1 commit 2026-10-05 20:57:52 +00:00
Multi-milestone work and documents on the new loop (M2.4)
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 3m45s
cd9ab2559e
- Every milestone branch is cut from the latest default branch: the next
  milestone builds on the merged previous one, and a redo after a closed PR
  drops the rejected work. Uncommitted work comes along.
- While the item's PR is open, start_milestone is refused, with the PR's
  state read from Gitea at that moment, not the last watch round.
- finish_milestone(final): earlier PRs say "Part of #N", the last "Closes
  #N"; unsaid, it's final, as before.
- close_item with the item's PR still open waits for the merge (L2: a
  closed item leaves nothing open).
- The driver's instructions cover ARCHITECTURE.md and build plans under
  docs/plans/ (D2); the harness never parses a plan.
- Parking stashes uncommitted work and pushes it to <item>-parked, put back
  on resume, instead of committing it onto the item's branch. The walk
  found a half-done review fix parked onto a PR that had merged meanwhile,
  where it was lost. Architecture D4's parking line says so.

Tests: unit tests for fresh milestone branches, the merge wait (including
a merge not yet watched), redo after a closed PR, Part of/Closes, close
waiting on an open PR, and the parked-fix regression; the walk's new
milestones_start_fresh property (fork-from-current fails 9 seeds); an e2e
two-milestone feature.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
dongar approved these changes 2026-10-05 23:49:46 +00:00
dev-agent merged commit 3adbcce2a6 into main 2026-10-05 23:56:30 +00:00
dev-agent deleted branch loop-milestones 2026-10-05 23:56:30 +00:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dev/nisse#103