@erclx/aitk 0.100.0 → 0.102.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/SKILL.md +11 -4
- package/claude/skills/claude-orchestrate/references/orchestrator-poll.md +4 -4
- package/claude/skills/claude-orchestrate/references/orchestrator-sweep.md +1 -1
- package/claude/skills/claude-orchestrate/scripts/poll.sh +11 -10
- package/claude/skills/claude-pr-review/SKILL.md +16 -16
- package/claude/skills/claude-tasks/SKILL.md +10 -1
- package/claude/skills/claude-teach/REQUIREMENT.md +2 -1
- package/claude/skills/claude-teach/SKILL.md +40 -9
- package/claude/skills/session-resume/SKILL.md +1 -1
- package/docs/agents/commands.md +5 -0
- package/docs/agents/index.md +2 -1
- package/docs/agents/markdown-audit.md +21 -11
- package/docs/agents/tasks.md +8 -4
- package/docs/agents/teach.md +119 -0
- package/docs/ai-workflow.md +1 -1
- package/docs/operating-model.md +9 -8
- package/docs/target-projects.md +1 -1
- package/package.json +1 -1
- package/scripts/core/verify.sh +3 -0
- package/src/cli.ts +4 -0
- package/src/commands/markdown.ts +44 -28
- package/src/commands/tasks.ts +6 -3
- package/src/commands/teach.ts +650 -0
- package/src/markdown/bans.ts +71 -210
- package/src/markdown/structure.ts +9 -71
- package/src/records/validate.ts +8 -7
- package/src/tasks/archive.ts +9 -4
- package/src/tasks/validate.ts +103 -3
- package/src/teach/workspace.ts +797 -0
- package/standards/prose.md +0 -2
- package/standards/tasks.md +51 -8
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +43 -47
|
@@ -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.
|
|
@@ -109,8 +112,8 @@ Write no shape for a correction. A correction is a sentence, and a format for ad
|
|
|
109
112
|
5. Hand off. The human opens a worker worktree with `claude-worktree` and runs `claude-autoship` against the plan. The orchestrator does not spawn workers.
|
|
110
113
|
6. Review the PR. When a worker opens a PR, run `claude-pr-review` to post findings to it. This is the deep, independent pass. The worker's autoship self-review was only the green gate.
|
|
111
114
|
- Learning that a PR moved is the mechanical half, so read `${CLAUDE_SKILL_DIR}/references/orchestrator-poll.md` and start the poll it carries on the first dispatch rather than checking the board by hand. That runbook holds the routing, and a summary of it here is a second source that drifts from it.
|
|
112
|
-
7. Dispatch the handback. A pass posting a finding at any severity tells the session holding that branch to run `claude-address-review`, rather than waiting for a person to relay it.
|
|
113
|
-
-
|
|
115
|
+
7. Dispatch the handback. A pass posting a finding at any severity tells the session holding that branch to run `claude-address-review`, rather than waiting for a person to relay it. Re-review when the answer lands, then the human merges. Tell the trailing worker to rebase when its branch shares a seam with the merged one.
|
|
116
|
+
- Read the threshold off `claude-pr-review`, which states it once and governs the heading with it, so an open heading and an owed dispatch answer the same question and either one is enough to send
|
|
114
117
|
- Resolve the target from a fresh session listing at the moment of sending, never from a mapping written down earlier, since names rotate as sessions end and one recorded earlier in a session has failed inside the hour
|
|
115
118
|
- Open the message with the worktree and branch the sender believes the reader holds, asking to be corrected, whenever that mapping is inferred rather than confirmed
|
|
116
119
|
- Name the skill for the reader to run rather than writing an invocation, which arrives as text
|
|
@@ -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
|
|
@@ -34,13 +34,13 @@ Poll GitHub for pull request movement by running <POLL_SCRIPT>, then act on what
|
|
|
34
34
|
- MOVED or RESPONSE on a pull request I have already reviewed: run the aitk:claude-pr-review skill on it immediately, narrow pass. Re-reviews read prior..head and gain nothing from waiting.
|
|
35
35
|
- OPENED, or a pull request with no prior review pass: run the aitk:claude-pr-review skill on it. A draft counts, since every pull request here opens as one and skipping drafts skips everything.
|
|
36
36
|
- SEEN: report it and stop. A pass already covers that head, whether it arrived out of band or before the poll first saw the pull request, so no review follows.
|
|
37
|
-
- STALLED: read the last pass and report what it carried. The pass has sat open for hours with nothing following it, so a worker mid-task is already ruled out and the dispatch either never went out or the session holding it is gone. Confirm and re-send it under the dispatch rule below
|
|
37
|
+
- STALLED: read the last pass and report what it carried. The pass has sat open for hours with nothing following it, so a worker mid-task is already ruled out and the dispatch either never went out or the session holding it is gone. Confirm and re-send it under the dispatch rule below, whatever grades the pass carried. Do not re-run a review to correct the heading, since a pass on an unchanged head with no response behind it stops by design.
|
|
38
38
|
- CONFLICT: report it and stop. The branch owner rebases, not this session.
|
|
39
39
|
- GONE: report it, then sweep the board by invoking the aitk:claude-orchestrate skill and following its queue-refill sweep.
|
|
40
40
|
- A line starting `poll:`: report it verbatim and treat that pull request as unread this run. It is a failed query, not a state.
|
|
41
41
|
- Nothing changed: say exactly "No movement." and nothing else.
|
|
42
42
|
|
|
43
|
-
After any pass that posts a finding, at any severity, tell the session holding that branch to run the aitk:claude-address-review skill. Resolve the target by running `aitk sessions list --branch <branch> --json` at that moment, which scopes the match to this repository, then route on how many sessions it returned. Zero: report the invocation for me and dispatch nobody. Exactly one, with the confidence field reading "confirmed": address that name directly. Any other count, any other confidence, or a command that is missing or refuses: fall back to picking from a session listing, open by naming the worktree and branch you believe the reader holds, and ask to be corrected. Two sessions can hold one branch, so read the count rather than the first row. The
|
|
43
|
+
After any pass that posts a finding, at any severity, tell the session holding that branch to run the aitk:claude-address-review skill. Resolve the target by running `aitk sessions list --branch <branch> --json` at that moment, which scopes the match to this repository, then route on how many sessions it returned. Zero: report the invocation for me and dispatch nobody. Exactly one, with the confidence field reading "confirmed": address that name directly. Any other count, any other confidence, or a command that is missing or refuses: fall back to picking from a session listing, open by naming the worktree and branch you believe the reader holds, and ask to be corrected. Two sessions can hold one branch, so read the count rather than the first row. The threshold is stated once in the aitk:claude-pr-review skill and governs the heading with it, so an open heading and an owed dispatch answer the same question and either one is enough to send.
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
## Reading the output
|
|
@@ -53,6 +53,6 @@ The baseline lives at `.claude/.tmp/pr-poll/baseline.txt` under the main worktre
|
|
|
53
53
|
|
|
54
54
|
The four review headings the script matches are written by `claude-pr-review` and `claude-address-review`. A project that posts its reviews under different headings edits the three jq filters in the script to match, or every pull request reads as never reviewed.
|
|
55
55
|
|
|
56
|
-
`STALLED` is the one state the script derives from a heading rather than from a commit or a count, since `claude-pr-review` posts the open heading
|
|
56
|
+
`STALLED` is the one state the script derives from a heading rather than from a commit or a count, since `claude-pr-review` posts the open heading exactly when a dispatch is owed, per the threshold that skill states. The heading alone cannot carry it, because an open pass means a dispatch was owed and made, so the ordinary healthy thread is a worker still working. The age of that pass is the third test: the state fires when the open pass covers the head, nothing has followed it, and it is older than the `STALE_AFTER` seconds set at the top of the script. It reports once per entry and fires again after any commit or reply resets the thread. A project whose workers run longer than the default two hours raises that number.
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
The state reaches every stalled dispatch, since one threshold governs the heading and the dispatch alike and a pass carrying anything posts the open heading. A minors-only pass therefore reports here on the same terms as a blocking one, which widens the state from what it caught while the two were split. It stays a heading test rather than a count test, so nothing here pins the summary line, which is a second string this script does not own.
|
|
@@ -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
|
|
|
@@ -55,11 +55,11 @@ JQ_REPLY_COUNT='
|
|
|
55
55
|
] | length
|
|
56
56
|
'
|
|
57
57
|
|
|
58
|
-
# `claude-pr-review` posts `## Review`
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
# waiting on a worker from one
|
|
62
|
-
#
|
|
58
|
+
# `claude-pr-review` states the threshold and posts `## Review` exactly when a
|
|
59
|
+
# pass carries a finding, so the heading of the last review is what says whether
|
|
60
|
+
# any work is owed on it. Taking it as well as the commit is what separates a
|
|
61
|
+
# thread waiting on a worker from one nothing is owed on. A project editing the
|
|
62
|
+
# two filters above for its own headings edits this one with them.
|
|
63
63
|
#
|
|
64
64
|
# The age of that review comes out of the same selection, because the heading
|
|
65
65
|
# alone cannot separate the two. Under the rule above an open heading means a
|
|
@@ -251,11 +251,12 @@ while read -r n head prior resp merges heading age; do
|
|
|
251
251
|
[ "$prior" = "$head" ] && [ "$age" -ge "$STALE_AFTER" ]; then
|
|
252
252
|
# Three things at once: the last pass is open, it covers the head so no
|
|
253
253
|
# commit followed it, and the two branches above found no reply either. The
|
|
254
|
-
# open heading is posted
|
|
255
|
-
#
|
|
256
|
-
#
|
|
257
|
-
#
|
|
258
|
-
#
|
|
254
|
+
# open heading is posted exactly when a dispatch is owed, per the threshold
|
|
255
|
+
# `claude-pr-review` states, so a pass owing one left it here at any grade
|
|
256
|
+
# it carried. Any two of these describe an ordinary review waiting on a
|
|
257
|
+
# worker, which is why the age carries the third: without it every
|
|
258
|
+
# dispatched worker is reported minutes into the work it was sent to do,
|
|
259
|
+
# and a signal firing on the healthy path is one an operator learns to
|
|
259
260
|
# skip. The report still asks for a confirmation rather than asserting.
|
|
260
261
|
echo "STALLED #$n open at ${head:0:7}, no commit or reply in $((age / 3600))h"
|
|
261
262
|
state=reported
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: claude-pr-review
|
|
3
|
-
description: Reviews an open pull request from an independent session and posts findings as a review comment on the PR. Posts a first pass against the whole change and every later pass against only the commits added since, under `## Review` while
|
|
3
|
+
description: Reviews an open pull request from an independent session and posts findings as a review comment on the PR. Posts a first pass against the whole change and every later pass against only the commits added since, under `## Review` while any finding is open and `## Review closed` once a pass carries none. Reads project docs and the roadmap for cross-feature context a self-review lacks. Use when asked to "review the PR", "review this feature's PR", "post a PR review", "re-review the PR", "close out the review", "confirm the findings are fixed", or acting as the orchestrator reviewing a worker's PR. Do NOT use to review local uncommitted changes. That is `claude-review`.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Claude PR review
|
|
@@ -13,10 +13,10 @@ findings to the PR, so the vantage is independent and the output is durable.
|
|
|
13
13
|
It posts at least twice over a pull request's life. A first pass opens the
|
|
14
14
|
review against the whole change, and every later pass reads only the commits
|
|
15
15
|
added since. The heading reports state rather than pass number: a pass carrying
|
|
16
|
-
a
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
a finding at any severity takes `## Review`, and `## Review closed` covers a
|
|
17
|
+
pass carrying none, so the most recent comment's heading reports whether any
|
|
18
|
+
work is owed. Every pass is this skill, and which one it is gets detected from
|
|
19
|
+
the thread rather than named by the caller.
|
|
20
20
|
|
|
21
21
|
## Guards
|
|
22
22
|
|
|
@@ -85,11 +85,11 @@ Review the diff and files for the same axes as `claude-review` (bugs, edge cases
|
|
|
85
85
|
|
|
86
86
|
Apply the high-signal filter: flag only what will cause incorrect behavior, break a documented rule, or mislead a downstream feature. If uncertain, do not flag.
|
|
87
87
|
|
|
88
|
-
A later pass applies the same axes to the delta, and adds one check the first pass cannot make: did each prior finding land, and did the fix regress anything it touched. Findings of its own are normal findings, stated at the same severity and counted the same way. That count is what Step 4 reads to pick the heading, so a pass raising a
|
|
88
|
+
A later pass applies the same axes to the delta, and adds one check the first pass cannot make: did each prior finding land, and did the fix regress anything it touched. Findings of its own are normal findings, stated at the same severity and counted the same way. That count is what Step 4 reads to pick the heading, so a pass raising a finding of its own is not a close-out at any severity.
|
|
89
89
|
|
|
90
|
-
A prior finding can also be settled by argument rather than by a fix. A reply naming the plan question that already declined it, or a constraint this session could not see, withdraws the finding or moves its grade. State that outcome in the body under the finding it changes, naming the fact that produced it, whether the argument arrived on the thread or through the channel that carried the dispatch. Dropping the finding from this body instead leaves a reader unable to tell a withdrawal from an oversight, and the reasoning goes with the session that heard it. A withdrawal removes the finding from the count, so a pass that withdrew every
|
|
90
|
+
A prior finding can also be settled by argument rather than by a fix. A reply naming the plan question that already declined it, or a constraint this session could not see, withdraws the finding or moves its grade. State that outcome in the body under the finding it changes, naming the fact that produced it, whether the argument arrived on the thread or through the channel that carried the dispatch. Dropping the finding from this body instead leaves a reader unable to tell a withdrawal from an oversight, and the reasoning goes with the session that heard it. A withdrawal removes the finding from the count, so a pass that withdrew every finding it carried is a close-out. Write the withdrawal and its cause into that body rather than taking the short close-out line Step 4 supplies, which reports prior findings addressed and would credit a fix nobody made.
|
|
91
91
|
|
|
92
|
-
Use severity: `critical` (blocks merge), `should-fix` (fix before merge), `minor` (
|
|
92
|
+
Use severity: `critical` (blocks merge), `should-fix` (fix before merge), `minor` (blocks nothing). The ladder ranks a finding and decides nothing about who acts on it, since every grade takes the open heading and owes a dispatch under the threshold Step 4 states.
|
|
93
93
|
|
|
94
94
|
## Step 4: post to the PR
|
|
95
95
|
|
|
@@ -144,15 +144,15 @@ Re-reviewed `<short-sha>`, N commits since the prior pass. X critical, Y should-
|
|
|
144
144
|
🤖 Reviewed by Claude Code
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
-
The
|
|
147
|
+
The threshold is stated here and nowhere else, and every other surface acting on it cites this skill rather than restating the grades. One rule governs both the heading and the dispatch: a pass carrying a finding at any severity takes `## Review` and owes a dispatch to the session holding the branch, and a pass carrying nothing at all takes `## Review closed` and owes none. Sending that dispatch is `claude-orchestrate`'s step rather than this one, which posts and stops. Post the open heading whether it is the first pass or the fourth. A pull request thread then reads as `## Review`, the worker's answer under `## Review response` from `claude-address-review`, another `## Review` while any finding is open, and `## Review closed` when none is.
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
Keying either half on the grade was measured wrong: across 8 findings on one archived pass, 3 were posted as minor and 2 of those were defects a worker fixed rather than recorded, so a floor at should-fix loses real fixes to a grade that runs low. Splitting the two halves so the dispatch fired lower than the heading was the other candidate, and it left a thread reading closed while work was owed on it.
|
|
150
150
|
|
|
151
|
-
The cost is that
|
|
151
|
+
The cost is that the merge decision no longer reads off the heading alone, since an open heading covers a minor as well as a critical. Take it from the counts on the summary line, which is where they already sit. No summary line reports the merge as unblocked under either heading, since a thread reading open cannot also report that nothing blocks it.
|
|
152
152
|
|
|
153
153
|
A minor the dispatched worker declines is what needs a surface that survives the merge, rather than every minor, since one that gets fixed on the branch needs no durable record. Write a declined minor into the `## Findings` section of the task the branch closes, which is where the queue-refill sweep already routes a finding that changes another task. A declined finding left on the thread alone is lost the moment the pull request merges.
|
|
154
154
|
|
|
155
|
-
Read the state off the most recent review comment rather than off the presence of a closed one. A close-out does not close the pull request, so a commit pushed after it gets its own pass, and that pass reopens the review under `## Review` when it raises a
|
|
155
|
+
Read the state off the most recent review comment rather than off the presence of a closed one. A close-out does not close the pull request, so a commit pushed after it gets its own pass, and that pass reopens the review under `## Review` when it raises a finding of any grade.
|
|
156
156
|
|
|
157
157
|
Both of this skill's headings anchor as a section distinct from human threads. Do not invent one beyond those two and the `## Review response` a sibling owns, and do not append the PR number, which GitHub already renders above the comment.
|
|
158
158
|
|
|
@@ -172,14 +172,14 @@ Before posting, run the scan in `.claude/standards/publish.md` against the body,
|
|
|
172
172
|
gh pr review <number> --comment --body-file .claude/.tmp/pr-review/body-<number>-<short-sha>.md
|
|
173
173
|
```
|
|
174
174
|
|
|
175
|
-
A pass carrying nothing at all takes `## Review closed` and a short body, with the footer line included either way. On a first pass, post `✅ No
|
|
175
|
+
A pass carrying nothing at all takes `## Review closed` and a short body, with the footer line included either way. On a first pass, post `✅ No findings. Reviewed against project docs and roadmap.` On a later pass, post `✅ Prior findings addressed. Re-reviewed <short-sha>, N commits since the prior pass.`
|
|
176
176
|
|
|
177
|
-
A pass carrying only minors takes the
|
|
177
|
+
A pass carrying only minors is an ordinary finding-carrying pass, so it takes the open heading and the full shape rather than either short line, since the minors have to be readable and neither line reports them. Keep whichever scope sentence the pass owes on the summary line:
|
|
178
178
|
|
|
179
179
|
```markdown
|
|
180
|
-
## Review
|
|
180
|
+
## Review
|
|
181
181
|
|
|
182
|
-
0 critical, 0 should-fix, Z minor.
|
|
182
|
+
0 critical, 0 should-fix, Z minor. Reviewed against project docs and roadmap.
|
|
183
183
|
|
|
184
184
|
**`path/to/file.ext`**
|
|
185
185
|
|
|
@@ -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
|
|
|
@@ -19,6 +19,7 @@ Two failures land specifically on where the folder sits. A workspace resolved ag
|
|
|
19
19
|
|
|
20
20
|
- Hold the workspace at the main worktree root, so one learner has one history rather than one per worktree
|
|
21
21
|
- Name the write route for a main-root path from a linked worktree, since a body naming only the destination reports a success that did not happen
|
|
22
|
+
- Route every edit inside a workspace file that already exists through a verb resolving the root in-process, since a heredoc reaches a whole-file create alone and the stream editors that would reach the rest are banned
|
|
22
23
|
- Settle the learner's starting point by asking, so difficulty sits above a measured floor
|
|
23
24
|
- Research the subject from sources before teaching it, and record what was read and what was found and not opened
|
|
24
25
|
- Place each lesson from the learning records rather than from the subject's order, and open with retrieval on the last wrong answer
|
|
@@ -40,6 +41,6 @@ Two failures land specifically on where the folder sits. A workspace resolved ag
|
|
|
40
41
|
## Out of scope
|
|
41
42
|
|
|
42
43
|
- Promoting a durable page out of the workspace, which is a judgment about public prose and belongs to a separate surface
|
|
43
|
-
-
|
|
44
|
+
- 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
|
|
44
45
|
- What a lesson renders as and how a quiz behaves once rendered, which the lesson-craft reference shapes and a rendering layer executes
|
|
45
46
|
- 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.
|
|
@@ -18,31 +18,54 @@ The shape of the workspace is fixed by `.claude/standards/teach.md`, or `${CLAUD
|
|
|
18
18
|
- Write nothing outside the workspace folder. A durable page stays in `reference/` until a promotion pass moves it, and this skill runs no promotion.
|
|
19
19
|
- Do not open a second workspace on a subject one already covers. Resume that one.
|
|
20
20
|
|
|
21
|
-
## Step 0: resolve the workspace root
|
|
21
|
+
## Step 0: let the CLI resolve the workspace root
|
|
22
22
|
|
|
23
23
|
Workspaces live at the main worktree root, never inside a linked worktree. A copy per worktree forks the learning records, and the learner is one person.
|
|
24
24
|
|
|
25
|
+
Every `aitk teach` verb resolves that root in-process, so no step below composes a path to a workspace file. Read the folder through the CLI rather than deriving its location:
|
|
26
|
+
|
|
25
27
|
```bash
|
|
26
|
-
|
|
28
|
+
aitk teach list --json
|
|
27
29
|
```
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
It reports every workspace with its path, its counts, and the ordinal a new one would take. A `no-teach` refusal means the project has opened none yet, which is the new-workspace path in Step 1 rather than a reason to stop. The open verb creates the folder.
|
|
32
|
+
|
|
33
|
+
From a linked worktree the file-editing tools refuse every path under the main root and offer a worktree copy instead, which is a second file no later session reads. Never take that redirect. The route splits by what the write does to the file:
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
- Creating a whole file that does not exist yet, which is a lesson, a reference page, and a learning record, goes out as one plain shell command carrying a heredoc
|
|
36
|
+
- Changing a line inside a file that already exists goes through the verb that owns it, since the stream editors are banned and no other shell route reaches it
|
|
32
37
|
|
|
33
38
|
## Step 1: open or resume
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
A topic the listing already carries is a resume, and anything else is a new workspace.
|
|
36
41
|
|
|
37
|
-
On a resume, 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.
|
|
42
|
+
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.
|
|
38
43
|
|
|
39
44
|
On a new workspace, settle the starting point first, by asking rather than by assuming. Difficulty with no floor under it teaches nobody, and the mission cannot be written without it.
|
|
40
45
|
|
|
41
|
-
Then
|
|
46
|
+
Then open the workspace, which derives the ordinal and writes all three required files:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
aitk teach open <topic> --json \
|
|
50
|
+
--subject "<one line stating the subject>" \
|
|
51
|
+
--starting-point "<what the learner already knows>" \
|
|
52
|
+
--success "<an observable thing the learner will be able to do>" \
|
|
53
|
+
--out-of-scope "<what this workspace does not cover>"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Repeat `--success` and `--out-of-scope` per line. The verb refuses a topic another workspace already covers, which is the guard against opening a second one on the same subject.
|
|
42
57
|
|
|
43
58
|
## Step 2: research before teaching
|
|
44
59
|
|
|
45
|
-
Read the subject from sources rather than from recall. Record
|
|
60
|
+
Read the subject from sources rather than from recall. Record what was read and what was only found through the verb that owns the file:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
aitk teach resource <topic> --json \
|
|
64
|
+
--read "<title, naming which claims rest on it>=<url>" \
|
|
65
|
+
--lead "<title>=<url>"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Each flag repeats, and the pair splits on the first `=` so a URL carrying one survives. A URL already listed is refused rather than repeated.
|
|
46
69
|
|
|
47
70
|
A claim nothing was read for is the failure this step exists against. Where no source is reachable, say so in the lesson and mark what rests on recall.
|
|
48
71
|
|
|
@@ -59,7 +82,15 @@ Two outputs with two lifetimes, and the split decides the format.
|
|
|
59
82
|
- A lesson goes to `lessons/<nnnn>-<slug>.html`, self-contained, carrying its own quiz and the feedback for each answer. It links the shared stylesheet under `assets/` rather than restating styles, and the first lesson in a workspace writes that stylesheet before linking it. A lesson is disposable and is never promoted.
|
|
60
83
|
- A reference page goes to `reference/<slug>.md`, written for a reader with no learner in it. This is the half that survives the workspace, so it is written in markdown to pass the authoring gates a promotion would put it through.
|
|
61
84
|
|
|
62
|
-
Add every term the lesson defines to `GLOSSARY.md
|
|
85
|
+
Add every term the lesson defines to `GLOSSARY.md` through the verb, which places the entries alphabetically in the shape the standard fixes:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
aitk teach glossary <topic> --json \
|
|
89
|
+
--term "<term>=<definition, written without using the term>" \
|
|
90
|
+
--first-seen <the lesson or reference page this batch comes from>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`--term` repeats and one call writes the file once, which is what keeps a batch of terms from racing on it. A term already defined is refused, since a definition the subject has moved under is a revision of the entry rather than a second one.
|
|
63
94
|
|
|
64
95
|
Follow `${CLAUDE_SKILL_DIR}/references/lesson-craft.md` for what makes a lesson worth returning to. Keep every quiz answer the same length, so formatting leaks no clue about which one is correct.
|
|
65
96
|
|
|
@@ -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/commands.md
CHANGED
|
@@ -32,6 +32,10 @@ Full help: `aitk <command> --help`. Behavior notes for the install and sync verb
|
|
|
32
32
|
| `aitk tasks validate` | Report board rows whose plan, task file, group, file set, or blocker does not hold (`--json`) |
|
|
33
33
|
| `aitk intake list` | Report intake folder counts, or one folder's items, keeping what is unread with `--unread` (`--json`) |
|
|
34
34
|
| `aitk intake answer` | Write selections into one cluster's answer slots, repeating `--set <item>=<answer>` (`--json`) |
|
|
35
|
+
| `aitk teach list` | Report learning workspaces and the ordinal a new one takes, or what one workspace holds (`--json`) |
|
|
36
|
+
| `aitk teach open` | Open a workspace at the next ordinal with its mission, resources, and glossary files (`--json`) |
|
|
37
|
+
| `aitk teach resource` | Record sources and leads in a workspace, repeating `--read` or `--lead` as `<title>=<url>` (`--json`) |
|
|
38
|
+
| `aitk teach glossary` | Add terms to a workspace glossary alphabetically, repeating `--term <term>=<definition>` (`--json`) |
|
|
35
39
|
| `aitk records validate` | Report a session record or a standard against the standard governing it, per kind (`--json`) |
|
|
36
40
|
| `aitk records push` | Commit the eight backed record folders and push them to a private records remote (`--json`) |
|
|
37
41
|
| `aitk records pull` | Fetch the records remote and write it back, refusing rather than discarding unpushed records (`--json`) |
|
|
@@ -59,6 +63,7 @@ Each domain exposes a consistent shape where applicable: `list`, `install`, `syn
|
|
|
59
63
|
| `slides` | `render`, `list` |
|
|
60
64
|
| `tasks` | `archive`, `validate` |
|
|
61
65
|
| `intake` | `list`, `answer` |
|
|
66
|
+
| `teach` | `list`, `open`, `resource`, `glossary` |
|
|
62
67
|
| `comments` | `scan` |
|
|
63
68
|
| `context` | `audit` |
|
|
64
69
|
| `markdown` | `audit` |
|
package/docs/agents/index.md
CHANGED
|
@@ -25,4 +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
|
+
- [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
|
|