ORCHESTKIT · v9.1.0 · 2026-07-26 · 15-agent adversarial audit · branch chore/opus5-trim-assessment

Delete your old rules?
Mostly no. Fix the five bugs hiding behind them.

A verified assessment of whether OrchestKit's 114 skills, 36 agents and rule surface are Opus-5-era dead weight.

1 · The thesis, scored

"Anthropic cut 80 percent of its own rules for Opus 5 and lost nothing. Yours are holding it back too."

ClaimVerdictEvidence
The always-loaded index is a heavy tax FALSE Real session tax is 9,977 tokens total, of which the skill index is 5,867. That is not a problem worth a redesign.
97 unused skills are dead weight FALSE 55 are intentionally hidden (documented 2-tier design, CONTRIBUTING-SKILLS.md:124). 87 are statically wired via agent skills:. 9 are genuinely orphaned.
36 specialists lose to Explore because descriptions are vague FALSE The repo already A/B tested description rewrites: delta-0 routing gain (audit-activation/SKILL.md:92). Descriptions sit at 249 of a hard 250 B CI cap.
Cut ~80 percent like Anthropic did 20% TRUE Defensible cut is 1,868 tok of 9,977 (19%) per session and 529 KB of 9.99 MB (5.3%) of source.
The scaffolding is actively harmful TRUE 5 shipped bugs sat undetected inside 500-line ceremony files. This is the real finding.

2 · Where the tokens actually are

flowchart LR subgraph B["BEFORE   9,977 tok"] B1["Skill index   59 skills
5,867 tok"] B2["Agent descriptions   36
1,329 tok"] B3["CLAUDE.md   1,156 tok"] B4["MEMORY.md   950 tok"] B5["path-less rules   675 tok"] end subgraph A["AFTER   8,109 tok"] A1["Skill index   56 skills
4,225 tok"] A2["Agent descriptions   36
1,329 tok"] A3["CLAUDE.md   1,080 tok"] A4["MEMORY.md   950 tok"] A5["path-less rules   525 tok"] end B1 -->|"-1,642"| A1 B2 -->|"0 · refuted"| A2 B3 -->|"-76"| A3 B4 -->|"0"| A4 B5 -->|"-150"| A5 classDef cut fill:#2a1f3d,stroke:#7c6cf0,color:#e8e6f0 classDef same fill:#1c2333,stroke:#4a5568,color:#9aa5b8 class B1,B3,B5,A1,A3,A5 cut class B2,B4,A2,A4 same

Net: -1,868 tokens (-19%). Agent descriptions do not move: they are 1 byte under a hard CI cap and the in-repo A/B shows rewriting them buys nothing.

3 · The five shipped bugs ALL VERIFIED AT HEAD

Each of these I confirmed myself against the files, not from the audit's report.

#DefectLocationProof
1 Tells an Opus 5 user to downgrade to Opus 4.8 doctor/SKILL.md:171,178-182 Ships literal text Fix: Either switch to Opus 4.8 (claude --model opus-4-8) or lower effort to high. This session is Opus 5 at xhigh. The check fires a false failure.
2 --base dev against a repo with no dev branch create-pr/SKILL.md:213 git ls-remote --heads origin dev returns 0 refs. The command cannot succeed.
3 /ork:help greps a path installed users do not have, then silently falls back to a hardcoded 18-of-114 table help/SKILL.md:55-66 Greps src/skills; marketplace installs only have ${CLAUDE_PLUGIN_ROOT}/skills.
4 cover mandates a manual worktree workaround that its own cited doc marks superseded cover/SKILL.md:263-290 Cited manual-worktree-pattern.md:3 literally reads ⚠ SUPERSEDED. Contradicts implement:340-345.
5 TaskGet instructed in 22 skills, permitted in 0 22 SKILL.md files grep -rl TaskGet src/skills/*/SKILL.md = 22; allowed-tools containing it = 0.

4 · The repo's own token gate is broken and red today

Gate counts
35
user-invocable: true
Real model-facing
59
dmi != true
Charged but free
10
slash-only, zero index cost
Costly but invisible
34
real index, never counted

tests/performance/test-token-overhead.sh:195 selects on user-invocable: true and multiplies by a flat 80 tokens (line 239). Both halves are wrong: wrong population, and an estimate instead of a measurement. The gate reports 6,235 against a 5,500 budget while the truth is ~9,977. It is failing, and it is failing at the wrong number.

5 · Before and after, verbatim

Every BEFORE is copied from HEAD. Every AFTER preserves the non-derivable information and states what was deliberately kept.

#SurfaceBeforeAfterCutLoaded
1CLAUDE.md:62-72 rule499375-24.8%every session
2assess/SKILL.md:163-1991,813252-86.1%on invoke (#1 skill)
3monitoring-engineer.md:60-871,616348-78.5%on spawn
4cover/SKILL.md:5 description596309-48.2%every session
5doctor/SKILL.md:166-1851,112796-28.4%on invoke
Exhibit 1 · A ban rewritten as a judgement call CLAUDE.md:62-72 · 499 → 375 chars
Before (verbatim)
## Critical Rules

**DO**: Edit `src/`, run `npm run build`, commit to
feature branches, use TaskCreate for 3+ step work.

**DON'T**: Edit `plugins/`, commit to `main`/`dev`
directly, skip security tests, bypass hooks with
`--no-verify`, commit secrets.

**Before committing**:
1. `npm test` — all suites must pass
2. `npm run test:security` — MUST pass (blocks push)
3. `npm run typecheck` — if hooks were changed
4. `git diff` — verify changes are real
After
## Before committing

`npm test`, plus `npm run typecheck` if you touched
`src/hooks/`. `main`/`dev` are protected, so work on
a branch. `bin/git-hooks/pre-push:322` runs
`tests/security/run-security-tests.sh` and rejects
the push, so `--no-verify` only relocates the
failure to CI. Nothing enforces TaskCreate any more;
use it when the operator gains from watching
progress.
Gained information the ban never carried: why --no-verify is futile, with the exact gate location. The old text asserted "MUST pass (blocks push)" without saying where the gate lives, so it was a prohibition with no content.

Cut because already stated elsewhere: Edit src/ / plugins/ is at CLAUDE.md:36, 26 lines earlier. commit secrets and skip security tests are enforced by gitleaks at ci.yml:162. git diff to verify changes are real is general practice with no repo-specific content.

Exhibit 2 · Ceremony in the most-used skill assess/SKILL.md · 64 invocations · 1,813 → 252 chars (-86%)
Before (verbatim, abridged)
## 🚨 Task Management (CC 2.1.16)

# 1. Create main task IMMEDIATELY
TaskCreate(subject="Assess: {target}", ...)

# 2. Create subtasks for each assessment phase
TaskCreate(subject="Understand target...")  # id=2
TaskCreate(subject="Discover scope...")     # id=3
TaskCreate(subject="Rate quality...")       # id=4
TaskCreate(subject="Analyze pros/cons")     # id=5
TaskCreate(subject="Compare alternatives")  # id=6
TaskCreate(subject="Generate suggestions")  # id=7
TaskCreate(subject="Compile report")        # id=8

# 3. Set dependencies for sequential phases
TaskUpdate(taskId="3", addBlockedBy=["2"])
TaskUpdate(taskId="4", addBlockedBy=["3"])
TaskUpdate(taskId="5", addBlockedBy=["4"])
TaskUpdate(taskId="6", addBlockedBy=["4"])
TaskUpdate(taskId="7", addBlockedBy=["5","6"])
TaskUpdate(taskId="8", addBlockedBy=["7"])

# 4. Verify unblocked
task = TaskGet(taskId="2")
# 5. Update status as you progress
TaskUpdate(taskId="2", status="in_progress")
After
## Task tracking

Track the phases below as tasks. Phase 1 to 1.5 to 2
is genuinely sequential (each consumes the previous
phase's output), but Phases 3-7 all fan out from the
Phase 2 scores, so do not chain those with
`addBlockedBy` just to look tidy.
Preserved: the only non-derivable content in the block, its dependency shape. Tasks 5 and 6 both depend on 4, which is a fan-out, not a chain. The AFTER states that structure against the real phase headings so it cannot drift out of sync with renumbered task IDs.

Note: this block also contains bug 5. It instructs TaskGet, which no skill is permitted to call.

Exhibit 3 · An index description tightened without losing routing cover/SKILL.md:5 · 596 → 309 chars (-48%)
Before (verbatim)
Generate tests that do not exist yet. Analyzes
coverage gaps, then writes and runs new test files
across three tiers (unit, integration against real
services via testcontainers/docker-compose, and
Playwright E2E), spawning one test-generator agent
per tier and healing failures for up to 3
iterations. Use when code has no tests, when raising
coverage after implementation, or when building a
suite from scratch. Chains naturally after
/ork:implement. Do NOT use to grade or score tests
that already exist (use /ork:verify), or to run a
suite without writing anything new (use npm test
directly).
After
Writes tests that do not exist yet: unit,
integration against real services
(testcontainers/docker-compose), and Playwright
E2E, then runs them. Use when code has no tests or
coverage needs raising. Do NOT use to grade tests
that already exist (that is /ork:verify), or just to
run a suite (that is npm test).
All three boundary clauses survive. cover and verify are a measured router collision (TF-IDF cosine 0.202, sharing grade, unit, integration, e2e, coverage). The two negative clauses are the only thing separating them, so they stay intact. This is the counter-intuitive result: negative clauses are ~23× the value per byte of "Use when" tails, so the trim should expand them and cut the positives.

Cut: agent-spawn and retry internals cannot change which skill a router picks, and belong in the body that loads only on invoke. "When raising coverage after implementation" is a verb-conjugation of sentence one, adding lexical overlap without a distinguishing signal.

Exhibit 4 · The downgrade bug, and why the category thesis failed doctor/SKILL.md:166-185
Before (verbatim)
### Category 14: Effort/Model Compatibility (CC 2.1.111+)

CC 2.1.111 added `xhigh` effort (Opus 4.8; since CC 2.1.154 it defaults to `high`...).

**Detection**:
- If the active model does NOT support `xhigh` (i.e. not Opus 4.8), check whether...

**Warning format**:
WARNING: xhigh effort requires Opus 4.8.
  Fix: Either switch to Opus 4.8 (`claude --model opus-4-8`) or lower effort to `high`.
After
### Category 14: Effort/Model Compatibility

`xhigh` effort degrades to `high` on a model that does not implement it: no error,
no log line, the skill just silently loses its extra deepening pass. That silence is
the only reason this check has to exist.

**Detection**: read `.claude/settings.json` -> `effort`, and `$ORCHESTKIT_EFFORT`.
The fix is to test a capability, not a model name. Pinning to a model generation guarantees re-rot at Opus 6. Note the audit flagged a trap here: do not route this through models.vocab.json, which has no xhigh field at all. That needs a schema addition first.

6 · Execution plan

flowchart TD W0["WAVE 0   Fix 5 shipped bugs
~0 bytes, highest value"] T1["Add the 2 missing gates
tool-coverage + reachability"] W1["WAVE 1   Zero-risk deletions
9 orphans + boilerplate
-322 KB"] M["MEASURE
re-baseline the token gate"] W3["WAVE 3   Index rewrites
-6,400 B, -1,600 tok"] W2["WAVE 2   Merges LAST
needs agent frontmatter surgery
-505 KB"] W4["WAVE 4   ban to judgement voice
anytime"] W0 --> T1 --> W1 --> M --> W3 --> W2 W4 -.-> M classDef crit fill:#3d1f28,stroke:#e0475f,color:#f5e8ea classDef safe fill:#1f3d2b,stroke:#3fbf7f,color:#e8f5ee classDef care fill:#3d331f,stroke:#e0a23f,color:#f5f0e8 classDef gate fill:#2a1f3d,stroke:#7c6cf0,color:#e8e6f0 class W0 crit class W1,W4 safe class W2,W3 care class T1,M gate
WaveContentSavingRisk
0The 5 shipped bugs~0 Bship first
19 true orphans (281 KB) · agent Task-Management tutorial, 31 of 34 byte-identical (11 KB) · CC-changelog archaeology below the 2.1.220 floor (12 KB)-322 KBlow, 2 orphans need a grep first
2product-frameworks (31 of 49 files byte-identical to its own split-outs) · 5 testing-* into one · design-ship into a flag-505 KBmedium, rewrite agent skills: in the same commit
38 longest index descriptions toward ~300 B · "Use when" tails across 54 skills-1,600 tokmedium, keep all 16 negative clauses
4Ban-voice to judgement-voice in CLAUDE.md-76 toklow

7 · What must not be cut

Agent frontmatter is enforcement, not information. 33 of 36 declare agent-scoped hooks:, 8 declare disallowedTools: [Write,Edit,MultiEdit], 29 scope mcpServers. disallowedTools on a reviewer is what makes the review honest. None of it is derivable.
Agent skills: blocks. All 36 declare them and 87 skills are reachable only through them. One audit dimension claimed "grep returns EMPTY, no agent declares any skill". I verified: 36 of 36 declare it. Acting on that fabricated finding would have deleted 30 wired skills.
The 6 "never spawned" agents. They are dispatched by name from skills. design-import/SKILL.md:139 literally contains subagent_type="ork:claude-design-orchestrator". Telemetry silence is not death.
The 16 negative/redirect clauses in descriptions. ~23× the value per byte of "Use when" text. These should be expanded, not trimmed.
Quality Bar sections and dream/quickviz. Written as checkable postconditions, and every guard names the incident that produced it. Use dream's shape (algorithm, guard, incident) as the rewrite target for the bloated skills.
Ban-voice that earns the ban. cc-native-first.md documents a measured 60% error rate on the alternative. A ban backed by a real incident is informative: keep the ban, and make sure the incident is stated, because the incident is the information.

8 · The highest-leverage work is two missing tests

1 · Assert allowed-tools covers what the body calls

audit-skill-permissions.sh:56 checks only that the key exists. That gap shipped TaskGet in 22 files and a commit skill declaring [Bash] while calling three other tools. One assertion kills an 11-name, 10-file class permanently.

2 · Add a reachability gate

dmi:true + ui:false + zero inbound refs = fail. This is the check that finds the 9 real orphans, and critically, the check whose absence let an auditor claim 39. Make dmi:true + ui:false legal only with a declared consumer.

3 · Fix the token gate to measure the real index

Swap user-invocable for dmi != true, measure actual name+description bytes instead of count × 80, then re-baseline honestly. It is red today at the wrong number.

4 · Teach test-model-recency.sh to read prose

It scans 1,698 files and reports 0 superseded while 79 Opus 4.8 prose mentions sit in the tree, including a doctor check that prescribes a downgrade. Without this, every Wave 3 fix re-rots at Opus 6.

9 · How this was produced

flowchart LR E["Evidence pack
telemetry + byte math
gathered inline"] subgraph AU["Audit   7 parallel dimensions"] D1[rules]; D2[live-skills]; D3[agents] D4[deadweight]; D5[index-tax]; D6[anachronism]; D7[overlap] end subgraph VE["Verify   adversarial, default = auditor is wrong"] V["8 refuters
open the files
re-check every quote"] end S["Synthesis
drop everything refuted"] H["Human re-verification
of every load-bearing number"] E --> AU --> VE --> S --> H D4 -.->|"failed: no
structured output"| S classDef ok fill:#1f3d2b,stroke:#3fbf7f,color:#e8f5ee classDef warn fill:#3d331f,stroke:#e0a23f,color:#f5f0e8 classDef gate fill:#2a1f3d,stroke:#7c6cf0,color:#e8e6f0 class E,S ok class D4 warn class VE,H gate
Agents
15
7 audit · 8 verify
Raw findings
87
across 6 returned dims
Survived
48
55% upheld
Subagent tokens
2.0M
384 tool calls · 21.8 min

The adversarial pass paid for itself. It killed a fabricated grep claiming 39 unreachable skills (would have deleted 30 wired ones), a recommendation to strip state.json pointers from 25 agents (the file exists and is schema-validated in CI), and a proposal to replace an inline 208 B protocol with a 2,238 B file read across 1,135 spawns, a 10× pessimisation sold as a saving.

Known gaps, stated rather than hidden: the deadweight dimension failed to return structured output, so orphan classification came from the adjacent dimensions and my own greps. One byte claim in 87 findings (1.35 MB from pattern-library consolidation) could not be reproduced and is excluded from all totals above. Telemetry has a real April-to-June hole where the tracker hook was dead (#959), so "never invoked" was cross-checked against static wiring rather than trusted alone.

Generated 2026-07-26 · OrchestKit v9.1.0 · branch chore/opus5-trim-assessment
Full plan: .audit/plan.md · Full exhibits: .audit/examples.md