@erclx/aitk 0.66.1 → 0.68.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.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/claude-orchestrate/REQUIREMENT.md +3 -0
- package/claude/skills/claude-orchestrate/SKILL.md +4 -6
- package/claude/skills/claude-orchestrate/references/orchestrator-handoff.md +12 -7
- package/claude/skills/claude-worktree/REQUIREMENT.md +8 -5
- package/claude/skills/claude-worktree/SKILL.md +24 -4
- package/claude/skills/claude-worktree/references/branch.md +60 -0
- package/claude/skills/git-branch/references/branch.md +1 -1
- package/claude/skills/git-followup/REQUIREMENT.md +3 -3
- package/claude/skills/git-followup/SKILL.md +3 -2
- package/claude/skills/git-pr/references/branch.md +1 -1
- package/claude/skills/git-split/references/branch.md +1 -1
- package/claude/skills/project-commands/SKILL.md +13 -5
- package/docs/agents/commands.md +1 -1
- package/docs/agents/context-audit.md +5 -1
- package/docs/agents/index.md +1 -1
- package/docs/agents/install-and-sync.md +23 -0
- package/docs/agents/markdown-audit.md +26 -6
- package/docs/ai-workflow.md +1 -1
- package/docs/target-projects.md +5 -5
- package/package.json +1 -1
- package/scripts/core/verify.sh +34 -0
- package/src/commands/markdown.ts +27 -6
- package/src/commands/sync.ts +51 -6
- package/src/commands/tooling.ts +35 -0
- package/src/markdown/gate.ts +28 -0
- package/src/sync/check.ts +125 -8
- package/src/sync/stamp.ts +64 -4
- package/src/tooling/stamp.ts +44 -0
- package/standards/bundled/branch.md +1 -1
- package/standards/slug.md +4 -2
- package/tooling/astro/reference.md +1 -1
- package/tooling/base/reference.md +1 -1
- package/tooling/claude/seeds/CLAUDE.md +1 -1
- package/tooling/vite-react/reference.md +1 -1
- package/tooling/web/reference.md +1 -1
|
@@ -19,6 +19,8 @@ Output drifts everywhere the contract stops. The specified shape covers invocati
|
|
|
19
19
|
|
|
20
20
|
The runbooks the session cannot run from memory fail on a third axis, which is where they are kept. A runbook reached by an installed path is a dependency on a channel this skill does not travel on, so a project holding the plugin and running no install follows the citation to nothing, and nothing reports the break because a missing file produces no error until someone opens the path. Every one of them therefore has to ship inside the skill, the three covering the moments the loop cannot detect and the fourth holding the review trigger. That fourth one fails on an axis of its own, since it names one client's command as the way to start the loop, so a session holding a different recurring-prompt scheduler reaches no path and a client without that command reaches none either, and the file ships to every target holding the plugin.
|
|
21
21
|
|
|
22
|
+
The session also records nothing of what it learns. Both other callers of memory capture are ship-chain skills and this one never ships, so the session taking every operator correction is the session with no moment that writes one down. Hanging that moment on the merge sweep answers it and bills the operator a capture pass per batch of merges while nothing is being built, which is a cost paid on the days shipping is fastest.
|
|
23
|
+
|
|
22
24
|
## Must
|
|
23
25
|
|
|
24
26
|
- Read the priority file for execution order, since the index sorts by filename and states no order
|
|
@@ -33,6 +35,7 @@ The runbooks the session cannot run from memory fail on a third axis, which is w
|
|
|
33
35
|
- Re-resolve the board's plan pointers after any archive, since the archiving skill rewrites the task file and knows nothing about the board
|
|
34
36
|
- Lead a sweep report, a board report, and an analysis with the state, the open decisions, and the next action, keeping the evidence below them
|
|
35
37
|
- Write the pre-compact handoff with what no other file carries, and name the runbook that reads it back
|
|
38
|
+
- Capture what the session learned at the handoff rather than in the merge sweep, and have the sweep report the debt dated from the last handoff, since a capture per batch of merges bills the operator a wait while nothing ships and an undated row reads the same however long the debt has run
|
|
36
39
|
- Carry every runbook the session cannot run from memory inside the skill, so each citation resolves for a project holding the plugin and nothing else
|
|
37
40
|
- State which rule wins where the tracked-file ban collides with the root instruction on small edits, and where a correction no open task owns goes
|
|
38
41
|
- State the review trigger as a recurring prompt rather than as one client's command, since the runbook ships to targets running whatever client they run
|
|
@@ -35,7 +35,7 @@ Then output the state of play so the human knows what to launch, review, and mer
|
|
|
35
35
|
|
|
36
36
|
The roadmap is optional and this skill does not require it. It carries why a sequence is what it is, changes only when strategy changes, and is absent in a project whose scope has already shipped. Report what it says and name it as the source. Never assert an active version the file does not state, and say nothing about one when the file is missing.
|
|
37
37
|
|
|
38
|
-
A compaction is a moment this skill cannot detect, so the human asks for each side of it and this skill reads the matching runbook when they do. On a request to write the handoff or save the session, read `${CLAUDE_SKILL_DIR}/references/orchestrator-handoff.md` and follow it. It writes `.claude/tasks/session.md` with the state of play, the decisions taken under delegated authority, the mistakes worth not repeating, and the standing cautions. On a request to resume after a compaction, read `${CLAUDE_SKILL_DIR}/references/orchestrator-resume.md`, which reads that file back with the board and the groundwork behind the live work. Write nothing to the handoff that the board, a task file, or a groundwork folder already carries.
|
|
38
|
+
A compaction is a moment this skill cannot detect, so the human asks for each side of it and this skill reads the matching runbook when they do. On a request to write the handoff or save the session, read `${CLAUDE_SKILL_DIR}/references/orchestrator-handoff.md` and follow it. It captures what the session learned, then writes `.claude/tasks/session.md` with the state of play, the decisions taken under delegated authority, the mistakes worth not repeating, and the standing cautions. That capture is the only one this session runs, since the refill sweep reports it as owed rather than paying it. On a request to resume after a compaction, read `${CLAUDE_SKILL_DIR}/references/orchestrator-resume.md`, which reads that file back with the board and the groundwork behind the live work. Write nothing to the handoff that the board, a task file, or a groundwork folder already carries.
|
|
39
39
|
|
|
40
40
|
The review trigger takes the same shape. `references/orchestrator-poll.md` holds the loop prompt and the condition under which the poll runs, and `scripts/poll.sh` is what the prompt invokes. A session holding a recurring-prompt scheduler starts and cancels that loop itself, and no hook or check does, so the condition holds only while whoever holds the loop applies it.
|
|
41
41
|
|
|
@@ -116,10 +116,6 @@ The tracked-file boundary collides with `CLAUDE.md`, which says to handle a smal
|
|
|
116
116
|
|
|
117
117
|
Keep enough planned, non-conflicting tasks available that a free worker never waits, and place the findings the last merge produced before promoting anything new. Run this after every merge and whenever the ready list thins. `${CLAUDE_SKILL_DIR}/references/orchestrator-sweep.md` wraps this procedure for a batch of merges and adds the plan re-verification that a merge invalidates.
|
|
118
118
|
|
|
119
|
-
Open the sweep by invoking `aitk:claude-memory-capture`. Both other callers are ship-chain skills and this session never ships, so without this the session that receives every operator correction is the one session that records none. The sweep is the closest bounded moment this session has to a ship, and it already runs once per batch of merges, which beats an end-of-session moment a compaction can cut short.
|
|
120
|
-
|
|
121
|
-
Capture is told this session does not commit, so it skips routing and writes memory files alone. A routed fact lands in a context entry, which is a tracked file, and Boundaries below forbids writing one from here. That is the correct split rather than a limitation: a domain fact belongs to the task that owns the surface and goes in that task's Findings, while what this session produces is feedback about how to work, which is exactly the class the memory folder keeps.
|
|
122
|
-
|
|
123
119
|
1. Run `gh pr list --state open` and `git log --oneline -8`. Report any pull request whose review has not been posted and stop for that one first.
|
|
124
120
|
2. For each pull request merged since the last sweep, place every finding it produced. Route a finding that changes a rule to the standard or rule that states it, one that changes another task to that task's Findings, and one that overturns a groundwork lean to that folder marked answered. Never leave a finding in a pull request thread alone.
|
|
125
121
|
3. Archive what closed. A task whose outcomes are all `[x]` runs `claude-docs` for the plan sweep, then `claude-tasks` to archive. A task whose outcomes describe standing policy rather than a deliverable never closes on its own, so hand it to a worker to encode the policy where it is enforced, then cut the outcomes with the reason recorded and archive once that branch merges. Encoding it from this session would write a tracked file, which Boundaries forbids.
|
|
@@ -129,7 +125,7 @@ Capture is told this session does not commit, so it skips routing and writes mem
|
|
|
129
125
|
7. Write a plan for each newly promoted task with `claude-feature`, then report:
|
|
130
126
|
|
|
131
127
|
```plaintext
|
|
132
|
-
|
|
128
|
+
Capture: owed since <the last handoff, or session start when none has run>
|
|
133
129
|
Findings placed: <finding> → <destination>
|
|
134
130
|
Archived: <task>
|
|
135
131
|
Promoted: <task>, touches <surfaces>, parallel with <task> because <disjoint sets>
|
|
@@ -137,6 +133,8 @@ Serialized: <task> behind <task>, both write <file>
|
|
|
137
133
|
Ready now: <tasks with plans, and what each waits on>
|
|
138
134
|
```
|
|
139
135
|
|
|
136
|
+
The capture row states a standing debt rather than a per-run result. Running capture from here costs the operator a pass between merges while nothing ships, so the row leaves the timing to them and dates the debt, since a capture owed for twenty minutes and one owed all day want different answers and undated text reads the same either way. `${CLAUDE_SKILL_DIR}/references/orchestrator-handoff.md` holds the step that pays it.
|
|
137
|
+
|
|
140
138
|
That block is the detail. Lead the reply with the three slots under Every later turn above, so the human reads what they own before the evidence for it.
|
|
141
139
|
|
|
142
140
|
Treat a task that edits `.claude/context/` entries wholesale as conflicting with every other task, because the root instruction file requires each task to update its own domain entry as it lands.
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Orchestrator handoff runbook
|
|
3
|
-
description:
|
|
3
|
+
description: Memory capture at the close of a session, what to write to .claude/tasks/session.md before a compaction, and what to leave to the board
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Capture what the session learned, then write the pre-compact handoff as orchestrator. Do both before a compaction, because a compaction keeps conclusions and drops the reasoning that produced them, and no other file in the repository carries that reasoning.
|
|
7
7
|
|
|
8
|
-
1.
|
|
9
|
-
2.
|
|
10
|
-
3.
|
|
8
|
+
1. Invoke `aitk:claude-memory-capture` and tell it this session does not commit. Capture reads the session and this handoff summarizes it, so capturing first lets the handoff cite what was written instead of restating the same lesson in prose.
|
|
9
|
+
2. Resolve the main worktree root with `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`, falling back to `pwd`. Write `.claude/tasks/session.md` under it.
|
|
10
|
+
3. Write only what a compaction destroys and no other file already carries. The board holds the ordering and what each task waits on, a task file holds its own findings, and a groundwork folder holds its track.
|
|
11
|
+
4. Use this shape:
|
|
11
12
|
|
|
12
13
|
```markdown
|
|
13
14
|
---
|
|
@@ -36,7 +37,11 @@ description: <what the board cannot show, and the date it was written>
|
|
|
36
37
|
<commands that lie, tools that measure the wrong tree, and anything unbacked>
|
|
37
38
|
```
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
5. Cite a commit, a task, or a file and line for every claim, so the next session can tell a read from a recall.
|
|
41
|
+
6. Overwrite the previous handoff rather than appending to it. A stale entry read as current is worse than no handoff.
|
|
41
42
|
|
|
42
43
|
Add a section only for content that fits none of the four and would otherwise be lost. Do not restate the board, and do not summarize the work that shipped, because git already carries it.
|
|
44
|
+
|
|
45
|
+
Step 1 exists because both other callers of capture are ship-chain skills and this session never ships. Without a call here, the session that receives every operator correction is the one session that records none. A compaction arriving with no warning takes the capture with it, and firing it once per batch of merges leaves the same window open across a long planning stretch, since a sweep runs only on a merge. The refill sweep reports the debt between handoffs so the operator knows one is owed.
|
|
46
|
+
|
|
47
|
+
Capture is told this session does not commit, so it skips routing and writes memory files alone. A routed fact lands in a context entry, which is a tracked file, and the orchestrator's boundaries forbid writing one from this session. That split is correct rather than a limitation, since a domain fact belongs to the task that owns the surface and goes in that task's Findings, while what this session produces is feedback about how to work, which is the class the memory folder keeps.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: claude-worktree
|
|
3
|
-
description: Why worktree entry is wrapped rather than called directly, covering name derivation, the branch rename
|
|
3
|
+
description: Why worktree entry is wrapped rather than called directly, covering name derivation, the conventional branch rename the ship chain depends on, and the shared-config repair
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Claude worktree requirement
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
10
|
-
Without this skill, the user names the worktree by hand, and a name matching no plan breaks every slug derived from it afterward. The entry tool then creates the branch as `worktree-<name>`, which diverges from the name the folder carries, so the ship chain looks for a plan file under a slug that does not exist and stops with nothing wrong except the name.
|
|
10
|
+
Without this skill, the user names the worktree by hand, and a name matching no plan breaks every slug derived from it afterward. The entry tool then creates the branch as `worktree-<name>`, which diverges from the name the folder carries, so the ship chain looks for a plan file under a slug that does not exist and stops with nothing wrong except the name. Correcting that to the bare name leaves the branch carrying no type, which `git-pr` refuses on format, so the same run stops a second time with the work already done and uncommitted.
|
|
11
11
|
|
|
12
12
|
Entry also writes the bare flag into the shared config, which strands the main worktree. Every command run there fails while the files sit untouched on disk, and the linked worktree keeps working, so nothing surfaces until the operator returns to the main checkout and finds the repository broken. A rename onto a branch that already exists is the third failure, and it is the one that destroys work rather than blocking it.
|
|
13
13
|
|
|
@@ -16,7 +16,9 @@ Entry also writes the bare flag into the shared config, which strands the main w
|
|
|
16
16
|
- Derive the name from the plan matched to the current branch, falling through the ordered sources rather than picking
|
|
17
17
|
- Validate and sanitize the derived name against what the entry tool accepts
|
|
18
18
|
- Preview the resolved name and which source produced it before entering
|
|
19
|
-
- Rename the created branch to
|
|
19
|
+
- Rename the created branch to a conventional `<type>/<name>`, so the pull request guard accepts it and the slug transform still reads `<name>` back out
|
|
20
|
+
- Take the type from the plan the name came from, and default to `feat` when a branch or the user supplied it
|
|
21
|
+
- Test the target branch and the target directory before entering, so a stop costs no worktree
|
|
20
22
|
- Read the bare flag before writing it, and repair it on both sides of entry
|
|
21
23
|
- Announce the repair only when a write actually happened
|
|
22
24
|
|
|
@@ -24,7 +26,7 @@ Entry also writes the bare flag into the shared config, which strands the main w
|
|
|
24
26
|
|
|
25
27
|
- Pick between plans when more than one could match. Ask.
|
|
26
28
|
- Enter on a name inferred from session context without confirmation
|
|
27
|
-
- Delete or overwrite a branch that already carries the target name
|
|
29
|
+
- Delete or overwrite a branch or a worktree directory that already carries the target name
|
|
28
30
|
- Rename when the worktree was entered by path, since that branch already has its own identity
|
|
29
31
|
- Invoke the exit path, which is the user's call
|
|
30
32
|
|
|
@@ -32,7 +34,8 @@ Entry also writes the bare flag into the shared config, which strands the main w
|
|
|
32
34
|
|
|
33
35
|
- Already inside a linked worktree: stop rather than nesting
|
|
34
36
|
- Not a git repository and no creation hook configured: stop
|
|
35
|
-
- Target branch already exists: stop and leave it alone, since resolving it automatically risks the wrong branch
|
|
37
|
+
- Target branch already exists: stop before entering and leave it alone, since resolving it automatically risks the wrong branch
|
|
38
|
+
- Target worktree directory already exists: stop before entering, which is the only read that sees two branches differing by type collapsing onto one name
|
|
36
39
|
|
|
37
40
|
## Out of scope
|
|
38
41
|
|
|
@@ -43,28 +43,48 @@ Try each source in order. Stop at the first match.
|
|
|
43
43
|
|
|
44
44
|
Validate the result: letters, digits, dots, underscores, dashes only, max 64 chars (`/` separators are also allowed). If the derived name violates the rule, sanitize by replacing invalid chars with `-` and truncating. Show the sanitized name in the preview before invoking.
|
|
45
45
|
|
|
46
|
+
Resolve `<type>` here as well, since Step 3 previews it and Step 5 renames onto it. A name from a plan takes the type that plan's own work carries, read off its `## Summary` and `**Files to touch:**` lines. Every other case takes `feat`, which covers a name from a branch, a name from the user, and a plan whose lines settle nothing. Draw the value from the type vocabulary in `${CLAUDE_SKILL_DIR}/references/branch.md`.
|
|
47
|
+
|
|
48
|
+
A wrong type is cheap. `git-branch` renames to conventional format later in the same chain and runs ahead of `git-pr`, so a `feat/` written over a fix is corrected before any pull request opens.
|
|
49
|
+
|
|
50
|
+
Then test both names the entry is about to claim. Neither read needs a worktree, and a stop after Step 4 leaves one built with the session sitting inside it, so both belong here rather than beside the rename:
|
|
51
|
+
|
|
52
|
+
- Branch. `git show-ref --verify --quiet refs/heads/<type>/<name>` succeeding means the ref exists. Stop: `❌ Branch <type>/<name> already exists. Resolve manually before continuing.`
|
|
53
|
+
- Directory. `<main-root>/.claude/worktrees/<name>/` existing means an earlier entry claimed the name. Stop: `❌ Worktree .claude/worktrees/<name>/ already exists. Resolve manually before continuing.`
|
|
54
|
+
|
|
55
|
+
Leave both in place. Resolving either automatically risks the wrong one.
|
|
56
|
+
|
|
57
|
+
The two tests catch different collisions. The branch test misses the one `.claude/standards/slug.md` records, where two branches differing only in type collapse onto one name: `feat/foo` and `fix/foo` are distinct refs and reach one directory. The directory test is the only read that sees it.
|
|
58
|
+
|
|
59
|
+
The branch test fires on the tier 1 and tier 4 sources whenever the branch the session started on is already conventional, since a name derived from that branch resolves back onto it. Stopping is the answer there. The concern already has a branch, git refuses a second under the same name, and the bare-name rename this replaces only carried the collision forward to the `git-branch` step.
|
|
60
|
+
|
|
46
61
|
## Step 3: preview
|
|
47
62
|
|
|
48
63
|
Output exactly:
|
|
49
64
|
|
|
50
65
|
```plaintext
|
|
51
66
|
Worktree: .claude/worktrees/<name>/
|
|
52
|
-
|
|
67
|
+
Branch: <type>/<name>
|
|
68
|
+
Source: <plan|branch|user>
|
|
53
69
|
```
|
|
54
70
|
|
|
71
|
+
Step 2 resolved `<type>`. Show it, since it is the one part of the entry the user cannot read off the name they supplied.
|
|
72
|
+
|
|
55
73
|
## Step 4: enter
|
|
56
74
|
|
|
57
75
|
Call `EnterWorktree` with `name: "<name>"`. Claude Code's tool permission dialog is the confirmation gate. Do not pause for additional confirmation.
|
|
58
76
|
|
|
59
77
|
## Step 5: align the branch name and repair the shared config
|
|
60
78
|
|
|
61
|
-
`EnterWorktree` creates a branch named `worktree-<name>`, which diverges from `<name>` and breaks downstream slug derivation in `claude-autoship` and any skill that reads `git branch --show-current`. Rename
|
|
79
|
+
`EnterWorktree` creates a branch named `worktree-<name>`, which diverges from `<name>` and breaks downstream slug derivation in `claude-autoship` and any skill that reads `git branch --show-current`. A bare `<name>` fixes that and fails the branch-format guard in `git-pr`, which requires `<type>/<description>`. Rename to the conventional form, which satisfies both:
|
|
62
80
|
|
|
63
81
|
```bash
|
|
64
|
-
git branch -m worktree-<name> <name>
|
|
82
|
+
git branch -m worktree-<name> <type>/<name>
|
|
65
83
|
```
|
|
66
84
|
|
|
67
|
-
|
|
85
|
+
The slug transform drops a leading type segment, so `<name>` is what every downstream derivation reads back out of the typed branch. See `.claude/standards/slug.md`, or `${CLAUDE_SKILL_DIR}/../../standards/slug.md` when the project does not have it.
|
|
86
|
+
|
|
87
|
+
Step 2 already cleared the target name, so the rename runs unguarded here. Do not repeat the test. A ref created between the two points is a second session racing this one, which a re-read narrows rather than closes.
|
|
68
88
|
|
|
69
89
|
Skip the rename if the worktree was entered via `path` rather than `name`, since the branch already exists under its own identity.
|
|
70
90
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Branch reference
|
|
3
|
+
description: Branch naming format and type conventions
|
|
4
|
+
consumers: git-branch, git-split, git-pr, claude-worktree
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Branch reference
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
Governs a git branch name: its structure, its length, and the type vocabulary it draws from.
|
|
12
|
+
|
|
13
|
+
Does not govern:
|
|
14
|
+
|
|
15
|
+
- Commit subject format, which shares the type vocabulary: `commit.md`
|
|
16
|
+
- Pull request title and body: `pr.md`
|
|
17
|
+
- Whether a phase label may appear in a branch name: `versioning.md`
|
|
18
|
+
- Deriving a slug from a branch name for use in an output filename: `slug.md`
|
|
19
|
+
|
|
20
|
+
## Format
|
|
21
|
+
|
|
22
|
+
- Structure: `<type>/<description>` or `<type>/<ticket>-<description>`
|
|
23
|
+
- Length: 50 characters maximum
|
|
24
|
+
- Casing: kebab-case only, no underscores or camelCase
|
|
25
|
+
- Description: 2 words maximum, 3 only when genuinely needed for specificity
|
|
26
|
+
- Capture the core change, not the commit message verbatim
|
|
27
|
+
- For branches with multiple commits, use the unifying concern as the description.
|
|
28
|
+
- Do not duplicate type in description (e.g., `feat/feature-login`)
|
|
29
|
+
|
|
30
|
+
## Types
|
|
31
|
+
|
|
32
|
+
- `feat`: new feature or capability
|
|
33
|
+
- `fix`: bug fix
|
|
34
|
+
- `refactor`: structural changes (not a fix or feature)
|
|
35
|
+
- `docs`: documentation only (README)
|
|
36
|
+
- `chore`: maintenance tasks (deps, tooling, configs)
|
|
37
|
+
- `perf`: performance improvements
|
|
38
|
+
- `test`: add or modify tests
|
|
39
|
+
- `style`: code formatting (whitespace, semicolons)
|
|
40
|
+
- `build`: build system changes (webpack, npm scripts)
|
|
41
|
+
- `ci`: CI/CD pipeline changes (GitHub Actions)
|
|
42
|
+
- `revert`: revert a previous commit
|
|
43
|
+
|
|
44
|
+
## Examples
|
|
45
|
+
|
|
46
|
+
### Correct
|
|
47
|
+
|
|
48
|
+
```plaintext
|
|
49
|
+
feat/jwt-expiration # clear feature scope
|
|
50
|
+
fix/AUTH-123-connection-pool # includes ticket ID
|
|
51
|
+
refactor/remove-deprecated-endpoints # clear refactor intent
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Incorrect
|
|
55
|
+
|
|
56
|
+
```plaintext
|
|
57
|
+
feature/auth_stuff # wrong type + underscore
|
|
58
|
+
feat/feature-add-login # duplicates type in description
|
|
59
|
+
fix/DB-456-fix-the-database-connection-pool-memory-leak # exceeds 50 chars + verbatim message
|
|
60
|
+
```
|
|
@@ -7,11 +7,12 @@ 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. A caller that rebased the branch before handing over hits a rejected push, since the tracking branch no longer reaches the head.
|
|
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. A branch entered through a worktree hits the opposite shape, carrying an open pull request with no tracking ref at all, which read as a branch that had never been pushed.
|
|
11
11
|
|
|
12
12
|
## Must
|
|
13
13
|
|
|
14
|
-
- Refuse unless the branch has an
|
|
14
|
+
- Refuse unless the branch has an open pull request, since every later step addresses it
|
|
15
|
+
- Set the tracking ref at the push when the branch has none, since a branch entered through a worktree carries an open pull request without one
|
|
15
16
|
- Delegate the message to `git-commit` rather than composing one, so a follow-up commit reads like every other commit
|
|
16
17
|
- Sync the body when the new commit moves the scope, and the title when the shift makes it inaccurate
|
|
17
18
|
- 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.
|
|
@@ -29,7 +30,6 @@ Without this skill, an edit made after a pull request is already open ships as a
|
|
|
29
30
|
|
|
30
31
|
- On `main`: stop and say to switch to a pull request branch
|
|
31
32
|
- Nothing changed: stop
|
|
32
|
-
- No upstream: stop and name both recoveries
|
|
33
33
|
- No open pull request: stop and route to the skill that opens one
|
|
34
34
|
|
|
35
35
|
## Out of scope
|
|
@@ -14,15 +14,16 @@ its own reply, so skip the comment in step 6. The push and body sync still run.
|
|
|
14
14
|
|
|
15
15
|
- If `git branch --show-current` returns `main`, stop: `❌ On main. Switch to a PR branch first.`
|
|
16
16
|
- If `git status --porcelain` is empty, stop: `❌ No changes to ship.`
|
|
17
|
-
- If `git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null` is empty, stop: `❌ No upstream. Push the branch first or use git-ship.`
|
|
18
17
|
- If `gh pr view --json state -q '.state' 2>/dev/null` is not `OPEN`, stop: `❌ No open PR for this branch. Use git-ship to open one.`
|
|
19
18
|
|
|
19
|
+
A missing tracking ref is no longer a guard. An open pull request proves the branch reached the remote, and a branch created by worktree entry has been measured carrying an open pull request with no tracking ref, where the old guard reported that the branch still needed pushing. That message describes a state the branch is not in, so the run stopped on a diagnosis nobody could act on. Step 4 sets the ref instead.
|
|
20
|
+
|
|
20
21
|
## Sequence
|
|
21
22
|
|
|
22
23
|
1. Run `git status` to confirm the changes are intentional
|
|
23
24
|
2. Run `git add -A` to stage every change
|
|
24
25
|
3. Invoke `aitk:git-commit` to generate one conventional commit from the staged diff
|
|
25
|
-
4.
|
|
26
|
+
4. Push. When `git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null` is empty, the branch has an open pull request and no tracking ref, so run `git push -u origin HEAD` to send the commit and set the ref in one step. Otherwise push to the tracking branch with `git push`, and 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. Run the ancestry test only where an upstream resolves, since it reads `@{u}`.
|
|
26
27
|
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
28
|
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
29
|
|
|
@@ -1,23 +1,31 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: project-commands
|
|
3
|
-
description: Runs a command the project documents in
|
|
3
|
+
description: Runs a command the project documents in its development context entry and stops there. Use when asked to "start the app", "start the dev server", "run the checks", "run the build", "spin it up", or "what commands does this project have". Do NOT use to confirm a change works in a running app, which needs verification past the launch. Do NOT use to deploy, publish, or release.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Project commands
|
|
7
7
|
|
|
8
|
-
Read
|
|
8
|
+
Read the project's development context entry, run the command the user named, report where it landed, and stop.
|
|
9
9
|
|
|
10
10
|
The value is the stop. A launch that continues into log inspection, browser checks, or unrelated defects is the failure this skill exists to avoid.
|
|
11
11
|
|
|
12
12
|
## Guards
|
|
13
13
|
|
|
14
|
-
-
|
|
14
|
+
- Resolve the entry before anything else. Take the flat `development.md` under `.claude/context/` when it exists, and `.claude/context/development/overview.md` when the domain outgrew one file and split into a folder, which is where the `## Scripts` table lands in a split. Test both paths, then read one. If neither resolves, stop with the line below and let the user decide. Do not read another file to reconstruct it, because a guess is worse than a stop when the user cannot see it was a guess.
|
|
15
15
|
- If the entry documents no command matching the request, stop and list what it does document. Do not infer a command from a filename or a framework.
|
|
16
16
|
- If the resolved command has an effect that outlives the process and stopping it does not undo, print it for the user to run and stop. Deploying, publishing, releasing, migrating, and resetting are the common shapes, and the test is the effect rather than the name. A script called `infra:apply` or `promote` qualifies.
|
|
17
17
|
|
|
18
|
+
The stop names the flat path in both cases, since a project carrying neither has no entry to point at and the flat one is where a project without a split keeps it:
|
|
19
|
+
|
|
20
|
+
```plaintext
|
|
21
|
+
❌ No .claude/context/development.md. This project has no documented dev loop.
|
|
22
|
+
```
|
|
23
|
+
|
|
18
24
|
## Step 1: read the entry
|
|
19
25
|
|
|
20
|
-
Read
|
|
26
|
+
Read the path the guard resolved, from the project root, the whole entry rather than a named section. That file and no others. A second file is a discovery chain, and this skill has none. Testing two candidate paths is not one, since the test happens before any read and exactly one file is opened.
|
|
27
|
+
|
|
28
|
+
A split domain keeps its other sub-area files out of reach on purpose. `overview.md` carries the run commands, and the siblings beside it cover verification stages, hooks, and scratch, none of which this skill runs.
|
|
21
29
|
|
|
22
30
|
## Step 2: resolve the command
|
|
23
31
|
|
|
@@ -67,7 +75,7 @@ One block per command when the request resolved to more than one.
|
|
|
67
75
|
For a request with no command to run, list what the entry documents instead:
|
|
68
76
|
|
|
69
77
|
```plaintext
|
|
70
|
-
📋 Documented in
|
|
78
|
+
📋 Documented in <the entry path the guard resolved>
|
|
71
79
|
|
|
72
80
|
- `<command>`: <purpose as the entry states it>
|
|
73
81
|
```
|
package/docs/agents/commands.md
CHANGED
|
@@ -33,7 +33,7 @@ Full help: `aitk <command> --help`. Behavior notes for the install and sync verb
|
|
|
33
33
|
| `aitk records validate` | Report a session record against the standard governing it, per kind (`--json`) |
|
|
34
34
|
| `aitk comments scan` | Measure comment density by language and comment kind, with a trend recomputed from git |
|
|
35
35
|
| `aitk context audit` | Report required sections, length, cited paths, catalog tables, provenance, superseded-decision narration, and index drift |
|
|
36
|
-
| `aitk markdown audit` |
|
|
36
|
+
| `aitk markdown audit` | Fail any markdown path on a banned character, word, or spelling, and report the structural checkpoints |
|
|
37
37
|
| `aitk claude skills audit` | Report both skill corpora against the mechanical rules in `standards/skill.md` |
|
|
38
38
|
| `aitk capture [source]` | Render HTML capture sources to PNG, toolkit-only and absent from an installed package |
|
|
39
39
|
|
|
@@ -74,6 +74,10 @@ The citation check resolves every path into an audited folder that appears anywh
|
|
|
74
74
|
|
|
75
75
|
Three exclusions keep it from firing on prose about paths. Fenced blocks are skipped in markdown, which covers a standard displaying a path as an example. Fixture and harness trees are skipped by location, covering sandbox scenarios that describe their own scratch tree, the eval harness naming its target project, and `*.test.ts`. A path into a folder the project does not carry is skipped, so a skill directing a reader to `.claude/wireframes/index.md` stays valid in a project that has wireframes and silent in one that does not.
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
Two cases remain, and no syntax separates either from a real reference. One is a sentence naming a hypothetical entry to show the shape of a name. The other is a line instructing a target project about its own tree, which resolves against the target rather than against this repository and passes here only while the two layouts agree. Splitting a seeded domain into a folder ends that agreement and turns every such line red at once.
|
|
78
|
+
|
|
79
|
+
Append `<!-- audit-ignore-citations -->` to the source line in either case. The marker suppresses citation checking for its own line only.
|
|
80
|
+
|
|
81
|
+
The marker itself stays out of anything that installs. A seed, a plugin skill body, and a stack reference all reach a target, so a marker there lands as toolkit bookkeeping in someone else's tree. Reword those lines to drop the path instead, and where a stop message has to spell it, move that message into a fenced block, which this check already skips.
|
|
78
82
|
|
|
79
83
|
The pattern spells the `.claude/` prefix, so a folder resolved at the project root is measured by every other check and contributes nothing here. Widening it to a bare `docs/x.md` would match prose that references nothing, which is a separate decision from where entries come from. A run whose folders all resolved at the root says the check is out of scope rather than reporting that zero paths resolved, and the same run under `--citations-only` refuses, because a gate exiting clean on a scope it could not build is the failure the gate exists to catch.
|
package/docs/agents/index.md
CHANGED
|
@@ -16,7 +16,7 @@ CLI catalog and invocation rules for agents, split by command domain. Start with
|
|
|
16
16
|
- [Docs](docs.md): How aitk docs resolves the toolkit's own reference surface from an install root, and how a split domain is named
|
|
17
17
|
- [Indexes](indexes.md): Flags, exit codes, and JSON shape for aitk indexes regen, plus when it auto-stages what it rewrote
|
|
18
18
|
- [Install and sync](install-and-sync.md): What each install and sync verb writes, refuses, or leaves alone, and how drift is attributed in a target project
|
|
19
|
-
- [Markdown audit](markdown-audit.md): Running the audit over any markdown path, where its bans and checkpoints are read from, what each check reports, and why
|
|
19
|
+
- [Markdown audit](markdown-audit.md): Running the audit over any markdown path, where its bans and checkpoints are read from, what each check reports, and why the ban half gates while the structural half reports
|
|
20
20
|
- [Output shape](output-shape.md): Two framed shapes every command renders into, how JSON and --names modes keep stdout clean, and the exit discipline that lets piped output drain
|
|
21
21
|
- [Overview](overview.md): What this folder covers, the invocation rules every command inherits, and where domain behavior is documented instead
|
|
22
22
|
- [Records](records.md): Validating the gitignored session records under .claude/, the per-kind checks, the refusal reasons, and why the root defaults to the main worktree
|
|
@@ -117,6 +117,29 @@ commits touching its own source path. The `covers` field names the domains a
|
|
|
117
117
|
target has actually stamped, so a domain that was never stamped is legible
|
|
118
118
|
rather than reading as a clean one.
|
|
119
119
|
|
|
120
|
+
### Tooling
|
|
121
|
+
|
|
122
|
+
Tooling records the stack chain an install resolved rather than per-file hashes,
|
|
123
|
+
since `src/tooling/` runs its own inject machinery and has no walk to attribute.
|
|
124
|
+
The chain is ordered nearest stack first, which is what a `--skip` run needs:
|
|
125
|
+
recording the leaf alone would send the next report measuring against a layer the
|
|
126
|
+
target deliberately does not carry. The report loads exactly those stacks, scans
|
|
127
|
+
them the way `aitk tooling sync` would, and counts what differs per category
|
|
128
|
+
under `tooling.counts`.
|
|
129
|
+
|
|
130
|
+
`measured` is the field the section exists for. A target carrying no chain
|
|
131
|
+
reports `measured: false`, which separates tooling nobody has ever looked at from
|
|
132
|
+
tooling that is current. Both produce zero changes otherwise. Every target
|
|
133
|
+
installed before the record shipped starts unmeasured and leaves on its next
|
|
134
|
+
`aitk tooling sync`, since backfilling would mean inferring the chain from
|
|
135
|
+
installed files, which is the guess the record replaces.
|
|
136
|
+
|
|
137
|
+
A workspace root records nothing, because each package resolves its own chain and
|
|
138
|
+
one written at the root would be that same guess. Run the check against a package
|
|
139
|
+
to measure it. Tooling never counts toward `--exit-code`, on the grounds seeds
|
|
140
|
+
are already excluded on, since it reports golden configs a project is expected to
|
|
141
|
+
edit and a job counting those stays red with no remedy.
|
|
142
|
+
|
|
120
143
|
### Surfaces reported beside the domains
|
|
121
144
|
|
|
122
145
|
Three sections sit outside the per-domain scan, because each names something
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Markdown audit
|
|
3
|
-
description: Running the audit over any markdown path, where its bans and checkpoints are read from, what each check reports, and why
|
|
3
|
+
description: Running the audit over any markdown path, where its bans and checkpoints are read from, what each check reports, and why the ban half gates while the structural half reports
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Markdown audit
|
|
@@ -82,13 +82,33 @@ A bullet, a heading, a table row, a blockquote, a blank line, and a fence each e
|
|
|
82
82
|
|
|
83
83
|
## Exit codes
|
|
84
84
|
|
|
85
|
-
Exit codes are `0` for a completed run
|
|
85
|
+
Exit codes are `0` for a completed run with no gating finding, `1` for a refusal, and `2` for a ban hit. A banned character, word, or spelling fails the run. Bullet, paragraph, and depth weight are judgments a reader settles, so all three report under every code.
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
`2` rather than `1` for the gate keeps a measurement that succeeded and found something distinct from the audit declining to measure at all. A caller reading one as the other sends a reader hunting a defect that does not exist, which is the distinction `aitk context audit` and the `verify.sh` seed stage already draw between the same two codes.
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
A banned character is a fact rather than a judgment, which is the test that admits it to a gate. What held it back was that gating on day one against a corpus never checked mechanically fails loudly on work nobody has had a chance to fix. The order was to land the verb reporting, measure the corpus once, fix what it finds, and turn the gate on as its own change, and the gate is the last of the four.
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
Measured at `4b7b13a2` across 444 files with the paragraph checkpoint at 600: 8 word hits, no character or spelling hits, 119 heavy bullets, 221 heavy paragraphs across 86 files, and 41 files carrying a run past the depth checkpoint. Of the paragraphs, 88 fire on weight alone. This is the baseline the corpus sweep tracked its work against. The ban count is what the gate holds at zero, and it is the only one of the five a gate should ever read.
|
|
92
|
+
|
|
93
|
+
The ban half of that baseline reached zero, which was the precondition the gate waited on, and it was re-measured against the same corpus at the moment the gate landed. The other four moved with the corpus rather than with any decision, so read them from a run rather than from this paragraph.
|
|
94
|
+
|
|
95
|
+
### What a hit asks of an author
|
|
96
|
+
|
|
97
|
+
Rewrite the sentence rather than swapping the banned token for a near-synonym. The rule is about the sense the token carries, so a swap that keeps the sense clears the report without clearing the violation.
|
|
98
|
+
|
|
99
|
+
A code span clears the report too, since the ban scan walks around one, and it is the answer only where the token is genuinely an identifier under discussion. `## Code and identifiers` in `markdown.md` reserves the span for commands, API names, file paths, and identifiers, so backticking a quoted utterance spends one rule to satisfy another and leaves the corpus no cleaner.
|
|
100
|
+
|
|
101
|
+
A hit the closed set cannot separate from correct prose is the case with no third option. `prose.md` bans vague qualifiers and lists the tokens those qualifiers happen to spell, so the temporal `just` reports as the vague one. The rule as written reaches neither, and rewriting the sentence is what the toolkit settled on over building an exemption path, for the reasons below.
|
|
102
|
+
|
|
103
|
+
### Where the rules are enforced
|
|
104
|
+
|
|
105
|
+
Four surfaces read the ban sets and two of them go through this verb. `.claude/hooks/standards-audit.sh` runs it against a single file after each markdown edit, and the `Markdown bans` stage in `scripts/core/verify.sh` runs it across the whole corpus before a push. The hook parsed its own copy of the word bans in awk until the gate landed, which left a British spelling passing at edit time and failing the push with nothing in between explaining the difference.
|
|
106
|
+
|
|
107
|
+
The other two read the standards directly and neither is a consolidation left half done. `claude/skills/claude-standards-audit/SKILL.md` greps the banned tokens agent-side, which is a session reading prose rather than a process it can shell out to, and it ships to every target. The seed copy of the hook keeps its awk, because a scaffolded project may carry no `aitk` and `scripts/core/check-seed-independence.sh` exists to catch seed content depending on the toolkit CLI. Both are the likelier place for the next drift, since nothing compares either against the verb.
|
|
108
|
+
|
|
109
|
+
The hook prefers a checkout's own `src/cli.ts` over a globally installed binary, so it and the push stage read one build. A published binary lags a branch by whatever has not been released, which would put a ban kind added on the branch into the push and not into the edit. It reads its findings out of the `--json` record rather than off the exit code, so an older binary still reports where the fallback applies. A machine with neither runner gets no enforcement at edit time rather than a blocked edit, and the push stage still holds.
|
|
110
|
+
|
|
111
|
+
The stage measures the whole corpus rather than the changed files. A `Do not use` bullet added to a standard bans a token retroactively, and no file in the push that adds the bullet was edited.
|
|
92
112
|
|
|
93
113
|
### Why a recorded count goes stale
|
|
94
114
|
|
|
@@ -106,7 +126,7 @@ The other five were correct prose the closed set cannot separate from a violatio
|
|
|
106
126
|
|
|
107
127
|
### Why they were rewritten rather than exempted
|
|
108
128
|
|
|
109
|
-
Rewriting all five is what settled them, over building an exemption path. An exemption has three consumers, `src/markdown/scan.ts` for the patterns, `src/markdown/bans.ts` for the sets, and `.claude/hooks/standards-audit.sh`, which
|
|
129
|
+
Rewriting all five is what settled them, over building an exemption path. An exemption has three consumers, `src/markdown/scan.ts` for the patterns, `src/markdown/bans.ts` for the sets, and `.claude/hooks/standards-audit.sh`, which held its own copy of the word bans in awk at that point. A mechanism landing in the verb and not the hook leaves an exempted line still failing on edit, which is the surface an author actually meets. Five sentences lost a small amount of naturalness and the count now means what it says.
|
|
110
130
|
|
|
111
131
|
A code span was the first answer for the quoted anti-pattern and it was the wrong one. The ban scan walks around a code span, so backticking a quotation clears the report, and `## Code and identifiers` reserves the span for commands, API names, file paths, and identifiers, which a quoted utterance is none of. Spending one rule to satisfy another leaves the corpus no cleaner than dropping the qualifier does.
|
|
112
132
|
|
package/docs/ai-workflow.md
CHANGED
|
@@ -65,7 +65,7 @@ When features are independent, run them in parallel instead of sequentially. Use
|
|
|
65
65
|
|
|
66
66
|
- Create a worktree per feature, then start a Claude Code session in each
|
|
67
67
|
- Invoke `aitk:claude-feature` in each session. Plans land at the main worktree root as `.claude/plans/feature-<slug>.md`, one per feature, no collisions. Small features stay in chat and skip the file.
|
|
68
|
-
- Implement, verify, and review each feature independently. `claude-review` and `claude-ui-test` write per-branch files at the main worktree root (`review-<
|
|
68
|
+
- Implement, verify, and review each feature independently. `claude-review` and `claude-ui-test` write per-branch files at the main worktree root (`review-<slug>.md`, `ui-checklist-<slug>.md`), so parallel sessions do not overwrite each other. The slug is the branch name with any leading type segment dropped, so `feat/jwt-expiration` and the plan at `feature-jwt-expiration.md` meet on one name
|
|
69
69
|
- Ship each worktree separately with `aitk:git-ship`
|
|
70
70
|
- For full autonomy per worktree, invoke `aitk:claude-autoship` instead of the manual chain. Approve the plan, walk away, come back to draft PRs.
|
|
71
71
|
|
package/docs/target-projects.md
CHANGED
|
@@ -46,10 +46,10 @@ The chain is:
|
|
|
46
46
|
|
|
47
47
|
- `aitk init` installs base tooling, Claude seeds, and governance rules into `.claude/rules/` in the same pass
|
|
48
48
|
- `aitk tooling sync <stack>` adds stack-specific deps, scripts, gitignore entries, and drops `.claude/tooling/<stack>.md` (plus parents) as the agent's audit context
|
|
49
|
-
- The agent follows the reference to generate eslint, vitest, playwright configs and the stack's setup script, and extends `.claude/context/ci.md` and `.claude/context/development.md` per the reference's extend sections
|
|
49
|
+
- The agent follows the reference to generate eslint, vitest, playwright configs and the stack's setup script, and extends `.claude/context/ci.md` and `.claude/context/development.md` per the reference's extend sections <!-- audit-ignore-citations -->
|
|
50
50
|
- `setup-verify` runs the installed `package.json` scripts (lint, typecheck, check, test, build) and reports pass or fail
|
|
51
51
|
|
|
52
|
-
Keep the `## Scripts` table in `.claude/context/development.md` current as scripts are added. Base tooling seeds that entry with the commands it installs, and each stack reference extends the table. `project-commands` reads it to start the app or run a check on request, so a command missing from the table cannot be run that way.
|
|
52
|
+
Keep the `## Scripts` table in `.claude/context/development.md` current as scripts are added. Base tooling seeds that entry with the commands it installs, and each stack reference extends the table. `project-commands` reads it to start the app or run a check on request, so a command missing from the table cannot be run that way. A project whose entry outgrew one file and split into `.claude/context/development/` keeps the table in `overview.md`, which is where the skill looks next. <!-- audit-ignore-citations -->
|
|
53
53
|
|
|
54
54
|
### From scaffold to first feature
|
|
55
55
|
|
|
@@ -100,7 +100,7 @@ When the toolkit updates, target projects pull changes per domain. There is one
|
|
|
100
100
|
|
|
101
101
|
`aitk sync --check <path>` reports what has drifted without writing anything. It splits each difference by cause, which is the question that decides what to do next. A `stale` file still matches what the toolkit installed, so the update is mechanical. A `customized` file carries local edits, so taking the upstream version is a decision and `aitk:claude-seed-sync` is the tool for it. A `stranded` file sits where an older toolkit installed it and the toolkit has since moved, which is what `aitk:migration-standards` handles.
|
|
102
102
|
|
|
103
|
-
That attribution comes from `.claude/aitk.json`, a stamp every install and sync writes
|
|
103
|
+
That attribution comes from `.claude/aitk.json`, a stamp every install and sync writes. Standards, snippets, and governance record a hash per installed file. Tooling records the stack chain it resolved instead, since its install runs no per-file walk to attribute. Each domain holds its own toolkit commit, so syncing governance today does not move the revision standards measures against, and each domain reports the upstream commits touching its own source path. Running any sync stamps that domain, and the report names the ones still unstamped.
|
|
104
104
|
|
|
105
105
|
A project that has never synced under a toolkit new enough to write a stamp falls back to the toolkit's own git history. Installed content matching any version that history published proves the file untouched, so it reports `stale` naming the commit it came from, and content matching no published version stays `drifted`. That fallback needs the toolkit as a git checkout. Installed from the registry it ships source without history, and the report says attribution was unavailable rather than reading every file as a local edit.
|
|
106
106
|
|
|
@@ -108,9 +108,9 @@ Three further causes sit outside the per-domain scan, each naming something that
|
|
|
108
108
|
|
|
109
109
|
That last one matters most on an older project. Before it existed, a target holding `standards/` at its root reported zero entries for that domain, so a project that had never migrated was indistinguishable from one that was fully current.
|
|
110
110
|
|
|
111
|
-
Add `--json` for the machine-readable report, and `--exit-code` to fail a CI job when a target falls behind. Files the project authored itself never count toward that exit code, and neither do superseded artifacts
|
|
111
|
+
Add `--json` for the machine-readable report, and `--exit-code` to fail a CI job when a target falls behind. Files the project authored itself never count toward that exit code, and neither do superseded artifacts, seed drift, or tooling, since each reports content the project is expected to edit or place itself. An unmigrated domain does count, because running the relocation closes it.
|
|
112
112
|
|
|
113
|
-
Tooling
|
|
113
|
+
Tooling reports under a section of its own, and `measured` there says whether the target ever recorded a chain. One that never ran a tooling sync reports unmeasured rather than clean, which is what separates tooling nobody has looked at from tooling that is current. A workspace root records nothing either way, since each package resolves its own chain. Reconcile the configs with `aitk tooling sync <stack> <path>`.
|
|
114
114
|
|
|
115
115
|
### Catch-all
|
|
116
116
|
|