Skip to content

Tier Vale findings in pre-merge reviews: blockers in 🚨, quieter nags, FP fixes - #20663

Open
CamSoper wants to merge 17 commits into
masterfrom
claude/vale-findings-review-ncs0f2
Open

Tier Vale findings in pre-merge reviews: blockers in 🚨, quieter nags, FP fixes#20663
CamSoper wants to merge 17 commits into
masterfrom
claude/vale-findings-review-ncs0f2

Conversation

@CamSoper

@CamSoper CamSoper commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Proposed changes

Restructures how Vale prose-lint findings surface in the pinned pre-merge review. The tiering/FP changes are deterministic config/Python with no new model calls; the inline-suggestions feature adds a small amount of work to the existing Opus editorial pass (≤10 one-line rewrites) and one API call.

1. Blocker tier — high-confidence Vale findings now block. A new blocker: allowlist in vale-deterministic-fixes.yaml (Pulumi.Substitutions, Pulumi.Nomenclature, Pulumi.PoliciesSingular, Google.Spelling, Pulumi.DeprecatedProductNames — wrong or deprecated product names, banned terms, misspellings, agreement errors; near-zero false-positive rate) is stamped onto findings by vale-findings-filter.py (exempt from the per-file/total caps) and rendered by compose-review.py as [style-blocker] bullets under 🚨 Outstanding with standard **[L<n>]** anchors. They count in the 🚨 cell, drive the review:outstanding-issues label, participate in the auto-refresh gate on fix-pushes, and are outcome-classified by the review telemetry. The model may not delete or demote them. The triage lane surfaces them with a [blocker] prefix in the TRIAGE_PROSE comment.

Blocker membership is independent of deterministic_fix: PoliciesSingular and DeprecatedProductNames block even though their fixes need authoring ("Pulumi Service" is always wrong; the right replacement — Cloud/ESC/Deployments — is the author's call). DeprecatedProductNames was also missing from RULE_CATEGORIES and rendered as generic "style"; it now renders as "deprecated product name".

2. Advisory findings quieted, but actionable. Non-blocker style findings now always render collapsed (per-file <details>) and are excluded from the ⚠️ count-table cell — kept for the style-rule tuning loop, not reviewer burden. Additionally, the editorial pass triages the advisory findings and stages the ones whose rewrite is a clear, meaning-preserving improvement into .style-suggestions.json (cap 10; false positives and load-bearing hedges — "usually completes in five minutes" — are explicitly excluded). A new deterministic step (post-style-suggestions.py) validates every entry against the PR diff and the checked-out file (anti-hallucination: the anchor must be a PR-added line and the original text must be present verbatim), then posts one event: COMMENT review with a suggestion block per finding — one-click applyable, batchable into a single commit, and deleted-and-reposted per run so no stale comments accumulate. The script never fails the workflow.

3. False positives fixed at the source.

  • HeadingSentenceCase gains multi-word proper-noun exceptions (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, Google Cloud Secret Manager, 1Password Secrets Automation, CyberArk Conjur, Doppler, Infisical) — phrase entries so generic words like "Secrets"/"Manager"/"Key" still flag when capitalized outside a product name (verified against fixtures).
  • Google.OxfordComma is disabled with a rationale comment: its regex can't distinguish serial lists from introductory clauses ("…the deciding factors, Doppler and…"), joining the nine other Google rules already disabled for FP rate.

Contract copy is updated everywhere it's duplicated: output-format.md, ci.md (including new editorial-pass step 10 for the suggestion sidecar), SKILL.md, the prompts in claude-code-review.yml and claude-update.yml, the validator rules (count-table-matches-bullets, style-render-mode, trail-match exemption), scrape-review-outcomes.py, and STYLE-GUIDE.md §Automated checks.

Verification done:

  • Vale 3.14.1 fixture run: all six product-name headings pass; genuinely wrong headings ("Configuring Your Secrets", "The Manager Approves") still flag; the Oxford-comma sentence no longer fires.
  • Filter test: blocker stamping + cap exemption; DeprecatedProductNames stamps blocker: true, deterministic_fix: false.
  • Composer dry-run: blockers render in 🚨 with anchors and are counted, nags collapsed and uncounted; composer self-check clean.
  • Validator: passes with a non-empty trail and [style-blocker] bullets that have no trail records (the exemption path), and still enforces counts.
  • auto-refresh-gate.py fires on a push fixing a blocker's line.
  • post-style-suggestions.py: 9 new tests covering validation (missing text, non-added line, duplicates, cap, payload shape) and the dry-run end-to-end path.
  • Full scripts test suite: 105 passed.

Unreleased product version (optional)

N/A

Related issues (optional)

N/A

… FP fixes

Three changes to how Vale prose-lint findings surface in the pinned PR
review, all deterministic (no new model calls):

1. Blocker tier. A new `blocker:` allowlist in vale-deterministic-fixes.yaml
   (Pulumi.Substitutions, Pulumi.Nomenclature, Pulumi.PoliciesSingular,
   Google.Spelling — near-zero-FP correctness rules) is stamped by
   vale-findings-filter.py (cap-exempt) and rendered by compose-review.py as
   [style-blocker] bullets under 🚨 Outstanding with standard **[L<n>]**
   anchors, so they count toward the review:outstanding-issues label and the
   auto-refresh gate matches fix-pushes. validate-pinned.py exempts them from
   trail-matching (Vale findings have no verification-trail record). The
   triage lane prefixes them [blocker] in the TRIAGE_PROSE comment.

2. Advisory findings quieted. Non-blocker style findings now always render
   collapsed (per-file <details>) and are excluded from the ⚠️ count-table
   cell — they're kept for the style-rule tuning loop, not reviewer burden.
   Blocker bullets are outcome-classified by scrape-review-outcomes.py like
   any 🚨 finding; advisory nags stay counts-only.

3. False positives fixed at the source. HeadingSentenceCase gains multi-word
   proper-noun exceptions (HashiCorp Vault, AWS Secrets Manager, Azure Key
   Vault, Google Cloud Secret Manager, 1Password Secrets Automation, CyberArk
   Conjur, Doppler, Infisical) — verified that generic words like "Secrets"/
   "Manager" still flag outside product names. Google.OxfordComma is disabled:
   its regex can't distinguish serial lists from introductory clauses.

Contract copy updated in output-format.md, ci.md, SKILL.md, both workflow
prompts, and STYLE-GUIDE.md §Automated checks.

Verified: vale 3.14.1 fixture run (FP headings pass, real violations flag);
filter/composer/validator dry-runs incl. non-empty-trail case; auto-refresh
gate fires on a blocker fix-push; existing scripts test suites pass (65).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
"Pulumi Service" is always wrong in current content — the correct
replacement (Cloud/ESC/Deployments) is context-dependent, which keeps the
rule out of deterministic_fix, but shipping the dead name should block
like any other product-name error. Also adds the rule to RULE_CATEGORIES
(it was unmapped and fell back to the generic "style" category) so its
blocker bullets render as "deprecated product name", and syncs the four
prose enumerations of the blocker set (output-format.md, both workflow
prompts, STYLE-GUIDE.md).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
@pulumi-bot

pulumi-bot commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

The advisory (non-blocker) style findings gain an actionable surface:
during the editorial pass, the reviewer triages the collapsed nags and
stages the ones whose rewrite is a clear, meaning-preserving improvement
into .style-suggestions.json (cap 10; load-bearing hedges like "usually
completes in five minutes" and false positives are explicitly excluded).
A new deterministic step, post-style-suggestions.py, validates every
entry — anchored to a PR-added line (reusing added_lines_per_file from
vale-findings-filter.py) and the `original` text present verbatim on
that line in the checkout — then posts one event=COMMENT review with a
```suggestion block per finding, so the author can apply all of them
with one click via "Add suggestion to batch". Prior suggestion comments
are deleted first (delete-and-repost, same as TRIAGE_PROSE), the script
always exits 0, and .style-suggestions.json joins the debug artifacts.

The collapsed #### Style findings block remains the complete record;
a suggested finding keeps its [style] bullet. Blocker findings never
render as suggestions. Contract documented in ci.md §3 step 10 and
output-format.md; 9 new tests (105 total pass).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
The 2026-08-03 fork smoke test caught this: post-style-suggestions.py
defaulted --repo to "pulumi/docs" and the workflow invoked it with only
--pr, so on CamSoper/pulumi.docs it POSTed the review to pulumi/docs with
the fork's GITHUB_TOKEN and got 403 "Resource not accessible by
integration". The model had staged a correct sidecar (1 valid suggestion,
0 dropped) that never reached the author. A fork CI probe confirmed the
reviews endpoint itself works fine with GITHUB_TOKEN + pull-requests:
write, isolating the cause to the repo argument.

- Default --repo to $GITHUB_REPOSITORY, falling back to pulumi/docs.
- Pass --repo ${{ github.repository }} explicitly from the workflow.
- Pass --repo through to `gh pr diff` too (it had been resolving from the
  local remote by luck).
- Set include-hidden-files on the debug artifact upload: .style-suggestions.json
  is a dotfile and was silently dropped from the bundle.
- Regression test pinning the env-derived repo default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
Two follow-ups from reviewing the fork smoke-test output.

Rename. With correctness errors escalated to the blocker tier and the
known false-positive rules disabled, what's left in the advisory block is
optional polish, and "findings" oversold it. compose-review.py now emits
`#### Style suggestions` (new STYLE_HEADING constant) with a caption to
match. validate-pinned.py accepts BOTH spellings (STYLE_HEADINGS) so a
re-entrant review merging a pre-rename body still validates, and
scrape-review-outcomes.py is unaffected because it keys on the bullet
form rather than the heading -- its self-test deliberately keeps the old
spelling, since it parses historical merged PRs.

No FP narration. The control run in the fork test showed Opus deleting
six false-positive heading flags and then writing a paragraph into the
pinned comment enumerating them and explaining why -- which re-adds the
noise the deletion removed, and already violated DO-NOT item 1. Made it
explicit in both workflow prompts, ci.md step 10, and the DO-NOT item:
delete false positives silently, with no tally, no rule name, and no
explanation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
The 2026-08-03 re-smoke (fork PR CamSoper#227) authored its
own `[style-blocker] _misspelling_` bullet for a "seperate" typo that Vale
never reported -- `misspelling` isn't even a category the filter can emit,
and Google.Spelling doesn't catch that word. The finding was real and
useful, but the provenance was not: `[style-blocker]` is what exempts a 🚨
bullet from trail-matching, so an authored one routes an unverified
finding into 🚨 behind a check. Any finding could ride in that way.

- New `style-blocker-provenance` validator rule (schema v20): every
  `[style-blocker]` bullet must match a `blocker: true` entry in
  `.vale-findings.json` by file and line. Skips when the artifact is
  absent -- a missing pre-step is not evidence of forgery. A non-blocker
  finding on the same line does not launder the marker.
- Plumb `.vale-findings.json` into Context (defaults to the workspace
  root, which is where the pre-step already writes it) plus a
  `--vale-findings` flag.
- Both workflow prompts and output-format.md now say plainly: never
  author the marker; reviewer-found issues go in 🚨 as ordinary `**[L…]**`
  bullets with a trail record.
- 5 regression tests reproducing the exact PR#227 case.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
A suggestion is a whole-line replacement, so one landing on a line that
also carries a blocker re-commits the blocking text if the author clicks
it. Observed on fork PR #227: the 'Simply' suggestion's replacement line
still read "Pulumi Service" and "click", both of which the same review
had just flagged in 🚨.

post-style-suggestions.py now reads .vale-findings.json and drops any
entry whose (file, line) carries a blocker-tier finding, with the reason
logged. Nothing is lost — the blocker stays flagged in 🚨 and the author
fixes that line there. Non-blocker findings on the line do not trigger
the drop, and a missing/unreadable artifact degrades to no filtering.

The review prompt now says the same thing so the model doesn't waste an
entry, but the deterministic filter is the guarantee.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
Two review-output tweaks.

Drop the batch wording. "Add suggestion to batch" isn't offered in every
context the suggestion review renders in, so the body no longer promises
it — suggestions are described one at a time.

Render the block expanded. Collapsing made sense while style findings
still counted toward ⚠️; now that the count excludes them they cost no
review burden, so the disclosure only added a click and hid the entries
worth acting on. Bullets group under an `##### <path>` H5 per file.

The H5 is load-bearing, not cosmetic: validate-pinned.py's
extract_bucket_bullets counts ANY column-0 `**bold**` line as a bucket
finding, so a `**<path>**` heading inflated the ⚠️ count and tripped the
L-prefix rule (caught by the composer's own self-check while building
this).

✏️ marks bullets with an applyable suggestion. The mark is appended by
post-style-suggestions.py --annotate-draft from the set the GitHub API
actually accepted, so it can't advertise a button that isn't there. That
required moving the posting step ahead of the pinned upsert (D3, was
after E); the ordering is documented at both ends.

118 tests pass, including 4 new annotator cases (same-line-across-files
disambiguation, idempotency, empty/missing draft).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
A published review carried 19 '…' markers, several cutting mid-word:
'claim asserts you reuse the "same IAM policies you have al…'. That reads
as a rendering bug and drops the clause that would have made the sentence
land. trunc() now backs up to the last space in the final quarter of the
budget, hard-cutting only when there isn't one (long URLs), and trims a
trailing separator before the ellipsis.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
Measuring a published review (fork PR #228, 16.1 KB body) put the
evidence/source/intuition tail on 🚨 and ⚠️ bullets at 1,596 chars — 10%
of the whole comment — and every character of it was already rendered
verbatim on that claim's 🔍 trail line a few lines above. Worse, it sat
between the quoted claim and the fix prose, so the actionable half of
each finding started below the fold.

The stub now carries the claim, the verdict, and the `framing:` note
(which the editorial pass is told to mirror for the ⚔️ mismatch
anti-hedge) — nothing else. A representative bullet drops from ~880 to
361 chars.

Nothing is weakened: every evidence-checking rule
(pass-3-unverifiable-evidence, pass-3-evidence-faithful,
verified-claims-trail-faithful) reads the trail, not the bucket bullet.
Verified before making the cut.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
Fork PR #229 shipped four correct ✏️ marks that the workflow did not
write — the log read `marked 0 style bullet(s)`. The editorial pass had
added them itself, mid-line, and the annotator's idempotency guard then
saw a mark already present and skipped every bullet.

They matched what posted, but only by luck: the model staged four and all
four survived validation. A mark it writes for an entry later dropped by
the blocker-line filter, an anchor mismatch, or the cap would promise a
one-click button that isn't there — the exact failure the mark exists to
prevent, and the same shape as the forgeable [style-blocker] marker.

annotate_draft now strips every existing mark from style bullets first
and re-applies only for entries the GitHub API accepted, so a
model-authored mark is corrected rather than trusted. Its return value is
now "marks present" (final state) rather than "newly added"; the
idempotency test asserts the body is byte-identical on a second pass.

The CI review prompt and ci.md now say plainly not to write the mark, and
why the model can't know which entries survive. The deterministic
overwrite is the guarantee; the prompt just stops the wasted effort.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
Batching IS offered on the suggestion comments — "Add suggestion to
batch" plus "Commit suggestions" stages several into one commit — so the
earlier removal of that wording was wrong. Both the pinned caption and
the suggestion review body now say so.

The caption also deep-links to the PR's Files-changed tab, since that is
where the ```suggestion blocks actually render; a ✏️ in the pinned
comment otherwise leaves the reader to work out where to look. The URL is
built from --repo/--pr and falls back to unlinked prose when either is
absent (local /docs-review runs have neither).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
Probed the API directly on the fork: POST /pulls/{n}/reviews with a
comments[] array is atomic. One unresolvable anchor returns `422 Line
could not be resolved` and creates NOTHING — there is no partial
acceptance. So a single bad entry silently cost every suggestion in the
run, and the script just logged and exited 0.

On a batch failure it now resolves the head SHA and retries one comment
at a time via POST /pulls/{n}/comments, so a bad anchor costs only itself.
The ✏️ marks are driven by the set that actually landed, which is now a
genuinely partial set rather than all-or-nothing.

This also corrects the rationale recorded earlier: local validation isn't
just tidiness, it is what keeps one malformed entry from sinking the
batch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
claude-update.yml told the reviewer both that a mark "keeps it only if the
suggestion is still posted" AND that it must "not add or remove it
yourself" — contradictory, and the second half was wrong for that lane.

post-style-suggestions.py is wired only into claude-code-review.yml, so
#update-review never re-posts suggestions and never runs the annotator.
Under the old wording the marks silently vanished on every refresh even
though the suggestion comments were still live on the PR — the author
refreshed the review and lost the pointers to their own buttons.

Because that lane leaves the comments untouched, carrying marks across is
the correct behavior: a finding that persists still has its posted
suggestion, and a finding that disappeared took the (now outdated)
comment with it. The rule now says exactly that, and forbids minting a
mark for a finding that never carried one.

Documented the lane split in output-format.md so the asymmetry is
discoverable rather than folklore.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RNTs4JzMiG36mQ2ChAyLF4
The ✏️ marks are the only evidence a suggestion exists, and they live in
the last section of a comment that routinely runs 16 KB — below every
finding the author actually has to fix. An author who clears 🚨 and stops
reading never learns the buttons are there.

post-style-suggestions.py --annotate-draft now also writes a one-line
banner directly under the count row, deep-linked to Files changed. Like
the marks, it's rewritten from the set the API accepted on every run and
stripped when nothing posts, so it can't outlive its buttons: a refresh
that converts nothing must not leave "4 suggestions are posted inline"
standing over zero comments.

Two supporting changes make that true on the re-entrant lane, where the
draft is the previously published body rather than a fresh compose:

- annotate now runs on every path, including zero-posted. It used to
  return early, which would have left last run's marks and banner in a
  body whose suggestion comments had just been deleted.
- a missing or unreadable sidecar is treated as "no suggestions this
  run" instead of "skip the run", for the same reason.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CamSoper and others added 2 commits August 4, 2026 00:51
#update-review re-ran Vale but never re-posted the suggestions, so the
marks in the refreshed body were hand-carried by the model against
comments from an arbitrarily old run. A finding the author fixed kept its
✏️ (its button now outdated), a newly-surfaced one could never gain one,
and a mark the model minted pointed at nothing.

Both lanes now post every run with the same delete-and-repost semantics.
The re-entrant lane can't use --annotate-draft, though: it has no draft
to intercept, since the model renders the body and upserts it inside its
own step. So annotation is factored into annotate_text() and a new
--annotate-pinned fetches the published <!-- CLAUDE_REVIEW N/M -->
comments and PATCHes each in place.

In place, rather than fetch → concatenate → re-upsert, because
re-upserting re-runs the splitter over a body that already carries the
splitter's own artifacts — the synthetic </details> and continuation
<details> pairs it inserts at page boundaries — which compounds on every
refresh. Editing each part touches only the lines the marks and banner
live on, and skips the PATCH entirely when a part is already correct so
a refresh doesn't re-notify subscribers.

The prompt change is the other half: the model is now told to drop every
✏️ it finds and stage the full qualifying set each run, rather than
carrying marks across. Same lesson as the two before it — the mark is a
promise that a button exists, and only the step that posted can keep it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Observed on the two-lane fork smoke (CamSoper#230): line 768
carried two weasel-word findings, one suggestion posted for it, and both
bullets got a mark — 4 marks against a banner reading 3. That is correct
behavior, since a suggestion replaces the whole line, but the contract
never said so. Says so now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@CamSoper
CamSoper marked this pull request as ready for review August 5, 2026 00:53
@github-actions github-actions Bot added review:triaging Claude Triage is currently classifying the PR domain:infra PR touches workflows, scripts, infra, Makefile, or build config review:in-progress Claude review is currently running and removed review:triaging Claude Triage is currently classifying the PR labels Aug 5, 2026
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Pre-merge Review — Last updated 2026-08-05T00:58:20Z

Tip

Summary: This is an infrastructure PR on the review pipeline itself — no reader-facing content changes. It splits Vale findings into a blocker tier that renders in 🚨 Outstanding (a new blocker: allowlist in vale-deterministic-fixes.yaml, exempt from the per-file/total caps) and an advisory tier that renders expanded and uncounted under ⚠️, adds a post-style-suggestions.py script that posts the advisory subset as one-click GitHub suggestion comments with reconciled ✏️ marks, guards the new [style-blocker] marker with a style-blocker-provenance validator rule, and turns off Google.OxfordComma while adding secrets-vendor exceptions to HeadingSentenceCase. The wrongness that matters here is a pipeline step that fails silently or a doc/hint that instructs the shape the code now rejects — four of those are outstanding: an unrecognized flag that stops review:in-progress from ever being applied, and three pieces of prose (the style guide plus two fix hints) still describing the collapsed-render behavior this PR replaces. The new script carries good test coverage (validation, cap, blocker-line collision, banner idempotence, split-comment PATCHing), and the two-tier count arithmetic is consistent across the composer, the validator, and both workflow lanes. Passes run: infra risk axes (workflow triggers, secret handling, documentation drift), shared criteria, and the automated fact-check sweep — which found nothing to contradict, since 39 of 41 extracted claims are self-referential descriptions of this tooling rather than checkable external assertions.

Review confidence:

Dimension Level Notes
mechanics HIGH
facts HIGH Only two claims were externally checkable (Vale.sh, the styles/Pulumi/ rule files); both verified.
code correctness MEDIUM Python and shell logic reviewed by reading, and the new script's tests are thorough; nothing was executed in CI, so the GitHub-API paths (batch review POST, per-comment fallback, --annotate-pinned PATCH) rest on the stubs rather than a live run.
Investigation log
  • Cross-sibling reads: not run (not in a templated section)
  • External claim verification: 2 of 41 claims verified (0 unverifiable, 0 contradicted) · 4 specialists (numerical, cross-reference, capability, framing); 0 cross-specialist corroborations · routed: 0 inline, 10 Pass 1, 0 Pass 2, 31 Pass 3 (verified 1, contradicted 0, unverifiable 30).
  • Cited-claim spot-checks: not run (no cited claims)
  • Frontmatter sweep: not run (no frontmatter in diff)
  • Temporal-trigger sweep: ran (recency words present in diff; spot-check in-review)
  • Code execution: not run (no static/programs/ change)
  • Code-examples checks: ran (3 specialists: structural, existence, body-code-coverage); 0 findings
  • Editorial-balance pass: not run (not under content/blog/)
🚨 Outstanding ⚠️ Low-confidence 💡 Pre-existing ✅ Resolved
4 0 0 0

🔍 Verification trail

41 claims extracted · 2 verified · 0 unverifiable · 0 contradicted
  • L35 in .claude/commands/docs-review/SKILL.md "For files under content/docs/ or content/blog/, also run Vale and surface its findings per the Style-findings render contract in…" → ➖ not-a-claim (evidence: This is a description of the PR author's own internal tooling design (a Claude Code skill command file describing its own Vale integration and rendering contract referencing its own sibling reference file), not a falsifiable third-party…; source: .claude/commands/docs-review/SKILL.md (self-referential design description))
  • L65 in .claude/commands/docs-review/ci.md "- stub 🚨 / ⚠️ bucket bullets — one **[L…]**-prefixed bullet per promoting verdict (contradicted/mismatch → 🚨; framing-drift, unverifiable, and…" → ➖ not-a-claim (evidence: This is internal documentation of the PR author's own review-tooling convention (a Claude Code slash-command spec for docs-review CI output formatting), not a falsifiable external claim.; source: .claude/commands/docs-review/ci.md (self-referential process documentation))
  • L113 in .claude/commands/docs-review/ci.md "Count-table cells == bucket-bullet counts (advisory [style] bullets are NOT counted in ⚠️; [style-blocker] bullets ARE counted in 🚨). Every 🔍 trail line…" → ➖ not-a-claim (evidence: This is internal specification text from the PR author's own CI tooling (.claude/commands/docs-review/ci.md), describing self-defined counting conventions for their own review artifact format. It's a design/spec description, not a…; source: .claude/commands/docs-review/ci.md (self-authored tooling spec))
  • L125 in .claude/commands/docs-review/ci.md "Triage the ADVISORY style bullets and Write .style-suggestions.json (array; [] if none qualify): `{'file', 'line', 'original', 'replacement', 'category'…" → ➖ not-a-claim (evidence: This is a description of the PR author's own internal Claude command/tooling design (output schema and triage rules for .claude/commands/docs-review/ci.md), not a falsifiable third-party factual assertion.; source: .claude/commands/docs-review/ci.md (self-described pipeline behavior))
  • L143 in .claude/commands/docs-review/ci.md "2. Read the pre-step artifacts directly: .verified-claims.json for the trail/verdicts (render one trail line per verdict, verbatim — verdict word +…" → ➖ not-a-claim (evidence: This is a description of the PR author's own CI command pipeline (reading its own pre-step artifact files .verified-claims.json/.candidate-claims.json), not a falsifiable external claim.; source: .claude/commands/docs-review/ci.md (self-referential pipeline spec))
  • L102 in .claude/commands/docs-review/references/blog.md "Vale catches Pulumi product-name capitalization, the Pulumi Policies singular-verb rule, and 'public preview' vs 'public beta' (surfaced under ⚠️…" → ➖ not-a-claim (evidence: (escalated from pass3) This line is a description of the PR author's own docs-review tooling pipeline (how Vale findings surface under ⚠️ Low-confidence via the Style-suggestions block), not a third-party technical assertion.…; source: .claude/commands/docs-review/references/output-format.md and blog.md (self-consistent internal tooling description))
  • L155 in .claude/commands/docs-review/references/blog.md "- Anything Vale catches. Product-name capitalization, Policies-singular, public-preview/public-beta, click→select, banned words, difficulty qualifiers …" → ➖ not-a-claim (evidence: This is a description of the PR author's own internal docs-review tooling pipeline (a Claude Code command reference describing how Vale findings surface via .vale-findings.json), not a falsifiable third-party assertion.; source: .claude/commands/docs-review/references/blog.md (self-describing pipeline documentation))
  • L54 in .claude/commands/docs-review/references/docs.md "Vale catches product-name capitalization, the Pulumi Policies singular-verb rule, 'public preview' vs 'public beta', and preferred-terminology pairs from…" → ➖ not-a-claim (evidence: This is a description of the PR author's own internal docs-review tooling/pipeline (Vale rules and reviewer workflow conventions defined within the same repo's .claude/commands system), not a falsifiable third-party assertion.; source: .claude/commands/docs-review/references/docs.md (self-referential pipeline description))
  • L102 in .claude/commands/docs-review/references/docs.md "- Anything Vale catches. Product-name capitalization, Policies-singular, public-preview/public-beta, click→select, banned words, difficulty qualifiers …" → ➖ not-a-claim (evidence: This is a description of the PR author's own internal docs-review tooling/pipeline (how Vale findings are surfaced via .vale-findings.json in a Claude Code slash-command reference), not a falsifiable third-party or product claim.; source: .claude/commands/docs-review/references/docs.md (self-referential design description))
  • L106 in .claude/commands/docs-review/references/output-format.md "In CI the workflow's compose-review.py pre-step assembles most of this body deterministically into .review-draft.md and the reviewer edits it (see…" → ➖ not-a-claim (evidence: (escalated from pass3) This is a self-referential description of the docs-review tooling's own pipeline (compose-review.py assembling .review-draft.md), cross-checked against ci.md which states the identical mechanism verbatim: "The…; source: .claude/commands/docs-review/ci.md and .claude/commands/docs-review/references/output-format.md)
  • L106 in .claude/commands/docs-review/references/output-format.md "The ✏️ banner under the table is workflow-written — never author or edit it. When one-click suggestions posted, post-style-suggestions.py…" → ➖ not-a-claim (evidence: (escalated from pass3) This line describes the PR author's own internal tooling design (the docs-review workflow's post-style-suggestions.py --annotate-draft` script and its banner-insertion behavior) within the same repo's command…; source: .claude/commands/docs-review/references/output-format.md (self-referential design doc, same PR))
  • L309 in .claude/commands/docs-review/references/output-format.md "- Blocker-tier Vale finding (blocker: true in .vale-findings.json, from the blocker: allowlist in vale-deterministic-fixes.yaml — wrong or deprecated…" → ➖ not-a-claim (evidence: This line describes the PR author's own internal tooling design (the docs-review Claude Code skill's composer logic: how .vale-findings.json blocker findings map to [style-blocker] bullets via the vale-deterministic-fixes.yaml…; source: repo:pulumi/docs .claude/commands/docs-review/scripts/vale-deterministic-fixes.yaml and vale-findings-filter.py)
  • L325 in .claude/commands/docs-review/references/output-format.md "Render expanded — never behind a <details>. They were collapsed while they still counted toward ⚠️; now that the count excludes them they cost no…" → ➖ not-a-claim (evidence: This is a design specification for the PR author's own docs-review command output format (an internal Claude Code slash-command spec), describing rendering rules the author chose for their own tool — not a falsifiable external claim.; source: .claude/commands/docs-review/references/output-format.md (self-authored spec))
  • L327 in .claude/commands/docs-review/references/output-format.md "✏️ marks a one-click suggestion. A bullet whose finding was posted as an applyable suggestion comment gets ✏️ appended, and the caption deep-links…" → ➖ not-a-claim (evidence: This line documents the PR author's own docs-review tooling's output-format convention (how the ✏️ mark is appended to bullets and links to the Files-changed tab). It's a faithful description of the author's own design/pipeline, not a…; source: .claude/commands/docs-review/references/output-format.md (self-describing tooling spec))
  • L394 in .claude/commands/docs-review/references/output-format.md "7. No findings markdownlint or Prettier catches. Specifically: trailing newlines, heading case, trailing whitespace. The lint job runs in parallel…" → ➖ not-a-claim (evidence: This is a self-description of Pulumi's internal docs-review Claude command's own design/pipeline (what the lint job in their own CI catches vs. what the review command should separately flag), not a falsifiable external claim.; source: .claude/commands/docs-review/references/output-format.md (file under review, describes author's own tooling design))
  • L396 in .claude/commands/docs-review/references/output-format.md "7. No findings markdownlint or Prettier catches. Specifically: trailing newlines, heading case, trailing whitespace. The lint job runs in parallel…" → ➖ not-a-claim (evidence: This is internal process documentation for the PR author's own docs-review Claude Code command, describing which lint issues to skip (handled by markdownlint/Prettier) versus flag manually (alt text, code fence languages). It's a…; source: .claude/commands/docs-review/references/output-format.md (file under review, describing its own authoring guidance))
  • L35 in .claude/commands/docs-review/references/pre-computation.md "The review-composition step (compose-review.py) is the consumer-side bookend: it runs after every other pre-step, reads all their artifacts, and…" → ➖ not-a-claim (evidence: (escalated from pass3) This line is the PR author's own design documentation describing their own pipeline script (compose-review.py) and its output contract — it's corroborated verbatim/consistently across sibling files…; source: repo:.claude/commands/docs-review/references/pre-computation.md (L35), cross-checked against repo:.claude/commands/docs-review/references/output-format.md and repo:.claude/commands/docs-review/ci.md)
  • L54 in .claude/commands/docs-review/references/prose-patterns.md "A handful of specific AI-drafting tells are caught by Vale rules under styles/Pulumi/: SetPieceTransitions (stock opener phrases), EmDashDensity…" → ✅ verified (evidence: (escalated from pass3) Directory listing of styles/Pulumi/ in pulumi/docs confirms EmDashDensity.yml, ListicleH2Headings.yml, and HedgeThenPivot.yml exist as Vale rule files there, and SetPieceTransitions is referenced consistently in…; source: gh api repos/pulumi/docs/contents/styles/Pulumi (directory listing); gh search code --owner pulumi SetPieceTransitions/EmDashDensity)
  • L70 in .claude/commands/docs-review/references/prose-patterns.md "- Anything Vale catches. Passive voice, filler phrases, empty intensifiers, difficulty qualifiers, hedging, buzzwords, empty transitions, em-dash…" → ➖ not-a-claim (evidence: This is a bullet point in an internal Claude command reference document describing the PR author's own docs-review tooling and Vale linter configuration expectations, not a falsifiable third-party assertion.; source: .claude/commands/docs-review/references/prose-patterns.md (self-referential internal tooling doc))
  • L775 in .claude/commands/docs-review/scripts/compose-review.py "# The advisory-tier sub-heading. Renamed from 'Style findings' on 2026-08-03:" → ➖ not-a-claim (evidence: This is a code comment in an internal Claude Code review script describing the author's own change history (renaming a sub-heading label). It is not a falsifiable external claim about Pulumi products/docs, but a self-referential…; source: .claude/commands/docs-review/scripts/compose-review.py L775)
  • L1111 in .claude/commands/docs-review/scripts/compose-review.py "# lines above, and measuring a published review (2026-08-03, fork PR Update reference docs to v0.12 SDK #228)" → ➖ not-a-claim (evidence: This is a code comment in the PR author's own review-composition script describing an example/reference point (a published review dated 2026-08-03 on fork PR Update reference docs to v0.12 SDK #228) used for internal measurement purposes, not a falsifiable external…; source: .claude/commands/docs-review/scripts/compose-review.py L1111)
  • L1112 in .claude/commands/docs-review/scripts/compose-review.py "# put the duplicate at 1,596 chars — 10% of the whole comment — sitting" → ➖ not-a-claim (evidence: This is a code comment describing a specific test fixture's own constructed data (a duplicate string of 1,596 chars) within the PR author's own script, not a falsifiable external claim.; source: .claude/commands/docs-review/scripts/compose-review.py L1112)
  • L1375 in .claude/commands/docs-review/scripts/compose-review.py "files_url = (f'https://github.com/{args.repo}/pull/{args.pr}/files'" → ➖ not-a-claim (evidence: This is a line of Python code constructing a GitHub URL string using f-string formatting within the PR author's own review tooling script; it's not a factual assertion to be verified but a code implementation detail.; source: .claude/commands/docs-review/scripts/compose-review.py L1375)
  • L28 in .claude/commands/docs-review/scripts/post-style-suggestions.py "- The batch endpoint is ATOMIC (verified 2026-08-03: one unresolvable" → ➖ not-a-claim (evidence: This is a code comment in the PR author's own script (post-style-suggestions.py) documenting their own testing/verification of an API behavior (batch endpoint atomicity) with a self-referenced date, not a third-party-attributed factual…; source: .claude/commands/docs-review/scripts/post-style-suggestions.py L28 (self-authored code comment))
  • L84 in .claude/commands/docs-review/scripts/post-style-suggestions.py "'Generated by Claude Code'" → ➖ not-a-claim (evidence: This is a standard auto-generated attribution footer ("Generated by Claude Code") linking to the live claude.ai/code product page; it is not a falsifiable factual assertion but boilerplate signature text embedded in a script's output.; source: https://claude.ai/code/new)
  • L89 in .claude/commands/docs-review/scripts/post-style-suggestions.py "# LAST section of a ~16 KB comment, below everything the author actually has" → ➖ not-a-claim (evidence: This is a code comment in the PR author's own script describing the placement/size of a comment section it generates (~16 KB), not a falsifiable external or product claim.; source: .claude/commands/docs-review/scripts/post-style-suggestions.py L89)
  • L233 in .claude/commands/docs-review/scripts/post-style-suggestions.py "verified 2026-08-03: a single unresolvable anchor returns" → ➖ not-a-claim (evidence: This is a code comment/changelog-style note in the PR author's own internal tooling script (post-style-suggestions.py) describing their own testing/verification of the script's behavior, not a falsifiable third-party technical claim.; source: .claude/commands/docs-review/scripts/post-style-suggestions.py L233)
  • L487 in .claude/commands/docs-review/scripts/post-style-suggestions.py "files_url = f'https://github.com/{args.repo}/pull/{args.pr}/files'" → ➖ not-a-claim (evidence: This is a line of Python code constructing a GitHub URL string (f"https://github.com/{args.repo}/pull/{args.pr}/files") using the standard GitHub PR "files" view pattern — it's the PR author's own script logic, not a falsifiable external…; source: .claude/commands/docs-review/scripts/post-style-suggestions.py L487)
  • L551 in .claude/commands/docs-review/scripts/post-style-suggestions.py "files_url = f'https://github.com/{args.repo}/pull/{args.pr}/files'" → ➖ not-a-claim (evidence: This is a line of Python code constructing a GitHub URL string using an f-string with variable interpolation (args.repo, args.pr) — it's part of the PR author's own script logic, not a factual assertion to verify.; source: .claude/commands/docs-review/scripts/post-style-suggestions.py L551)
  • L30 in .claude/commands/docs-review/scripts/scrape-review-outcomes.py "spelled #### Style findings before 2026-08-03 — this reader keys on the" → ➖ not-a-claim (evidence: This is a code comment describing the author's own script's parsing logic/history for their internal review-outcome scraper, not a falsifiable external claim.; source: .claude/commands/docs-review/scripts/scrape-review-outcomes.py (PR's own file))
  • L136 in .claude/commands/docs-review/scripts/test_post_style_suggestions.py "Regression: the 2026-08-03 fork run POSTed to pulumi/docs with the" → ➖ not-a-claim (evidence: This is a code comment in the PR author's own test file explaining the motivation for a regression test (a prior fork-run incident that POSTed to the wrong repo and got a 403). It's a docstring describing the test's own design rationale…; source: repo:.claude/commands/docs-review/scripts/test_post_style_suggestions.py:163-169)
  • L270 in .claude/commands/docs-review/scripts/test_post_style_suggestions.py "FILES_URL = 'https://github.com/pulumi/docs/pull/7/files'" → ➖ not-a-claim (evidence: FILES_URL is a test fixture constant (FILES_URL = "https://github.com/pulumi/docs/pull/7/files") used as an arbitrary placeholder value passed into unit test calls like pss.annotate_draft(d, [...], FILES_URL) — it's not an assertion…; source: repo:.claude/commands/docs-review/scripts/test_post_style_suggestions.py)
  • L131 in .claude/commands/docs-review/scripts/test_scrape_review_outcomes.py "# Deliberately uses the pre-2026-08-03 'Style findings' heading: this" → ➖ not-a-claim (evidence: This is a code comment in a test script describing the author's own test fixture design (a deliberate use of an old heading string for backward-compatibility testing), not a falsifiable external claim.; source: .claude/commands/docs-review/scripts/test_scrape_review_outcomes.py L131)
  • L3 in .claude/commands/docs-review/scripts/test_style_blocker_provenance.py "Regression: on 2026-08-03 (fork PR docs: add a secrets-backend comparison to the secrets concept page CamSoper/pulumi.docs#227) a review authored" → ➖ not-a-claim (evidence: This is a code comment in a test file (test_style_blocker_provenance.py) documenting the provenance of a regression test case, referencing an internal fork PR used as a test fixture. It's the author's own description of their testing…; source: .claude/commands/docs-review/scripts/test_style_blocker_provenance.py L3 (self-referential test metadata))
  • L189 in .claude/commands/docs-review/scripts/validate-pinned.py "# 'Style findings' -> 'Style suggestions' on 2026-08-03; both are accepted so a" → ➖ not-a-claim (evidence: This is a code comment in the PR author's own script describing an internal rename ("Style findings" -> "Style suggestions") and noting both labels are accepted for backward compatibility; it's a self-referential implementation note, not…; source: .claude/commands/docs-review/scripts/validate-pinned.py L189)
  • L658 in .claude/commands/docs-review/scripts/validate-pinned.py "# was renamed 'Style findings' -> 'Style suggestions' on 2026-08-03, and a" → ➖ not-a-claim (evidence: This is a code comment in the PR author's own script documenting an internal rename decision ("Style findings" -> "Style suggestions") within their own docs-review tooling pipeline, not a falsifiable external claim.; source: .claude/commands/docs-review/scripts/validate-pinned.py (self-referential code comment))
  • L701 in .claude/commands/docs-review/scripts/validate-pinned.py "observed on 2026-08-03, when a run authored a [style-blocker] _misspelling_" → ➖ not-a-claim (evidence: This is an internal log/comment artifact from Pulumi's own docs-review validation script recording an observed run event (a style-blocker misspelling detection), not a falsifiable external claim. It reflects the script's own operational…; source: .claude/commands/docs-review/scripts/validate-pinned.py L701 (self-referential tooling artifact))
  • L1010 in .github/workflows/claude-code-review.yml "- stub 🚨 / ⚠️ bucket bullets — one **[L…]**-prefixed bullet per promoting verdict (contradicted/mismatch → 🚨; framing-drift, unverifiable, and…" → ➖ not-a-claim (evidence: (escalated from pass3) This is a self-description of the workflow's own compose-review.py behavior within the same file (.github/workflows/claude-code-review.yml), describing how the PR author's own pipeline stubs bucket bullets by…; source: .github/workflows/claude-code-review.yml (self-referential design description, lines ~1002-1010))
  • L1011 in .github/workflows/claude-code-review.yml "Your job is to EDIT this draft, not rebuild it. Do NOT re-parse .verified-claims.json / .candidate-claims.json / .vale-findings.json /…" → ➖ not-a-claim (evidence: This is an internal instruction/directive within the PR author's own GitHub Actions workflow file, describing the author's own pipeline behavior for a Claude-based code review bot. It is not a falsifiable factual assertion about an…; source: .github/workflows/claude-code-review.yml (self-authored workflow instructions))
  • L1214 in .github/workflows/claude-code-review.yml "# the debug bundle on the 2026-08-03 fork run." → ➖ not-a-claim (evidence: This is a code comment in a GitHub Actions workflow file referencing an internal debug bundle from a specific CI run date, which is workflow metadata/authoring context rather than a falsifiable external assertion.; source: .github/workflows/claude-code-review.yml (line 1214, code comment))
  • L396 in STYLE-GUIDE.md "The rules in this guide are enforced — where mechanically possible — by Vale via .vale.ini at the repo root. Custom rules live under…" → ✅ verified (framing: Vale.sh is accurately described as the linter; the repo-specific details (styles/Pulumi/, make lint-prose) are the author's own project configuration…; evidence: Vale.sh is confirmed as a real prose-linting tool configured via a .vale.ini file, and the pulumi/docs repo's own dev container and README confirm it ships "Vale for prose linting" as part of its tooling. The specific styles/Pulumi/…; source: https://vale.sh/ and https://github.com/pulumi/docs)
  • L520 in .github/workflows/claude-code-review.yml "the in-progress label step passes --vale-findings to set-review-label.sh" → ⚔️ mismatch (evidence: set-review-label.sh parses only --pr, --label, --clear, --repo, -h/--help; its *) catch-all prints ::error::set-review-label: unknown arg and exits 2, so the label is never applied; source: .claude/commands/docs-review/scripts/set-review-label.sh lines 39-51, unchanged by this PR)
  • L396 in STYLE-GUIDE.md "everything else renders collapsed under ⚠️ Low-confidence as advisory nags that never block" → ⚔️ mismatch (evidence: the same PR inverts that rendering — advisory suggestions now render expanded, and check_style_render_mode fails a body that puts them inside a <details>; source: .claude/commands/docs-review/references/output-format.md §"Render expanded — never behind a <details>" and validate-pinned.py check_style_render_mode)
  • L684 in .claude/commands/docs-review/scripts/validate-pinned.py "the style-render-mode fix hint tells the reviewer to group suggestions under a bold **<path>** line per file" → ⚔️ mismatch (evidence: the render contract mandates an ##### <path> H5 precisely because a column-0 **bold** line is counted as a bucket finding by extract_bucket_bullets and breaks the ✏️ annotator's heading walk; source: .claude/commands/docs-review/references/output-format.md §Style suggestions and compose-review.py _render_style_findings)
  • L2415 in .claude/commands/docs-review/scripts/validate-pinned.py "the style-render-mode rule-registry hint still reads 'Inline-all when total ≤5 … collapse-all when multi-file AND total >5, or total >30'" → ⚔️ mismatch (evidence: the same registry entry's desc was updated to "render expanded, never hidden behind a <details> block", and the inline-vs-collapse mode selection was deleted from both the checker and the composer in this PR; source: validate-pinned.py RULES entry style-render-mode and the removed _style_mode helper in compose-review.py)

🚨 Outstanding in this PR

These must be resolved or refuted before merging.

  • [L520] .github/workflows/claude-code-review.yml — the Set review:in-progress label step passes a flag set-review-label.sh does not accept. That script's argument loop handles only --pr, --label, --clear, --repo, and -h/--help; anything else hits its catch-all, prints ::error::set-review-label: unknown arg: --vale-findings, and exits 2 before touching any label. The step is continue-on-error: true, so CI stays green while review:in-progress silently stops being applied on every review run. The flag looks copied from the new post-style-suggestions.py invocation, which does need it. Drop the two lines:

            .claude/commands/docs-review/scripts/set-review-label.sh \
              --pr "${{ steps.pr-context.outputs.pr_number }}" \
              --repo "${{ github.repository }}" \
              --label review:in-progress
    
  • [L396] STYLE-GUIDE.md — the new contributor-facing paragraph says advisory findings render "collapsed under ⚠️ Low-confidence," but this PR inverts exactly that: advisory suggestions now render expanded, and the rewritten check_style_render_mode fails any body that hides them inside a <details>. As written the style guide documents the behavior the same commit removes. Rewrite the tail of the sentence:

    The rules in this guide are enforced — where mechanically possible — by [Vale](https://vale.sh) via `.vale.ini` at the repo root. Custom rules live under `styles/Pulumi/` and layer on top of the Google Developer Style Guide and write-good packages. Run locally with `make lint-prose`. Vale findings also surface in the pinned PR review in two tiers: a small set of near-zero-false-positive correctness rules (wrong or deprecated product names, banned terms, misspellings, grammatical agreement — the `blocker:` list in `.claude/commands/docs-review/scripts/vale-deterministic-fixes.yaml`) renders under 🚨 Outstanding and must be resolved or refuted before merging; everything else renders under ⚠️ Low-confidence as advisory nags that never block.
    
  • [L684] .claude/commands/docs-review/scripts/validate-pinned.py — the fix hint on the rewritten style-render-mode violation tells the reviewer to group suggestions "under a bold **<path>** line per file." That is the one shape this PR forbids: the render contract mandates an ##### <path> H5 specifically because a column-0 **bold** line is counted as a bucket finding by extract_bucket_bullets (inflating the ⚠️ count and tripping the L-prefix rule) and because post-style-suggestions.py --annotate-draft walks H5 headings to bind bullets to a file. A reviewer who follows the hint reintroduces both bugs:

              hint=("Render style suggestions expanded, grouped under an `##### <path>` H5 heading per "
                    "file. They are uncounted, so they cost no review burden, and collapsing them "
                    "hides the ✏️ marks that flag one-click suggestions."),
    
  • [L2415] .claude/commands/docs-review/scripts/validate-pinned.py — the style-render-mode entry in the RULES registry got a new desc ("render expanded, never hidden behind a <details> block") but kept the old hint, which still prescribes the deleted inline-vs-collapse thresholds. The registry is what show-rules prints and what a fixer reads next to the failure, so the two halves of the same entry now contradict each other. Replace the hint:

          "hint": "Render advisory style suggestions expanded — remove the <details> wrapper and group them under an `##### <path>` H5 heading per file.",
    

⚠️ Low-confidence

No low-confidence findings.

💡 Pre-existing issues in touched files (optional)

No pre-existing issues in touched files.

✅ Resolved since last review

No items resolved since the last review.

📜 Review history

  • 2026-08-05T00:58:20Z — Four blockers: an unrecognized --vale-findings flag that makes the review:in-progress label step exit 2, and three pieces of prose (STYLE-GUIDE.md plus two style-render-mode fix hints) still describing the collapsed style-findings rendering this PR replaces. (334307b)

  • Refresh this review — comment @claude #update-review. Say what you fixed, or which finding you dispute and why; both work in the same mention.
  • Ask for anything else — comment @claude with no hashtag (questions, one-off fixes). Leaves this review untouched.

Important

Please don't hide, resolve, or delete this comment! It breaks things!

📖 How pre-merge review works — the full lifecycle, short-circuits, and escape hatches.

@github-actions github-actions Bot added review:outstanding-issues Claude review completed; outstanding has author-actionable findings and removed review:in-progress Claude review is currently running labels Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge domain:infra PR touches workflows, scripts, infra, Makefile, or build config review:outstanding-issues Claude review completed; outstanding has author-actionable findings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants