@erclx/aitk 0.48.0 โ†’ 0.50.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.48.0",
4
+ "version": "0.50.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -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: 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 |
@@ -18,7 +18,7 @@ The default. `.claude/DESIGN.md` holds visual intent as prose plus token tables
18
18
 
19
19
  ### Seed shape
20
20
 
21
- The toolkit seed in `tooling/claude/seeds/.claude/DESIGN.md` ships a token-table template. The `aitk:claude-design-extract` skill drafts the file, sourcing tokens from a project's existing prose and CLI UI surfaces, or proposing them from `.claude/REQUIREMENTS.md` and a `## Personality` paragraph when no UI code exists yet. `aitk design render` writes an HTML plus CSS preview to `.claude/review/design/` for eyeballing the current system without leaving Claude Code. See `.claude/context/design.md`.
21
+ The toolkit seed in `tooling/claude/seeds/.claude/DESIGN.md` ships a token-table template with a starting set of roles, and `.claude/standards/design.md` carries the same tables under `## Template` with placeholder rows. The column headers are what the renderer parses, so they stay verbatim in either, while the rows and values are the project's own. The `aitk:claude-design-extract` skill drafts the file, sourcing tokens from a project's existing prose and CLI UI surfaces, or proposing them from `.claude/REQUIREMENTS.md` and a `## Personality` paragraph when no UI code exists yet. `aitk design render` writes an HTML plus CSS preview to `.claude/review/design/` for eyeballing the current system without leaving Claude Code. See `.claude/context/design.md`.
22
22
 
23
23
  ### Tools
24
24
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@erclx/aitk",
3
3
  "type": "module",
4
- "version": "0.48.0",
4
+ "version": "0.50.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
  /**
@@ -37,3 +37,47 @@ Does not govern:
37
37
  ## Sections
38
38
 
39
39
  Use `## Personality`, `## Color`, `## Typography`, `## Spacing`, `## Borders`, `## Motion`, and `## Iconography`. The token tables carry fixed headers the renderer reads.
40
+
41
+ ## Template
42
+
43
+ The column headers are the strings the renderer parses, read by exact key, so they stay verbatim. Row names are not. Each is slugged into the variable name it emits, which leaves a project free to rename a row, add one, or drop one it has no use for.
44
+
45
+ ```markdown
46
+ # Design
47
+
48
+ ## Personality
49
+
50
+ <one paragraph on voice, tone, and the feeling a user should have>
51
+
52
+ ## Color
53
+
54
+ | Role | Intent | Value |
55
+ | ------ | ---------------- | ------- |
56
+ | <role> | <what it is for> | <value> |
57
+
58
+ ## Typography
59
+
60
+ | Role | Family | Weight | Size | Line height |
61
+ | ------ | -------- | -------- | ------ | ----------- |
62
+ | <role> | <family> | <weight> | <size> | <height> |
63
+
64
+ ## Spacing
65
+
66
+ | Step | Multiplier | Value |
67
+ | ------ | ------------ | ------- |
68
+ | <step> | <multiplier> | <value> |
69
+
70
+ ## Borders
71
+
72
+ | Role | Radius | Width | When used |
73
+ | ------ | -------- | ------- | ----------- |
74
+ | <role> | <radius> | <width> | <when used> |
75
+
76
+ ## Motion
77
+
78
+ <whether motion is used at all, and if so the default duration and easing>
79
+
80
+ ## Iconography
81
+
82
+ <style, source library, and whether custom icons are allowed>
83
+ ```
@@ -122,3 +122,31 @@ Reference the context entry by path when a reader needs the mechanism. The diagr
122
122
  - That watch samples thinly. It sees the one or two paths an entry happened to cite and nothing else, so a change elsewhere leaves the entry looking current. `verified` is what covers the gap, and an entry whose date sits far behind the branch is due a read whether or not anything flagged it.
123
123
  - The explanation paragraphs around a Mermaid block are prose and follow `prose.md`. The fenced block itself is not, which is why a check scoped to prose is the wrong thing to rely on for what sits inside it.
124
124
  - The punctuation bans still apply to node and subgraph labels, and nothing checks them there. An em dash in a label passes every gate the repository has, so read the labels before shipping the entry.
125
+
126
+ ## Template
127
+
128
+ The filename and the `category` value both come from Entry kinds and are fixed per kind. A stub nobody has drawn yet carries `TODO: never verified` in place of the SHA and date. The node names and labels inside the fence are placeholders, written bare because Mermaid reads an angle bracket as markup.
129
+
130
+ ````markdown
131
+ ---
132
+ title: <what the entry answers>
133
+ description: <which question it settles and which source signal drives it>
134
+ category: <the kind, verbatim from Entry kinds>
135
+ verified: <short-sha> <YYYY-MM-DD>
136
+ ---
137
+
138
+ # <what the entry answers>
139
+
140
+ ```mermaid
141
+ flowchart TB
142
+ accTitle: what the diagram answers
143
+ accDescr: the structure in one sentence for a reader who cannot see the render
144
+
145
+ a[first part] --> b[second part]
146
+ b --> c[third part]
147
+ ```
148
+
149
+ <One paragraph leading with what the diagram shows.>
150
+
151
+ <One paragraph on why this shape was chosen and what was rejected, where the choice was non-obvious. Name one or two code paths the reader can open.>
152
+ ````
@@ -7,7 +7,7 @@ description: Scan run against finished text leaving through a channel no automat
7
7
 
8
8
  ## Scope
9
9
 
10
- Governs the scan an author runs against finished text on its way out, and the responses available when a source it reaches for cannot be read. It is an attribute standard rather than a document-type one, so it applies to any text leaving through a channel no automated check covers.
10
+ Governs the scan an author runs against finished text on its way out, and the responses available when a source it reaches for cannot be read. It is an attribute standard rather than a document-type one, so it applies to any text leaving through a channel no automated check covers, and it carries no template because a scan has no document to shape.
11
11
 
12
12
  Does not govern:
13
13
 
package/standards/slug.md CHANGED
@@ -7,7 +7,7 @@ description: Transform from a git branch name to a slug, and the three responses
7
7
 
8
8
  ## Scope
9
9
 
10
- Governs the transform from a git branch name to the slug a surface carries in a derived name, and the responses available when the transform returns empty. It is an attribute standard rather than a document-type one, so it applies wherever a branch-derived name is produced.
10
+ Governs the transform from a git branch name to the slug a surface carries in a derived name, and the responses available when the transform returns empty. It is an attribute standard rather than a document-type one, so it applies wherever a branch-derived name is produced, and it carries no template because a string has no document to shape.
11
11
 
12
12
  Does not govern:
13
13
 
@@ -91,3 +91,60 @@ A standard failing these questions is non-conforming even when it satisfies ever
91
91
  - When shown, label them `### Correct` and `### Incorrect` with an inline `# reason` on each entry
92
92
  - Keep to two or three entries. Show the pattern, not a catalog.
93
93
  - Keep each entry a short one-liner or command. Do not write multi-line correct and incorrect function blocks.
94
+
95
+ ## Template
96
+
97
+ - Carry one fenced template of the document the standard governs, so an author copies a shape instead of reconstructing it from prose.
98
+ - Bind this to a standard governing a document type. An attribute standard governs a scan, a string, or a label rather than a file, so it has no document to template and carries none.
99
+ - State that exemption in the sentence declaring the standard an attribute standard. An exemption left to inference reads as an omission, and the next author writes a template that teaches nothing.
100
+ - Place the template below the rules it satisfies, under a `## Template` heading or inside the section holding those rules. A reader arrives at it having already read what each part means.
101
+ - Show the skeleton alone: every required section, one placeholder line for what each holds. A full worked document is a second document to maintain.
102
+ - Write placeholders in angle brackets rather than copying a real document. A copied file goes stale, and its backticked filenames read as citations to anything parsing the standard.
103
+ - Switch to a bare word where the fenced language reads `<` as syntax of its own, as Mermaid and HTML do, and say in the line above the fence that the names are placeholders. A template that does not parse in its own language teaches a shape the author cannot run.
104
+ - Carry any header, key, or label a consuming tool parses verbatim. The template is the only place an author learns which strings are load-bearing, since prose calling them fixed does not say what they are.
105
+ - Treat the template as authoritative where it and the prose disagree. An author copies the block, so a contradiction ships as the block, and naming the winner turns a drift into a visible defect rather than a silent one.
106
+
107
+ ````markdown
108
+ ---
109
+ title: <Document type> reference
110
+ description: <one line naming what this standard covers>
111
+ ---
112
+
113
+ # <Document type> reference
114
+
115
+ Applies to `<path/to/document>`. <One line on what the document is for and when it changes.>
116
+
117
+ ## Scope
118
+
119
+ Governs `<path/to/document>`: <the aspects this standard sets>.
120
+
121
+ Does not govern:
122
+
123
+ - <excluded concern>: `<sibling>.md`
124
+ - <excluded concern>: <the surface that owns it>
125
+
126
+ ## What a working <document type> looks like
127
+
128
+ A <document type> works when <the task a reader completes from it alone>:
129
+
130
+ - <question the document must answer>
131
+ - <question the document must answer>
132
+
133
+ A <document type> failing these is non-conforming even when it satisfies every shape rule below.
134
+
135
+ ## Frontmatter
136
+
137
+ - `title` (required): <casing, and what it names>
138
+ - `description` (required): <what the one line covers>
139
+
140
+ ## <Shape rule group>
141
+
142
+ - <imperative rule, one concern per bullet>
143
+ - <imperative rule, one concern per bullet>
144
+
145
+ ## Template
146
+
147
+ ```markdown
148
+ <the skeleton of the governed document, placeholders throughout>
149
+ ```
150
+ ````
@@ -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
 
@@ -9,7 +9,7 @@ Two namespaces, kept separate.
9
9
 
10
10
  ## Scope
11
11
 
12
- Governs the two version namespaces, phase labels and semver tags, and which surfaces each may appear on. It is an attribute standard rather than a document-type one, so it applies wherever either namespace is written.
12
+ Governs the two version namespaces, phase labels and semver tags, and which surfaces each may appear on. It is an attribute standard rather than a document-type one, so it applies wherever either namespace is written, and it carries no template because a label has no document to shape.
13
13
 
14
14
  Does not govern:
15
15
 
@@ -75,3 +75,38 @@ Reference the context entry from the wireframe by path when a reader needs the m
75
75
 
76
76
  - When a surface's layout or interaction changes, update its wireframe file in the same PR. A wireframe showing a defunct layout is worse than none.
77
77
  - The Behavior and Copy prose around an ASCII block is prose and follows `prose.md`. The fenced block itself is not, so a check scoped to prose is the wrong thing to rely on for what sits inside it.
78
+
79
+ ## Template
80
+
81
+ One H2 per layout variant, each holding its own fence. A surface with a single layout carries one.
82
+
83
+ ````markdown
84
+ ---
85
+ title: <Surface name>
86
+ description: <when and where the surface appears>
87
+ ---
88
+
89
+ # <Surface name>
90
+
91
+ ## <what triggers this variant>
92
+
93
+ ```plaintext
94
+ +------------------------------------------+
95
+ | <region> โ† <its role> |
96
+ +------------------------------------------+
97
+ | |
98
+ | <region> โ† <its role> |
99
+ | |
100
+ +------------------------------------------+
101
+ ```
102
+
103
+ ## Copy
104
+
105
+ - <on-screen text, word for word>
106
+ - <text the surface templates>: <marked so a reader does not read it as final>
107
+
108
+ ## Behavior
109
+
110
+ - <what the visitor does, and what changes on screen>
111
+ - <what each reachable state looks like>
112
+ ````
@@ -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