Skip to content

audit: a citation must resolve on the ref the audit named, and both passes get checkpointed (0.2.0) - #34

Merged
mmcky merged 2 commits into
mainfrom
audit-severity-1-defects
Aug 7, 2026
Merged

audit: a citation must resolve on the ref the audit named, and both passes get checkpointed (0.2.0)#34
mmcky merged 2 commits into
mainfrom
audit-severity-1-defects

Conversation

@mmcky

@mmcky mmcky commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

The two severity-1 defects from run 1, filed as items 1 and 2 on #21 and sequenced there as one doctrine-level PR because they are the same defect at two altitudes: the audit's own record claiming more than it can support. Five of the seven defects on #21 remain open after this.

Defect 1 — a [verified] citation that the reader cannot resolve

doctrine §2 required file:line, a merged PR or a tag, and never that the cited thing be reachable from the ref the audit says it verified against. Run 1's headline finding cited commit b99b431 as where a file's history ends — a commit that is real and does touch the file, but lives only on an unmerged branch, while the report's own header said "verified against main @ 2c3d624". The conclusion survived independent checking; the citation did not. A citation that resolves for its author and not for its reader is worse than an untagged claim, because the tag is what invited the trust.

§2 now states the requirement for every citation form, not just commits. This is broader than #21 asked for, deliberately: file:line and PR citations are ref-relative too and fail the same way — a line number that is right in a dirty working tree and wrong on the ref, an open PR cited as though merged. So a commit must be an ancestor of the baseline ref, a file:line must be that line on the ref rather than in the working tree, and a PR must be merged into it. /audit:issues phase 2 runs the mechanical case before tagging:

git merge-base --is-ancestor <sha> <ref>   # exit 0 = citable

Evidence that genuinely lives off-ref stays citable — as the open PR it is, tagged [stated] or [inferred]. The rule removes a false-precision trap, not a class of evidence.

Defect 2 — half of phase 2 sat outside the checkpoint

findings.md held the 56 open issues. The 62 closed ones were verified and written straight into the catalog, so the resume rule shipped in 0.1.2 — "resume at the lowest number in issues.json with no entry" — would have re-verified all 62 from scratch while reporting itself complete. The checkpoint materialised, which is what #17 set out to prove; it just covered one of the two passes.

findings.md now carries ## Open and ## Closed sections, and the resume rule partitions issues.json by state and resumes each side independently at the lowest number with no entry under the matching heading. The skill also says explicitly not to infer progress from a single block or from the file's length.

This is what makes run 2 worth running for its stated purpose. Run 2 exists to test resume, and testing a resume path against a checkpoint already known to cover half the phase would have wasted the most informative run in #16's matrix — the block-3-before-block-4 argument on #25.

Release

audit 0.1.4 → 0.2.0, minor rather than patch. Both fixes change what an operator does during a run — one adds a check that can change how a finding is tagged, the other changes which files a run writes — which is the line developing-skills draws between the two. scripts/validate.py passes all three plugins and scripts/check-version-bump.py reports ok audit — 0.1.4 → 0.2.0.

🤖 Generated with Claude Code

…asses get checkpointed (0.2.0)

The two severity-1 defects from run 1 (#21). They are the same defect at two
altitudes: the audit's own record claiming more than it can support.

Defect 1 — reachability. doctrine §2 required `file:line`, a merged PR or a tag,
and never that the cited thing be reachable from the ref the audit says it
verified against. Run 1's headline finding cited a commit that is real, does
touch the file, and exists only on an unmerged branch, while the report's header
named `main` @ 2c3d624. The conclusion survived independent checking; the
citation did not. §2 now states the requirement for every citation form, and
phase 2 runs `git merge-base --is-ancestor <sha> <ref>` before tagging a commit.
Off-ref evidence stays citable as the open PR it is, tagged [stated]/[inferred].

Defect 2 — the closed side was never checkpointed. `findings.md` held the 56 open
issues; the 62 closed ones went straight to the catalog, leaving half of phase 2
outside the checkpoint and breaking the single-block resume rule shipped in
0.1.2, which would have re-verified all 62 from scratch while reporting itself
complete. `findings.md` now carries `## Open` and `## Closed`, and the resume
rule partitions `issues.json` by state and resumes each side independently.

Minor rather than patch: both change what an operator does during a run.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 7, 2026 04:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the audit plugin’s doctrine and /audit:issues runbook to (1) require that [verified] citations resolve on the baseline ref the audit names, and (2) ensure phase-2 checkpointing covers both the open and closed passes, with a corresponding minor version bump to 0.2.0.

Changes:

  • Tighten evidence rules: [verified] citations must be reachable from the audit’s named baseline ref (including commit-SHA reachability checks).
  • Update /audit:issues checkpoint/resume guidance so findings.md checkpoints both open and closed passes separately.
  • Release the behavior/procedure change as audit 0.2.0 and sync the marketplace entry.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
audit/skills/issues/SKILL.md Updates the runbook to checkpoint both passes and to require baseline-ref citation checks before tagging [verified].
audit/references/doctrine.md Extends evidence-class doctrine to make baseline-ref reachability a requirement for [verified] citations.
audit/CHANGELOG.md Documents the 0.2.0 release and the two severity-1 procedural fixes.
audit/.claude-plugin/plugin.json Bumps audit plugin version to 0.2.0.
.claude-plugin/marketplace.json Updates the marketplace’s audit entry to version 0.2.0.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 25 to 26

An unqualified claim is a defect. `[inferred]` is legitimate and often the most valuable class — but it must never be dressed as `[verified]`, and a status change recommended on `[inferred]` alone should say so in the recommendation itself.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, and fixed in 27a5db6 — though at the other end than suggested. You are right that the two statements disagreed: §2's table had grown a fourth form and the reachability rule, while §1 rule 1 still read "Cite file:line, a PR, or a tag for each verified claim". A reader meets rule 1 first and gets the stale list.

The fix is to stop §1 enumerating rather than to add a clarification at §2. §2 already states it correctly, so a third statement of the accepted forms would be one more copy to drift — and duplicated lists drifting is exactly what produced this defect. Rule 1 now carries the requirement and points at §2 for the forms, which leaves one place where they are written down. That also matches the repo's single-source-of-truth rule (AGENTS.md), which this plugin's own doctrine is supposed to model.

Comment thread audit/skills/issues/SKILL.md Outdated
…hability check read as an instruction

Copilot's two comments on #34, both on text this PR introduced.

doctrine §1 rule 1 still enumerated "file:line, a PR, or a tag" while §2's
table had grown a fourth form and the reachability rule — the drift Copilot
spotted. Fixed at the cause rather than by adding a third copy: rule 1 now
points at §2, which is the only place the forms are stated.

SKILL.md's check read "For a commit that is `git merge-base ...`; ... for a PR
it is merged into it" — a missing comma and two unanchored pronouns, in what is
meant to be an operator instruction. Now one bullet per citation type, each
naming the action.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mmcky
mmcky merged commit d4e8df8 into main Aug 7, 2026
5 checks passed
@mmcky
mmcky deleted the audit-severity-1-defects branch August 7, 2026 05:07
mmcky added a commit that referenced this pull request Aug 7, 2026
…f the citation list

Copilot's three comments on #35, all on text this PR introduced.

Step 4 said the closed pass "has never been checkpointed at all" two sentences
before crediting #34 with checkpointing it. True of run 1, false of main. The
point is that it has never been *exercised*, which is what it now says.

The doctrine §2 link was hard-coded to blob/main while line 7 of the same file
links doctrine relatively, and developing-skills says to keep relative links
relative because CI checks they resolve. The AGENTS.md absolute-URL rule governs
links out of a plugin directory, since an installed plugin ships alone and
cannot resolve `../`; docs/ never ships alone, so relative is right here.

Review check 3 enumerated citation forms and omitted tags. Rather than sync what
had become the fourth copy of that list, the row no longer enumerates at all —
the same fix applied to doctrine §1 on #34, and what line 7 means by "points,
never restates". The list at line 79 is kept deliberately: it is the teaching
sentence and it links to §2 in the same breath.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mmcky added a commit that referenced this pull request Aug 7, 2026
…ually does (#35)

* Docs: bring the audit tutorial and CATALOG up to what audit 0.2.0 actually does

The tutorial is the procedure for run 2, and run 2 is the run that tests
resume — so it was the one document that could not be left describing the
pre-#34 behaviour.

Step 4 taught the single-block resume rule that #34 replaced: read findings.md,
resume at the lowest number with no entry. It now describes partitioning
issues.json by state and resuming each side independently, and names the new
failure mode — resuming the open set correctly while re-doing the closed set
from scratch. The same step quoted the three-form citation list that doctrine §2
has outgrown, without the reachability rule that is the whole point of defect 1.

Two review checks are strengthened where run 1 showed them to be weak. Check 3
passed a citation that pointed at an unmerged branch, so it now says to resolve
each sampled citation on the ref the header names. Check 5 held in the report
and broke in the checkpoint, so it now looks at findings.md as well as the
output.

CATALOG records the two severity-1 fixes. Its central caveat is unchanged and
still true: resumability is untested, because run 1 was never interrupted.

Repo-level files only — no plugin directory touched, so no version bump.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Docs: fix a contradiction, an absolute self-link, and a fourth copy of the citation list

Copilot's three comments on #35, all on text this PR introduced.

Step 4 said the closed pass "has never been checkpointed at all" two sentences
before crediting #34 with checkpointing it. True of run 1, false of main. The
point is that it has never been *exercised*, which is what it now says.

The doctrine §2 link was hard-coded to blob/main while line 7 of the same file
links doctrine relatively, and developing-skills says to keep relative links
relative because CI checks they resolve. The AGENTS.md absolute-URL rule governs
links out of a plugin directory, since an installed plugin ships alone and
cannot resolve `../`; docs/ never ships alone, so relative is right here.

Review check 3 enumerated citation forms and omitted tags. Rather than sync what
had become the fourth copy of that list, the row no longer enumerates at all —
the same fix applied to doctrine §1 on #34, and what line 7 means by "points,
never restates". The list at line 79 is kept deliberately: it is the teaching
sentence and it links to §2 in the same breath.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants