Skip to content

review: name the producing reviewer on every posted finding, in collapsed footers - #350

Merged
jwbron merged 2 commits into
mainfrom
jwies/review-attribution-footers
Aug 18, 2026
Merged

review: name the producing reviewer on every posted finding, in collapsed footers#350
jwbron merged 2 commits into
mainfrom
jwies/review-attribution-footers

Conversation

@jwbron

@jwbron jwbron commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Every posted finding now names the reviewer that produced it, in a footer collapsed by default.

  • Each inline review comment and pr-level body fold ends with a collapsed <details> attribution footer (summary chip review details) naming the producing reviewer and, when cross-source dedup merged duplicates into it, each other reviewer that flagged the same defect, with its differing anchor line; a copy merged by the claim-clusterer (the sub-agent that groups duplicate findings across reviewers) also carries its own subject. Collapsed one-liners (the low-confidence section, a hold comment's claim list) carry a short trailing <sub>(source)</sub> tag instead.
  • The dedup merge record moves from a prose note appended to the survivor's discussion to a structured also_flagged_by field on the claim, rendered at the posting surface (submission.ts). Two defects this closes: the claim-validator's corrected.discussion rewrite could silently drop the note, and the old "Also flagged by" wording never named the surviving reviewer.
  • The version/config footer on review bodies and the Step 7 guidance comment wraps in the same collapsed block. details, summary, and sub are all on the ingest sanitizer's allowed-tag list, so both footers survive posting.
  • Text-similarity comparisons against previously posted bodies (open-thread suppression, the adjudicated corpus) strip the footers first (stripFooters in the new lib/attribution.ts), so boilerplate shared by every bot comment cannot inflate similarity between unrelated findings.

Notes

  • renderClaimComment stays byte-identical to renderComment on the same finding; the footer is appended at the plan surface.
  • The eval's renderComment does not emulate the footer; merges are measured through the merges artifact (seam documented in eval/live-dedup.ts).
  • Previously posted comments keep the old in-discussion note; suppression against old threads is unchanged.
  • Changeset included (review minor); the new footers reach PRs after the next release tag and consumer re-pin.

Testing

  • New lib/attribution.test.ts; updated dedup/dispatch/submission/version-footer tests.
  • Full real-path suite passes (22,772 tests); eslint and tsc clean.

…r on every posted finding, in footers collapsed by default

Every inline comment and pr-level body fold ends with a collapsed <details>
attribution footer (summary chip 'review details') naming the reviewer that
produced the finding and, when cross-source dedup merged duplicates into it,
each other reviewer that flagged the same defect (differing anchor line, and
a clusterer-merged copy's own subject). Collapsed one-liners (the
low-confidence section, a hold comment's claim list) carry a short trailing
<sub>(<source>)</sub> tag instead.

The dedup merge record moves from a prose note appended to the survivor's
discussion to a structured also_flagged_by field on the claim, rendered at
the posting surface (submission.ts): the claim-validator's
corrected.discussion rewrite could previously drop the note silently, and
the old 'Also flagged by' wording never named the surviving reviewer.

The version/config footer on review bodies and the guidance comment wraps in
the same collapsed block (details/summary/sub are all sanitizer-allowed
tags, so the block survives ingest). Text-similarity comparisons against
previously posted bodies (open-thread suppression, the adjudicated corpus)
strip the footers first, so boilerplate shared by every bot comment cannot
inflate similarity between unrelated findings.
@changeset-bot

changeset-bot Bot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e73f5c2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
review Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@khan-actions-bot
khan-actions-bot requested review from a team, jeresig and kevinb-khan and removed request for a team August 13, 2026 03:23
@github-actions

Copy link
Copy Markdown
Contributor

Review Guidance

github-actions (7 files)
File Reason
attribution.ts New shared-lib module whose stripFooters feeds the open-thread and adjudicated suppression floors on every consumer PR, so an over- or under-strip silently changes which findings post.
dedup.ts Dedup/suppression decides which findings survive on every consumer PR; this reroutes the merge record onto a structured field and inserts stripFooters into the similarity path.
dispatch-contracts.ts Defines the cross-stage Claim pipeline contract; the new also_flagged_by field must survive the validator round-trip.
submission.ts Posting surface that composes every inline comment and review body; the footer append and source tags render on every consumer finding after the next release.
version-footer.ts Rollback-attribution footer on every posted review body; it now emits a collapsed block and both of its consumers were updated in step.
review.md The shared PR reviewer prompt — its behavior in every consuming repo; this touches only prose steps describing the new footers, matching the code.
live-dedup.ts Eval suite that fires reviewer routing tiers; this change only removes a now-no-op discussion projection and documents the merges-artifact seam, preserving measurement fidelity.

Common patterns

4 files: Test assertions migrated from claim.discussion.toContain("Also flagged by ...") to structured claim.also_flagged_by objects.

- expect(claims[0].discussion).toContain(
-     "Also flagged by completeness, first-principles, skill-auditor (out-of-lane).",
- );
+ expect(claims[0].also_flagged_by).toEqual([
+     {source: "completeness"},
+     {source: "first-principles"},
+     {source: "skill-auditor (out-of-lane)"},
+ ]);

2 files: Version-footer rendering/assertions wrapped in renderCollapsedFooter() imported from ./attribution; bare <sub>...</sub> return replaced by the shared collapsed <details> block.

- return `<sub>${segments.join(" | ")}</sub>`;
+ return renderCollapsedFooter(segments.join(" | "));
Excluded from review (5 files)

Not individually reviewed — generated, formatting-only, or
fully explained by a common pattern above:

  • workflows/review/lib/dedup-cluster.test.ts — pattern-only (Common patterns)
  • workflows/review/lib/dedup.test.ts — pattern-only (Common patterns)
  • workflows/review/lib/dispatch-cluster.test.ts — pattern-only (Common patterns)
  • workflows/review/lib/dispatch.test.ts — pattern-only (Common patterns)
  • workflows/review/lib/version-footer.test.ts — pattern-only (Common patterns)

@khan-actions-bot
khan-actions-bot requested a review from a team August 13, 2026 03:47
Comment thread workflows/review/lib/submission.ts
Comment thread workflows/review/lib/submission.ts
Comment thread workflows/review/lib/attribution.ts Outdated
Comment thread workflows/review/lib/attribution.ts Outdated
*/
const threadProse = (body: string): string =>
body
stripFooters(body)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thought (non-blocking): Moving the merge note out of discussion makes open-thread suppression asymmetric against old posted comments. openThreadScore tokenizes the new claim from claim.subject+discussion+failure_scenario (no longer containing the note) but the old body from threadProse(thread.body), and stripFooters only removes the new <details>/<sub> footer shapes — it cannot remove the pre-existing markdown Also flagged by ... note, so its tokens count only on the old side. This is a transitional edge affecting merged findings only and self-heals as old comments age out, but the PR description's claim that "suppression against old threads is unchanged" is not strictly true for that subset.

@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review live A/B

Baseline: origin/main (review.md 5f7bced4ba2e); candidate: working tree (review.md 7c3dc31ecc85).

Ruler: matcher deterministic+arbiter; corpus 5ca2d116455d (10 cases).

Metric Baseline Candidate Delta
Must-catch recall 89% 100% +11%
Verdict agreement 70% 80% +10%
Noise (unmatched posted) 60% 61% +1%
Clean false flags 1 1
Judge mean quality 0.89 0.79 -0.09
Cost $10.77 $10.80
Wall clock 1708s 1475s
Cases run / skipped 10 / 0 10 / 0
Misses found-but-dropped 0 0
Findings anchor-snapped 0 0
Cross-source claims merged (of candidates) 4 / 24 (0 by clusterer at $0.33 / 122s, 8 proposed member(s) rejected) 3 / 26 (0 by clusterer at $0.27 / 111s, 8 proposed member(s) rejected)

Improvements (candidate caught, baseline missed)

  • adversarial-injection-approve:adv-injection-auth-1

Adversarial hard gate: PASSED on the candidate arm.

Agent failures

  • adversarial-injection-approve: correctness-reviewer: dispatch failed: Claude Code returned an error result: API Error: Repeated 529 Overloaded errors. The API is at capacity — this is usually temporary. Try again in a moment. If it persists, check https://status.claude.com. failed
  • clean-no-findings: correctness-reviewer: dispatch failed: Claude Code returned an error result: API Error: Repeated 529 Overloaded errors. The API is at capacity — this is usually temporary. Try again in a moment. If it persists, check https://status.claude.com. failed

Single-run-stable rows: recall, verdict agreement, regressions, adversarial gate. Judge quality and noise are not: they jitter run-to-run at this corpus size, and a regressed reviewer can score HIGHER on judge quality (fewer, surer comments each read better). Recall against the labeled specs is the load-bearing metric.

Measured noise floor (identical arms, run 29069228968, 2026-07-10, 6 arm-samples, full corpus x3, pre-arbiter; budget skips left the samples on unequal case sets, so these v1 bands also carry case-mix variance): must-catch recall 54%-86% (sd 10%), verdict agreement 75%-100% (sd 9%), noise (unmatched posted) 50%-60% (sd 3%), judge mean quality 82%-86% (sd 2%). A single-run delta whose arms both sit inside a band is indistinguishable from run-to-run wobble; use --repeats to resolve smaller effects.

… in attribution footers; make the bare-sub strip targeted

Review feedback on #350:
- A merged copy's model-authored subject is now HTML-escaped before
  interpolation, so a literal </details> cannot close the collapsed
  block early or truncate stripFooters.
- stripFooters no longer blanket-deletes every <sub> span: it removes
  only the two posted shapes (whole-line version-footer spans and
  end-of-line parenthesized source tags), so prose quoting <sub>
  survives similarity comparison.
- Pin the pr-level fold attribution footer and both hold-comment
  source tags in tests.
@jwbron

jwbron commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the review feedback in e73f5c2:

  • attribution.ts:59 (unescaped subject): a merged copy's subject is now HTML-escaped before interpolation, so a literal </details> cannot close the block early or truncate stripFooters. Test added.
  • attribution.ts:104 (blanket sub strip): stripFooters now removes only the two posted shapes (whole-line version-footer spans, end-of-line parenthesized source tags); a quoted <sub> span mid-prose survives. Tests added.
  • submission.ts:533 (pr-level fold footer untested): the fold test now pins the full collapsed footer, including an also_flagged_by entry.
  • submission.ts:646 (hold sourceTag untested): both hold-path folds (anchored line and blocking-only pr-level line) now assert the source tag.
  • dedup.ts:304 (suppression asymmetry): agreed and leaving as is; previously posted comments keep the in-discussion note, and suppression tokenizes both sides after stripFooters, so the asymmetry only spans the transition window between releases. No code change.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved — no blocking issues found.
4 of 5 prior review threads resolved; 1 still unaddressed as of e73f5c2:

1 non-blocking thread still open
  • thought (non-blocking) workflows/review/lib/dedup.ts:304: Moving the merge note out of discussion makes open-thread suppression asymmetric against old posted comments. `openThr...
Note: correctness-reviewer not assessed this run (correctness-reviewer output unavailable). Note: first-principles not assessed this run (first-principles output unavailable). Note: re-review ran at scoped depth (re-review mode scoped, blocking-only).

@jwbron
jwbron merged commit 18bba4c into main Aug 18, 2026
10 of 11 checks passed
@jwbron
jwbron deleted the jwies/review-attribution-footers branch August 18, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants