Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions plugins/compound-engineering/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ The primary entry points for engineering work, invoked as slash commands:
| `/ce:compound` | Document solved problems to compound team knowledge |
| `/ce:compound-refresh` | Refresh stale or drifting learnings and decide whether to keep, update, replace, or archive them |

### Writing

Prose-native skills for the writing workflow, run by the Perkins orchestrator (`/ce:run perkins`). They draft and review against a voice guide rather than a git diff.

| Skill | Description |
|-------|-------------|
| `/ce:write` | Develop, outline, and draft prose in a target voice (stage:develop, stage:outline, stage:draft) |
| `/ce:prose-review` | Review a draft with the seven-voice editorial panel against the voice guide |

### Git Workflow

| Skill | Description |
Expand Down
98 changes: 98 additions & 0 deletions plugins/compound-engineering/skills/ce-prose-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
name: ce:prose-review
description: "Review a piece of writing with the seven-voice editorial panel against the voice guide. Use to review a draft essay, email, or doc for voice, rhythm, concision, structure, formatting, audience, and terms of art — typically invoked by the Perkins orchestrator, but works standalone on any prose file."
argument-hint: "target:<path-to-draft> [brief:<path>] [mode:report|headless]"
---

# Prose Review (the seven-voice panel)

Reviews a prose file with the writing panel — seven named editors, each owning one dimension of Jeff's voice. Dispatches them in parallel, each returning structured JSON findings against the voice guide, then merges and synthesizes the findings by theme.

Unlike `ce:review`, this skill needs **no git diff** — the input is a file. The draft is the unit of review.

## Step 1: Parse arguments

- **Target** — `target:<path>`, the prose file to review (usually `docs/writing/<slug>/draft.md`). Required. If absent, ask for the file (or, standalone, review the most recently modified file under `docs/writing/`).
- **Brief** — `brief:<path>`, optional. Supplies audience and purpose so the panel — Handley and Garner especially — can judge fit to the intended reader.
- **Mode** — `mode:report` (default) presents findings for a human or orchestrator to act on; `mode:headless` skips all interaction and returns findings as the terminal value for a calling skill. This skill never edits the draft — revision is the caller's job (Perkins revises in the review loop).

## Step 2: Locate the panel

Find the plugin and the writing reviewers:

```bash
# Prefer the active Claude profile over a global search
if [ -n "$CLAUDE_CONFIG_DIR" ]; then
PLUGIN_DIR=$(find "$CLAUDE_CONFIG_DIR" -path "*/compound-engineering/*/agents/review" -type d 2>/dev/null | head -1 | sed 's|/agents/review$||')
fi
if [ -z "$PLUGIN_DIR" ]; then
PLUGIN_DIR=$(find "$HOME/.claude" "$HOME/.claude-"* -path "*/compound-engineering/*/agents/review" -type d 2>/dev/null | head -1 | sed 's|/agents/review$||')
fi
PLUGIN_DIR="${PLUGIN_DIR:-plugins/compound-engineering}"
```

Read every `.md` file in `$PLUGIN_DIR/agents/review/` using the native file-search/glob tool (e.g. Glob in Claude Code) and select those whose frontmatter has `category: writing`. That set is the panel: king-voice, provost-rhythm, orwell-concision, minto-structure, nielsen-formatting, handley-audience, garner-vocabulary.

If no `category: writing` reviewers are found, report: "No writing reviewers found in agents/review/. Run /ce:refresh to sync them from ce-reviewers-jsl." Then stop.

## Step 3: Locate the voice guide

Same resolution the reviewers use, so the skill can confirm it exists and pass its path:

1. `docs/writing/voice-guide.md` (project override), else
2. `$HOME/.config/compound-engineering/voice-guide.md` (the live guide).

If neither exists, 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 5: Dispatch the panel

Read `references/prose-reviewer-template.md` for the subagent prompt template.

For each writing reviewer selected in Step 2:
1. Read the reviewer's `.md` content.
2. Fill the template variables: `{reviewer_persona}`, `{voice_guide_path}`, `{brief}`, `{draft}`.
3. Spawn a sub-agent with the caller's `agent-model` (Perkins sets `sonnet`; default to `sonnet` if unspecified).

Spawn all seven in parallel. If parallel dispatch is unavailable, spawn sequentially. If a reviewer times out or fails, note it and continue with the results received — a partial panel still has signal.

## Step 6: Merge and synthesize

Collect the seven JSON responses. Then:

1. **Merge.** Flatten all findings. De-duplicate: when two reviewers flag the same quote for related reasons, keep both perspectives but group them (e.g. King and Orwell both on a generic sentence).
2. **Rank.** High severity first, then medium, then low. Within a tier, order by confidence.
3. **Synthesize by theme, not by reviewer.** Group findings by what's wrong with the piece, naming the editors who raised each — "King and Handley both read the opening as writer-centered." Lead with voice (King) and audience (Handley) findings when they fire; those two most decide whether the piece works.
4. **Collect guide candidates.** Gather every `voice_guide_updates_needed` entry across reviewers into one list — this is the raw material for Perkins's compound phase.

## Output

```markdown
## Prose Review: <draft title>

**Panel verdict:** <one line — does it sound like Jeff yet, and what's the biggest gap>

### Blockers (high severity)
- **<theme>** — <finding>. *(King, Orwell)*
- Quote: "<offending text>"
- Fix: <concrete rewrite>

### Worth fixing (medium)
- ...

### Minor (low)
- ...

### Reads-aloud check
<Provost's rhythm verdict — clean, uneven, or monotone, with the worst passage.>

### Candidate voice-guide rules
<Merged voice_guide_updates_needed — hand to the compound phase.>
```

## Pipeline / headless mode

When invoked by Perkins (`mode:headless`), skip all interaction, return the structured findings and the candidate-rules list as the terminal output, and do not edit the draft. Perkins reads the findings, revises `draft.md`, and re-invokes this skill until no high-severity findings remain and Provost reports the read-aloud clean.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Prose reviewer subagent template

Fill the variables and pass as the sub-agent prompt. One reviewer per sub-agent.

---

You are a member of the writing panel reviewing a draft. Your persona, lens, and output contract are defined below. Adopt them fully — review only through your lens, defer everything outside it to your colleagues as your persona instructs, and return JSON exactly in the format your persona specifies.

## Your persona

{reviewer_persona}

## The voice guide (your ground truth)

Read the voice guide at this path before reviewing — it is the codified record of how Jeff writes, and you must cite it by section:

`{voice_guide_path}`

If the path is empty or the file is missing, review against the principles in your persona and set every finding's `guide_ref` to `"(guide missing)"`.

## The brief (audience and purpose)

{brief}

If the brief is empty, infer the audience conservatively and note in your `emphasis` that no brief was supplied.

## The draft to review

<<<DRAFT
{draft}
DRAFT

## Your task

1. Read the voice guide, focusing on the sections your persona owns.
2. Read the draft as your persona reads — for your one dimension only.
3. Return your findings as the JSON object your persona defines. Quote the exact offending text in each finding, cite the guide section, and give a concrete fix in Jeff's voice. No prose outside the JSON block.

Return only the JSON.
64 changes: 64 additions & 0 deletions plugins/compound-engineering/skills/ce-write/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
name: ce:write
description: "Develop, outline, and draft prose in Jeff's voice against the voice guide. Use when writing an essay, email, doc, or announcement — invoked per stage (stage:develop, stage:outline, stage:draft), typically by the Perkins orchestrator."
argument-hint: "stage:<develop|outline|draft> [brief:<path>] [outline:<path>] [topic or description]"
---

# Write (voice-guided prose generation)

Produces prose in Jeff's voice through three stages — develop the idea, outline the shape, draft the prose — each grounded in the voice guide. This skill handles the generation arc of the writing workflow; review is handled by `ce:prose-review`.

Each stage runs independently and is normally invoked one at a time by the Perkins orchestrator (`/ce:run perkins`), but each also works standalone.

## Interaction Method

Use the platform's question tool when available (`AskUserQuestion` in Claude Code, `request_user_input` in Codex, `ask_user` in Gemini). Otherwise, present numbered options in chat and wait for a reply before proceeding. In pipeline mode (see below), skip interaction and use what the args and context provide.

## Step 1: Parse arguments

Extract from the input:
- **Stage** — `stage:<value>` where value is `develop`, `outline`, or `draft`. Required. If absent, infer: no brief present → `develop`; brief present, no outline → `outline`; both present → `draft`.
- **Brief path** — `brief:<path>`. Used by `outline` and `draft`.
- **Outline path** — `outline:<path>`. Used by `draft`.
- **Topic** — the remaining text after extracting the tokens: the subject of the piece.

## 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.

## Step 3: Determine the working directory

Prose artifacts live under `docs/writing/<run-slug>/`, where `<run-slug>` is a short kebab-case title derived from the topic (e.g. `docs/writing/jtbd-alignment-essay/`). Reuse the slug the orchestrator passes via the brief/outline paths when present, so all three stages write to the same folder.

## Step 4: Run the stage

Load the reference for the current stage and follow it:

- `stage:develop` → read `references/develop.md`. Produces `brief.md`.
- `stage:outline` → read `references/outline.md`. Produces `outline.md`.
- `stage:draft` → read `references/draft.md`. Produces `draft.md`.

Each reference defines the procedure, the output artifact, and the voice-guide sections that stage leans on hardest.

## Step 5: Report the artifact path

End by stating the path of the artifact written (`brief.md`, `outline.md`, or `draft.md`) so the orchestrator can thread it into the next phase. In pipeline mode, this path is the return value — state it plainly, with no surrounding prose.

## Pipeline Mode

When invoked from the Perkins orchestrator, skip interactive approval questions. Use the stage, brief, and outline provided in args. For `develop`, if the brief cannot be completed without a question the user must answer (e.g. the audience is genuinely unknown), write the brief with the gap marked `⚠ NEEDS INPUT` and report it, rather than blocking — the orchestrator surfaces it at the gate.
42 changes: 42 additions & 0 deletions plugins/compound-engineering/skills/ce-write/references/develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Stage: develop

Turn a rough ask into a **brief** — the foundation every later stage builds on. The brief is small and sharp, not a document for its own sake. Its whole job is to make the five decisions that a draft cannot be good without.

## The five decisions the brief must lock

1. **Audience** — who, specifically, reads this. Not "developers" but "senior engineers new to this codebase" or "a funder deciding whether to renew." The named reader drives register and terms of art (voice guide §9).
2. **Purpose** — what changes because this piece exists. Inform, persuade, decide, announce, teach.
3. **The one job** — the single thing the piece must do. If it does only one thing, what is it? Everything not serving the one job is a candidate for cutting.
4. **Thesis / angle** — the governing idea, stated as a claim, not a topic (voice guide §2.1, §6). "Get Connor out of ops and the value engine scales" — not "thoughts on the podcast workflow."
5. **Medium** — essay, email, doc, README, announcement. This selects the medium profile in voice guide §8.

## Procedure

1. Read the topic from args and whatever context the conversation already holds.
2. For any of the five that the request already answers, adopt it — do not re-ask what Jeff already told you.
3. For the genuinely open ones, ask (batched into one question set via the platform question tool). Keep it to what actually blocks the brief. Do not interview for its own sake.
4. Write `brief.md` in the working directory.

## Output: brief.md

```markdown
# Brief: <short title>

- **Audience:** <the specific reader>
- **Purpose:** <what changes because this exists>
- **The one job:** <the single thing it must do>
- **Thesis / angle:** <the governing idea as a claim>
- **Medium:** <essay | email | doc | readme | announcement>

## Notes
<Any constraints, must-include points, tone calls, length target, or
things to deliberately leave out. Mark unknowns with ⚠.>
```

Keep it under a screen. A brief that grows into an essay has missed the point.

## Voice-guide sections this stage leans on

- §9 Audience & terms of art — the named reader.
- §2.1 / §6 — the thesis as a governing idea, not a topic.
- §8 By medium — which medium profile applies downstream.
47 changes: 47 additions & 0 deletions plugins/compound-engineering/skills/ce-write/references/draft.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 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.

## Read first

- The brief at `brief:<path>` — audience, purpose, one job, thesis, medium.
- The outline at `outline:<path>` — the section order and per-section ideas.
- The **entire** voice guide. Every section applies now.

## Draft against the guide, deliberately

Do not write generically and hope it sounds like Jeff. Write *toward* the guide:

- **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.

## Kill on sight while drafting (§5, §10)

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.

## Procedure

1. Read brief, outline, and the full voice guide.
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.

## 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.

## Voice-guide sections this stage leans on

All of them. This is the stage the whole guide exists for.
50 changes: 50 additions & 0 deletions plugins/compound-engineering/skills/ce-write/references/outline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Stage: outline

Turn the brief into a **skeleton** — the order of ideas, answer-first. The outline is where structure is cheap to change; fixing a tangled argument here costs a minute, in the draft it costs an hour.

## Read first

- The brief at `brief:<path>`.
- The voice guide, especially §6 (structure) and §2.1 (lead with the governing idea).

## Principles (voice guide §6)

- **Answer first.** The governing idea from the brief goes on top. The reader learns the thesis, then spends the piece confirming it — never hunting for it. This is Minto's pyramid, and it is the outline's spine.
- **One idea per section.** Each section makes exactly one point. If a section wants to argue two things, it is two sections.
- **Build an arc.** Order the sections so each earns the next. Evidence after the claim it supports, not before. The close should land the thesis, not introduce a new one.
- **Mark what compresses.** Where the content is structured, parallel data (options, roles, a comparison), note "→ table" — prose should not narrate what a grid can show.
- **Plan the clinchers.** For an essay, note where each section should land its aphoristic closing line (voice guide §3).

## Procedure

1. Extract the thesis and the one job from the brief.
2. Draft the section order as answer-first: thesis on top, then the sections that prove and extend it, then the close.
3. Under each section, write one line: the single idea it carries. Add "→ table" or "→ clincher" markers where they apply.
4. Present the shape for approval (skip in pipeline mode — the orchestrator gates it). Revise once if the shape is wrong; do not perfect prose here.
5. Write `outline.md`.

## Output: outline.md

```markdown
# Outline: <short title>

**Governing idea (goes on top of the draft):** <the thesis>

1. <Section header — states the point or poses the question>
- Idea: <the one idea this section carries>
- <optional: → table | → clincher | must-include note>
2. <Section header>
- Idea: <...>
...
N. <Close>
- Idea: <how the piece lands the thesis>
```

Headers are noun phrases or framing questions, never generic ("Overview," "Introduction," "Conclusion" are banned — voice guide §7).

## Voice-guide sections this stage leans on

- §6 Structure — answer-first, one idea per section, scaffold then fill.
- §2.1 — lead with the governing idea.
- §3 — where clinchers land.
- §7 — header style (no generic headers).