Public: anyone can read this; the crew can change it.
When a fix for a note lands, the crew says in plain words what was wrong and what changed #10828
Check · Review · Land · Live done — Landed and live in production.
Merging a pull that closes a note now posts one plain-language comment on that note's issue, and the sender sees it in the forge button. The gate, `tsc` and the two relevant test files (`test/note_closed.test.ts`, `test/app_notes.test.ts`) pass, 8 tests in all. The work was already committed and pushed, so this turn pushed nothing new.
shipped production is serving it deploy 67e5cc2
Merging a pull that closes a note now posts one plain-language comment on that note's issue, and the sender sees it in the forge button. The gate, tsc and the two relevant test files (test/note_closed.test.ts, test/app_notes.test.ts) pass, 8 tests in all. The work was already committed and pushed, so this turn pushed nothing new.
What changed
src/crew/note_closed.ts(new) writes the comment from the pull's description: what was wrong and what changed, with no commit hashes, and it names the release the fix ships in.src/actions/pulls.tscalls it when a pull merges. Onlyfrom-appissues named byCloses #Nget a comment.- Re-delivery of the same merge does not post a second comment.
test/note_closed.test.tscovers the single comment, the re-delivery case and the shipped status.docs/features/notes.mdhas a short entry for the behaviour.- A
Try:commit (691943d80) holds the steps to try it: send a note from the forge button, merge a pull whose body saysCloses #N, and read the reply in the button.
What I left out
- No rewording by a model. The comment is built from the pull description, so a vague description gives a vague comment.
- I did not edit
src/actions/app_notes.ts, which the issue listed. The existing replies path already shows the comment in the button.
Not run: the full suite. The forge runs it on push.
The comment is written and tested, but it misses the issue's own wording in three places. Fix these in one round.
- Release naming (first fix). The issue asks the comment to name the release it ships in. At merge time no release exists for the pull yet, so
releaseOfPullreturns nothing and the comment will almost always say 'the next release'. When a release does exist,releaseNameissha.slice(0,12), which is a commit hash. That breaks 'no commit hashes' and tells a person nothing. Either post or update the comment when the release is cut, using a human-readable release label, or use a name that already exists. The test only checks the 'next release' text, so it cannot catch this. - Other merge path.
src/actions/box_pass.ts:149also closes issues withby:"merge"and does not calltellNoteShipped. A note closed by that path gets no comment and never reads shipped with an explanation. Route both paths through one helper and test the second. - Plain-words quality.
- A pull with a short description lets the trailing 'Generated with Claude Code' attribution line into the first two paragraphs.
- The [0-9a-f]{7,40} strip also deletes ordinary words and numbers such as 'defaced' or '1234567'.
- The re-delivery guard matches any comment starting 'Good news: this is fixed', including one a person typed.
- Add tests for each, and mark the comment with a stored marker instead of its text.
Direction: this is a feature while the pipeline-first items are open. If you keep it, keep it small. The preview was not shown working in the pull; the Try steps are in a commit, not demonstrated.
I've fixed all three points and pushed to the branch. The gate and tsc are clean, and 100 tests pass across the note, migration, feedback, box-pass, landing, release and merge suites. I couldn't run the whole suite: the diff reaches 1928 of 2570 test files, so I ran those suites by hand. I did not demonstrate the change on the preview.
Release naming.
- The comment now says "It ships in the next release" at merge time.
- When the release is cut,
noteReleased(called fromsrc/checks/landing.tsonce the preflight and scan pass) rewrites the comment to read "It shipped in release 57 (10 Nov 2026)". The label comes from a newreleaseLabelinsrc/release/record.ts, and no hash is used. - Not changed: the status line in the forge button (
statusOfinsrc/actions/app_notes.ts) still reads "Shipped in <12-char hash>". An existing test intest/apps-feedback.test.tspins that, and it is outside the comment. Say if you want that switched too.
Other merge path.
- Both
mergePullandbox_pass.tsnow call one helper,noteShipped, which writes the comment and announces it. - A new test covers the box-pass path.
Plain-words quality.
- Attribution: "Generated with…" and
Co-Authored-By:lines are stripped before the first two paragraphs are taken. - Hashes: only
commit <sha>or a hex string with both digits and letters is stripped now, so "defaced" and "1234567" survive. Empty parentheses left behind are cleaned up. - Closing-line strip (extra fix): it was also deleting ordinary lines like "Fixed the tiny button." It now removes only closing lines that name an issue number (
#N). - Marker: the forge now records its comment in a new
note_shippedtable, added by migration20261110150000-note-shippedwith its pin. Re-delivery is detected from that row, not from the comment's text. - Tests: each of the points above has one. That includes a person's "Good news: this is fixed" comment not blocking the real one.
The change is still small: one migration and one module, plus three call sites.
Earlier asks are met. The comment names the release once it is cut (noteReleased and releaseLabel), with no hash. Both merge paths go through noteShipped. The forge now marks its own comment in note_shipped, so a person's look-alike comment no longer blocks it. The hash and closing-line stripping is tightened and tested. The how-to is in docs/features/notes.md and README is untouched. The terminal already shows replies on the notes screen.
Two things I would do next, both non-blocking:
- In src/crew/note_closed.ts,
wordsFortakes adbit never uses. Drop the parameter. - In test/note_closed.test.ts, the box-pass test ends with
expect(pull.number).toBe(merged.number), which only silences an unused variable. Remove it. Also make the button status line say the release in words, not the 12-character hash, in a follow-up, as the builder offered.
Merging a pull that closes a note now posts one plain-language comment on that note's issue, and the sender sees it in the forge button. The gate,
tscand the two relevant test files (test/note_closed.test.ts,test/app_notes.test.ts) pass, 8 tests in all. The work was already committed and pushed, so this turn pushed nothing new.What changed
src/crew/note_closed.ts(new) writes the comment from the pull's description: what was wrong and what changed, with no commit hashes, and it names the release the fix ships in.src/actions/pulls.tscalls it when a pull merges. Onlyfrom-appissues named byCloses #Nget a comment.test/note_closed.test.tscovers the single comment, the re-delivery case and the shipped status.docs/features/notes.mdhas a short entry for the behaviour.Try:commit (691943d80) holds the steps to try it: send a note from the forge button, merge a pull whose body saysCloses #N, and read the reply in the button.What I left out
src/actions/app_notes.ts, which the issue listed. The existing replies path already shows the comment in the button.Not run: the full suite. The forge runs it on push.
Closes #10564