@erclx/aitk 3.46.0 → 3.47.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/claude-orchestrate/REQUIREMENT.md +3 -1
- package/claude/skills/claude-orchestrate/references/orchestrator-dispatch.md +18 -2
- package/claude/skills/claude-worker/SKILL.md +41 -4
- package/docs/agents/commands.md +56 -56
- package/docs/agents/index.md +2 -2
- package/docs/agents/sessions.md +27 -2
- package/docs/agents/superseded.md +35 -7
- package/package.json +1 -1
- package/src/commands/gov.ts +64 -9
- package/src/commands/sessions.ts +83 -6
- package/src/gov/superseded.ts +223 -15
- package/src/process/harness.ts +167 -0
- package/src/sessions/resolve.ts +103 -0
|
@@ -82,7 +82,9 @@ The session also records nothing of what it learns. Both other callers of memory
|
|
|
82
82
|
- Check a candidate branch is unclaimed by an existing worktree or a live session before dispatching a background worker for it, since the measured failure this closes is a worker colliding with someone else's work already sitting in the row
|
|
83
83
|
- Dispatch only a candidate whose file set is disjoint from every track in flight, compared at the file path rather than a folder above it, since a count knows nothing about what two workers write
|
|
84
84
|
- Hold a candidate whose sets are disjoint when a stated reason serializes it, and write that reason on the hold, since disjointness is necessary and not sufficient
|
|
85
|
-
- Name each self-dispatched worker with the `
|
|
85
|
+
- Name each self-dispatched worker with the `worker-` prefix, since that is the role the name marks and no controlling session has ever carried it
|
|
86
|
+
- Pass `-n` explicitly on every self-dispatch, since a launch that omits it leaves the client to derive a name and the fallback is a fragment of the session's own identifier
|
|
87
|
+
- Carry the dispatcher's `sessionId` in the launch prompt, since a worker owed two messages has no property on the roster that resolves a controller and a name goes stale inside the window it builds in
|
|
86
88
|
- Report each self-dispatch and the row it fired against loudly enough to follow, since a person no longer watches the launch step happen
|
|
87
89
|
- Stop dispatching once `## Run now` is empty or every row in it reads claimed, rather than waking again to fire on a board nobody is clearing
|
|
88
90
|
|
|
@@ -54,15 +54,31 @@ Name `<model>` on the launch, and pick it against the task rather than copying w
|
|
|
54
54
|
## Dispatch
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
claude --bg --model <model> -n "
|
|
57
|
+
claude --bg --model <model> -n "worker-<slug>" "Run /aitk:claude-worktree <type>/<slug>, then /aitk:claude-autoship <plan>. Your controller is the session whose sessionId is <dispatcher-id>. Resolve its current name from that id at the moment you send, and never resolve an addressee by name prefix. Message it when the pull request opens, carrying the number, the branch, the head sha, the CI state, and every point you departed from the plan on, and message it again if you stop on a question."
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
`--bg, --background` starts the session as a background agent and returns immediately, `-n, --name` sets the display name that tells a self-dispatched worker from an operator's own launch in `aitk sessions list`, and `--model` overrides the inheritance the section above measured.
|
|
60
|
+
`--bg, --background` starts the session as a background agent and returns immediately, `-n, --name` sets the display name that tells a self-dispatched worker from an operator's own launch in `aitk sessions list`, and `--model` overrides the inheritance the section above measured. Pass `-n` on every dispatch rather than letting the client derive one. A launch that omits it leaves the session named for a fragment of its own identifier, which is both its address on the send channel and the whole of what the operator sees for it in agent view.
|
|
61
|
+
|
|
62
|
+
The prefix reads `worker-` because that is the role it marks. It read `orchestrator-` until 2026-08-31, and no controlling session ever carried it, so a worker filtering the roster for that string found a sibling or itself on every row. Nothing matches the prefix programmatically, which is what kept the rename down to three strings.
|
|
63
|
+
|
|
64
|
+
Read `<dispatcher-id>` with `aitk sessions list --self --json` and interpolate the `sessionId` that row carries. Carry the id rather than the name. A name is derived from whatever the session turned out to be doing, and across the 181 records stamping both fields, nine were renamed after launch at a median of 5.4 minutes and a maximum of 509. Three landed more than ten minutes in, which is inside the window a worker announces its pull request in, so a name written into the prompt is aimed at a send that happens after it goes stale.
|
|
65
|
+
|
|
66
|
+
Where the installed CLI answers `--self` with an unknown option, that flag is newer than the release the target holds. Read the `sessionId` from the record the client writes for this session under its configuration directory, and say which route answered so the reader knows whether the id was read or inferred.
|
|
61
67
|
|
|
62
68
|
The worktree call comes first and carries the branch as its argument, which is tier 0 of `claude-worktree` Step 2 and the only tier a caller can reach. `claude-autoship` Step 0 then finds the session already in a linked worktree and continues, which is a path it already documents. The autoship call carries `<plan>`, the same file this runbook already read to derive the branch, so its Step 1 takes it as the caller-supplied plan rather than re-deriving one from the slug the worker's branch happens to carry.
|
|
63
69
|
|
|
64
70
|
Naming the branch in prose instead was tried and closes nothing, because no tier of that ladder reads the prompt. A worker launched onto `main` cannot match tier 1, a board carrying more than one plan puts tier 2 out of reach, and tier 3 tells it to ask a person who is not there. Four workers took the right branch that way, by inference rather than by contract, which is the same judgment both live disagreements came from.
|
|
65
71
|
|
|
72
|
+
### What the brief may carry
|
|
73
|
+
|
|
74
|
+
The prompt carries pointers and standing context, and stops there. The branch and the plan stay arguments, because a skill resolves an argument through a documented ladder and reads no prose at all. What the prose reaches is the worker's judgment, so it holds only what a session has to weigh:
|
|
75
|
+
|
|
76
|
+
- Name the addressee and what it is owed, which the two message clauses above already do.
|
|
77
|
+
- Carry standing context this session holds that a cold one cannot derive, such as a constraint settled in conversation that never reached the plan.
|
|
78
|
+
- Leave out anything scope-shaped. A file list, a naming convention, or a check to run belongs in the plan, where the review reads it back against the diff.
|
|
79
|
+
|
|
80
|
+
The last bullet is the one under pressure, since the dispatch that first proved unattended work possible sent a prompt naming the task file, the likely files, the conventions, and the check to run. It shipped in 874 seconds and touched four files its task never named. Scope that arrives as prose is scope nothing verifies afterward.
|
|
81
|
+
|
|
66
82
|
Report the dispatch as loudly as the human-launch line it replaces: name the branch, the model, the task, and the session name, so a person reading the transcript can follow what fired without watching it happen.
|
|
67
83
|
|
|
68
84
|
## Fall back to the human
|
|
@@ -41,10 +41,47 @@ nothing else.
|
|
|
41
41
|
- Send a block out as a message before it becomes an interactive prompt. A session already waiting on input never reaches the tool round that drains an inbound message, so a relayed answer arrives under the open question and changes nothing.
|
|
42
42
|
- Send nothing on progress. A worker reporting progress rebuilds, on this side of the channel, the poll the announcement retired on the other.
|
|
43
43
|
|
|
44
|
-
Address the session the launch named.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
Address the session the launch named. It names a `sessionId` rather than a name,
|
|
45
|
+
so read `aitk sessions list --json`, find the row carrying that id, and send to
|
|
46
|
+
the `name` on it. Resolve that name at the moment of sending rather than at
|
|
47
|
+
launch, since a name is derived from what a session turned out to be doing and
|
|
48
|
+
has gone stale inside the hour that a build takes.
|
|
49
|
+
|
|
50
|
+
Check that name against the agent listing before sending it. A name is not
|
|
51
|
+
unique, and the roster carries no field that separates two live sessions holding
|
|
52
|
+
one, so the resolution can end on a string that reaches the wrong session. Send
|
|
53
|
+
the name bare where the listing shows one row under it. Where it shows more than
|
|
54
|
+
one, complete the address with the `[ref]` that listing prints beside each row
|
|
55
|
+
rather than sending to the name alone, which lands on whichever row the channel
|
|
56
|
+
resolves first. Two sessions differing only by a trailing ` (3)` is the shape
|
|
57
|
+
this meets in practice, and one of them being a controller is what makes the
|
|
58
|
+
wrong pick silent.
|
|
59
|
+
|
|
60
|
+
Ask the operator when the launch named nobody and a person is there to answer.
|
|
61
|
+
Put the candidate rows to them through the structured question surface, so they
|
|
62
|
+
pick a row rather than recalling a name. The ask halts the build, and the halt
|
|
63
|
+
is the cheaper error: a worker that cannot reach its controller has nothing
|
|
64
|
+
useful to do with the message it owes, where sending to the wrong session
|
|
65
|
+
reports success and loses it. A halt is only as visible as whatever watches for
|
|
66
|
+
one, so say what you are waiting on in the same turn you stop, and expect a
|
|
67
|
+
controller running no stall detector to find the question only when it next
|
|
68
|
+
looks.
|
|
69
|
+
|
|
70
|
+
Infer only where no operator is present. Read `aitk sessions list --json` and
|
|
71
|
+
take the sessions holding no feature branch as the candidates, since a
|
|
72
|
+
controlling session holds none. Say the addressee was inferred so the reader can
|
|
73
|
+
correct it. Never filter that roster by name prefix: every self-dispatched
|
|
74
|
+
worker is named `worker-<slug>`, so a prefix scan returns a sibling or this
|
|
75
|
+
session itself, which is the defect that sent messages owed to a controller
|
|
76
|
+
somewhere else.
|
|
77
|
+
|
|
78
|
+
Report a resolution that returns nothing rather than falling back to a guess.
|
|
79
|
+
The roster and the send channel enumerate different populations in both
|
|
80
|
+
directions, measured at one moment: a live background session sat on the roster
|
|
81
|
+
that the agent listing did not carry, and nine sessions were addressable there
|
|
82
|
+
with no roster row at all. Those nine were driving through Remote Control, which
|
|
83
|
+
writes no local process record, so a controller working from a phone is exactly
|
|
84
|
+
the case this read answers nothing for.
|
|
48
85
|
|
|
49
86
|
## Refusing is part of the job
|
|
50
87
|
|
package/docs/agents/commands.md
CHANGED
|
@@ -9,62 +9,62 @@ Full help: `aitk <command> --help`. Behavior notes for the install and sync verb
|
|
|
9
9
|
|
|
10
10
|
## Project-level
|
|
11
11
|
|
|
12
|
-
| Command | Purpose
|
|
13
|
-
| -------------------------- |
|
|
14
|
-
| `aitk init [path]` | Bootstrap a project with selected toolkit domains
|
|
15
|
-
| `aitk sync [path]` | Sync all installed domains in a target project
|
|
16
|
-
| `aitk sync --check` | Report toolkit drift and the installed version against the newest published (`--json`, `--exit-code`)
|
|
17
|
-
| `aitk sandbox [cat:cmd]` | Run sandbox scenarios (interactive or routed), toolkit-only like the tree it reads
|
|
18
|
-
| `aitk sandbox reset` | Reset sandbox to baseline
|
|
19
|
-
| `aitk sandbox clean` | Wipe the sandbox
|
|
20
|
-
| `aitk sandbox check` | Score a provisioned sandbox against a scenario expectation (`--json` for the verdict)
|
|
21
|
-
| `aitk sandbox coverage` | Report which scenarios declare expectations (`--json`, `--strict`, `--skills`)
|
|
22
|
-
| `aitk indexes regen` | Regenerate `index.md` files from sibling frontmatter
|
|
23
|
-
| `aitk docs [topic]` | Emit toolkit reference docs (`list`, or a topic by name)
|
|
24
|
-
| `aitk design render` | Render `.claude/DESIGN.md` tokens to HTML and CSS
|
|
25
|
-
| `aitk slides render` | Render a `.claude/SLIDES.md` source into a PowerPoint deck
|
|
26
|
-
| `aitk slides list` | List the available slide layouts (`--json` for the catalog)
|
|
27
|
-
| `aitk feedback` | Write toolkit feedback from stdin to `.claude/review/feedback/`, or open a GitHub issue with `--github`
|
|
28
|
-
| `aitk transcripts <url>` | Fetch a YouTube transcript with metadata frontmatter (needs `yt-dlp`)
|
|
29
|
-
| `aitk tasks archive` | Move a shipped task off the board, clear its ordering row, and regenerate the index
|
|
30
|
-
| `aitk tasks pull-request` | Record a pull request number on the task a branch closes, by stem or `--plan` (`--json`)
|
|
31
|
-
| `aitk tasks outcome` | Mark outcomes `[x]` on a task by position, repeating `--close` (`--json`)
|
|
32
|
-
| `aitk tasks validate` | Report board rows whose plan, task file, group, file set, or blocker does not hold (`--json`)
|
|
33
|
-
| `aitk intake list` | Report intake folder counts, or one folder's items, keeping what is unread with `--unread` (`--json`)
|
|
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`)
|
|
39
|
-
| `aitk records validate` | Report a session record or a standard against the standard governing it, per kind (`--json`)
|
|
40
|
-
| `aitk records migrate` | Rewrite the records a validate finding names a recoverable transform for (`--write`, `--json`)
|
|
41
|
-
| `aitk records size` | Report what each record folder holds and how much of it is recent, heaviest first (`--json`)
|
|
42
|
-
| `aitk records push` | Commit the nine backed record folders and push them to a private records remote (`--json`)
|
|
43
|
-
| `aitk records pull` | Fetch the records remote and write it back, refusing rather than discarding unpushed records (`--json`)
|
|
44
|
-
| `aitk sessions list` | Resolve live sessions to the worktree and branch each holds, filtered by `--branch` (`--json`)
|
|
45
|
-
| `aitk worktrees list` | Report which worktrees are reclaimable, keyed on the pull request having merged, with every refusal and the removal route named (`--json`)
|
|
46
|
-
| `aitk comments scan` | Measure comment density by language and comment kind, with a trend recomputed from git
|
|
47
|
-
| `aitk context audit` | Report required sections, length, cited paths, reference form, catalog tables, provenance, superseded-decision narration, and index drift
|
|
48
|
-
| `aitk markdown audit` | Fail any markdown path on a banned character, word, or spelling, and report the structural checkpoints
|
|
49
|
-
| `aitk claude skills audit` | Report both skill corpora against the mechanical rules in `standards/skill.md`
|
|
50
|
-
| `aitk standards audit` | Report the corpus against the `## Success criterion` gate, failing only on a standard new to the branch (`--json`, `--arrivals-only`)
|
|
51
|
-
| `aitk claude skills drift` | Name the shipped skill bodies rewritten between a given ref and `HEAD`, and the installed version against the newest published (`--json`)
|
|
52
|
-
| `aitk claude skills reach` | Report the bodies in either skill corpus citing a toolkit path no target project receives, exiting 2 on an unqualified one
|
|
53
|
-
| `aitk claude skills rank` | Score either skill corpus's descriptions against a case corpus by TF-IDF cosine similarity, reporting rank-one and top-three (`--cases <path>`)
|
|
54
|
-
| `aitk claude routing` | Report per `CLAUDE.md` section how many bullets name a path and how many of those a path-scoped rule already covers (`--json`)
|
|
55
|
-
| `aitk gov test-order` | Report where an implementation reached history ahead of the test covering it (`--json`)
|
|
56
|
-
| `aitk gov superseded` | Report where the tree still asserts a value a changed convention no longer produces, keyed on the value (`--json`)
|
|
57
|
-
| `aitk gov restated` | Report every instruction the always-loaded file or a rule shares with the seed, a shipped skill body, or another rule, classed and with its anchors named (`--json`)
|
|
58
|
-
| `aitk secrets scan` | Report credential-shaped values in the tree the package ships, keyed on issued values rather than on words (`--json`)
|
|
59
|
-
| `aitk deps audit` | Report published advisories against the resolved dependency set, refusing rather than reporting clean when the index is unreachable (`--json`)
|
|
60
|
-
| `aitk labels audit` | Report the labels a changed set earns from the pull request label map and the paths no row reaches (`--json`)
|
|
61
|
-
| `aitk census [path]` | Report tracked file count, a breakdown by extension, and a line total that skips whatever reads as binary (`--json`)
|
|
62
|
-
| `aitk audits run` | Run every audit as one set, report per check under one verdict, and compare each count to the recorded baseline (`--json`, `--record`)
|
|
63
|
-
| `aitk audits list` | List every audit the set runs, with the corpus each reads and whether it gates (`--json`)
|
|
64
|
-
| `aitk inventory [subject]` | Walk every route a project declares and group its elements by the property each computes, as a listing rather than a gate (`--json`)
|
|
65
|
-
| `aitk capture [source]` | Render HTML capture sources to PNG, toolkit-only and absent from an installed package
|
|
66
|
-
| `aitk serve [dir]` | Serve a directory on the loopback interface and print the link that opens it, running until interrupted (`--port`, `--entry`, `--json`)
|
|
67
|
-
| `aitk upgrade` | Reinstall the CLI globally with the package manager the install path names (`--json`)
|
|
12
|
+
| Command | Purpose |
|
|
13
|
+
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
14
|
+
| `aitk init [path]` | Bootstrap a project with selected toolkit domains |
|
|
15
|
+
| `aitk sync [path]` | Sync all installed domains in a target project |
|
|
16
|
+
| `aitk sync --check` | Report toolkit drift and the installed version against the newest published (`--json`, `--exit-code`) |
|
|
17
|
+
| `aitk sandbox [cat:cmd]` | Run sandbox scenarios (interactive or routed), toolkit-only like the tree it reads |
|
|
18
|
+
| `aitk sandbox reset` | Reset sandbox to baseline |
|
|
19
|
+
| `aitk sandbox clean` | Wipe the sandbox |
|
|
20
|
+
| `aitk sandbox check` | Score a provisioned sandbox against a scenario expectation (`--json` for the verdict) |
|
|
21
|
+
| `aitk sandbox coverage` | Report which scenarios declare expectations (`--json`, `--strict`, `--skills`) |
|
|
22
|
+
| `aitk indexes regen` | Regenerate `index.md` files from sibling frontmatter |
|
|
23
|
+
| `aitk docs [topic]` | Emit toolkit reference docs (`list`, or a topic by name) |
|
|
24
|
+
| `aitk design render` | Render `.claude/DESIGN.md` tokens to HTML and CSS |
|
|
25
|
+
| `aitk slides render` | Render a `.claude/SLIDES.md` source into a PowerPoint deck |
|
|
26
|
+
| `aitk slides list` | List the available slide layouts (`--json` for the catalog) |
|
|
27
|
+
| `aitk feedback` | Write toolkit feedback from stdin to `.claude/review/feedback/`, or open a GitHub issue with `--github` |
|
|
28
|
+
| `aitk transcripts <url>` | Fetch a YouTube transcript with metadata frontmatter (needs `yt-dlp`) |
|
|
29
|
+
| `aitk tasks archive` | Move a shipped task off the board, clear its ordering row, and regenerate the index |
|
|
30
|
+
| `aitk tasks pull-request` | Record a pull request number on the task a branch closes, by stem or `--plan` (`--json`) |
|
|
31
|
+
| `aitk tasks outcome` | Mark outcomes `[x]` on a task by position, repeating `--close` (`--json`) |
|
|
32
|
+
| `aitk tasks validate` | Report board rows whose plan, task file, group, file set, or blocker does not hold (`--json`) |
|
|
33
|
+
| `aitk intake list` | Report intake folder counts, or one folder's items, keeping what is unread with `--unread` (`--json`) |
|
|
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`) |
|
|
39
|
+
| `aitk records validate` | Report a session record or a standard against the standard governing it, per kind (`--json`) |
|
|
40
|
+
| `aitk records migrate` | Rewrite the records a validate finding names a recoverable transform for (`--write`, `--json`) |
|
|
41
|
+
| `aitk records size` | Report what each record folder holds and how much of it is recent, heaviest first (`--json`) |
|
|
42
|
+
| `aitk records push` | Commit the nine backed record folders and push them to a private records remote (`--json`) |
|
|
43
|
+
| `aitk records pull` | Fetch the records remote and write it back, refusing rather than discarding unpushed records (`--json`) |
|
|
44
|
+
| `aitk sessions list` | Resolve live sessions to the worktree and branch each holds, filtered by `--branch` (`--json`) |
|
|
45
|
+
| `aitk worktrees list` | Report which worktrees are reclaimable, keyed on the pull request having merged, with every refusal and the removal route named (`--json`) |
|
|
46
|
+
| `aitk comments scan` | Measure comment density by language and comment kind, with a trend recomputed from git |
|
|
47
|
+
| `aitk context audit` | Report required sections, length, cited paths, reference form, catalog tables, provenance, superseded-decision narration, and index drift |
|
|
48
|
+
| `aitk markdown audit` | Fail any markdown path on a banned character, word, or spelling, and report the structural checkpoints |
|
|
49
|
+
| `aitk claude skills audit` | Report both skill corpora against the mechanical rules in `standards/skill.md` |
|
|
50
|
+
| `aitk standards audit` | Report the corpus against the `## Success criterion` gate, failing only on a standard new to the branch (`--json`, `--arrivals-only`) |
|
|
51
|
+
| `aitk claude skills drift` | Name the shipped skill bodies rewritten between a given ref and `HEAD`, and the installed version against the newest published (`--json`) |
|
|
52
|
+
| `aitk claude skills reach` | Report the bodies in either skill corpus citing a toolkit path no target project receives, exiting 2 on an unqualified one |
|
|
53
|
+
| `aitk claude skills rank` | Score either skill corpus's descriptions against a case corpus by TF-IDF cosine similarity, reporting rank-one and top-three (`--cases <path>`) |
|
|
54
|
+
| `aitk claude routing` | Report per `CLAUDE.md` section how many bullets name a path and how many of those a path-scoped rule already covers (`--json`) |
|
|
55
|
+
| `aitk gov test-order` | Report where an implementation reached history ahead of the test covering it (`--json`) |
|
|
56
|
+
| `aitk gov superseded` | Report where the tree still asserts a value a changed convention no longer produces, keyed on the value and on the family stem behind a templated citation (`--json`) |
|
|
57
|
+
| `aitk gov restated` | Report every instruction the always-loaded file or a rule shares with the seed, a shipped skill body, or another rule, classed and with its anchors named (`--json`) |
|
|
58
|
+
| `aitk secrets scan` | Report credential-shaped values in the tree the package ships, keyed on issued values rather than on words (`--json`) |
|
|
59
|
+
| `aitk deps audit` | Report published advisories against the resolved dependency set, refusing rather than reporting clean when the index is unreachable (`--json`) |
|
|
60
|
+
| `aitk labels audit` | Report the labels a changed set earns from the pull request label map and the paths no row reaches (`--json`) |
|
|
61
|
+
| `aitk census [path]` | Report tracked file count, a breakdown by extension, and a line total that skips whatever reads as binary (`--json`) |
|
|
62
|
+
| `aitk audits run` | Run every audit as one set, report per check under one verdict, and compare each count to the recorded baseline (`--json`, `--record`) |
|
|
63
|
+
| `aitk audits list` | List every audit the set runs, with the corpus each reads and whether it gates (`--json`) |
|
|
64
|
+
| `aitk inventory [subject]` | Walk every route a project declares and group its elements by the property each computes, as a listing rather than a gate (`--json`) |
|
|
65
|
+
| `aitk capture [source]` | Render HTML capture sources to PNG, toolkit-only and absent from an installed package |
|
|
66
|
+
| `aitk serve [dir]` | Serve a directory on the loopback interface and print the link that opens it, running until interrupted (`--port`, `--entry`, `--json`) |
|
|
67
|
+
| `aitk upgrade` | Reinstall the CLI globally with the package manager the install path names (`--json`) |
|
|
68
68
|
|
|
69
69
|
`aitk serve` ships and drives no browser, which is what separates it from the two that do. A generated page loses its stylesheet and its script to an editor preview and to a `file://` open, so the link is the delivery rather than a convenience, and every generated surface here reaches a reader through one. It binds `127.0.0.1` and never a wildcard, because what it is pointed at is routinely a gitignored record tree. It sends `cache-control: no-store`, since a preview exists to be edited and reloaded and a cached stylesheet reads as a fix that did not work.
|
|
70
70
|
|
package/docs/agents/index.md
CHANGED
|
@@ -30,12 +30,12 @@ CLI catalog and invocation rules for agents, split by command domain. Start with
|
|
|
30
30
|
- [Routing report](routing.md): Reading per CLAUDE.md section how many bullets name a path, what counts as naming one, when a rule counts as covering it, the two refusals, and why the verb reports rather than gates
|
|
31
31
|
- [Sandbox](sandbox.md): Scenario routing, the expectation scoring surface, and the coverage census over scenarios and skills
|
|
32
32
|
- [Scripting](scripting.md): The runtime catalogs that replace hardcoded names, what each carries, and a headless invocation per domain
|
|
33
|
-
- [Sessions](sessions.md): Resolving live peer sessions to the worktree and branch each holds,
|
|
33
|
+
- [Sessions](sessions.md): Resolving live peer sessions to the worktree and branch each holds, reading which row is the caller, the liveness confidence field, and what each session surface can see
|
|
34
34
|
- [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
|
|
35
35
|
- [Citation reach](skills-reach.md): Reporting the skill bodies that cite a path no target project receives, which corpus the verb reads, the ownership key that decides what counts, the one-word qualifier that marks a citation as decided, and why the verb reports instead of gating
|
|
36
36
|
- [Standard success criteria](standards-audit.md): Reading the corpus against the Success criterion gate, why the check scopes to arrival rather than the whole corpus, and the exit codes it sets
|
|
37
37
|
- [State-scoped risk](state-scoped-risk.md): Reading committed state rather than an arriving change, the shipped-tree corpus the secret scan reads, what it keys on and how a deliberate value is exempted, the advisory check and its network failure mode, and why one gates while the other reports
|
|
38
|
-
- [Superseded values](superseded.md): Reading where the tree still asserts a value a changed convention no longer produces, why the sweep keys on the value rather than the file, the exemption marker, the blind
|
|
38
|
+
- [Superseded values](superseded.md): Reading where the tree still asserts a value a changed convention no longer produces, why the sweep keys on the value rather than the file, the family stem behind a templated citation, the exemption marker, the blind spots it cannot reach, and why it reports rather than gates
|
|
39
39
|
- [Targets](targets.md): The projects this toolkit installed into, the record the install writes against the sweep that backs it, what bounds each answer, and the cross-target pull request read
|
|
40
40
|
- [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
|
|
41
41
|
- [Teach](teach.md): Listing learning workspaces and the ordinal a new one takes, opening one with its required files, recording sources and glossary terms, resolving what the next lesson needs before it is written, the refusal reasons, and why every write here runs through a verb
|
package/docs/agents/sessions.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Sessions
|
|
3
|
-
description: Resolving live peer sessions to the worktree and branch each holds,
|
|
3
|
+
description: Resolving live peer sessions to the worktree and branch each holds, reading which row is the caller, the liveness confidence field, and what each session surface can see
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Sessions
|
|
@@ -14,6 +14,7 @@ aitk sessions list
|
|
|
14
14
|
aitk sessions list --json
|
|
15
15
|
aitk sessions list --branch feat/parser --json
|
|
16
16
|
aitk sessions list --branch chore/agents --repository ../caret --json
|
|
17
|
+
aitk sessions list --self --json
|
|
17
18
|
```
|
|
18
19
|
|
|
19
20
|
| Option | Behavior |
|
|
@@ -21,10 +22,11 @@ aitk sessions list --branch chore/agents --repository ../caret --json
|
|
|
21
22
|
| `--json` | Add a machine-readable record on stdout |
|
|
22
23
|
| `--branch <name>` | Report the sessions holding this branch |
|
|
23
24
|
| `--repository <path>` | Answer about this project rather than the working one |
|
|
25
|
+
| `--self` | Report the caller's own row |
|
|
24
26
|
|
|
25
27
|
It reads and never writes. The question it answers is which session to address when work has to reach the one holding a given branch, which a session listing cannot answer on its own.
|
|
26
28
|
|
|
27
|
-
Exit codes: `0` the roster was read, `1` refused. The refusal carries a `reason` of `no-registry` or `no-
|
|
29
|
+
Exit codes: `0` the roster was read, `1` refused. The refusal carries a `reason` of `no-registry`, `no-repository`, `no-self-identity`, or `no-self-row`.
|
|
28
30
|
|
|
29
31
|
An exit code says nothing about a call made from a session, since a shell profile may wrap the binary in a function taking its status from a later command. Read the record's `reason` rather than the exit when a skill consumes this.
|
|
30
32
|
|
|
@@ -52,6 +54,29 @@ The ref read covers the local head and the remote-tracking ref, which means it s
|
|
|
52
54
|
|
|
53
55
|
Two flags say which reading came up short. `sessionsReadable` is `false` when the session roster could not be read, and `refsReadable` is `false` when the ref read failed. Either one leaves `claimed` covering the readings around it alone, so a `false` there is a report that ran short of evidence rather than a report that the branch is clear. They stay separate fields because a caller told the roster failed goes and looks at the roster, and folding both into one flag would send it to the wrong place.
|
|
54
56
|
|
|
57
|
+
## Which row is the caller
|
|
58
|
+
|
|
59
|
+
`--self` narrows the report to the row belonging to the session making the call. A dispatcher reads it to learn the `sessionId` it carries into a launch, because the roster returns every field on every row and marks none of them as the caller.
|
|
60
|
+
|
|
61
|
+
Three identifier namespaces reach a session and two of them join to a row. Four variables spell them:
|
|
62
|
+
|
|
63
|
+
- `CLAUDE_CODE_SESSION_ID` holds the roster's own `sessionId`, and is read first because it survives a rename.
|
|
64
|
+
- `CLAUDE_PID` holds the caller's process id, which every row already carries as `pid`.
|
|
65
|
+
- `CLAUDE_CODE_MESSAGING_SOCKET` spells that same pid in its basename. It is read last, since the spelling is a client convention rather than a published interface and a client that moves the socket drops this rung alone.
|
|
66
|
+
- `CLAUDE_CODE_HOST_SESSION_ID` is never read. It carries a `local_`-prefixed value from the harness namespace that matches no row, and it is the variable a reader searching the environment for a session id finds first.
|
|
67
|
+
|
|
68
|
+
The read refuses rather than returning an empty roster, on the same ground as `no-registry`. A `no-self-identity` refusal means the environment stated none of the three, which is a client identifying its sessions some other way. A `no-self-row` refusal means it stated one and no live row carries it, which is what a session running outside a local process gets.
|
|
69
|
+
|
|
70
|
+
## What each surface can see
|
|
71
|
+
|
|
72
|
+
The roster this verb reads and the channel a session sends messages on enumerate different populations, and neither contains the other. Read at one moment, `aitk sessions list` returned 6 rows against the 13 peers plus caller the agent listing reported. The roster held a background session at confirmed confidence on two reads a minute apart that the listing never carried, so a live session sat here with no way to reach it. Nine Remote Control sessions ran the other way, reachable there with no row here at all, since they leave no local process for the registry to record.
|
|
73
|
+
|
|
74
|
+
That bounds what a carried identifier buys. Resolving a `sessionId` to a name here can produce a name the send channel rejects, and `--self` answers nothing for a controller driving from Remote Control, which is the operator working from their phone rather than an edge case. A caller that cannot resolve an addressee reports the failed resolution instead of falling back to a guess.
|
|
75
|
+
|
|
76
|
+
The `name` field is what both surfaces agree on, and that agreement is what makes the resolution work. `SendMessage` takes a name and carries no identifier parameter, so the carry runs id to name to send rather than sending an id anywhere.
|
|
77
|
+
|
|
78
|
+
Agreement is not uniqueness, and the last hop is where that bites. Two live sessions can hold one name, the roster carries no field that separates them, and a send to the bare name reaches whichever the channel resolves first. The agent listing prints a ref beside each row and the roster does not, so a name resolving to more than one live row is completed from that listing rather than from anything this verb returns.
|
|
79
|
+
|
|
55
80
|
## Why the verb exists
|
|
56
81
|
|
|
57
82
|
A session listing reports a name, a kind, a status, and how long each session has been running. None of those names a branch. Resolving a branch to a session therefore meant ordering the roster by start time and matching it against the order the worktrees were created, which is an inference that fails whenever two sessions start inside the same minute.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Superseded values
|
|
3
|
-
description: Reading where the tree still asserts a value a changed convention no longer produces, why the sweep keys on the value rather than the file, the exemption marker, the blind
|
|
3
|
+
description: Reading where the tree still asserts a value a changed convention no longer produces, why the sweep keys on the value rather than the file, the family stem behind a templated citation, the exemption marker, the blind spots it cannot reach, and why it reports rather than gates
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Superseded values
|
|
@@ -30,11 +30,31 @@ The slug transform is what proved it. Dropping the type segment left four fixtur
|
|
|
30
30
|
|
|
31
31
|
The whole corpus git lists: tracked files plus untracked ones git does not ignore. The untracked half keeps a file added on this branch in scope rather than one push later.
|
|
32
32
|
|
|
33
|
-
Matching is a literal substring,
|
|
33
|
+
Matching is a literal substring, for the value and for the family stem below it alike, so either one carrying regular-expression characters means what it says. Every occurrence on a line reports under its own column, since a line carrying the value twice is two edits, and a column both kinds reach reports once as the literal one.
|
|
34
34
|
|
|
35
35
|
Binary files are skipped on a NUL byte rather than on an extension list, and so is any listed path that will not open. Both are counted. A run states the files it opened against the files git listed, because a count of what passed reads as a verdict on the repository unless it also says how much it left out.
|
|
36
36
|
|
|
37
|
-
Pass an empty replacement to retire a value outright, as in `aitk gov superseded feature-feat- ""`. Findings report the same way
|
|
37
|
+
Pass an empty replacement to retire a value outright, as in `aitk gov superseded feature-feat- ""`. Findings report the same way, none is annotated, since a line cannot carry a replacement that does not exist, and no templated form is read, since there is no second value for a stem to diverge from.
|
|
38
|
+
|
|
39
|
+
## The templated citation
|
|
40
|
+
|
|
41
|
+
A citation naming a family as a pattern carries neither value. `aitk-*` and `internal-<X>` are the two forms this corpus writes, and a literal comparison matches neither, so a rename running the verb once per name reports clean while the family citations stay stale. Two of those on `#1250` had inverted, stating the old prefix as a guard, which left a rule instructing the next session to flag the correct naming as a mismatch.
|
|
42
|
+
|
|
43
|
+
Beside the literal comparison the run matches a family stem, derived from the segment the two values actually differ on, with everything they share carried ahead of it. `toolkit-operator` to `aitk-operator` derives `toolkit`, and `aitk-cli` to `aitk-shell` derives `aitk-cli` rather than `aitk`, which is what keeps a rename of one folder off every sibling in its family.
|
|
44
|
+
|
|
45
|
+
Three forms report, decided by the character after the stem and its separator:
|
|
46
|
+
|
|
47
|
+
| Form | Shape | What it names |
|
|
48
|
+
| ------------- | ------------ | ---------------------------------- |
|
|
49
|
+
| `glob` | `<stem>-*` | the family written as a pattern |
|
|
50
|
+
| `placeholder` | `<stem>-<X>` | the family with a stand-in segment |
|
|
51
|
+
| `prefix` | `<stem>-` | the family written bare |
|
|
52
|
+
|
|
53
|
+
The stem has to start a name. A letter, a digit, an underscore, or a separator directly before it means the stem sits mid-name, which is what a temp-directory prefix such as `aitk-check-toolkit-` looks like, and a path separator or a backtick before it means a citation, which is what `claude/skills/toolkit-*` looks like.
|
|
54
|
+
|
|
55
|
+
A hit under any of the three counts as a finding and moves the exit code. A stale templated citation is as real as a literal one, and reporting it outside the count would recreate the silence being fixed one report shape further along.
|
|
56
|
+
|
|
57
|
+
Every hit in a markdown file carries the nearest heading above it. A line reads differently under the section holding it, and `Use the aitk-* prefix on an internal skill` is a prohibition under `## Must not` and an instruction anywhere else. A reviewer reading that line without its heading made exactly that misreading against this tree.
|
|
38
58
|
|
|
39
59
|
## The exemption marker
|
|
40
60
|
|
|
@@ -42,15 +62,23 @@ A declaration disagreeing with a convention for a stated reason carries `aitk-al
|
|
|
42
62
|
|
|
43
63
|
Only a marker naming a reason counts. A bare token is a line that meant to say something and did not, and honoring it would let a typo mute a finding. This is the `aitk-allow-secret` shape, and both read the same placement rule through one helper.
|
|
44
64
|
|
|
45
|
-
## The blind
|
|
65
|
+
## The blind spots
|
|
66
|
+
|
|
67
|
+
The sweep sees the value, its stem, and nothing else. A prose reference that went stale without carrying either is invisible here, which is not hypothetical: alongside the mechanical instances, one declaration had gone stale by citing the wrong standard for the transform, and it matches no string this sweep could have been given.
|
|
68
|
+
|
|
69
|
+
The second is a family written in a form the three shapes do not read: a bracket style other than `<>`, a glob with no separator ahead of it, or the family described in words. Adding a form is a change to the classifier rather than a name a caller can pass, since a list of names cannot reach this class by construction, which is the whole finding behind the stem.
|
|
70
|
+
|
|
71
|
+
A value sweep closes most of the first class and no part of either one. The help text and the frame name both on every run, so a clean report is not read as a clean tree.
|
|
72
|
+
|
|
73
|
+
## The false-positive rate
|
|
46
74
|
|
|
47
|
-
|
|
75
|
+
Over-reporting is the design here as it is for the literal half, and the corpus bounds it. Sweeping `toolkit-operator` to `aitk-operator` over this tree named one templated hit outside the change's own fixtures, a passage recording the retired `toolkit-` prefix as history, which reads correctly in place.
|
|
48
76
|
|
|
49
|
-
A
|
|
77
|
+
A version reporting a page of hits teaches the next rename to skip the verb, which is worse than the blind spot being fixed. Read a report against that rate rather than against zero.
|
|
50
78
|
|
|
51
79
|
## Exit codes
|
|
52
80
|
|
|
53
|
-
Exit codes are `0` when nothing asserts the superseded value, `1` for a refusal, and `2` for at least one finding. It refuses an empty superseded value, which would match every line rather than a convention, a superseded value equal to its replacement, which means no convention changed, and a tree git cannot list, since an empty list passes each of its zero files. An empty replacement is not among them, because retiring a value is an ordinary reason to run this.
|
|
81
|
+
Exit codes are `0` when nothing asserts the superseded value or its family, `1` for a refusal, and `2` for at least one finding of either kind. It refuses an empty superseded value, which would match every line rather than a convention, a superseded value equal to its replacement, which means no convention changed, and a tree git cannot list, since an empty list passes each of its zero files. An empty replacement is not among them, because retiring a value is an ordinary reason to run this.
|
|
54
82
|
|
|
55
83
|
Nothing wires this into `bun run check` or into a hook. A value sweep over-reports by construction, and gating a measure carrying a known false-positive class is what teaches contributors to route around the stage. `aitk gov test-order` is the sibling precedent.
|
|
56
84
|
|
package/package.json
CHANGED
package/src/commands/gov.ts
CHANGED
|
@@ -306,18 +306,31 @@ export function register(program: Command): void {
|
|
|
306
306
|
`\`${SUPERSEDED_MARKER}: <reason>\` marker on its own line or the one above.`,
|
|
307
307
|
'',
|
|
308
308
|
'Pass an empty replacement to retire a value outright. Findings report',
|
|
309
|
-
'the same way
|
|
310
|
-
'replacement that does not exist
|
|
309
|
+
'the same way, none is annotated, since a line cannot carry a',
|
|
310
|
+
'replacement that does not exist, and no templated form is read, since',
|
|
311
|
+
'there is no second value for a stem to diverge from.',
|
|
311
312
|
'',
|
|
312
|
-
'
|
|
313
|
+
'Templated forms, matched on the segment the two values differ on:',
|
|
314
|
+
' glob <stem>-* , the family written as a pattern',
|
|
315
|
+
' placeholder <stem>-<X> , the family written with a stand-in segment',
|
|
316
|
+
' prefix <stem>- , the family written bare',
|
|
317
|
+
'',
|
|
318
|
+
'A hit under one of them counts as a finding, since a stale templated',
|
|
319
|
+
'citation is as real as a literal one. Each carries the nearest heading',
|
|
320
|
+
'above it in a markdown file, because a line reading as a prohibition',
|
|
321
|
+
'under one section reads as an instruction under another.',
|
|
322
|
+
'',
|
|
323
|
+
'Blind spots:',
|
|
313
324
|
' a prose reference that went stale without carrying the value, such as',
|
|
314
325
|
' a declaration citing the wrong standard for the transform, matches',
|
|
315
326
|
' nothing here and is reached by reading rather than by this sweep',
|
|
327
|
+
' a family named in any other form, such as a bracket style other than',
|
|
328
|
+
' <>, a trailing glob with no separator, or a description in words',
|
|
316
329
|
'',
|
|
317
330
|
'Exit codes:',
|
|
318
|
-
' 0 nothing in the corpus asserts the superseded value',
|
|
331
|
+
' 0 nothing in the corpus asserts the superseded value or its family',
|
|
319
332
|
' 1 refused, with the reason on stderr or in the JSON record',
|
|
320
|
-
' 2 at least one declaration
|
|
333
|
+
' 2 at least one declaration asserts either',
|
|
321
334
|
'',
|
|
322
335
|
'Examples:',
|
|
323
336
|
' aitk gov superseded feature-feat- feature-',
|
|
@@ -520,7 +533,37 @@ function describeHit(hit: SupersededHit): string {
|
|
|
520
533
|
const note = hit.carriesReplacement
|
|
521
534
|
? ' (the replacement is on this line)'
|
|
522
535
|
: ''
|
|
523
|
-
|
|
536
|
+
const section = hit.heading === undefined ? '' : ` under ${hit.heading}`
|
|
537
|
+
return `[${hit.match}] ${hit.file}:${hit.line}:${hit.column}${section}${note}: ${hit.preview}`
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Named separately from the literal hits rather than counted in with them. A
|
|
542
|
+
* templated hit is a wider match on a shorter string, so a reader weighing one
|
|
543
|
+
* is weighing a different question, and the section is where the forms it still
|
|
544
|
+
* cannot read are stated.
|
|
545
|
+
*/
|
|
546
|
+
function reportTemplated(
|
|
547
|
+
report: Extract<SupersededReport, { kind: 'measured' }>,
|
|
548
|
+
): void {
|
|
549
|
+
const templated = report.findings.filter((hit) => hit.match !== 'literal')
|
|
550
|
+
|
|
551
|
+
logStep('Templated')
|
|
552
|
+
if (report.stems === undefined) {
|
|
553
|
+
logInfo(
|
|
554
|
+
'no stem derives from these two values, so no templated citation was read',
|
|
555
|
+
)
|
|
556
|
+
} else if (templated.length === 0) {
|
|
557
|
+
logInfo(
|
|
558
|
+
`nothing names the family as ${report.stems.superseded}-*, ${report.stems.superseded}-<X>, or ${report.stems.superseded}- bare`,
|
|
559
|
+
)
|
|
560
|
+
} else {
|
|
561
|
+
for (const hit of templated) logWarn(describeHit(hit))
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
logInfo(
|
|
565
|
+
'not read: a family named in any other form, such as a bracket style other than <>, a trailing glob with no separator, or a description in words',
|
|
566
|
+
)
|
|
524
567
|
}
|
|
525
568
|
|
|
526
569
|
function reportSuperseded(
|
|
@@ -531,14 +574,26 @@ function reportSuperseded(
|
|
|
531
574
|
|
|
532
575
|
logStep('Sweep')
|
|
533
576
|
logInfo(`${report.superseded} → ${report.replacement} in ${root}`)
|
|
577
|
+
logInfo(
|
|
578
|
+
report.stems === undefined
|
|
579
|
+
? 'no family stem, so the sweep is the literal value alone'
|
|
580
|
+
: `family stem ${report.stems.superseded} → ${report.stems.replacement}`,
|
|
581
|
+
)
|
|
534
582
|
|
|
535
|
-
|
|
536
|
-
|
|
583
|
+
const literal = report.findings.filter((hit) => hit.match === 'literal')
|
|
584
|
+
|
|
585
|
+
// Named for the kind rather than for a verdict. `Clean` over the literal half
|
|
586
|
+
// alone would read as a clean tree on a run whose templated half is the one
|
|
587
|
+
// carrying every finding.
|
|
588
|
+
logStep('Literal')
|
|
589
|
+
if (literal.length === 0) {
|
|
537
590
|
logInfo('nothing in the corpus asserts the superseded value')
|
|
538
591
|
} else {
|
|
539
|
-
for (const finding of
|
|
592
|
+
for (const finding of literal) logWarn(describeHit(finding))
|
|
540
593
|
}
|
|
541
594
|
|
|
595
|
+
reportTemplated(report)
|
|
596
|
+
|
|
542
597
|
// Named rather than counted. A muted line is a judgment someone recorded,
|
|
543
598
|
// and a reader weighing this report has to be able to reach the reason.
|
|
544
599
|
logStep('Exempt')
|