* test(#2142): failing-first coverage for quick-task archival at milestone close-out * enhance(#2142): archive quick tasks at milestone close-out * fix(#2142): resolve review findings — readme injection, move/reset ordering, owned state write * fix(#2142): fold archival under milestone namespace, expose index IR, dedupe reset decision * test(#2142): assert archive-dir-relative summary path in index IR * docs(#2142): backfill changeset pr number to 3592 * test(#2142): skip newline-fixture injection test on windows (control chars illegal in path names) --------- Co-authored-by: sim <sim@local>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<purpose>
|
||||
|
||||
Archive accumulated phase directories from completed milestones into `.planning/milestones/v{X.Y}-phases/`. Identifies which phases belong to each completed milestone, shows a dry-run summary, and moves directories on confirmation.
|
||||
Archive accumulated phase directories from completed milestones into `.planning/milestones/v{X.Y}-phases/`. Identifies which phases belong to each completed milestone, shows a dry-run summary, and moves directories on confirmation. Also offers retroactive archival of `.planning/quick/` (#2142) when it is non-empty.
|
||||
|
||||
</purpose>
|
||||
|
||||
@@ -9,6 +9,7 @@ Archive accumulated phase directories from completed milestones into `.planning/
|
||||
1. `.planning/MILESTONES.md`
|
||||
2. `.planning/milestones/` directory listing
|
||||
3. `.planning/phases/` directory listing
|
||||
4. `.planning/quick/` directory listing
|
||||
|
||||
</required_reading>
|
||||
|
||||
@@ -69,6 +70,26 @@ Match phase directories to milestone membership. Only include directories that s
|
||||
|
||||
</step>
|
||||
|
||||
<step name="identify_quick_tasks">
|
||||
|
||||
Check whether `.planning/quick/` has anything to retroactively archive (#2142):
|
||||
|
||||
```bash
|
||||
ls -d .planning/quick/*/ 2>/dev/null || true
|
||||
```
|
||||
|
||||
**If no directories are found:** `.planning/quick/` is empty (or absent) — say nothing about quick-task archival and do not offer the step. Skip straight to `show_dry_run` with no quick-task summary or prompt.
|
||||
|
||||
**If at least one directory is found:** determine the target milestone. Unlike phase directories — whose milestone membership is derivable from the archived ROADMAP snapshot each completed milestone already has — quick tasks carry **no on-disk provenance** at all; there is no way to tell which milestone any given quick task directory belongs to. The target is therefore the single most recent completed milestone (from `.planning/MILESTONES.md`, already read in `identify_completed_milestones`, listed newest-first) that does not yet have a `-quick` archive directory:
|
||||
|
||||
```bash
|
||||
ls -d .planning/milestones/v*-quick 2>/dev/null || true
|
||||
```
|
||||
|
||||
Walk `.planning/MILESTONES.md`'s entries newest-first and pick the first version with no matching `v{version}-quick` directory above. If every completed milestone already has a `-quick` archive, or `.planning/MILESTONES.md` has no entries, there is no valid target — say so and skip the quick-task step entirely (do not prompt).
|
||||
|
||||
</step>
|
||||
|
||||
<step name="show_dry_run">
|
||||
|
||||
Present a dry-run summary for each milestone:
|
||||
@@ -92,6 +113,19 @@ These phase directories will be archived:
|
||||
Destination: .planning/milestones/v{X.Z}-phases/
|
||||
```
|
||||
|
||||
**If a quick-task target milestone was determined in `identify_quick_tasks`**, add:
|
||||
|
||||
```
|
||||
### Quick tasks — bucket-all into v{X.Y}
|
||||
{N} directories under .planning/quick/ will ALL be archived into this ONE milestone
|
||||
(v{X.Y} — {Milestone Name}), regardless of when each was actually completed.
|
||||
Quick tasks carry no on-disk record of which milestone they belong to, so this is
|
||||
a bucket-all, not a per-milestone split — unlike the phase archival above, which
|
||||
is derived per-milestone from each archived ROADMAP snapshot.
|
||||
|
||||
Destination: .planning/milestones/v{X.Y}-quick/
|
||||
```
|
||||
|
||||
**Stale local branches (upstream gone):**
|
||||
|
||||
First, update remote-tracking refs so the candidate list matches the execution list exactly:
|
||||
@@ -112,11 +146,12 @@ Show each branch name. If none, show:
|
||||
No stale local branches detected.
|
||||
```
|
||||
|
||||
If no phase directories remain to archive (all already moved or deleted) AND no stale branches exist:
|
||||
If no phase directories remain to archive (all already moved or deleted) AND no stale branches exist AND no quick-task target milestone was determined:
|
||||
|
||||
```
|
||||
No phase directories found to archive. Phases may have been removed or archived previously.
|
||||
No stale local branches detected either.
|
||||
No quick tasks to archive either.
|
||||
```
|
||||
|
||||
Stop here.
|
||||
@@ -127,6 +162,12 @@ AskUserQuestion: "Proceed with archiving and pruning?" with options: "Yes — ar
|
||||
|
||||
If "Cancel": Stop.
|
||||
|
||||
**If a quick-task target milestone was determined in `identify_quick_tasks`**, ask a separate, explicit question — this is a distinct, bucket-all action and must not be silently folded into the "Yes" above:
|
||||
|
||||
AskUserQuestion: "Archive ALL {N} quick-task directories into v{X.Y} — {Milestone Name}? This buckets every remaining quick task into this ONE milestone; there is no way to split them per-milestone." with options: "Yes — archive quick tasks into v{X.Y}" | "Skip"
|
||||
|
||||
If "Skip": do not run `archive_quick_tasks` — proceed to `archive_phases` (or `report`, if there were no phase directories to archive) with quick-task archival omitted.
|
||||
|
||||
</step>
|
||||
|
||||
<step name="archive_phases">
|
||||
@@ -147,6 +188,20 @@ Repeat for all milestones in the cleanup set.
|
||||
|
||||
</step>
|
||||
|
||||
<step name="archive_quick_tasks">
|
||||
|
||||
Only run this step when the "Yes — archive quick tasks into v{X.Y}" option was confirmed in `show_dry_run`.
|
||||
|
||||
Uses the narrow `milestone.archive-quick` command (#2142 escalation) rather than `milestone.complete --archive-quick`: cleanup runs against milestones that are typically ALREADY completed, and `milestone.complete` is the full close-out — it archives ROADMAP/REQUIREMENTS and writes a MILESTONES.md entry, so re-running it against an already-completed milestone would clobber that milestone's archived ROADMAP/REQUIREMENTS snapshot (the very snapshot this cleanup depends on) and duplicate its MILESTONES.md entry. `milestone.archive-quick` shares the same move/README-index/table-reset logic as `milestone.complete --archive-quick` (same underlying helper) without any of that.
|
||||
|
||||
```bash
|
||||
gsd_run query milestone.archive-quick "v{X.Y}"
|
||||
```
|
||||
|
||||
This moves every directory under `.planning/quick/` into `.planning/milestones/v{X.Y}-quick/`, (re)writes that directory's `README.md` index, and clears STATE.md's `### Quick Tasks Completed` table rows — identical move/index/reset behavior to the `--archive-quick` flag documented in `complete-milestone.md`'s `archive_milestone` step, without touching ROADMAP.md, REQUIREMENTS.md, MILESTONES.md, or milestone-completion guards. Extract `archived` from the result to confirm.
|
||||
|
||||
</step>
|
||||
|
||||
<step name="prune_local_branches">
|
||||
|
||||
After phase archival, prune local branches whose upstream has been deleted. Use the same filter as the dry-run so the execution list matches exactly what the user confirmed:
|
||||
@@ -168,7 +223,7 @@ Notes:
|
||||
Commit the changes:
|
||||
|
||||
```bash
|
||||
gsd_run query commit "chore: archive phase directories from completed milestones" --files .planning/milestones/ .planning/phases/
|
||||
gsd_run query commit "chore: archive phase directories from completed milestones" --files .planning/milestones/ .planning/phases/ .planning/quick/ .planning/STATE.md
|
||||
```
|
||||
|
||||
</step>
|
||||
@@ -179,6 +234,8 @@ gsd_run query commit "chore: archive phase directories from completed milestones
|
||||
Archived:
|
||||
{For each milestone}
|
||||
- v{X.Y}: {N} phase directories → .planning/milestones/v{X.Y}-phases/
|
||||
{If quick-task archival ran}
|
||||
- v{X.Y}: {N} quick-task directories → .planning/milestones/v{X.Y}-quick/ (bucket-all — see known limit)
|
||||
|
||||
Pruned: {N} local branches whose upstream is gone.
|
||||
|
||||
@@ -196,6 +253,8 @@ Pruned: {N} local branches whose upstream is gone.
|
||||
- [ ] Dry-run summary shown and user confirmed (covers both archival and pruning)
|
||||
- [ ] Phase directories moved to `.planning/milestones/v{X.Y}-phases/`
|
||||
- [ ] Stale local branches pruned (branches whose upstream is gone)
|
||||
- [ ] `.planning/quick/` checked; quick-task archival offered only when non-empty
|
||||
- [ ] When offered and confirmed, ALL remaining quick-task directories archived into the single named target milestone (bucket-all, not per-milestone) via `milestone.archive-quick`
|
||||
- [ ] Changes committed
|
||||
|
||||
</success_criteria>
|
||||
|
||||
Reference in New Issue
Block a user