fix(claude-ops): recover the bundled-skill lane on 2.1.263 and report integrity per lane - #4092
Conversation
Contract slice for the native-overlap tooling fix and the route-to-compose policy change, locked through /planning:interview on 2026-09-10. Pruned before merge per the topic-docs convention. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
Plan section drafted for the tooling fix, the integration axis, and the per-plugin sweep; stress-test findings are still pending, so this is the pre-approval draft the contract slice carries on the task branch. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
…lap plan Adds the mutation clause and three-state skip report to the wrap grammar, tests for the extractor's region selection, one exit-code rule for both integrity readers, the marketplace-plugin class row, suggest-sentence parity, and positive-path probes per sweep unit. Devil's-advocate findings pending. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
…-overlap plan Region rule drops to a 256-byte floor with chunk-scoped constant resolution and the ESM export list as the primary registrar route; the extractor records each registration's invocation-control fields; rows for model-disabled bundled skills can no longer take wrap, so the doctor and design rows move to suggest or route pending the user's decision. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
…t-native-overlap plan Container #4047 with sub-issues #4048 to #4056 published; native blocked-by edges deferred to a session with tracker seam access. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
Fold the two-validator research pass into the plan: the design canvas registration is model-invocable (route stands on job merits, marker keyed per registration, Phase 1 gains a same-name collision rule), all three doctor rows take suggest, a model-disabled bundled-skill row takes suggest only, the wrap grammar gains a resolved-but-degraded state and named refusal reasons, the convention bump cites the enforceability and token triggers, and #4049 stays structural and needs-human with the verdict table as its C4 plan approval. Both USER-RESERVED questions are closed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
… integrity per lane inventory.py reads a bytecode-fragmented bundle through a region rule (every printable run of at least 256 bytes from the first marker to end of file), discovers the registrar by three routes (CJS getter, ESM export list, canary), resolves computed names by nearest-preceding binding with a locality window for single-character identifiers, records the invocation control fields per registration, and keeps both registrations when two share a name. Integrity is per lane, with the top-level status the worst lane, so one broken lane is a named degraded run rather than a run with no counts; exit mappings are unchanged in both tools. overlap.py detect reads the lanes and marks candidates re_derivable per lane; self-check flags a presence-gated native mention without the gate token as an advisory and accepts one --upstream-sha per upstream repository. Two audit-skill-visibility pairs are seeded, VALIDATED_AGAINST moves to 2.1.263, and claude-ops is 0.48.0. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
…re merge The slice (Brief, Plan, design resolution) is retrievable from the pre-prune commit eab2284 and is restored on the branch for the next unit; durable outcomes live in the tracker container and its sub-issues. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
Resolves three conflicts: claude-ops moves to 0.50.0 above main's 0.49.0 with this unit's CHANGELOG entry inserted, the extraction reference keeps the rewrite from this branch (already free of em dashes), and the presence-mention parity test seeds the Boundary section main's stricter parity rule now requires. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee0af40488
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…loor literals, label lane counts by run-wide drift A registration whose invocation field is function-valued is a distinct registration from its constant-true twin, so the dedupe includes flag_driven and the pair is kept as a collision. A registration literal in a run under the region floor now degrades the bundled-skill lane with an advisory naming the count, instead of leaving the lane ok over a roster it did not fully read. In detect, a lane's counts are totals only when the lane is ok and no run-wide advisory (an unvalidated CLI version) stands; a lane-attributed advisory degrades only its own lane. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
claude-ops moves to 0.51.0 above main's 0.50.0; this unit's CHANGELOG entry sits above it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
…overlap description under the cap The approved plan and its design resolution move from the pruned topic slice into docs/specs with a status section that re-anchors the remaining units on the native-references 1.1.0 convention and the 19-row store, so the deferred units resume from a durable contract rather than an unreachable commit. The audit-native-overlap description keeps every claim and trigger phrase in 1,020 characters, under the 1,024 Skills API cap the skill-quality check enforces. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
claude-ops moves to 0.52.0 above main's 0.51.0; this unit's CHANGELOG entry sits above it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
…n-cap baseline The description is under the cap now, and the changed-skills check refuses a baseline row that no longer breaches. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
claude-ops moves to 0.53.0 above main's 0.52.0; this unit's CHANGELOG entry sits above it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
Main released claude-ops 0.53.0 (audit-skill-visibility Markdown sections) while this branch was in flight; this branch's release entry moves to 0.54.0 and the plugin version follows. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e
|
CI note on head a6c2ff3: This is not this PR's failure:
It reads as a timing race in the test's 33-way parallel writer fan-out (one writer's stdin pipe closed before the hook read it), so no fix is ported here. I am re-running the failed job once after the workflow finishes; a second failure will be treated as real. Generated by Claude Code |
…26p6y Restack claude-ops to 0.54.1 above main's 0.54.0 (#4092); the voice-sweep changelog entry sits above the new main entry. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MSGD4WGhUXepHq3LTmpQML
…n prose across 36 skills (#4108) No related issue: this closes the one decision the audit behind #4072 reclassified to a human, resolved by re-reading the sources; no issue tracks it. ## Summary Anthropic's [skill-authoring best-practices page](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices#writing-effective-descriptions) rules out first and second person in a skill description. Its two Avoid examples are "I can help you process Excel files" and "You can use this to process Excel files", and its reason is that the text is injected into the system prompt. Its own effective examples, the Claude Code skills page's examples, and the bundled skill-creator's frontmatter are all imperative ("Extract text and tables from PDF files", "Fix a GitHub issue", "Create new skills..."), so imperative and third-person singular both conform and this marketplace's imperative descriptions are not a deviation. The real gap was description prose that addresses the reader. A scripted scan that strips quoted trigger phrases and hyphenated or slash-joined identifiers found it in 36 skills across 24 plugins. ## Fix - **36 skill descriptions** (adhd, bugs, claude-config, claude-ops, code-metrics, discipline, discovery, docs-hygiene, education, firecrawl, improvement, instruction-placement, kindle-dedrm, mutation-testing, overengineering, playgrounds, plugin-quality, prototype, session-flow, songwriting, source-control, tdd): each clause that addressed the reader now names the user, the session, the assistant, or the repository. Examples: "so you can act on it" becomes "so the reader can act on it"; "a permission rule you cannot locate" becomes "a permission rule whose source is unknown"; "books you own" becomes "books the user owns"; "synthesize where we stand" becomes "synthesize where the session stands". Quoted trigger phrases (user utterances such as 'audit my .claude folder'), backticked tokens, slash tokens, and skill names are byte-identical. No description grew by more than 20 codepoints or crossed 1,024; two that sat near the cap got shorter. - **One clause stays as it was.** The native-surface presence gate ("resolves in your session") in the two claude-ops descriptions (`audit-install-state`, `audit-skill-visibility`) is a literal token the native-overlap registry self-check matches against every baked store row, so `validate-plugins.sh` fails when it is reworded (that is what turned `7cbf30ab8` red). Commit `af0e7b274` restores the token in both and the claude-ops changelog entry says why. Changing the token itself touches the checker, its tests, twelve skills, the seam-phrasing convention, and the store evidence, and is tracked as #4112. - **Two plugin manifests** (kindle-dedrm, session-flow) carried the same wording in their own descriptions and follow; `docs/CATALOG.md` regenerated. - **playbooks 0.11.2**: `skill-authoring/reference/authoring-guidance.md` states the rule as the page defines it, with the Avoid examples, the system-prompt reason, and the finding that imperative conforms, and its Record cites the three imperative example surfaces with a recheck trigger for the page rewriting its examples. `reference/authoring-checklist.md` gains the matching judgment row. The previous text called the fleet's imperative voice a deviation to leave alone, which the sources do not support. - Each of the 24 touched plugins gets a patch bump and a CHANGELOG entry naming its rewritten skills. Main moved four times while this was open; the merge commits `2cc1102c0`, `f082ed2f8`, `7cbf30ab8`, and `0b10ccae7` restack this change's entries above the newer main entries: claude-ops to 0.54.1 (above #4099, #4107, and #4092), code-metrics to 0.2.3 (above #4098), source-control to 0.55.76 (above #4106). Every other plugin's bump is unchanged. ## Verification Run on Linux at head `0b10ccae7`: - Voice scan over all 258 skill descriptions (quoted phrases and identifiers stripped, then first and second person pronouns matched): 36 hits before; after, only the two claude-ops descriptions that carry the checked gate token (3 occurrences of that token, nothing else). An uppercase variant scan finds 0. - `scripts/validate-plugins.sh`: passes; the native-overlap self-check reports degraded (stale-but-honest advisories, the same as main), not broken. - `scripts/check-changed-skills.sh origin/main`: 35 skills checked, 0 failed, no dropped-trigger-keyword WARN on any skill (check 3 compares every trigger phrase against the base ref). - `check-changelog-parity.sh --check`, `--check-bump origin/main`, `--check-order`: pass across all 93 changelogs. `generate-catalog.mjs --check`: in sync. - `markdownlint-cli2` over every changed markdown file: 0 issues. `typos` over the added lines: clean. `check-purged-em-dashes.sh`: no em dashes. - Diff shape: 36 SKILL.md files touched on their description line only, 23 plugin.json version bumps plus the two manifest description edits, 23 CHANGELOG.md entries, the two playbooks spokes, and the catalog. No skill body, script, or test changed. - `scripts/affected-tests.sh --run`: no suites selected (every changed file is a recorded no-suite class). - CI: `ci-status` and every lane green on `45af55489` (draft) and on `2cc1102c0` (draft and after the ready flip). Codex review on `2cc1102c0`: completed, no findings. `7cbf30ab8` went red on `test-linux` (the gate-token self-check above); `af0e7b274` carries the fix and `0b10ccae7` merges the latest main on top. ## Related - Follow-up to #4069 and #4072. The two fresh-context validators behind #4072 both reclassified the description-voice row to a human decision on the premise that imperative and third person are two voices; re-reading the page's examples shows they are one conforming class, so the decision resolves on evidence rather than taste. The reasoning and the scan live in the untracked `.work/skill-authoring-best-practices/INTERVIEW-ACCEPTED.md` ("Audit resolution", row I1.2) of the authoring checkout. - #4112 tracks retokening the presence gate so the last two descriptions lose their second person too. - #4070 and #4071 remain the deferred follow-ups from #4069. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01MSGD4WGhUXepHq3LTmpQML --------- Co-authored-by: Claude <noreply@anthropic.com>
Closes #4048
Summary
The inventory extractor's bundled-skill lane returned empty on Claude Code 2.1.263 (a bytecode-fragmented bundle whose readable source is scattered across thousands of small printable runs, with an ESM export list in place of the CJS getter), so every native-overlap run reported
broken. This PR recovers the lane, reports integrity per lane in both engines, closes the reverse-parity blind spot, seeds the two missing pairs, and releasesclaude-ops0.54.0 (main released 0.49.0 through 0.53.0 while this was in flight; all merged in). It also graduates the effort's approved plan intodocs/specs/and trims the audit-native-overlap description under the Skills API cap. Unit 1 of the native-overlap effort tracked in #4047; units 2 to 9 are deferred as filed, each re-anchored by a comment.Fix
inventory.pysources.binaryrecordsruns,joined_bytes,region_rule,runs_below_floor(registration tokens under the floor, counted rather than lost, and degrading the bundled-skill lane when positive), andelapsed_seconds. A build with no marker keeps the largest-run fallback.<ident> as registerBundledSkill), canary registration;bundled_skill_notes.registrar_routerecords which resolved. The registrar-shaped-export advisory sees both export shapes; the known set gainsregisterDesignCanvasSkillandregisterWorkflowAuthoringSkill.ident="kebab"binding, a farther one never wins; a single-character identifier only within a 64 KiB window). A loop or template-literal registration is adynamic_rosternote; a registrar-identifier call whose object has noname:is another module's function and is counted apart.user_invocable,disable_model_invocation,terminal_oriented,survives_kill_switch; a function-valued field reads as true with the key underflag_driven, andflag_drivenis part of a registration's identity.collision: true(designon 2.1.263: the canvas skill and the claude.ai/design hub);registrations_of(entry)reads either shape.integrity.lanes(builtin_commands,bundled_skills,plugin_backed), top-level status the worst lane; top-levelbrokenonly when every lane is broken or the binary is unreadable.plugin_backedgains a canary (security-review). Exit mappings unchanged;--self-checkprints each lane.VALIDATED_AGAINSTis2.1.263.overlap.pydetectreads the lanes, reports per-lane floors (a lane's counts are totals only when the lane is ok and no run-wide advisory such as an unvalidated CLI version stands; a lane-attributed advisory degrades only its own lane), and marks every candidatere_derivable(false when the lane its seeded or observed class maps to is broken, both directions on a class collision; null for session-provided and marketplace classes). A name collision lists every registration with its invocation mode. An inventory withoutlaneskeeps the previous reading.self-checkflags a description that names a native surface by class and kind inside awhen/where/ifclause with an availability word and no gate token in that clause, as an advisory (exit 3).--upstream-sharepeats, one value per upstream repository the store cites (the store records commits in two repositories, so one value always drifted).Also: two seeded pairs (
doctorandskill-doctoragainstclaude-ops:audit-skill-visibility), the inventory skill's integrity table and the audit-native-overlap detection posture reworded per lane,reference/extraction.mdrewritten for the region, registrar, locality, collision, and lane rules, the inventory eval for degraded counts updated, the audit-native-overlap description trimmed to 1,020 characters with every claim and trigger phrase kept (and its row dropped fromscripts/skill-description-cap-baseline.txt, which the changed-skills check requires once a description no longer breaches), CHANGELOG entry, version 0.53.0 to 0.54.0.docs/specs/native-overlap-route-to-compose.mdanddocs/specs/native-overlap-integration-design.md: the approved plan and design resolution, graduated from the pruned topic slice per the topic-docs convention, with a## Statussection that re-anchors the deferred units on native-references 1.1.0 and the 19-row store.Deviations from the plan, recorded in the spec: the planned marker-scoped constant map cannot work (the hoisted constants sit about 8.7 MB and 173 marker occurrences ahead of their registrations on 2.1.263), so the locality rule above replaced it; the self-check sanity criterion needs both upstream SHAs; measured wall clock is about 14 s, so the bound is stated as 30 s rather than 15 s.
Review round: the three Codex findings (flag-driven twins deduped, below-floor literals not degrading the lane, per-lane count labels ignoring run-wide drift) are fixed in f60ef12 with a test each; threads resolved.
Verification
Seeded pairs quoted per the plan:
{ "native": { "name": "doctor", "class": "bundled-skill" }, "component": { "plugin": "claude-ops", "skill": "audit-skill-visibility", "kind": "skill" }, "why": "doctor's checkup covers unused extensions and skill visibility as one pass of a broader health check; the audit asks the whole-fleet visibility question." } { "native": { "name": "skill-doctor", "class": "builtin-command" }, "component": { "plugin": "claude-ops", "skill": "audit-skill-visibility", "kind": "skill" }, "why": "Both ask which loaded skills go unused and what each costs; the built-in is a one-shot report that excludes bundled skills, the audit is the fleet-wide visibility question." }Run locally on the Linux ELF 2.1.263 build in this container, on the merged head:
python3 plugins/claude-ops/skills/inventory/scripts/test_inventory.py: 60 tests OK (sixtest_read_bundlecases, routes, locality, invocation fields, collisions, lanes, below-floor degradation).python3 plugins/claude-ops/skills/audit-native-overlap/scripts/test_overlap.py: 99 tests OK (main's Boundary-naming parity tests plus this PR's lanes,re_derivable, collision evidence, run-wide versus lane-attributed count labels, presence-mention advisory with negative fixtures, repeatable--upstream-sha).inventory.py --binary-only --out /tmp/inv.json: 13.6 to 14.7 s wall clock; 35 bundled-skill names,designas a two-registration list withdisable_model_invocation[false, true],doctormodel-disabled and terminal-oriented,simplifyandrunwith no invocation-control field,registrar_routeesm-export,plugin_backedholdssecurity-review, noehrpd,runs_below_floor2.inventory.py --self-check:DEGRADEDwith lanesok/degraded/ok; the bundled advisories are the dynamic roster (2 registrations) and the 2 below-floor literals, exit 3.overlap.py self-check --upstream-sha ed404106fcd80ba98ecb7c851e531dcb626d13b7 --upstream-sha d7dbd9a09f59775726ed14bbea8fc9dfdff62f7b: exit 3, no problems, exactly three advisories on the 19-row store (version drift 2.1.232/251/252 vs 2.1.263, and the two presence-mention advisories namingvisualization:visualizeandprototype:explore-directions).overlap.py generate --check: in sync, 19 rows.jq '.pairs | length'on the canonical pairs prints 16.scripts/validate-plugins.sh: passes.scripts/run-ruff.sh checkandformat --checkon both script directories: clean.check-evals-quality.shon the inventory evals: PASS. markdownlint and typos on the touched markdown and the two specs: clean.scripts/check-purged-em-dashes.sh: no em dashes.scripts/check-changed-skills.sh origin/main: 0 failed (check-skillpasses on audit-native-overlap and inventory; three pre-existing advisory warnings remain on the former).scripts/affected-tests.sh --run: every selected shell suite passes exceptplugins/claude-ops/skills/plugins/scripts/cache-content-check.test.sh, whose process-budget probe measures-1in this container (its pid-stampedPS4does not reach the traced shell). The same suite fails identically onmain's copy of that directory, which this PR does not touch, so it is an environment finding of this sandbox, not this change's. The 14 Python suites the runner lists as NOT RUN were run directly where relevant (the two above plustest_audit_skill_visibility.py, 96 OK).ciworkflow passed in full on head ef9b96f (run 34626653025: lint, hook-utils, test-linux 0 to 3, test-windows, ci-status); the one earlier red lane (changed-skills on 3f2f538) was the stale baseline row, fixed in 5490b5f. Head a6c2ff3 merges main's 0.53.0 release and moves this entry to 0.54.0; the three Python suites, markdownlint, the em-dash gate, validate-plugins, and the changed-skills check pass on it.claude.exewas reachable from this session; the PE container path is covered by a byte-layout fixture and the CHANGELOG states the Linux-only basis.Contract slice: pruned in
daf8d692per the topic-docs convention (pre-prune commiteab22841); its durable outcomes are the two spec files above and the sub-issue comments.Related
🤖 Generated with Claude Code
https://claude.ai/code/session_01JEFsqe8fDbDjSFx79hVB9e