From 645c7e9c22123667514220aa421989f3529a9281 Mon Sep 17 00:00:00 2001 From: Jeff Casimir Date: Thu, 23 Jul 2026 14:49:41 -0600 Subject: [PATCH] feat(ce-write): serve voice guide, exemplars, and lint from the rotunda voice service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The canonical guide now comes from the rotunda MCP voice_guide tool (local files demoted to cache/fallback), the draft stage injects per-register voice_exemplars pairs and gates on voice_lint, and prose-review adds a stylometric pre-pass whose fail blocks ship even when the panel is clean. The draft stage also stops restating guide rules that the compounding guide has since overturned — the fetched guide is the sole source of voice rules. Co-Authored-By: Claude Fable 5 --- .../skills/ce-prose-review/SKILL.md | 16 +++-- .../skills/ce-write/SKILL.md | 25 +++---- .../skills/ce-write/references/draft.md | 66 ++++++++++++------- 3 files changed, 63 insertions(+), 44 deletions(-) diff --git a/plugins/compound-engineering/skills/ce-prose-review/SKILL.md b/plugins/compound-engineering/skills/ce-prose-review/SKILL.md index 9370e03de..367852cec 100644 --- a/plugins/compound-engineering/skills/ce-prose-review/SKILL.md +++ b/plugins/compound-engineering/skills/ce-prose-review/SKILL.md @@ -37,17 +37,22 @@ If no `category: writing` reviewers are found, report: "No writing reviewers fou ## Step 3: Locate the voice guide -Same resolution the reviewers use, so the skill can confirm it exists and pass its path: +The canonical guide is served live; local files are cache and fallback: -1. `docs/writing/voice-guide.md` (project override), else -2. `$HOME/.config/compound-engineering/voice-guide.md` (the live guide). +1. **Voice service (preferred).** If a `rotunda` MCP connection is available, call its `voice_guide` tool, write the body to `$HOME/.config/compound-engineering/voice-guide.md` (refreshing the cache), and use that path. +2. `docs/writing/voice-guide.md` (project override), else +3. `$HOME/.config/compound-engineering/voice-guide.md` (cache — possibly stale). -If neither exists, warn that the panel will fall back to first principles and be much weaker, then proceed (or stop in headless mode). +If none resolves, warn that the panel will fall back to first principles and be much weaker, then proceed (or stop in headless mode). ## Step 4: Read the inputs Read the target draft in full and the brief if provided. These are passed to every reviewer as content (the draft is the whole point of the review; pass it inline, not as a path the subagent must re-open). +## Step 4.5: Stylometric pre-pass + +Before dispatching the panel, get the mechanical verdict. If a `rotunda` MCP connection is available, call `voice_lint` with the draft and its register band (inferred from the brief per the guide's register section). Keep the result for synthesis: the lint measures architecture (sentence mix, paragraph pacing, question and punctuation rates) that human-style review reliably misses — a panel can pass prose that the numbers expose as machine-shaped. Without the connection, skip and note it in the output. + ## Step 5: Dispatch the panel Read `references/prose-reviewer-template.md` for the subagent prompt template. @@ -89,6 +94,9 @@ Collect the seven JSON responses. Then: ### Reads-aloud check +### Stylometric gate + + ### Candidate voice-guide rules ``` diff --git a/plugins/compound-engineering/skills/ce-write/SKILL.md b/plugins/compound-engineering/skills/ce-write/SKILL.md index a9a3a95fd..be18d0b85 100644 --- a/plugins/compound-engineering/skills/ce-write/SKILL.md +++ b/plugins/compound-engineering/skills/ce-write/SKILL.md @@ -24,22 +24,15 @@ Extract from the input: ## Step 2: Locate the voice guide -The voice guide is the single source of truth for how Jeff writes. Find it in priority order: - -```bash -# 1. Project override, if this project has a house voice -VOICE_GUIDE="" -if [ -f "docs/writing/voice-guide.md" ]; then - VOICE_GUIDE="docs/writing/voice-guide.md" -# 2. The live, compounding guide -elif [ -f "$HOME/.config/compound-engineering/voice-guide.md" ]; then - VOICE_GUIDE="$HOME/.config/compound-engineering/voice-guide.md" -fi -``` - -If no guide is found, report: "No voice-guide.md found. Seed it from ce-reviewers-jsl's voice/voice-guide.md into ~/.config/compound-engineering/, or run the Perkins bootstrap. Proceeding will produce generic prose, not Jeff's voice." Then either stop (pipeline mode) or ask whether to proceed. - -Read the voice guide in full before generating anything. It is loaded fresh every run so the latest compounded rules apply. +The voice guide is the single source of truth for how the author writes. The canonical copy is served live; local files are cache and fallback. Resolve in priority order: + +1. **The voice service (preferred).** If a `rotunda` MCP connection is available, call its `voice_guide` tool. Write the returned body to `$HOME/.config/compound-engineering/voice-guide.md` (refreshing the local cache) and use that path as `VOICE_GUIDE`. This guarantees the latest compounded rules on every machine. +2. **Project override:** `docs/writing/voice-guide.md`, when this project has a house voice. +3. **Local cache:** `$HOME/.config/compound-engineering/voice-guide.md` — possibly stale; note that in the run output. + +If none resolves, report: "No voice guide available (no rotunda MCP connection, no local voice-guide.md). Proceeding will produce generic prose, not the author's voice." Then either stop (pipeline mode) or ask whether to proceed. + +Read the voice guide in full before generating anything. ## Step 3: Determine the working directory diff --git a/plugins/compound-engineering/skills/ce-write/references/draft.md b/plugins/compound-engineering/skills/ce-write/references/draft.md index e43156f25..d46843aba 100644 --- a/plugins/compound-engineering/skills/ce-write/references/draft.md +++ b/plugins/compound-engineering/skills/ce-write/references/draft.md @@ -1,46 +1,64 @@ # Stage: draft -Write the piece. This is where the voice guide does its heaviest work — the draft should sound, read, and look like Jeff wrote it, not like a competent stranger did. +Write the piece. This is where the voice guide does its heaviest work — the draft should sound, read, and look like the author wrote it, not like a competent stranger did. ## Read first - The brief at `brief:` — audience, purpose, one job, thesis, medium. - The outline at `outline:` — the section order and per-section ideas. -- The **entire** voice guide. Every section applies now. +- The **entire** voice guide. Every section applies now. The guide is the sole + source of voice rules — do not rely on remembered rules from previous + versions of this skill or from other drafts; the guide compounds and old + rules get overturned. -## Draft against the guide, deliberately +## Pull the exemplars + +Identify the piece's register band from the brief using the guide's register +section (expressive / analytical / formal / technical). If a `rotunda` MCP +connection is available, call `voice_exemplars` with that register and keep the +returned pairs in view while drafting: each pair shows the same content as a +competent generic model wrote it and as the author actually wrote it. **Write +like the author side of the pairs.** The pairs quote private documents — never +copy them into the draft or into public files; they are reference only. -Do not write generically and hope it sounds like Jeff. Write *toward* the guide: +Without the MCP connection, proceed on the guide alone and note the gap in the +run output. -- **Lead with the governing idea** (§2.1, §6). The first lines state the thesis. No runway, no throat-clearing. -- **Reach for Jeff's verbs** (§5): narrow, collapse, absorb, land, resolve, gate, ship, cut. Plain Anglo-Saxon over Latinate abstraction. -- **Use the signature moves where they fit** (§3) — but earn them, don't sprinkle them: - - the triad (group into threes), - - the aphoristic clincher to close a section, - - the em-dash sharpener with a concrete example, - - the framing-question header with a stakes parenthetical, - - the stakes sentence ("if no one owns it, X silently fails"), - - the "X, not Y" reframe, - - honesty markers (⚠, "ruled out:") instead of hedging. -- **Vary sentence length hard** (§4). Long, clause-stacked sentence, then a short hammer. Deliberate fragments are allowed. Read each paragraph aloud in your head; if it drones or you run out of breath, re-cut before moving on. -- **Match the medium profile** (§8): essay = voice-forward, a clincher per section; doc = Summary → Evidence → Why-it-matters skeleton, concrete numbers, minimal adjectives; email = open with the ask or answer, one screen, end with the single next action. -- **Format for the skim** (§7): framing-question or noun-phrase headers, bold inline labels for category list items, short paragraphs, tables where data is parallel, ⚠ for uncertain claims, functional emoji only. -- **Use the right term of art once** (§9), matched to the audience in the brief. Define on first use only if that reader might not know it. +## Draft against the guide, deliberately -## Kill on sight while drafting (§5, §10) +Do not write generically and hope it lands. Write *toward* the guide: identify +the register band first and apply that band's rules, reach for the signature +moves where they fit (and only where they fit — the guide's anti-pattern list +names the manufactured versions), and honor the guide's rhythm and formatting +sections. Read each paragraph aloud in your head; if it drones, re-cut before +moving on. -Do not draft these in the first place: `delve`, `tapestry`, `realm`, `landscape`, `leverage` (verb), `utilize`, `robust` (as filler), `seamless`; the inflation construction **"not just X — it's Y"** (distinct from the *allowed* sharp "X, not Y"); throat-clearing openers; hedges (`honestly`, `arguably`, `somewhat`); empty intensifiers (`very`, `really`). The panel will catch these, but a clean first draft saves a review round. +The architecture matters more than the words. The measured failure mode of +model drafts is structural: sentences welded long, one-beat paragraphs merged +away, questions answered instead of left standing, transitions announced +("I bring this up because…") instead of made. Check the shape of what you +just wrote, not only its vocabulary. ## Procedure -1. Read brief, outline, and the full voice guide. +1. Read brief, outline, the full voice guide, and the register's exemplars. 2. Write the complete draft — every section from the outline, no placeholders. -3. Do one self-pass against §5 and §10 before handing off: cut the slop you can already see. -4. Write `draft.md`. This file is revised in place during the review loop, so write it as the working copy. +3. Self-pass against the guide's diction kill-list and anti-pattern section: + cut the slop you can already see. +4. **Lint the architecture.** If the `rotunda` MCP connection is available, + call `voice_lint` with the draft and the register. `pass` or `borderline` + hands off; on `fail`, restructure toward the flagged metrics (sentence mix, + paragraph pacing, questions, punctuation habits — not word swaps) and lint + once more. Include the final verdict in the run output. Without the + connection, skip and note it. +5. Write `draft.md`. This file is revised in place during the review loop, so + write it as the working copy. ## Output: draft.md -The finished prose, in the target medium's format. No meta-commentary, no "here is the draft" preamble — the file is the piece. Lead with the governing idea on the first line. +The finished prose, in the target medium's format. No meta-commentary, no +"here is the draft" preamble — the file is the piece. Lead with the governing +idea on the first line. ## Voice-guide sections this stage leans on