Skip to content

feat(synth): list loadable skills in each Claude agent file and lint the preload budget - #151

Draft
knihit wants to merge 7 commits into
feat/agent-skill-indexfrom
feat/claude-preload-lint
Draft

knihit wants to merge 7 commits into
feat/agent-skill-indexfrom
feat/claude-preload-lint

Conversation

@knihit

@knihit knihit commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Description

Stack: 2 of 9 in the skills stack, directly after #120. Base: feat/agent-skill-index (#120). Depends on #120. First of three PRs that replace #137, split so each can be reviewed on its own: this one adds the measuring and the lint, the next trims the agent specs, the third updates the guide.

Claude Code injects the full SKILL.md of every name in an agent's clientConfig.claudeCli.skills into each subagent it spawns, and that text is re-sent on every turn. Nothing measured or limited it.

CLI:

  • konductor synth warns (konductor: warning:) when an agent's preload passes 32,768 B or Claude Code's 32-name cap, and names the dropped skills. On this branch's own tree it prints 9 such warnings, which the next PR removes by trimming the specs.
  • synth -v prints a claude preload: line per agent ("preloads N B across K skills") and --json carries a claude_preload array. Both use the same measuring function as the warning.
  • The generated Claude agent file ends with a "Skills you can load" block listing declared skills that are not preloaded. The frontmatter emits each preload name once.
  • synth warns when an agent lists on-demand skills but cannot use the Skill tool, listing each skill once.
  • New e2e test cli/konductor-rs/tests/synth_claude_preload_e2e.rs: a fat fixture skill trips the byte budget, read from synth --json; scratch copies are removed after each test.
  • cli/README.md documents the warning and the new -v / --json output.
  • CHANGELOG.md: [Unreleased] bullet. No VERSION change.

Type of Change

  • CLI (cli/) change: Rust
  • Documentation

Testing

  • npm test: not run (no JS changed).
  • cd cli && make test passes
  • Gate on this branch's head, and on the top of the stack (feat/slim-cypress-test-implementation, which contains it): make build && make synth, cd cli && make test (1,836 Rust tests on the top, 0 failed), make test-skills-sh, uvx --with pyyaml pytest -q tests/ (468 passed on the top), make claude-plugin-check. All pass. On this head alone, synth prints the 9 expected preload warnings.
  • New or changed code files carry the required SPDX header

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own changes
  • I have commented my code where necessary
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings: cd cli && make lint passes
  • I have added or updated tests that prove my change works

Agents Affected

Generated Claude Code agent files gain the "Skills you can load" block; no spec changes here.

Notes for Reviewers

  • Review: feat(claude): trim each agent's skill preload and warn on oversized preloads #137 was reviewed before the split (5 findings, all fixed), then each split PR went through adversarial review in rounds until 0 CRITICAL and 0 IMPORTANT findings remained (3 rounds on this one, none CRITICAL or IMPORTANT). Fixes on this branch: the missing Skill grant warning, a scratch-dir drop guard, a self-contained fixture skill, "across N skills" wording and de-duplicated names.
  • Benchmark figures are in the trim PR above this one, which is where the cost changes.

Nihit Kasabwala added 7 commits October 30, 2026 01:17
…the preload budget

Each generated Claude Code agent file now lists the skills the agent can
load on demand, and synth warns when an agent's claudeCli.skills preload
passes 32 KiB or 32 names. `synth --json` reports the preload per agent.

The e2e test checks the lint on fixture agents only. It no longer copies
the budget, the name cap or the thousands formatter (F5): the fat-fixture
test reads the byte count from `synth --json`. The tests that assert this
repo is under budget move to the agent-trim change, since every agent but
two is over budget on this tree.

Verified on this commit:
- make build && make synth: pass (9 expected preload warnings)
- cd cli && make test: pass
- make test-skills-sh: pass (10 passed)
- uvx --with pyyaml pytest -q tests/: pass (223 passed)
- make claude-plugin-check: pass
The preload lint counts distinct claudeCli.skills names, but the agent
file shipped the raw list, duplicates included. Emit the deduplicated
list (first occurrence wins) so the name cap measures what Claude Code
reads.

Verified on feat/claude-preload-lint: make build && make synth exit 0
(9 expected preload warnings on this tree); cd cli && make test exit 0
(lib 1783 passed, all integration suites ok); make test-skills-sh exit 0;
uvx --with pyyaml pytest -q tests/ 223 passed; make claude-plugin-check
exit 0 (1 non-blocking ICON_MISSING directory warning).
…the Skill tool

The Claude agent file tells the agent to load its non-preloaded skills
with the Skill tool. An explicit clientConfig.claudeCli.tools list
without Skill makes that impossible, so synth now warns for it. Three
unit tests cover the warning, the empty list and the silent cases.

Verified: cargo test --bin konductor claude_ (121 passed).
The warning read 'preloads 40,000 B over 1 clientConfig.claudeCli.skills',
which looks like a comparison and gives the count no noun.

Verified: cargo test --bin konductor claude_preload (8 passed).
Each test copied the repo tree into a temp dir and never removed it.
A drop guard now removes it, also when an assertion fails, matching the
sibling synth e2e tests.

Verified: cargo test --test synth_claude_preload_e2e (3 passed); the
count of konductor-synth-claude-preload-e2e-* dirs in TMPDIR did not grow.
…kill

The budget test preloaded the shipped dynamodb-design skill and relied
on it staying over 32 KiB. It now writes a 40 KiB fixture skill, the
same helper the dynamodb-design slimming change adds, so this PR's test
does not depend on unrelated content.

Verified: cargo test --test synth_claude_preload_e2e (3 passed).
…rning

A spec that repeats a name in dependencies.skills.skillNames got "has 2
declared skill(s) ... cannot load them: b, b", while the agent file lists
b once. The check now collects into an IndexSet, as
render_on_demand_skills_block does, and the unit test repeats b and
expects a count of 1.

Gate on this tree, from the worktree root:
- make build && make synth: pass
- cd cli && make test: pass (1834 passed, 0 failed)
- make test-skills-sh: pass (10 scripts)
- uvx --with pyyaml pytest -q tests/: pass (223 passed)
- make claude-plugin-check: pass

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant