TestkennBreathline Federation

Chapter card → reviewed spec

A chapter is a contract.
Testkenn turns it into one.

Every Breathline Federation title carries the same five fields on its card: title, promise, beats, keywords, BISAC. Testkenn treats those five as the source of truth for the backend that ships alongside the book — Gemini drafts the spec, Claude scores it against the series rubric, and no spec reaches the encoder without a human pressing Approve.

01 — INTAKE

Paste the card, keep the fields honest

The form below is the exact shape of the POST /api/cards body. Beats are one per line — the drafter maps each beat to at least one endpoint or state transition, so a vague beat produces a vague spec. BISAC codes are validated against the subject list before the card is written to SQLite.

Chapter card

unsaved

02 — TWO-STAGE PIPELINE

Draft on the left, criticism on the right

Stage one asks Gemini for a backend spec in YAML: entities, endpoints, state machine, and the beat-to-endpoint map. Stage two hands that YAML to Claude with the series rubric and no ability to edit it — the reviewer only scores and lists blockers. Same separation BeardSign uses: the model that writes is never the model that signs off.

Stage 1

Gemini draft — spec.yaml

No draft yet. Submit a card above, or load the S07 example.
Stage 2

Claude review — score & blockers

The reviewer runs once a draft exists.

03 — HUMAN PANEL

The gate is a person, not a threshold

A score of 88 does not ship anything. Approve writes the spec to specs with status='approved' and stamps the reviewer; Fix re-runs stage one with your note appended as a constraint; Regenerate discards the draft and starts from the card with a fresh seed. Every press lands in review_events — the history below is that table.

Decision

awaiting draft

review_events

  • Nothing logged in this session yet.

04 — SERIES TRACKER

S0 through S13, and where each one stopped

Fourteen stages, one row each. Status moves in one direction — draft, review, approved, encoded — except when a reviewer sends a spec back, which resets it to draft and keeps the old revision in history. Timestamps are the last state change, not the last read.

Draft In review Approved Encoded
Stage Title Status Score BISAC Last change

05 — DATA MODEL

Four tables, no ORM

SQLite through better-sqlite3, synchronous and single-file. Cards are immutable once drafted — an edit writes a new revision rather than mutating the row, so a spec always points at the exact card text it was generated from.

schema.sql

sqlite

        

cards

The five card fields plus stage, revision and author. Beats stored as a JSON array; keywords normalised to lowercase and deduplicated on insert.

specs

Raw YAML from stage one, the model and prompt hash that produced it, and status. One card can hold many specs; only one carries approved.

reviews

Stage two output: four criterion scores, the blocker list, and the total. Stored verbatim so a rubric change never rewrites past verdicts.

review_events

Append-only. Every Fix, Regenerate and Approve with actor, note and timestamp — this is what the tracker's "last change" column reads from.