@erclx/aitk 0.101.0 → 0.103.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-docs/REQUIREMENT.md +7 -1
- package/claude/skills/claude-docs/SKILL.md +26 -3
- package/claude/skills/claude-orchestrate/SKILL.md +9 -2
- package/claude/skills/claude-orchestrate/references/orchestrator-sweep.md +1 -1
- package/claude/skills/claude-tasks/SKILL.md +10 -1
- package/claude/skills/claude-teach/REQUIREMENT.md +9 -2
- package/claude/skills/claude-teach/SKILL.md +51 -5
- package/claude/skills/claude-teach/references/promotion.md +54 -0
- package/claude/skills/session-resume/SKILL.md +1 -1
- package/docs/agents/index.md +1 -1
- package/docs/agents/markdown-audit.md +21 -11
- package/docs/agents/tasks.md +8 -4
- package/docs/agents/teach.md +1 -1
- package/docs/ai-workflow.md +2 -0
- package/docs/target-projects.md +1 -1
- package/package.json +1 -1
- package/scripts/core/verify.sh +3 -0
- package/src/commands/markdown.ts +44 -28
- package/src/commands/tasks.ts +6 -3
- package/src/markdown/bans.ts +71 -210
- package/src/markdown/structure.ts +9 -71
- package/src/tasks/archive.ts +9 -4
- package/src/tasks/validate.ts +103 -3
- package/standards/glossary.md +75 -0
- package/standards/index.md +2 -1
- package/standards/prose.md +0 -2
- package/standards/tasks.md +51 -8
- package/standards/teach.md +5 -7
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +43 -47
|
@@ -11,6 +11,8 @@ Without this skill, the planning docs describe the scope the session opened with
|
|
|
11
11
|
|
|
12
12
|
A decision's verification anchor has the same shape of gap in the other direction. The reasoning keeps reading as current while the number it cites moves underneath, and an amendment written without an anchor leaves nothing recording which numbers were checked and which nobody has read since.
|
|
13
13
|
|
|
14
|
+
A handoff file has the same shape of gap as an unmarked outcome. A page a learning workspace produced and an operator already picked a destination for sits in gitignored scratch until something lands it, and the session that produced it is gone by the time a branch exists to carry the write. Left unfolded it reads as promoted while the destination holds nothing.
|
|
15
|
+
|
|
14
16
|
The trigger side carries a gap of its own. "Sync the docs" names either corpus to the person saying it, so a description leaving its corpus to the opening clause alone competes with its public-facing sibling on nothing the routing field states, and the planning surface the request was about goes untouched.
|
|
15
17
|
|
|
16
18
|
## Must
|
|
@@ -24,6 +26,8 @@ The trigger side carries a gap of its own. "Sync the docs" names either corpus t
|
|
|
24
26
|
- Retarget a closed task at the archived plan, so the reasoning behind finished work stays reachable
|
|
25
27
|
- Anchor a decision entry this run writes or amends whose reasoning cites a measured number, re-reading the number against the tree before writing the marker
|
|
26
28
|
- Report an anchored decision whose cited path the diff touched, since the number was read before the branch moved what it counted
|
|
29
|
+
- Land each block of a promotion handoff at the destination its heading names, then delete the file so a later run does not fold it twice
|
|
30
|
+
- Take a promotion destination as already decided, since the operator confirmed it where the page was produced
|
|
27
31
|
|
|
28
32
|
## Must not
|
|
29
33
|
|
|
@@ -32,6 +36,7 @@ The trigger side carries a gap of its own. "Sync the docs" names either corpus t
|
|
|
32
36
|
- Widen what a writing step reads when the baseline is unusable. Widening a read is safe and widening a write stubs a surface for every file in the repository.
|
|
33
37
|
- Edit `CLAUDE.md` inline. Every change there goes through a diff-and-approve gate, so this skill only flags.
|
|
34
38
|
- Create a context entry or delete a plan
|
|
39
|
+
- Overwrite a file a promotion block routes to. A destination that already holds a page is a merge for a person, and folding over it discards work this skill never read.
|
|
35
40
|
- Write an anchor onto a decision the run did not amend, or refresh one without re-reading the number. A date from a pass that measured nothing is the false confidence the marker exists to prevent.
|
|
36
41
|
- Anchor an entry written before the rule, which dates it by blame rather than by a read
|
|
37
42
|
|
|
@@ -43,7 +48,8 @@ The trigger side carries a gap of its own. "Sync the docs" names either corpus t
|
|
|
43
48
|
## Out of scope
|
|
44
49
|
|
|
45
50
|
- Creating a task file or moving one off the board, which `claude-tasks` owns
|
|
46
|
-
- Public-facing docs, which `docs-sync` owns. This skill reconciles the `.claude/` planning surface, and both descriptions name their corpus in the trigger so a request saying only "sync the docs" lands on one of the pair rather than on either.
|
|
51
|
+
- Public-facing docs, which `docs-sync` owns, apart from landing a page a promotion handoff already carries a confirmed destination for. This skill reconciles the `.claude/` planning surface, and both descriptions name their corpus in the trigger so a request saying only "sync the docs" lands on one of the pair rather than on either.
|
|
52
|
+
- Deciding where a promoted page belongs, which is settled with the operator by the surface that produced the page
|
|
47
53
|
- Regenerating the task index, owned by a hook
|
|
48
54
|
- Redrawing diagrams, which `claude-diagram` owns. This skill flags staleness and leaves the re-run to the author.
|
|
49
55
|
- Re-measuring an architecture claim to decide whether its number moved. The sweep keys on a cited path entering the diff, so a claim whose number moved with no cited path in the diff goes unflagged.
|
|
@@ -51,7 +51,7 @@ Read these in parallel from the current worktree root (`pwd`), not the main work
|
|
|
51
51
|
|
|
52
52
|
Read the task board from the main worktree root instead, per Worktrees in `CLAUDE.md`. It is gitignored scratch and never commits with the branch:
|
|
53
53
|
|
|
54
|
-
- `.claude/tasks/index.md` first, then the task files this session touched. That narrow read serves the marking step.
|
|
54
|
+
- `.claude/tasks/index.md` first, then the task files this session touched. That narrow read serves the marking step. The scratch sweep reads every file in the folder for its plans sweep and states that where it gives the instruction.
|
|
55
55
|
|
|
56
56
|
## Step 2: identify what changed
|
|
57
57
|
|
|
@@ -85,7 +85,7 @@ The steps that follow reach past the session, so each earns the reach separately
|
|
|
85
85
|
- Steps 4 and 5 stub against the diff. These are why the skip is not a stop. A session that changed no docs is exactly when an uncovered surface or diagram kind goes unnoticed.
|
|
86
86
|
- Step 6 reads the architecture record against the diff. A run that amended no decision is the one where an anchored number moves under a reasoning nobody reread, which is the case the marker exists to surface.
|
|
87
87
|
- Step 8 rewrites context entries against the diff and against the facts `claude-memory-capture` routed. The Diff baseline section above groups its diff half with Steps 4 and 5 as a scoped-set step, so a quiet session is no different from any other for it. The routed half reads a named file and runs whatever the diff shows.
|
|
88
|
-
-
|
|
88
|
+
- The scratch sweep reads the board rather than the session. Its board-wide scan exists to clear a plan an earlier run stranded, and a run that stops at Step 2 can never reach one.
|
|
89
89
|
|
|
90
90
|
This changes which steps the skill reaches. It does not widen what any of them reads. Steps 4, 5, 6, and 8 still take the same scoped set the Diff baseline section defines, and that section's rule is about the input a step is handed rather than about which steps run.
|
|
91
91
|
|
|
@@ -184,7 +184,30 @@ Add a line naming the handoff when one was consumed:
|
|
|
184
184
|
|
|
185
185
|
The base lint-staged config runs `aitk indexes regen` on every committed `*.md`, so `.claude/context/index.md` refreshes automatically on commit. No manual step needed.
|
|
186
186
|
|
|
187
|
-
## Step 9:
|
|
187
|
+
## Step 9: fold promoted pages
|
|
188
|
+
|
|
189
|
+
Derive `<slug>` per `.claude/standards/slug.md`, falling back to `latest` on an empty result, and read `.claude/.tmp/teach-promotion/<slug>.md` at the main worktree root. `claude-teach` writes it, one H2 per destination naming the path, with a source line under the heading and the page body in a fenced block below that. Read the body out of the fence rather than off the heading level, since a reference page carries headings of its own and only the fence separates them from the next destination. Skip this step silently when the file is absent, which is every run where nothing was promoted.
|
|
190
|
+
|
|
191
|
+
Each block is a page an operator already confirmed a destination for, so this step lands it rather than judging it again. Write to the destination the heading names, at `pwd` rather than at the main root, since every destination here is a tracked file that commits with the branch:
|
|
192
|
+
|
|
193
|
+
- A wiki page and a public doc arrive as a whole file. Write it as the block gives it, and stop with the block unfolded when the destination path already holds a file, since overwriting a page someone else wrote is not a fold.
|
|
194
|
+
- A context entry is merged into rather than created. Fold the body into the sections it belongs under, the same way the routed facts above are folded, and never add an entry the catalog does not already carry.
|
|
195
|
+
|
|
196
|
+
Then delete the handoff file so a later run does not fold it twice, and regenerate the index of any folder that carries one.
|
|
197
|
+
|
|
198
|
+
Output one line per page landed:
|
|
199
|
+
|
|
200
|
+
`✅ Promoted: <destination path>`
|
|
201
|
+
|
|
202
|
+
Add a line naming the handoff when one was consumed:
|
|
203
|
+
|
|
204
|
+
`🧹 Folded: .claude/.tmp/teach-promotion/<slug>.md`
|
|
205
|
+
|
|
206
|
+
Report a block left unfolded rather than dropping it:
|
|
207
|
+
|
|
208
|
+
`⚠ Skipped: <destination path> already exists. Merge by hand.`
|
|
209
|
+
|
|
210
|
+
## Step 10: sweep consumed scratch
|
|
188
211
|
|
|
189
212
|
Sweep reviews this session consumed, and sweep plans across the whole board. Resolve all paths at the main worktree root, not the current worktree. See Worktrees in `CLAUDE.md`.
|
|
190
213
|
|
|
@@ -25,6 +25,7 @@ session's review are different passes, and how a feature is sized.
|
|
|
25
25
|
Read the board in parallel, resolving the paths at the main worktree root per Worktrees in `CLAUDE.md`:
|
|
26
26
|
|
|
27
27
|
- `.claude/tasks/priority.md`: execution order and what each task is waiting on
|
|
28
|
+
- `.claude/tasks/backlog.md`: what is not being scheduled, when the file exists
|
|
28
29
|
- `.claude/tasks/index.md`: what is queued
|
|
29
30
|
- `.claude/plans/*.md`: features already planned and ready to hand off
|
|
30
31
|
- `.claude/ROADMAP.md`: sequencing rationale, when the file exists
|
|
@@ -34,6 +35,8 @@ Then output the state of play so the human knows what to launch, review, and mer
|
|
|
34
35
|
|
|
35
36
|
`priority.md` is the ordering source. `index.md` sorts by filename and says nothing about order, so read the sequence from the first and never infer it from the second. When `priority.md` is absent, report the queue and say the order is unrecorded.
|
|
36
37
|
|
|
38
|
+
Row position under `## Needs a plan` is what gets planned next, top first, per `.claude/standards/tasks.md`. `backlog.md` carries what nobody is scheduling and is explicitly unordered, so read it for what exists and never as a queue. Report a backlog count rather than its rows, since listing them puts the length back in front of the reader the cut took it away from.
|
|
39
|
+
|
|
37
40
|
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.
|
|
38
41
|
|
|
39
42
|
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.
|
|
@@ -155,7 +158,8 @@ It counts unclaimed plans against workers rather than reading the reserve in ste
|
|
|
155
158
|
- A task whose outcomes are all `[x]` runs `claude-docs` for the plan sweep, then `claude-tasks` to archive
|
|
156
159
|
- 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.
|
|
157
160
|
4. Read `.claude/tasks/priority.md` and count entries under its `## Run now` heading that carry a written plan. Keep one in reserve beyond what is running.
|
|
158
|
-
5. Promote
|
|
161
|
+
5. Promote from the top of `## Needs a plan`, which is where the last sweep recorded what to plan next. Depart from that order when something has changed under it and say what changed, since a position nobody honors is the ordering going stale on the surface built to hold it. What sets the order in the first place is whether a task establishes functionality rather than how old it is, so prefer a task that adds or proves a mechanism over one that trims, tidies, or audits an existing surface.
|
|
162
|
+
- Re-take the board-or-backlog call while the file is open. A row that has stopped being near-term moves to `backlog.md`, and a backlogged task the last wave made near-term moves onto the board. Both are one line removed from one surface and written to the other, and the standard states the test.
|
|
159
163
|
6. Before promoting a candidate, list the files it touches against every task already running, per Parallelism below. Name the overlap and serialize when the sets are not disjoint.
|
|
160
164
|
- A candidate held by something outside the tree stays where it is whatever those sets show. A collision is one of the reasons a task cannot start, so disjointness clears that reason alone and leaves an external condition standing.
|
|
161
165
|
7. Write a plan for each newly promoted task with `claude-feature`, carrying the in-flight constraint that The loop above states, then report:
|
|
@@ -166,6 +170,7 @@ Findings placed: <finding> → <destination>
|
|
|
166
170
|
Archived: <task>
|
|
167
171
|
Promoted: <task>, touches <surfaces>, parallel with <task> because <disjoint sets>
|
|
168
172
|
Serialized: <task> behind <task>, both write <file>
|
|
173
|
+
Backlogged: <task>, because <what stopped being near-term>
|
|
169
174
|
Ready now: <tasks with plans, and what each waits on>
|
|
170
175
|
```
|
|
171
176
|
|
|
@@ -179,9 +184,11 @@ Do not promote a task to fill the queue when nothing qualifies. A thin queue is
|
|
|
179
184
|
|
|
180
185
|
### Writing the board
|
|
181
186
|
|
|
182
|
-
Promoting, demoting, and archiving a row all write `.claude/tasks/priority.md`, and this session is the only writer apart from `aitk tasks archive`.
|
|
187
|
+
Promoting, demoting, and archiving a row all write `.claude/tasks/priority.md`, and this session is the only writer apart from `aitk tasks archive`. Moving a task between the board and `.claude/tasks/backlog.md` writes both files, and this session is that file's only writer.
|
|
183
188
|
|
|
184
189
|
- 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.
|
|
190
|
+
- Write both halves of a move before reporting it. A row removed from one surface and not written to the other leaves a task file nothing names, and the folder is gitignored with no history to recover the row from. `aitk tasks validate` reports that state, so run it after any move.
|
|
191
|
+
- Put the reason a row sits where it does in its Waiting on cell. Position is the ordering and the cell is where the ordering's rationale lives, so a row promoted with the cell left alone carries an order the next sweep cannot check.
|
|
185
192
|
- 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.
|
|
186
193
|
- 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.
|
|
187
194
|
- Re-resolve every Plan pointer after anything archives a plan
|
|
@@ -10,7 +10,7 @@ Sweep the board as orchestrator after merging. Run this once per batch of merges
|
|
|
10
10
|
3. Re-verify every plan already written, not only the ones this sweep writes. A queued plan goes stale from whatever merged while it waited, and the loop's verify step fires at handoff rather than after a merge, so nothing else catches it. Grep each construct the plan names and count the sites against its claim, then open each file rather than trusting its account.
|
|
11
11
|
4. Re-check any precondition a plan states about live state outside the repository. A remote branch, an open issue, or an installed version was true when the plan was written and is not a fact about the tree.
|
|
12
12
|
|
|
13
|
-
Run `aitk tasks validate` once the board is rewritten and before reporting it. It resolves every plan pointer,
|
|
13
|
+
Run `aitk tasks validate` once the board is rewritten and before reporting it. It resolves every plan pointer, accounts every task file against the board and the backlog both, tests the `## Run now` file sets for overlap, and re-takes the two blocker kinds a command can settle. It reports and never writes, so fix each row it names and run it again. A finding it reports is a board defect rather than a task finding, so it goes nowhere but the board.
|
|
14
14
|
|
|
15
15
|
Then run `orchestrator-parked.md` over the rows the validator listed as untested. Those carry the three blocker kinds no command settles, and the merge this sweep followed changed the tree under every one of them at once while the refill above re-read none. Take the untested rows alone rather than the whole board, since the validator already answered the rest.
|
|
16
16
|
|
|
@@ -43,7 +43,15 @@ Never write a `Pull request:` line here. `git-pr` adds it when a pull request op
|
|
|
43
43
|
|
|
44
44
|
Write it immediately. Claude Code's tool permission dialog is the confirmation gate. Do not pause for approval.
|
|
45
45
|
|
|
46
|
-
### Step 4:
|
|
46
|
+
### Step 4: place it on a surface
|
|
47
|
+
|
|
48
|
+
A task file with no row is a dropped task, so name the surface it lands on in the same pass that creates it. A task that would plausibly be planned within the next few waves takes a row under `## Needs a plan` in `.claude/tasks/priority.md`, positioned by where it sits against the rows already there, with the reason for that position in its `Waiting on` cell. Anything else takes a line in `.claude/tasks/backlog.md`, which is unordered and where in the file it goes means nothing.
|
|
49
|
+
|
|
50
|
+
The test and both file shapes are in `.claude/standards/tasks.md`. From a linked worktree the file-editing tools refuse the main root, so a row lands through the same `Bash` route the file itself took.
|
|
51
|
+
|
|
52
|
+
Say which surface it went to and why in the report. The call is a judgment restated on every sweep rather than a property of the task, and a placement with no stated reason is one the next sweep re-derives from nothing.
|
|
53
|
+
|
|
54
|
+
### Step 5: report unlinked origins
|
|
47
55
|
|
|
48
56
|
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.
|
|
49
57
|
|
|
@@ -105,6 +113,7 @@ Create:
|
|
|
105
113
|
✅ Created: .claude/tasks/vXX.Y-<slug>.md
|
|
106
114
|
|
|
107
115
|
<label> sits between <neighbor> and <neighbor>.
|
|
116
|
+
<board or backlog, and why it landed there>.
|
|
108
117
|
|
|
109
118
|
**Origin with no task:**
|
|
110
119
|
|
|
@@ -13,6 +13,8 @@ It also produces one output where two are needed. A page written to be worked th
|
|
|
13
13
|
|
|
14
14
|
A session that does record something records the wrong thing. It writes what was taught rather than what the learner retrieved, and a tally of errors carries none of the misconception a later session would work against.
|
|
15
15
|
|
|
16
|
+
The durable half then has nowhere to go. A reference page and a glossary carry no learner and are ordinary reference prose, so they belong wherever the project already keeps prose on that subject, and a workspace holding them is a gitignored folder one person reads. A session moving them by hand picks a destination from the reader's activity rather than from who owns the subject, drops a page into a corpus without the source line that corpus requires, and has nothing stopping it from carrying a lesson across.
|
|
17
|
+
|
|
16
18
|
Two failures land specifically on where the folder sits. A workspace resolved against the current directory forks into a copy per linked worktree, so the learning records split and no session sees the whole history. A body naming only the destination path reports success and loses the write, because the file-editing tools refuse a main-root path from a linked worktree and offer a worktree copy instead.
|
|
17
19
|
|
|
18
20
|
## Must
|
|
@@ -26,21 +28,26 @@ Two failures land specifically on where the folder sits. A workspace resolved ag
|
|
|
26
28
|
- Split the output by lifetime, sending the worked-through half to lessons and the looked-up half to reference pages in the format the authoring gates read
|
|
27
29
|
- Record the wrong answer itself rather than the count, since that is what the next session places the learner from
|
|
28
30
|
- Report progress against the mission's success lines, so a mission can be called finished
|
|
31
|
+
- Propose a destination for each durable page by who owns its subject, and wait for the operator rather than routing on the session's own reading
|
|
32
|
+
- Hand each confirmed page off through a named file of its own, so one skill owns the durable writes and no other producer's unread work is discarded with it
|
|
33
|
+
- Name what the destination expects that the page does not carry yet, since the workspace runs none of the gates the destination does
|
|
29
34
|
|
|
30
35
|
## Must not
|
|
31
36
|
|
|
32
37
|
- Teach from recall without saying which claims rest on it
|
|
33
|
-
- Write
|
|
38
|
+
- Write to a destination surface directly, since the skill owning that file makes the edit and two skills writing one file at one step is what the handoff exists against
|
|
34
39
|
- Open a second workspace on a subject an existing one already covers
|
|
35
40
|
- Renumber a workspace folder, a lesson, or a learning record, since the number is cited by files already written
|
|
41
|
+
- Promote a lesson, at any age and on any request, since it is generated markup carrying a quiz and a learner into a corpus every other page passed a gate to enter
|
|
36
42
|
|
|
37
43
|
## Guards
|
|
38
44
|
|
|
39
45
|
- No subject named and no existing workspace matching, stop rather than opening a workspace with nothing to learn
|
|
46
|
+
- No wiki folder in the project and a page routing there, refuse and name the command that creates one rather than scaffolding a surface the project never chose
|
|
40
47
|
|
|
41
48
|
## Out of scope
|
|
42
49
|
|
|
43
|
-
-
|
|
50
|
+
- Landing a promoted page at its destination, which belongs to the skill that owns durable writes there, and creating a wiki folder a project never chose
|
|
44
51
|
- What the verbs do internally, which is the CLI domain's own contract rather than this skill's, and the records backup that carries the folder off one disk
|
|
45
52
|
- What a lesson renders as and how a quiz behaves once rendered, which the lesson-craft reference shapes and a rendering layer executes
|
|
46
53
|
- Deciding when to fire. The skill is user-invoked through `disable-model-invocation`, so opening a workspace is the learner's call rather than a description match.
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: claude-teach
|
|
3
|
-
description: Opens and runs a learning workspace on one subject, holding a mission, resources, numbered lessons, reference pages, a glossary, and learning records that survive across sessions. Use when asked to "teach me X", "open a learning workspace", "I want to learn X", "quiz me on this", "continue the lesson",
|
|
3
|
+
description: Opens and runs a learning workspace on one subject, holding a mission, resources, numbered lessons, reference pages, a glossary, and learning records that survive across sessions, and proposes where a durable page from one belongs once it outgrows the workspace. Use when asked to "teach me X", "open a learning workspace", "I want to learn X", "quiz me on this", "continue the lesson", "resume my workspace on X", or "promote this reference page". Do NOT use to write project documentation, which belongs to the surface owning that document, and do NOT use to answer one question, which is an ordinary reply.
|
|
4
4
|
disable-model-invocation: true
|
|
5
|
-
argument-hint: <subject to learn, or the topic of
|
|
5
|
+
argument-hint: <subject to learn, or the topic of a workspace to resume or promote>
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Claude teach
|
|
9
9
|
|
|
10
10
|
Run a learning workspace on one subject across sessions. The workspace holds what the learner has been through, so a session weeks later resumes from the folder rather than from the conversation.
|
|
11
11
|
|
|
12
|
-
The shape of the workspace is fixed by `.claude/standards/teach.md`, or `${CLAUDE_SKILL_DIR}/../../standards/teach.md` when the project does not have that file. Read it before writing anything into the folder. The pedagogy sits in `${CLAUDE_SKILL_DIR}/references/pedagogy.md
|
|
12
|
+
The shape of the workspace is fixed by `.claude/standards/teach.md`, or `${CLAUDE_SKILL_DIR}/../../standards/teach.md` when the project does not have that file. Read it before writing anything into the folder. The glossary answers to `.claude/standards/glossary.md`, or `${CLAUDE_SKILL_DIR}/../../standards/glossary.md` when the project does not have it. The pedagogy sits in `${CLAUDE_SKILL_DIR}/references/pedagogy.md`, the lesson craft in `${CLAUDE_SKILL_DIR}/references/lesson-craft.md`, and the promotion routing in `${CLAUDE_SKILL_DIR}/references/promotion.md`.
|
|
13
13
|
|
|
14
14
|
## Guards
|
|
15
15
|
|
|
16
16
|
- If the invocation names no subject and no existing workspace matches, stop: `❌ No subject. Invoke with the subject to learn, or the topic of a workspace to resume.`
|
|
17
17
|
- Never trust recall for what the subject says. Research first, cite what was read, and say what was not.
|
|
18
|
-
- Write nothing outside the workspace folder. A durable page stays in `reference/`
|
|
18
|
+
- Write nothing outside the workspace folder, apart from the one handoff file Step 6 names. A durable page stays in `reference/` and is copied out by the skill that owns the destination, never by this one.
|
|
19
19
|
- Do not open a second workspace on a subject one already covers. Resume that one.
|
|
20
|
+
- Never promote a lesson. It is generated markup carrying a quiz and a learner, and no request makes it promotable.
|
|
20
21
|
|
|
21
22
|
## Step 0: let the CLI resolve the workspace root
|
|
22
23
|
|
|
@@ -37,7 +38,7 @@ From a linked worktree the file-editing tools refuse every path under the main r
|
|
|
37
38
|
|
|
38
39
|
## Step 1: open or resume
|
|
39
40
|
|
|
40
|
-
A topic the listing already carries is a resume, and anything else is a new workspace.
|
|
41
|
+
A topic the listing already carries is a resume, and anything else is a new workspace. An invocation asking to promote is neither: read the named workspace through the listing and go to Step 6, which teaches nothing and writes no lesson.
|
|
41
42
|
|
|
42
43
|
On a resume, run `aitk teach list <topic> --json` for the files behind each count, then read `MISSION.md`, the highest-numbered learning record, and `GLOSSARY.md`. Those three carry where the learner stopped and what they got wrong. Report the mission's success lines with what is already met before teaching anything.
|
|
43
44
|
|
|
@@ -102,6 +103,42 @@ Record the wrong answer rather than the count. The next session places the learn
|
|
|
102
103
|
|
|
103
104
|
Then restate the mission's success lines with what is now met. A mission whose lines are all met is finished, and saying so is what closes a workspace.
|
|
104
105
|
|
|
106
|
+
## Step 6: propose where the durable half belongs
|
|
107
|
+
|
|
108
|
+
Run this when the invocation asks for it, or offer it in one line when a mission finishes, since that is when the workspace stops growing and its reference pages stop changing. Never run it unasked mid-course.
|
|
109
|
+
|
|
110
|
+
Read `${CLAUDE_SKILL_DIR}/references/promotion.md` first. It carries what may be promoted, the routing test, both spellings of the wiki folder, the refusal when a project has none, and what each destination expects a page to carry.
|
|
111
|
+
|
|
112
|
+
Propose and wait. A promoted page is public prose that needs a line naming who owns its subject, which is a judgment about ownership rather than a move a session makes on its own reading. Present one block per candidate page:
|
|
113
|
+
|
|
114
|
+
```plaintext
|
|
115
|
+
reference/<slug>.md → <destination path>
|
|
116
|
+
Subject owner: <who owns it, in a few words>
|
|
117
|
+
Still owed: <what the destination expects that the page does not carry yet>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Then stop and let the operator strike, redirect, or confirm each block.
|
|
121
|
+
|
|
122
|
+
Write nothing to a destination here. One skill owns the durable writes, and two skills editing one file at one step is the failure that rule exists against. Record each confirmed block in `.claude/.tmp/teach-promotion/<slug>.md` at the main worktree root instead, appending when the file exists, with one H2 per destination naming its path, the source page beneath it, and the page body fenced:
|
|
123
|
+
|
|
124
|
+
````markdown
|
|
125
|
+
## <destination path>
|
|
126
|
+
|
|
127
|
+
Source: .claude/teach/<nn>-<topic>/reference/<slug>.md
|
|
128
|
+
|
|
129
|
+
```markdown
|
|
130
|
+
<the page body as it should land, with the source line the destination expects>
|
|
131
|
+
```
|
|
132
|
+
````
|
|
133
|
+
|
|
134
|
+
The body is fenced rather than written bare because a reference page carries headings of its own, and the reader splits this file on its H2 lines. An unfenced body turns every section heading in the page into a destination naming no path. Open the body fence with four backticks so a page carrying a fenced code block of its own still closes where it should, and widen both fences together if it carries a four-backtick fence.
|
|
135
|
+
|
|
136
|
+
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.
|
|
137
|
+
|
|
138
|
+
The handoff is its own file rather than a shared one. The routed-facts file another skill writes is deleted by whichever pass folds it, so a second producer's unread work goes with it, and a sibling path costs the folding skill one more read and removes the interaction.
|
|
139
|
+
|
|
140
|
+
An append is a whole-file operation, so send it as a plain single `Bash` command carrying a heredoc, per Step 0. Then tell the operator that `/claude-docs` folds the file in from a branch. The proposal costs nothing tracked and runs anywhere, while the page it describes is a tracked file, so the fold is a worktree operation and the workspace it came from is not.
|
|
141
|
+
|
|
105
142
|
## Output
|
|
106
143
|
|
|
107
144
|
```plaintext
|
|
@@ -113,3 +150,12 @@ Progress: <n> of <m> success lines met
|
|
|
113
150
|
```
|
|
114
151
|
|
|
115
152
|
Omit the reference line where the lesson produced no durable page. Emit every path from the project root, in the form the project's instruction file sets.
|
|
153
|
+
|
|
154
|
+
A promotion pass reports its own shape instead, one line per page the operator confirmed and one naming the handoff:
|
|
155
|
+
|
|
156
|
+
```plaintext
|
|
157
|
+
➡️ Promoting: .claude/teach/<nn>-<topic>/reference/<slug>.md → <destination path>
|
|
158
|
+
→ Confirmed pages wait at .claude/.tmp/teach-promotion/<slug>.md. Run /claude-docs from a branch to fold them in.
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
A pass where the operator confirmed nothing writes no handoff file and reports that alone.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Promotion routing
|
|
2
|
+
|
|
3
|
+
Which surface a durable page from a learning workspace belongs to, and what to do when the destination does not exist yet.
|
|
4
|
+
|
|
5
|
+
## What may be promoted
|
|
6
|
+
|
|
7
|
+
Only the durable half. A reference page under `reference/` and `GLOSSARY.md` carry no learner and are ordinary reference prose about a subject, so they sort under the routing test like anything else.
|
|
8
|
+
|
|
9
|
+
A lesson is never promoted, at any age and on any request. It is generated markup written to be worked through once, it carries a quiz and a second person, and nothing downstream cites it. Promoting one puts ungated markup into a corpus every other page passed a gate to enter.
|
|
10
|
+
|
|
11
|
+
A reference page that reads like a lesson is a lesson wearing the wrong extension. Where a page under `reference/` carries a quiz, a second person, or an instruction to the learner, say so and propose rewriting it in place before promotion rather than promoting it and repairing it at the destination.
|
|
12
|
+
|
|
13
|
+
## The routing test
|
|
14
|
+
|
|
15
|
+
Sort by who owns the subject, which is the test the wiki already runs. The reader's activity decided the workspace and decides nothing here.
|
|
16
|
+
|
|
17
|
+
| The page's subject | Destination |
|
|
18
|
+
| -------------------------------------------------------------- | ----------------------------- |
|
|
19
|
+
| Owned by someone outside the project, such as a tool or vendor | the project's wiki |
|
|
20
|
+
| How this project itself works, for the people who build it | `.claude/context/<domain>.md` |
|
|
21
|
+
| Written for someone consuming what this project ships | the project's public docs |
|
|
22
|
+
|
|
23
|
+
A page a reader cannot sort by that question is a page whose subject has not been settled. Say which two destinations it sits between and let the operator choose, rather than picking the nearer one.
|
|
24
|
+
|
|
25
|
+
Within the wiki, place the page by the same owner test that decides the folder: a vendor's own subject, another tool's subject, and a subject no single vendor owns each take the folder the project's wiki index names for them.
|
|
26
|
+
|
|
27
|
+
## Where the wiki sits
|
|
28
|
+
|
|
29
|
+
The folder has two spellings and a project carries whichever its scaffold wrote:
|
|
30
|
+
|
|
31
|
+
- `.claude/wiki/`, which is where the scaffolding verb creates one
|
|
32
|
+
- A folder named `wiki` at the project root, which is where a project scaffolded before the move keeps its pages
|
|
33
|
+
|
|
34
|
+
Read which one exists rather than composing either. A project carrying both keeps its pages at the root, so propose the root spelling and say the other folder is there.
|
|
35
|
+
|
|
36
|
+
A project carrying neither gets a refusal rather than a scaffold:
|
|
37
|
+
|
|
38
|
+
`❌ No wiki folder. Run aitk wiki init to create one, then promote again.`
|
|
39
|
+
|
|
40
|
+
Creating the folder as a side effect of promoting one page hands the project a surface it never chose, and the refusal is one command from resolved.
|
|
41
|
+
|
|
42
|
+
## What a promoted page owes its destination
|
|
43
|
+
|
|
44
|
+
Each destination gates prose the workspace does not, so name what the page still needs rather than proposing a move that fails at the gate.
|
|
45
|
+
|
|
46
|
+
- A wiki page closes its intro paragraph with a sentence naming who owns the subject, and links the canonical page when one exists. A page carrying no such sentence is not ready to move.
|
|
47
|
+
- A context entry is internal narrative about one domain, so a page landing there merges into an existing entry rather than arriving as a new one.
|
|
48
|
+
- A glossary keeps the shape `glossary.md` fixes wherever it lands, and a promoted one has to state any rule it departs from.
|
|
49
|
+
|
|
50
|
+
## Anti-patterns
|
|
51
|
+
|
|
52
|
+
- **The page promoted into a new context entry.** Entries are created deliberately, so a promotion proposing one is proposing a domain rather than moving a page.
|
|
53
|
+
- **The glossary split across destinations.** Terms drawn from one subject move together or not at all, since an entry defining a term the other half uses strands both.
|
|
54
|
+
- **The workspace emptied on promotion.** Promotion copies rather than moves. The workspace stays readable to the learner who built it, and the page's later life belongs to its destination.
|
|
@@ -12,7 +12,7 @@ Resolve `.claude/plans/`, `.claude/memory/`, and `.claude/tasks/` at the main wo
|
|
|
12
12
|
Read these in parallel, skipping any that do not exist:
|
|
13
13
|
|
|
14
14
|
- the newest `.claude/tasks/session-*.md`: the handoff a previous session wrote before a compaction, per `.claude/standards/session.md`, or `${CLAUDE_SKILL_DIR}/../../standards/session.md` when the project does not have it. It leads the report rather than the reads.
|
|
15
|
-
- `.claude/tasks/index.md`: the folder catalog. Read this before any individual task file, and take the
|
|
15
|
+
- `.claude/tasks/index.md`: the folder catalog. Read this before any individual task file, and take the task list from it by dropping the `index`, `priority`, `backlog`, and `session-` rows, which are siblings rather than tasks.
|
|
16
16
|
- `.claude/plans/*.md`: execution detail for in-progress tasks
|
|
17
17
|
- `.claude/memory/index.md` and any memory files relevant to the top backlog item
|
|
18
18
|
|
package/docs/agents/index.md
CHANGED
|
@@ -25,5 +25,5 @@ CLI catalog and invocation rules for agents, split by command domain. Start with
|
|
|
25
25
|
- [Scripting](scripting.md): The runtime catalogs that replace hardcoded names, what each carries, and a headless invocation per domain
|
|
26
26
|
- [Sessions](sessions.md): Resolving live peer sessions to the worktree and branch each holds, the liveness confidence field, the unresolved reasons, and what the read depends on
|
|
27
27
|
- [Skill audit](skills-audit.md): Measuring both skill corpora against standards/skill.md, the checks it reads, the requirement gate that is the only failing one, and the drift verb that names bodies rewritten since a ref
|
|
28
|
-
- [Tasks](tasks.md): Selecting a shipped task by stem or pull request, recording a number and closing an outcome, the refusal reasons, the board checks validate runs, and why the board root defaults to the main worktree
|
|
28
|
+
- [Tasks](tasks.md): Selecting a shipped task by stem or pull request, recording a number and closing an outcome, the refusal reasons, the board and backlog checks validate runs, and why the board root defaults to the main worktree
|
|
29
29
|
- [Teach](teach.md): Listing learning workspaces and the ordinal a new one takes, opening one with its required files, recording sources and glossary terms, the refusal reasons, and why every write here runs through a verb
|
|
@@ -27,21 +27,25 @@ A bare run measures every markdown file git lists, tracked plus untracked-and-no
|
|
|
27
27
|
|
|
28
28
|
## Where the rules come from
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
The three ban sets and all six checkpoints ship with the `aitk` package as data, in `src/markdown/bans.ts` and `src/markdown/structure.ts`. Every project is measured against the same sets whether or not it installed any standards, and no file has to resolve for a run to mean something.
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Reading them out of the standards per run was the original design. It put a parser contract on two documents authored for people, and `prose.md` had to carry a paragraph of its own warning an author that a one-word backticked example in a `- Do not use ` bullet would be lifted into a literal ban set and ban that word everywhere. A rule existing to protect a parser from the prose it parses is the argument for separating them.
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
`markdown.md` and `prose.md` still state every ban and every checkpoint, and a reader follows those rather than the code. Nothing compares the two, so a number moved in one place and left in the other drifts silently. Move both in the same change.
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
The sets are closed rather than extensible, so a project cannot add a term by editing a file. What decides that is the measurement behind them: 21 terms across 483 markdown files report a clean exit, and every occurrence of a banned word in the corpus sits inside the ban list itself or inside an example demonstrating the ban. The set is a prior an author already knows rather than a filter that has caught anything, and enumeration cannot close the gap it aims at, since `just`, `allows`, and `very` carry honest uses no literal match separates.
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
Freezing the spellings gave up a property worth naming. They were derived by applying the standard's own suffix pairs to its own examples, so an example added there extended the check with no code edit. The set is now carried whole, and `analyse` stays out of it for the reason it was always out: the standard's example is `analyze`, which ends in `-yze` rather than the `-ize` its rule states.
|
|
39
|
+
|
|
40
|
+
A set shipped empty is reported rather than passed. It finds nothing and would exit clean, which reports a corpus nobody checked as a corpus carrying no violation, so the run names the empty set and exits `1`. The sets ship with the package, so a defect in the build is the only cause left.
|
|
41
|
+
|
|
42
|
+
`aitk standards <name>` still resolves a standard under `.claude/standards/`, then the authoring root, then the package corpus, and prints it, so the human catalog reads without a project copy on disk.
|
|
39
43
|
|
|
40
44
|
## What each check reports
|
|
41
45
|
|
|
42
46
|
### Bans
|
|
43
47
|
|
|
44
|
-
Three closed sets report a hit: the characters `markdown.md` bans under `## Punctuation`, the single lowercase words `prose.md` bans under `## Language`, and the British spellings
|
|
48
|
+
Three closed sets report a hit: the characters `markdown.md` bans under `## Punctuation`, the single lowercase words `prose.md` bans under `## Language`, and the British spellings of the American examples that section lists.
|
|
45
49
|
|
|
46
50
|
Deriving the spellings rather than pattern-matching a suffix is what keeps `exercises`, `promises`, and `revised` out of the report. A suffix pattern over the same corpus produced 46 false positives from words of that shape, and a closed set of whole words reaches none of them.
|
|
47
51
|
|
|
@@ -96,7 +100,9 @@ A bullet, a heading, a table row, a blockquote, a blank line, and a fence each e
|
|
|
96
100
|
|
|
97
101
|
## Exit codes
|
|
98
102
|
|
|
99
|
-
Exit codes are `0` for a completed run with no gating finding, `1` for a refusal, and `
|
|
103
|
+
Exit codes are `0` for a completed run with no gating finding, `1` for a refusal, `2` for a ban hit, and `3` for a shipped ban set that arrived empty. 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.
|
|
104
|
+
|
|
105
|
+
`3` is separate from `1` because the two want different responses from a caller. A refusal means no corpus was built, and the `Markdown bans` stage in `scripts/core/verify.sh` is right to warn and skip. An empty set means the corpus was walked and nothing was looked for, so that stage fails the push on `3` rather than skipping.
|
|
100
106
|
|
|
101
107
|
`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.
|
|
102
108
|
|
|
@@ -118,13 +124,17 @@ A hit the closed set cannot separate from correct prose is the case with no thir
|
|
|
118
124
|
|
|
119
125
|
### Where the rules are enforced
|
|
120
126
|
|
|
121
|
-
Four surfaces
|
|
127
|
+
Four surfaces apply the ban sets and three of them go through this verb. `.claude/hooks/standards-audit.sh` runs it against a single file after each markdown edit, the seed copy a project installs does the same, and the `Markdown bans` stage in `scripts/core/verify.sh` runs it across the whole corpus before a push. Each hook parsed its own copy of the word bans in awk before that, which left a British spelling passing at edit time and failing the push with nothing in between explaining the difference.
|
|
128
|
+
|
|
129
|
+
The seed copy moved onto the verb when the sets became data, since its awk had nothing left to parse. It resolves one runner where the toolkit copy resolves two, looking for no checkout source, and a machine carrying no `aitk` gets a report naming the binary to install rather than a silent pass. `scripts/core/check-seed-independence.sh` scopes its walk to markdown and leaves the seed hooks outside it, which its own comment records as deliberate.
|
|
130
|
+
|
|
131
|
+
The fourth surface reads the standards directly and is not 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. It is the likeliest place for the next drift, since nothing compares it against the verb.
|
|
122
132
|
|
|
123
|
-
The
|
|
133
|
+
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. It reads `bans.emptySets` out of the same record, so a set the verb shipped empty reaches the author as a check narrowed to what it could measure rather than as a clean pass.
|
|
124
134
|
|
|
125
|
-
|
|
135
|
+
That field replaced `bans.missingStandards`, which answered a standard resolving under none of three roots. The sets ship with the package now, so the state it named cannot occur and the narrowed check has one cause left, a defect in the build. The hook keeps reading a field either way, since a reader cannot tell a narrowed check from a clean one without it.
|
|
126
136
|
|
|
127
|
-
|
|
137
|
+
Both hooks answer an absent record as well. A completed run always writes the record and a refusal writes none, so an empty one means the verb declined to measure rather than measured and found nothing. The verb needs a git repository to build its corpus and refuses without one, which is a project the seeded hook can be installed into, and reading the findings alone reported that as a clean file.
|
|
128
138
|
|
|
129
139
|
A machine with neither runner still blocks no edit, and it says so rather than exiting clean. The push stage holds either way. An edit nobody checked and an edit carrying no violation are one silence to a reader, so the enforcement a machine lacks is reported rather than inferred.
|
|
130
140
|
|
package/docs/agents/tasks.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Tasks
|
|
3
|
-
description: Selecting a shipped task by stem or pull request, recording a number and closing an outcome, the refusal reasons, the board checks validate runs, and why the board root defaults to the main worktree
|
|
3
|
+
description: Selecting a shipped task by stem or pull request, recording a number and closing an outcome, the refusal reasons, the board and backlog checks validate runs, and why the board root defaults to the main worktree
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Tasks
|
|
@@ -95,11 +95,15 @@ Five checks run. Plan and Collisions reach one half each of the `## Run now` tes
|
|
|
95
95
|
| Check | What it reports |
|
|
96
96
|
| ---------- | ------------------------------------------------------------------------------------ |
|
|
97
97
|
| Plan | A `## Run now` row whose Plan column carries no link, or one resolving to no file |
|
|
98
|
-
| Mapping | A row naming no task file, and a task file
|
|
99
|
-
| Grouping | A task carrying a row in more than one readiness group
|
|
98
|
+
| Mapping | A row or backlog line naming no task file, and a task file neither surface names |
|
|
99
|
+
| Grouping | A task carrying a row in more than one readiness group, or on both surfaces |
|
|
100
100
|
| Collisions | Two `## Run now` rows whose Touches columns name a path in common |
|
|
101
101
|
| Blockers | A parked row whose blocker has stopped holding, or whose cited task resolves nowhere |
|
|
102
102
|
|
|
103
|
+
Mapping spans two surfaces, because a task sits on `priority.md` when it would plausibly be planned soon and on `backlog.md` otherwise. A task file either surface names is accounted for, a file neither names is `row-missing`, and a file both name is `row-duplicated` for the reason a task in two groups is: it claims two things about itself and only one can hold. One check across both is what lets a task move between them without the move reading as a dropped file.
|
|
104
|
+
|
|
105
|
+
A backlog line is a bullet carrying a link to a sibling task, since the backlog is a flat unordered list rather than a table. A bullet holding prose is skipped rather than reported, which keeps the file's own intro out of the findings, and the task that bullet meant to name is still reported as reaching neither surface. A project carrying no `backlog.md` reads as an empty backlog rather than a refusal, which leaves the one-to-one mapping this check ran before the second surface existed.
|
|
106
|
+
|
|
103
107
|
The collision check is the one a person cannot run by eye. Paths come from the backticked spans in the Touches column, a span naming no file is dropped, and a directory collides with any file beneath it. A `## Run now` row whose column parses to nothing is reported rather than skipped, since a row stating no file set makes a claim nothing can check.
|
|
104
108
|
|
|
105
109
|
The blocker check re-takes a measurement the board records once and never repeats. Two of the five blocker kinds put a fact on disk: a dependency is settled by the cited task being archived or closing every outcome, and a collision is settled by nothing under `## Run now` still holding the file the cell cites.
|
|
@@ -126,7 +130,7 @@ An untested row is not a finding and moves no exit code. Reading a clean finding
|
|
|
126
130
|
|
|
127
131
|
Exit codes: `0` every check passed, `1` refused, `2` at least one finding. The `reason` field carries which gate refused: `no-board`, `no-ordering`, or `no-groups`. A board grouping under headings of its own trips `no-groups` rather than being read against columns it never declared.
|
|
128
132
|
|
|
129
|
-
Columns are read from each table's own header rather than by position, so a project whose board differs from this one is reported for what it lacks. The `index` and `
|
|
133
|
+
Columns are read from each table's own header rather than by position, so a project whose board differs from this one is reported for what it lacks. The `index`, `priority`, and `backlog` siblings are skipped, along with every pre-compaction handoff, which takes one file per session under a `session-` prefix. None of them is a task, and a handoff counted as one would be reported as a task carrying no row on every session that wrote one.
|
|
130
134
|
|
|
131
135
|
Skills branch on the findings rather than on the exit code:
|
|
132
136
|
|
package/docs/agents/teach.md
CHANGED
|
@@ -5,7 +5,7 @@ description: Listing learning workspaces and the ordinal a new one takes, openin
|
|
|
5
5
|
|
|
6
6
|
# Teach
|
|
7
7
|
|
|
8
|
-
Learning workspaces sit under `.claude/teach/<nn>-<topic>/`, and `standards/teach.md` fixes their layout, naming, and file formats. Every verb here resolves that folder against the main worktree root rather than against the working directory, so a session standing in a linked worktree reaches the one workspace the learner has rather than opening a second.
|
|
8
|
+
Learning workspaces sit under `.claude/teach/<nn>-<topic>/`, and `standards/teach.md` fixes their layout, naming, and file formats, apart from the glossary, whose shape `standards/glossary.md` fixes so it travels with the file wherever a promotion lands it. Every verb here resolves that folder against the main worktree root rather than against the working directory, so a session standing in a linked worktree reaches the one workspace the learner has rather than opening a second.
|
|
9
9
|
|
|
10
10
|
That root resolution is also why the writing verbs exist at all. The file-editing tools refuse a main-root path from a linked worktree and offer a worktree copy instead, and a caller naming only the destination reports a success that did not happen. A whole-file create still goes out as a shell heredoc. Changing a line inside a file that already exists has no shell route, because the stream editors are banned, so `resource` and `glossary` are the route for the two files a running workspace edits.
|
|
11
11
|
|
package/docs/ai-workflow.md
CHANGED
|
@@ -282,6 +282,8 @@ This section is the corpus the coverage claim is measured against: every name `a
|
|
|
282
282
|
|
|
283
283
|
Every row answers a question rather than marking a point in a project's life, so a phase above would send a reader to the wrong group.
|
|
284
284
|
|
|
285
|
+
A learning workspace produces two halves and only one of them leaves. A lesson is worked through once and stays in the workspace, and a reference page or a glossary carries no learner, so it belongs wherever the project already keeps prose on that subject. Asking `aitk:claude-teach` to promote sorts each durable page by who owns its subject, sending an outside subject to the wiki, an internal one to the matching context entry, and consumer-facing material to the public docs. It proposes and waits, because a promoted page is public prose that needs a line naming who owns the subject, and it writes nothing to a destination: each page the operator confirms goes to a handoff file that `aitk:claude-docs` folds in from a branch. A project with no wiki folder gets a refusal naming `aitk wiki init` rather than a folder it never asked for.
|
|
286
|
+
|
|
285
287
|
## Feedback routing
|
|
286
288
|
|
|
287
289
|
```plaintext
|
package/docs/target-projects.md
CHANGED
|
@@ -89,7 +89,7 @@ Run `aitk tooling list --json` and `aitk gov list --json` to see the current cat
|
|
|
89
89
|
`governance`, `standards`, and `wiki` are skippable:
|
|
90
90
|
|
|
91
91
|
- `--skip governance`: leave `.claude/rules/` empty. Standards still install, so `.claude/standards/prose.md` lands with nothing pointing at it and no coding standard loads on a file match. The preview names any `--add` rules the skip drops, and the run prints the `aitk gov install <stack> <path>` command to add rules afterward, carrying those extras so one paste restores what the skip declined.
|
|
92
|
-
- `--skip standards`: leave standards out. The governance rules still reference `.claude/standards/`, so their authority lines resolve to nothing for a reader following the path. Toolkit skills are unaffected, since each falls back to the copy in its own plugin root
|
|
92
|
+
- `--skip standards`: leave standards out. The governance rules still reference `.claude/standards/`, so their authority lines resolve to nothing for a reader following the path. Toolkit skills are unaffected, since each falls back to the copy in its own plugin root. `aitk standards <name>` searches the corpus inside the CLI's own package behind both project roots, so it prints a standard in a project that skipped the install, and `aitk markdown audit` needs no standard at all, its ban sets and checkpoints shipping with the package as data. What the skip costs is the editable copy rather than the enforcement.
|
|
93
93
|
- `--skip wiki`: skip the `.claude/wiki/` scaffold. A target that already carries a root `wiki/` keeps it, since the verb reports that folder rather than migrating it.
|
|
94
94
|
|
|
95
95
|
That standards fallback carries runtime behavior rather than reference prose alone, because the pre-publish scan and the branch-slug transform each have a standard of their own, `publish.md` and `slug.md`, cited by the skills that run them.
|
package/package.json
CHANGED
package/scripts/core/verify.sh
CHANGED
|
@@ -363,6 +363,9 @@ main() {
|
|
|
363
363
|
1)
|
|
364
364
|
log_warn "Skipped, the markdown audit refused and measured nothing"
|
|
365
365
|
;;
|
|
366
|
+
3)
|
|
367
|
+
log_error "The markdown audit shipped an empty ban set, so the corpus was walked and nothing was looked for. Check src/markdown/bans.ts."
|
|
368
|
+
;;
|
|
366
369
|
2)
|
|
367
370
|
# `|| true` because the re-run exits non-zero by construction, and `set -e`
|
|
368
371
|
# would take the script down before log_error names the remedy.
|