Skip to content

fix(claude-config): audit-pass specifies 1,547 lines of runtime mechanism and ships no scripts, so the lease, the partial, and the resume path are prose only #2280

Description

@kyle-sexton

audit-pass specifies sha256 state keys, sixty-second heartbeats, two-sided lease liveness,
compare-and-set owner_epoch fencing, append-only partials and a run manifest — across 1,547 lines of
SKILL.md plus ten reference/*.md — and ships no scripts at all. It is the only audit skill in
claude-config with no scripts/ directory. Three separately-observable defects are consequences of
that one gap: the lease the contract requires of every run was not written, the /doctor handoff's
--resume closure depends on a partial the run is most likely to skip, and Phase 3 declines to bound
the one cost dimension that actually blew up while naming a mitigation that is not implemented.

Two smaller placeholder-semantics defects ride along in the same skill: the {id} derivation the
report path depends on is still unstated, and the default target is expressed as a condition over a
placeholder the reader cannot evaluate — the exact shape the sibling audit-prompting-postures now
forbids in writing after #2250.

Rows

  • F3plugins/claude-config/skills/audit-pass/ — 1,547 lines of machine-checkable contract across SKILL.md and ten reference/*.md, zero scripts, in a plugin whose four sibling audit skills all ship scripts/ with tests.
  • F5SKILL.md:125 and reference/run-state-and-resumability.md:76-100 — the lease is specified in full (path, two-sided liveness window, released tombstone, owner_epoch compare-and-set) as prose with no executable, and the observed run wrote none.
  • F12reference/report-location-and-schema.md:121 and SKILL.md:285 — Phase 4 marks the /doctor lane open, closable only by --resume; --resume reads the partial, not the report; no partial is written, so the report's instruction to the operator cannot work.
  • F13SKILL.md:258-262 — Phase 3 bounds lane count, explicitly declines to bound intra-lane fan-out, and mitigates with "let incremental persistence carry the rest" — the mechanism F5 shows absent. The observed failure was intra-lane.
  • F8reference/report-location-and-schema.md:19-23 — the {id} mangling rule is stated nowhere in the skill, and nothing records that ${CLAUDE_PLUGIN_DATA} is not in the Bash tool's environment, so a run cannot expand it from a shell. Fixed by ceaf013 (fix(claude-config): stop audit-pass asking the model to test a substituted placeholder #2403); see the verification note below.
  • F9SKILL.md:42-43 — the default target is written as "${CLAUDE_PROJECT_DIR} when set, else git rev-parse --show-toplevel", a condition over a token the harness has already substituted before the reader sees it. Fixed by ceaf013 (fix(claude-config): stop audit-pass asking the model to test a substituted placeholder #2403); see the verification note below.

Evidence

F3 — the spec-to-implementation gap

wc -l over the skill at HEAD: SKILL.md 395 plus ten reference/*.md = 1,547 lines.
git ls-tree -d origin/main plugins/claude-config/skills/*/scripts returns audit,
audit-automation-gaps, audit-instructions, audit-permission-grantsaudit-pass is the only
audit skill in the plugin with no scripts/ directory.
For contrast,
plugins/claude-memory/skills/audit/scripts/ ships ten files, five with .test.sh siblings.

Scope this precisely. The "no scripts" fact is verifiable from the repository and was verified. The
consequence the originating item leans on — "the run wrote no lease, no partial, no manifest" — rests
on one observed run reported by the session that performed it and is not reproducible from the
repository
.

Deferred shape, from the item and concurred with: scripts/resolve-run-paths.sh (plugin data dir plus
{id} mangling, state key across git/no-remote, the containment verdict report_path ⊆ target_root,
derived exclusion additions) and scripts/lease.sh (acquire/heartbeat/release/classify). Note
the ordering dependency: resolve-run-paths.sh would make the containment predicate that #2230 just
landed executable rather than prose, so it should follow the spec fixes rather than replace them.

F5 — the lease is specified and was not written

plugins/claude-config/skills/audit-pass/SKILL.md:125:

So every active run, read-only included, maintains a **lease**, and `--resume` reads it before it
reads the manifest.

reference/run-state-and-resumability.md:76-100 (§ "The lease — how --resume tells a live run from
an abandoned one") specifies the path, the contents (run id, pid, ISO-8601 start, a heartbeat_at
the run rewrites in place, an owner_epoch integer starting at 1), the two-sided liveness window, the
released tombstone, and the compare-and-set fencing — all prose, no executable.

Keep the attribution split the originating audit itself makes. The missing lease is
audit-pass's own defect. The concurrent writer being undetectable at its destination is a
different defect, owned by the unkeyed report paths filed separately in this batch. They must not be
retired by the same change.

F12 — the resume path depends on the artifact the run skips

reference/report-location-and-schema.md:121:

**Resume reads the partial, not the report**, so completion state is derivable from the artifact

SKILL.md:285: "open is an assembly terminator, not a completion.--resume therefore re-runs
it, which for a delegated lane means re-prompting rather than re-scanning."

This is the one place the F3/F5 mechanism gap reaches the operator as a false instruction in the
report
rather than as a missing internal, which is why it is worth its own row rather than being
folded into F3.

F13 — the disclaimed dimension is the one that blew up

SKILL.md:258-262:

**The lane count is bounded by the delegated interfaces, not chosen here** — one per scope value the
instruction catalog accepts, plus one for the memory layer — so it is a handful, and a per-run
dispatch ceiling would never bind. What is *not* bounded here is the fan-out inside a lane: the
delegated catalogs spawn their own subagents. So cap concurrency at 3–5 lanes and let incremental
persistence carry the rest — it is what degrades a blown session ceiling into a resumed run.

The reasoning in the passage is correct; the mitigation it names is the one F5 shows absent. The
observed failure was intra-lane (instruction-scan.sh exceeding a 120-second timeout over 39
surfaces). The scanner and its cost belong to audit-instructions; only the disclaimer and the
unimplemented mitigation are this skill's.

F8 — placement, environment, and derivation

grep -rn CLAUDE_PLUGIN_DATA plugins/claude-config/skills/audit-pass/ at HEAD. One of the three
original facts is now fixed by #2229/#2230:
the token does appear in SKILL.md (:105, :393), and
reference/report-location-and-schema.md:19-23 now states the resolution and cites the source:

- The report goes under `${CLAUDE_PLUGIN_DATA}` at `runs/<state-key>/<run-id>/findings.json`, which
  survives plugin updates. **State its location precisely, because a whole target class turns on it:**
  that directory resolves to `~/.claude/plugins/data/{id}/`
  ([plugins reference](https://code.claude.com/docs/en/plugins-reference), verified 2026-08-11), and no
  documented setting relocates it.

Two facts remain unstated. (1) The {id} mangling rule — "the plugin identifier with characters
outside a-z, A-Z, 0-9, _, and - replaced by -" (plugins reference, fetched 2026-08-11) —
appears nowhere in the skill; a wrong derivation produces a report the next run cannot find, which is
also how --resume loses a partial. (2) Nothing records that ${CLAUDE_PLUGIN_DATA} is not in the
Bash tool's environment. Plugins reference, fetched 2026-08-11: "All three are exported as environment
variables to hook processes and to MCP and LSP server subprocesses." The Bash tool is none of those, so
the variable is not expandable from a run's shell.

Explicitly unconfirmed, and it should stay that way here: whether "skill content" substitution
extends to bundled reference/*.md loaded on demand via Read is not stated by the docs. #1568 owns
the empirical check; resolve it there rather than re-litigating it in this skill.

F9 — a condition over a token the reader never sees

plugins/claude-config/skills/audit-pass/SKILL.md:42-43, unchanged at HEAD:

- **`target`** — the git repository to audit. Default: `${CLAUDE_PROJECT_DIR}` when set, else
  `git rev-parse --show-toplevel`. Never the working directory — a run launched from a subdirectory

Plugins reference, fetched 2026-08-11: "Which fields substitute them inline depends on the plugin
component: | Skill and agent content | Anywhere the placeholder appears |". SKILL.md is unambiguously
skill content, so for this file the substitution premise is doc-confirmed and the "when set" test is
one the reader is asked to make about a token the harness has already resolved. (Note the cross-page
tension #1568 records — the skills page's own substitution table omits ${CLAUDE_PLUGIN_DATA} and
${CLAUDE_PLUGIN_ROOT} while listing ${CLAUDE_PROJECT_DIR} — so for ${CLAUDE_PROJECT_DIR}
specifically both pages agree it substitutes in skill content.)

This row is stronger at HEAD than when it was filed. #2250 landed the opposite instruction in a
sibling skill of the same plugin —
plugins/claude-config/skills/audit-prompting-postures/SKILL.md now says, in the block that derives
its report path:

Run those and use the result. Do **not** express the path as a condition over `${CLAUDE_PROJECT_DIR}`
"when set": that placeholder is substituted inline before this file reaches you, so the literal token
is never visible and the condition is not yours to evaluate. Derive the key from commands you actually
run.

Two skills in one plugin now contradict each other on the same placeholder. Cheap fix, unchanged from
the original suggestion: phrase the default in prose — "the project root Claude Code resolved for this
session; otherwise git rev-parse --show-toplevel".

Adjacent, deliberately not duplicated

Provenance

Severity: MED · Provenance: mixed, stated per row. F3 (structural half), F12, F13, F8, F9 are AUDITOR_VERIFIED. F5 is SELF_REPORTED — the non-write is a runtime observation by the session that ran the component, and nothing in the repository can confirm or refute it. F3's runtime half ("the run wrote no lease, no partial, no manifest") is single-observation and is marked as such above. Every file:line and quoted line was independently re-verified against HEAD by the validation pass.
Origin: handoff-inbox item 20260811-020411-claude-config-audit-pass-report-path-inside-scan-set
Ledger: .work/handoff-inbox-batch-4/ledgers/I8-audit-pass-report-path.md § F3, F5, F12, F13, F8, F9
Verified against repo HEAD 9b34a82a. Line anchors re-derived at that commit — SKILL.md grew from 353 to 395 lines under #2234, so every ledger anchor past line 57 has moved.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions