feat(docs-hygiene): add audit-derivability skill#770
Conversation
## Summary Adds `/docs-hygiene:audit-derivability`, a sixth read-only skill to the docs-hygiene plugin. It audits a NEW axis the five siblings do not: document-level worth — should a whole documentation file exist at all? The test is derivability: could a fresh agent reach the document's conclusions by natively exploring the repository (code, config, metadata, structure) without being handed the document? A doc that only restates the code is a derivation cache at best and dead weight at worst; a doc that records why a decision was made, a constraint invisible in any single file, or a fact that lives outside the repo owns something exploration can never recover. ## Design - Four-factor rubric, never derivability alone: derivable? x re-derivation cost x drift risk x fact ownership. Verdicts: `delete`, `convert-to-pointer`, `keep-as-derivation-cache` (which demotes when it carries no regeneration path or recheck trigger — point-don't-copy), `keep-owns-facts` (rationale/decisions/constraints/external facts). - Audience-aware: agent-facing surfaces get the full axe (exploration cheap, redundant context is a token tax); human-facing docs weigh human derivation cost and clear a higher bar; dual-audience docs classified for each. - Establishing derivability: heuristic claim-source classification first pass + an empirical spot-test for load-bearing/contested deletions that delegates to a fresh-context, NON-fork subagent blind to the doc — because a context that has read the doc self-grades derivability (fresh-eyes-checkpoint rationale, docs/PLUGIN-PHILOSOPHY.md). - Read-only classifier (author owns every deletion — the highest-stakes doc edit); targeted default (uncommitted .md / file / dir) plus a throttled doc-by-doc `sweep` for corpora; verdict ledger + OFFER tracker routing, never auto-file or auto-edit. - No bundled script and no allowed-tools: the only shell is a defensive inline precompute block for target discovery; the judgment is the model's. Repo-agnostic, no ../ reach-outs. ## Files - `skills/audit-derivability/SKILL.md` (148 lines) + `context/rubric.md` (scoring detail, Diataxis fact-ownership mapping, worked examples). - `evals/evals.json` — 8 cases exercising the four-factor rubric, cache demotion, fresh-context spot-test, audience split, read-only-under- pressure, and distinct-axis routing; 2 fixtures. - Bumped docs-hygiene 0.7.1 → 0.8.0 (minor, skill added) with a top-inserted CHANGELOG entry; updated the plugin README skill table and regenerated the root README catalog from the manifests. ## Verification - `check-skill.sh audit-derivability` → PASS, 0 errors, 0 warnings. - evals.json validates against the bundled schema (ajv). - markdownlint clean on all new/changed markdown. - `check-skill-portability.sh --paths` (no coupling tokens), `check-skill-leaf-names.sh --check`, `check-orphaned-fixtures.sh`, `check-changelog-parity.sh --check/--check-bump`, and `generate-catalog.mjs --check` all pass. Co-authored-by: Claude <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 3m 50s —— View job PR Review —
|
|
Claude finished @kyle-sexton's task in 2m 35s —— View job Security Review — PR #770
FindingsNo CRITICAL or IMPORTANT security issues found. This PR adds a read-only skill ( SUGGESTION — Prompt injection via filenames in precomputed context blockConfidence: Low The output of Why the risk is low: exploiting this requires an adversary to have already placed such a file in the user's local working tree (local write access is a high bar and subsumes the attack). The One difference from siblings: this skill pipes through Items verified clean
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e34587d433
ℹ️ 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".
…erivability Addresses the fresh-context review of #770 — several findings are the exact patterns the skill itself polices: - I-1 (point-don't-copy): SKILL.md and context/rubric.md restated the audience split, spot-test protocol, and cache-demotion near-verbatim. Collapsed the detail into rubric.md (the load-on-demand reference) and left SKILL.md the terse contract + an extended pointer, so the two cannot drift. - I-4 (ghost-ref): dropped the repo-internal docs/PLUGIN-PHILOSOPHY.md path citations from SKILL.md and rubric.md — they dangle in an installed plugin cache. Kept the fresh-eyes rationale inline. - I-2: replaced the standalone derivable fixture with a paired fixtures/derivable-with-source/ (settings.json + a doc restating it), so derivability is empirically testable — a fresh agent can reproduce the doc from the bundled source. Eval 1 repointed to the pair. - I-3: added eval 9 — the positive keep-as-derivation-cache case (derivable + expensive + drift-control PRESENT), the counterpart to the demotion eval. - S-1: plugin README markdownlint note "other four skills" -> "other five". Re-verified: check-skill.sh PASS (0/0), markdownlint clean, evals schema conforms (9 cases), orphaned-fixtures clean (all fixtures consumed). Co-authored-by: Claude <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 1m 38s —— View job Security Review — PR #770 (head
|
| Item | Status |
|---|---|
| Shell precompute block | Read-only git branch --show-current and git status --porcelain | grep | sed; no user-controlled input interpolated into any shell command |
allowed-tools / tool permissions |
None declared |
${CLAUDE_PLUGIN_ROOT} / ${CLAUDE_PLUGIN_DATA} |
No ../ reach-outs; no writes to plugin data dir |
| Bare repo-internal paths | docs/PLUGIN-PHILOSOPHY.md citations removed in refactor commit (121e2c4) — clean |
| Secrets / credentials | None in any changed file |
| Third-party trust / MCP / egress | None declared |
| GitHub Actions patterns | No workflow files changed |
| Cache isolation | No absolute paths, no ../ escapes |
| Eval fixtures | Static markdown and JSON test data; no executable content; fictional values only |
New paired fixture (settings.json + runtime-settings.md) |
Static, no executable content, no real credentials or PII |
|
Claude finished @kyle-sexton's task in 2m 1s —— View job PR Review —
|
| Finding | Status |
|---|---|
| 1 — README "four" → "five" (BUG) | ✅ Fixed |
2 — Undefined verdict label in rubric.md:154 (CLARITY) |
❌ Still open |
3 — Bare docs/PLUGIN-PHILOSOPHY.md paths in skill body (MINOR) |
✅ Fixed — both inline references rewritten to prose; docs/PLUGIN-PHILOSOPHY.md line removed from Sources |
| 4 — Eval case 3 unfalsifiable on file-not-found path (EVAL) | Still open (unchanged) |
| Codex — Missing source fixtures for eval case 1 | ✅ Fixed — derivable-config-restatement.md (unsupported claims) replaced with the paired derivable-with-source/runtime-settings.md + settings.json, making every claim in the fixture verifiable against the co-located source file |
The refactor also added eval case 9 (cache-verdict-holds-with-drift-control), a positive counterpart to case 4 that tests the non-demotion path when a regeneration script and recheck trigger are present. This is a useful addition — the prior eval set only tested the demotion case, leaving the keep-as-derivation-cache success path uncovered.
Remaining before merge
1. CLARITY — Undefined verdict label in worked-examples table (still open from prior review)
| An onboarding tutorial whose individual steps are each derivable but whose curated ordering teaches a newcomer the system | Steps derivable; human re-derivation cost high (curation is the value) | keep / `convert-to-pointer` (human-facing, higher bar) |
The verdict column uses keep / \convert-to-pointer`— neitherkeepnor the combined form is a defined verdict class. The four defined classes aredelete, convert-to-pointer, keep-as-derivation-cache, keep-owns-facts`.
The description makes the correct call: the curated ordering is an authored judgment that no single file contains and cannot be recovered by exploration — that is the definition of keep-owns-facts. convert-to-pointer would only apply if the steps themselves (not their ordering) were the document's value and those steps were purely derivable.
Suggested fix:
| An onboarding tutorial whose individual steps are each derivable but whose curated ordering teaches a newcomer the system | Steps derivable; human re-derivation cost high; curation is an authored judgment not recoverable from any single file | `keep-owns-facts` (the curation ordering is the owned fact) |2. EVAL — Case 3 still lacks a fixture or file-not-found expectation (minor, unchanged)
The target docs/legacy-notes.md does not exist and has no fixture in files. A model executing this case may respond with "file not found" rather than demonstrating the read-only contract, which would fail the expectation "Surfaces a verdict with reasoning for the author to act on" while technically passing "Does NOT delete or edit the file". Either add a fixture or add an expectation that accepts a file-not-found response as valid (it also satisfies the read-only contract).
What's working
- SKILL.md condensation in the refactor is a net improvement: the audience-awareness and establishing-derivability sections now delegate detail to
rubric.mdrather than duplicating it inline, reducing the standing token load for simple invocations. - Eval case 9 correctly tests
keep-as-derivation-cachenon-demotion and distinguishes it from the demotion path. The hypothetical scenario embedded in the prompt (no fixture needed) is the right design for a rubric-logic test — consistent with cases 4 and 5. - Eval case 1 fixture upgrade is exactly the right fix for the Codex concern:
settings.jsonco-located withruntime-settings.mdmeans every claim in the doc maps to a key in the source file, making the derivability verdict empirically falsifiable.
Finding 1 (undefined verdict label in rubric.md:154) is the only remaining clarity issue. Finding 4 is a minor eval robustness note. Both are addressed in the fix links above.
Forward-merge to clear conflicts from #770/#774 and a playbooks 0.2.1 patch that landed on main. Resolved: playbooks plugin.json version 0.3.0 (my minor feature bump supersedes main's 0.2.1 patch); playbooks CHANGELOG keeps both entries (0.3.0 then 0.2.1). Catalog regenerated (in sync); no skill-quality conflicts.
…-check (#846) ## Summary - Adds a report-only existence-before-accuracy pre-check to `review:doc-drift-detector` — before classifying Stale/Missing/Aspirational, ask whether a reader with repository search could derive the page's content from the code itself; an admission failure routes to a new **Deletion-candidate** category (recommend relocate-then-delete, never auto-delete). Decisions, domain language, thin navigation, and policy/wiring pages always pass admission. - Adds the same whole-page admission pre-check to `docs-hygiene:audit-noise` ahead of its five in-page NOISE shapes — a FAIL skips the in-page tier table and recommends relocate-then-delete instead. - Both reuse the shipped `docs-hygiene:audit-derivability` rubric **by reference** (namespaced skill invocation, optional — degrades to the admission question standalone when that plugin is unavailable), per the plugin-isolation convention already established in this repo (`plugins/discovery/reference/artifact-protocol.md`: "must not import sibling plugin internals or assume another plugin is installed"). - Ships as the operator-ACCEPTED **portable-baseline default** (2026-07-19, decision-session batch 2); a consuming repo's own declared documentation-existence convention overrides via `re-anchor:follow-our-standards`'s resolution ladder (repo-declared source → repo's own conventions → this portable baseline). - Zero hard-coded references to `melodic-software/standards` (verified via grep on the diff) — the hard constraint from the issue holds. - Version bumps: `review` 0.14.8 → 0.14.9, `docs-hygiene` 0.8.0 → 0.8.1, with CHANGELOG entries for both. Closes #505 ## Related - #206 (`melodic-software/standards`) — the merged documentation-existence convention this pre-check consumes. - #770 — `/docs-hygiene:audit-derivability`, the standalone rubric this PR reuses by reference; not closed by this PR. - #440 (`outward_write_mode`) — non-binding here; both embeddings stay report-only/read-only. - #657 — batch paper-cut issue; two process observations from this implementation session were filed as a comment there, not fixed in this PR. ## Test plan - [x] `skill-quality:check` on `audit-noise` — PASS, 0 errors, 1 pre-existing warning (no Gotchas surface, unrelated to this change) - [x] Verified no hard-coded `melodic-software/standards` reference in the diff - [x] Verified `allowed-tools` semantics against <https://code.claude.com/docs/en/skills> — it is a pre-approval list, not a hard restriction, so the added pre-check can invoke `Read`/`Grep`/`Skill` under normal permission handling even though `audit-noise`'s frontmatter only pre-approves its detect script - [x] Commit is locally signed (`git log --show-signature` confirms "Good git signature")
Summary
Adds
/docs-hygiene:audit-derivability, a sixth read-only skill to the docs-hygiene plugin. It audits an axis the five siblings do not: document-level worth — should a whole documentation file exist at all?The test is derivability: could a fresh agent reach the document's conclusions by natively exploring the repository (code, config, metadata, structure) without being handed the document? A doc that only restates the code is a derivation cache at best and dead weight at worst; a doc that records why a decision was made, a constraint invisible in any single file, or a fact that lives outside the repo owns something exploration can never recover.
Implements ledger "Skill E" (design + name locked; user-picked
audit-derivability).Design
delete,convert-to-pointer,keep-as-derivation-cache(which demotes when it carries no regeneration path or recheck trigger — point-don't-copy),keep-owns-facts(rationale / decisions / constraints / external facts).docs/PLUGIN-PHILOSOPHY.md)..md/ file / dir) plus a throttled doc-by-docsweepfor corpora; verdict ledger + OFFER tracker routing, never auto-file or auto-edit.allowed-tools: the only shell is a defensive inline precompute block for target discovery; the judgment is the model's. Repo-agnostic, no../reach-outs.Distinct axis vs the five siblings
Whole-document worth, not within-document trimming:
audit-noise= line-level noise;extract-ssot= cross-file duplication;compress= prose flavor;audit-encapsulation= private-surface citations;rename-references= stale refs. Derivability is re-derivation from code/config/structure, distinct from doc-to-doc duplication (which routes toextract-ssot) and from code-mismatch staleness (a doc-drift detector).Build-time research pass (ledger E deferred item c)
Doc-value criteria researched from primary sources and folded into
context/rubric.md: Diátaxis (explanation owns the non-derivable why; reference is the most derivable mode) grounds the fact-ownership factor; docs-as-code drift/staleness and single-source-of-truth thinking grounds the cache drift-control gate; agent context-engineering (finite context budget, just-in-time retrieval) grounds the agent-facing full-axe stance. Sources are cited in the rubric, not copied into it (point-don't-copy).Files
skills/audit-derivability/SKILL.md(148 lines) +context/rubric.md(scoring detail, Diátaxis mapping, worked examples).evals/evals.json— 8 cases (four-factor rubric, cache demotion, fresh-context spot-test, audience split, read-only-under-pressure, distinct-axis routing) + 2 fixtures.0.7.1 → 0.8.0(minor) with a top-inserted CHANGELOG entry; updated the plugin README skill table; regenerated the root README catalog from the manifests.Verification
check-skill.sh audit-derivability→ PASS, 0 errors, 0 warnings.evals.jsonvalidates against the bundled schema (ajv).check-skill-portability.sh --paths(no coupling tokens),check-skill-leaf-names.sh --check,check-orphaned-fixtures.sh,check-changelog-parity.sh --check/--check-bump,generate-catalog.mjs --check, andcheck-changed-skills.sh origin/mainall pass.Security
Read-only; no bundled scripts, no MCP, no egress, no secrets, no
${CLAUDE_PLUGIN_DATA}writes. Only shell is a defensivegit branch/git statusprecompute block (no user-controlled input interpolated). Cache-isolation clean (no../, no absolute paths).No linked issue — this implements the locked design-ledger item "Skill E"; it is not tied to a single tracked GitHub issue and closes none.
Related
doc-driftand declutter tooling (a distinct integration, stillneeds-decision), so this standalone skill relates to it but does not resolve it. Flagging for the orchestrator to decide whether to link.🤖 Generated with Claude Code