@erclx/aitk 0.47.0 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "aitk",
3
3
  "description": "Automated governance, versioning, and discovery tools for Claude Code.",
4
- "version": "0.47.0",
4
+ "version": "0.49.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -9,14 +9,21 @@ description: What the review return leg is for, the gaps it closes, and why the
9
9
 
10
10
  Without this skill, review findings are worked in whatever order the author read them and the thread never records which landed. A reply posted before the push describes code the remote does not have, so a reviewer checks the branch and finds the old version. A failing check gets treated as separate from the review, which produces a follow-up that answers every comment and leaves continuous integration red. One finding nobody can resolve stalls the rest.
11
11
 
12
+ A branch also goes stale from `main` moving rather than from anything the branch did. Nothing in the return leg rebases it, so the worker closes every finding, reports the pull request answered, and the branch still cannot merge. Half the resolution is mechanical and wrong to do by hand, since a generated file merged manually produces a diff the next regen discards.
13
+
12
14
  ## Must
13
15
 
14
16
  - Treat a failing check as a finding alongside the review comments, so the follow-up closes both
15
17
  - Handle each finding independently, so one unresolved item does not block the others
16
18
  - Verify before pushing, since a red follow-up costs the reviewer a second pass
19
+ - Rebase onto `origin/main` when the branch no longer merges, after the findings are addressed and before the push, so one force-push carries both
20
+ - Test staleness on every invocation, including one carrying no findings, since a branch goes stale from `main` moving rather than from anything the review said
21
+ - Re-test once the fixes are commits, since the first test reads committed history and cannot see a fix that touches lines `main` moved
22
+ - Rebuild a generated file through the project check rather than resolving its conflict by hand
17
23
  - Push before replying, so the comment never runs ahead of the code it describes
18
24
  - Map every finding to what changed, or to a one-line reason when it is a question or a conscious accept
19
25
  - Post the terminal comment only when the findings are addressed and every check passes
26
+ - Say what the run actually did on a rebase-only pass, since a reply mapping findings and a terminal comment claiming they were addressed are both false on a pull request carrying none
20
27
  - Scan the reply for banned characters and internal phase labels before posting, since the comment leaves for the remote unchecked
21
28
 
22
29
  ## Must not
@@ -26,11 +33,15 @@ Without this skill, review findings are worked in whatever order the author read
26
33
  - Post the closing comment while a check is failing
27
34
  - Reimplement the follow-up push or the doc refresh. Both have owners, and a second copy here drifts from them.
28
35
  - Edit silently. A finding answered without a reply leaves the reviewer re-deriving the change from the diff.
36
+ - Take one side of a conflict wholesale. Both sides are valid content, so `--ours` or `--theirs` drops one silently and passes every check.
37
+ - Merge `main` into the branch. The repository squash-merges, so a merge commit reads as noise on the pull request.
38
+ - Guess at a hunk the tree does not settle. That case reaches the operator as an ordinary finding on the next pass only if the worker stops.
29
39
 
30
40
  ## Guards
31
41
 
32
42
  - No open pull request for the current branch: stop
33
- - The pull request carries no review comments or threads: stop with a pass
43
+ - The pull request carries no review comments or threads and the branch still merges: stop with a pass. A closed review says nothing about whether the branch still merges, so the staleness test decides this one rather than the finding count.
44
+ - A conflict needing a decision the tree does not carry: stop with the branch left on its old base
34
45
 
35
46
  ## Out of scope
36
47
 
@@ -38,3 +49,4 @@ Without this skill, review findings are worked in whatever order the author read
38
49
  - Staging, committing, and pushing the follow-up, which `git-followup` owns under this skill's direction
39
50
  - Refreshing the `.claude/` docs the fixes made stale, which `claude-docs` owns
40
51
  - Re-reviewing its own fixes, which hands back to the orchestrator
52
+ - Re-reading a rewritten branch, which `claude-pr-review` absorbs by testing whether the prior reviewed commit still reaches the head and paying for a full pass when it does not
@@ -11,7 +11,7 @@ the PR from an independent session. This skill consumes them: fix, reply, push.
11
11
  ## Guards
12
12
 
13
13
  - If no open PR resolves for the current branch via `gh pr view`, stop: `❌ No open PR. Nothing to address.`
14
- - If the PR has no review comments or threads, stop: `✅ No review findings to address.`
14
+ - If the PR has no review comments or threads, run step 5's staleness test before deciding. A branch that still merges stops here: `✅ No review findings to address.` One that does not skips steps 1 through 4 and runs step 5 onward, since a branch goes stale from `main` moving and a closed review says nothing about whether it still merges.
15
15
  - Fix findings. Do not merge.
16
16
 
17
17
  ## Step 1: pull the review findings and CI status
@@ -48,7 +48,57 @@ Do not push a red follow-up.
48
48
 
49
49
  The fixes may have changed or added behavior that `.claude/` context entries, docs, or wireframes describe. Refresh them with the `claude-docs` skill, which maps the changed files to the entries that reference them and rewrites the stale sections. Do not reimplement that mapping here. When a fix adds a new capability with no existing entry, `claude-docs` flags it rather than creating one.
50
50
 
51
- ## Step 5: push, then reply
51
+ ## Step 5: rebase a stale branch
52
+
53
+ A branch goes stale from `main` moving rather than from anything the branch did,
54
+ so the test runs on every invocation, including the one the second guard sends
55
+ straight here with no findings to fix. Fetch first. A stale local `origin/main`
56
+ reports no conflict on a branch that has one.
57
+
58
+ ```bash
59
+ git fetch origin main
60
+ git merge-tree --write-tree origin/main HEAD
61
+ ```
62
+
63
+ A zero exit means the branch still merges. Skip to step 6. A non-zero exit means
64
+ it does not. Stash the fixes first when `git status --porcelain` reports
65
+ anything, since a rebase refuses to run over a dirty tree, then rebase onto
66
+ `origin/main` and restore them:
67
+
68
+ ```bash
69
+ git stash push -u
70
+ git rebase origin/main
71
+ git stash pop
72
+ ```
73
+
74
+ Pop only when the stash ran. On a clean tree, which is what a run whose findings
75
+ were all conscious-accepts leaves behind, `git stash push` saves nothing and
76
+ exits zero, so the pop restores an unrelated entry from an earlier session.
77
+
78
+ Never merge `main` into the branch. The repository squash-merges, so a merge
79
+ commit here reads as noise on the pull request.
80
+
81
+ Resolve every conflict under these rules, which apply to a hunk from the rebase
82
+ and a hunk from the stash pop alike:
83
+
84
+ - Never take one side wholesale with `--ours` or `--theirs`. Both sides are valid content, so the drop is silent and passes every check.
85
+ - Never resolve a generated file by hand. A file the project check rebuilds, such as an `index.md` carrying no `auto: false`, takes either side to clear the conflict and gets its real content from the regen below.
86
+ - Where two branches wrote prose into one file, keep both sides and rewrite what the merge broke. A section that opens by counting what follows needs the count updated rather than the two versions concatenated.
87
+ - When a hunk needs a decision the tree does not carry, stop rather than guessing, and name where the branch was left. The two sources recover differently. A hunk raised by the rebase takes `git rebase --abort`, which restores the old base: `❌ Conflict needs a decision at <file>. Branch left on its old base.` A hunk raised by the stash pop arrives after the rebase already landed, so no abort applies and the conflict stays in the tree: `❌ Conflict needs a decision at <file>. Branch rebased, fixes left conflicted in the tree.` A guess that compiles is the failure this stage would otherwise introduce, and either case reaches the operator as an ordinary finding on the next review pass.
88
+
89
+ Both sides of every hunk sit in the conflict and `git log origin/main` names what
90
+ landed, so the tree carries the context. Do not wait on the orchestrator for it.
91
+
92
+ Re-run the project check after the rebase. It rebuilds the generated files and
93
+ covers what the replayed commits broke, and step 6 commits the result alongside
94
+ the fixes.
95
+
96
+ `git merge-tree` reads committed history, so this test says nothing about the
97
+ fixes still sitting in the working tree. A branch that merges clean as committed,
98
+ whose fixes touch lines `main` moved, passes here and reaches the remote
99
+ unmergeable. Step 6 re-runs the test once those fixes are commits.
100
+
101
+ ## Step 6: push, then reply
52
102
 
53
103
  Push the fixes before posting the reply so the comment never runs ahead of the
54
104
  code it describes. Ship the fixes as a follow-up commit on the same branch with
@@ -56,7 +106,21 @@ the `git-followup` skill, invoked with `reply-owned` so it stages, commits,
56
106
  pushes, and refreshes the open PR body without posting its own comment. This
57
107
  skill owns the reply. Do not reimplement that flow here. For in-place fixes to
58
108
  files the PR body already covers, `git-followup` leaves the body untouched and
59
- the reply comment carries the fix log.
109
+ the reply comment carries the fix log. A rebase in step 5 rewrote the branch, so
110
+ that push is a force-push and `git-followup` resolves it from the tracking
111
+ branch. Worker branches are single-owner here, which is what makes overwriting
112
+ the remote safe.
113
+
114
+ `git-followup` stops on an unchanged tree. A run that answered every finding as a
115
+ conscious-accept and whose rebase left the generated files alone has nothing for
116
+ it to commit, so the rebase would never reach the remote. Push that case directly
117
+ with `git push --force-with-lease`, then post the reply below.
118
+
119
+ Once the fixes are commits, re-run step 5's staleness test against the new head.
120
+ A conflict that appears only now is one the fixes introduced against lines `main`
121
+ moved, which the earlier test could not see. Rebase again under step 5's rules
122
+ and force-push, then continue. The second push costs one extra force-push in a
123
+ case that needs the fix and the sibling to touch the same lines.
60
124
 
61
125
  Then write a summary reply to `.claude/.tmp/address-review/reply-<number>.md`
62
126
  mapping each finding to what changed, or to a one-line reason when it is a
@@ -72,6 +136,18 @@ review itself carries. Follow it with a one-line summary sentence, then one
72
136
  bullet per finding, each opening with the bolded finding identifier.
73
137
  Close the body with `🤖 Addressed by Claude Code` on its own line so the reply
74
138
  reads as an independent machine pass, not a human sign-off.
139
+ When step 5 rebased the branch, say so in the summary sentence and name which
140
+ files were resolved by hand and which the regen rebuilt. The next review is a
141
+ full pass rather than a delta, and the reader is owed the reason.
142
+
143
+ A run the second guard sent straight to step 5 has no findings to map, so it
144
+ takes a different body rather than an empty list. Open it with `## Rebase`, not
145
+ `## Review response`, since nothing on the pull request is being responded to and
146
+ that heading claims a review this run never read. State that the branch stopped
147
+ merging, name what landed on `main`, name the files resolved by hand and those
148
+ the regen rebuilt, and close the same way. The heading stays outside the
149
+ `## Review` family so the close-out's equality test on the first line never
150
+ matches it.
75
151
 
76
152
  Before posting, run the scan in `.claude/standards/publish.md`
77
153
  against the reply, or `${CLAUDE_SKILL_DIR}/../../standards/publish.md` when
@@ -82,7 +158,7 @@ only gate on the published reply. Post it to the PR:
82
158
  gh pr comment <number> --body-file .claude/.tmp/address-review/reply-<number>.md
83
159
  ```
84
160
 
85
- ## Step 6: confirm resolution
161
+ ## Step 7: confirm resolution
86
162
 
87
163
  After the follow-up push, watch CI on the PR. Poll `gh pr checks <number>`
88
164
  until no check is pending, then read the final status. When every finding is
@@ -93,15 +169,33 @@ clear terminal state:
93
169
  gh pr comment <number> --body "✅ All review findings addressed, CI green."
94
170
  ```
95
171
 
172
+ A rebase-only run addressed no finding, so it takes its own terminal comment
173
+ rather than that one. Claiming findings were addressed on a pull request that
174
+ carries none is false on a surface nothing else checks:
175
+
176
+ ```bash
177
+ gh pr comment <number> --body "✅ Rebased onto origin/main, CI green. No review findings were open."
178
+ ```
179
+
96
180
  If any check fails, do not post the closing comment. Report the failing check
97
181
  so it can be fixed first. This is a resolution signal, not a formal approval,
98
182
  since the PR author cannot approve their own PR.
99
183
 
100
- ## Step 7: output
184
+ ## Step 8: output
101
185
 
102
186
  ```plaintext
103
187
  Addressed <N> findings on PR #<number>. Follow-up pushed.
188
+ <Rebased onto origin/main. <N> files resolved by hand, <N> rebuilt by the check.>
189
+ ```
190
+
191
+ Omit the second line when the branch still merged. Name any finding left as a
192
+ reply rather than a code change, with its one-line reason.
193
+
194
+ A rebase-only run drops the first line rather than reporting zero findings
195
+ addressed, and leads with the rebase instead:
196
+
197
+ ```plaintext
198
+ Rebased PR #<number> onto origin/main. <N> files resolved by hand, <N> rebuilt by the check.
104
199
  ```
105
200
 
106
- Name any finding left as a reply rather than a code change, with its one-line
107
- reason. Do not merge. Hand back to the orchestrator for re-review.
201
+ Do not merge. Hand back to the orchestrator for re-review.
@@ -238,18 +238,18 @@ Sweep reviews this session consumed, and sweep plans across the whole board. Res
238
238
 
239
239
  Board-wide scope is the one place this sweep reaches past Step 3's rule against touching task files the session did not change. A board carrying a task that closed while an earlier run missed its archive is the defect this exists to clear, and skipping those tasks would preserve it. Reaching them is safe because the archive moves the plan and points the task at the new path, so a task from unrelated work ends up with a working pointer rather than a broken one.
240
240
 
241
- Before moving anything, count the other citations. Scan every `.claude/tasks/*.md` file except the one being processed for a `Plan:` line naming the same plan. Compare the resolved target from the parse above, never the raw target string and never the filename alone. A board carrying one task written `../plans/x.md` and another written `.claude/plans/x.md` cites one plan, and a raw string comparison reads two, counts zero, and archives the file out from under a live task. Comparing filenames swaps that for the opposite error, since a live plan and an archived one share a basename whenever a closed task still points into `.claude/.tmp/plans-archive/`, and the count then reads a citation that does not exist and archives nothing.
241
+ Before moving anything, count the other citations. Scan every `.claude/tasks/*.md` file except the one being processed for a `Plan:` line naming the same plan. Compare the resolved target from the parse above, never the raw target string and never the filename alone. A board carrying one task written `../plans/x.md` and another written `.claude/plans/x.md` cites one plan, and a raw string comparison reads two, counts zero, and archives the file out from under a live task. Comparing filenames swaps that for the opposite error, since a live plan and an archived one share a basename whenever a closed task still points into `.claude/plans-archive/`, and the count then reads a citation that does not exist and archives nothing.
242
242
 
243
243
  Exclude the closing task explicitly. It sits on the board and cites the plan itself, so a scan that counts it never reaches zero and no plan is ever archived.
244
244
 
245
245
  A plan can serve more than one task, and archiving on the first task to close strands every other task's pointer at a path that has moved. `.claude/plans/` is gitignored, so that retarget would be the only record and there is nothing to recover it from.
246
246
 
247
- - Target resolves inside `.claude/plans/`, the file exists, and no other task file cites it: create `.claude/.tmp/plans-archive/`, move the file there under its original name, overwriting any file already sitting at that name. Then rewrite the task file's `Plan:` line to the archive path, so a completed task still leads to the reasoning behind it.
247
+ - Target resolves inside `.claude/plans/`, the file exists, and no other task file cites it: create `.claude/plans-archive/`, move the file there under its original name, overwriting any file already sitting at that name. Then rewrite the task file's `Plan:` line to the archive path, so a completed task still leads to the reasoning behind it.
248
248
  - Target resolves inside `.claude/plans/` and at least one other task file cites it: leave the plan where it is and retarget nothing. Report the shared citation.
249
- - Target resolves inside `.claude/.tmp/plans-archive/`: skip silently. The plan was archived by an earlier pass and the task file is already correct.
249
+ - Target resolves inside `.claude/plans-archive/`: skip silently. The plan was archived by an earlier pass and the task file is already correct.
250
250
  - Any other resolved target outside `.claude/plans/`: warn and skip.
251
251
 
252
- Write the retarget as a markdown link, `Plan: [feature-<slug>](../.tmp/plans-archive/feature-<slug>.md)`, updating both halves so the text and the target stay in step. This branch is the only writer that produces a `Plan:` line nobody authored by hand, so a retarget that emits a bare path converts every task to the old form as it closes and drifts the board back to two shapes on its own.
252
+ Write the retarget as a markdown link, `Plan: [feature-<slug>](../plans-archive/feature-<slug>.md)`, updating both halves so the text and the target stay in step. This branch is the only writer that produces a `Plan:` line nobody authored by hand, so a retarget that emits a bare path converts every task to the old form as it closes and drifts the board back to two shapes on its own.
253
253
 
254
254
  **Reviews.** Derive `<slug>` per `.claude/standards/slug.md`, or `${CLAUDE_SKILL_DIR}/../../standards/slug.md` when the project does not have it. Fall back to `latest` on an empty result. If `.claude/review/review-<slug>.md` exists, delete it. `claude-review` writes with this convention. Do not sweep any other `review-*.md` file.
255
255
 
@@ -257,7 +257,7 @@ Do not sweep `ui-checklist-*.md` (pending human verification) or `ux-audit-*.md`
257
257
 
258
258
  Output one line per file swept:
259
259
 
260
- - `📦 Archived: <path>` for a plan moved into `.claude/.tmp/plans-archive/`
260
+ - `📦 Archived: <path>` for a plan moved into `.claude/plans-archive/`
261
261
  - `⏭ Kept: <path>, still cited by <task-file>` for a plan another live task shares
262
262
  - `🧹 Deleted: <path>` for a swept review
263
263
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: claude-groundwork
3
- description: Opens and runs a numbered groundwork folder under `.claude/.tmp/groundwork/<slug>/` for a topic that has to be measured before it can be planned. Detects open, resume, and close from the folder itself. Use when asked to "research X", "dig into X", "work out what we should do about X", "measure this before we commit", or "open a groundwork folder". Do NOT use to write a feature plan or to implement. That is `claude-feature`.
3
+ description: Opens and runs a numbered groundwork folder under `.claude/groundwork/<slug>/` for a topic that has to be measured before it can be planned. Detects open, resume, and close from the folder itself. Use when asked to "research X", "dig into X", "work out what we should do about X", "measure this before we commit", or "open a groundwork folder". Do NOT use to write a feature plan or to implement. That is `claude-feature`.
4
4
  ---
5
5
 
6
6
  # Claude groundwork
@@ -18,9 +18,9 @@ Read `${CLAUDE_SKILL_DIR}/references/folder-format.md` before writing any file i
18
18
 
19
19
  ## Write scope
20
20
 
21
- - Write only inside `.claude/.tmp/groundwork/<slug>/`. A feature plan, source changes, a standard, a rule, and a reference doc all live outside that folder, so this one rule forbids every one of them.
21
+ - Write only inside `.claude/groundwork/<slug>/`. A feature plan, source changes, a standard, a rule, and a reference doc all live outside that folder, so this one rule forbids every one of them.
22
22
  - One exception, at close only: write one task file recording what the track concluded.
23
- - A second exception, for experiments: write a fixture a spike needs under `.claude/.tmp/groundwork-fixtures/<slug>/`. Keep it out of `.claude/.tmp/groundwork/` so mode detection never matches a fixture as a track. A fixture a headless run is pointed at goes outside the repository instead, per the rule in `## Running a spike`.
23
+ - A second exception, for experiments: write a fixture a spike needs under `.claude/.tmp/groundwork-fixtures/<slug>/`. Keep it out of `.claude/groundwork/` so mode detection never matches a fixture as a track. A fixture a headless run is pointed at goes outside the repository instead, per the rule in `## Running a spike`.
24
24
  - Reading is not restricted. External research is in scope, so read documentation, comparable projects, and papers whenever a live question needs them.
25
25
  - Every claim about a source outside the project carries a link to it. A source found and not read is listed as a lead and is never cited.
26
26
  - Treat the folder as gitignored and unbacked. It dies with the machine, so `07-next-session.md` repeats what it needs instead of pointing at its siblings.
@@ -39,11 +39,11 @@ Record method, result, measured cost, and caveats in `08-spikes.md`. Reach for a
39
39
 
40
40
  ## Step 1: detect the mode
41
41
 
42
- List `.claude/.tmp/groundwork/` from the project root and match the topic against the tracks already there before deriving anything. A resume pass rarely phrases the topic the way the folder was named, so a fresh slug derived from the wording would miss a live track and restart it.
42
+ List `.claude/groundwork/` from the project root and match the topic against the tracks already there before deriving anything. A resume pass rarely phrases the topic the way the folder was named, so a fresh slug derived from the wording would miss a live track and restart it.
43
43
 
44
- Never match against `.claude/.tmp/` itself. That directory is scratch shared with every other skill, so a topic matched there lands on a folder that was never a track.
44
+ Never match against `.claude/` itself. That directory holds every other workflow surface, so a topic matched there lands on a folder that was never a track.
45
45
 
46
- With no match, derive a kebab-case slug named for the subject rather than the activity. Prefer `ts-migration` over `migration-research`. Then route on `.claude/.tmp/groundwork/<slug>/`:
46
+ With no match, derive a kebab-case slug named for the subject rather than the activity. Prefer `ts-migration` over `migration-research`. Then route on `.claude/groundwork/<slug>/`:
47
47
 
48
48
  - Folder absent: open
49
49
  - Folder present without `06-decision.md`: resume
@@ -80,7 +80,7 @@ Every open question carries a lean, wherever it appears: inside a topic file, in
80
80
 
81
81
  ## Open mode
82
82
 
83
- 1. Create `.claude/.tmp/groundwork/<slug>/`.
83
+ 1. Create `.claude/groundwork/<slug>/`.
84
84
  2. Write `README.md` first. Writing it first forces the question of what the track is for.
85
85
  3. Write `01-current-state.md` by measuring now. Never carry a figure from a previous session or from recall without re-measuring it. Measure only what an open question in the folder needs. A number with no question attached is how groundwork turns into the work.
86
86
  4. Write `00-scope.md` when the track is large enough to run away. Skip it on a small track.
@@ -111,12 +111,12 @@ Emit the full relative path from the project root for every file written or upda
111
111
  Open and resume:
112
112
 
113
113
  ```plaintext
114
- 📂 Opened .claude/.tmp/groundwork/<slug>/
114
+ 📂 Opened .claude/groundwork/<slug>/
115
115
 
116
116
  **Written:**
117
117
 
118
- - `.claude/.tmp/groundwork/<slug>/README.md`
119
- - `.claude/.tmp/groundwork/<slug>/01-current-state.md`
118
+ - `.claude/groundwork/<slug>/README.md`
119
+ - `.claude/groundwork/<slug>/01-current-state.md`
120
120
 
121
121
  **Open questions:**
122
122
 
@@ -130,12 +130,12 @@ Use `📂 Resumed` in place of `📂 Opened` on a resume pass.
130
130
  Close:
131
131
 
132
132
  ```plaintext
133
- ✅ Closed .claude/.tmp/groundwork/<slug>/
133
+ ✅ Closed .claude/groundwork/<slug>/
134
134
 
135
135
  **Written:**
136
136
 
137
- - `.claude/.tmp/groundwork/<slug>/06-decision.md`
138
- - `.claude/.tmp/groundwork/<slug>/07-next-session.md`
137
+ - `.claude/groundwork/<slug>/06-decision.md`
138
+ - `.claude/groundwork/<slug>/07-next-session.md`
139
139
 
140
140
  **Uncited external claims:** <count, or none>
141
141
 
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: Groundwork folder reference
3
- description: Reserved file numbers, required file contents, and anti-patterns for a .claude/.tmp/groundwork/ folder
3
+ description: Reserved file numbers, required file contents, and anti-patterns for a .claude/groundwork/ folder
4
4
  ---
5
5
 
6
6
  # Groundwork folder reference
7
7
 
8
- Applies to a groundwork folder at `.claude/.tmp/groundwork/<slug>/`. The numbering is the table of contents: a reader opens the folder and knows where to start and what follows, with no index maintained inside each file. Protect that first, because the instinct when adding a file mid-track is to name it for its topic instead.
8
+ Applies to a groundwork folder at `.claude/groundwork/<slug>/`. The numbering is the table of contents: a reader opens the folder and knows where to start and what follows, with no index maintained inside each file. Protect that first, because the instinct when adding a file mid-track is to name it for its topic instead.
9
9
 
10
10
  The folder is gitignored and unbacked. It dies with the machine, which is why the handoff file has to be self-contained.
11
11
 
@@ -146,7 +146,7 @@ Promoting, demoting, and archiving a row all write `.claude/tasks/priority.md`,
146
146
  - Edit the file with the file-editing tool. A shell stream editor and an inline string replace both exit clean on a non-match, so a promotion that matched nothing leaves the board wrong with nothing reporting it, and the file-editing tool errors instead.
147
147
  - Put a pointer in the Plan column, never prose. `## Run now` claims a written plan covers every open outcome, and `claude-autoship` refuses at its guard when it follows the column and finds no plan, which spends a worker dispatch to learn what the row should have said.
148
148
  - Name the file set in the Touches column. The disjointness call in step 6 is only checkable later when the sets are written down rather than reasoned once and discarded.
149
- - Re-resolve every Plan pointer after anything archives a plan. `claude-docs` moves a plan to `.claude/.tmp/plans-archive/` and rewrites the citation in the task file alone, so a row for a task still on the board keeps pointing into `.claude/plans/` at a file that has moved. Workers running the ship chain on their own branches archive plans this board still cites, and the board reads as correct until a pointer is followed.
149
+ - Re-resolve every Plan pointer after anything archives a plan. `claude-docs` moves a plan to `.claude/plans-archive/` and rewrites the citation in the task file alone, so a row for a task still on the board keeps pointing into `.claude/plans/` at a file that has moved. Workers running the ship chain on their own branches archive plans this board still cites, and the board reads as correct until a pointer is followed.
150
150
  - Read the file back after writing it, since the row that lands is the row a worker acts on.
151
151
 
152
152
  ## Parallelism
@@ -44,7 +44,7 @@ Write it immediately. Claude Code's tool permission dialog is the confirmation g
44
44
 
45
45
  ### Step 4: report unlinked origins
46
46
 
47
- Scan for work that has been decided and would otherwise be forgotten. List `.claude/.tmp/groundwork/` and run `gh issue list --state open` when a remote is configured, then grep the board for each track name and issue number. Report any with no task, one line each.
47
+ Scan for work that has been decided and would otherwise be forgotten. List `.claude/groundwork/` and run `gh issue list --state open` when a remote is configured, then grep the board for each track name and issue number. Report any with no task, one line each.
48
48
 
49
49
  Report rather than prompt. A track can be opened long after its task would have been written, so an offer to create one for each is noise on most runs.
50
50
 
@@ -106,7 +106,7 @@ Create:
106
106
 
107
107
  **Origin with no task:**
108
108
 
109
- - `.claude/.tmp/groundwork/<slug>/`: open, touched <date>
109
+ - `.claude/groundwork/<slug>/`: open, touched <date>
110
110
  - #NNN: <issue title>
111
111
  ```
112
112
 
@@ -115,7 +115,7 @@ Omit the origin block when everything is linked.
115
115
  Archive, reporting the paths the command returned:
116
116
 
117
117
  ```plaintext
118
- 📦 Archived: .claude/.tmp/task-archive/vXX.Y-<slug>.md
118
+ 📦 Archived: .claude/task-archive/vXX.Y-<slug>.md
119
119
 
120
120
  <ordering and index disposition in one line>
121
121
  ```
@@ -7,7 +7,7 @@ description: What the follow-up push is for, the gaps it closes, and how it spli
7
7
 
8
8
  ## Gap
9
9
 
10
- Without this skill, an edit made after a pull request is already open ships as a bare push. The body still describes the scope from before the edit, so a reviewer returning to the page reads a description the diff no longer matches. A reviewer who left comments gets no reply, and when a caller has already posted its own reply, a second one lands underneath it.
10
+ Without this skill, an edit made after a pull request is already open ships as a bare push. The body still describes the scope from before the edit, so a reviewer returning to the page reads a description the diff no longer matches. A reviewer who left comments gets no reply, and when a caller has already posted its own reply, a second one lands underneath it. A caller that rebased the branch before handing over hits a rejected push, since the tracking branch no longer reaches the head.
11
11
 
12
12
  ## Must
13
13
 
@@ -16,6 +16,7 @@ Without this skill, an edit made after a pull request is already open ships as a
16
16
  - Sync the body when the new commit moves the scope, and the title when the shift makes it inaccurate
17
17
  - Reply on the pull request when it carries review comments, and scan that reply for the banned characters and internal phase labels before posting. The hook watches files and never sees a comment body on its way to the remote.
18
18
  - Suppress the reply when the caller owns it, and still run the push and the body sync
19
+ - Force the push under a lease when the tracking branch no longer reaches the head, so a caller's rebase lands and a commit this session never read is not overwritten
19
20
 
20
21
  ## Must not
21
22
 
@@ -22,7 +22,7 @@ its own reply, so skip the comment in step 6. The push and body sync still run.
22
22
  1. Run `git status` to confirm the changes are intentional
23
23
  2. Run `git add -A` to stage every change
24
24
  3. Invoke `aitk:git-commit` to generate one conventional commit from the staged diff
25
- 4. Run `git push` to the tracking branch
25
+ 4. Run `git push` to the tracking branch. When `git merge-base --is-ancestor @{u} HEAD` exits non-zero, a caller rewrote the branch and a plain push is rejected, so push with `--force-with-lease` instead. The lease is what stops the force from overwriting a commit this session never read.
26
26
  5. Check for existing review comments: `gh api 'repos/{owner}/{repo}/pulls/<number>/comments' --jq 'length'`, resolving `<number>` from `gh pr view --json number`.
27
27
  6. When invoked with `reply-owned`, skip this step's comment: the caller posts the reply. Otherwise, if the count is above zero, the followup addresses review feedback: post a one-line summary of the fix with `gh pr comment --body`, first running the scan in `.claude/standards/publish.md` against it, or `${CLAUDE_SKILL_DIR}/../../standards/publish.md` when the project does not have it, since the hook does not see an inline comment body. If it is zero, run `gh pr view --json url,title,body` and update the body with `gh pr edit --body` when the new commit changes scope, and the title with `gh pr edit --title` when the scope shifted enough to make it inaccurate.
28
28
 
@@ -7,7 +7,7 @@ description: Selecting a shipped task by stem or pull request, the refusal reaso
7
7
 
8
8
  ## Archive
9
9
 
10
- `aitk tasks archive` moves a shipped task from `.claude/tasks/` into `.claude/.tmp/task-archive/`, drops its row from `priority.md`, and regenerates the board index. The three run as one unit, so the attended and unattended callers cannot archive differently.
10
+ `aitk tasks archive` moves a shipped task from `.claude/tasks/` into `.claude/task-archive/`, drops its row from `priority.md`, and regenerates the board index. The three run as one unit, so the attended and unattended callers cannot archive differently.
11
11
 
12
12
  Name the task by its filename stem, or by the pull request it carries:
13
13
 
@@ -44,7 +44,7 @@ One session works for most features. Prefer splitting across two sessions only w
44
44
 
45
45
  Work in Claude Code directly. It reads `CLAUDE.md` automatically and has full file access, no pasting needed.
46
46
 
47
- - When the current state is unmeasured and more than one approach is live, invoke `aitk:claude-groundwork` first. It opens a scratch folder under `.claude/.tmp/groundwork/<slug>/` and ends in a decision, which may be to do nothing. Skip it when the approach is already settled. A track may run experiments to settle a question, writing a fixture it reads itself under `.claude/.tmp/groundwork-fixtures/<slug>/` and spawning up to three billed headless runs before it asks. A fixture a headless run is pointed at sits outside the repository, since a session started under the project root inherits that project's `CLAUDE.md` and rules and would measure them instead of the arm.
47
+ - When the current state is unmeasured and more than one approach is live, invoke `aitk:claude-groundwork` first. It opens a track folder under `.claude/groundwork/<slug>/` and ends in a decision, which may be to do nothing. Skip it when the approach is already settled. A track may run experiments to settle a question, writing a fixture it reads itself under `.claude/.tmp/groundwork-fixtures/<slug>/` and spawning up to three billed headless runs before it asks. A fixture a headless run is pointed at sits outside the repository, since a session started under the project root inherits that project's `CLAUDE.md` and rules and would measure them instead of the arm.
48
48
  - Invoke `aitk:claude-feature` to scan for code-level conflicts and ambiguities, confirm approach before proceeding
49
49
  - Implement the feature, then Claude Code runs the commands defined in `CLAUDE.md`, fixes failures, and iterates until all pass
50
50
  - For UI changes, invoke `aitk:claude-ui-test` to generate and run Playwright e2e tests
@@ -78,7 +78,7 @@ Before a handoff, the orchestrator checks the plan against the tree rather than
78
78
 
79
79
  `.claude/plans/`, `.claude/review/`, and `.claude/memory/` all resolve at the main worktree root, so artifacts created in any session are visible from any sibling worktree. See [Claude Code and git worktrees](../wiki/claude-worktrees.md) for the full rule and the domain-level fan-out guidance.
80
80
 
81
- A plan that ships is archived, never deleted. `aitk:claude-docs` moves it to `.claude/.tmp/plans-archive/` and retargets the task file's `Plan:` line at the new location, so a completed task still leads to the reasoning behind it. Both folders are gitignored, which is why a deleted plan had no recovery path. A plan cited by more than one task stays put until the last of them closes, since moving it early would strand every other pointer.
81
+ A plan that ships is archived, never deleted. `aitk:claude-docs` moves it to `.claude/plans-archive/` and retargets the task file's `Plan:` line at the new location, so a completed task still leads to the reasoning behind it. Both folders are gitignored, which is why a deleted plan had no recovery path. A plan cited by more than one task stays put until the last of them closes, since moving it early would strand every other pointer.
82
82
 
83
83
  The sweep reads the whole board rather than the tasks the session touched. It is the one place the skill reaches past its own rule against editing a task file the session did not change, because a task that closed while an earlier run missed its archive is exactly what the sweep exists to clear. Reaching it is safe: the archive moves the plan and retargets the pointer in the same pass, so an untouched task ends up with a working link rather than a broken one.
84
84
 
@@ -88,7 +88,7 @@ The sweep reads the whole board rather than the tasks the session touched. It is
88
88
 
89
89
  `aitk tasks validate` checks what those rows claim against what the tree holds: every plan pointer resolves, every row and task file map one to one, no task sits in two groups, and no two rows marked ready touch the same file. That last check is the half a reader cannot run by eye, and it is what keeps two workers from being handed colliding work. It reports and never writes, because a row is the orchestrator's claim and a validator repairing one would assert the claim it exists to test. Nothing fires it automatically, since the board is gitignored per-machine scratch with no shared moment to hang a hook on, so the orchestrator's sweep calls it at the point the readiness claim is made.
90
90
 
91
- `aitk:claude-tasks` owns the two operations that bracket a task's life. It creates the file, holding the filename convention and the frontmatter contract so a malformed write cannot break the index for every sibling, and it moves a shipped task to `.claude/.tmp/task-archive/`. Creation is where the origin invariant is enforced: every task names a plan, a groundwork folder, an intake folder, or an issue, since a task with no origin is either lost context or work nobody decided to do. Archiving a task leaves its plan alone, because `aitk:claude-docs` owns the plans sweep and already holds the last-live-citation rule. That makes the order load-bearing, so the archive verb refuses to run while the `Plan:` line still points into `.claude/plans/`. The sweep only reaches tasks still in the live folder, and archiving the task first would strand the plan there with nothing citing it.
91
+ `aitk:claude-tasks` owns the two operations that bracket a task's life. It creates the file, holding the filename convention and the frontmatter contract so a malformed write cannot break the index for every sibling, and it moves a shipped task to `.claude/task-archive/`. Creation is where the origin invariant is enforced: every task names a plan, a groundwork folder, an intake folder, or an issue, since a task with no origin is either lost context or work nobody decided to do. Archiving a task leaves its plan alone, because `aitk:claude-docs` owns the plans sweep and already holds the last-live-citation rule. That makes the order load-bearing, so the archive verb refuses to run while the `Plan:` line still points into `.claude/plans/`. The sweep only reaches tasks still in the live folder, and archiving the task first would strand the plan there with nothing citing it.
92
92
 
93
93
  Nothing chained that archive until the `post-merge` git hook landed. Every earlier step fires from `aitk:claude-autoship` or `aitk:git-ship`, both of which finish while the pull request is still open, so a task archived there would close for work that may be abandoned. The board is gitignored, which rules out reading it from anywhere but the machine that pulled. The hook names the board's archive candidates and stays silent otherwise, including on a project with no board.
94
94
 
@@ -131,7 +131,7 @@ Before the first feature session on a UI-heavy project, pick a design tier. The
131
131
 
132
132
  | Skill | When to use |
133
133
  | ---------------------------- | -------------------------------------------------------------------------------------------------------------------- |
134
- | `aitk:claude-groundwork` | Before a plan is warranted, measure an unknown in a scratch folder under `.claude/.tmp/groundwork/` |
134
+ | `aitk:claude-groundwork` | Before a plan is warranted, measure an unknown in a track folder under `.claude/groundwork/` |
135
135
  | `aitk:claude-feature` | Before implementation, scan for conflicts and ambiguities |
136
136
  | `aitk:claude-roadmap` | Sequence MVP scope into ordered versions in `.claude/ROADMAP.md` |
137
137
  | `aitk:claude-orchestrate` | Assert the orchestrator role, refill the ready queue, and dispatch the feature, review, and worktree skills |
@@ -139,7 +139,7 @@ Before the first feature session on a UI-heavy project, pick a design tier. The
139
139
  | `aitk:claude-design-extract` | Draft `.claude/DESIGN.md`, sourcing tokens from existing UI code or proposing them from requirements on day one |
140
140
  | `aitk:claude-review` | In a fresh session, review all changes since main |
141
141
  | `aitk:claude-pr-review` | Review an open PR from an independent session, then re-review the commits added since until nothing is open |
142
- | `aitk:claude-address-review` | Address PR findings and CI status, refresh stale docs, then push a follow-up |
142
+ | `aitk:claude-address-review` | Address PR findings and CI status, refresh stale docs, rebase a branch that stopped merging, then push a follow-up |
143
143
  | `aitk:claude-tasks` | Add a task to `.claude/tasks/` or archive a shipped one out of the folder |
144
144
  | `aitk:claude-docs` | When decisions diverged from plan, update `.claude/` docs |
145
145
  | `aitk:claude-ui-test` | After UI changes, generate and run e2e tests + visual checklist |
@@ -33,9 +33,9 @@ One feature travels this path end to end.
33
33
  2. Orchestrator plans the next feature with `claude-feature`, writing a plan to `.claude/plans/`. Planning stays in the warm session because good planning is cross-feature. It needs the contract other features consume and the shared wiring seam. A cold session would re-derive or guess.
34
34
  3. The human opens a worker worktree with `claude-worktree` and runs `claude-autoship` against the plan. The worker builds, self-checks, opens a PR, and stops at the PR boundary.
35
35
  4. Orchestrator reviews the PR with `claude-pr-review` and posts findings to it.
36
- 5. Worker addresses the findings with `claude-address-review`, then pushes a follow-up.
36
+ 5. Worker addresses the findings with `claude-address-review`, rebases onto `origin/main` when a sibling landed first and left the branch unable to merge, then pushes a follow-up.
37
37
  6. Orchestrator closes the review out with `claude-pr-review` again. The second pass reads only the commits the follow-up added, and posts under `## Review closed` when it finds nothing open or under `## Review` when it does, so a reader learns the state from the heading. Repeat from step 5 until the review closes.
38
- 7. The human reads the result and merges. The orchestrator tells any trailing worker to rebase when its branch shares a seam with the merged one.
38
+ 7. The human reads the result and merges. The orchestrator tells any trailing worker whose branch shares a seam with the merged one to run `claude-address-review`, which rebases whether or not the review left anything open.
39
39
 
40
40
  There is no loop construct here. Each worker is a single build that halts at the
41
41
  PR. The merge stays a manual human gate. Reliability comes from the plan being
@@ -61,6 +61,14 @@ the PR. `claude-address-review` reads them back, fixes each, replies or resolves
61
61
  the threads, and pushes a follow-up. `claude-pr-review` then runs again, reading
62
62
  only what the follow-up added.
63
63
 
64
+ A branch that stopped merging while the review was open is the worker's problem
65
+ to close. `claude-address-review` rebases onto `origin/main` between the fixes
66
+ and the push, so one force-push carries both and the reviewer reads one delta.
67
+ The staleness test sits ahead of the no-findings guard, so a branch whose review
68
+ closed clean and then went stale still rebases when the skill is invoked. The
69
+ re-read costs a full pass rather than a delta, since the prior reviewed commit no
70
+ longer reaches the head, and `claude-pr-review` detects that itself.
71
+
64
72
  The heading carries the state rather than the pass number. A pass with a finding
65
73
  takes `## Review` and a pass with none takes `## Review closed`, so a thread can
66
74
  be scanned for what is still open without opening a comment. The feedback
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@erclx/aitk",
3
3
  "type": "module",
4
- "version": "0.47.0",
4
+ "version": "0.49.0",
5
5
  "description": "Infrastructure and quality tooling for developer workflows",
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -4,7 +4,7 @@ import { join, relative, resolve, sep } from 'node:path'
4
4
  import { regenOne } from '@/indexes/regen'
5
5
 
6
6
  const TASKS_DIR = join('.claude', 'tasks')
7
- const ARCHIVE_DIR = join('.claude', '.tmp', 'task-archive')
7
+ const ARCHIVE_DIR = join('.claude', 'task-archive')
8
8
  const PLANS_DIR = join('.claude', 'plans')
9
9
 
10
10
  /**
@@ -124,7 +124,7 @@ description: One line on what this task achieves
124
124
  # vX.Y: Title
125
125
 
126
126
  Plan: [feature-<slug>](../plans/feature-<slug>.md)
127
- Groundwork: [<slug>](../.tmp/groundwork/<slug>/)
127
+ Groundwork: [<slug>](../groundwork/<slug>/)
128
128
  Intake: [<slug>](../intake/<slug>/)
129
129
  Issue: #NNN
130
130
  Pull request: #NNN
@@ -149,13 +149,13 @@ Every task names where it came from, through a `Plan:`, `Groundwork:`, `Intake:`
149
149
 
150
150
  A task with no origin is either lost context or work nobody decided to do. The invariant runs both ways, and the second direction is the one that bites: a groundwork track or an open issue that no task points at is work already decided and on its way to being forgotten. An intake folder is exempt from that direction, since it dispositions many items at once and most of them close without ever becoming a task.
151
151
 
152
- `Plan:`, `Groundwork:`, and `Intake:` name their target as a markdown link whose text is the file or folder stem, so the line resolves on a ctrl-click the way `priority.md` rows already do. Write the path relative to `.claude/tasks/`, which makes it `../plans/`, `../.tmp/groundwork/`, and `../intake/`. A path written from the project root renders as a link and resolves to nothing in an editor rooted at the project. `Issue:` stays a bare `#NNN`, since an issue number is not a path and a full URL would write the remote into a gitignored file.
152
+ `Plan:`, `Groundwork:`, and `Intake:` name their target as a markdown link whose text is the file or folder stem, so the line resolves on a ctrl-click the way `priority.md` rows already do. Write the path relative to `.claude/tasks/`, which makes it `../plans/`, `../groundwork/`, and `../intake/`. A path written from the project root renders as a link and resolves to nothing in an editor rooted at the project. `Issue:` stays a bare `#NNN`, since an issue number is not a path and a full URL would write the remote into a gitignored file.
153
153
 
154
154
  Phase-label format and where labels may appear are governed by `standards/versioning.md`.
155
155
 
156
- `Plan:` points at `../plans/feature-<slug>.md` while the task is open. Once the task ships and the plan is archived, it points at `../.tmp/plans-archive/feature-<slug>.md`. Retarget both halves of the link rather than dropping it, so a completed task still leads to the reasoning behind it. One plan per task. A plan cited by two tasks is a misfile rather than a shape to design for, which is why the sweep counts citations before archiving: the count is a guard against the misfile stranding a pointer, not support for the shape.
156
+ `Plan:` points at `../plans/feature-<slug>.md` while the task is open. Once the task ships and the plan is archived, it points at `../plans-archive/feature-<slug>.md`. Retarget both halves of the link rather than dropping it, so a completed task still leads to the reasoning behind it. A project that archived plans before the folder moved out of `.claude/.tmp/` holds closed tasks pointing at `../.tmp/plans-archive/`, and both forms resolve against the files each names, so leave those pointers where they are. Nothing migrates them, and a task retargeted without its plan moving leads nowhere. One plan per task. A plan cited by two tasks is a misfile rather than a shape to design for, which is why the sweep counts citations before archiving: the count is a guard against the misfile stranding a pointer, not support for the shape.
157
157
 
158
- `Groundwork:` points at `../.tmp/groundwork/<slug>/`, the folder `claude-groundwork` fills. It names the surface it points at the way `Plan:` does. Use this key alone. `Research record` and `Decision record` are earlier spellings of the same thing and both convert to it.
158
+ `Groundwork:` points at `../groundwork/<slug>/`, the folder `claude-groundwork` fills. It names the surface it points at the way `Plan:` does. Use this key alone. `Research record` and `Decision record` are earlier spellings of the same thing and both convert to it.
159
159
 
160
160
  `Intake:` points at `../intake/<slug>/`, the folder an intake pass fills. Use it rather than `Groundwork:`, because a groundwork track measures one question in depth while an intake dispositions many across a tree, and one key covering both loses which kind of pass produced the task. The line names the folder rather than an item inside it. A task routinely promotes several items at once, so an anchored line would name one and drop the rest, and the item numbers belong in that task's `## Findings`.
161
161
 
@@ -180,11 +180,11 @@ The line is what lets a merge close its own task. Every merge on `main` is a squ
180
180
 
181
181
  ## Archiving
182
182
 
183
- Never delete a task file. A shipped task moves to `.claude/.tmp/task-archive/` under its own name, and the live index regenerates without it. `aitk tasks archive` owns the move, the ordering-row removal, and the index regen as one unit.
183
+ Never delete a task file. A shipped task moves to `.claude/task-archive/` under its own name, and the live index regenerates without it. `aitk tasks archive` owns the move, the ordering-row removal, and the index regen as one unit.
184
184
 
185
185
  Two callers reach that command. The `claude-tasks` skill runs it inside a session, and the `post-merge` hook runs it unattended after a pull that merged the work. Both go through the command rather than moving the file themselves, so the two paths cannot drift into archiving differently. Every gate the command applies refuses with a non-zero exit rather than reporting, because a caller with nobody watching cannot act on a warning.
186
186
 
187
- One destination rather than a per-project choice is what lets the move happen without asking. It mirrors the plans archive at `.claude/.tmp/plans-archive/` and stays gitignored, so an archived task does not start appearing in diffs. The cost is that scratch is unbacked, which is the same cost the plans archive already carries.
187
+ One destination rather than a per-project choice is what lets the move happen without asking. It mirrors the plans archive at `.claude/plans-archive/` and stays gitignored, so an archived task does not start appearing in diffs. The cost is that the folder is unbacked, which is the same cost the plans archive already carries.
188
188
 
189
189
  Archiving a task does not archive its plan. `claude-docs` owns the plans sweep and moves a plan only when the closing task is its last live citation. The archive clears the task's row from `priority.md` itself, since a shipped task left in the ordering reads as ready to hand a worker. It leaves prose naming the task alone for a person to resolve.
190
190
 
@@ -8,4 +8,4 @@ runtime = ""
8
8
  scaffold = ""
9
9
 
10
10
  [gitignore]
11
- "# Claude" = [".claude/.tmp/", ".claude/intake/", ".claude/memory/", ".claude/plans/", ".claude/review/", ".claude/worktrees/", ".claude/tasks/"]
11
+ "# Claude" = [".claude/.tmp/", ".claude/groundwork/", ".claude/intake/", ".claude/memory/", ".claude/plans/", ".claude/plans-archive/", ".claude/review/", ".claude/task-archive/", ".claude/worktrees/", ".claude/tasks/"]
@@ -49,7 +49,7 @@ A project installed before the diagram surface became a folder still holds `.cla
49
49
 
50
50
  ## Gitignore
51
51
 
52
- - `# Claude`: `.claude/.tmp/`, `.claude/intake/`, `.claude/memory/`, `.claude/plans/`, `.claude/review/`, `.claude/worktrees/`, `.claude/tasks/`
52
+ - `# Claude`: `.claude/.tmp/`, `.claude/groundwork/`, `.claude/intake/`, `.claude/memory/`, `.claude/plans/`, `.claude/plans-archive/`, `.claude/review/`, `.claude/task-archive/`, `.claude/worktrees/`, `.claude/tasks/`
53
53
 
54
54
  ## CLI
55
55
 
@@ -66,7 +66,7 @@
66
66
  - `.claude/tasks/` is gitignored local session scratch, one file per task. Edit freely. No staging or revert before commits.
67
67
  - Only create a task for work that spans multiple sessions or has real dependencies. Handle small edits immediately without a task entry.
68
68
  - Do not add tasks retroactively for work already completed. Completed work is visible in git.
69
- - When a task needs execution detail beyond its own file, create a plan in `.claude/plans/` and link to it from the task's intro paragraph. When that task ships, move its plan file to `.claude/.tmp/plans-archive/`. Never delete it.
69
+ - When a task needs execution detail beyond its own file, create a plan in `.claude/plans/` and link to it from the task's intro paragraph. When that task ships, move its plan file to `.claude/plans-archive/`. Never delete it.
70
70
  - Write the plan in the same session as the task file. The session that executes the plan later inherits reasoning context it would otherwise have to re-derive.
71
71
 
72
72
  ## Memory