Skip to content

fix(docs): scope three setup-contract rules to what backs them - #3183

Merged
kyle-sexton merged 9 commits into
mainfrom
fix/3182-prose-reach-past-evidence
Aug 23, 2026
Merged

fix(docs): scope three setup-contract rules to what backs them#3183
kyle-sexton merged 9 commits into
mainfrom
fix/3182-prose-reach-past-evidence

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Closes #3182

Summary

Post-merge verification of #3139 (merged as ef4d53959) found three defects in the prose it shipped, each the same class that PR existed to correct: a claim or rule reaching past what backs it. They were filed rather than quietly patched because the content was already on main.

This fixes those three plus the smaller items #3182 lists, in 46 added lines across three files.

Fix

1. The fetch prohibition's stated cause did not entail its stated rule. PLUGIN-PHILOSOPHY.md sanctioned "a documentation URL", then condemned any skill instructed to fetch it as having "made the publisher a runtime dependency". Fetching code.claude.com creates no such dependency, and a practice already shipping in the tree was condemned by it.

The prohibition now turns on the target's owner and reaches publisher-owned targets only. For those targets, distinguishing an instruction to fetch from a citation offered for a reader is genuinely hard, and the statement says so rather than implying it has been settled — plugins/architecture/reference/topic-docs.md is named as the open case, and no ticket owns it (#3136 is enforcement-site consolidation, not this).

2. The evidence-bearing bullet was unsatisfiable as worded. It required setup to report "the effective value it observed", while the same section pins effective value to running-session behaviour and directs verification to a fresh session. A same-session run can only observe the stored value. One word: effectivestored.

3. A narrowing presented as a faithful clarification. The hook-plugin eval skip stated its rationale as "no model-facing skill at all" where the prior text said "no model-invoked skill". Neither works: a setup skill sets disable-model-invocation: true, so either phrasing is satisfied by a plugin that ships one — admitting as skips exactly the plugins the rest of the rule excludes. The defect was stating the condition in terms of invocation mode at all. It now reads "no skill carrying a judgment-bearing contract", the test the warrant rule two sentences above already uses. Outcome unchanged: 19 hook plugins ship a setup skill, all 19 carry setup evals.

Smaller items. Both paired reconfiguration sites in MIGRATION-PLAYBOOK.md now name the readback location and agree in substance, including the sensitive-value limit — an asymmetry between them would have sent a reader reconfiguring a sensitive option at project scope to look in user settings, find nothing, and report a failed write, which is the false failure PLUGIN-PHILOSOPHY.md exists to prevent. Their provenance cites seam 1, which documents both halves, rather than smoke-test C, which explicitly disclaims covering a sensitive option. The "step 3 above" cross-reference — which pointed from inside Reintegration's step 1 at Reintegration's own step 3, about verify-before-retiring — is replaced by a direct citation of seam 1. The github.test.sh sweep's wider/narrower axes are named, and "both steps of the same job" is corrected to "each running in its own step". The workflow header's gate description is corrected: the pinned reusable requires four sections, not a closing keyword plus ## Related.

Verification

Local gates at the final commit: markdownlint-cli2 0 issues; check-contract-clause-coverage.py exit 0; lychee --offline 0 errors across 103 unique links; zizmor no findings. The workflow change is comment-only, confirmed by diff.

Six fresh-context verification passes, each given the bounded criteria plus an unbounded criterion instructing it to hunt for claims reaching past their evidence anywhere in the touched paragraphs. All six returned FAIL, and each round's fixes introduced at least one new instance of the defect being repaired.

The sixth pass found two, both in the single paragraph this PR had to write rather than cut, and both repairs were deletions: a tracker-wide "no ticket owns that question" that the tracker contradicts (#432 carries an accepted ruling on it, and scripts/skill-portability-tokens.txt stages a lint class blocked on that ruling), and a hedge that denied the statement its own preceding clause had just made. Every deletion from the prior round verified clean against the tree.

Reviewing where the findings came from settled the approach. Items 2 and 3 were clean from round three onward; essentially every finding from round two on landed in material added beyond what #3182 asked for — an enumeration of nonconforming instances, a paragraph grounding the prohibition against the tree, a rewritten security rationale, a sensitive-value carve-out. Each was written to close the previous round's finding and opened one or two of its own. The final revision deletes those elaborations rather than repairing them again, which is why the diff is 46 lines rather than the 2,926 it peaked at.

Twenty-five instances of the defect class were found across the five rounds. One was caught by the author re-reading their own writing, four by the review bots, and the rest by fresh-context verification. None by self-review.

Two things generalise. A verifier is bounded by its criteria, so a defect nobody names survives any number of green passes — every round's findings came from the unbounded criterion, not the checklist. And under-claiming is not the safe direction: round four's findings were mostly repairs to what round three's removals broke. Both directions are the same failure to say exactly what the evidence supports.

One pre-existing defect is deliberately left alone and filed as #3184: the workflow header's security rationale ("reads PR body metadata from the event payload only") is false against the pinned reusable, which live-refetches. It is outside #3182's scope, the zizmor suppression it backs is independently sound, and three separate rewrites of that comment block each introduced a new inaccuracy.

Related

🤖 Generated with Claude Code

Post-merge verification of #3139 found three defects in the prose it
shipped, each the same class that PR existed to correct: a claim or rule
reaching past its evidence.

- The org-agnosticism fetch prohibition stated a cause ("has made the
  publisher a runtime dependency") that does not hold for the
  third-party documentation URLs its own sanction covers, condemning a
  practice already shipping in the tree. The line now turns on who owns
  the target rather than on cite-versus-fetch, which also settles a
  coherence gap: for content an agent reads, "cited for a reader to
  consult" and "instructed to fetch" are not cleanly separable, so a
  rule keyed on that distinction leaves cases undecidable.
- The evidence-bearing bullet demanded the "effective value" observed,
  while the same section pins effective value to fresh-session
  behaviour. A same-session run can only observe the stored value, so
  the bullet was unsatisfiable as worded by the surface other docs
  restate in isolation.
- The hook-plugin eval skip restated its own rationale as "no
  model-facing skill at all" where the prior text said "no
  model-invoked skill". A setup skill sets disable-model-invocation:
  true and so is genuinely not model-invoked, meaning the original term
  did cover the excluded case: a substantive narrowing wearing the word
  clarification. The original term is restored and the exclusion now
  argues its own merits.

Also: name the read-back location at the first of the two paired sites
so it agrees with the second; correct a cross-reference that named
Reintegration's own step 3 rather than Fresh-consumer onboarding's;
name the axes on which the github sweep is wider and narrower; and
correct the pr-issue-linkage header comment, which still described the
gate as validating one section when the pinned reusable requires four.

Closes #3182

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

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 2m 1s —— View job


Code review complete ✅

  • Gather context (PR diff, CLAUDE.md, skill instructions)
  • Review docs/PLUGIN-PHILOSOPHY.md changes
  • Review docs/MIGRATION-PLAYBOOK.md changes
  • Review .github/workflows/pr-issue-linkage.yml comment-only change
  • Post findings

Ran the CODE-REVIEW lane (/review:code-review), scoped to correctness and maintainability. No security lane applies here (docs + comment-only workflow change).

Summary

This is a self-correcting prose PR, so I verified each of its own factual claims against the referenced code/docs rather than just reading the diff in isolation:

  • Item 1 (ownership-based fetch rule) — confirmed plugins/claude-config/skills/audit/SKILL.md:167 does curl https://code.claude.com/docs/en/<page>.md, which the old wording ("cited for a reader to consult" vs. "instructed to fetch") would have condemned. The new "who owns the target" framing in docs/PLUGIN-PHILOSOPHY.md correctly stops flagging this conforming, non-publisher-owned fetch.
  • Item 2 (evidence-bearing bullet) — confirmed the surrounding "fresh session" paragraph in docs/PLUGIN-PHILOSOPHY.md still pins effective value to a fresh session, so effectivestored in the bullet resolves the self-contradiction without touching the paragraph that governs the effective-value claim.
  • Item 3 (hook-plugin eval skip) — confirmed the restored "no model-invoked skill" term literally covers a setup skill (disable-model-invocation: true), and the new sentence explaining why the skip still doesn't reach it (absence of a judgment-bearing contract, not invocation mode) is internally consistent with the rest of the warrant-rule paragraph in docs/MIGRATION-PLAYBOOK.md.
  • Cross-reference fix — verified "Fresh-consumer onboarding's step 3" in the Reintegration section (docs/MIGRATION-PLAYBOOK.md) now correctly points at the step-3 install/config text in the Fresh-consumer onboarding section, not Reintegration's own step 3 (verify-before-retiring). The remaining same-section "step 3" self-reference a few lines later in Reintegration's own Exception note is correctly left unqualified, since it's unambiguous in that local list context.
  • Workflow comment — confirmed via git diff that only #-comment lines changed in .github/workflows/pr-issue-linkage.yml (no on:/jobs:/permissions:/uses:/pin touched), and cross-checked the new header text against .claude/source-control.md's pr_body_required_sections (Summary, Fix, Verification, Related), which matches.

No correctness or maintainability defects found in the touched lines. The PR's own verification claims (markdownlint, check-contract-clause-coverage.py, lychee, zizmor) are author-reported and were not independently re-run in this pass — noted per lane policy rather than restated as independently confirmed.

@claude

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 46s —— View job


Security review — skipped (no security-relevant surface)

  • Gather context (PR diff, changed files)
  • Apply skip gate
  • Review changed files for security-relevant surface
  • Post findings

Skip gate triggered: condition 2 — "Change has no security-relevant surface after reading the diff."

All three changed files are prose-only:

  • docs/MIGRATION-PLAYBOOK.md and docs/PLUGIN-PHILOSOPHY.md — wording/clarification edits to documentation content (no code, no config schema, no examples with executable snippets touched).
  • .github/workflows/pr-issue-linkage.yml — a comment-only edit (lines starting with #, describing what the gate validates). Verified the diff does not touch on:, jobs:, permissions:, uses:, any pinned SHA, or any input — confirmed by direct diff inspection.

No injection surfaces, authorization/access-control changes, secret/token handling, or GitHub Actions permission/trigger changes are present in this PR. Per the security-review skill's skip gate, no further findings are reported.

@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown

Last security-reviewed head: 50c8555610725c9fe27842e2b1a71fbc449025c7. On the next push, the relevance gate compares only the commits since this SHA; delete this comment to force a full re-review.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cd113e57d9

ℹ️ 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".

Comment thread docs/MIGRATION-PLAYBOOK.md Outdated
@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown

Claude has reviewed this PR 5 times. The lane skips further automatic reviews after 5; deleting this comment resets the count.

…n mode

Review caught that the previous fix was internally contradictory. It
restored "no model-invoked skill" as the skip *condition* while arguing
in the next sentence that a hook plugin shipping a setup skill is not a
skip — but a setup skill sets disable-model-invocation: true, so it
satisfies that condition. The literal rule admitted exactly the plugins
the surrounding prose excludes, and the text conceded as much rather
than resolving it.

Both candidate wordings fail the same way: "no model-invoked skill" and
"no model-facing skill at all" are each satisfied by a plugin whose only
skill is a manually-invoked setup skill. The defect was never the choice
between them — it was stating the condition in terms of invocation mode
at all.

The condition is now the absence of a judgment-bearing contract, which
is what the rationale always turned on and what the warrant rule two
sentences above already uses as its test. The outcome is unchanged: all
19 hook plugins shipping a setup skill carry setup evals.

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

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 3m 53s —— View job


Code review complete ✅

  • Gather context (PR diff, CLAUDE.md, /review:code-review skill instructions)
  • Invoke /review:code-review skill and follow it exactly
  • Review docs/PLUGIN-PHILOSOPHY.md changes
  • Review docs/MIGRATION-PLAYBOOK.md changes
  • Review .github/workflows/pr-issue-linkage.yml comment-only change
  • Address Codex's P2 finding on the hook-skip warrant rule
  • Post findings

Ran the /review:code-review lane, scoped to correctness and maintainability (docs + comment-only workflow change — no security-relevant surface, so no overlap with the security lane).

Codex's P2 finding is already resolved

Codex flagged that the hook-plugin eval skip (docs/MIGRATION-PLAYBOOK.md) was internally contradictory: disable-model-invocation: true satisfies "no model-invoked skill," yet the next sentence says a setup-shipping plugin is not a skip. Commit 5f8bb0f (already on this branch, pushed after Codex's review) fixes this directly — the condition is now stated as "no skill carrying a judgment-bearing contract," explicitly disclaiming invocation mode as the test (docs/MIGRATION-PLAYBOOK.md:306-320). I re-read the paragraph and it's now self-consistent: the skip condition, its restatement two sentences later, and the warrant rule two sentences above it all key on the same "judgment-bearing contract" test. No further action needed there.

Verified claims

Spot-checked the PR's own factual claims against the referenced code (not just the diff in isolation), since this PR's stated purpose is fixing prose that reached past its evidence:

  • plugins/claude-config/skills/audit/SKILL.md:168,175,192,199 does fetch code.claude.com at runtime — confirms the new ownership-based framing in docs/PLUGIN-PHILOSOPHY.md:24-31 correctly stops condemning this conforming, non-publisher-owned fetch.
  • docs/PLUGIN-PHILOSOPHY.md:402 (stored value) vs. the fresh-session paragraph at docs/PLUGIN-PHILOSOPHY.md:411-416 (effective value) — no longer self-contradictory; only one occurrence of the bullet's literal wording exists in the tree, so no other restatement was left stale.
  • plugins/github/github.test.sh:37-69 — confirms "wider token set over a narrower scope" (docs/PLUGIN-PHILOSOPHY.md:39-40): it checks a broader set of GitHub scope/API tokens than validate-plugin-contracts.mjs, but only within its own $PLUGIN_DIR.
  • docs/MIGRATION-PLAYBOOK.md:1422 ("Fresh-consumer onboarding's step 3") and the untouched docs/MIGRATION-PLAYBOOK.md:1427 ("step 3's verify edit...") — the first now correctly names the cross-section referent; the second is a same-list self-reference (Reintegration's own step 3, a few lines below) and is unambiguous left unqualified.
  • The .claude/source-control.md pr_body_required_sections list (Summary, Fix, Verification, Related) matches the new .github/workflows/pr-issue-linkage.yml header comment's claim of four sections. I could not independently verify the header's added claims about the reusable workflow's internals (case-insensitive heading match, nested-subsection-counts-as-parent) — gh api against the external ci-workflows repo isn't in this lane's allowed tools, so that detail is author-claimed and unverified by me.

Finding

File: .github/workflows/pr-issue-linkage.yml
Lines: 39-40 (unchanged by this diff, so not anchorable as an inline PR comment)

This diff corrects the file's header comment (lines 3-7) from "a non-empty ## Related section" to "four non-empty contract sections — ## Summary, ## Fix, ## Verification, ## Related." It does not touch the dependabot-exemption comment 30 lines below:

      # dependabot PR bodies cannot carry the closing-keyword + `## Related`
      # markers this gate requires; exempt the login so its PRs are mergeable.
      exempt-authors: 'dependabot[bot]'

Before this PR, both comments agreed (each said only ## Related). After this PR, they disagree within the same file: the header says four sections are required, the exemption comment still says one. This is the same class of defect the PR exists to fix — a claim (here, "the gate requires") reaching past what the rest of the file now says backs it — just introduced by this diff rather than by the prior one. Suggest updating lines 39-40 to reference the same four-section contract, e.g. "the closing-keyword + four-section contract this gate requires."

Fix this →

Not independently re-verified

Per lane policy, the PR body's own verification claims (markdownlint-cli2, scripts/check-contract-clause-coverage.py, lychee --offline, zizmor) are author-reported and were not re-run in this pass.

Fresh-context verification returned FAIL on the item-1 rewrite with three
blocking findings, all correct.

The rule is a conjunction — publisher-owned AND fetch/poll/write — so
cite-versus-fetch remains the sole discriminator across the whole
publisher-owned row. "The line is drawn by who owns the target, not by
whether the content merely cites it" therefore denied a discriminator
that demonstrably operates, two clauses after the sanctioned-use
sentence that depends on it. Stated as a conjunction now, with both
conditions named.

The rationale also claimed to remove an undecidability it had only
relocated. Ownership narrows the prohibition — third-party targets leave
it entirely, so cite-versus-fetch never has to be answered for them —
but for publisher-owned targets the question still governs and is still
hard. topic-docs.md is named as the standing undecided case, undecided
on two axes since it is also not skill, agent, or schema content.

Third: only the permitted half was ever checked against the tree. The
prohibiting half — the rule's entire novel content — was not. Measured:
41 files under plugins/*/skills/ across 17 plugins cite a publisher-owned
URL and 14 carry an explicit fetch instruction, the strongest being
ai-slop's persist-findings, which is fail-closed on fetching a
publisher-owned contract. The count is now stated so the prohibition is
read against what it binds rather than against its one worked permitted
case.

Also from the same pass: the identical stale gate description 33 lines
below the header comment this PR already corrected; a claim about
"model-facing" — a term defined nowhere and asserted against the reading
in #3182 — dropped, since the model-invoked half alone carries the
argument; and a modifier left attached to a noun that cannot be stale
after the effective/stored change.

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

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 3m 9s —— View job


Code review in progress

  • Gather context (PR diff, CLAUDE.md, /review:code-review skill instructions)
  • Invoke /review:code-review skill and follow it exactly
  • Diff since last review (previous reviews covered up to 5f8bb0f; new commit 8e2c328 landed)
  • Review docs/PLUGIN-PHILOSOPHY.md fetch-rule conjunction rewrite
  • Review docs/MIGRATION-PLAYBOOK.md warrant-rule wording (Codex's P2 already resolved)
  • Review .github/workflows/pr-issue-linkage.yml comment (dependabot-exemption sync — resolves my own prior finding)
  • Independently verify the new "41 files / 17 plugins / 14 explicit-fetch" claim in PLUGIN-PHILOSOPHY.md
  • Post findings

@claude

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 50s —— View job


Security review — skipped (no security-relevant surface)

  • Gather context (PR diff, CLAUDE.md, custom instructions)
  • Invoke /review:security-review and follow it exactly
  • Review changed files for security-relevant surface
  • Post findings

Skip gate triggered: condition 2 — "Change has no security-relevant surface after reading the diff."

Per the last automated review's tracking comment, the last security-reviewed head was cd113e57d9. I diffed forward to this run's head (8e2c32815) to scope the review to what changed since then (two commits: 5f8bb0f, 8e2c328):

  • docs/MIGRATION-PLAYBOOK.md — prose-only edit restating the hook-plugin eval skip condition ("no skill carrying a judgment-bearing contract" instead of "no model-invoked skill"). This resolves Codex's P2 finding from the earlier review pass (internal contradiction between the skip condition and the setup-skill exclusion). No executable content, no schema, no config.
  • docs/PLUGIN-PHILOSOPHY.md — prose-only edit reframing the fetch-prohibition rule as a two-condition conjunction (ownership and fetch-instruction) and adding a stated count of publisher-owned-URL fetch sites in the tree. No code, no examples with executable snippets.
  • .github/workflows/pr-issue-linkage.yml — comment-only edit (lines 39-40), updating the dependabot-exemption comment to match the four-section contract described in the header. This is the exact fix suggested by the prior review pass's finding. Confirmed via diff that on:, permissions:, jobs:, uses:, and the pinned SHA (7107b34832a7b6db5d08d3b132621c599fbe5e50) are all unchanged from the previously-reviewed version.

No injection surfaces, authorization/access-control changes, secret/token handling, or GitHub Actions permission/trigger changes are present in the commits since the last security review. Per the security-review skill's skip gate, no further findings are reported.

…alify storage

Second fresh-context verification returned FAIL with four blocking
findings. All four were correct; two were introduced by the commit that
answered the first FAIL.

The conjunction scoped the wrong prohibition. Following the paragraph
that establishes "tokens do not appear in skill, agent, or schema
content", "the prohibition is a conjunction ... both conditions must
hold" made fetch-on-publisher-owned necessary for nonconformance —
contradicting the retained sentence that bare organization names in
skill prose are nonconforming, and contradicting the MELODIC_* gate this
same passage cites approvingly. It scopes the sanctioned-use exception,
not the token rule, and now says so.

The counts did not resolve. "41 files ... 14 of them" reproduced under
no stated method: the glob matches 42 including a .py and a .js, and the
14 landed between eight different plausible criteria without matching
any. Worse, the 41 counted citations, which conform under this document's
own rule, so leading with it as the gap overstated the nonconformance.
Replaced with the five files that carry an actual imperative, named
individually so the claim is checkable rather than counted.

The previous commit also introduced a fresh unqualified harness claim —
"where non-sensitive options land irrespective of enable scope" — while
its own sibling 55 lines later correctly qualifies the same proposition
as observed only at --scope local. The primary record
(extensibility-contract-smoke-tests.md) confirms the sibling. Both sites
now carry the provenance, including the pre-existing instance #3182
flagged as leaned-on, and the readback destination now says a sensitive
value is not in pluginConfigs at all.

Finally, the workflow header's retained security rationale was false
against the pinned reusable: it claims the body is read "from the event
payload only", but the reusable live-refetches through the GitHub API and
falls back to the payload only on failure. That sentence is the stated
basis for a zizmor dangerous-triggers suppression, so it is corrected
rather than left. The no-issue marker is a case-insensitive regex, not a
literal, and is now described as one.

Also: #3136 does not mention cite-versus-fetch, decidability, or the
named file, so routing the open question there was deferral wearing
resolution's clothes; the text now says no ticket owns it. The
"strongest form" singular is dropped — three of the five are
byte-identical. The second undecidability axis is marked weaker than it
looks, since three architecture skill sites load that file during
execution.

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

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 3m 36s —— View job


Code review complete ✅

  • Gather context (PR diff, CLAUDE.md, /review:code-review skill instructions)
  • Invoke /review:code-review skill and follow it exactly
  • Diff since last review (previous reviews covered up to 8e2c328; new commit f1051ad landed)
  • Review docs/PLUGIN-PHILOSOPHY.md conjunction-scoping + file-list rewrite
  • Review docs/MIGRATION-PLAYBOOK.md storage-shape qualification
  • Review .github/workflows/pr-issue-linkage.yml comment (re-fetch step description)
  • Independently verify the new named-file list against the actual files on disk
  • Post findings

Ran the /review:code-review lane, scoped to correctness and maintainability (all three files are docs/comment-only — no security-relevant surface, so no overlap with the security lane, which already skipped separately on this head).

Findings (posted inline)

Both are the same defect class this PR exists to fix — a claim reaching past what backs it — freshly introduced by commit f1051ad itself, in the same paragraphs it's correcting:

  1. docs/PLUGIN-PHILOSOPHY.md:50 — "The first three are byte-identical" is false. Checked file sizes and diffed all three: ai-slop/skills/audit/context/persist-findings.md (4899 bytes), claude-config/skills/audit-instructions/context/persist-findings.md (7924 bytes), mutation-testing/skills/audit/context/persist-findings.md (26531 bytes) differ substantially in title, section structure, and content — mutation-testing's file alone carries three extra sections the others lack. They share the fail-closed clause and a common template, but are not byte-identical.
  2. docs/MIGRATION-PLAYBOOK.md:1424-1425 — The Reintegration section's cross-reference still says "Fresh-consumer onboarding's step 3 records non-sensitive options landing irrespective of enable scope." But this same commit rewrote step 3 (lines 1359-1361) to explicitly disclaim exactly that — it now says the behavior is "observed only at --scope local... not as established for every enable scope." The cross-reference wasn't updated to match, so it now restates step 3's pre-fix, overreaching claim as if step 3 still made it.

Verified claims (no issue found)

  • docs/PLUGIN-PHILOSOPHY.md:24-30 — the "conjunction scopes the exception, not the token rule above" rewrite is internally consistent with the org-agnosticism token rule two paragraphs up.
  • docs/PLUGIN-PHILOSOPHY.md:46-53 — all five newly-named files exist at the stated paths; testing/skills/audit/SKILL.md:88 and work-items/skills/triage/SKILL.md:166 do carry imperative fetch/read instructions to publisher-owned raw.githubusercontent.com URLs, and the three persist-findings.md files do all carry the quoted fail-closed sentence (only "byte-identical" above is wrong).
  • docs/PLUGIN-PHILOSOPHY.md:36-39 — the "three plugins/architecture/skills/improve/** sites" figure is a defensible count (1 link in SKILL.md + 2 in deepening.md, both pointing at reference/topic-docs.md).

Not independently verified

.github/workflows/pr-issue-linkage.yml:12-14's new claim that a "Load current PR body" step in the pinned ci-workflows reusable re-fetches the body via the GitHub API (rather than reading the event payload) describes behavior in an external repo this lane's tools can't inspect (gh api against ci-workflows isn't in the allowed toolset). Comment-only change confirmed via diff — no on:/jobs:/permissions:/uses:/pin touched — but the substance of that claim is author-claimed and unverified by me.

@claude

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 8s —— View job


Security review — skipped (no security-relevant surface)

  • Gather context (PR diff, CLAUDE.md, custom instructions)
  • Invoke /review:security-review and follow it exactly
  • Review changed files for security-relevant surface
  • Post findings

Skip gate triggered: condition 2 — "Change has no security-relevant surface after reading the diff."

Per the last automated review's tracking comment, the last security-reviewed head was 8e2c32815ec23236e2aa753716d53cefa2e5ddc4. Diffed forward to this run's head (f1051ad75e892d34a1b4fa2d8b41383f90a3cd22) to scope the review to what changed since then — one commit, f1051ad:

  • docs/MIGRATION-PLAYBOOK.md and docs/PLUGIN-PHILOSOPHY.md — prose-only edits (scoping the fetch-rule conjunction to the sanctioned-use exception rather than the token rule, replacing an unverifiable file/instance count with five named files, and qualifying the pluginConfigs storage-location claim to the scope it was actually observed at). No code, no executable examples, no schema or config changes.
  • .github/workflows/pr-issue-linkage.yml (lines 3-11) — comment-only edit correcting the header's stated security rationale for the pull_request_target trigger (it now says the reusable live-refetches the PR body via a "Load current PR body" API step rather than reading it from the event payload, falling back to the payload only on failure) and describing the no-issue marker as a case-insensitive regex rather than a literal string. Confirmed via diff that every changed line starts with #; on:, jobs:, permissions:, uses:, and the pinned SHA are all unchanged from the previously-reviewed version.

This comment-only change updates a description of existing trust-boundary behavior — it does not alter the trigger, permissions, checkout behavior, or pinned reusable itself, so there's no new security-relevant surface to review even though the topic (a pull_request_target safety rationale) is security-adjacent. No injection surfaces, authorization/access-control changes, secret/token handling, or GitHub Actions permission/trigger changes are present in the commit since the last security review. Per the security-review skill's skip gate, no further findings are reported.

Comment thread docs/PLUGIN-PHILOSOPHY.md Outdated
Comment thread docs/MIGRATION-PLAYBOOK.md Outdated
Third fresh-context verification returned FAIL with four blocking
findings. Three were introduced by the commit answering the second FAIL.
The pattern across three rounds is that each added factual claim became
the next round's defect, so this round removes claims rather than
sharpening them.

"The first three are byte-identical" was false and trivially checkable:
4899, 7924, and 26531 bytes, diverging at line 1. It shipped in the same
sentence as "named rather than counted so the claim can be checked",
which is the sharpest form the defect has taken. Removed; the
fail-closed characterisation, which does hold for all three, stays.

The five-file enumeration selected on exactly the cite-versus-fetch
distinction that the paragraph twelve lines above calls not cleanly
separable, and it was incomplete under its own reading — write-for-agents
and skill-authoring both sit inside it. Replaced with three clear
instances and an explicit refusal to enumerate, naming the four
near-boundary files as near-boundary. A statement that declares a line
undecidable cannot also publish the list that line induces.

The claim that claude-config's audit skill "reads code.claude.com that
way and conforms" was scoped to that read: the same file also cites a
publisher-owned convention doc through its curl route, which is the
undecided question, not a settled one.

The storage hedge over-corrected. Seam 1 tags the location [SPEC] --
project and local pluginConfigs entries are ignored since Claude Code
2.1.207 -- so downgrading it to "observed only at --scope local" put one
fact under two incompatible epistemic labels across five sites, and made
the prescribed readback able to produce the false failure the philosophy
forbids. Both paired sites now cite the spec.

The Reintegration citation still described Fresh-consumer step 3 in the
wording this PR had already replaced, 60 lines away in the same commit.

The workflow header's replacement claim was false in behavior: the
reusable's "Load current PR body" step has no token in step env, so the
gh api call fails silently and the payload fallback is what runs. Rather
than describe the mechanism a third time, the sentence is dropped. What
remains is what verification confirmed against the whole reusable and is
what the zizmor suppression actually rests on -- it reads only PR
metadata and never checks out or executes head code. The no-issue marker
is quoted exactly now, word boundaries included.

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

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 3m 21s —— View job


Code review complete ✅

  • Gather context (PR diff, CLAUDE.md, /review:code-review skill instructions)
  • Invoke /review:code-review skill and follow it exactly
  • Diff since last review (previous reviews covered up to f1051ad; new commit aa160f2 landed)
  • Review docs/PLUGIN-PHILOSOPHY.md byte-identical removal + five-file→three-instance rewrite
  • Review docs/MIGRATION-PLAYBOOK.md storage-hedge and cross-reference sync
  • Review .github/workflows/pr-issue-linkage.yml comment (dropped unverifiable "Load current PR body" claim)
  • Independently verify the new claims against the referenced files
  • Post findings

Ran the /review:code-review lane, scoped to correctness and maintainability (all three files are docs/comment-only — no security-relevant surface, so no overlap with the security lane).

Finding (posted inline)

docs/PLUGIN-PHILOSOPHY.md:54-58 — Same defect class this PR exists to fix, freshly introduced by this commit's own rewrite. The paragraph justifies its three "clearest" fetch instances by a fail-closed test ("if the contract cannot be fetched, do not write"), then groups testing/skills/audit/SKILL.md with three other files as merely "near that boundary" (cite-vs-fetch ambiguous). But testing/skills/audit/SKILL.md:87-91 has the identical fail-closed fetch imperative — "Read the producer contract before the first write... If it cannot be fetched, do not write" — that the paragraph just used to justify the three it does name. The other three grouped files (work-items/triage, docs-hygiene/write-for-agents, playbooks/skill-authoring) only carry inline markdown-link citations with no fetch imperative or fail-closed clause — genuinely ambiguous, unlike this one. Notably, the immediately prior commit (f1051ad) and an earlier review pass on this PR both confirmed this same file as a clear fetch instance; nothing in the file changed since, only its classification here.

Verified claims (no issue found)

  • docs/PLUGIN-PHILOSOPHY.md:47-52 — the three named persist-findings.md files (ai-slop, claude-config, mutation-testing) do all carry the exact fail-closed clause "If the contract cannot be fetched, do not write." The removed "byte-identical" claim (4899/7924/26531 bytes, flagged in the prior review round) is gone; only the fail-closed characterization remains, which holds.
  • docs/PLUGIN-PHILOSOPHY.md:29-31 — the new parenthetical scoping claude-config's code.claude.com conformance to that specific read, while noting its separate curl route also cites a publisher-owned convention doc (docs/conventions/upstream-drift/README.md), matches plugins/claude-config/skills/audit/SKILL.md:167-169.
  • docs/MIGRATION-PLAYBOOK.md:1360-1361, 1424-1425 — "documented behavior, not an observation... ignored since Claude Code 2.1.207" now correctly cites Seam 1's [SPEC] tag (docs/MIGRATION-PLAYBOOK.md:205-207), resolving the two-incompatible-epistemic-labels issue from the prior review round. Both paired sites (Fresh-consumer step 3 and Reintegration) now agree word-for-word on the storage claim and its basis.
  • .github/workflows/pr-issue-linkage.yml:41-43 — the dependabot-exemption comment still matches the header's four-section contract (Summary/Fix/Verification/Related), resolving the prior review round's mismatch finding.
  • .github/workflows/pr-issue-linkage.yml:19 — the zizmor: ignore[dangerous-triggers] suppression's stated rationale ("metadata-only gate; rationale in the header comment") now matches what the header comment (lines 3-17) actually asserts (reads PR metadata only, never checks out/executes head code) — the previously-flagged unverifiable "Load current PR body" API-fetch claim was dropped rather than re-asserted.

Not independently verified

The workflow header's underlying claim that the pinned ci-workflows reusable "only reads PR metadata and never checks out or executes head code" describes behavior in an external repo this lane's tools can't inspect (gh api against ci-workflows isn't in the allowed toolset). Comment-only change confirmed via diff — no on:/jobs:/permissions:/uses:/pin touched — but the substance is author-claimed. Per lane policy, the PR body's own verification claims (markdownlint-cli2, scripts/check-contract-clause-coverage.py, lychee --offline, zizmor) are likewise author-reported and not re-run in this pass.

@claude

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 43s —— View job


Security review — skipped (no security-relevant surface)

  • Gather context (PR diff, CLAUDE.md, custom instructions)
  • Invoke /review:security-review and follow it exactly
  • Review changed files for security-relevant surface
  • Post findings

Skip gate triggered: condition 2 — "Change has no security-relevant surface after reading the diff."

Per the last automated review's tracking comment, the last security-reviewed head was f1051ad75e892d34a1b4fa2d8b41383f90a3cd22. Diffed forward to this run's head (aa160f22088b5aac6a27f9d61f4ecc9011bad125) — one commit, aa160f2:

  • docs/MIGRATION-PLAYBOOK.md and docs/PLUGIN-PHILOSOPHY.md — prose-only edits: dropping the "possibly stale"/observed-only-at---scope local qualifier now that the underlying behavior is documented (Claude Code 2.1.207+) rather than merely observed, and softening the file-naming paragraph so it no longer implies exhaustiveness or byte-identity it can't support. No code, no schema, no config, no executable examples touched.
  • .github/workflows/pr-issue-linkage.yml (lines 3-11) — comment-only edit. Every changed line starts with #. It corrects the no-issue-marker regex description to match the pattern's actual anchoring (\b-bounded, not "matched case-insensitively anywhere") and reworks the security rationale for the pull_request_target trigger to rest on "the reusable only reads PR metadata and never checks out or executes head code" rather than an unverified claim about a specific re-fetch step — which resolves the prior review pass's open question about that claim's provenance. Confirmed via diff that on:, permissions:, jobs:, uses:, and the pinned SHA are all unchanged from the previously-reviewed version.

No injection surfaces, authorization/access-control changes, secret/token handling, or GitHub Actions permission/trigger changes are present in the commit since the last security review. Per the security-review skill's skip gate, no further findings are reported.

Comment thread docs/PLUGIN-PHILOSOPHY.md Outdated
kyle-sexton and others added 2 commits August 23, 2026 06:30
Review caught that `testing/skills/audit/SKILL.md` was listed as
near-boundary while clearing the exact bar used to justify the three
named as clear: `:87` "Read the producer contract before the first
write" and `:90` "If it cannot be fetched, do not write". Both halves,
same as the persist-findings trio.

The near-boundary group now states what makes it near-boundary — those
three direct the agent at a publisher-owned document without a
fail-closed guard — rather than asserting the classification and
leaving the reader to infer the criterion.

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

Fourth verification pass. Its first blocking finding was already fixed by
520a591; the rest are addressed here.

Both paired storage sites warranted a write-location rule with seam 1's
read-precedence clause ("project and local entries are ignored since
2.1.207"). Ignoring-on-read is compatible with writing there, so that
clause does not entail the rule. Seam 1's first clause -- non-sensitive
values store in user settings -- does, and is what both sites now cite.
The rule and the outcome are unchanged; only the warrant was wrong,
which is the shape #3182 item 3 was filed as blocking on.

Three artifacts of removing claims, each the mirror of over-claiming:

- "Enforcement reaches a strict subset of the whole" lost its antecedent
  when the paragraph it followed was restructured; it names the target
  again and starts its own paragraph.
- The plugin.json parenthetical had drifted to the tail of the
  undecidability paragraph, where it reads as a non-sequitur. Returned to
  the token-rule paragraph it comments on.
- The workflow header carried "not any claim about where the body is read
  from", a negation pointing at a sentence deleted in the same commit. A
  fresh reader cannot resolve it, so it is gone, and the retained
  rationale now states the three properties verification actually
  established: no checkout step, `pull-requests: read` + `actions: read`
  only, no head-code execution.

One newly added clause over-claimed: a sensitive value "reads back from
secure credential storage" asserts a route no smoke test covers, and Test
B records a sensitive value as unreachable from a skill entirely. It now
says only what smoke-test A establishes -- absent from settings, so the
readback does not apply.

Also corrected in the workflow comment: the no-issue marker is not matched
"anywhere in the body" (fenced and indented code, inline spans, and HTML
comments are stripped first), and the runner is pinned by this caller
rather than inherited from the reusable's default.

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

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 2s —— View job


Security review — skipped (no security-relevant surface)

  • Gather context (PR diff, CLAUDE.md, custom instructions)
  • Invoke /review:security-review and follow it exactly
  • Review changed files for security-relevant surface
  • Post findings

Skip gate triggered: condition 2 — "Change has no security-relevant surface after reading the diff."

Per the last automated review's tracking comment, the last security-reviewed head was aa160f22088b5aac6a27f9d61f4ecc9011bad125. Diffed forward to this run's head (8e83ef3c3d03d9b43248090b5eccf73ea9e68d4d) — two commits, 520a591 and 8e83ef3:

  • docs/MIGRATION-PLAYBOOK.md — prose-only edit. Rewords the storage-location claims in Fresh-consumer onboarding (steps 3–4) and Reintegration to say seam 1 "records that non-sensitive values store in user settings" rather than restating the [SPEC] fact directly, and clarifies that a sensitive value's absence from settings means the readback instruction "does not apply to one." No behavioral claim, code, schema, or config changed — just which paragraph a fact is attributed to.
  • docs/PLUGIN-PHILOSOPHY.md — prose-only edit. Moves testing/skills/audit/SKILL.md from the "near-boundary" group into the "unambiguous" fetch-instance group (now four named files instead of three), adds a sentence scoping plugin.json publisher metadata as outside the rule, and relocates that same sentence earlier in the paragraph. No code, schema, or executable example touched.
  • .github/workflows/pr-issue-linkage.yml (lines 3-20) — comment-only edit. Every changed line starts with #. Diffed the non-comment lines specifically (git diff aa160f2..8e83ef3 -- .github/workflows/pr-issue-linkage.yml filtered to non-# +/- lines) and confirmed zero hits — on:, permissions:, jobs:, uses:, the pinned SHA (7107b34832a7b6db5d08d3b132621c599fbe5e50), and with: are byte-identical to the previously-reviewed version. The header now grounds its pull_request_target safety rationale in the caller's own declared job permissions (pull-requests: read, actions: read at lines 38-40 of this same file) rather than a claim about the external reusable's internals, and adds detail on how the two body scans (closing-keyword, no-issue-marker) mask code fences/spans/HTML comments before matching.

No injection surfaces, authorization/access-control changes, secret/token handling, or GitHub Actions permission/trigger changes are present in the commits since the last security review. Per the security-review skill's skip gate, no further findings are reported.

Fifth verification pass returned FAIL with five blocking findings, the
fifth consecutive round to do so. Reviewing where the findings came from:
items 2 and 3 of #3182 have been clean since round three, and essentially
every finding from round two onward landed in material this PR added
beyond the ask -- an enumeration of nonconforming instances, a paragraph
grounding the prohibition against the tree, a rewritten security
rationale, and a sensitive-value carve-out. Each elaboration was written
to close the previous round's finding and opened one or two of its own.

So this round removes the elaborations rather than repairing them again.

The org-agnosticism fix is now one paragraph that does what item 1 asked:
scope the prohibition to publisher-owned targets, and state plainly that
the cite-versus-fetch question for those targets is unsettled, with
topic-docs.md as the open case. Gone: the four/three partition of live
instances (whose classification was falsified twice), the "what ownership
buys" elaboration (which asserted both readings of its own scope), and
the claim that no enumeration is offered (made one paragraph after
offering one).

The workflow header returns to main's text with one correction -- the
gate requires four sections, not a closing keyword plus `## Related`.
That was the only part #3182 raised. The security-rationale sentence is
false against the pinned reusable, which live-refetches rather than
reading the payload, but it is pre-existing and out of this issue's
scope; it gets its own issue rather than a fourth rewrite here.

Both storage sites now carry identical wording, including the sensitive
carve-out that had been added to one and not the other -- an asymmetry
that would have sent a reader reconfiguring a sensitive option at project
scope to look in user settings, find nothing, and report a failed write.
The carve-out states the limit ("cannot be verified this way") rather
than asserting a readback route no test covers. The provenance citation
drops smoke-test C, which explicitly disclaims covering a sensitive
option, in favour of seam 1, which documents both halves.

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

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 2m 17s —— View job


Security review — skipped (no security-relevant surface)

  • Gather context (PR diff, CLAUDE.md, custom instructions)
  • Invoke /review:security-review and follow it exactly
  • Review changed files for security-relevant surface
  • Post findings

Skip gate triggered: condition 2 — "Change has no security-relevant surface after reading the diff."

Per the last automated review's tracking comment, the last security-reviewed head was 8e83ef3c3d03d9b43248090b5eccf73ea9e68d4d. Diffed forward to this run's head (50c8555610725c9fe27842e2b1a71fbc449025c7) — one commit, 50c8555 ("cut the diff back to what #3182 asked for"):

  • docs/MIGRATION-PLAYBOOK.md and docs/PLUGIN-PHILOSOPHY.md — prose-only edits, trimming detail added in earlier rounds (e.g. reverting a "sensitive value ... cannot be verified this way" qualifier, simplifying the fetch-rule paragraph, dropping the unambiguous/near-boundary file enumeration). No code, schema, config, or executable example touched.
  • .github/workflows/pr-issue-linkage.yml (lines 3-14) — comment-only edit. Confirmed via git diff 8e83ef3..50c8555 -- .github/workflows/pr-issue-linkage.yml | grep -E '^[+-]' | grep -v '^[+-]#' that every changed line starts with # — no non-comment line touched in this commit. Extended the check across the whole PR (git diff origin/main..HEAD, same filter): still zero hits. on:, permissions:, jobs:, uses:, the pinned SHA (7107b34832a7b6db5d08d3b132621c599fbe5e50), and every with: input (including runner: ubuntu-24.04, unchanged since before this PR started) are byte-identical to origin/main.

One thing surfaced worth flagging for the correctness lane rather than security: this commit reverts the header's runner description from the prior round's more precise "the runner is pinned below rather than inherited from the reusable's default" back to "runs on the reusable's hosted default runner" — which is the same wording already on origin/main pre-PR, but arguably still in tension with the explicit with: runner: ubuntu-24.04 input a few lines below. Not a security finding either way (GitHub-hosted ubuntu-24.04 either way, not self-hosted), so out of scope for this lane.

No injection surfaces, authorization/access-control changes, secret/token handling, or GitHub Actions permission/trigger changes are present in the commit since the last security review. Per the security-review skill's skip gate, no further findings are reported.

Sixth verification pass. Two findings, both in the one paragraph this
round had to write rather than cut; both repairs are deletions.

"No ticket owns that question" is a tracker-wide negative asserted
without a tracker search, and the tracker contradicts it. #432 carries an
accepted operator ruling on this exact question -- bundle the contract,
demote the raw URL to a pinned provenance link -- and generalises it
across the eight implementer plugins sharing that binding. #410 and #531
carried it too. `scripts/skill-portability-tokens.txt:139-152` stages a
lint class for the same distinction and records that splitting it "needs
#432's bundle-vs-pin ruling first". All three tickets are closed and the
remediation is undone, so a narrow "no open ticket" reading might have
survived -- but that is not what the sentence said, and a reader would
conclude the disposition is unowned when a ruling covers it.

"and says nothing about third-party ones either way" contradicts the
clause it modifies: "fetching one does not forfeit the citation" is
itself a statement about third-party targets. The preceding clause
already scopes the prohibition, so the hedge only undercut the sentence
that un-breaks the shipped `code.claude.com` read.

The #3136 disclaimer goes with the first sentence. The paragraph still
says the question is unsettled and still names the open case, which is
what item 1 asked for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kyle-sexton
kyle-sexton merged commit 393658c into main Aug 23, 2026
52 checks passed
@kyle-sexton
kyle-sexton deleted the fix/3182-prose-reach-past-evidence branch August 23, 2026 11:25
kyle-sexton added a commit that referenced this pull request Aug 23, 2026
…d reusable (#3209)

Closes #3184

## Summary

The header comment in `.github/workflows/pr-issue-linkage.yml` justified
its `pull_request_target` trigger — and the `zizmor:
ignore[dangerous-triggers]` suppression that points at it — with a
sentence that does not describe the pinned reusable: "the reusable reads
PR body metadata from the event payload only and runs no head code."
Only the second half is true. The same block also misattributed the
runner to "the reusable's hosted default" and described the no-issue
opt-out as a literal string. This PR rewrites the header so every claim
matches the reusable's actual code at the pinned SHA (`7107b34`,
v0.14.2).

## Fix

Comment text only; no functional YAML changes. Three corrections:

- **Body-read mechanism.** The reusable's `Load current PR body` step
live-refetches the body via `gh api` and uses the event payload only as
a fallback when that call fails. Re-verified at the pinned SHA: no
`GH_TOKEN`/`GITHUB_TOKEN` reaches that step (its `env:` carries only
`PR_NUMBER` and `FALLBACK_BODY`, and neither the job nor the workflow
wires a token), so the re-fetch fails auth every time and the payload
fallback is the path that actually runs. The header now states this —
payload-only in effect, as a side effect of the failed re-fetch, not by
design — and rests the `pull_request_target` safety rationale on what
actually makes the trigger safe: no head-branch code ever executes (the
reusable checks out nothing, holds `pull-requests: read` / `actions:
read` only, and passes the body through `env:`/`GITHUB_ENV` rather than
splicing it into script text).
- **Runner.** "Runs on the reusable's hosted default runner" replaced
with the truth: the `with:` block pins `runner: ubuntu-24.04`
explicitly, which coincides with the reusable's default.
- **No-issue marker.** Described as what it is: a case-insensitive regex
matching the phrase "no linked issue" or "no related issue" (`/\bno
(?:linked|related) issue\b/i`), not a literal string, with both body
scans running against a body whose fenced code blocks and
4-space/tab-indented lines are blanked, inline code spans masked, and
HTML-commented text discarded.

Per the issue's scope note, wiring a token into the reusable so the
re-fetch succeeds is out of scope — that lives in
`melodic-software/ci-workflows` and would be a behavior change, not a
comment fix.

## Verification

- Every claim in the new header was verified directly against the
reusable's source fetched at the exact pinned SHA
`7107b34832a7b6db5d08d3b132621c599fbe5e50`: the `gh api` re-fetch with
`FALLBACK_BODY` fallback, the absence of any token in the
step/job/workflow environment, the absence of any checkout step, the
read-only `permissions:` block, the `env:`/`GITHUB_ENV` body path with
random heredoc delimiter, the `runner` input default, the
`NO_ISSUE_MARKER` regex, and the code/comment masking in
`stripRenderedHtmlComments` (including the `/^(?: {4}|\t)/`
indented-code branch).
- `actionlint` passes on the edited file; `zizmor` passes with the
`dangerous-triggers` suppression still honored (`No findings to report.
(1 ignored, 1 suppressed)`).
- `git diff -U0` filtered to non-comment lines is empty: `on:`,
`permissions:`, the `uses:` pin, and the `with:` values are
byte-identical to `main`.
- An independent fresh-context reviewer re-verified each header claim
against the pinned reusable source with the author rationale withheld:
PASS on every criterion, plus two advisory phrasing findings (the
"indented code blocks" wording and a dangling "Public repo:" lead-in),
both applied in the second commit with linters re-run green.
- This change is comment-only; no test can meaningfully cover it, so no
test is claimed.

## Related

- #3183 — corrected the gate-description half of this comment block;
this PR corrects the half it deliberately left alone.
- #3182 — parent issue that first flagged the block.
- This PR does not touch `.github/workflows/ci.yml`; it cannot collide
with the concurrent `docs_only` scope-resolution work there (#3159).

---------

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.

fix(docs): three rules in the merged setup-contract prose reach past what backs them

1 participant