All releases
Release
v1.2.20
What shipped, in numbers
- 39
- PRs merged
- 3,584,091
- Lines added
- 1,006,798
- Code lines
- Code
- 1,006,798
- Tests
- 1,124,046
- Docs
- 1,453,247
- Sum · code + tests + docs
- 3,584,091
of 39 merged
- bug 28 72%
- feature 4 10%
- polish 0 0%
- docs 2 5%
- groundwork 3 8%
- unclassified 2 5%
since v1.2.19 · tagged
What shipped
The release that makes the path from a passing review to a merged PR run without a human standing on it. Every failure point on that path was mapped, and every one of them is closed here: a review that could not be dispatched, a verdict that never reached the worker who owned it, a merge the cockpit started and never finished, a lease held by a process that had already died. Forty-nine changes, and the shape of all of them is the same — the pipeline used to assume its own steps landed. Now it reads each one back.
The review lane stops stalling on itself
- 🔴 A real GOLDEN was refused by the parser that reads it, so it was never stamped, never banked, and the PR got reviewed again. The §7.3 evidence parser over-split a report in five different ways — a count numeral on a label line read as a finding of its own, nested evidence bullets read as sibling entries — and an unclassified entry fails closed by design. Honest reviews were being rejected for their formatting (#5574).
- 🔴 A NOT-GOLDEN verdict never reached the worker that owns the PR. The verdict was produced, posted and recorded, and the one party who had to act on it was never told. Delivery is now coupled to the fact in both lanes, so a verdict that exists is a verdict that arrived (#5539).
- 🔴 A review whose PR merged underneath it kept reading shipped code. Four crews burned on a merged PR in a single day. A review now detects that its subject merged, stands down, releases its lease and frees its slot instead of running to the wall (#5655).
- A push could kill the review reading its own head. The worker had no way to see the lease, so it would push mid-round, supersede the head, and the refund made the loop free — three heads superseded for zero verdicts, two of them from test-only pushes. The worker gets the lease read it never had (#5570).
- The lease reaper was wired all along and could not see through a hostname that drifts — so dead leases accumulated and blocked live dispatches (#4538).
- The head is validated and expanded BEFORE a round is spent, and its refusal now reads nothing like the duplicate guard, which is what made the two indistinguishable in a log (#5604).
- A crew killed by the wall no longer records a verdict nobody made (#5575). A supersession is named a supersession, never a dead crew, and a blocked beat is named blocked, never an unserviced queue (#5556).
- A refund is a recorded fact, and now something reacts to it — the successor round stops waiting for a human to notice (#5632). A binding failure is loud, read back, and told apart from a reviewer's judgement (#5631).
- The crew wall is 2 hours for every customer, with a Settings dial, and the stall banner stops reading its own countdown as a cap (#5559). The wall bounds the ROUND, not just the process id — a context kill bounds a pid, and every descendant holding the output pipe kept the round alive long past its limit (#5622).
- A PR nobody will ever review is now DETECTED, by enumerating from the forge and joining the ledger rather than trusting either alone (#5562).
- The reviewer's template copy had gone stale, and the parity guard was comparing names instead of content — so it reported agreement it had never checked (#5602).
The merge completes
- 🔴 A merge the cockpit started and did not finish now completes the work. The gap between "the merge call returned" and "the ticket is closed and the worker retired" was open, and it needed a human every time (#4868).
- A merge in flight is not a merge that failed. One merger per PR, and the outcome is read back before it is reported (#5624). An out-of-band ready flip is recorded, and the record is read back (#5610).
- A ticket can outlive its work. The lane is re-checked BEFORE the slot is spent, and the check grades the answer instead of guessing at it (#4878).
- The drain brake brakes the drain, not the review. One operator brake silently held reviewer dispatch for 22 hours; a braked pipeline now says it is braked (#5607).
- Merged PRs read REMED on the board because the ledger's classifier never asked the cockpit which PRs were still open (#5540).
- Every surface reads the verdict before it describes one. The budget is a budget fact, not an inference drawn from a verdict nobody looked at (#5527).
- A relay refuses rather than fusing two authors into one message. It asserts the composer's pre-state first, so two messages can never arrive as one (#4894).
The cockpit tells you what is actually running
- The rails name every background agent, not just the reviewer vehicles (#5136).
- The cockpit already knew a worker had stopped — now something reads it. A worker-stall detector, so a wedged lane surfaces instead of sitting quiet (#5626).
- Live Reviews names every row by its ticket, not just its PR number (#5601), and the ROUNDS table renders round times in UTC instead of silently in the viewer's local zone (#5573).
- The War Room's most expensive keystroke asks first — and finally says its own name (#5639).
- Handoff,
/clearand restart stop reporting failure on work that succeeded (#5623).
Light themes, finished
The v1.2.19 seal covered the surfaces we had found. This one covers the class.
- 🔴 The foreground class is swept to ZERO and the guard is ARMED — CI now fails when any cell renders text without resolving a foreground, so the defect cannot return one surface at a time (#5530, #5560).
- The frozen palette the guard could not see. A theme copied at construction never follows a theme change:
theme.Themewraps a map and the setter swaps a new pointer, so every surface that copied the boot palette in was stuck with it. Both halves of a cell can bind correctly and still paint from a dead palette (#5530). - The Projects screen — the founder's own capture, fixed and proven by revert (#5576).
- The ACE composer boot-painted whatever theme was active before the persisted one resolved (#5549), and the cold terminal chrome is now generated AFTER the theme resolves, proven by capturing the painted bytes at launch rather than reasoning about them (#5567).
- The chrome heal verified one of the options it stamped, and the bottom bar had no repair path at all (#5557).
The Gantt, and the charts underneath it
- One key widens the timeline from open-only to every ticket, closed included (#5548).
- The chart stack moved two majors: ntcharts v0.5.1 → v2.2.0, and lipgloss v1 is out of the tree. A Go v2 module lives at a different import path, so
go get -uhad been reporting "current" across two majors of drift — there is now a check for the next silent major (#5564). The Charm stack is bumped past four upstream repaint fixes (#5566).
Measurement honesty
- The storm ceiling was measuring a colourless frame. A test render has no TTY, so the escapes are stripped before the frame is measured — the "safe" size was exact for a render the product never performs. Said plainly, asserted, and not moved (#5546).
- The cockpit allocation ceiling is re-anchored to a measurement, and erosion is visible before the wall (#5545). The cockpit guard measures the SURFACE — geometry × fleet × colour — instead of one point and calling it covered (#5554).
- Sixteen macOS-red golden frames were one GOOS-resolved token, pinned at render rather than regenerated — regenerating would have frozen one platform's reading and broken the other (#5544). Thirty-three more were measured and closed the same way (#5621).
- bubblezone/v2 was measured and recommended AGAINST, with the numbers written down: its marker scanner re-slices the whole frame once per marker, and it would have replaced only 140 of 366 lines of hit-testing. Two live hit-test drifts it was meant to kill are filed instead (#5568).
Smaller, and still yours
- The Team self-serve gate is data, not prose — two gates cleared, and the third is named rather than implied (#5553).
- Every contact address points at
alex@flowforgesoft.com(#5555), and the footer's X link points at the real FlowForge account (#5599). - ADR-0131 — review and merge truth lives in git refs, so the local-only repository is the base case and the forge is optional (#5578).
Known, and stated plainly
- A terminal resize can still panic the cockpit on the Live Reviews screen. The history table rebuilds its columns at a new responsive tier while its row cache, keyed on a different width, hands back rows built for the old one. It is filed with a full root cause and lands next (#5657).
- Three review-lifecycle seams closed in this release were the ones v1.2.19 named as still open. They are closed because they were finally mapped end to end as a single path, not because the test suite grew — unit tests do not cover seams, and every one of these lived in a seam.