Release
v1.2.11
What shipped, in numbers
- 19
- PRs merged
- 2,825,197
- Lines added
- 774,669
- Code lines
- Code
- 774,669
- Tests
- 816,338
- Docs
- 1,234,190
- Sum · code + tests + docs
- 2,825,197
of 19 merged
- bug 5 26%
- feature 10 53%
- polish 0 0%
- docs 3 16%
- groundwork 1 5%
- unclassified 0 0%
since v1.2.10 · tagged
What shipped
The release where "fixed" had to prove itself. A blink that four releases believed was solved turned out to be guarded by a comment claiming it was solved; the waves seal stopped being an announcement and became a mutation harness that names which clauses fail; the cockpit stopped exhausting its own GitHub budget in fourteen minutes; and the roster grew past engineering into the commercial half of a company.
The cockpit stops self-DoSing the GitHub API
Measured at 348 gh calls in 60 seconds — ~20,880/hour against a 5,000/hour GraphQL budget. The cockpit burned a fresh budget in ~14 minutes, then kept hammering failing calls until the next reset, so for most of every hour every gh-backed surface was dead. Three defect classes, fixed as three independent slices:
- The ship-state force never disarmed — its conditions ("a merged-but-unshipped row exists" + "5s elapsed") stay satisfied indefinitely, because Rule #12 keeps a merged PR's ticket open pending founder approval. It fired every ~5s for the life of the cockpit (~720 calls/hour) from a guard working exactly as designed. Now bounded, and re-armed only by an observed merge (#4716 slice 1).
- 1+N becomes 2 — the merge queue resolved heads one
gh pr viewper PR; a batchedgh pr listnow returns every open PR's head, plus one deliberate second call because--json commentstruncates to the oldest 100. At N≈10 on the 30s cadence that is 11 calls/30s down to 2 — ~1,080 calls/hour reclaimed (#4716 slice 2). - Failure now DECELERATES the loop — a rate-limited call fails in ~200ms against ~600ms for real work, so being rate-limited made the cockpit spawn
ghmore often than when healthy.ghgov.Backoffmakes the retry interval monotone non-decreasing in failures, with additive-only jitter so a failing loop can never retry sooner than a healthy one (#4716 slice 3). - The crew-timeout default is raised off the 15-minute guillotine, and auto-dispatched crews now carry it (#4698).
Waves — the seal made falsifiable
- The workers-queue blink is dead after four releases. It was a Busy⇄Ready state flap, and it survived because
idle.goalready carried a 2s damper whose comment claimed it had solved this exact symptom — so anyone grepping for the blink found reassurance and moved on. The comment was wrong twice: on magnitude (it assumed the silence was the ~1s gap between tool calls; the real silence is the tool call itself, 3–60s+) and on symmetry (it damped one direction, so the pair alternated at any window width). The row now demotes on the prompt evidence the machine already computes, not on silence — which also makes "waiting: your reply" true whenever it renders. The old comment is kept and inverted, quoting itself as a warning, so the next reader finds the trap and its history (#4692). - The wave seal is now a definition, not a claim — ADR-0120 states what "sealed" means clause by clause, a mutation harness proves each check can fail, and
TestWaveSeal_C1..C4ships with its remaining gap named rather than hidden — one NAMED GAP at head (the presence half of the blink, owned by #4692), which the harness refuses to call SEAL PROVEN while it stands, and whichFF_WAVE_SEAL_STRICT=1runs red on demand. A seal that can name its own gaps is the first one worth the word (#4298). - Wave lane truth — a merged-and-closed lane now counts done and is never respawned. Root cause was a case-sensitive
stateReasonparse:ghemitsCOMPLETEDand the code compared lowercase, so the closed-ticket snapshot came back unconditionally empty, 0 of 200 (#4708). - Wave-ETA forecast on WaveView with an honest distinct chip (#4624), the
wscreen reframed under BRIEF B (#4625), the estimate tile centred (#4626), sequencer heartbeat symmetric with the WS-1 lease (#4627). - BEHIND visibility in the War Room — a red ◇ diamond, an additive ▮ ticket mark, and a behind-only filter (#4661).
Agents — the GTM tier (roster 37 → 41)
The bench now covers the commercial half of a company: two Customer Success agents and two paid-media agents, each pairing a strategy head with an execution leaf.
fft-cs-architect(head) — Customer Success strategy: onboarding/adoption/retention/expansion architecture, health-score design, churn-risk modelling, QBR + success-plan design, segmented playbook authoring, and the CS tool landscape with the NRR/GRR math (#4791).fft-cs-analyst(leaf) — executes the CS play brief against real accounts: playbooks, health reports, touchpoint cadence, renewal runway, save plays, and structured outcome reports back to the head (#4791).fft-paid-media-architect(head) — paid-media / tráfego-pago strategy: market and audience research, positioning and offer design, sales-funnel architecture, Meta + Google/YouTube channel mix, campaign and creative direction, budget and bidding strategy, and the measurement plan with named success metrics (#4791).fft-media-buyer(leaf) — operates the actual consoles: Meta Ads Manager / Business Manager and Google Ads / YouTube — account + pixel/CAPI + conversion setup, audience build, campaign→ad-set→ad construction, budget/bid entry, a hard pre-launch QA gate, and the post-launch optimisation loop (#4791).- Every surface that asserts the roster size now reads 41, and the pre-existing 36-vs-37 drift — the doctor gate said 36 while the managed CLAUDE.md mirror said 37, and both shipped to customers — is reconciled (#4791).
- The roster also ships as a branded, send-ready PDF in A4 and US Letter, rendered from committed source so the next roster change is a re-render rather than a redraw (#4805).
The marketing site — rebuilt on guards, not on copy edits
The site stopped asserting FlowForge's shape by hand. Five fail-closed gates now make whole classes of defect unshippable, each with a reviewed allowlist rather than a kill switch:
- G-A
no-literal-money— no$amount, seat count, discount percentage or cadence-derived total may be typed into.astro/.md; everything renders fromplans.tsthrough an expression. It retired a live$66that claimed to cover 2 Team seats when 2 × $35 = $70 (#4728). - G-B token-literal ban — no raw hex outside the token layer, on the T1/T2/T3 Direction C substrate (#4726).
- G-D facts —
gen-facts.mjsgenerates a committedfacts.ts; the site's factual claims are derived, not typed (#4727). - G-E route-nav invariant — every href resolves to a built route or an on-page anchor; zero
#hrefs. Seven dead footer links are gone, including Privacy, on a site taking real cards (#4733). The gate now also covers brand assets (#4785). - PR-3 md-claim gate — prose claims under
v3/site/**are allowlisted;LANDING_PAGE_CONTENT.mdleft the blast radius entirely (#4730).
Routes and content: Privacy · Terms · Security shipped (#4717), a designed /404 (#4724), a real /contact route behind the Enterprise CTA (#4725), the ribbon/logo collision fixed by giving each its own grid lane (#4729), the hero fold rebuilt on candidate D with a typed fold contract (#4734), "Order on Chaos" on Direction C with its orphaned styles deleted rather than left looking live (#4736), What's-inside plus The Bench roster wall generated from facts (#4739), Proof of Work with the two roadmap blocks unified into one component (#4740), Pricing + ROI with both cadences at rest (#4742), the Final CTA and footer legal block restored (#4744).
The four social preview cards were advertising a free tier at $50/seat — served from the CDN, and what rendered whenever anyone shared a link. Redrawn against plans.ts canon; there is no free tier, and the prices are Solo 22 · Team 35/dev · Enterprise 99 (#4785). A production Core Web Vitals baseline is committed so the target is falsifiable rather than asserted (#4723), and the live Stripe Team price IDs are verified hydrated (#4720).
Pipeline and desktop
- A persistent observer —
loop autofire --drainwas one-shot: it drained the board and exited, so a worker that finished remediating afterwards sat unwatched. The observer now keeps watching, and every held PR reports why it is held — not-green, no-GOLDEN-at-head, escalated, ratification wall, conflict — never a bare "held" (#4823). - The desktop app stops shipping a licensing-blind bundled CLI — it refuses, stamps, and asserts at the artifact, with ADR-0119 recording the casca/CLI identity seam (#4316).
Tickets and hierarchy
- One shared umbrella predicate — the writer and the reader stopped disagreeing, so legacy and closed parents nest again (#4762).
- The War Room screen name rename is finished (#4718).
Plans and design records
- ForgePlay 4 — Go-To-Market / Paid Media — the fourth play, designed and founder-ratified: its DAG, exactly two founder gates, and a complete 36-artifact map covering campaign plan through per-asset creative specs including the long-form video roteiro. Production is deliberately outside the play; it stops at production-ready specs and the launch package (#4792).
- Volan 2.0 planning and the Ateliê pitch, both authored in Brazilian Portuguese (#4806, #4807).