- VERIFIED.md lists the 152 skills that loaded on every plain-language test
prompt, built by scripts/build_verified_tier.py from the latest measurement
of each live description; gate G15 keeps it current.
- heroes/heroes.json + scripts/export_hero.py generate standalone repos for
agent-run-forensics, human-gate and skill-retro; hero-sync.yml pushes them
once HERO_SYNC_TOKEN and the repos exist.
- README opens with the tested-library promise, one install line per path,
a pick-your-role table and six verified starting skills; stale counts gone.
- release.yml thanks community contributors by handle.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFKjWjYmERFxzdP2kKu
- Nav: 12 top tabs down to 6 (Home, Skills, Plugins, Agents, Commands,
Other Tools); Personas and Orchestration sit under Agents, guides and
Custom GPTs under Other Tools. The hook keeps hand-written entries next
to the generated ones.
- Domain pages: a "Start here" row of up to three picks per domain
(scripts/docs_start_here.json, checked by G14), one card per plugin
group so plugin-packaged skills (karpathy-coder, agenthub, ...) are no
longer missing from the grid, card text from the skill description, and
the same per-domain count the homepage shows.
- Search: skill pages boosted 2x, agent and command pages 0.5x, so a
query lands on the skill before the wrappers that duplicate it.
- Social cards: Material social plugin, on only for the Pages deploy
(SOCIAL_CARDS=true) with a fallback build without cards; main.html
emits its own OG/Twitter tags only when the plugin is off.
- docs-preview.yml builds docs PRs the way Pages deploys them and uploads
the site as an artifact.
- traffic-snapshot.yml saves GitHub's 14-day traffic data daily to a
metrics branch; it does nothing until a TRAFFIC_TOKEN secret exists.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFH1Jfe2JqY8uFr4aBx
The docs site had drifted (345 skills / 80 plugins against 411 / 110,
~150 pages missing from the nav, 32 pages with install commands for
plugins that do not exist). The fix is to stop hand-maintaining it.
- MkDocs hook (scripts/docs_hooks.py) runs the generator, builds the
Skills/Agents/Commands nav from what it generated, and fills
{{ count.* }}, {{ plugin_table }} and {{ whats_new }} tokens in
hand-written pages and llms.txt
- generate-docs.py: install lines resolve to real marketplace plugins,
c-level-agents and loop-library domains added, vendored links mapped
to the real files, edit buttons point at the source SKILL.md, writes
only when content changes
- Generated skill/agent/command pages are no longer committed; 42
redirects keep moved URLs working
- New What's New page (from CHANGELOG.md), Hermes and Vibe guides,
support matrix; Vibe path corrected to the flat ~/.vibe/skills layout
- Fixed broken install instructions (OpenClaw curl one-liner, claude
/plugin form, nonexistent plugins) in guides and README; README
install order now starts with Claude Code
- Pinned mkdocs versions; Pages build runs --strict (0 warnings)
- Gate G14 (scripts/check_docs_site.py): hard-coded counters, unknown
install targets and nav orphans fail CI
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFH1Jfe2JqY8uFr4aBx
The probe run on this PR showed the cause of #1111's errors: every run
got 'API Error: 401 OAuth access token has expired'. The summary now
says so and how to fix it (claude setup-token, update the secret).
Also reverts the temporary probe edit to vpe-advisor.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFKfjX994ACZHWmjDqy
On PR #1111 every claude run errored on the runner and all 12 skills came
back NOT_MEASURED, yet the check passed. An unmeasured skill has not
passed: NOT_MEASURED (errored runs, budget or --max-skills exhausted) now
exits 3 and fails the check like a regression. run_claude keeps the CLI's
stderr next to each transcript, a stream with no result message counts
as an error, and the gate summary lists the distinct errors so the cause
is visible in the job log. Defaults raised to 20 skills / $30 so a normal
sweep is not failed by the cap alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFKfjX994ACZHWmjDqy
Blind A/B on prompts generated from the old descriptions, 2 runs each:
rewriting 43 raised exact fires 23/172 -> 50/172, zero near-miss fires.
Keep the 14 rewrites that improved; revert the rest. Make four routers
(c-level-skills, engineering-advanced-skills, ra-qm-skills,
self-improving-agent) command-only: they never fired and Claude Code
already picks among their siblings. Bump changed plugins, resync the
Codex/Gemini/Vibe/Hermes indexes, and make generate_trigger_cases.py
accept a near-miss prompt wrapped in a list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFH1gyqU4qnDvS2RoJh
- Gate G13 (scripts/check_harness_mirrors.py): regenerate the .codex,
.gemini, .vibe and .hermes mirrors from scratch in a temp copy and fail on
any difference in link names, link targets or index bytes. --fix rewrites
them, replacing hand-run syncs.
- harness-compat.yml + scripts/check_harness_installs.py: install the real
Codex, Gemini CLI, Hermes Agent and Mistral Vibe CLIs (pinned on PRs, latest
weekly), run the documented install path into an empty HOME and fail unless
the harness itself lists every installed skill. Offline listings only, no
model calls or API keys.
- Fix: Codex skipped 6 single-skill plugins because their installed folder
held .claude-plugin/; the Codex installers now drop it.
- Fix: Gemini skipped 8 command entries without a frontmatter name; added.
- Regenerated 6 Vibe/Hermes links that a fresh sync points at the bundle copy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFHtMEP35nSKLy8fRkj
PRs that change a skill's name or description, or add a skill, now run
scripts/evals/trigger_gate.py: held-out prompts from the base branch,
base vs head description in the same job, fail on a regression beyond
25 points, a new skill under 50%, or any near-miss fire; failures are
re-measured once and judged pooled. Body-only edits make no model call.
Fork PRs are skipped (no secrets, untrusted plugin); hooks are off in
gate runs; event text goes through env. Commits the audit's held-out
cases as scripts/evals/cases/heldout_cases.json.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFKfjX994ACZHWmjDqy
A trigger sweep of all 389 skills (Sonnet, Claude Code 2.1.317, 2 realistic
prompts + 1 near miss each) found 112 skills that fired on neither prompt.
Their descriptions now lead with the job in the words a user types and name
the situations that should load the skill ("Use whenever the user ..."),
with script names dropped to stay within each old length (G12 unchanged or
smaller). reflect is left as is: its pilot rewrite measured worse.
Also: run_evals.py --trigger-only for sweeps, a trigger case for design-qa,
and plugin versions bumped for every changed plugin (G11).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFKBwgFwRBdcBaR6xCa
The Vibe and Hermes sync scripts now read folded YAML descriptions
(description: >), so caveman and 13 Vibe entries no longer index as '>'.
Vibe gains the seven skills added in v2.14.3 to v2.14.7; Hermes gains
i18n-localization.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFKTiTwoEXuZq3cgE7L
Three stdlib scripts with blocking exit codes for shipping a new language:
locale_sync.py (keys, placeholders, ICU syntax, CLDR 49 plural categories,
gettext), hardcoded_strings.py (UI text that bypasses t() in React/Vue/
Svelte/HTML) and pseudo_localize.py (en-XA / ar-XB pseudo-locales).
Agent cs-i18n-engineer, /cs-i18n-check and /cs-pseudo-locale, three
references, CI job example. Bundled in engineering-advanced-skills 2.14.15.
Eval, 3 runs per arm on 8 planted defects: 24/24 both arms; with the skill
43% cheaper and 26% faster. The value is a repeatable CI gate.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFGuNUFriREtj1haTcG
Claude Code 2.1.316 bundles a deep-research skill (its fan-out web research
workflow), and our research plugin used the same skill name. Rename the
plugin, skill, agent (cs-meta-research) and command (/cs-meta-research);
update marketplace, Codex/Gemini/Vibe/Hermes mirrors, docs pages, harness
manifest, eval cases, listing baseline and cross-references. Upstream
catalog URL keeps its name. Reserve deep-research and the other bundled
skills/workflows seen in 2.1.316 in check_skill_names.py.
The maintainer project command .claude/commands/review.md hid /review,
which Claude Code uses as an alias of built-in /code-review: renamed to
/quality-gate. The commands README loaded as a /README command, said
/git:pr targets main, and listed half the commands: moved to
.claude/COMMANDS.md and rewritten. /git:* commands verified working.
Bump changed plugins (G11): meta-research, research-orchestrator,
deepread 2.14.7; agent-harness 2.14.11; engineering-advanced-skills 2.14.14.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFK8uNKfEuEFhyaapiR
Agents answer questions about their own earlier work from memory, and memory
drops the failed test run, the file a sed one-liner rewrote and the edit made
after the last green run. Claude Code and Codex already record every call,
result and exit code on disk; this plugin reads that record instead.
- trace_finder.py: find the run by repo, window, touched file or command text
- trace_timeline.py: numbered steps, --files with SILENT changes, --why STEP
with every causal edge labelled recorded or inferred by a named rule
- claim_checker.py: typed claims vs the run; STALE, PARTIAL, CONTRADICTED
- UserPromptSubmit hook names the session transcript for questions about the
past; fail-open, AGENT_RUN_FORENSICS_HOOK=0 disables it
- secrets redacted in every output, no off switch
Idea from PR #1016, rebuilt without the proposer's npm tool (no-vendor rule).
Bundle engineering-advanced-skills 2.14.10 -> 2.14.11; G12 baseline raised by
the new skill's 272 characters.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFLjaj5gnwaZdF3RyDn
The Tessl step reported "tool error, not scored" on every skill because
of two failures: Tessl removed `tessl skill review` (replaced by
`tessl review run`), and reviews now need authentication, while the
workflow never passed a token. The CLI auto-updates, so the npm install
picked up the breaking change without a version bump on our side.
- Run `tessl review run <dir> --workspace $TESSL_WORKSPACE --json` with
TESSL_TOKEN from repo secrets.
- Skip the review cleanly, and say why in the PR comment, when the
secret or workspace variable is missing (always true for forks).
- Parse scores with scripts/tessl_review_parse.py, which looks them up
by key because the new JSON schema is undocumented, and logs the keys
it saw instead of inventing a 0 when it cannot find a score.
- Make the score advisory until it has a track record; the repo
variable TESSL_ENFORCE=true restores blocking below 70. The security
audit still blocks.
- Cap the job at 30 minutes, since each review polls a server-side run.
- Update SKILL_PIPELINE.md to the new command.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFJsLjhFMhNTyXSzqyY
Claude Code namespaces plugin commands by plugin.json name, so shorthand
prefixes never resolved: agenthub /hub: (now bare /hub-* and
/agenthub:spawn|eval|merge|board), executive-mentor /em: (now
/executive-mentor:<name>), docker/terraform/helm sub-commands (skill
arguments: /docker-development optimize), persona /pm: /devops:
/finance: /content: (now named workflows) and invented commands in the
Codex, Cursor and OpenClaw guides. check_command_refs.py now fails on any
/<prefix>:<name> whose prefix is not a plugin name. Drop redundant
'Use for /<cmd>, or' description leads (G12 shrinks 153 chars). Reserve
more CC 2.1.314 built-ins in check_skill_names.py. Bump changed plugins.
Claude-Session: https://claude.ai/code/session_01L8KYFLDu2gf1Jru9svgJHW
Co-authored-by: Claude <noreply@anthropic.com>
Issue #1004 named a real gap: agents leave large mixed diffs, and
nothing in the catalog shapes them into commits before they exist.
Built independently from public sources.
- commit_planner.py groups the working tree in build-safe order
(manifest with lockfile, moves, formatting, each change with its
tests, docs, CI), holds back .env/keys/tfstate, and flags a move
whose callers' import edits sit in another commit, because that
commit would not build. A plain mv is detected as a rename.
- secret_gate.py blocks staged or pushed secrets, sensitive files and
conflict markers with redacted output and reasoned waivers. On 174k
lines added to this repo it raised 7 findings, all fake fixtures.
- message_linter.py blocks vague subjects, large changes with no why
and fixup commits, and enforces Conventional Commits only where the
repo already uses them.
Standalone plugin at 2.14.5, mirrored into engineering-advanced-skills
(bumped to 2.14.8, above the unreleased 2.14.7 on dev). The
bundle's G12 baseline grows by the new skill's 279 listing chars.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFJm9vze5Kqnyb5yvFs
Claude Code namespaces plugin commands by plugin name, so /ar:<name>
never resolved for the autoresearch-agent plugin. Use the bare ar-*
names (unique) and /autoresearch-agent:setup. check_command_refs.py
now fails on any /ar: reference. Shorten the setup description so G12
does not grow. Bump autoresearch-agent 2.14.7, research-ops 2.14.6,
agent-harness and engineering-advanced-skills 2.14.8.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFLDu2gf1Jru9svgJHW
The bare skill name shadowed Claude Code's built-in /loop scheduler.
Rename to ar-loop, matching ar-run, ar-resume and ar-status. Update the
Codex, Gemini, Vibe and Hermes mirrors, docs page and mkdocs nav, eval
cases, agent-harness manifest, and the G12 baseline (+3 chars from the
prefix). Reserve loop in check_skill_names.py. CHANGELOG migration note.
Bump autoresearch-agent to 2.14.6, agent-harness and
engineering-advanced-skills to 2.14.7.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFLDu2gf1Jru9svgJHW
Claude Code 2.1.314 ships a built-in /skill-doctor, and our plugin skill
of the same name hid it. Rename the plugin, skill, agent (cs-skill-retro)
and command (/cs-skill-retro); update the marketplace, the Codex, Gemini,
Vibe and Hermes mirrors, docs pages, harness manifest, eval cases and
listing baseline. Upstream (warpdotdev) attribution keeps its original
name. Add skill-doctor and three other bundled skills to the G-names
reserved list, a CHANGELOG migration note and README deviation 24.
Bump changed plugins to 2.14.6.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFLDu2gf1Jru9svgJHW
check_listing_budget.py measures the characters each marketplace plugin
adds to Claude Code's skill listing (SKILL.md name + description, plus
model-invocable commands) and fails when a plugin grows past its line in
listing_budget_baseline.txt or a new plugin exceeds 6,000 characters.
Baseline taken after the description rewrite: 107 plugins, 97,362 chars.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFLGyaha8ReWA1JaCfC
The workflow now accepts CLAUDE_CODE_OAUTH_TOKEN (from claude setup-token,
already used by claude.yml) so maintainers on a Pro/Max plan run the evals
against their usage limits instead of a per-token bill.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFLywRRE8eU2sVPtJAL
Harness in scripts/evals/ built from the v2.14 audit evals: trigger cases
for all 384 unique skills (13 hand-written, the rest drafted with Claude),
6 behaviour cases with fixtures and a blind JSON-schema grader, a date
rotation (15 skills/night, $10 cap), and a scoreboard that flags
regressions. The workflow stays off until ANTHROPIC_API_KEY and
SKILL_EVALS_ENABLED are set.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L8KYFLywRRE8eU2sVPtJAL
- Rewrite code-reviewer, self-improving-agent, session-handoff, handoff and
si:remember descriptions to lead with the user's ask; trigger evals go from
1/24 to 15/28 positive hits with no false fires.
- Move OWASP references from Top 10:2021 to Top 10:2025 (pen-testing scanner,
checklist, report example, secops/backend/security references) with a
2021-to-2025 mapping table and new A10 Mishandling of Exceptional Conditions.
- Replace deprecated datetime.utcnow() in 15 scripts and hooks with identical
output, and block it in CI.
- Make gate G9 blocking as a ratchet over a 240-tool legacy baseline.
- Fix INSTALLATION.md drift (Vibe flat layout, Codex advice, skill counts),
add install lines to 35 plugin READMEs, regenerate all 20 agent-harness
manifests and the docs site.
- Bump the 43 changed plugins to 2.14.2.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018HXynYUKMCEpmhMQjyTx8J
* fix(plugins): bump all plugins to 2.14.1 and gate unbumped changes
Claude Code caches plugins by version. 70 of 104 plugins changed between
v2.12.0 and v2.14.0 without a bump, so claude plugin update reported
"already at the latest version" and existing installs never received the
v2.13/v2.14 fixes. Every plugin moves to 2.14.1 so stale caches refresh once.
check_plugin_versions.py (G11, blocking in ci-quality-gate) fails when a
plugin's payload, including symlinked vendor files, changes without a higher
version, and when marketplace.json and plugin.json disagree.
bump_plugin_versions.py sets both together.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uNBQ6tRS5P1dRsgNfK4Wh
* fix(codex): stop installing all skills by default
With the full library (~380 skills) Codex drops every skill description from
its prompt budget, so it cannot pick skills. codex-install.sh now asks for
--category (comma-separated), --skill or an explicit --all, lists categories
when run without arguments, and warns when more than ~100 skills are
installed. The Windows installer and install docs follow.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uNBQ6tRS5P1dRsgNfK4Wh
* fix(gemini): link whole skill folders and drop duplicate mirror entries
Each .gemini/skills entry held only a SKILL.md symlink, so the relative
scripts/ and references/ a skill points to were missing. Entries are now
directory symlinks (Gemini CLI 0.65 discovers them). Dual-published copies
with identical SKILL.md are listed once, commands and agents that share a
skill's name are skipped, fixtures under assets/ and vendor/ re-exports are
excluded, discovery is sorted so reruns are stable, and stale generated
entries are pruned. gemini skills list: 20 conflicts -> 1 (handoff, fixed
next). GEMINI.md documents folder trust and fixes a dead example path.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uNBQ6tRS5P1dRsgNfK4Wh
* fix(handoff): rename the productivity skill to session-handoff
engineering/handoff and productivity/handoff both shipped a skill named
handoff. Claude Code namespaces them, but Codex, Gemini CLI, Vibe and Hermes
key skills by name and silently kept one. The productivity skill is now
session-handoff (handoff-productivity:session-handoff); its folder, plugin
manifest, hook script paths, command paths, mirrors, harness manifest and
docs page follow. /cs-handoff, /cs-handoff-setup and ~/.config/handoff are
unchanged; the plugin README carries a migration note.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uNBQ6tRS5P1dRsgNfK4Wh
* fix(convert): include plugins whose SKILL.md is at the plugin root
convert.sh searched at -mindepth 4, which skipped boost-asio-pro, deepread,
hivemind, loop-library, minimalist, strict-api and swedish-mentor for every
converted tool (opencode, Cursor, Windsurf, Kilo, Augment, Aider,
Antigravity). It now searches from depth 2 and skips assets/ fixtures.
opencode conversion: 375 -> 382 skills.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uNBQ6tRS5P1dRsgNfK4Wh
* fix(codex): keep skill-tester's sample fixture from loading as a skill
Codex scans installed skill folders recursively and picked up
skill-tester/assets/sample-skill/SKILL.md as 'sample-text-processor'.
The installer renames SKILL.md files under assets/ in the installed copy.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uNBQ6tRS5P1dRsgNfK4Wh
* fix(plugins): address scripts via ${CLAUDE_PLUGIN_ROOT} in commands and agents
343 script invocations in 90 command/agent files across 36 plugins used
repo-relative or ../ paths. Plugin commands and agents run from the user's
project, so those paths only resolved inside a clone of this repo; in the
v2.14.0 evals the agent fell back to find / to locate scripts. Every one now
uses ${CLAUDE_PLUGIN_ROOT}/. Two cross-plugin calls (write-a-skill ->
karpathy-coder, c-level-agents cpo -> product-manager-toolkit) go through
vendor/ symlinks, per the repo's install-cache lesson.
check_paths.py (G1) now fails a plugin command or agent that invokes a
script without ${CLAUDE_PLUGIN_ROOT}; on the v2.14.0 tree it reports 279.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uNBQ6tRS5P1dRsgNfK4Wh
* fix(month-end-close): treat opening-balance rows as balances and pair transpositions
On a bank and GL export that each begin with an 'Opening balance' row, the
matcher returned RECONCILED_WITH_ITEMS and told the user to book a 25,000.00
journal entry for the opening balance, and it reported a 7,980/7,890
transposition as two unrelated items. Opening rows are now balances: a
difference between them is reported as carried in from the prior period
(R5, blocks sign-off, never booked). Same-date digit transpositions pair into
one correcting entry. The GL file's 'memo' column is read as description.
The v2.14.0 eval fixture now proves 1,405.00 = 150 opening + 90
transposition + 1,200 outstanding check - 35 bank fee. Bundled copy synced.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uNBQ6tRS5P1dRsgNfK4Wh
* fix(coding-agent-rollout): flag connection-URL passwords and production MCP servers
On a committed .claude/settings.json holding
env.DATABASE_URL=postgresql://admin:<password>@prod-db... and
enabledMcpjsonServers: ["postgres-prod"], the linter flagged neither: the
env check only matched token formats and KEY/TOKEN/SECRET names. S11 now
catches a password embedded in any connection URL (BLOCKER in shared files),
and new S13 warns when a shared file pre-approves an MCP server whose name
marks it as production. Bundled copy synced; --sample output unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uNBQ6tRS5P1dRsgNfK4Wh
* docs: changelog and lessons for the v2.14.0 audit fixes
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016uNBQ6tRS5P1dRsgNfK4Wh
---------
Co-authored-by: Claude <noreply@anthropic.com>
- capture-skill, email-pair, reflect-skill, research-orchestrator: plugin.json
name now equals the marketplace name. Installs are keyed on the marketplace
name, so existing installs are untouched; bare /cs-* commands are unchanged.
- self-improving-agent keeps plugin.json name `si` (its /si:* commands) as a
documented exception; check_plugin_json.py --all now fails on any other
marketplace/plugin.json name mismatch.
- sync-vibe/hermes: add c-level-agents and loop-library, detect a SKILL.md at
the domain root, skip vendor/, and dedupe bundle/standalone twins by
(domain, name). Mirrors regenerated: 379 skills, 0 duplicate or stale links.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vr9qnGkGfrCBiVt4WF94Hd
Conflicts were only the headline counter lines; took dev's 728 tools and
re-applied 100 marketplace plugins. Re-ran the /cs: sweep over the merged
tree, including the Codex index #1023 regenerated, and caught three forms the
first pass missed: /cs:* wildcards, /cs:<slug> placeholders, and the
book-to-skill emitter, which generated /cs:{slug} into every new package.
c-level-agents counts now say /c-level-agents:* since its skills are not
cs-prefixed. check_command_refs.py now also catches the wildcard forms.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HiL4hfMQoQjiFmMUbPnpJJ
Claude Code runs a plugin command as /<plugin>:<name> or bare /<name>. A test
plugin on 2.1.306 confirmed /cs-foo and /tp:cs-foo run while /cs:foo matches
nothing, so every /cs:<name> in the docs, descriptions and hook messages sent
users to an unknown command.
- Commands named cs-<name> are now written /cs-<name>.
- c-level-agents and compliance-os skills with generic names (decide, brief,
freeze, ...) are written fully qualified, e.g. /c-level-agents:decide, so they
cannot collide with other commands.
- Five names that never existed were mapped to what they described:
/cs:setup and /cs:update -> /cs-onboard setup|update, /cs:decisions and
/cs:review -> /decision-logger ..., /cs:board -> /board-meeting,
/cs:unfreeze -> /c-level-agents:freeze release.
- CHANGELOG.md and audit/ keep the old spelling as history.
- New blocking gate scripts/check_command_refs.py keeps the tree clean.
- Counters: 100 marketplace plugins (loop-library).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HiL4hfMQoQjiFmMUbPnpJJ
Their agents and skills ran scripts and read references through paths like
../../c-level-advisor/skills/cfo-advisor/scripts/x.py and
ra-qm-team/skills/... . A marketplace install copies only the plugin's own
directory, so all 395 of those references failed once installed.
- vendor/ in each plugin now holds 37 relative symlinks to the source skill
folders. Claude Code dereferences symlinks that stay inside the marketplace
when it copies a plugin into its cache, so the install carries real files
with no duplicated source in the repo and nothing to drift.
- References now use ${CLAUDE_PLUGIN_ROOT}/vendor/..., which Claude Code
substitutes in agent, skill and command bodies.
- check_paths.py resolves ${CLAUDE_PLUGIN_ROOT}/... against the owning
plugin root, so a broken plugin-root path now fails the gate instead of
being skipped as dynamic.
These files also carry their /cs:<name> -> runnable-name fixes (see the
following commit for the rule).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HiL4hfMQoQjiFmMUbPnpJJ
agenthub and autoresearch-agent both shipped a skill named run, the
same name as Claude Code's bundled /run skill. In the mirrors the
collision was worse than a shadow: .codex/skills/run pointed at
whichever plugin the sync visited last (it flipped during this sweep),
and the .vibe and .hermes indexes listed both skills at one path, so
one of them could never load.
Follow the hub-init/ar-status convention from #973: rename the
directories and names, update /hub:run -> /hub:hub-run and
/ar:run -> /ar:ar-run in docs, settings, marketplace and harness
manifests, re-point the four mirrors, and add run to the reserved set in
check_skill_names.py so it cannot come back.
Co-Authored-By: benrfairless <6841582+benrfairless@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H62X35SkaV44z2QQZQGqnC
Salvages the maintainer-approved scope of #939 by @benrfairless, whose
investigation found both problems; the branch went eight weeks without
the requested rebase, so this re-does the work on current dev.
- skills: in subagent frontmatter preloads each listed skill by
plugin:skill name. Every value in the repo was a path or bare name
that resolved to nothing. Per the decision recorded on #939, delete
them (86 agents) rather than switch preloading on: agents here are
lightweight routers.
- context: fork is a skill field and is ignored on agents (11 files).
- Agent template, agents/CLAUDE.md and the documentation standard no
longer tell authors to add skills:.
- check_frontmatter.py now errors on either key in an agent file.
Co-Authored-By: benrfairless <6841582+benrfairless@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H62X35SkaV44z2QQZQGqnC
The only real finding in the AI Skill Shield report: the Gemini sync
picked up agents/personas/README.md and TEMPLATE.md as agents, so
.gemini/skills/README and .gemini/skills/TEMPLATE shipped as skills
with no name or description. The report's 10 'critical' findings are
documentation examples (a Slack webhook curl, a DROP TABLE in a caveman
example, an apt cleanup rm -rf, a detection-pattern table) and need no
change.
Refs #1001
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H62X35SkaV44z2QQZQGqnC
#1022/#1023 register c-level-agents; loop-library was the second domain
missing from the Codex index (noted in #1019's thread). Its SKILL.md is
at loop-library/SKILL.md, which matched none of the discovery patterns,
so add a domain-root pattern and register the domain. Regenerates the
index (also picks up the #1027 description rewording).
Refs #1019
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H62X35SkaV44z2QQZQGqnC
Codex's quick_validate.py allows only name, description, license,
allowed-tools and metadata at the top level, and rejects < or > in a
description. 77 SKILL.md files carried version/author/tags/
compatible_tools (and similar) at the top level and 36 descriptions
contained angle brackets, so they failed on a clean Codex install.
- Move those keys under metadata: (values verified identical after the
move; claude-coach's duplicate Name/Version keys dropped).
- Reword angle brackets in descriptions (/cs:x <arg> -> /cs:x [arg],
-> -> arrow, >50% -> more than 50%, and so on).
- check_frontmatter.py now fails a SKILL.md that reintroduces either.
Claude Code runtime keys (context, argument-hint) stay top-level: they
change behaviour, so they are left for Codex to ignore.
Closes#1027
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H62X35SkaV44z2QQZQGqnC
create_symlinks() and validate_symlinks() both walk the discovered
skills. A symlink left behind in .codex/skills/ by an earlier sync
generation is therefore visited by neither: it survives every run, and
--validate reports success. The target directory is never read.
Measured on 527a1b8 + e294da96:
discovered skills 372 (unique names)
symlinks in the tree 374
orphans 2
dsh-deepread -> ../../research/dsh-deepread (dangles;
the source is in no commit of the tree)
playwright-pro -> ../../engineering-team/playwright-pro
(resolves, but has no SKILL.md; the sync
discovers its 10 sub-skills individually)
current --validate on that tree exit 0
this change, dry run exit 0, both orphans named
this change, real run both removed, exit 0, idempotent
Codex loads .codex/skills/ by directory. Both entries are shipped to it
today; neither can be loaded.
Removal is limited to where nothing can be lost by removing it: the link
dangles, or there is no SKILL.md behind it. A link that does resolve to a
real skill but that no discovered skill claims is reported and kept, and
exits 1. That case is not hypothetical -- it is exactly what the missing
c-level-agents entry looked like from this side. Run against a
SKILL_DOMAINS with that entry removed again:
Unclaimed symlinks (kept): 22
- boardroom: resolves to a skill no domain claims ...
- brief: ...
exit 1, 0 files touched
Deleting on that signal would have turned a discovery bug into the loss
of 22 working links. Reporting it turns the same bug into a red run,
which is what the last three weeks were missing.
Gates before and after, all exit 0: check_plugin_json, check_skill_names,
check_paths, check_frontmatter, check_dual_publish, check_model_freshness,
smoke_scripts, derive_counters --check. G9 smoke_json_output lists the
same six scripts before and after (exit 1 both times, advisory, and
sync-codex-skills.py was already on that list). --help and --json still
parse; the new "orphans" key carries removed/unclaimed/errors. stdlib
only.
.codex/ is not in this diff (CONTRIBUTING lists it as auto-generated);
the sync workflow removes the two links on its next run on dev.
Refs #1020
`SKILL_DOMAINS` in scripts/sync-codex-skills.py lists 18 domain folders.
Of the 99 plugins in .claude-plugin/marketplace.json, exactly one points
at a domain folder the sync does not know: c-level-agents, a 22-skill
plugin the c-level-skills description tells users to install separately
for the persona layer.
Measured on 527a1b8:
c-level-agents skills in the tree 22
of those in .codex/skills-index.json 0
of those in .gemini/skills-index.json 0
of those present as a symlink in .codex 22
of those present as a symlink in .gemini 22
of those present in .hermes / .vibe 22
So the skills are installed in every mirror and listed in none of the
indexes. The symlinks are left over from an earlier sync generation; the
current one neither writes nor removes them, which is why the gap is
invisible from the tree alone.
The same omission was fixed in scripts/generate-docs.py, whose comment
names c-level-agents among the standalone-only plugins whose sub-skills
were "silently dropped (~79 pages missing from the docs site)". That
makes this an oversight rather than a deliberate exclusion.
find_skills already handles the layout (<domain>/skills/<name>/SKILL.md,
discovery pattern 1), so registering the domain is the whole change.
Checked for symlink name collisions first: 0 of the 22 names clash with
the 350 already discovered.
After:
category c-level 46 -> 68 skills
orphan symlinks 24 -> 2 (dsh-deepread, playwright-pro)
Not included, and not fixed here:
- loop-library, the remaining unregistered domain. Its SKILL.md sits
directly at loop-library/SKILL.md, which matches none of the three
discovery patterns; registering it needs a fourth and a separate
change.
- The 28 "Symlinks updated" the sync reports on every run, before and
after this change. It is the 14 dual-published skills writing their
link twice per run. The end state is stable, the counter is not.
Untouched here.
.codex/ is deliberately not in this diff (CONTRIBUTING lists it as
auto-generated); the sync workflow regenerates the index on dev.
Gates before and after, all exit 0: check_plugin_json, check_skill_names,
check_paths (658 files), check_frontmatter (669), check_dual_publish
(12 pairs), check_model_freshness (3078), smoke_scripts, derive_counters
--check. The script's own --help and --json output still parse.
Refs #1019
derive_counters.py --check gated absolute totals in five files but never
read CHANGELOG.md, and only scanned CLAUDE.md's two 'Current Scope'/
'Status' lines rather than its release-note history — so a fabricated
delta claim like 'commands 147 -> 150' for a one-command change passed
CI green in both files (issue #995).
Add a one-directional check: since every tracked counter only grows
over the repo's life, no delta claim's right-hand (new) value can
legitimately exceed today's derived total. That's enforceable without
knowing which changelog entry is 'current' and without touching any
of the existing, correct historical entries -- unlike an equality
check, which would fail on entirely legitimate past deltas.
Wires scripts/test_derive_counters.py into CI so a future regression
to the new delta-claim logic is caught, not just the absolute-total
gate it already ran.
Two reviewer nits batched: derive_counters.py's module docstring and --check
help still described the pre-#989 three-source coverage (flagged on #989);
check_model_freshness.py's EXCLUDED_DIRS did double duty as a directory AND
filename exclusion set, which the name hid (flagged on #985 and #988's
reviews) — renamed with a comment stating both roles. No behavior change;
both gates re-verified passing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qgc6RYXWJPr5oW9DHU7zR4
Review follow-up on #989: shortDescription/longDescription carry their own
counts and were just trued — include them in the gated source text so
standardized-phrasing claims in them are checked (non-matching prose is
simply not read). Verified: planting 997 in shortDescription fails the
gate; restored passes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qgc6RYXWJPr5oW9DHU7zR4
Adopts the two verified findings from PR #940 (credit: @benrfairless):
- .codex-plugin/plugin.json still said v2.2.0 / 223 skills / 23 agents /
298 tools / 9 domains — roughly nine releases behind, and it is the
manifest Codex users see. Version, description, and the interface
short/long descriptions are trued to the v2.12.0 counters (380 skills /
20 domains / 706 tools / 823 refs / 114 agents / 138 commands / 96
plugins), with the top-level description written in the standardized
claim phrasing so the gate can read it.
- mkdocs.yml's site_description was content-correct after v2.12.0 but
ungated and phrased invisibly to extract_claims ('agent skills',
'installable plugins') — reworded to the standardized phrasing.
- derive_counters.py run_check() now reads both as claim sources
(mkdocs.yml restricted to the site_description line since its !!python
tags reject safe_load). Verified: planting 999/998 in the two sites
fails the gate naming both; restored values pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qgc6RYXWJPr5oW9DHU7zR4