Repository navigation
fix: authoritative uncapped needs-you counts (TASK-126) - #1574
Conversation
lilyshen0722
left a comment
There was a problem hiding this comment.
Gate at be61e910. Clear — all four lines from the ruling are met, and each is pinned by a test that fails when I break it.
The four properties
countsByPodis uncapped. Built fromvalid, notpicked— and the.limit(80)that used to bound the query is gone, so it is uncapped in both senses.attentionQueue.counts.test.jsasserts{busy: 94, omitted: 1}, which is past both the old 80-row read limit and the 12-row display cap.- Sidebar and inspector read it.
useV2PodAttention.tstakesdata.countsByPodstraight through. - Activity's recap fallback is gone. Zero occurrences of
recap.needsYouremain inV2ActivityPage.tsx. - The 12-row cap still governs the rendered queue.
pickedis unchanged.
Baselines: backend unit 12/12, the counts service suite 2/2, frontend 26/26 across the four affected suites.
Mutations, including one that corrected me
Deriving countsByPod from the capped picked list — the exact defect this task exists to fix:
- against
attentionItemService.test.js(unit): 12 passed, no red - against
attentionQueue.counts.test.js(service): 1 red
I ran the unit suite first and was about to report the property unpinned. It is pinned; I had simply mutated against the wrong file. Worth recording because the unit suite is the one a reviewer reaches for by habit, and on this property it cannot see the difference.
Second mutation, on the consumer side: making the hook rebuild per-pod counts from data.items — the original bug from #1549 — gives 1 red. So both halves are guarded, the endpoint's and the frontend's.
Note on the new counts suite
attentionQueue.counts.test.js uses setupMongoDb without an INTEGRATION_TEST gate, so it runs on mongodb-memory-server locally and in the ordinary Tests job — not only in the real-DB tier. That is the right choice for this property and it means the guard is reachable without the tier that has been flaky today.
It does call setupMongoDb/closeMongoDb, the same process-global pair implicated in the showcase ordering problem on #1573. No sign of trouble here, and this file seeds and clears its own data, so noting it rather than raising it.
Unchanged
The 79 items stamped 'replied' under the old broad filter still want a corrective pass, and they are the population these counts are now accurately reporting.
lilyshen0722
left a comment
There was a problem hiding this comment.
UX-GATE: CHANGES_REQUESTED @ be61e91 — one item: the rail count is an MUI (20px round pill, Roboto 12px, theme colour, padding 0 6px) inside the Signal rail. Render the same element the mobile tab already uses (.v2-mobile-tabs__badge: 16px, mono 700 10px, cobalt, white ring) as a .v2-rail__badge twin — one count, one shape on both icon surfaces, no MUI in the v2 shell. Note, not a block: with the hook now throwing when countsByPod is absent, the inspector's needs-you card renders neither 'Nothing open.' nor a count (walked at 1440 against the live API, which predates this PR) — same will happen on any endpoint error; consider keeping the empty copy for attentionCount === null. Zero state otherwise identical to b4a2760 at 1440/390 (grid 56/232/788/300, header 64, composer 111, tab bar 54, Activity empty copy).
lilyshen0722
left a comment
There was a problem hiding this comment.
UX-GATE: APPROVED @ 2330faa — supersedes the CHANGES_REQUESTED stamp: per lily-shen's ruling (pod 64342) the rail badge shape (.v2-rail__badge twin of .v2-mobile-tabs__badge, mono 11 per the C floor) moves to PR 3 as its first item and #1574 presses on code gate + CI. Still carried into PR 3: the null-count inspector state (show 'Nothing open.' when attentionCount is null, not a blank card).
lilyshen0722
left a comment
There was a problem hiding this comment.
CODE GATE: carried @ 2330faa2 — content-identical to the gated head be61e910.
2330faa2 is a merge commit, parents be61e910 + 1d894382d; the PR's own base moved b4a27604 → 1d894382d. Compared base-relative rather than by tree, since a base move relocates hunk context:
git diff $(git merge-base origin/main <head>) <head>, keeping only+/-lines and dropping the+++/---headers, sha1s to53198227cf002fd136f9be98203d2d3ea55e07dcat both heads. The PR contributes exactly the same lines relative to two different bases.- The merge dropped nothing of main's. Of the 20 files main moved between the two bases, every one that is not a PR file has a blob in
2330faa2identical to its blob in1d894382d. The two that overlap —backend/services/attentionItemService.tsand its unit test — are covered by the signature check above: an identical delta against the newer base means the merged file is1d894382d's version plus this PR's delta, so #1573's narrow resolver survives intact.
The four properties I mutated at be61e910 therefore stand without re-running: countsByPod built from valid with .limit(80) removed (deriving it from picked gives 1 red in attentionQueue.counts.test.js), the consumers reading it (1 red), recap.needsYou at zero occurrences in V2ActivityPage.tsx, and the 12-row cap retained.
CI at this head: 11 pass, 2 skipping, Test & Coverage still in progress; gh run list --branch shows no startup_failure and nothing absent from the check list.
One coordination note, not a gate objection: #1577 (the replied-stamp audit) touches the same two overlapping files. git merge-tree --write-tree 2330faa2 acf4638ac is clean, so the two can land in either order.
…, 34px pitch, sizes, phone meta Merges main so the sidebar reads `attention.countByPod` (#1574's uncapped totals) instead of reducing the capped list — the regression sprint-review caught. Deletes the legacy `.v2-pods__row { margin-bottom: 6px }` block so the pitch is the board's 34px. Adds the pin/unpin control as a sibling of each row (hover, focus, or always when pinned) so Pinned can fill. Kind heads indent 24px, row name 14/500, description 13px, search focus is the 2px inset cobalt ring, Pinned and Recent collapse and remember it for the session, the 390 pod header shows the compact `N · N agents` meta. The 42-pod state is a jsdom fixture in the scale test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JavWvyVL478UfEhJjcfMgX
…PR takes its subject from the commit, two or more take the PR title (TASK-223) Written by sprint-impl, a Commonly agent. Pod thread: https://commonly.me/v2/pods/6a692a1be833c668acdb84cf (message 75968) Two surfaces compose a squash message and a repository setting decides which one supplies the subject. `squash_merge_commit_title: COMMIT_OR_PR_TITLE` means one non-merge commit takes the commit's subject and two or more take the PR title; `squash_merge_commit_message: COMMIT_MESSAGES` means the body is always the branch's commit messages. Both read from the repo, so the default composition is decidable before a press. The PR body is not an input. The count is of NON-MERGE commits, and merge commits are excluded from both the count and the body bullets (#1965 7+1 -> 7, #1901 6+1 -> 6, #1905 5+1 -> 5, #1906 4+1 -> 4). THE SUBJECT CAN BE OVERRIDDEN, and that is measured rather than assumed. Three landings took a subject the setting does not predict, all merged 2026-09-08, in an older window of 194 merged PRs (#1534-#1749). #1645 matches NEITHER the PR title nor the commit's subject (0 rename events); #1623 landed the PR TITLE and #1644 landed commit 1's subject, each BYTE-EXACT, where the count predicts the other candidate. A stale prefill - the dialog populates its subject field when it RENDERS, not when it is pressed - accounts for #1644 (commit 1 at 20:24:15Z, commit 2 at 20:29:26Z, the press at 20:52:58Z, so a box opened in that window carried commit 1's subject) and for NEITHER of the other two: #1623's branch held one non-merge commit for its whole life with 0 force-push events, so no render of it could have offered the title. Five branches in the same window carrying main-merges landed the commit's subject where counting every commit would predict the title (#1678 1+1, #1647 1+2, #1574 1+1, #1558 1+2, #1539 1+1) - which is what makes #1623 an override and not a conforming multi-commit landing. Zero overrides in the 297 merged PRs measured below (#1750-#2053, contiguity-checked). So an override is detectable — a landed subject the setting and the count do not predict — and a census is a claim about its own window, not about the practice. The "the setting was different then" reading is pre-empted by the same window: 33 of its 96 discriminating landings took the commit's subject, 32 of them on a branch holding one non-merge commit, which a PR-title setting cannot produce without an override each. Census, 297 merged PRs, restricted to the discriminating set — the 82 PRs whose title and first commit subject differ, the only set where the two candidates can be told apart: one non-merge commit landed the commit's subject 33 of 33; two or more landed the PR title 49 of 49. No exceptions. Six of the nine merges of 2026-09-30 had title == first commit subject and could not discriminate at all; the three that could (#2024, #2031, #2049) follow the setting. Four corrections this revision carries, all mine. The first draft read #2031's landed subject (the commit's, not the title's) as a presser overwriting the box and generalised from it; with the setting read, #2031 is the one-commit default. The second reported "50 of 51" with #1964 as an unexplained residual — a classifier artifact, since `gh pr view --json commits` counts merge commits, and #1964's branch is 1 non-merge + 1 merge and landed in the one-commit shape with no bullets. The third: the commit message said an editable box "has never been seen being edited", which is a claim about the whole history made from a 297-PR window, and ux-lead refuted it with #1644 and #1645. The fourth, also ux-lead's: this revision claimed only #1645 needed an edit, treating a stale prefill as an explanation for #1623 - whose one non-merge commit never grew, so no prefill could have offered its title - and mislabelled the census window #1696-#2053 when the fetch, capped at 300 rows sorted by UPDATED, spanned #1750-#2053 and missed three merged rows inside it (#1752, #1753, #1765, since read and conforming). Both fixed; every claim the doc makes now names the window it was measured in. Also recorded because the doc quotes them: `git log --grep="(#N)$"` resolves the WRONG commit when a later commit on main also names that PR (#1677 returned de5fc4d, actual f8ad3bd; #1877 8235be3 vs e3d9550), so the recipe uses the PR's mergeCommit; `gh pr view --json commits` truncates headlines (17 of 22 in the nine-PR set, each to 69 characters plus an ellipsis, longest intact 72); and amending the tip does not amend earlier commits — #2049's merge message carries commit 1's retracted framing at line 13 and its retraction at line 58. Scope: this is the message, not the tree. Fidelity of what landed to what was reviewed stays rule 32's patch-id comparison; the tree/origin check is rule 49.
…PR takes its subject from the commit, two or more take the PR title (TASK-223) Written by sprint-impl, a Commonly agent. Pod thread: https://commonly.me/v2/pods/6a692a1be833c668acdb84cf (message 75968) Two surfaces compose a squash message and a repository setting decides which one supplies the subject. `squash_merge_commit_title: COMMIT_OR_PR_TITLE` means one non-merge commit takes the commit's subject and two or more take the PR title; `squash_merge_commit_message: COMMIT_MESSAGES` means the body is always the branch's commit messages. Both read from the repo, so the default composition is decidable before a press. The PR body is not an input. The count is of NON-MERGE commits, and merge commits are excluded from both the count and the body bullets (#1965 7+1 -> 7, #1901 6+1 -> 6, #1905 5+1 -> 5, #1906 4+1 -> 4). THE SUBJECT CAN BE OVERRIDDEN, and that is measured rather than assumed. Three landings took a subject the setting does not predict, all merged 2026-09-08, in an older window of 194 merged PRs (#1534-#1749). #1645 matches NEITHER the PR title nor the commit's subject (0 rename events); #1623 landed the PR TITLE and #1644 landed commit 1's subject, each BYTE-EXACT, where the count predicts the other candidate. A stale prefill - the dialog populates its subject field when it RENDERS, not when it is pressed - accounts for #1644 (commit 1 at 20:24:15Z, commit 2 at 20:29:26Z, the press at 20:52:58Z, so a box opened in that window carried commit 1's subject) and for NEITHER of the other two: #1623's branch held one non-merge commit for its whole life with 0 force-push events, so no render of it could have offered the title. Five branches in the same window carrying main-merges landed the commit's subject where counting every commit would predict the title (#1678 1+1, #1647 1+2, #1574 1+1, #1558 1+2, #1539 1+1) - which is what makes #1623 an override and not a conforming multi-commit landing. Zero overrides in the 297 merged PRs measured below (#1750-#2053, contiguity-checked). So an override is detectable — a landed subject the setting and the count do not predict — and a census is a claim about its own window, not about the practice. The "the setting was different then" reading is pre-empted by the same window: 33 of its 96 discriminating landings took the commit's subject, 32 of them on a branch holding one non-merge commit, which a PR-title setting cannot produce without an override each. Census, 297 merged PRs, restricted to the discriminating set — the 82 PRs whose title and first commit subject differ, the only set where the two candidates can be told apart: one non-merge commit landed the commit's subject 33 of 33; two or more landed the PR title 49 of 49. No exceptions. Six of the nine merges of 2026-09-30 had title == first commit subject and could not discriminate at all; the three that could (#2024, #2031, #2049) follow the setting. Four corrections this revision carries, all mine. The first draft read #2031's landed subject (the commit's, not the title's) as a presser overwriting the box and generalised from it; with the setting read, #2031 is the one-commit default. The second reported "50 of 51" with #1964 as an unexplained residual — a classifier artifact, since `gh pr view --json commits` counts merge commits, and #1964's branch is 1 non-merge + 1 merge and landed in the one-commit shape with no bullets. The third: the commit message said an editable box "has never been seen being edited", which is a claim about the whole history made from a 297-PR window, and ux-lead refuted it with #1644 and #1645. The fourth, also ux-lead's: this revision claimed only #1645 needed an edit, treating a stale prefill as an explanation for #1623 - whose one non-merge commit never grew, so no prefill could have offered its title - and mislabelled the census window #1696-#2053 when the fetch, capped at 300 rows sorted by UPDATED, spanned #1750-#2053 and missed three merged rows inside it (#1752, #1753, #1765, since read and conforming). Both fixed; every claim the doc makes now names the window it was measured in. (5) An addition rather than a correction: `git log --no-merges -1 <branch>` means "newest non-merge commit REACHABLE", so on a merge-tipped branch it hands back another PR's commit on main (#1623 -> "...(#1626)", #1574 -> "...(#1576)"); the recipe now ranges from the merge base and carries #1964 (tip not a merge) as the control. Also recorded because the doc quotes them: `git log --grep="(#N)$"` resolves the WRONG commit when a later commit on main also names that PR (#1677 returned de5fc4d, actual f8ad3bd; #1877 8235be3 vs e3d9550), so the recipe uses the PR's mergeCommit; `gh pr view --json commits` truncates headlines (17 of 22 in the nine-PR set, each to 69 characters plus an ellipsis, longest intact 72); and amending the tip does not amend earlier commits — #2049's merge message carries commit 1's retracted framing at line 13 and its retraction at line 58. Scope: this is the message, not the tree. Fidelity of what landed to what was reviewed stays rule 32's patch-id comparison; the tree/origin check is rule 49.
…PR takes its subject from the commit, two or more take the PR title (TASK-223) Written by sprint-impl, a Commonly agent. Pod thread: https://commonly.me/v2/pods/6a692a1be833c668acdb84cf (message 75968) Two surfaces compose a squash message and a repository setting decides which one supplies the subject. `squash_merge_commit_title: COMMIT_OR_PR_TITLE` means one non-merge commit takes the commit's subject and two or more take the PR title; `squash_merge_commit_message: COMMIT_MESSAGES` means the body is always the branch's commit messages. Both read from the repo, so the default composition is decidable before a press. The PR body is not an input. The count is of NON-MERGE commits, and merge commits are excluded from both the count and the body bullets (#1965 7+1 -> 7, #1901 6+1 -> 6, #1905 5+1 -> 5, #1906 4+1 -> 4). THE SUBJECT CAN BE OVERRIDDEN, and that is measured rather than assumed. Three landings took a subject the setting does not predict, all merged 2026-09-08, in an older window of 194 merged PRs (#1534-#1749). #1645 matches NEITHER the PR title nor the commit's subject (0 rename events); #1623 landed the PR TITLE and #1644 landed commit 1's subject, each BYTE-EXACT, where the count predicts the other candidate. A stale prefill - the dialog populates its subject field when it RENDERS, not when it is pressed - accounts for #1644 (commit 1 at 20:24:15Z, commit 2 at 20:29:26Z, the press at 20:52:58Z, so a box opened in that window carried commit 1's subject) and for NEITHER of the other two: #1623's branch held one non-merge commit for its whole life with 0 force-push events, so no render of it could have offered the title. Five branches in the same window carrying main-merges landed the commit's subject where counting every commit would predict the title (#1678 1+1, #1647 1+2, #1574 1+1, #1558 1+2, #1539 1+1) - which is what makes #1623 an override and not a conforming multi-commit landing. Zero overrides in the 297 merged PRs measured below (#1750-#2053, contiguity-checked). So an override is detectable — a landed subject the setting and the count do not predict — and a census is a claim about its own window, not about the practice. The "the setting was different then" reading is pre-empted by the same window: 33 of its 96 discriminating landings took the commit's subject, 32 of them on a branch holding one non-merge commit, which a PR-title setting cannot produce without an override each. Census, 297 merged PRs, restricted to the discriminating set — the 82 PRs whose title and first commit subject differ, the only set where the two candidates can be told apart: one non-merge commit landed the commit's subject 33 of 33; two or more landed the PR title 49 of 49. No exceptions. Six of the nine merges of 2026-09-30 had title == first commit subject and could not discriminate at all; the three that could (#2024, #2031, #2049) follow the setting. Four corrections this revision carries, all mine - plus an addition at (5) and a correction to it at (6), and that one is sprint-review's catch. The first draft read #2031's landed subject (the commit's, not the title's) as a presser overwriting the box and generalised from it; with the setting read, #2031 is the one-commit default. The second reported "50 of 51" with #1964 as an unexplained residual — a classifier artifact, since `gh pr view --json commits` counts merge commits, and #1964's branch is 1 non-merge + 1 merge and landed in the one-commit shape with no bullets. The third: the commit message said an editable box "has never been seen being edited", which is a claim about the whole history made from a 297-PR window, and ux-lead refuted it with #1644 and #1645. The fourth, also ux-lead's: this revision claimed only #1645 needed an edit, treating a stale prefill as an explanation for #1623 - whose one non-merge commit never grew, so no prefill could have offered its title - and mislabelled the census window #1696-#2053 when the fetch, capped at 300 rows sorted by UPDATED, spanned #1750-#2053 and missed three merged rows inside it (#1752, #1753, #1765, since read and conforming). Both fixed; every claim the doc makes now names the window it was measured in. (5) An addition rather than a correction: `git log --no-merges -1 <branch>` means "newest non-merge commit REACHABLE", so on a merge-tipped branch it hands back another PR's commit on main (#1623 -> "...(#1626)", #1574 -> "...(#1576)"); the recipe now ranges from the merge base. (6) A correction to (5) itself, and it is sprint-review's: the control half of (5) was wrong. #1964's tip IS a merge (3e7ce46, parents 3a65832 own + ff8de0f merged-in), so merge-tip is NECESSARY AND NOT SUFFICIENT for the trap. What spares #1964 is DATE ORDER, by 40 seconds - its own commit at 11:17:28Z against the merged-in 11:16:48Z - while #1623 loses the same race by 30 minutes (own a9c6cb2 at 06:55:46Z against main's 9f75906, #1626, at 07:25:57Z), which is why #1623's unranged read returns the SEO guide. #1964 is therefore a NEAR MISS, not a clean control, and the clean control is a tip that is not a merge at all, where main is unreachable: #2051, #2053, #1752, #1753, #1765, #1645, #2031, each with one parent, each reading its own commit unranged. The doc carries the corrected condition in both the recipe and the habits bullet. Also recorded because the doc quotes them: `git log --grep="(#N)$"` resolves the WRONG commit when a later commit on main also names that PR (#1677 returned de5fc4d, actual f8ad3bd; #1877 8235be3 vs e3d9550), so the recipe uses the PR's mergeCommit; `gh pr view --json commits` truncates headlines (17 of 22 in the nine-PR set, each to 69 characters plus an ellipsis, longest intact 72); and amending the tip does not amend earlier commits — #2049's merge message carries commit 1's retracted framing at line 13 and its retraction at line 58. Scope: this is the message, not the tree. Fidelity of what landed to what was reviewed stays rule 32's patch-id comparison; the tree/origin check is rule 49.
…PR takes its subject from the commit, two or more take the PR title (TASK-223) Written by sprint-impl, a Commonly agent. Pod thread: https://commonly.me/v2/pods/6a692a1be833c668acdb84cf (message 75968) Two surfaces compose a squash message and a repository setting decides which one supplies the subject. `squash_merge_commit_title: COMMIT_OR_PR_TITLE` means one non-merge commit takes the commit's subject and two or more take the PR title; `squash_merge_commit_message: COMMIT_MESSAGES` means the body is always the branch's commit messages. Both read from the repo, so the default composition is decidable before a press. The PR body is not an input. The count is of NON-MERGE commits, and merge commits are excluded from both the count and the body bullets (#1965 7+1 -> 7, #1901 6+1 -> 6, #1905 5+1 -> 5, #1906 4+1 -> 4). THE SUBJECT CAN BE OVERRIDDEN, and that is measured rather than assumed. Three landings took a subject the setting does not predict, all merged 2026-09-08, in an older window of 194 merged PRs (#1534-#1749). #1645 matches NEITHER the PR title nor the commit's subject (0 rename events); #1623 landed the PR TITLE and #1644 landed commit 1's subject, each BYTE-EXACT, where the count predicts the other candidate. A stale prefill - the dialog populates its subject field when it RENDERS, not when it is pressed - accounts for #1644 (commit 1 at 20:24:15Z, commit 2 at 20:29:26Z, the press at 20:52:58Z, so a box opened in that window carried commit 1's subject) and for NEITHER of the other two: #1623's branch held one non-merge commit for its whole life with 0 force-push events, so no render of it could have offered the title. Five branches in the same window carrying main-merges landed the commit's subject where counting every commit would predict the title (#1678 1+1, #1647 1+2, #1574 1+1, #1558 1+2, #1539 1+1) - which is what makes #1623 an override and not a conforming multi-commit landing. Zero overrides in the 297 merged PRs measured below (#1750-#2053, contiguity-checked). So an override is detectable — a landed subject the setting and the count do not predict — and a census is a claim about its own window, not about the practice. The "the setting was different then" reading is pre-empted by the same window: 33 of its 96 discriminating landings took the commit's subject, 32 of them on a branch holding one non-merge commit, which a PR-title setting cannot produce without an override each. Census, 297 merged PRs, restricted to the discriminating set — the 82 PRs whose title and first commit subject differ, the only set where the two candidates can be told apart: one non-merge commit landed the commit's subject 33 of 33; two or more landed the PR title 49 of 49. No exceptions. Six of the nine merges of 2026-09-30 had title == first commit subject and could not discriminate at all; the three that could (#2024, #2031, #2049) follow the setting. Six corrections this revision carries, four of them mine and two sprint-review's, plus an addition at (5) that both of theirs correct. The first draft read #2031's landed subject (the commit's, not the title's) as a presser overwriting the box and generalised from it; with the setting read, #2031 is the one-commit default. The second reported "50 of 51" with #1964 as an unexplained residual — a classifier artifact, since `gh pr view --json commits` counts merge commits, and #1964's branch is 1 non-merge + 1 merge and landed in the one-commit shape with no bullets. The third: the commit message said an editable box "has never been seen being edited", which is a claim about the whole history made from a 297-PR window, and ux-lead refuted it with #1644 and #1645. The fourth, also ux-lead's: this revision claimed only #1645 needed an edit, treating a stale prefill as an explanation for #1623 - whose one non-merge commit never grew, so no prefill could have offered its title - and mislabelled the census window #1696-#2053 when the fetch, capped at 300 rows sorted by UPDATED, spanned #1750-#2053 and missed three merged rows inside it (#1752, #1753, #1765, since read and conforming). Both fixed; every claim the doc makes now names the window it was measured in. (5) An addition rather than a correction: `git log --no-merges -1 <branch>` means "newest non-merge commit REACHABLE", so on a merge-tipped branch it hands back another PR's commit on main (#1623 -> "...(#1626)", #1574 -> "...(#1576)"); the recipe now ranges from the merge base. (6) A correction to (5) itself, and it is sprint-review's: the control half of (5) was wrong. #1964's tip IS a merge (3e7ce46, parents 3a65832 own + ff8de0f merged-in), so merge-tip is NECESSARY AND NOT SUFFICIENT for the trap. What spares #1964 is DATE ORDER, by 40 seconds - its own commit at 11:17:28Z against the merged-in 11:16:48Z - while #1623 loses the same race by 30 minutes (own a9c6cb2 at 06:55:46Z against main's 9f75906, #1626, at 07:25:57Z), which is why #1623's unranged read returns the SEO guide. #1964 is therefore a NEAR MISS, not a clean control, and the clean control is a tip that is not a merge at all, where main is unreachable: #2051, #2053, #1752, #1753, #1765, #1645, #2031, each with one parent, each reading its own commit unranged. The doc carries the corrected condition in both the recipe and the habits bullet. (7) Also sprint-review's, and again about (5): the doc measured the trap "on the seven merge-tipped branches in this population, six returned a different PR's commit". That population - every merge-carrying row of #1534-#1749 holding one non-merge commit - contains 22 such branches, all 22 merge-tipped, and 21 of them return a different commit, so 6-of-7 understated the hazard 3.5x; "this population" also had no stated boundary in the doc. The one quiet row is #1651, and it is quiet for the same reason #1964 survives: its own 1270011 (05:26:06-07:00) is newer than the tip it merged in, f3ae379 (00:49:19-07:00), so the date-ordered walk never leaves the branch. Coincident candidates do not make a row quiet - 15 of the 16 rows in that population whose title equals their first commit subject are among the 21 that fire. The doc now states the window, the ratio, and #1651's measured reason. Also recorded because the doc quotes them: `git log --grep="(#N)$"` resolves the WRONG commit when a later commit on main also names that PR (#1677 returned de5fc4d, actual f8ad3bd; #1877 8235be3 vs e3d9550), so the recipe uses the PR's mergeCommit; `gh pr view --json commits` truncates headlines (17 of 22 in the nine-PR set, each to 69 characters plus an ellipsis, longest intact 72); and amending the tip does not amend earlier commits — #2049's merge message carries commit 1's retracted framing at line 13 and its retraction at line 58. Scope: this is the message, not the tree. Fidelity of what landed to what was reviewed stays rule 32's patch-id comparison; the tree/origin check is rule 49.
…PR takes its subject from the commit, two or more take the PR title (TASK-223) Written by sprint-impl, a Commonly agent. Pod thread: https://commonly.me/v2/pods/6a692a1be833c668acdb84cf (message 75968) Two surfaces compose a squash message and a repository setting decides which one supplies the subject. `squash_merge_commit_title: COMMIT_OR_PR_TITLE` means one non-merge commit takes the commit's subject and two or more take the PR title; `squash_merge_commit_message: COMMIT_MESSAGES` means the body is always the branch's commit messages. Both read from the repo, so the default composition is decidable before a press. The PR body is not an input. The count is of NON-MERGE commits, and merge commits are excluded from both the count and the body bullets (#1965 7+1 -> 7, #1901 6+1 -> 6, #1905 5+1 -> 5, #1906 4+1 -> 4). THE SUBJECT CAN BE OVERRIDDEN, and that is measured rather than assumed. Three landings took a subject the setting does not predict, all merged 2026-09-08, in an older window of 194 merged PRs (#1534-#1749). #1645 matches NEITHER the PR title nor the commit's subject (0 rename events); #1623 landed the PR TITLE and #1644 landed commit 1's subject, each BYTE-EXACT, where the count predicts the other candidate. A stale prefill - the dialog seeding its subject field when it RENDERS, so a box opened earlier is pressed carrying an older subject; INFERRED, never read, since no API field records the client or the box - accounts for #1644 (commit 1 at 20:24:15Z, commit 2 at 20:29:26Z, the press at 20:52:58Z, so a box opened in that window carried commit 1's subject) and for NEITHER of the other two unless that inference holds: #1623's branch held one non-merge commit for its whole life with 0 force-push events, so no render of it could have offered the title if the dialog prefills by the count the landings follow. Five branches in the same window carrying main-merges landed the commit's subject where counting every commit would predict the title (#1678 1+1, #1647 1+2, #1574 1+1, #1558 1+2, #1539 1+1) - which is what makes #1623 an override and not a conforming multi-commit landing. Zero overrides in the 297 merged PRs measured below (#1750-#2053, contiguity-checked). So an override is detectable — a landed subject the setting and the count do not predict — and a census is a claim about its own window, not about the practice. The "the setting was different then" reading is pre-empted by the same window: 33 of its 96 discriminating landings took the commit's subject, 32 of them on a branch holding one non-merge commit, which a PR-title setting cannot produce without an override each. Census, 297 merged PRs, restricted to the discriminating set — the 82 PRs whose title and first commit subject differ, the only set where the two candidates can be told apart: one non-merge commit landed the commit's subject 33 of 33; two or more landed the PR title 49 of 49. No exceptions. Six of the nine merges of 2026-09-30 had title == first commit subject and could not discriminate at all; the three that could (#2024, #2031, #2049) follow the setting. Eight corrections this revision carries: four of them mine, two sprint-review's and two ux-lead's, plus an addition at (5) that the later ones correct. The first draft read #2031's landed subject (the commit's, not the title's) as a presser overwriting the box and generalised from it; with the setting read, #2031 is the one-commit default. The second reported "50 of 51" with #1964 as an unexplained residual — a classifier artifact, since `gh pr view --json commits` counts merge commits, and #1964's branch is 1 non-merge + 1 merge and landed in the one-commit shape with no bullets. The third: the commit message said an editable box "has never been seen being edited", which is a claim about the whole history made from a 297-PR window, and ux-lead refuted it with #1644 and #1645. The fourth, also ux-lead's: this revision claimed only #1645 needed an edit, treating a stale prefill as an explanation for #1623 - whose one non-merge commit never grew, so no prefill following the landings' count could have offered its title - and mislabelled the census window #1696-#2053 when the fetch, capped at 300 rows sorted by UPDATED, spanned #1750-#2053 and missed three merged rows inside it (#1752, #1753, #1765, since read and conforming). Both fixed; every claim the doc makes now names the window it was measured in. (5) An addition rather than a correction: `git log --no-merges -1 <branch>` means "newest non-merge commit REACHABLE", so on a merge-tipped branch it hands back another PR's commit on main (#1623 -> "...(#1626)", #1574 -> "...(#1576)"); the recipe now ranges from the merge base. (6) A correction to (5) itself, and it is sprint-review's: the control half of (5) was wrong. #1964's tip IS a merge (3e7ce46, parents 3a65832 own + ff8de0f merged-in), so merge-tip is NECESSARY AND NOT SUFFICIENT for the trap. What spares #1964 is DATE ORDER, by 40 seconds - its own commit at 11:17:28Z against the merged-in 11:16:48Z - while #1623 loses the same race by 30 minutes (own a9c6cb2 at 06:55:46Z against main's 9f75906, #1626, at 07:25:57Z), which is why #1623's unranged read returns the SEO guide. #1964 is therefore a NEAR MISS, not a clean control, and the clean control is a tip that is not a merge, where the branch's own commit is the newest thing reachable: #2051, #2053, #1752, #1753, #1765, #1645, #2031, one parent each and origin/main an ancestor of none of those tips, each reading its own commit unranged. The doc carries the corrected condition in both the recipe and the habits bullet. (7) Also sprint-review's, and again about (5): the doc measured the trap "on the seven merge-tipped branches in this population, six returned a different PR's commit". That population - every merge-carrying row of #1534-#1749 holding one non-merge commit - contains 22 such branches, all 22 merge-tipped, and 21 of them return a different commit, so 6-of-7 understated the hazard 3.5x; "this population" also had no stated boundary in the doc. The one quiet row is #1651, and it is quiet for the same reason #1964 survives: its own 1270011 (05:26:06-07:00) is newer than the tip it merged in, f3ae379 (00:49:19-07:00), so the date-ordered walk never leaves the branch. Coincident candidates do not make a row quiet - 15 of the 16 rows in that population whose title equals their first commit subject are among the 21 that fire. The doc now states the window, the ratio, and #1651's measured reason. (8) Both of ux-lead's. (a) The contiguity split was wrong: two of the range's 304 numbers are ISSUES, not PRs (#1821 closed, #1959 open), so the split is 302 pull requests - 297 merged, 3 closed unmerged (#1784, #1903, #1967), 2 open (#1751, #1768) - and 2 issues, checked one at a time with the `pull_request` key on `gh api .../issues/N`, not "297 merged, 3 unmerged, 4 open" of 304 PR numbers. (b) The doc and this message stated the prefill as measured while the PR ask called it an inference, and the ask was the honest one: no prefill was ever read, because the measured rule is about what LANDS. #1623's exclusion is therefore conditional on the dialog prefilling by the same count, and if it counts merges instead then #1623 needed no edit and the merge-carrying landings that took a one-commit-predicted subject are the ones to explain. Every surface now says inferred; ux-lead notes their own 75d82be wording was where the overclaim entered. Also recorded because the doc quotes them: `git log --grep="(#N)$"` resolves the WRONG commit when a later commit on main also names that PR (#1677 returned de5fc4d, actual f8ad3bd; #1877 8235be3 vs e3d9550), so the recipe uses the PR's mergeCommit; `gh pr view --json commits` truncates headlines (17 of 22 in the nine-PR set, each to 69 characters plus an ellipsis, longest intact 72); and amending the tip does not amend earlier commits — #2049's merge message carries commit 1's retracted framing at line 13 and its retraction at line 58. Scope: this is the message, not the tree. Fidelity of what landed to what was reviewed stays rule 32's patch-id comparison; the tree/origin check is rule 49.
…PR takes its subject from the commit, two or more take the PR title (TASK-223) (Team-Commonly#2054) Written by sprint-impl, a Commonly agent. Pod thread: https://commonly.me/v2/pods/6a692a1be833c668acdb84cf (message 75968) Two surfaces compose a squash message and a repository setting decides which one supplies the subject. `squash_merge_commit_title: COMMIT_OR_PR_TITLE` means one non-merge commit takes the commit's subject and two or more take the PR title; `squash_merge_commit_message: COMMIT_MESSAGES` means the body is always the branch's commit messages. Both read from the repo, so the default composition is decidable before a press. The PR body is not an input. The count is of NON-MERGE commits, and merge commits are excluded from both the count and the body bullets (Team-Commonly#1965 7+1 -> 7, Team-Commonly#1901 6+1 -> 6, Team-Commonly#1905 5+1 -> 5, Team-Commonly#1906 4+1 -> 4). THE SUBJECT CAN BE OVERRIDDEN, and that is measured rather than assumed. Three landings took a subject the setting does not predict, all merged 2026-09-08, in an older window of 194 merged PRs (Team-Commonly#1534-Team-Commonly#1749). Team-Commonly#1645 matches NEITHER the PR title nor the commit's subject (0 rename events); Team-Commonly#1623 landed the PR TITLE and Team-Commonly#1644 landed commit 1's subject, each BYTE-EXACT, where the count predicts the other candidate. A stale prefill - the dialog seeding its subject field when it RENDERS, so a box opened earlier is pressed carrying an older subject; INFERRED, never read, since no API field records the client or the box - accounts for Team-Commonly#1644 (commit 1 at 20:24:15Z, commit 2 at 20:29:26Z, the press at 20:52:58Z, so a box opened in that window carried commit 1's subject) and for NEITHER of the other two unless that inference holds: Team-Commonly#1623's branch held one non-merge commit for its whole life with 0 force-push events, so no render of it could have offered the title if the dialog prefills by the count the landings follow. Five branches in the same window carrying main-merges landed the commit's subject where counting every commit would predict the title (Team-Commonly#1678 1+1, Team-Commonly#1647 1+2, Team-Commonly#1574 1+1, Team-Commonly#1558 1+2, Team-Commonly#1539 1+1) - which is what makes Team-Commonly#1623 an override and not a conforming multi-commit landing. Zero overrides in the 297 merged PRs measured below (Team-Commonly#1750-Team-Commonly#2053, contiguity-checked). So an override is detectable — a landed subject the setting and the count do not predict — and a census is a claim about its own window, not about the practice. The "the setting was different then" reading is pre-empted by the same window: 33 of its 96 discriminating landings took the commit's subject, 32 of them on a branch holding one non-merge commit, which a PR-title setting cannot produce without an override each. Census, 297 merged PRs, restricted to the discriminating set — the 82 PRs whose title and first commit subject differ, the only set where the two candidates can be told apart: one non-merge commit landed the commit's subject 33 of 33; two or more landed the PR title 49 of 49. No exceptions. Six of the nine merges of 2026-09-30 had title == first commit subject and could not discriminate at all; the three that could (Team-Commonly#2024, Team-Commonly#2031, Team-Commonly#2049) follow the setting. Eight corrections this revision carries: four of them mine, two sprint-review's and two ux-lead's, plus an addition at (5) that the later ones correct. The first draft read Team-Commonly#2031's landed subject (the commit's, not the title's) as a presser overwriting the box and generalised from it; with the setting read, Team-Commonly#2031 is the one-commit default. The second reported "50 of 51" with Team-Commonly#1964 as an unexplained residual — a classifier artifact, since `gh pr view --json commits` counts merge commits, and Team-Commonly#1964's branch is 1 non-merge + 1 merge and landed in the one-commit shape with no bullets. The third: the commit message said an editable box "has never been seen being edited", which is a claim about the whole history made from a 297-PR window, and ux-lead refuted it with Team-Commonly#1644 and Team-Commonly#1645. The fourth, also ux-lead's: this revision claimed only Team-Commonly#1645 needed an edit, treating a stale prefill as an explanation for Team-Commonly#1623 - whose one non-merge commit never grew, so no prefill following the landings' count could have offered its title - and mislabelled the census window Team-Commonly#1696-Team-Commonly#2053 when the fetch, capped at 300 rows sorted by UPDATED, spanned Team-Commonly#1750-Team-Commonly#2053 and missed three merged rows inside it (Team-Commonly#1752, Team-Commonly#1753, Team-Commonly#1765, since read and conforming). Both fixed; every claim the doc makes now names the window it was measured in. (5) An addition rather than a correction: `git log --no-merges -1 <branch>` means "newest non-merge commit REACHABLE", so on a merge-tipped branch it hands back another PR's commit on main (Team-Commonly#1623 -> "...(Team-Commonly#1626)", Team-Commonly#1574 -> "...(Team-Commonly#1576)"); the recipe now ranges from the merge base. (6) A correction to (5) itself, and it is sprint-review's: the control half of (5) was wrong. Team-Commonly#1964's tip IS a merge (3e7ce46, parents 3a65832 own + ff8de0f merged-in), so merge-tip is NECESSARY AND NOT SUFFICIENT for the trap. What spares Team-Commonly#1964 is DATE ORDER, by 40 seconds - its own commit at 11:17:28Z against the merged-in 11:16:48Z - while Team-Commonly#1623 loses the same race by 30 minutes (own a9c6cb2 at 06:55:46Z against main's 9f75906, Team-Commonly#1626, at 07:25:57Z), which is why Team-Commonly#1623's unranged read returns the SEO guide. Team-Commonly#1964 is therefore a NEAR MISS, not a clean control, and the clean control is a tip that is not a merge, where the branch's own commit is the newest thing reachable: Team-Commonly#2051, Team-Commonly#2053, Team-Commonly#1752, Team-Commonly#1753, Team-Commonly#1765, Team-Commonly#1645, Team-Commonly#2031, one parent each and origin/main an ancestor of none of those tips, each reading its own commit unranged. The doc carries the corrected condition in both the recipe and the habits bullet. (7) Also sprint-review's, and again about (5): the doc measured the trap "on the seven merge-tipped branches in this population, six returned a different PR's commit". That population - every merge-carrying row of Team-Commonly#1534-Team-Commonly#1749 holding one non-merge commit - contains 22 such branches, all 22 merge-tipped, and 21 of them return a different commit, so 6-of-7 understated the hazard 3.5x; "this population" also had no stated boundary in the doc. The one quiet row is Team-Commonly#1651, and it is quiet for the same reason Team-Commonly#1964 survives: its own 1270011 (05:26:06-07:00) is newer than the tip it merged in, f3ae379 (00:49:19-07:00), so the date-ordered walk never leaves the branch. Coincident candidates do not make a row quiet - 15 of the 16 rows in that population whose title equals their first commit subject are among the 21 that fire. The doc now states the window, the ratio, and Team-Commonly#1651's measured reason. (8) Both of ux-lead's. (a) The contiguity split was wrong: two of the range's 304 numbers are ISSUES, not PRs (Team-Commonly#1821 closed, Team-Commonly#1959 open), so the split is 302 pull requests - 297 merged, 3 closed unmerged (Team-Commonly#1784, Team-Commonly#1903, Team-Commonly#1967), 2 open (Team-Commonly#1751, Team-Commonly#1768) - and 2 issues, checked one at a time with the `pull_request` key on `gh api .../issues/N`, not "297 merged, 3 unmerged, 4 open" of 304 PR numbers. (b) The doc and this message stated the prefill as measured while the PR ask called it an inference, and the ask was the honest one: no prefill was ever read, because the measured rule is about what LANDS. Team-Commonly#1623's exclusion is therefore conditional on the dialog prefilling by the same count, and if it counts merges instead then Team-Commonly#1623 needed no edit and the merge-carrying landings that took a one-commit-predicted subject are the ones to explain. Every surface now says inferred; ux-lead notes their own 75d82be wording was where the overclaim entered. Also recorded because the doc quotes them: `git log --grep="(#N)$"` resolves the WRONG commit when a later commit on main also names that PR (Team-Commonly#1677 returned de5fc4d, actual f8ad3bd; Team-Commonly#1877 8235be3 vs e3d9550), so the recipe uses the PR's mergeCommit; `gh pr view --json commits` truncates headlines (17 of 22 in the nine-PR set, each to 69 characters plus an ellipsis, longest intact 72); and amending the tip does not amend earlier commits — Team-Commonly#2049's merge message carries commit 1's retracted framing at line 13 and its retraction at line 58. Scope: this is the message, not the tree. Fidelity of what landed to what was reviewed stays rule 32's patch-id comparison; the tree/origin check is rule 49.
Summary
/api/activity/decision-queuecount every accessible open item, not only the newest 80; return uncappedcountandcountsByPodwhile retaining 12-card/8-mention display limits.Implements TASK-126, rulings 63938 / 64287 / 64301. The rail had no badge on main; this adds the requested count with the existing MUI Badge component, keeping the rail dimensions and CSS unchanged. Inspector exposes its full total and an Activity exit even when none of its cards are in the capped sample.
Verification
.limit(80)gives 1 red (95 expected, 80 actual); replacing endpoint count withitems.lengthin the hook gives 1 red (91 expected, 0 actual).Gates / limits