keel.pub yard

Changelog

Versioning is x.y.z — major.minor.bugfix (owner rule 2026-08-28): a bug

fix bumps the patch, a minor feature round bumps the minor, and any

component reaching 20 flips over to the next (x.y.20 → x.(y+1).0). A major

bump marks a massive dev sprint — rare, owner permission only. The

workspace Cargo.toml is the single source of the number; the TUI head

and the Yard display it. Every bump cuts its section out of [Unreleased].

[Unreleased]

[2.2.0] — 2026-08-31

The publishing round (backlog #41): the pipeline anchors to what can

physically be printed, and the whole road from finished book to print

job is built — dark until go-live.

Bookvault and Cloudprinter recorded as later candidates behind the

provider abstraction). The yard's new client speaks OAuth2 to the

SANDBOX by default; production demands the explicit PRINT_LIVE=1

secret and every provider action is disabled until LULU_CLIENT_KEY/

SECRET exist. Nothing prints until the owner flips the switch.

tools/lulu/pod-packages.json — 3,277 real pod_package_ids with page

ranges, paper bulk, and list-price estimates. Both sides validate

against it; a SKU keel would compose that Lulu cannot manufacture is

refused at check-in and at submission.

royal join the trim table on both sides, each proven by `keel geometry

--check`. The UK trade trims stay renderable but are flagged

screen-only everywhere (Lulu prints none of them). New series seed at

novella — the closest printable trim to b-format; the sample follows

(parity hashes re-pinned from the release binary).

coil · saddle · casewrap · linen · wire-o), five papers, B&W/color,

standard/premium, finish, linen/foil colors, quantity, shipping level

— a frozen card seeded at init, edited in the yard, validated against

the catalogue on both sides.

spine + front cover, spine sized from the measured page count × the

paper's bulk, 0.125in bleed, spine text auto-omitted under 6mm, back

cover carrying the design card's new back_cover_text + imprint with

a clear barcode zone. The yard re-verifies every wrap against Lulu's

cover-dimensions endpoint before submission — a mismatched spine

refuses loudly.

the true page count via typst, renders the wrap, and pushes both to

the yard (--local renders without pushing). The TUI gains no other

surface — the standing rule lands in SPEC: the TUI is for writing;

user management, publishing, billing, and approvals live in the yard.

the m-print editor with live SKU echo and list-price estimate, the

ship-to address (carriers demand a phone number), Lulu validation /

five-level quotes / submission / cancel / status timeline with

tracking, an HMAC-verified status webhook with lazy refresh as the

auto-stop fallback — and RFQ lines for tier-2 bulk runs (Markono,

PrintNinja, QinPrinting researched: ~1,000-copy offset on bulky cream

stock is the realistic mass-market-style run; Lulu's acid-free stock

can't be that product), advanced by hand through their own statuses.

Print packages are VERSIONED and served to Lulu through revocable

unguessable tokens.

Alegreya, Vollkorn, Libre Baskerville, Source Serif 4, Spectral, and

Cormorant Garamond (display-grade) join EB Garamond — vendored (OFL),

calibrated per face against typst renders, embedded in the EPUB, and

chosen on the design page with a rendered one-page specimen per face.

Lulu prints any embedded face; the menu is keel's own constraint.

[2.1.4] — 2026-08-30

The lowercase convention reaches everywhere: every Rust string literal

and comment (help overlay, verb output, doc comments — 55 files) and

SPEC.md itself now write the yard, the helm, davy, the ledger, the

loft, plank, planking, the worldline. The sweep masked strings and

comments so code identifiers (View::Yard, DavyPanel, Store::Yard) were

never touched; book titles and all-caps treatments keep their case.

BACKLOG and CHANGELOG history stays as written.

[2.1.3] — 2026-08-30

The tension sunset, preview's own key, and the floating footer.

work"). The map view's sparkline, the rail's tension chip, the yard

scene form's field, the tree rollup, and the amend-diff entry are all

gone; the docs and mock illustrations no longer show it. The scene

contract SUNSETS the field gracefully: tension: still PARSES so

every pre-2.1.3 scene opens, but it is never emitted — the next

check-in scrubs it (Rust skip_serializing, yard codec drop; both

sides tested). The showcase sample no longer writes it.

symmetric with i — p in from interactive mode, Esc out. F5 stays a

synonym everywhere, and the only entry while editing (plain p is

prose there). Help overlay and manual updated.

[2.1.2] — 2026-08-30

The live-review continues: the invisible-diagram bug, the lowercase

convention, and three site behaviors.

carried an unscoped <style>text{fill:ink}</style> — document-scoped

in HTML, it repainted every text in all sixteen chapters' figures

ink-on-ink (the "so many pieces missing" TUI tour). Scoped by class;

gotcha recorded in SPEC. Stale version strings inside illustrations

(v1.3.0, v0.11.0) dropped.

SPEC): the yard, the helm, davy, the ledger, the loft, plank,

planking, the worldline — mid-sentence, at sentence start, and in

titles, matching the keel.x wordmark style. Swept across the site and

docs; caps survive only as typographic treatments and in book titles.

docs scrollspy nav and anchors offset beneath it.

holds it for 60 seconds, then the rotation resumes.

[2.1.1] — 2026-08-30

The keel.pub polish round, live with the owner — and the login incident,

found and hardened the same night.

chapter on a single scrollable page; the LHS nav is a scrollspy that

tracks the section under the reading line and jumps on click. The

sixteen per-chapter templates merged into docs/all.html; old chapter

URLs 301 to their anchors. /how-to-use/ (the Begin group) keeps its

own pages.

the click lands on the card or its dot (the highlight selectors had

silently broken when the strip moved inside the carousel wrapper) —

and the page reads ~30% wider (62rem → 80rem).

hairline card.

ADMIN_PASSWORD secret — a machine without it had silently reset the

prod admin password to the test default. The seed now refuses outside

DEBUG, failing the deploy's release_command instead. Production login

is admin/mvp by explicit owner decision (2026-08-30, not

mission-critical yet), set via the secret so the guard stays armed.

[2.1.0] — 2026-08-30

The feedback round: five backlog features land in one session — the

worldline learns to fork, unknown names capture themselves, and three

new verdicts (contract, first-read, print-readiness) arrive.

branch: keel new m-worldline --name <branch> creates the card (the

card IS the branch — a duplicate create refuses), co/ci edits its

fork and optional rejoin points, and scenes opt on via

story_time.strand. Temporal mode draws the fork (┬), the branch

strand below with its scenes, and the rejoin curving home — a drawing

rule, not a merge; open-ended branches trail ⋯. Chronological mode

keeps one line with ◆ branch marks; an unmatched strand tag renders ?

— visible, never silently mainlined. Story-time branching only:

version control stays dead.

markers naming entities that don't exist (@ref{Hollow Gate} →

e-hollow-gate); the quick-capture overlay lists them — j/k select,

h/l pick the kind (character · location · faction · lore), Enter

creates the stub via the sibling CLI without leaving the scene.

Check-in warns about unknown refs (never blocks), and the Codex sees

new entities immediately.

deliver the contract's input → output? A verdict (delivered · partial

· missed) with quoted evidence and up to three gaps. Ephemeral by

owner decision — nothing stored, nothing gated. Rides sonnet

(verify.contract).

confused / guessed it / landed. The reader sees only the stripped

prose of the chapters up to and including the target, never the

contracts, ledger, or spine — the one agent that catches

author-knowledge leakage. Opus (reader.react), on demand, ephemeral.

book: CSS derived from the page config and m-design (face, size,

leading, justification, opener treatment), EB Garamond roman + italic

embedded, and the Yard's cover as the EPUB cover. `keel export

--print` emits the print-on-demand interior PDF — the exact-trim book

block built coverless (print-identical by the Round 2 cover decision),

no bleed, no crop marks: the KDP/IngramSpark "interior" file.

manual chapters updated; the in-app help too. Backlog: #41 publishing

workflow engine and #42 roles redesign (Super Admin / Story Master /

Writer / Reader) recorded for later rounds.

[2.0.0] — 2026-08-29

The simplification — the owner's redesign of the core model, a clean

break (no migration; prod and the sample reseed). The six-level spine

collapses to the near-universal writer's shape, and the collaboration

loop (comments + a pull-request queue) arrives.

card carries the ordered scenes: list — the list IS the spine;

scenes keep flat s-#### ids so reordering is one card edit. Unlisted

scenes surface visibly as orphans, everywhere.

(input / output / overview, optional pov / story_time /

tension / word_budget) over the Plank prose body. @page markers

subdivide the body into drafting pages (render as nothing); the foot

shows page 2/5 and ^PgUp/^PgDn jump the seams. The Helm edits the

body only — the contract is held aside and re-attached on save.

writes. Review statuses per scene: ○ draft · ◐ in-review · ● canon.

in-review; the Yard's approval queue lists it; the book admin lands

canon with an honest checkout/checkin.

replies, taggable to an editor, either side marks it done. The web

authors them; the Helm's ^k overlay lists threads and d resolves

them through the API.

(⛔), input → the predecessor's output (⛔), anchored promises/facts

(⚠ tracked debt). Ledger anchors are scene ids; a fact's revealed_at

is (arc, position). Frontier = the last scene in tree order with

prose — where the book runs dry.

keyed to the open scene, so ^g fills in the instruction and starts

streaming immediately; the recipe's V1/V2 are now the scene contract

and its neighbours. Proofread's output ceiling doubles to 16k tokens.

regenerated for the new model (315 Rust + 61 Yard tests green; the

Store::Yard e2e drives review → approve → canon and comments live).

[1.4.0] — 2026-08-28

The backlog round: the preview grows a table of contents, the prose gets

an ear for echoes, the morning gets a ritual, and the manual catches up.

every chapter opener (physical page + displayed folio, via typst

query); Preview mode shows a CONTENTS column with live page numbers —

j/k + Enter or click to jump. Inside the rendered window the jump is

instant; outside, a fresh 16-page window renders around the target.

a common word, not a name) repeated within ~two pages underlines

yellow on both occurrences — a nudge beside spellcheck on the idle

tick, never an error.

due-first, unproofread leaves, yesterday's/today's words, and one

suggested next action. In the palette; the verb stays for scripts.

per-revision proofread mark; ✎% is the real accepted-Davy share from

the provenance log. The placeholders are gone.

keelhelm.exe, the two modes, the toolbar and mouse, in-app pages, the

console lesson; the footprint learns keel-wind and both binaries).

[1.3.0] — 2026-08-28

The Helm learns its manners: two modes, a mouse, an icon, and one door

into the editor.

The app round (2026-08-28, owner requests)

the draw pass registers (zones live exactly where the pixels are

painted) — lens tabs switch, rail rows and codex names select,

worldline marks select and a second click opens, toolbar chips as

before. The wheel scrolls the help/changelog/console overlays, steps

list selections, and turns preview pages; the windowed shell now

forwards wheel events. The write chip left the toolbar — i is the

editor's door; clicking into edit mode lands typing like i does.

←→ rove the toolbar with Enter to activate, Tab/⇧Tab step the lens

strip, ↑↓ walk the active view's content) and EDIT mode (every plain

key belongs to the prose). i enters the editor straight into typing;

Esc taps out — insert › normal › interface. The badge top right names

the mode in its own color and the key that flips it. Retired: the 1–7

view digits, ^←/^→ on the lens strip, and quitting on q from inside

the editor. The worldline walks with ↑↓ now (←→ is nav). F5 preview

returns to whichever mode it came from; Esc out of the editor (or

preview) lands on the map — interactive mode's home. The badge reads

INTERACTIVE (light green) / EDITING (light orange), naming the flip key.

"k." mark, ink on paper with the red dot (tools/icon/keel-icon.typ;

build-icon.ps1 renders the .ico + window PNG; winresource embeds it).

local or hosted series now — new series are made in the Yard (`keel

init / auto-novel` remain as debug CLI verbs). An empty picker points

at the Yard.

missing, launch. Sample-building and Yard docker auto-start removed.

OS-preference fallback is gone) — an explicit bulb choice is still

remembered client-side and wins.

[1.2.0] — 2026-08-28

The Helm leaves the terminal, and the book leaves the defaults: one day,

two rounds — the native windowed app, then the design card driving the

rendered PDF end to end.

The Helm becomes a native windowed app — keelhelm.exe (overnight 2026-08-28)

edge-to-edge in a real window by wgpu — vendored JetBrains Mono with true

bold/italic (DejaVu Sans Mono fallback), themed ground, F11 borderless

fullscreen, close-safe worker shutdown. winit runs the window on the main

thread; the unchanged keel-tui shell runs on a worker thread fed

translated events (macOS ⌘ maps to ^). The terminal TUI survives as a

debug fallback: KEEL_DEBUG_TUI=1 keel. start-keel.ps1 launches the

app; the dotted keel.helm.exe copy hack is gone.

a ~16-page window around the leaf being written (`keel render

--pages-png`), browsable with ←/→, composited full-resolution as a

wgpu texture in the preview pane.

with hit zones drawn from the same table the mouse reducer checks.

headers, accent key columns, true italics, Plank directives in color,

double-line frame.

strip under the head); the help grew getting-started content; keel.pub

gained the mobile hamburger nav.

Round 2 — design → PDF (2026-08-28)

The book designed in the browser is now the book typst produces.

emitted Rust-side (byte parity with the Yard's codec pinned by tests and

a fixture regenerated from a real keel co m-design); bad styles refuse

check-in loudly. m-design joins the init seeds on both sides and both

sample generators (18 → 19 objects; parity hash re-verified).

pages, contents style, opener style — and the page geometry itself:

book.typ no longer hardcodes B-format; trim/margins/face/size/leading

flow from m-vol-01 [page] into the render, so demy actually changes

the page. Pre-Round-2 stores render on in-memory defaults (render stays

read-only; the Yard's design page keeps the self-heal).

two-line · hairline) and four chapter openers (sunk-caps ·

drop-cap via @preview/droplet 0.3.1, imported lazily so the other

styles render offline · raised-cap on the unstretched baseline grid ·

ornament). The generator wraps each chapter's first scene in

#firstScene, splitting the initial Rust-side; a scene opening with

markup degrades honestly to the plain body.

(the public /cover/<slug> stays the web's door); yard-bound renders

fetch it as page 1 plus a blank verso, with the folio counter reset at

the half-title so print folios never move. No cover is not an error;

a network failure falls back to the cached cover with a warning.

every italic in the book (part/chapter titles, epigraphs, thoughts) had

been silently rendering upright.

sys.inputs and the new flag proves lines-per-page against a real typst

render of the volume's actual geometry (34/35 at B-format, 37/38 demy).

the shortcut shown in the foot and rail. The ? help is rewritten as

a getting-started guide: the screen decoded (head, rail, foot fields),

the full Plank @ directive reference, Davy, tension, the console

verbs, and step-by-step workflows.

hamburger; the docs chapter list becomes a Chapters toggle.

[1.1.0] — 2026-08-27

The two 2026-08-27 lines rejoin: the web overhaul, developed in parallel

and released as 0.11.0, merges onto the signed-off 1.0.0 — one history,

both surfaces current. Naming reconciled in the merge: the app and its

editor engine share one name, the Helm (keel.helm); the web line's

short-lived "Rigging" split is retired.

[1.0.0] — 2026-08-27

The MVP, signed off. Two surfaces, one store — and now the Helm reaches

the hosted store too. (Owner declaration 2026-08-27 with Store::Yard

landed; the sign-off supersedes the separate verification pass.)

Store::Yard — the last feature before 1.0.0

trait over the Yard's HTTP API: checkout/checkin (changesets included),

locks, log, list — same semantics, same loud errors, mapped from the

Yard's machine-readable {error, code} bodies onto StoreError (new

variants: Transport, Unauthorized, Protocol).

(object, rev)): pinned-rev reads never re-cross the network; checkout,

checkin, create, and head reads seed it from their own responses. The

index rebuild reads at pinned head revisions and so runs mostly from

cache on a remote store.

keel init --yard <slug> binds a directory to a hosted series; the

series picker lists hosted series as "slug (yard)" rows when signed in

and materializes the workspace on first open. Store construction moved

after the TUI login (a yard store needs that session).

against a real local Yard on sqlite (no Docker).

The fleet (owner decisions)

the TUI app and its editor engine; the "C-shell" label retires. CLI

verbs are debug-only (zero-CLI hardened). deploy.ps1 ships the Yard

to keel.pub in one command; .gitattributes pins byte-exact checkouts.

editor engine ProseView is now the Helm (crate keel-prose →

keel-helm). keel, the Yard, Plank, and the Ledger keep their names.

Renamed throughout both surfaces; model-routing keys are now

davy.draft / davy.continue.

[0.11.0] — 2026-08-27

keel.pub grows up: a public face, real collaborators, and the whole book

designed from the browser.

The site (keel.pub)

diagram, the keel.x module rolodex (six illustrated mockups with dot

navigation and cross-fade), and a Start-today call to action. Content

fades softly into view on load.

version, API, and Admin left the header (Admin and the changelog live

in the footer); the wordmark reads keel.pub and always goes home.

strip); /docs/ keeps the sixteen reference chapters; the changelog

page widened; the footer sticks to the viewport bottom.

persisted, defaulting to the OS preference. Website only.

The Yard (né the Planner — keel.yard, at /yard/)

creator becomes book admin, the superuser (exactly one — the owner)

sees everything. The Chart was this rename's one-day interim name;

301s cover /planner/ and /chart/.

New series, Activity (with the approval queue — the book admin lands

◐ pending spine cards into ● canon via an ordinary checkin),

Previews, Profile (name, email, initials disc), Logout.

signing in to the admin or the Yard signs you out of the other.

imprint, dedication, epigraph, five contents styles, and four chapter

openers on the new self-healed m-design card; cover upload served

at /cover/<slug>; a live geometry echo. The render pipeline reads

it in Round 2.

The admin (superuser only)

management with membership inlines, token revocation by prefix,

stale-lock breaking, per-series storage stats, PreviewPdf and

CoverImage registered.

[0.10.0] — 2026-08-26

The Yard becomes an author's workspace, and the road to keel.pub opens.

The Planner (author-facing book setup)

object set, instantly usable in planner and TUI), and the one-click

sample-novel builder.

beats → leaves with status glyphs ◌○◐●, word counts and rollups,

inline add-child at every level, id conventions enforced, the write

gate honored for new leaves.

checkout → checkin revision as yard:<user>; a leaf locked by a TUI

writer shows who holds it and since when — never force-unlocked.

(fixtures generated by the release binary; 17 parity tests).

byte-identical to the Rust keel auto-novel --offline output.

The manual and the shell

getting-started, hierarchy & glossary with recommended ratios, full

annotated file footprint, and everything between.

place; a bare keel outside a workspace opens the series picker.

Going online (Fly.io + keel.pub)

whitenoise, TLS-proxy-aware cookies, ADMIN_PASSWORD secret — the

printed test login shows in local dev only.

Fixes

with the changelog link, ? help overlay on Windows, seeded password

self-heals on every startup.

[0.9.0] — 2026-08-25

The entire solo tool, built in one run (M0–M7 plus the morning's decisions).

The writing surface

typewriter scrolling, focus dimming, decoration spans, vim-lite keys,

undo/redo. ^e hands off to $EDITOR and reloads.

emitted never typed; fmt on save, strip to CommonMark, errors block

check-in. ^m contextual markup palette.

accept/reject, --mark-only for human passes), per-revision ✂ marks,

warnings at render/export.

Structure

position; parents required in order; containers hold premise+intent only.

can never outrun its beat.

budgets, the Map with the tension sparkline.

temporal across five customizable eras (Mythic · Old · Present · Future ·

Far Future); Enter opens a leaf to write.

Memory & change

stale-base failures are loud, reads never lock.

with due-bys, quote-anchored refs; the two clocks (true_at / known_at)

and the do-not-reveal list.

--changeset reconciles, land` refuses unresolved ⛔ unless waived with

the reason recorded, warnings become tracked ⚠ stale debt; abandon

walks heads back over retained history.

The Ghost

until accepted. ^; inspects the exact context (pinnable sections).

provenance log and the ✎% density; cost meter (keel ai usage).

The book

running heads, recto/verso, generated contents, sunk openers, the exact

13.6pt line grid (~300 words/page verified on renders).

via pandoc, named snapshots, keel stats burn-down.

Groundwork for M8

configured), versioning surfaced in the TUI head.