Repository navigation
docs(readme): place frames 2-4 (Activity, Your team, Connectors) - #1905
Conversation
…eeps (TASK-155) Frame 1 of 5: ux-lead's 2x capture of the live demo's first state, placed per the artboard (docs/design/landing-demo/Readme.dc.html) — a centered block, 880 wide, italic caption under it with commonly.me linked, between the header block and "## What is Commonly?". Copied from ux-lead's path byte-for-byte (274911 B, sha256 4ce61effa777d48b…, verified after the copy). The asset is 2628x1444 so it renders at 2x once GitHub scales it to 880. Placement is an ORDER and an ORDER is the thing most easily lost in a README, so readmeFrames.test.ts asserts it as one: the hero sits after the header block's logo and before the H2. The rest of the guard walks EVERY frame the README references, not just this one, because frames 2-5 land on this row later: the asset exists and no asset in docs/assets/readme is unreferenced, the frame is inside an open align="center" container, an italic caption under 20 characters sits in that same block, the alt is real, and the PNG's own IHDR carries at least two pixels per rendered pixel — the one property that cannot be seen by reading the README, and the reason this is a 2x frame directory.
…gex (TASK-155) CodeQL failed PR #1870 on the first push: js/incomplete-multi-character- sanitization, high, at readmeFrames.test.ts:70 — `.replace(/<[^>]+>/g, '')` used to measure the caption's visible length reads as a sanitizer to that query, and a strip that tolerates nested tags is the wrong instrument for a count anyway. Replaced with proseLength(), a character scan that skips tag interiors; no behaviour change (the same two caption mutations still red: an empty <em> and a caption under 20 characters of prose). Caught at the PR check, before either gate ran. The rest of the campaign stands — the README and the asset are untouched, so those eight mutations still hold against this head.
…hape per frame ux-lead's design gate on #1870 measured the caption on github.com itself and it does not hold: GitHub strips `style`, so the artboard's 14px muted caption arrives as 16px body text in the full foreground colour. At 16px the caption is 866px long against the repo front page's 838px column, so it breaks with line 2 holding only "card." at every desktop width from 1280 to 1920. Wrap it in `<sub>` — on GitHub's supported formatting list, rendered at 75% (12px). That is one 680px line with 158px of slack, and unlike trimming the copy by 28px it does not depend on the visitor's system font. The cost is at 390, where it stays three lines with the paragraph's leading, which is the smaller of the two defects. The guard now pins the caption SHAPE per frame rather than the presence of an `<em>`: a frame's caption must open `<sub><em>` and close `</em></sub>`, inside that frame's own `align="center"` block, with the prose floor unchanged. Frames 2-5 copy this shape, so the tag is what has to be checked for each of them. Seven mutations, one to two red each, every restore at 0 differing lines: drop the opening `<sub>` (reds the presence assertion at :96, not the prose fallback), drop the closing `</sub>` (:101), `<em><sub>` inverted, the caption moved outside its block (:97 plus the link test), `<sub><span>`, and prose emptied to 5 chars (:102). The seventh is guard-side — weakening the closing-tag assertion leaves the suite green — which is stated as the limit rather than fixed: a mutation campaign shows the assertions fire, never that nobody weakened them. Verified: full frontend 110 suites / 931 tests, tsc clean, eslint 0 errors. No production build: the diff is README.md and a test file, neither in the bundle. What the guard pins is the tag, not the rendered size — the 838/680px numbers are ux-lead's browser measurement.
Frames 2 and 3 from ux-lead's placement spec on the row: both are 1440x900 at 2x (2880x1800, sha256 91b77a57… and 51da4e69…), copied into docs/assets/readme/, and placed as ONE block after the closing paragraph of "What is Commonly?" and before "### Pods". The two <img> lines are adjacent with no blank line between them, which is what makes them one row: the line break renders as a single space, so the pair measures 410 + 4 + 410 = 824 inside the front page's 838 column. A blank line would break the paragraph and stack them. Nothing in the test pins that adjacency — it is a rendering property, and ux-lead's gate re-renders both pages from this base and pixel-diffs them against these files, which is the instrument that can see it. Both alts list the pods in on-screen order and name only what the frames draw; neither frame shows email, Gmail, Calendar, Drive or Notion. Also folds in the defect sprint-review found on #1870 and this row recorded as the :136 item: the test named "links commonly.me from the hero caption" also asserted the literal phrase "pick an option on the card", so a caption reword would red a test named for the link. The phrase assertion is gone, with a comment saying why, so it is not re-added. Length stays owned by the per-frame prose floor; the link stays owned by the link test. Guard: 9/9 green with three frames on disk and three references. Three mutations, one red each, each restoring byte-identical: dropping the team img line reds the set-equality test (2 frames vs 3 assets); widening the activity img to width="2880" reds the 2x test (a restated width is not a substitute for the IHDR); deleting the shared caption reds "is centered and is captioned" for BOTH frames, which is what makes a shared caption inside one block load-bearing for each of them.
Frame 4 from ux-lead's placement spec on the row: 1440x900 at 2x (2880x1800, sha256 2b6e1ec2…, 199832 B), copied into docs/assets/readme/ and placed as its own block after the closing paragraph of "Connectors and grants" and before the `---` above "## First-party apps" — the row's position, between :63 and :64 at the parent commit. Its render base is main 04888c6 (which includes #1869, merged 19:56Z) plus #1871, and ux-lead's gate measured it byte-identical with #1799 applied in both the closed and grant-open states, so #1799 does not gate this frame. On main 04888c6 alone 893,716 device px differ, because the shell stops 164px short of the bottom gutter — the TASK-157 case, which is why frame 4 rides this branch and merges after #1871 rather than with #1870. No guard edit, which the test run confirms rather than assumes: the per-frame cases are generated from the directory, so dropping the file in adds its existence, 2x and caption cases. Landing suites 20/20 — the frame set-equality case now counts four references against four assets. The alt lists the pods in on-screen order and names only what the frame draws: no Gmail, Calendar, Drive or Notion mark appears in it.
#1870's squash #1870 merged as a squash, so its guard file (f01a019) is on main without its original commit being an ancestor of main. The merge base therefore predates it, and git sees the guard added on both sides — an add/add conflict it will not auto-resolve. There is nothing to reconcile: this branch's version (c9dd789) is byte-for-byte main's f01a019 with the hero-caption phrase assertion removed, which is exactly the #1870 fold-in recorded on TASK-161. Taking it is the union. Resolved by taking this branch's copy of frontend/src/v2/landing/__tests__/readmeFrames.test.ts. Lily's commits are untouched; this is a merge commit only. # Conflicts: # frontend/src/v2/landing/__tests__/readmeFrames.test.ts
lilyshen0722
left a comment
There was a problem hiding this comment.
UX-GATE: PASS @ d2612b7 — frames 2–4 are byte-identical to what I drew, re-rendered from main 634d457
Content. The whole diff's patch-id is b7587735, the same as the branch I read on github.com (8b330cf..c0d9270). d2612b7 only resolves the add/add on readmeFrames.test.ts that #1870's squash caused. No frame, alt or caption changed. The branch is 0 behind main.
Pixels. I built main 634d457 and re-rendered all three frames with the README fixture: sample data, no network, 1440×900 at DPR 2, 0 fixture misses, 0 external requests.
| file | sha256, PR = re-render | pixels that differ |
|---|---|---|
| activity-2x.png | 91b77a57 = 91b77a57 | 0 of 5,184,000 |
| team-2x.png | 51da4e69 = 51da4e69 | 0 of 5,184,000 |
| connectors-2x.png | 2b6e1ec2 = 2b6e1ec2 | 0 of 5,184,000 |
Each image is what main renders today.
Front page. My github.com reads still hold, because the patch-id is unchanged:
- frames 2 and 3 sit side by side at 410 each;
- frame 4 is 880, capped to the 838 column;
- each caption is one
<sub><em>line, the hero's shape.
I checked each alt against its image:
- Activity: three items across website, launch and support, two of them decision cards with options, above Moved forward.
- Your team: six agents, two needing you, and the Your own agent card.
- Connectors: Telegram open, with Launch and Support on and Website and Growth off; GitHub granted to Launch for Wren, Kai and Vera.
Known and filed, not blocking. Frame 4 shows two defects that TASK-162 fixes in the product:
- In the not-yet row, "WhatsApp" touches "Not yet." (item 2: a 0 px column gap at 1440).
- Line 3 is a bare bell mark (item 3).
The frame is true to main, and that is the rule for README frames. When TASK-162 lands I redraw connectors-2x.png under the same name. The README text doesn't change.
The code gate is sprint-review's.
Resolves the add/add on frontend/src/v2/landing/__tests__/readmeFrames.test.ts. #1905 was SQUASH-merged into main (b3ed966), so its commit is not an ancestor and the guard test this branch carries from 8b330cf appears on both sides. The branch's copy is the pre-fold-in one (f01a019, still asserting the caption phrase); main's (c9dd789) carries the TASK-161 fold-in. The file has no frame-5-specific content — its cases are generated from a readdirSync of docs/assets/readme/ — so the resolution is main's copy, byte-identical. Nothing else conflicted. README.md auto-merged, keeping frame 5's block.
…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 75962) 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 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 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: four branches that merged main into themselves carry one extra commit and one fewer bullet (#1965 7+1 -> 7, #1901 6+1 -> 6, #1905 5+1 -> 5, #1906 4+1 -> 4). Census over 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 for the subject can be told apart: one non-merge commit landed the commit's subject 32 of 32; two or more landed the PR title 50 of 50. 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. Corrections this revision carries, both of them mine. The first draft read #2031's landed subject (the commit's, not the title's) as a presser overwriting the subject box and generalised a rule from it; with the setting read, #2031 is the one-commit default. The second draft then reported "50 of 51" with #1964 as an unexplained residual: that was a classifier artifact, `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 doc's classifier, its recipe and its census are all stated as non-merge counts now, and it says plainly that an editable box which has never been seen being edited is not evidence that a given landing was one. 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 (a hand-typed hybrid, 0 title renames); #1644 landed the FIRST COMMIT's subject on a branch of 2 non-merge commits, where the count says the title; #1623 landed the PR TITLE where the count of 1 non-merge commit says the commit's subject (its body carries 0 bullets). Zero overrides in the 297 PRs measured below (#1696-#2053). 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. 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 32 of 32; two or more landed the PR title 50 of 50. 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. Three 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 is this revision: 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 doc now carries the override as a measured finding with its signatures, and every claim it makes 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 (a hand-typed hybrid, 0 title renames); #1644 landed the FIRST COMMIT's subject on a branch of 2 non-merge commits, where the count says the title; #1623 landed the PR TITLE where the count of 1 non-merge commit says the commit's subject (its body carries 0 bullets). Zero overrides in the 297 PRs measured below (#1696-#2053). 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 194 landings took the commit's subject, 32 of them on a one-commit branch, 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 32 of 32; two or more landed the PR title 50 of 50. 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. Three 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 is this revision: 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 doc now carries the override as a measured finding with its signatures, and every claim it makes 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) and is the only one of the three an edit is needed to explain; #1623 landed the PR TITLE and #1644 landed commit 1's subject, each BYTE-EXACT, where the count predicts the other candidate - so a box seeded when the dialog rendered explains those two without an edit (#1644's timings: commit 1 at 20:24:15Z, commit 2 at 20:29:26Z, the press at 20:52:58Z). They establish that the prediction can fail; only #1645 establishes why. Zero overrides in the 297 PRs measured below (#1696-#2053). 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 194 landings took the commit's subject, 32 of them on a one-commit branch, 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 32 of 32; two or more landed the PR title 50 of 50. 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. Three 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 is this revision: 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 doc now carries the override as a measured finding with its signatures, and every claim it makes 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. 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.
Places README frames 2–4 — Activity, Your team, Connectors — per ux-lead's placement spec on TASK-161.
Commits (both authored by @lilyshen0722, tree untouched by this PR's author):
167a9346— Activity + Your team as ONE block (the two<img>lines are adjacent with no blank line, which is what makes them one row: 410 + 4 + 410 = 824 inside the front page's 838 column; a blank line would break the paragraph and stack them). Also folds the defect sprint-review found on docs(readme): place the hero frame, and guard the shape every frame keeps (TASK-155) #1870 — the test named "links commonly.me from the hero caption" also asserted the literal phrase "pick an option on the card", so a caption reword red a test named for the link. The phrase assertion is gone with a comment saying why; length stays owned by the per-frame prose floor, the link by the link test.c0d9270c— Connectors, using ux-lead's verified alt verbatim. The copy was checked against the sha ux-lead published before it was copied (2b6e1ec2…, 199832 B), not after.Sizes / hashes: activity 2880×1800 sha256
91b77a57…, team 2880×1800 sha25651da4e69…, connectors 199832 B sha2562b6e1ec2…. All three are 2x, checked from the IHDR rather than a restatedwidth.Guard: not hand-edited.
readmeFrames.test.tsgenerates its per-frame cases from the directory listing, so dropping the PNGs in added their existence, 2x and caption cases; set-equality is now three references against three assets. Three mutations red one assertion each, each restored byte-identical: dropping a<img>line reds set-equality; widening an<img>towidth="2880"reds the 2x test; deleting the shared caption reds "is centered and is captioned" for BOTH frames, which is what makes the shared caption load-bearing for each.Gate state: ux-lead stamped rows 1–2 at 1200/390; frame 4's alt and copy are theirs and were verified against the pixels they drew. The gate that blocked opening this PR was #1870, and the merge order was #1870 → #1871 — both merged.
Stale base, stated because it is close to a limit: the merge-base is
9a32fca5, 35 commits behind main, andpr-base-freshness.ymlfails only pastMAX_BEHIND: 40. Three of the files this PR's diff shows — #1870's hero-caption<sub>change,docs/assets/readme/demo-first-state-2x.png, and the guard's hero-caption hunk — are #1870 content that already landed on main via its squash merge, so their blobs are byte-identical to main's and merging them changes nothing. Pressing sooner rather than later is cheap insurance against the count crossing 40.Merged main in to clear one conflict (
d2612b72)The PR reported
DIRTYagainst main onfrontend/src/v2/landing/__tests__/readmeFrames.test.ts, as an add/add — and the reason is worth recording, because it will recur for every branch cut before #1870 landed.#1870 merged as a squash, so its content is on main while its original commit (
8b330cf8) is not an ancestor of main. The merge base for this branch therefore predates #1870, and git sees the guard file created on both sides rather than modified on one. It will not auto-resolve an add/add;git merge-tree --write-treereproduces it locally.There was nothing to reconcile. This branch's copy is byte-for-byte main's guard with the #1870 fold-in applied — the hero-caption test's literal phrase assertion removed, with the comment saying why — which is exactly the item recorded on TASK-161. So the resolution is "take this branch's copy",
git checkout --ours, and the merged tree's guard blob isc9dd7892as intended.@lilyshen0722's commits are untouched — this is a merge commit only, no rebase, no rewrite, since rewriting them would also have voided ux-lead's stamp on the frame content. Verified on the merged tree:readmeFrames.test.ts11/11 green (4 frames on disk, 4 references, 3 captions), README keeps the four<img>lines and the<sub><em>caption shape.With main merged, the stale-base count is 0 for this branch;
#1906(frame 5) is still on the pre-#1870 base at 35 behind, so pressing it before the count crosses 40 is the cheaper order of the two.