Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
bump: patch
---

### Changed

- The README, `/context-budget:audit` and its engine and report references no longer restate
upstream behavior: what `/context` itemizes, the skill-frontmatter subtraction from
`System tools` (now recorded as the engine's own observation), the bundled `explain-usage`
skill's description, the skill listing budget's unit, and what `/skill-doctor` and `/doctor`
cover. Each keeps its own rule and links the upstream section, or the local record where no
upstream page documents the fact, with an as-of date and a recheck trigger.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
bump: patch
---

### Changed

- The permission preflight reference, the tracker seam reference, `/work-items:attend-queue`,
`/work-items:setup`, the work-loop telemetry upsert reference and the GitHub adapter README no
longer restate upstream behavior: permission rule matching, when git sets `core.worktree`, the
`jq` install on Windows, `gh` flag spellings, `--limit` defaults, `--reason` values, `gh api`
field and placeholder handling, the sub-issue `--json` projection, GitHub search qualifiers, REST
pagination and assignee responses, closing keywords and linkage, `includeClosedPrs`,
cloud-session API refusals and issue form labels. Each keeps its own rule and links the upstream
section with an as-of date and a recheck trigger. The adapter README's "Edit labels / assignees"
recipe now shows the `--remove-assignee "@me"` call attend-queue and triage use.
16 changes: 9 additions & 7 deletions plugins/context-budget/README.md
Comment thread
melodic-automation-lanes[bot] marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
Measure a Claude Code session's fixed startup context payload **per item**, on your machine, at a
pinned binary, and record what every trim actually saved.

Per-skill, per-agent, and per-MCP-tool attribution stays with the built-in `/context` command.
This plugin covers what our measurements see `/context` report only as totals: the built-in tool
pools, `System tools` and `System tools (deferred)`. Together they are typically the largest
single contributor to the fixed payload, which is why the plugin targets them. It attributes them
per tool by A/B differencing: a baseline headless session versus one session per candidate
This plugin attributes the built-in tool pools, `System tools` and `System tools (deferred)`, per
tool. Together they are typically the largest single contributor to the fixed payload, which is
why the plugin targets them. The rest of the breakdown stays with the built-in `/context` command;
what it itemizes is read at its row in
[commands § All commands](https://code.claude.com/docs/en/commands#all-commands)
(as of 2026-11-03; recheck when that row changes what `/context` itemizes). The plugin attributes
the pools by A/B differencing: a baseline headless session versus one session per candidate
tool with that tool denied by bare name. The two attributed buckets compose differently:
deferred-side deltas add, so a basket's deferred saving is the sum of its members, while
prefix-side deltas double-count, so their sum is only an upper bound on the basket's prefix
Expand Down Expand Up @@ -192,8 +194,8 @@ tool needs its own probe, and NotebookEdit was not probed.
- **Every report is stamped** with the measured binary path and version, the measurement mode,
and the session kind. Machines with two CLI installs get an answer per binary, not a blend.
- **Comparability is enforced, not advised.** `System tools` deltas are only valid between runs
with identical skill listings (listed skill frontmatter is subtracted from that bucket); the
engine fingerprints the listing per run and marks violating comparisons incomparable rather
with identical skill listings (why: `skills/audit/reference/engine.md` "Comparability rules");
the engine fingerprints the listing per run and marks violating comparisons incomparable rather
than reporting their numbers.
- **Levers are catalogued data.** Each row in
`skills/audit/reference/levers.json` carries its honesty category (does it remove weight, work
Expand Down
14 changes: 7 additions & 7 deletions plugins/context-budget/skills/audit/SKILL.md
Comment thread
melodic-automation-lanes[bot] marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ Two rules govern everything this skill says, per the plugin's
One native surface also answers "what is using my tokens", and the two get conflated when a
session feels crowded:

- **`explain-usage` (bundled skill)**: after the fact, explains where the current session's tokens
went, with one simple chart in plain language. The model and the person can both invoke it where
it resolves.
- **`explain-usage` (bundled skill)**: what it does and who can invoke it are recorded in
[`reference/native-explain-usage.md`](reference/native-explain-usage.md). No upstream page
documents it: the commands and skills pages and the docs index carry no entry (as of 2026-11-03;
recheck when the commands page gains an `/explain-usage` row or a release note names it).
- **This skill (marketplace plugin).** Measures the fixed startup payload of a fresh headless
session per item, including the built-in tool pools `/context` shows only as totals, and keeps a
before/after ledger for every lever the operator toggles.
Expand Down Expand Up @@ -334,10 +335,9 @@ otherwise use the payload's share of the measured window.

Each of these produces a confidently wrong number unless the engine's guard is honored:

- **Removing skills makes `System tools` rise.** Listed skill-frontmatter tokens are subtracted
from that bucket, so a run that changes the skill listing shifts `System tools` with no tool
changing state; read naively, a safe-mode run looks as if safe mode loads deferred tools. The
signature check catches this; never hand-compare two snapshots the engine marked incomparable.
- **`System tools` moves with the skill listing.** The signature check catches a run whose
listing differed (why: [`reference/engine.md`](reference/engine.md) "Comparability rules");
never hand-compare two snapshots the engine marked incomparable.
- **Unredirected stdin prepends a warning line** to headless output, which breaks naive parsing.
The engine redirects and strips; if you capture `/context` by hand for `parse-context`, redirect
stdin or expect the leading line.
Expand Down
11 changes: 7 additions & 4 deletions plugins/context-budget/skills/audit/reference/engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,17 @@ Each row is our decision; what the upstream section says about it is read live a
record the last row relays changes its pointer or its heading moves.

Where the engine's behavior rests on empirical observation rather than documentation (headless
`/context`, the skill-listing subtraction below), the record says so in `caveats`. The engine
`/context`, the skill-listing signature below), the record says so in `caveats`. The engine
reports the observation and never silently assumes it durable.

## Comparability rules (enforced, not advisory)

1. **Skill-listing signature.** The prefix `System tools` bucket has listed skill-frontmatter
tokens subtracted from it, so its value is only meaningful relative to a run with an identical
skill listing. Every snapshot carries `skillListing.signature`, a hash of the sorted
1. **Skill-listing signature.** The prefix `System tools` value is treated as meaningful only
relative to a run with an identical skill listing, because the engine observes it moving with
the listing. That is an observation, not documentation: the `/context` row in
[commands § All commands](https://code.claude.com/docs/en/commands#all-commands) does not
itemize the bucket (as of 2026-11-03; recheck when that row documents what `System tools`
counts). Every snapshot carries `skillListing.signature`, a hash of the sorted
(name, source) listing. On a mismatch, `compare`/`attribute` mark `systemToolsComparable: false`
and put the reason in `comparability.reasons`. The deferred bucket is a separate pool
and listing or Skills-token drift does not poison it: per-bucket additivity applies this gate
Expand Down
14 changes: 8 additions & 6 deletions plugins/context-budget/skills/audit/reference/report.md
Comment thread
melodic-automation-lanes[bot] marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ mode; the displayed fraction in cli-parse mode).
not measurable rather than as not additive. Unmeasured tools (candidates this run
that were not priced) are listed as unmeasured, not omitted. Silence reads as "measured
zero". Some tools exist only in an interactive session; [`interactive-only-tools.json`](interactive-only-tools.json)
names them, plus the interactive-only MCP server class (relayed as of 2026-10-11; recheck this
relay when that file moves or its `tools` list or `notes` change). These are listed as
names them, plus the interactive-only MCP server class (relayed as of 2026-10-11; recheck when
that file moves or its `tools` list or `notes` change). These are listed as
**known-uncovered**, a distinct category from unmeasured-but-candidate, because they were
never candidates in this headless sweep. The names come from the attribution record's
`knownUncovered.tools` (product-level surfaces) plus `knownUncovered.notes` (the
Expand All @@ -48,14 +48,16 @@ mode; the displayed fraction in cli-parse mode).
measured resolution where the row has one), the measured or measurable delta, the exact
emitted config, and the official citation. A row with `saving: "runtime-resolved"` does not
print its stored category as the saving; print the measured resolution, including an explained
zero when the listing cap is saturated. The listing cap is characters, not the Skills token
total. A row with `measurementScope: "unmeasurable-in-this-session-kind"` is its own group,
zero when the listing cap is saturated; what the cap counts is read at
[skills § Skill descriptions are cut short](https://code.claude.com/docs/en/skills#skill-descriptions-are-cut-short)
(as of 2026-11-03; recheck when that section changes the listing budget's unit). A row with `measurementScope: "unmeasurable-in-this-session-kind"` is its own group,
"unmeasurable in this session kind", and is not reported as a measured zero. Grouped by
category, `removes-weight` first. Postures bind: `never-recommend` rows appear under a
"priced, not recommended" heading; `report-only` vendor weight closes the group as the honest
floor.
6. **Routes.** The catalogue's route-outs (`/skill-doctor` for unused skills and `/doctor` for
unused MCP servers and plugins, both of which the operator runs; memory files, hooks, live occupancy to their owners), each in one line.
6. **Routes.** The catalogue's route-outs (`/skill-doctor` and `/doctor`, both of which the
operator runs, routed and pointed at in [SKILL.md](../SKILL.md) "Scope boundary (route out)";
memory files, hooks, live occupancy to their owners), each in one line.
7. **Degradations and caveats.** Every `caveats[]` entry from the records used, plus anything the
engine could not measure and why. The attribution record already merges the baseline with
each deny run and the combined additivity run, so a deny-run disclosure is in that list and
Expand Down
27 changes: 15 additions & 12 deletions plugins/work-items/reference/permission-preflight.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,13 @@ is interpreter-led, so no allow rule pre-approves it
permission mode decides it, the auto-mode classifier in an unattended lane. It reads the effective `permissions.allow` from the operator's user-global settings
and the project settings. It never runs a live permission probe. A verb counts as covered only by an
**open-glob** grant: `Bash(git commit *)` or `Bash(git commit:*)`. A **bare-exact** rule
(`Bash(git commit)`) is **not** coverage: it permits only the argumentless command, and a work-lane
invocation always carries arguments, so the real call would still prompt. When a gapped verb has
*only* a bare-exact grant, the gap message says so precisely. That grant does cover an argumentless
call but not the work lane's argument-carrying one, and the remedy is to add the open glob
(`git commit *`). A narrower, flag-scoped rule
(`Bash(git commit --amend)`) is likewise not coverage. A missing
(`Bash(git commit)`) or a narrower, flag-scoped one (`Bash(git commit --amend)`) is **not**
coverage, because a work-lane invocation always carries arguments. When a gapped verb has *only* a
bare-exact grant, the gap message names it, and the remedy is to add the open glob
(`git commit *`). What each rule shape matches is read live at
[permissions § Wildcard patterns](https://code.claude.com/docs/en/permissions#wildcard-patterns)
(as of 2026-11-03; recheck when that section changes what a rule with no `*`, or with a trailing
`*`, matches). A missing
verb means the floor is not composed in on this machine; the remediation is to apply the component
operator-side, not to add a one-off rule.

Expand Down Expand Up @@ -168,9 +169,12 @@ one). The candidates:
1. **The probed checkout itself**, whose own git dir *is* the common dir. True whatever the git dir
is named, so the **main checkout of** a `--separate-git-dir` or submodule layout resolves here.
The probed checkout is `--project-root` when given, else the cwd.
2. **`core.worktree`** in the common dir's config, resolved relative to that dir. Git writes it for
submodules, which is what makes a submodule's `<super>/.git/modules/<name>` common dir resolvable at
all, since no parent-of-`.git` arithmetic can invert it.
2. **`core.worktree`** in the common dir's config, resolved relative to that dir. It is the
candidate for a submodule's `<super>/.git/modules/<name>` common dir, which no parent-of-`.git`
arithmetic can invert. Where git sets the key, and how a relative value resolves, is read live
at [git-config § core.worktree](https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreworktree)
(as of 2026-11-03; recheck when that entry changes how a relative value resolves or what
overrides it).
3. **The conventional `<root>/.git` spelling**, the parent of the common dir.

Resolution has three outcomes, and the report distinguishes them:
Expand Down Expand Up @@ -215,9 +219,8 @@ that worktree. Two cases:
in silence.** For a repository created with `--separate-git-dir <path>/.git`, the main working tree is
the directory holding the `.git` *file*, but git records no back-pointer to it. A recursive search
of the whole common dir turns up only `worktrees/<name>/gitdir` entries, which point at *linked*
worktrees; `core.worktree` is unset by every creation path (`git init --separate-git-dir` on a
fresh directory, `git clone --separate-git-dir`, and `git init --separate-git-dir` over an existing
repository). Git's own `git worktree list` therefore reports `<path>` as the main worktree, and
worktrees, and the `core.worktree` candidate resolves only where that key is set (git's entry
above). Git's own `git worktree list` therefore reports `<path>` as the main worktree, and
reports it identically when run *from* that true working tree. That `<path>` is the parent of the
separate git *directory*, not of the `.git` file, which lives in the true working tree and is the
very link git does not record in reverse. `<path>`
Expand Down
14 changes: 7 additions & 7 deletions plugins/work-items/reference/tracker-seam.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ third, the provider **binding**, is discharged differently: a missing binding bl
routes rather than halting unconditionally.

- **`jq`** (`command -v jq`). The actions' snippets parse with it unconditionally. Missing: stop
and surface the install remediation (<https://jqlang.org/download/>; a separate install under Git
Bash on native Windows). Never improvise a parse.
and surface the install remediation, the per-platform install at <https://jqlang.org/download/>
(as of 2026-11-03; recheck when that page moves). Never improvise a parse.
- **The seam script**, `"$TRACKER"` above. The plugin bundles it, so it resolves at the plugin-dir
path by default; if it resolves at **neither** the plugin path nor the project-root fallback, the
plugin install is incomplete: stop and surface that the plugin must be reinstalled or repaired,
Expand Down Expand Up @@ -96,8 +96,8 @@ is nonetheless authoritative for `parent_id`, which is how an item reaches its c
the text of an item, such as a container's Brief or an item's acceptance criteria, is therefore a
**provider-mechanic** read (`gh issue view <n> --repo <owner>/<repo> --json body,title` on GitHub;
the provider's REST equivalent otherwise), and a surface that shows a body read must label it as
such rather than folding it into a seam snippet. That GitHub form is GraphQL-backed, so a sandboxed
session (Claude Code on the web, remote execution) reads over REST instead; the adapter's
such rather than folding it into a seam snippet. A sandboxed session (Claude Code on the web,
remote execution) reads that body over REST instead; the adapter's
operations reference carries the REST substitute and the pointer record under "View item"
(`${CLAUDE_PLUGIN_ROOT}/tools/work-item-tracker/adapters/github/README.md`).
Provider mechanics run unbound, so the read still
Expand Down Expand Up @@ -236,9 +236,9 @@ need attention.
## Gotchas

Skill-behavior failure patterns. Add to this section when new gotchas are discovered.
Provider-mechanic gotchas (Windows `\r`, search-qualifier syntax, the `gh` 30-row default limit,
`--add-label` vs `--label`, `--reason` values, rate limits, Issue-Forms auto-labeling) live in the
bound adapter's operations reference. For GitHub, that is
Provider-mechanic gotchas (Windows `\r`, search syntax, `gh` list limits, label and assignee edit
flags, close reasons, rate limits, labels on programmatic creation) live in the bound adapter's
operations reference. For GitHub, that is
`${CLAUDE_PLUGIN_ROOT}/tools/work-item-tracker/adapters/github/README.md` "Gotchas".

- **Unattended loops hold to the provider's API budget.** Every lane, worker and session under one
Expand Down
11 changes: 6 additions & 5 deletions plugins/work-items/skills/attend-queue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,12 @@ worker lane off the flipped item. Once the row's answer is written

- **When the human blocker is removed:** perform the single-edit role-label flip **while this
session still holds the claim**, then clear `@me` from assignees via the bound adapter's assignee
edit (`--remove-assignee "@me"` for GitHub. See the adapter README "Edit labels / assignees"),
then end the lease with `"$TRACKER" release "<id>" --lease-comment-id <n>`. Never clear the
assignee before the flip: a released row still reads as `[escalated]` in another
attended session's view until the label lands. A brief frontier delay after the flip is
acceptable.
edit (for GitHub, the adapter README "Edit labels / assignees"; the flag is read live at
[gh issue edit § Options](https://cli.github.com/manual/gh_issue_edit#options),
as of 2026-11-03; recheck when that section renames the assignee flags), then end the lease with
`"$TRACKER" release "<id>" --lease-comment-id <n>`. Never clear the assignee before the flip: a
released row still reads as `[escalated]` in another attended session's view until the label
lands. A brief frontier delay after the flip is acceptable.
- **When disposition leaves the item human-gated** (decline, an answered
escalation on a human-floor work class that was not reclassified): clear `@me` via the
same adapter assignee edit once disposition comments are written, still while holding the claim
Expand Down
4 changes: 2 additions & 2 deletions plugins/work-items/skills/setup/SKILL.md
Comment thread
melodic-automation-lanes[bot] marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,8 @@ report INFO naming `/work-items:setup apply` with a user present.
`config.github.wont_do_labels`; an empty pick removes the key.
- **`jira`: classify resolutions.** Modeled on the role-label pass above:
1. **Read the current binding** and present `config.jira.resolutions` when set.
2. **Discover** the instance's resolutions with the paginated
`GET /rest/api/3/resolution/search` (the call, its auth and its fields are
2. **Discover** the instance's resolutions through Jira's resolution search (the call, its
paging, its auth and its fields, with the pointer to Atlassian's Issue resolutions API, are
[`reference/providers.md`](reference/providers.md) "`jira`"). Show each resolution's name and
description, and mark the default one.
3. **Have the user sort each into `completed` or `wont_do`.** You may pre-select a suggestion
Expand Down
2 changes: 1 addition & 1 deletion plugins/work-items/skills/track/actions/list.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ The `#` column is a sequential index for this listing. When the user references

## Search syntax

Provider search qualifiers (label/exclude/assignee/sort/date) and the pass-through behavior of `--search` are documented in the bound adapter's operations reference. GitHub: `${CLAUDE_PLUGIN_ROOT}/tools/work-item-tracker/adapters/github/README.md` "Search items".
Provider search qualifiers (label/exclude/assignee/sort/date) are linked from, and the pass-through behavior of `--search` is documented in, the bound adapter's operations reference. GitHub: `${CLAUDE_PLUGIN_ROOT}/tools/work-item-tracker/adapters/github/README.md` "Search items".
Loading
Loading