Repository navigation
Make the review cards shorter, quieter, and easier to act on - #21908
Conversation
… card The author action guide ran past a full screen even when nothing blocked merge: the resolved table (long verbatim claim cells) and the worked-example footer pushed the open items out of view. Reader feedback from #docs (2026-09-22, 2026-09-25) asked for both to fold. - ✅ Resolved since last review renders its table inside a <details> whose summary counts the rows. One helper (compose-review.render_resolved_block) serves both apply-update paths: first-resolve insertion and re-render, so a refresh rebuilds a single fold rather than nesting. The H3 stays outside the fold since every parser anchors on it. - The How-to-answer footer is collapsed. The one reply shape an author must get right (`@claude F1: … #update-review`, tag required) moves into the IMPORTANT callout, which is the part of the card everyone reads, so folding the examples doesn't hide the instruction. Brief and evidence output are byte-identical; the v3 author fixture is regenerated. New test pins the fold across two resolves and checks both row walkers still see the rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz
Sentinel — merge gate status (preview)Warning
|
| Gate | What it needs | |
|---|---|---|
| ✅ | G1 review-ran | Nothing to do: review current at 62384bf30. |
| ✅ | G2 findings-answered | Nothing to do: every finding answered. |
| 🔴 | G3 right-approver | Needs approval from a member of any review team (pulumi/docs-blog-review, pulumi/docs-guild, pulumi/docs-marketing-review, pulumi/docs-tools) or a repository administrator — no qualifying human approval at this head (bot approvals never count). |
| ➖ | G4 infra-evidence | Doesn't apply to this PR: no changed path affects the deploy. |
| ➖ | G5 oversized-ack | Doesn't apply to this PR: not oversized. |
Break glass: a member of a routing team (.github/review-routing.yml teams:) can apply review:waived, which is logged.
Evaluated at head 62384bf30.
|
Your site preview for commit 62384bf is ready! 🎉 http://www-testing-pulumi-docs-origin-pr-21908-62384bf3.s3-website.us-west-2.amazonaws.com |
A successful #update-review / #new-review ended with a fresh "🤖 Review updated on @x's request." comment, and an auto-refresh with "🤖 Review auto-refreshed …". On a busy PR these stacked up (six on #21871) and buried the cards and the re-request button. On success the spinner is still deleted, and the requesting comment now gets a 🚀 reaction (ack-request.sh). Auto-refresh success is silent: the cleared 🔄 banner and the card's new stamp already say it. Failures keep their @-mention comment, since those need action. ack-request.sh falls back to the old comment when there is nothing to react to (a submitted review body, a manual dispatch) or the reaction call fails. The #new-review lane is dispatched, so the triggering comment travels as a new `ack_target` input, passed by claude-new.yml, the update lane's retry path, and the redispatch job. Lanes that run scripts from the PR head guard on the helper existing, so branches cut before this change keep today's behavior. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz
The italic one-sentence summary is written once at v1 and carried verbatim through every refresh. When the model put live state in it, it went stale: #21871's card was headed "nothing blocks merge" and still opened by naming four claims "only you can confirm". - Prevent: the compose TODO now says no open-item counts and nothing only the author can answer, since the header and sections carry the live state. - Repair: the update patch takes an optional top-level `summary` (one line, ≤300 chars) that apply-update swaps in for the sentence (or inserts under the callout when a card has none). The prompt and update.md tell the model to send it when the current sentence names open items that its actions change, and to omit it otherwise. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz
A nothing-blocks card opened with a NOTE saying there was nothing to do, then spent eight lines on two headed sections each saying "nothing here". build-evidence.drop_empty_author_sections removes both sections when every line in them is the empty placeholder. It runs at initial publish and after every update-lane render. It is strict: any row, bullet, or other text keeps both, and "nothing blocks" is not the test, because a /resolve'd row stays in its section with a disposition. The composer still emits the sections (the model's anchor for added rows). ensure_author_sections puts the pair back before the update lane places a reopened, added, or promoted row. validate-pinned's section-order rule accepts the pair missing together, never one alone. Both helpers match headings line-anchored: the composer's TODO stubs quote "### 🚨 Fix or disagree" in finding text, which fooled a substring check during testing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz
A 🚨/❓ row quoted its claim (up to 160 chars) plus the verifier's framing note in the table cell. The Do-this block right under the table then quoted the line verbatim and explained the same problem in its Why bullet. On #21871 that doubled every finding. - An author-card cell for a claim verdict now carries a ≤90-char excerpt plus the verdict: enough to say which claim, since the block has the full line (compose-review.author_cell_bullet). Detector and style-blocker rows keep their full message, which is the finding. - The framing note moves out of the cell into the Why TODO as material to write from, so the author reads the reason once, in prose. - The brief's⚠️ rows are unchanged; they have no block to lean on. - normalize-v3-draft's fallback block prefers the evidence record's claim text over the cell's excerpt for "Line (verbatim)". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz
Non-binding Vale suggestions posted as inline review comments cluttered the Files-changed view and sat between the human review comments (reader feedback, 2026-09-22). The style block on the card is the complete record; the inline copy was the noisy part. Both lanes now post advisory suggestions only when the repo variable REVIEW_STYLE_INLINE is '1'. When it's off, the poster still runs with an explicit empty sidecar. The script already treats that as authoritative: it deletes buttons an earlier run posted and strips the ✏️ marks and banner, so open PRs clean up on their next review. The caption's "✏️ marks one you can apply …" legend is now written only when a mark is actually on the page. The composer's caption is unchanged (it can't know yet), and the annotator reconciles it either way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz
Guin read the social review's "X" section as a request she couldn't fulfil (no work social account), and a post with no social block got three identical "— missing" sections plus a screenful of drafted copy. - CI reviews open with a one-line NOTE: Pulumi's accounts post the copy after the blog goes live, and only a character-limit FAIL fails a check. - When every platform is missing, one line replaces the three headings. - Suggested copy and advisory notes are collapsed in <details> with a count in the summary. The apply/re-run CTA stays visible. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz
Heading emoji mark state (🚨 ❓⚠️ ✅). 📎 on the "Full evidence" line and 💡 on the brief's pre-existing count line marked nothing, so both go: "**Full evidence:** …" and "**Pre-existing issues in touched files:** N — …". Cards published before this change still carry the old prefixes, and the update lane refreshes them in place, so every reader keyed on those lines accepts both forms: the section terminators (build-evidence, normalize-v3-draft, validate-pinned), the evidence-URL rewrite and Resolved-section insertion anchor (apply-update), the pre-existing recount, validate-pinned's v3-evidence-link rule, and review-v3/collect.py's rubber-stamp span. build-evidence's self-test fixtures keep the legacy form as backward-compat coverage, and set_evidence_url is tested on both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz
Readers asked for inline, applyable suggestions for what they have to fix (Julien, 2026-09-25), and for the optional nags to leave the Files view (previous commit). This adds the first half. post-style-suggestions.py --fixes-from-author-card <card> derives suggestions deterministically from the v3 author card's 🚨 rows, with no model sidecar. A row qualifies when it's anchored to one line and its Do-this block quotes text that occurs literally on exactly one line of the anchor, with exactly one single-line fenced replacement. The fence is spliced into the quoted span, so indentation outside it survives. Findings on the same line merge into one suggestion; a later one whose quote no longer matches is skipped. ❓ rows (proposals awaiting an answer), findings already answered in REVIEW_STATE, multi-line fences, and multi-fence blocks are skipped. A corrupt state block posts nothing. These rules come from 18 live Do-this blocks sampled across 8 PRs: the fence replaced exactly the quote in 8 of 10 🚨 blocks. It reuses the style poster's validation (PR-added line, literal match on the checked-out file) and posting (atomic batch with per-comment fallback) under its own marker, so the two sets never touch. The unchanged-set short-circuit now also covers a subset: when a fix lands, its comment is deleted and the survivors stay live, with no new (undeletable) review event. Wired after the v3 build (initial lane) and after the v3 publish (update lane), best-effort. The Do-this Fix TODO and output-format.md now tell the model the fence shape that qualifies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz
Running fix-mode derivation against the live author card of #21645, with files checked out at its merge commit, produced one wrong suggestion. F4 quoted a whole three-sentence bullet but fenced only its rewritten last sentence, so splicing the fence into the quoted span would have deleted the first two sentences. For a quote of 80+ chars, a fence under 60% of the quote's length is now skipped as a partial rewrite. On that card the whole-quote rewrites ran 87-95% of the quote's length; F4 was 36%. Phrase-level quotes are unaffected. Result on that card: F2 and F3 post; F4 (partial), F9 (multi-line), F5 (same line as F2, conflicting fence), and F22-F24 (no Do-this block) are skipped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz
1. HIGH: the unprefixed `**Full evidence:**` line matches FINDING_START_RE. Under ✅ Resolved, the paragraph walk read it as a finding and swallowed the REVIEW_STATE block behind it, so a hold reason containing "conceding" tripped outcome-annotation-shape and failed the update lane's publish. extract_bucket_bullets, _finding_paragraphs, and scrape-review-outcomes' paragraph walk now stop at card furniture (validate-pinned.is_card_furniture). 2. Fix mode could post corrupting splices whenever the fence and the quote covered different spans: a whole-line fence against a phrase quote, a one-sentence fence against a short whole-line quote, a list marker on one side only, or a line that is itself a quoted string. _span_mismatch now skips each of those with a reason, and a fence that keeps the quote's wrapper matches it as written. The real #21645 card still posts F2 and F3. 3. An optional `summary` sent as "", null, or the prompt's placeholder failed the refresh. normalize_update now drops all three, and the prompt's envelope no longer shows a copyable placeholder. 4. A kept fix comment could name stale F-ids after a re-review renumbered them. In fix mode the comment's header is now part of its identity. 5. Fix mode matched lines on the checkout but posted against the live head. It now posts nothing when the head has moved; the next refresh posts against the new head. Each has a regression test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz
|
@claude #new-review The
62b137e documents the gotcha in Generated by Claude Code |
|
🤖 Review regenerated on @CamSoper's request. |
A requested refresh still cost the timeline a transient "Working on it"
comment, and #new-review two ("regenerating from scratch" plus the
initial lane's spinner). Each notified every PR subscriber even though
it was deleted minutes later.
Requested runs now put a 👀 on the comment that asked for them
(ack-request.sh --start) and swap it for 🚀 when the card lands, so a
successful refresh or regenerate leaves no bot comment at all. Failures
clear the 👀 and comment back to the requester by @-mention. An
auto-refresh posts nothing in flight: the card's 🔄 banner already says
it. A ready-transition, a review-body mention, or a failed reaction
keeps the spinner comment as the fallback.
review-label-reconcile.yml counts a github-actions[bot] 👀 on a PR
comment as a live run, so a long requested review isn't swept to
review:stale for lacking a spinner.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz
|
@claude #new-review (Fresh review for the 👀 → 🚀 commit. Generated by Claude Code |
Reviewer's guide v1 — not for the authorTip This is the reviewer's guide. Work through the PR author: your to-do list is the other review comment, "Author action guide" — nothing on this card is yours. Approval needed from: @pulumi/docs-tools — any member's approval satisfies the merge gate. Note What this PR changes:
The risk is workflow or script logic that breaks review posting or merge-gating on every PR. Claim verification and the pre-computed mechanics checks ran; the script and workflow logic was not read line by line. Review confidence:
|
Author action guide v1 — nothing blocks mergeNote Nothing here blocks merge — no open items need an answer from you. A human reviewer still approves the merge. This PR reworks the v3 review cards, style-suggestion posting, and review workflows; the review checked the one factual claim and the pre-computed mechanics; it did not do a line-by-line read of the script and workflow logic. Full evidence: verification trail, investigation log, review history. Review v1 · updated 2026-09-25T23:16:07Z · head commit 62384bf How to answer — fix it, disagree with it, or accept it as-is (click for the exact replies)Every 🚨 and ❓ item above needs one of these before merge:
The Full mechanics: CONTRIBUTING.md §AI-assisted contributions. Please don't edit, hide, or delete this comment — it is the review's record. |
|
🤖 Review regenerated on @CamSoper's request. |
The update lane's progress step and the initial lane's claude-review job check out the PR head, so they ran the PR's copy of ack-request.sh. Every branch cut before #21908 has no copy, so those PRs silently fell back to the "Working on it" / "Reviewing" spinner comment instead of the 👀. Observed on #21760 right after the merge: both #update-review and #new-review posted a spinner (then cleaned up and ended on 🚀). Fetch the helper from the default branch into $RUNNER_TEMP instead. The spinner stays as the fallback if the fetch fails. Claude-Session: https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
- normalize-v3-draft.py: drop a model-written F? detail block (#21892), restore a deleted empty 🚨/❓ section and a deleted composed finding (#21885). Both captured drafts are now regression fixtures. - apply-update.py: map the card's own bucket words ('blocking') to the closed set (#21761); treat resolve/concede on an already-resolved id as a no-op (concurrent refresh, #21614) and drop actions on ids the card never had (#21785) instead of failing the refresh. - claude-update.yml: run the deterministic publish chain from the default branch, not the PR head (#21908's own half-finished validator refused master's cards); list the add buckets in the prompt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GtKzf3eR8238vqCLcc1qZt
- normalize-v3-draft.py: drop a model-written F? detail block (#21892), restore a deleted empty 🚨/❓ section and a deleted composed finding (#21885). Both captured drafts are now regression fixtures. - apply-update.py: map the card's own bucket words ('blocking') to the closed set (#21761); treat resolve/concede on an already-resolved id as a no-op (concurrent refresh, #21614) and drop actions on ids the card never had (#21785) instead of failing the refresh. - claude-update.yml: run the deterministic publish chain from the default branch, not the PR head (#21908's own half-finished validator refused master's cards); list the add buckets in the prompt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GtKzf3eR8238vqCLcc1qZt
…aps, and id reuse (#21948) * Review loop: fix dropped #new-review, REVIEW_STATE gaps, id reuse, legacy card picks - claude-new.yml: trust the same bots as the other lanes (workprentice's #new-review was silently dropped), read permissions with gh api, and say so on the PR when a request is declined. A sanity test keeps the four allowlists identical. - apply-update.py: concede records not-applicable, and every refresh backfills a disposition for any resolved row that lacks one. - compose-review.py: finding ids continue above the previous review's high_water instead of restarting at F1. - pinned-comment.sh: a v3 author card beats a legacy 1/1 monolith; new prune-legacy subcommand. - sentinel.py: read legacy pages posted by pulumi-bot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GtKzf3eR8238vqCLcc1qZt * Review loop: carry reviews across base merges, un-stale current reviews, fix Sentinel PR resolution - restamp-base-merge.py: a base-only merge with an unchanged diff moves the v3 card's head carriers instead of staling the review (mark-stale and the reconcile cron both use it). - review-label-reconcile.yml: read the v3 card (the legacy monolith on #21066 re-staled it every two hours), and add the missing un-stale pass. - sentinel.py: G2 no longer calls a stale card 'every finding answered'; G1 stops advising a push that refreshes nothing; reads retry a 5xx. - review-sentinel.yml: trust workflow_run.pull_requests only for a pull_request run at that head (every other run evaluated #2), and refuse to publish a check-run with no head SHA. - Both lanes delete earlier 'Review errored' notices once a review lands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GtKzf3eR8238vqCLcc1qZt * Review loop: stop losing whole reviews to mechanical slips - normalize-v3-draft.py: drop a model-written F? detail block (#21892), restore a deleted empty 🚨/❓ section and a deleted composed finding (#21885). Both captured drafts are now regression fixtures. - apply-update.py: map the card's own bucket words ('blocking') to the closed set (#21761); treat resolve/concede on an already-resolved id as a no-op (concurrent refresh, #21614) and drop actions on ids the card never had (#21785) instead of failing the refresh. - claude-update.yml: run the deterministic publish chain from the default branch, not the PR head (#21908's own half-finished validator refused master's cards); list the add buckets in the prompt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GtKzf3eR8238vqCLcc1qZt * Review loop: stale briefs, oversized definition, triage file counts, cleanup script - apply-update.py: a refresh drops 'What this PR changes' bullets for files that left the PR, settles review-confidence notes that point at resolved findings or an empty list, and removes a summary naming open work under 'nothing blocks merge' (#21801, #21798, #21790). - One definition of oversized: triage-classify.is_oversized, which the Sentinel now computes from the PR instead of racing triage's label (#21936). Triage reads the paginated file list and changedFiles, so the 150-file axis and the '1,156 files' count work. - review-sentinel.yml: name the job so it can't pass for the gate. - cleanup-review-leftovers.py: dry-run sweep for the stale labels, errored notices, legacy pages and stray status comment already on PRs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GtKzf3eR8238vqCLcc1qZt * Pass --prior-high-water only to a composer that knows it The compose step runs the PR head's compose-review.py, so a branch cut before the flag existed would reject it and error its review. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GtKzf3eR8238vqCLcc1qZt * Collapse an emptied⚠️ table even with the hand-off hint beside it This PR's own v1 brief showed a header-only⚠️ table under 'Check the⚠️ items, then approve': the model filed both rows off, and the '_Not your area?_' hint the composer puts beside rows kept the section from reading as empty. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GtKzf3eR8238vqCLcc1qZt * Review loop: fix the adversarial review's findings on #21948 - Triage: merge the paginated file list via --slurpfile (new with-pr-files.sh). `jq --argjson` over ~1,000 files overflowed MAX_ARG_STRLEN, so triage went green without review:oversized. - #new-review ids: the redispatch job forwards prior_high_water, and a forced run that fails after its card was cleared carries the mark on its failure notice (<!-- REVIEW_HIGH_WATER n -->), which the composer and claude-new read back. - Reconcile cron: actions: write and a Sentinel dispatch after each restamp or un-stale. - apply-update: prune only file-looking change bullets inside "What this PR changes"; narrow _OPEN_WORK_RE to asks addressed to the author. - Sentinel: review:oversized is the label again, not size, so approved PRs don't flip; triage re-dispatches the Sentinel when it moves review:oversized or review:trivial (#21936's race). - restamp-base-merge: re-read the card before PATCH; a patchless file must keep its blob sha. - cleanup-review-leftovers: age notices against the card's composition stamp and the notice's own edit time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cni84G1WNvPbAZ5BwqaLXJ * Review loop: tighten the high-water reader, summary check, and file names Follow-up to the verification pass on 6b32a93: - Read REVIEW_HIGH_WATER only from CLAUDE_PROGRESS failure notices. Cards and triage prose can quote PR text, so a quoted marker could inflate ids. - _OPEN_WORK_RE no longer matches bare "you need/must/have to", which a docs PR's summary uses about the page's reader. - A scoped package lead (`@pulumi/aws`) isn't a path, so it's not pruned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cni84G1WNvPbAZ5BwqaLXJ * Review loop: fix blast-radius findings on the rebased branch - Drop the Sentinel job's display name. /pr-review filters the job by "sentinel", so the rename made every stamp preflight wait on it. - On a push, flag a not-yet-labelled PR as oversized by the line axis only. The paginated file count made the 150-file axis reachable, which would have flipped open PRs already reviewed under the normal gates. The classifier reports `oversized_by_lines` for this. - apply-update: keep site-URL and renamed-file change bullets (the file list now carries previous_filename), and drop a summary only when it asks the author about a counted set of items and isn't negated. - Page the PR file listings 100 at a time. - mark-stale's restamp step no-ops on a base branch that predates the script (stacked PRs) instead of erroring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cni84G1WNvPbAZ5BwqaLXJ --------- Co-authored-by: Claude <noreply@anthropic.com>
Proposed changes
Reader feedback from #docs (Julien and Ian on 2026-09-25, Guin on 2026-09-22 and 2026-08-28) comes down to three complaints: the author card doesn't fit on a screen, the PR timeline is noisy, and optional bot output reads like a list of demands. This PR works on all three while keeping the must-do instructions in view. Each commit covers one item.
Author card
✅ Resolved since last review(the row count stays in the summary) and the How to answer footer. The one reply format authors have to get right,@claude F1: … #update-reviewwith the tag required, moves into the IMPORTANT callout at the top, which is always visible.summaryfield, and the initial review no longer puts live counts in it. This is the Add blog post about component state migrations #21871 bug, where a card headed "nothing blocks merge" still said four claims were "only you can confirm".Timeline and Files view
#update-reviewand#new-reviewput a 👀 on the requesting comment while they work and swap it for a 🚀 when the card lands. Before this, a successful refresh posted and deleted a "Working on it" spinner and then posted "🤖 Review updated on @x's request".#new-reviewposted a "regenerating from scratch" comment and a spinner. Every one of those notified all PR subscribers. Failures clear the 👀 and post a comment that @-mentions the requester. An auto-refresh posts nothing while it runs, because the card's 🔄 banner already says it's running. A ready-transition, a review-body mention, or a failed reaction still falls back to the spinner comment.review-label-reconcile.ymlcounts the bot's 👀 as a live run, so a long requested review isn't swept toreview:stale.REVIEW_STYLE_INLINErepo variable is1. When it's off, the next review clears existing advisory buttons and removes the ✏️ markers.Social review
Testing
make test-review-pipelinepasses. New tests cover each change, the five issues an adversarial review of this branch turned up (commit 39ad8e2), and a fix-mode bug I caught by running it against the live Add the agentic infrastructure operating model whitepaper #21645 card.#update-reviewwent 👀 → 🚀 in about 5 minutes and#new-reviewin about 7. Neither added a comment at any point: the timeline was polled every 15 seconds. Both runs succeeded, and the cards and label were updated.Not covered live:
Related issues (optional)
Motivating PR: #21871.
🤖 Generated with Claude Code
https://claude.ai/code/session_01GKHS8qr1o8N7QkAdtHyWPz