Deterministic gates that block the launch: release readiness and scope integrity
Three parallel workers built pure, local-only gates — a release-readiness scanner and a scope-integrity decision model — that refuse to call Talkak shippable until owner and legal facts are resolved. Honest caveat: the readiness gate is a manual script, not yet CI-wired.
The fastest way to ship a bad launch is to let an eager agent "polish until green." So before
the next Talkak build I wanted the opposite reflex: a deterministic gate that refuses to
declare the product shippable while real owner/legal facts are still unresolved. Three parallel
workers landed that on main on 2026-06-17 — REL02 (trust-claim cleanup), REL03 (readiness
gate), and SIG01 (scope-integrity model).
REL03 — a scanner that reports blockers instead of inventing facts
packages/shared/src/releaseReadinessGate.ts is a pure function: it takes file contents in,
emits a ReleaseReadinessGateReport out. No filesystem, no network, no LLM. The CLI wrapper
scripts/release-readiness-gate.mjs reads a fixed list of release surfaces (landing pages,
launch-plan.md, latest.json, tauri.conf.json, the entitlement files) and feeds them in.
It scans for the things that quietly poison a launch:
- Conflicting prices.
extractPriceClaimsnormalizes every$N/periodit finds; if the set has more than one entry — or the launch plan still records the price asJason picks— it emits a blocker. - Conflicting Merchant-of-Record. LemonSqueezy vs Paddle vs Polar mentions across public and app surfaces.
- Unsupported public claims. A blocklist of regexes for phrases like "records, fact-checks, and remembers everything" and "written by the product it documents."
- Unlabeled managed-AI copy, version drift, notarization conflicts.
Run today, the gate does exactly what it should: pnpm release:readiness exits 1 with
5 blockers, 0 warnings, 2 passes (--dry-run prints the same report but exits 0). The repo
is correctly not release-ready. The point of the gate is to make that verdict mechanical and
unbluffable rather than a vibe.
The honest caveat: it is a manual script, not CI
This is where I have to stay honest with myself. The two workflows in .github/workflows
(ci.yml, regression.yml) run cargo and pnpm tests and Biome — neither calls
release:readiness. A git grep for the gate across .github returns nothing. So today the
gate is a deterministic command a human must remember to run, not an enforced merge blocker.
Calling it a "CI gate" would be exactly the kind of overclaim REL02 was cleaning up. It is a
gate in logic, not yet in wiring; promoting it to a required check is a one-line follow-up.
REL02 — the claim ledger that feeds the scanner
REL03's blocklist isn't arbitrary; it's the codification of REL02's work.
docs/product/release-trust-claim-ledger-2026-06-17.md classifies every public claim as
proven / partial / planned / unsupported, and REL02 made the narrow landing-copy edits
to pull the unsupported ones (broad "fact-checks/remembers everything", "the product wrote this
page", current managed-AI behavior). A sharp friction surfaced here: Biome 1.9.4 processed
0 HTML files — it doesn't lint HTML at all, so the landing edits got no automated lint
coverage. Worth knowing before trusting "biome passed" on a copy change.
SIG01 — feedback is feedback, not a requirement
packages/shared/src/scopeIntegrity.ts is the same shape: a pure combiner,
buildScopeIntegrityDecisionGateReport, fusing structured feedback, blueprint-diff state,
task-packet non-goal checks, and sycophancy/scope-critic output. Its core rule is the anti-
sycophancy discipline I keep relearning: user pressure and medium critic-risk do not silently
become requirements — they raise a captain-review reason. It blocks only on real conditions:
blueprint conflict, ADR-required changes, non-goal violations, an explicit critic block, or high
scope risk. It is phase-1 shared model only — no Mission Control UI, no merge-queue, no
GraphStore persistence, no git scanner (callers pass changed files in).
Where it stands
44 shared tests for REL03, 39 for SIG01, both typecheck-clean. The gates are pure, isolated, and deterministic — the cheap, boring kind of correctness. The remaining work is wiring (CI enforcement) and the facts the gates exist to wait for: owner-confirmed price, one Merchant-of- Record, aligned versions, and notarization state of the actual artifact. The gate's whole value is that it won't let me pretend those are done.