KEEL · YARD v0.10.0

Davy

Davy is Keel's writing partner: it drafts prose into the leaf you are working on, one suggestion at a time, and nothing it writes ever enters your book until you accept it. The entire design hangs on one idea — you can always see exactly what the model is looking at. That is the trust story, and it is inspectable in the tool itself.

What Davy sees — the context recipe

Every generation call is assembled from the same recipe. A stable prefix (cached between calls — the single largest cost lever), a volatile middle that changes with the beat you are writing, and the task itself.

CACHED PREFIX — stable, reused across calls S1 style contract S2 cast sheet S3 voice profile S4 world invariants changes rarely → cached → cheap VOLATILE — this beat, this moment V1 keel path: arc → movement → this beat card V2 neighbouring beats (write toward the next) V3 verbatim tail of the prior leaf V5 entity cards on stage V7 retrieved passages V8 DO NOT REVEAL — unpaid promises + truths the reader has not met TASK T1 your instruction T2 output contract: prose only · target length · one sentence per line · end on momentum
The recipe, top to bottom. Empty sections are omitted — except V8, which is always stated.

V8 earns its keep. The dominant AI failure in fiction is resolving tension too early. The do-not-reveal list costs a couple of hundred tokens and prevents most of it. Even before the Ledger has anything to embargo, the section is sent explicitly: “none recorded yet — still: never resolve tension the scene has not earned.” In a flashback it is the only thing keeping the scene from leaking the future.

The flow: instruct → inspect → stream → accept

In the Write view, ^g opens Davy panel on the right. Type what you want:

┌ DAVY ─────────────────────────────┐ │ Kael realises the toll was a name. │ │ Four paragraphs, no dialogue.▏ │ │ │ │ Enter generate │ │ ^; inspect context │ │ Esc close │ └────────────────────────────────────┘

^; opens the inspector — the recipe above, as it will actually be sent, with a token estimate per section. Every section can be pinned or unpinned before you generate.

┌ CONTEXT ───────────────────────────┐ │ ◉ S1 style contract ~0.3k │ │ ◉ S2 cast sheet ~0.4k │ │ ◉ S3 voice profile ~0.6k │ │ ◉ V1 keel path ~0.5k │ │ ○ V3 verbatim tail ~1.2k │ ← unpinned: excluded │ ◉ V8 do not reveal ~0.1k │ │ ◉ T1 the ask · T2 contract ~0.1k │ │ │ │ Space pin/unpin · Enter generate · Esc back │ └────────────────────────────────────┘

Then the draft streams in. Esc cancels mid-stream. When it finishes, you review:

│ He counted the coins twice on the │ │ road, and both times arrived at │ │ six, which was how he knew the │ │ counting was not what went wrong. │ │ │ │ a accept · r reject │ │ $0.03 this call · $0.14 today │
Nothing is written until you accept. a inserts the suggestion at your cursor; r or Esc discards it without a trace. Every accepted span is recorded in .keel/provenance.jsonl, and the foot shows your leaf's ✎ AI-density — an honest answer if a publisher ever asks.

What it costs, and which model runs

Different jobs ride different models — prose rides the mid-tier, structural reasoning rides the top, mechanical lint rides the cheapest:

DAVY.draft / continueclaude-sonnet-5 — $3 in / $15 out per MTok
editor.line · ledger.extractclaude-sonnet-5
architect · continuity · readerclaude-opus-5 — $5 in / $25 out per MTok
editor.style_lintclaude-haiku-4-5 — $1 in / $5 out per MTok

The cached prefix bills at a tenth of the input rate on reuse, which is why the stable sections exist. Every call is logged; the meter is one command away:

$ keel ai usage today $0.14 30 days $2.87

Setup — and writing without a key

ANTHROPIC_API_KEYset it in your environment and Davy is live
KEEL_AI_MOCK=<file>offline mode: streams the file's text as the “draft” — used by every test, useful for demos
neither setDavy tells you loudly, and everything else in Keel works untouched

Davy also works from the command line — same recipe, streamed to stdout, nothing written to the store:

$ keel ai draft s-0068 -i "Continue the scene." context: 9 sections · ~4.2k tokens The ferryman did not look up... — claude-sonnet-5 · $0.0310 this call

Proofreading — the Editor's pass

The same machinery powers proofreading, in the status chain rather than the margin. keel proofread s-0068 runs a strict copy-editing pass: objective errors only — spelling, grammar, doubled words — never style. You see a word-level diff first; nothing applies without --accept.

$ keel proofread s-0068 s-0068 r4 — corrections ([-…-] {+…+}): He [-walkked-]{+walked+} to the gate. The toll [-was was-]{+was+} memory. apply with `keel proofread s-0068 --accept` — nothing was written

Accepting applies the corrections as a new revision and marks it proofread. The mark is per revision — edit the leaf again and it clears. Unproofread leaves show as in keel status and as warnings on render and export. A human pass counts too: --mark-only records it without the AI.

Keys

^gopen Davy (Write view)
Entergenerate from the instruction
^;inspect the context — j/k move, Space pin/unpin
Escback / cancel the stream / discard
a · raccept · reject the finished draft