Skip to content
All releases

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 view per PR; a batched gh pr list now returns every open PR's head, plus one deliberate second call because --json comments truncates 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 gh more often than when healthy. ghgov.Backoff makes 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.go already 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..C4 ships 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 which FF_WAVE_SEAL_STRICT=1 runs 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 stateReason parse: gh emits COMPLETED and 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 w screen 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 from plans.ts through an expression. It retired a live $66 that 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.mjs generates a committed facts.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.md left 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 --drain was 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).

v1.2.11 — 19 PRs, 2.8M lines, made with FlowForge