aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-10 10:12:22 -0500
committerCraig Jennings <c@cjennings.net>2026-06-10 10:12:22 -0500
commit571669583e634a90f9c96e7073d5e91658e1119c (patch)
tree4558945c8b812b4b075596382655af0190834ee9
parenta19db36005b527c51a55b0e6eb39a49ecd3b6d9f (diff)
downloadrulesets-571669583e634a90f9c96e7073d5e91658e1119c.tar.gz
rulesets-571669583e634a90f9c96e7073d5e91658e1119c.zip
feat(voice): expand skill to 45 patterns with attestation receipts and artifact budgets
Two patterns kept failing in practice despite being documented (#40 praise asymmetry and the #38 terse cut), so I made the walk verifiable and closed the content gap behind tangled review text. The high-recurrence set (#13, #37, #38, #40, #42) now gets per-pattern attestation receipts. The anti-AI audit runs after the terse pass so the audited text is the text that ships. Short personal-mode artifacts get a compact output format, and a write-back step puts the voiced text in the file the publish flow posts from. Four patterns are new: #42 finding stems (one claim per sentence in review findings), #43 single-sentence paragraph cadence, #44 parenthetical asides, #45 declarative register marker. #37 exempts verdict formulas. #40 covers verification narration. #13 and #33 carry the self-discipline framing. A per-artifact budgets table makes terse a checkable budget instead of an adjective. The profile gains paired entries with the approved worked examples, and commits.md plus no-approvals.org drop hardcoded pattern counts so the next addition doesn't re-drift them.
-rw-r--r--.ai/workflows/no-approvals.org4
-rw-r--r--claude-rules/commits.md12
-rw-r--r--claude-templates/.ai/workflows/no-approvals.org4
-rw-r--r--docs/design/2026-06-10-voice-skill-revision-handoff.org56
-rw-r--r--voice/SKILL.md139
-rw-r--r--voice/references/voice-profile.org177
6 files changed, 332 insertions, 60 deletions
diff --git a/.ai/workflows/no-approvals.org b/.ai/workflows/no-approvals.org
index e4181ce..1efce82 100644
--- a/.ai/workflows/no-approvals.org
+++ b/.ai/workflows/no-approvals.org
@@ -45,7 +45,7 @@ The interaction gates that step the workflow back to Craig for an "OK to proceed
The engineering-discipline gates protect quality, not Craig's interaction time. They remain in force:
- =/review-code= against the staged diff before every commit. Critical and Important findings still block. Minor findings still surface. No "proceed anyway" override unless Craig has given it explicitly for this batch.
-- =/voice personal= on every publish artifact (commit messages, PR titles + bodies, PR review comments). The 41-pattern walk happens. The printed result just doesn't wait for approval.
+- =/voice personal= on every publish artifact (commit messages, PR titles + bodies, PR review comments). The full pattern walk happens. The printed result just doesn't wait for approval.
- The full test suite + lint + compile before commit (per =verification.md=).
- Fetch-and-reconcile in =commits.md= Step 0.
- Session Log updates per =protocols.org=. Every state-mutating turn writes to =.ai/session-context.org= before the closing message. The log is the crash-recovery anchor while Craig is away. Missing entries lose work.
@@ -69,7 +69,7 @@ For each item:
- Do the work.
- Update the Session Log per the rules in =protocols.org=.
- Before any commit: run =/review-code= against the staged diff. Surface Critical and Important findings inline; fix them and re-review until clean. Minor findings show but don't block.
-- Draft the commit message. Run =/voice personal= (the skill, or walk the 41 patterns inline if unavailable). Print the final message inline before committing so the log shows it.
+- Draft the commit message. Run =/voice personal= (the skill, or walk the patterns inline if unavailable). Print the final message inline before committing so the log shows it.
- Commit and push.
- One-line status between items ("Task X done, on to Y.") so Craig knows what's happening when he checks back in.
diff --git a/claude-rules/commits.md b/claude-rules/commits.md
index 2ce871e..3bb6724 100644
--- a/claude-rules/commits.md
+++ b/claude-rules/commits.md
@@ -286,7 +286,7 @@ enough to skip review" exemption on top of it.
**Voice patterns and the approval gate are two independent decisions.** Don't bundle them.
-*Voice patterns are always personal for publish artifacts.* Commit messages, PR titles + bodies, and PR review comments all go out under the user's name, so they always run through `/voice personal` (41 patterns — general + Craig's-voice + the three artifact-mechanics patterns: first-person rewrite, public-artifact scope flag, praise/correction asymmetry), regardless of whether `.ai/` is tracked. These three are personal-voice artifacts by definition — the skill's personal mode exists for exactly them. Pattern #39 (public-artifact scope flag) matters *most* on team-visible artifacts, so it must never be skipped on a PR comment or PR body. There is no "general-voice mode" for publish artifacts.
+*Voice patterns are always personal for publish artifacts.* Commit messages, PR titles + bodies, and PR review comments all go out under the user's name, so they always run through `/voice personal` (the full pattern walk — general + Craig's-voice + the artifact-mechanics patterns: first-person rewrite, public-artifact scope flag, praise/correction asymmetry, finding stems), regardless of whether `.ai/` is tracked. These three are personal-voice artifacts by definition — the skill's personal mode exists for exactly them. Pattern #39 (public-artifact scope flag) matters *most* on team-visible artifacts, so it must never be skipped on a PR comment or PR body. There is no "general-voice mode" for publish artifacts.
*The approval gate is the only thing `.ai/`-tracking decides.* Before drafting, run this command:
@@ -304,8 +304,8 @@ Either way the draft runs through `/voice personal` first. The subflows below de
**For commit messages:**
1. Write the proposed message to `/tmp/commit-<short-slug>.md`.
-2. Run `/voice personal` on the file. Always. The skill walks 41 patterns covering signs of AI writing, universal good-writing rules (Strunk & White, Orwell, Plain English, Garner), and Craig's voice patterns (first-person rewrite, semicolons → periods/commas, contractions, sentence-split on conjunctions, felt-experience cut, sentence-fragment rewrite, terse cut for rhetorical padding, no-emphasis-formatting, public-artifact scope flag, praise/correction asymmetry). The commit subject line stays imperative per Conventional Commits — `/voice personal` rewrites the body, not the subject. Skip the pass for purely mechanical commits (a chore version bump, a typo fix) where the subject alone carries the message.
-3. Print the final draft inline in the terminal. Every line, exactly as it'll be committed. No truncation, no summary. State that the skill ran (e.g. "/voice personal — 41 patterns walked"). If pattern #39 (public-artifact scope) flagged anything, surface those warnings; the user resolves them manually.
+2. Run `/voice personal` on the file. Always. The skill walks its full pattern list covering signs of AI writing, universal good-writing rules (Strunk & White, Orwell, Plain English, Garner), and Craig's voice patterns (first-person rewrite, semicolons → periods/commas, contractions, sentence-split on conjunctions, felt-experience cut, sentence-fragment rewrite, terse cut for rhetorical padding, no-emphasis-formatting, public-artifact scope flag, praise/correction asymmetry, finding stems). The commit subject line stays imperative per Conventional Commits — `/voice personal` rewrites the body, not the subject. Skip the pass for purely mechanical commits (a chore version bump, a typo fix) where the subject alone carries the message.
+3. Print the final draft inline in the terminal. Every line, exactly as it'll be committed. No truncation, no summary. State that the skill ran (e.g. "/voice personal — full pattern walk"). If pattern #39 (public-artifact scope) flagged anything, surface those warnings; the user resolves them manually.
4. Ask: approve, request changes, or open in editor. Wait for an explicit answer. Do not open the file in `emacsclient` (or any editor) by default — print first, edit only if asked.
- **Approve** → commit with `git commit -F /tmp/commit-<short-slug>.md`.
- **Request changes** → make them, re-run `/voice personal`, re-print inline, ask again.
@@ -353,9 +353,9 @@ Pick the shape first. Most reviews are Shape 1.
The separator format is exactly `=== SUMMARY ===` and `=== INLINE path=<path> line=<n> ===`. The summary block is mandatory even for verdict-only reviews. Inline blocks are zero-or-more.
-3. Run `/voice personal` on the file once. The skill walks all 41 patterns across every block at the same time. The separators stay intact because they aren't prose.
+3. Run `/voice personal` on the file once. The skill walks its full pattern list across every block at the same time. The separators stay intact because they aren't prose.
-4. Print the final draft inline in the terminal. Every block, exactly as it'll be posted, with its separator header. State that the skill ran (e.g. "/voice personal — 41 patterns walked across summary + 3 inline"). Surface any pattern #39 warnings.
+4. Print the final draft inline in the terminal. Every block, exactly as it'll be posted, with its separator header. State that the skill ran (e.g. "/voice personal — full pattern walk across summary + 3 inline"). Surface any pattern #39 warnings.
5. Ask: approve, request changes, or open in editor. Wait for an explicit answer. Do not open the file in `emacsclient` (or any editor) by default.
- **Approve** → continue to step 6.
@@ -414,7 +414,7 @@ conversation (e.g. "commit this as `chore: bump version`", "reply just
`/review-code` in Step 1 still runs when it applies; Phase 0 of that skill
handles trivial diffs, and acknowledgment-only replies don't need it at all.
-**Single-skill gate.** Each of the three subflows above runs `/voice personal` before printing the draft — 41 patterns covering AI-writing signs, universal good-writing rules, Craig's voice patterns, and the three artifact-mechanics patterns (first-person rewrite, public-artifact scope flag, praise/correction asymmetry). Publish artifacts (commits, PR titles + bodies, PR review comments) always use personal mode; the `.ai/`-tracking check at the top of Step 2 decides only whether the approval gate fires, not which patterns run. Running the skill is mandatory; the printed draft must have been through it. When the user asks mid-flow for "the voice pass" on an in-progress draft, that means re-run the full 41-pattern walk — not a subset. Always state that the skill ran when announcing the printed draft (e.g. "/voice personal — 41 patterns walked"). Skipping the pass without flagging it is a defect. The terse/omit-needless-words cut (pattern #38) is the *last* thing the skill does before the draft is printed: read each sentence and cut it in half, keeping only what changes meaning. The draft the user first sees must already be terse — if they have to ask for an Orwell pass after seeing it, the pass was skipped.
+**Single-skill gate.** Each of the three subflows above runs `/voice personal` before printing the draft — the full pattern walk covering AI-writing signs, universal good-writing rules, Craig's voice patterns, and the artifact-mechanics patterns (first-person rewrite, public-artifact scope flag, praise/correction asymmetry, finding stems). Publish artifacts (commits, PR titles + bodies, PR review comments) always use personal mode; the `.ai/`-tracking check at the top of Step 2 decides only whether the approval gate fires, not which patterns run. Running the skill is mandatory; the printed draft must have been through it. When the user asks mid-flow for "the voice pass" on an in-progress draft, that means re-run the full pattern walk — not a subset. Always state that the skill ran when announcing the printed draft (e.g. "/voice personal — full pattern walk"). Skipping the pass without flagging it is a defect. The terse/omit-needless-words cut (pattern #38) is the *last* thing the skill does before the draft is printed: read each sentence and cut it in half, keeping only what changes meaning. The draft the user first sees must already be terse — if they have to ask for an Orwell pass after seeing it, the pass was skipped.
**If `/voice` is unavailable.** The skill should be installed (it ships with rulesets), but a fresh or partial environment may not have it. Don't let that block the publish, and don't skip the discipline silently. Walk the same patterns inline — they're documented in the skill, and the publish flow already names which ones matter (first-person rewrite, semicolons → periods/commas, contractions, sentence-split, felt-experience cut, fragment rewrite, terse cut, the pattern #39 public-artifact scope flag, plus the AI-writing and good-writing passes). Then state that the skill was unavailable and the pass was applied by hand (e.g. "/voice unavailable — patterns walked inline"). The gate is the pattern walk, not the tooling; the skill is the convenient way to run it, not the only way. Flag the missing skill so it gets installed.
diff --git a/claude-templates/.ai/workflows/no-approvals.org b/claude-templates/.ai/workflows/no-approvals.org
index e4181ce..1efce82 100644
--- a/claude-templates/.ai/workflows/no-approvals.org
+++ b/claude-templates/.ai/workflows/no-approvals.org
@@ -45,7 +45,7 @@ The interaction gates that step the workflow back to Craig for an "OK to proceed
The engineering-discipline gates protect quality, not Craig's interaction time. They remain in force:
- =/review-code= against the staged diff before every commit. Critical and Important findings still block. Minor findings still surface. No "proceed anyway" override unless Craig has given it explicitly for this batch.
-- =/voice personal= on every publish artifact (commit messages, PR titles + bodies, PR review comments). The 41-pattern walk happens. The printed result just doesn't wait for approval.
+- =/voice personal= on every publish artifact (commit messages, PR titles + bodies, PR review comments). The full pattern walk happens. The printed result just doesn't wait for approval.
- The full test suite + lint + compile before commit (per =verification.md=).
- Fetch-and-reconcile in =commits.md= Step 0.
- Session Log updates per =protocols.org=. Every state-mutating turn writes to =.ai/session-context.org= before the closing message. The log is the crash-recovery anchor while Craig is away. Missing entries lose work.
@@ -69,7 +69,7 @@ For each item:
- Do the work.
- Update the Session Log per the rules in =protocols.org=.
- Before any commit: run =/review-code= against the staged diff. Surface Critical and Important findings inline; fix them and re-review until clean. Minor findings show but don't block.
-- Draft the commit message. Run =/voice personal= (the skill, or walk the 41 patterns inline if unavailable). Print the final message inline before committing so the log shows it.
+- Draft the commit message. Run =/voice personal= (the skill, or walk the patterns inline if unavailable). Print the final message inline before committing so the log shows it.
- Commit and push.
- One-line status between items ("Task X done, on to Y.") so Craig knows what's happening when he checks back in.
diff --git a/docs/design/2026-06-10-voice-skill-revision-handoff.org b/docs/design/2026-06-10-voice-skill-revision-handoff.org
new file mode 100644
index 0000000..9b82127
--- /dev/null
+++ b/docs/design/2026-06-10-voice-skill-revision-handoff.org
@@ -0,0 +1,56 @@
+#+TITLE: Voice skill revision — full revised SKILL.md + change rationale
+#+DATE: 2026-06-10
+
+* What this is
+
+Craig reviewed an analysis of the voice skill during the 2026-06-10 work session and adopted all of it. The companion file in this inbox delivery (=...voice-skill-revised...=, a complete replacement =voice/SKILL.md=) carries every change already applied. This file is the change list, the why per change, and the paired-profile obligations.
+
+This SUPERSEDES AND INCORPORATES the earlier handoff from this morning (=2026-06-10-0848-from-work-handoff-voice-finding-stems.org=) — the finding-stems pattern proposed there is included here as pattern #42. Don't apply that handoff separately; its worked examples are still the right content for the new profile §42.
+
+* Context: why these changes
+
+Two of the skill's existing patterns failed in practice this morning despite being well-documented: #40 (praise asymmetry — a review draft praised a fix and then narrated the verification supporting the praise) and the general terseness discipline (a #233 review comment shipped with hedged gerund chains and compressed trade-off clauses that passed all 41 patterns). Craig named detangling wordy or overly complex Claude-drafted review text as THE key issue he fights in PR reviews, and the reason he now gates every review draft. The diagnosis: the failures aren't missing rules but unverifiable execution, plus one genuine content gap (sentence architecture). The revision attacks both.
+
+* Changes in the revised SKILL.md
+
+** Execution changes
+
+1. *Attestation block (new Process step 8, both output formats).* The high-recurrence patterns (#13, #37, #38, #40, #42) each get an explicit one-line receipt: checked, match/no-match, action. Why: the walk was 45 patterns checked silently, and the output only listed patterns that fired, so a skimming pass looked cleaner than a diligent one. The skill already discovered this fix once when #38 kept being glossed and was promoted to a standalone step; this generalizes that discovery to the whole empirically-failing set instead of escalating one pattern per failure. The block also documents rotation: a pattern that fails in the wild gets escalated, one that holds clean can rotate out.
+
+2. *Anti-AI audit moved after the terse pass (Process steps 5-6 reordered).* Previously the audit ran on a pre-final draft and the terse cut changed the text afterward, so the audited artifact wasn't the shipped artifact. Now: terse cut is the last rewrite pass, audit runs on the final text, and any audit-triggered rewrite re-runs the #38 per-sentence test on changed sentences.
+
+3. *Compact output format (new default for personal-mode artifacts under ~25 lines).* Final text + WARNs + fired-list + attestation + write-back note. Why: for a three-sentence review comment the old format (draft rewrite + final rewrite + audit Q&A) was 10x the deliverable, buried the text the approval gate needs to read, and was long enough to print without doing the work. The full format remains for long-form and general mode.
+
+4. *Write-back step (Process step 7).* When invoked with a file path, the final text is written back to the file. Why: the publish flow posts from the file (git commit -F, gh pr create --body-file), and the old skill only "presented" text — a silent drift bug where the approved chat text and the posted file text differ.
+
+** Content changes
+
+5. *#42 Finding Stems (new, personal).* A finding is clean stems, one claim per sentence: where the bug is, the fix, why it's better. Cut context that doesn't change the author's next action. Anti-patterns named: hedged gerund chains, compressed trade-off clauses, multi-claim so/and chains, fixes buried after mid-sentence colons. Why: today's tangles passed all 41 patterns — #38 shortens but doesn't untangle; a sentence can be terse and still carry three claims. Profile §42 content: use the three worked Before/After examples from the superseded stems handoff (they're Craig-approved rewrites from PR #233).
+
+6. *#37 exemption for verdict formulas.* "Approving." / "Requesting changes." / "Approved." in PR review summaries are house style and stay. Why: the skill survived by being selectively ignored here, and selective ignoring is the same muscle that skips real patterns. Documenting the exception removes one standing occasion for judgment-override.
+
+7. *Personal-Mode Artifact Budgets (new section after Modes).* A table: commit body (skip when subject carries it), PR description (four tight sections), review summary (one long sentence or a few short ones + verdict), inline pin (~4 sentences in stems shape), praise comment (one sentence), follow-up approval (exactly "Approved."). Why: these shapes lived only in the work project's memory layer, invisible to the skill and other machines. The table converts "terse" from an adjective into a budget the walk can check, and moves the rules from the recall layer to the enforcement layer.
+
+8. *#40 strengthened with the verification-narration variant.* "I traced X and it's safe because..." is the same defect as justified praise — the reviewer's homework padding the compliment. If verification found a problem, the problem gets the words; if nothing, zero words. This was today's exact failure shape on the #236 draft. Profile §40 should gain a Before/After: Before "All three fixes look right. I traced useMapActions and the unmount cleanup is safe because the hook returns a memoized object, and the provider wraps the whole app so neither call site lands on the no-op path." After "All three fixes are clean and well-aimed."
+
+9. *Profile's own pending deltas landed.* The profile's "Suggested deltas" section (written 2026-05-29, apparently never applied) is now in SKILL.md: #13 and #33 rule lines carry the self-discipline framing with corpus rates; #7 already had the "comprehensive" soft-flag; new #43 (single-sentence paragraph cadence is a feature, protective), #44 (parenthetical asides are part of the voice, protective, noted as the preferred em-dash landing spot), #45 (declarative register marker, advisory flag on rhetorical questions).
+
+10. *Personality and Soul section mode-tagged.* It now states it applies in general and prose modes only; personal mode skips soul-injection because "let some mess in" pulls directly against the artifact budgets, and the budgets win.
+
+* Obligations for the rulesets agent (pairing rule)
+
+The revised SKILL.md alone is an incomplete change. To land it:
+
+1. Replace =voice/SKILL.md= with the companion file.
+2. Profile updates required:
+ - New entries §42 (stems — use the worked examples from the superseded handoff), §43, §44, §45 (basis: the corpus measurements already in the profile's "Worth adding" section).
+ - §37: add the verdict-formula exemption + history line (Craig, 2026-06-10).
+ - §40: add the verification-narration variant + the Before/After in item 8 above + history line (third recurrence, 2026-06-10).
+ - §13, §33: move the "Aspirational" reframing from the findings section into the entries proper (the suggested-deltas content).
+ - History lines throughout: 2026-06-10, Craig's call, from the work-project session.
+3. Count references: =claude-rules/commits.md= says "41 patterns" in several places (the Step 2 publish flow and the single-skill gate paragraph). Update to 45, or better, replace hardcoded counts with "all patterns" so the next pattern addition doesn't re-drift them. Same check in any other rules file that names the count.
+4. The work project's startup-synced copies pick the skill up via the normal symlink (=make install= already links =voice/=), so no per-project action needed.
+
+* Why this works better, in one paragraph
+
+The gate Craig runs on every review draft exists because drafts arrive tangled and padded. Every change here either makes the walk verifiable (receipts for the patterns that actually fail), makes the deliverable readable at the gate (compact output), closes the content gap behind the tangles (stems, budgets), or removes a documented occasion to override the skill (verdict-formula exemption, soul-section mode tag). The goal state: Craig approves drafts instead of detangling them, and the gate gets cheap enough to keep.
diff --git a/voice/SKILL.md b/voice/SKILL.md
index 664a6a6..4690b97 100644
--- a/voice/SKILL.md
+++ b/voice/SKILL.md
@@ -1,7 +1,7 @@
---
name: voice
description: |
- Multi-pass prose editor with three modes. General mode (default) edits arbitrary writing — research notes, essays, anyone's README prose — by walking 31 patterns: Wikipedia's Signs of AI Writing patterns plus universal good-writing rules (long-word → short-word, active-over-passive, comma splices, cliché flag, jargon-fragment-in-prose rewrite, corporate-speak nominalizations). Prose mode adds Craig's writing-voice patterns for prose he authors or sends — emails, documents, notes — on top of general (em-dash zero-tolerance, no-emphasis-formatting, contractions, semicolons → periods, sentence-split, felt-experience cut, sentence-fragment rewrite, terse-cut). Personal mode is for publish artifacts only (commits, PR titles + bodies, PR review comments) and adds the artifact-mechanics patterns on top of prose (first-person rewrite, public-artifact scope flag, praise/correction asymmetry). Total 41 patterns; one editorial review covers all relevant ones for the chosen mode. Replaces the standalone humanizer skill. Use when editing prose. Do NOT use for code, structured data, or plain bullet lists where fragments are valid.
+ Multi-pass prose editor with three modes. General mode (default) edits arbitrary writing — research notes, essays, anyone's README prose — by walking 31 patterns: Wikipedia's Signs of AI Writing patterns plus universal good-writing rules (long-word → short-word, active-over-passive, comma splices, cliché flag, jargon-fragment-in-prose rewrite, corporate-speak nominalizations). Prose mode adds Craig's writing-voice patterns for prose he authors or sends — emails, documents, notes — on top of general (em-dash zero-tolerance, no-emphasis-formatting, contractions, semicolons → periods, sentence-split, felt-experience cut, sentence-fragment rewrite, terse-cut, single-sentence cadence, parenthetical asides, declarative-register marker). Personal mode is for publish artifacts only (commits, PR titles + bodies, PR review comments) and adds the artifact-mechanics patterns on top of prose (first-person rewrite, public-artifact scope flag, praise/correction asymmetry, finding stems) plus per-artifact terseness budgets. Total 45 patterns; one editorial review covers all relevant ones for the chosen mode, with an attestation receipt for the high-recurrence set. Replaces the standalone humanizer skill. Use when editing prose. Do NOT use for code, structured data, or plain bullet lists where fragments are valid.
allowed-tools:
- Read
- Write
@@ -31,24 +31,39 @@ This skill is split across two files by design.
Three modes determine which patterns to walk. They nest: prose is general plus Craig's writing-voice patterns; personal is prose plus the artifact-mechanics patterns.
- **General** (default) — apply patterns **#1-31**. Use for writing whose author isn't Craig and that isn't a publish artifact: research notes you're editing for someone else, a quoted passage, README prose for a shared project, any third-party text. Output is well-edited human-sounding prose, but does not impose Craig's voice (first-person, contractions, em-dash elimination) — those conflict with academic, literary, or formal registers that aren't his.
-- **Prose** — apply **#1-31** plus the patterns tagged **(prose + personal)**: em-dash zero-tolerance (#13), contractions (#34), semicolons → periods (#33), sentence-split (#35), felt-experience cut (#36), sentence-fragment rewrite (#37), terse-cut (#38), and no-emphasis-formatting (#41). Use for prose Craig authors or sends in his own voice that isn't a publish artifact: emails, documents he writes or hands to someone, working notes, journal entries. This is the mode that finally applies his actual writing voice to the documents he most wants it on. It skips the artifact-mechanics patterns (#32, #39, #40) — those assume a commit or PR and misfire on free prose (a document is legitimately third-person; a journal has no public-scope concern; praise/correction asymmetry is a PR-review rule).
-- **Personal** — apply all **#1-41**. Use only for publish artifacts: commits, PR titles + bodies, and PR review comments. Adds the three artifact-mechanics patterns (#32 first-person rewrite, #39 public-artifact scope flag, #40 praise/correction asymmetry) on top of everything prose mode walks.
+- **Prose** — apply **#1-31** plus the patterns tagged **(prose + personal)**: em-dash zero-tolerance (#13), contractions (#34), semicolons → periods (#33), sentence-split (#35), felt-experience cut (#36), sentence-fragment rewrite (#37), terse-cut (#38), no-emphasis-formatting (#41), single-sentence cadence (#43), parenthetical asides (#44), and the declarative-register marker (#45). Use for prose Craig authors or sends in his own voice that isn't a publish artifact: emails, documents he writes or hands to someone, working notes, journal entries. This is the mode that finally applies his actual writing voice to the documents he most wants it on. It skips the artifact-mechanics patterns (#32, #39, #40, #42) — those assume a commit or PR and misfire on free prose (a document is legitimately third-person; a journal has no public-scope concern; praise/correction asymmetry and finding stems are PR-review rules).
+- **Personal** — apply all **#1-45**. Use only for publish artifacts: commits, PR titles + bodies, and PR review comments. Adds the artifact-mechanics patterns (#32 first-person rewrite, #39 public-artifact scope flag, #40 praise/correction asymmetry, #42 finding stems) on top of everything prose mode walks.
If invoked without a mode argument, default to general. Prose mode is invoked explicitly with `/voice prose` (emails, authored documents). Personal-context callers (`commits.md` publish flow, `respond-to-cj-comments.md`) invoke `/voice personal`.
+## Personal-Mode Artifact Budgets
+
+Terse is a budget, not an adjective. Each publish-artifact type has a target shape; the walk checks the draft against it. Exceeding a budget needs a reason the reader will thank you for.
+
+| Artifact | Budget |
+|----------|--------|
+| Commit body | Skip entirely when the subject line carries the change. Otherwise short paragraphs: the constraint, bug, or tradeoff. No play-by-play. |
+| PR description | Problem / Fix / Why / Testing, each section tight. |
+| PR review summary | One long sentence or a few short ones. Verdict closes it. Verdict formulas ("Approving.", "Requesting changes.") are valid sentences here. |
+| Inline pin (finding) | ~4 sentences in stems shape (#42): where the bug is, the fix, why it's better. |
+| Praise comment | One sentence naming what's good. Nothing else (#40). |
+| Follow-up approval after prior feedback was addressed | Exactly "Approved." |
+
## Your Task
When given text to edit:
-1. **Identify which patterns apply** — Scan for the patterns numbered below. General mode walks #1-31 only. Prose mode adds the patterns tagged **(prose + personal)**. Personal mode adds those *and* the ones tagged **(personal only)** — i.e. all 41.
+1. **Identify which patterns apply** — Scan for the patterns numbered below. General mode walks #1-31 only. Prose mode adds the patterns tagged **(prose + personal)**. Personal mode adds those *and* the ones tagged **(personal only)** — i.e. all 45.
2. **Rewrite problematic sections** — Replace each detected pattern with its rewrite.
3. **Preserve meaning** — Keep the core message intact.
4. **Maintain voice** — Match the intended tone (formal, casual, technical, academic, literary).
-5. **Add soul** — Don't just remove bad patterns; inject actual personality where the register supports it (see Personality and Soul below).
-6. **Final anti-AI pass** — After rewriting, prompt: "What makes the below so obviously AI generated?" Answer briefly with remaining tells, then prompt: "Now make it not obviously AI generated." and revise.
+5. **Add soul where the register supports it** — see Personality and Soul below, and note its mode limits.
+6. **Run the closing passes in order** — terse cut last among rewrites, then the anti-AI audit on the final text, then the attestation block. The Process section below is the authoritative order.
## Personality and Soul
+**Mode note.** This section applies in general and prose modes, where the register supports personality. Personal mode (publish artifacts) skips soul-injection: a commit message or review comment needs clarity and brevity, not pulse. "Let some mess in" and "have opinions" pull directly against the artifact budgets, and the budgets win.
+
Avoiding AI patterns is half the job. Sterile, voiceless writing is just as obvious as slop. Good writing has a human behind it.
### Signs of soulless writing (even if technically clean)
@@ -159,7 +174,7 @@ See `voice/references/voice-profile.org` §12 for problem, basis, examples, and
### 13. Em Dash Overuse [general: overuse-reduction · prose/personal: zero-tolerance]
-**Rule.** Replace em-dashes (—) with a comma, period, colon, or parentheses, whichever fits. Zero-tolerance in prose and personal modes holds everywhere in the text, including inside example blocks, code-fence prose, and quoted material.
+**Rule.** Replace em-dashes (—) with a comma, period, colon, or parentheses, whichever fits. Zero-tolerance in prose and personal modes holds everywhere in the text, including inside example blocks, code-fence prose, and quoted material. The zero-tolerance rule is chosen self-discipline, not a reflection of Craig's pre-rule habit (corpus: 3.49/1000 words).
See `voice/references/voice-profile.org` §13 for problem, basis, examples, and history.
@@ -281,7 +296,7 @@ See `voice/references/voice-profile.org` §31 for problem, basis, examples, and
## Craig's Voice (prose + personal modes)
-These patterns carry Craig's writing voice. Most apply in **both** prose mode (emails, documents, notes he authors) and personal mode (commits, PRs, PR comments) — tagged **(prose + personal)**. Three are publish-artifact-specific — tagged **(personal only)** — because they assume a commit or PR and misfire on free prose: #32 (first-person rewrite) wrongly imposes "I did X" voice on a document that's legitimately third-person, #39 (public-artifact scope flag) has nothing to guard in a private journal, and #40 (praise/correction asymmetry) is a PR-review rule. General mode skips all of them — it edits text that isn't Craig's, where contractions, em-dash elimination, and first-person would conflict with academic, literary, or formal registers.
+These patterns carry Craig's writing voice. Most apply in **both** prose mode (emails, documents, notes he authors) and personal mode (commits, PRs, PR comments) — tagged **(prose + personal)**. Four are publish-artifact-specific — tagged **(personal only)** — because they assume a commit or PR and misfire on free prose: #32 (first-person rewrite) wrongly imposes "I did X" voice on a document that's legitimately third-person, #39 (public-artifact scope flag) has nothing to guard in a private journal, and #40 (praise/correction asymmetry) and #42 (finding stems) are PR-review rules. General mode skips all of them — it edits text that isn't Craig's, where contractions, em-dash elimination, and first-person would conflict with academic, literary, or formal registers.
### 32. First-Person Voice Rewrite [personal]
@@ -291,7 +306,7 @@ See `voice/references/voice-profile.org` §32 for problem, basis, examples, and
### 33. Semicolon → Period or Comma [prose · personal]
-**Rule.** Replace semicolons with a period (split into two sentences) or a comma (when the clauses are tightly coupled) in Craig's authored prose. A formal long-form document can keep the semicolon, but the default is to split.
+**Rule.** Replace semicolons with a period (split into two sentences) or a comma (when the clauses are tightly coupled) in Craig's authored prose. A formal long-form document can keep the semicolon, but the default is to split. Chosen self-discipline, not habit-reflection (corpus: 3.16/1000 words).
See `voice/references/voice-profile.org` §33 for problem, basis, examples, and history.
@@ -315,7 +330,7 @@ See `voice/references/voice-profile.org` §36 for problem, basis, examples, and
### 37. Sentence Fragments → Complete [prose · personal]
-**Rule.** Rewrite every sentence fragment inside a prose paragraph in Craig's authored text as a complete sentence with subject and verb. Bullets and headings can stay fragments. This is the stricter cousin of general-mode #30.
+**Rule.** Rewrite every sentence fragment inside a prose paragraph in Craig's authored text as a complete sentence with subject and verb. Bullets and headings can stay fragments. This is the stricter cousin of general-mode #30. **Exemption:** verdict formulas in PR review summaries ("Approving.", "Requesting changes.", "Approved.") are house style and stay — rewriting them imposes the rule where Craig's calibrated voice already decided otherwise.
See `voice/references/voice-profile.org` §37 for problem, basis, examples, and history.
@@ -333,7 +348,7 @@ See `voice/references/voice-profile.org` §39 for problem, basis, examples, and
### 40. Praise vs Correction Asymmetry [personal]
-**Rule.** Praise on a PR review is short and unjustified (the author knows why their good change is good). Correction always explains the why, gently and briefly, the way a mentor would. Never as a verdict from on high.
+**Rule.** Praise on a PR review is short and unjustified (the author knows why their good change is good). Correction always explains the why, gently and briefly, the way a mentor would. Never as a verdict from on high. **Verification narration is the same defect as justified praise:** "I traced X and it's safe because..." pads the compliment with the reviewer's homework. Tracing the code is the reviewer's job, not content for the comment — if verification found a problem, the problem gets the words; if it found nothing, it gets zero words.
See `voice/references/voice-profile.org` §40 for problem, basis, examples, and history.
@@ -343,67 +358,100 @@ See `voice/references/voice-profile.org` §40 for problem, basis, examples, and
See `voice/references/voice-profile.org` §41 for problem, basis, examples, and history.
+### 42. Finding Stems — One Claim Per Sentence [personal]
+
+**Rule.** A PR review finding is built from clean stems, each a straightforward sentence carrying one claim: (1) where the bug is, (2) the way(s) to fix it, (3) why that's better. Cut context sentences that don't change what the author does next (ticket history, design archaeology). Rewrite the anti-pattern shapes: hedged gerund chains ("the real bug looks like the model emitting a partial set"), compressed trade-off clauses ("I'd rather X, or Y, than lose Z"), multi-claim sentences chained through so-clauses or "and", and fixes buried after a mid-sentence colon. A sentence can pass #38 terse and still tangle three claims — #38 shortens, #42 untangles.
+
+See `voice/references/voice-profile.org` §42 for problem, basis, examples, and history.
+
+### 43. Single-Sentence Paragraph Cadence Is a Feature [prose · personal]
+
+**Rule.** A one-sentence paragraph is a finished thought, not a fragment. Break paragraphs after one complete thought when the next thought shifts angle, even if both are short. Never merge short paragraphs into multi-sentence ones in a "clean prose" pass (corpus: 41-74% of Craig's paragraphs are exactly one sentence, depending on register).
+
+See `voice/references/voice-profile.org` §43 for problem, basis, examples, and history.
+
+### 44. Parenthetical Asides Are Part of the Voice [prose · personal]
+
+**Rule.** Parentheses for asides, clarifications, and scope-narrowing are Craig's voice (corpus: 23 opening parens per 1000 words). Don't strip them in a cleanup pass. They're also the preferred landing spot for em-dash replacements under #13.
+
+See `voice/references/voice-profile.org` §44 for problem, basis, examples, and history.
+
+### 45. Declarative Register Marker [prose · personal, advisory]
+
+**Rule.** Craig's prose is declarative (corpus: 0.33 question marks per 1000 words). When a draft contains a rhetorical question, flag it for a second look — it's usually AI rhetoric, not his register. Genuine questions to the reader (a review asking the author's intent, an email asking for a decision) stay. Advisory: flag, don't auto-rewrite.
+
+See `voice/references/voice-profile.org` §45 for problem, basis, examples, and history.
+
## Process
-1. Read the input text carefully. Confirm the mode (general, prose, or personal) — invocation argument or context.
-2. Walk patterns 1-31 in general mode; add the (prose + personal) patterns in prose mode; walk all 41 patterns in personal mode.
-3. For each pattern, scan the text. If a match is found, rewrite it according to the pattern's rule. Pattern #39 emits warnings without rewriting (personal mode only).
+1. Read the input text carefully. Confirm the mode (general, prose, or personal) — invocation argument or context. If a file path was given, that file is the deliverable: the final text gets written back to it in step 7.
+2. Walk patterns 1-31 in general mode; add the (prose + personal) patterns in prose mode; walk all 45 patterns in personal mode.
+3. For each pattern, scan the text. If a match is found, rewrite it according to the pattern's rule. Patterns #39 and #45 emit flags without rewriting.
4. After walking all patterns, ensure the revised text:
- Sounds natural when read aloud
- Varies sentence structure
- Uses specific details over vague claims
- Maintains appropriate tone for the register
-5. Present a draft humanized version.
-6. Run a final anti-AI pass: prompt "What makes the below so obviously AI generated?" Answer briefly with remaining tells. Then prompt "Now make it not obviously AI generated" and revise.
-7. **Terse pass — mandatory and last (prose + personal modes).** Before presenting any draft, walk pattern #38 again as a standalone final action: read each sentence and try to cut it in half, keeping only the words that change meaning. Run it on its own here, not folded into step 3's walk — it is the most-skipped pattern and the bloat it catches is the first thing a reader notices, so a draft that cleared the other 40 patterns still routinely runs a third too long. A draft that has not been through this pass is not ready to show; presenting one is a defect in the same class as skipping the skill. General mode skips this step — academic and third-party registers keep their transition markers.
-8. Present the final version.
+5. **Terse pass — mandatory, last rewrite pass (prose + personal modes).** Walk pattern #38 again as a standalone action: read each sentence and try to cut it in half, keeping only the words that change meaning. Run it on its own here, not folded into step 3's walk — it is the most-skipped pattern and the bloat it catches is the first thing a reader notices. General mode skips this step — academic and third-party registers keep their transition markers.
+6. **Anti-AI audit — on the final text.** Prompt: "What makes the below so obviously AI generated?" Answer briefly with remaining tells, then revise. This runs *after* the terse pass so the audited text is the text that ships. If the audit triggers rewrites, re-apply the #38 per-sentence test to every changed sentence before proceeding.
+7. **Write-back.** If the invocation supplied a file path, write the final text to that file now and say so. The publish flow posts from the file (`git commit -F`, `gh pr create --body-file`), so a final text that lives only in chat is a drift bug waiting to post the un-voiced version.
+8. **Attestation block (prose + personal modes).** The high-recurrence patterns — the ones with a documented failure history — each get one explicit line: pattern, checked, match or no match, action taken. Current high-recurrence set: **#13 (em-dash), #37 (fragments), #38 (terse), #40 (praise asymmetry), #42 (finding stems)**. This is a receipt, not a summary: a pattern with no match still gets its line. When a pattern in this set fails in the wild despite the receipt, escalate it the way #38 was escalated; when one holds clean for a long stretch, it can rotate out.
+9. Present the final version per the Output Format below.
## Output Format
-Provide:
+### Compact (default for personal-mode artifacts under ~25 lines: commit messages, review summaries + pins, short PR bodies)
+
+1. **Final text** — exactly what will be posted, nothing else above it
+2. **Pattern-39 warnings** — WARN lines, if any
+3. **Fired** — one line listing patterns that fired (e.g., "fired: #13, #38, #42")
+4. **Attestation** — the high-recurrence receipt block (one line per pattern)
+5. **Write-back note** — "written back to <path>" when a file path was supplied
+
+The compact format exists because the deliverable must not drown in ceremony: for a three-sentence review comment, printing a draft rewrite, a final rewrite, and an audit Q&A buries the text the gate needs to read, and a long scaffold is easy to print without doing the work. The attestation block is the anti-performative check — it names the patterns that actually fail in practice.
+
+### Full (long-form prose, general mode, or on request)
+
1. **Draft rewrite** — the text after walking all applicable patterns
2. **Mode used** — general, prose, or personal
3. **What makes the below so obviously AI generated?** — brief bullets
-4. **Final rewrite** — revised after the anti-AI audit
-5. **Pattern-39 warnings** (personal mode only) — any public-artifact scope flags
-6. **Summary of changes** — list of patterns that fired (e.g., "patterns 4, 7, 13, 22 in general mode")
-7. **Terse pass** (prose + personal) — state that the mandatory final #38 cut ran on the draft being presented.
+4. **Final rewrite** — revised after the anti-AI audit (and post-audit terse re-check)
+5. **Pattern-39 warnings** (personal mode only)
+6. **Summary of changes** — list of patterns that fired
+7. **Attestation block** (prose + personal)
+8. **Write-back note** — when a file path was supplied
-## Full Example — Personal Mode
+## Full Example — Personal Mode (compact output)
-**Before** (a commit message draft from a model):
+**Before** (a commit message draft from a model, supplied at `/tmp/commit-empty-guard.md`):
> Adds new validator for empty input handling.
>
> The previous validation logic in `~/code/rulesets/voice/SKILL.md` allowed empty strings to leak through to the database layer; this change introduces a guard at the API boundary that returns a 400 response when the input field is empty or contains only whitespace, ensuring data integrity is maintained throughout the request lifecycle. It is worth noting that this does not affect the upstream caller, and we are excited about the productivity gains this will provide.
>
> Furthermore, the new pattern leverages our existing validation framework to deliver a robust, scalable, and maintainable solution.
-**Mode used:** personal
-
-**Draft rewrite (after walking patterns 1-41):**
-> feat(api): add empty-input guard at the validator boundary
->
-> I added a guard that rejects empty or whitespace-only input fields at the API boundary with a 400 response. The previous flow let empty values leak through to the database layer.
->
-> The change doesn't affect the upstream caller — that's a separate concern. The new pattern reuses the existing validation framework.
-
-**What makes the below so obviously AI generated?**
-- "ensuring data integrity is maintained throughout the request lifecycle" was a textbook -ing-phrase analysis (pattern #3)
-- "we are excited about the productivity gains" was felt-experience narration (pattern #36)
-- "robust, scalable, and maintainable" was rule-of-three (pattern #10)
+**Output:**
-**Final rewrite:**
+**Final text:**
> feat(api): add empty-input guard at the validator boundary
>
> I added a guard that rejects empty or whitespace-only input fields at the API boundary with a 400 response. The previous flow let empty values leak through to the database layer.
>
-> The change doesn't affect the upstream caller — that's a separate concern. The new pattern reuses the existing validation framework.
+> The change doesn't affect the upstream caller. The new pattern reuses the existing validation framework.
**Pattern-39 warnings:**
- WARN: original draft line 3: `~/code/rulesets/voice/SKILL.md` — local absolute path. State the underlying validation behavior instead.
-**Summary of changes:**
-- Patterns that fired in personal mode: #3 (-ing analysis), #4 (promotional language), #10 (rule of three), #29 (cliché flag — "leverages"), #32 (first-person voice), #34 (contractions), #36 (felt-experience), #38 (terse cut: "It is worth noting"), #39 (public-artifact scope warning)
+**Fired:** #3 (-ing analysis), #4 (promotional), #10 (rule of three), #29 (cliché: "leverages"), #32 (first-person), #33 (semicolon), #34 (contractions), #36 (felt-experience), #38 (terse: "It is worth noting")
+
+**Attestation:**
+- #13 em-dash: checked — no match
+- #37 fragments: checked — no match
+- #38 terse: checked — fired ("It is worth noting that" cut; final per-sentence pass ran)
+- #40 praise asymmetry: checked — not applicable (commit, not review)
+- #42 finding stems: checked — not applicable (commit, not review finding)
+
+**Write-back:** written back to /tmp/commit-empty-guard.md
## Full Example — General Mode
@@ -422,7 +470,7 @@ Provide:
> The Statistical Institute of Catalonia was established in 1989 to collect and publish regional statistics independently from Spain's national statistics office. It was part of a wider movement to decentralize administrative functions across Spain. Regional reporting got more accurate after the change.
**Summary of changes:**
-- Patterns that fired in general mode: #1 (significance inflation: "pivotal moment", "evolution of"), #4 (promotional: "vital component"), #3 (-ing analysis: "showcasing how... can foster"), #8 (copula avoidance: "serves as"), #26 (long-word: removed Latinate constructions). General mode skipped patterns #32-41 (Craig's-voice patterns — prose and personal modes only).
+- Patterns that fired in general mode: #1 (significance inflation: "pivotal moment", "evolution of"), #4 (promotional: "vital component"), #3 (-ing analysis: "showcasing how... can foster"), #8 (copula avoidance: "serves as"), #26 (long-word: removed Latinate constructions). General mode skipped patterns #32-45 (Craig's-voice patterns — prose and personal modes only).
## Reference
@@ -432,8 +480,11 @@ This skill draws from:
- Orwell, *Politics and the English Language* — patterns #26 (short over long), #27 (active over passive), #29 (cliché).
- Plain English Campaign — pattern #26 (Plain English wordlist).
- Garner, *Modern English Usage* — pattern #26 (word-pair preferences).
-- Craig's voice rules from `claude-rules/commits.md` (Voice and Focus section) — patterns #32-41, split across prose mode (his authored prose and email) and personal mode (publish artifacts).
+- Craig's voice rules from `claude-rules/commits.md` (Voice and Focus section) — patterns #32-42, split across prose mode (his authored prose and email) and personal mode (publish artifacts).
+- Corpus measurement (2026-05-29 phases 1-2, documented in the profile) — patterns #43-45 and the calibration notes on #7, #13, #33.
Key insight (Wikipedia, paraphrased): LLMs use statistical algorithms to guess what should come next. The result tends toward the most statistically likely text that applies to the widest variety of cases. Patterns #1-25 detect that signature.
Key insight (Orwell): "If it is possible to cut a word out, always cut it out." Patterns #22, #23, #26, #38 act on this rule at increasing levels of aggressiveness depending on register.
+
+Key insight (2026-06-10): the patterns that fail in practice aren't missing rules — they're present rules walked without receipts. The attestation block exists because "walk all 45" is a prose instruction, and prose instructions about diligence don't survive contact; named per-pattern receipts do.
diff --git a/voice/references/voice-profile.org b/voice/references/voice-profile.org
index ab37ba1..088f0eb 100644
--- a/voice/references/voice-profile.org
+++ b/voice/references/voice-profile.org
@@ -110,6 +110,8 @@ These two rules are still valuable. Em-dashes and semicolons both read cleaner w
* Suggested deltas
+*All six deltas landed 2026-06-10* via the voice-skill revision from the work-project session: 1 and 2 are in the §13/§33 rule lines and entries, 3 is the §7 soft-flag, 4-6 became patterns §43-§45. The list is kept as the record of what was proposed on 2026-05-29.
+
Six concrete edits to =voice/SKILL.md=, all of which can land independently:
1. *#13 (Em-Dash).* Drop the "LLMs use em dashes more than humans" framing in the personal-mode section. Restate the zero-tolerance rule as self-discipline ("Craig's published voice drops em-dashes by choice"), not habit-reflection. Cite: corpus rate 3.49/1000, AI-comparable.
@@ -134,7 +136,7 @@ Six concrete edits to =voice/SKILL.md=, all of which can land independently:
* Per-pattern entries
-The 41 patterns are migrated below from SKILL.md per the pairing rule above. Phase 1 of this migration populates only Pattern §13 as a worked example of the form. The remaining 40 patterns are scheduled for the backfill pass once Craig confirms the shape.
+All patterns are entered below per the pairing rule above, §1 through §45, matching SKILL.md's numbering.
** §1 Undue Emphasis on Significance, Legacy, and Broader Trends
@@ -485,7 +487,7 @@ Prose + personal modes: zero-tolerance.
Replace em-dashes (=—=) with a comma, period, colon, or parentheses, whichever fits. Zero-tolerance in prose and personal modes holds *everywhere in the text*, including inside example blocks, code-fence prose, and quoted material. An em-dash in a quoted line still gets replaced.
*** Problem
-LLMs use em dashes more than the median human writer, mimicking "punchy" sales writing.
+Craig's published voice drops em-dashes by choice: they read cleaner absent from short imperative-leaning prose and their overuse is a common AI tell (LLMs use em dashes more than the median human writer, mimicking "punchy" sales writing). The rule is chosen self-discipline, not a reflection of his pre-rule habit — the corpus shows he used them regularly in commit bodies.
*** Basis
Phase 1 corpus (git commits, 128k words): 3.49 em-dashes per 1000 words. Comparable to AI-generated prose. Phase 2 corpus reveals a sharp register split: personal email 0.28 per 1000, work email 2.05, PR descriptions 0.62, PR review comments 0.00. Em-dashes are concentrated in commit prose, almost absent from email and PR review prose. The zero-tolerance rule in prose and personal modes mostly enforces what is already true for non-commit registers. The rule still earns its place because commit prose is the high-volume register where the AI-tell em-dash habit shows up. Self-discipline, not habit-reflection, for the commit register specifically.
@@ -505,6 +507,7 @@ The term is primarily promoted by Dutch institutions, not by the people themselv
- 2026-05-26 (commit =4fac2a0=): prose mode added, rule strengthened to zero-tolerance in prose and personal.
- 2026-05-29 (commit =c3cf9a5=): Note on basis added with corpus measurement.
- 2026-05-29: migrated to this file as the canonical home per the pairing rule.
+- 2026-06-10: the self-discipline reframing (a "Suggested deltas" item from 2026-05-29, never applied) moved from the findings section into the entry proper and into the SKILL.md rule line. Craig's call, from the work-project session.
** §14 Overuse of Boldface
@@ -1074,10 +1077,10 @@ Impersonal third-person construction in a publish-artifact body where first-pers
Prose and personal modes. General mode keeps semicolons because academic and literary registers use them legitimately.
*** Rule
-Replace semicolons with a period (split into two sentences) or a comma (when the clauses are tightly coupled) in Craig's authored prose: emails, documents, working notes, commit-message bodies, PR descriptions, PR review comments. A formal long-form document can keep the semicolon, but the default is to split.
+Replace semicolons with a period (split into two sentences) or a comma (when the clauses are tightly coupled) in Craig's authored prose: emails, documents, working notes, commit-message bodies, PR descriptions, PR review comments. A formal long-form document can keep the semicolon, but the default is to split. Chosen self-discipline, not habit-reflection.
*** Problem
-Craig's voice avoids semicolons. They make the writing feel unnecessarily literary. The period-split usually reads better, and dropping semicolons removes one common AI tell.
+Craig's published voice drops semicolons by choice. They make the writing feel unnecessarily literary, the period-split usually reads better, and dropping them removes one common AI tell. The rule overrides his pre-rule habit rather than codifying one — the corpus shows he used semicolons regularly in commit prose.
*** Basis
Corpus-measured across registers (2026-05-29): semicolons run 3.16 per 1000 words in git commits, 0.64 in personal email, 0.26 in work email, 0.62 in PR descriptions, 0.00 in PR review comments. Same register split as em-dashes (§13). Semicolons are concentrated in commit prose; conversational prose almost never uses them. The rule mostly enforces what is already true for non-commit registers. It earns its place because commit prose is the register where Craig's habit and the AI-tell pattern overlap.
@@ -1099,6 +1102,7 @@ Semicolons in prose Craig authors: emails, documents, working notes, commit-mess
- Original SKILL.md entry: semicolon to period or comma in Craig's authored prose.
- 2026-05-29 (commit =c3cf9a5=): basis note added with corpus measurement reframing the rule as self-discipline.
- 2026-05-29: migrated to this file as the canonical home per the pairing rule.
+- 2026-06-10: the self-discipline reframing (a "Suggested deltas" item from 2026-05-29, never applied) moved from the findings section into the entry proper and into the SKILL.md rule line. Craig's call, from the work-project session.
** §34 Contractions
@@ -1199,7 +1203,7 @@ Phrases that tell the reader how the change will feel or how often the writer wi
Prose and personal modes. General mode keeps the softer §30, which exempts more, because the strong "every sentence" rule is Craig's voice and should not be imposed on third-party text.
*** Rule
-Rewrite every sentence fragment inside a prose paragraph in Craig's authored text as a complete sentence with subject and verb. Bullets and headings can stay fragments.
+Rewrite every sentence fragment inside a prose paragraph in Craig's authored text as a complete sentence with subject and verb. Bullets and headings can stay fragments. Exemption: verdict formulas in PR review summaries ("Approving.", "Requesting changes.", "Approved.") are house style and stay — rewriting them imposes the rule where Craig's calibrated voice already decided otherwise.
*** Problem
Bullet shorthand leaking into running prose ("Two changes." "Fix incoming." "Body as decision log.") reads as bullet-list notes pasted into a paragraph. Every prose sentence needs a subject and a verb in prose and personal modes.
@@ -1223,6 +1227,7 @@ Sentence fragments inside prose paragraphs in any text Craig authors: an email,
*** History
- Original SKILL.md entry: sentence-fragment rewrite for Craig's authored prose.
- 2026-05-29: migrated to this file as the canonical home per the pairing rule.
+- 2026-06-10: verdict-formula exemption added. The skill survived in practice by being selectively ignored on "Approving." / "Requesting changes." / "Approved.", and selective ignoring is the same muscle that skips real patterns. Documenting the exception removes one standing occasion for judgment-override. Craig's call, from the work-project session.
** §38 Terse Cut — Omit Needless Words
@@ -1309,6 +1314,8 @@ On an approve summary: praise plus verdict, nothing else. Cut any clause that de
On a finding or change-request: always give the why, gently and briefly. Not "Move this to a helper." but "I'd pull this into one helper — three copies of the same rule means the next change has to touch all three, and missing one brings the bug back."
+Verification narration is the same defect as justified praise. "I traced X and it's safe because..." pads the compliment with the reviewer's homework. Tracing the code is the reviewer's job, not content for the comment — if verification found a problem, the problem gets the words; if it found nothing, it gets zero words.
+
*** Problem
Praise and correction call for opposite treatment. The author already knows why their good change is good, so justifying praise reads as flattery. Correction is the reverse. Behavior only changes when the reason lands, so a finding, change-request, or inline coaching note must always explain the why. And the why is delivered gently, the way a kind coach or mentor would.
@@ -1325,12 +1332,23 @@ Nice clean migration, the provider mocks and the Normal/Boundary/Error cases are
Clean migration. Approving. One note inline: I'd rename `x` to `provider` — it reads as a generic placeholder and the next person won't know it's the resolved provider without tracing it.
#+end_example
+*** Before (verification narration)
+#+begin_example
+All three fixes look right. I traced useMapActions and the unmount cleanup is safe because the hook returns a memoized object, and the provider wraps the whole app so neither call site lands on the no-op path.
+#+end_example
+
+*** After
+#+begin_example
+All three fixes are clean and well-aimed.
+#+end_example
+
*** Detection
-In a PR review summary or comment: a praise clause that explains why the good thing is good, or a finding or change-request that states what to fix without saying why.
+In a PR review summary or comment: a praise clause that explains why the good thing is good, a praise clause followed by the verification work that supports it, or a finding or change-request that states what to fix without saying why.
*** History
- Original SKILL.md entry: praise-versus-correction asymmetry for PR review.
- 2026-05-29: migrated to this file as the canonical home per the pairing rule.
+- 2026-06-10: verification-narration variant added after the third recurrence — a review draft praised a fix and then narrated the verification supporting the praise (the #236 draft). Added to the SKILL.md rule line and the high-recurrence attestation set. Craig's call, from the work-project session.
** §41 No Emphasis Formatting
@@ -1362,3 +1380,150 @@ Bold (=**...**=), italic (=*...*= or =_..._=), or underscore-wrapped words used
*** History
- Original SKILL.md entry: no emphasis formatting for Craig's authored prose.
- 2026-05-29: migrated to this file as the canonical home per the pairing rule.
+
+** §42 Finding Stems — One Claim Per Sentence
+
+*** Modes
+Personal mode only. General and prose skip because the rule assumes a PR review finding.
+
+*** Rule
+A PR review finding is built from clean stems, each a straightforward sentence carrying one claim: (1) where the bug is, (2) the way(s) to fix it, (3) why that's better. Cut context sentences that don't change what the author does next (ticket history, design archaeology). Rewrite the anti-pattern shapes: hedged gerund chains ("the real bug looks like the model emitting a partial set"), compressed trade-off clauses ("I'd rather X, or Y, than lose Z"), multi-claim sentences chained through so-clauses or "and", and fixes buried after a mid-sentence colon.
+
+*** Problem
+Craig named detangling overly complex or overly wordy Claude-drafted PR review text as THE key issue he fights in PR reviews, and the reason he gates every review draft. The tangles passed all 41 then-existing patterns — §38 shortens but doesn't untangle; a sentence can be terse and still carry three claims. §40 governs praise; this governs how finding text is constructed.
+
+*** Basis
+Observation-derived from PR #233 (2026-06-10): a review comment shipped with hedged gerund chains and compressed trade-off clauses that cleared the full walk. The three Before/After pairs below are Craig-approved rewrites from that PR.
+
+*** Before (multi-claim opener + context sentence)
+#+begin_example
+POST fixes the wipe but it's additive: it no-ops on an empty list and never removes, so "cancel all partners" and any de-selection silently stop working. PUT came from SE-195 so the confirm could reconcile the full set. The real bug is upstream: on a new tasking the confirm emits only the new provider, not the full set. Fix that, or merge with the mission's current providers before the PUT. Either way removal keeps working.
+#+end_example
+
+*** After
+#+begin_example
+POST is additive: it no-ops on an empty list and never removes. That breaks "cancel all partners" and any de-selection. The real bug is upstream: on a new tasking the confirm emits only the new provider, not the full set. Fix that, or merge with the mission's current providers before the PUT, and removal keeps working.
+#+end_example
+
+The SE-195 context sentence is cut because it doesn't change the author's next action.
+
+*** Before (hedged gerund chain + compressed trade-off — the calibration case Craig pulled up)
+#+begin_example
+The real bug looks like the model emitting a partial set on a new tasking. I'd rather fix what the confirm emits, or merge client-side before the PUT, than lose removal.
+#+end_example
+
+*** After (where / fix / payoff)
+#+begin_example
+The real bug is upstream: on a new tasking the confirm emits only the new provider, not the full set. Fix that, or merge with the mission's current providers before the PUT. Either way removal keeps working.
+#+end_example
+
+*** Before (claims joined with "and"; fix buried after a mid-sentence colon)
+#+begin_example
+The prefix check catches any message starting with "confirm ", and the options block exists so the LLM can resolve "number 2" style references. A typed "confirm number 2" loses the list it needs. The card click already sends a self-describing "confirm <id>": pass an explicit parameter through sendAgentMessage and strip only on that path.
+#+end_example
+
+*** After
+#+begin_example
+The prefix check strips the options block from any typed message starting with "confirm ", so "confirm number 2" loses the list the LLM needs to resolve it. Strip on the card-click path instead, with an explicit parameter passed through sendAgentMessage. The click already sends a self-describing "confirm <id>", so stripping is safe there.
+#+end_example
+
+*** Detection
+In a PR review finding: a sentence carrying more than one claim (chained through so-clauses, "and", or a mid-sentence colon hiding the fix), a hedged gerund chain where a direct claim belongs, a compressed trade-off clause, or a context sentence that doesn't change the author's next action.
+
+*** History
+- 2026-06-10: created from the PR #233 calibration session. Proposed in the work project's stems handoff, landed via the consolidated voice-skill revision. Included in the high-recurrence attestation set from day one. Craig's call.
+
+** §43 Single-Sentence Paragraph Cadence Is a Feature
+
+*** Modes
+Prose and personal modes. General mode skips because third-party registers legitimately prefer multi-sentence paragraphs.
+
+*** Rule
+A one-sentence paragraph is a finished thought, not a fragment. Break paragraphs after one complete thought when the next thought shifts angle, even if both are short. Never merge short paragraphs into multi-sentence ones in a "clean prose" pass.
+
+*** Problem
+Most prose-style guides advise multi-sentence paragraphs, so a generic cleanup pass merges Craig's short paragraphs and erases a distinctive feature of his voice. This is a protective pattern: it guards an existing trait rather than correcting a defect.
+
+*** Basis
+Corpus-measured (2026-05-29). Single-sentence-paragraph rate: git commits 41.1%, personal email 57.4%, work email 44.5%, PR descriptions 74.4%, PR review comments 50.0%. Between 41% and 74% of Craig's paragraphs are exactly one sentence, depending on register.
+
+*** Before (a cleanup pass merging short paragraphs)
+#+begin_example
+The build now finishes in half the time, and the cache no longer invalidates on every run, which means the CI queue clears faster too.
+#+end_example
+
+*** After
+#+begin_example
+The build now finishes in half the time.
+
+The cache no longer invalidates on every run, so the CI queue clears faster too.
+#+end_example
+
+*** Detection
+An edit pass that merged short paragraphs, or a draft whose paragraphs each stack multiple shifted angles that would read better broken apart.
+
+*** History
+- 2026-05-29: surfaced by the Phase 1-2 corpus measurement as a "worth adding" trait; filed as suggested delta 4.
+- 2026-06-10: promoted from the suggested-deltas list into a numbered pattern. Craig's call, from the work-project session.
+
+** §44 Parenthetical Asides Are Part of the Voice
+
+*** Modes
+Prose and personal modes. General mode skips because third-party text owns its own aside conventions.
+
+*** Rule
+Parentheses for asides, clarifications, and scope-narrowing are Craig's voice. Don't strip them in a cleanup pass. They're also the preferred landing spot for em-dash replacements under §13.
+
+*** Problem
+Generic style passes treat parentheticals as clutter and strip them. For Craig they carry asides, clarifications, and scope-narrowing, and removing them flattens the voice. Protective pattern, like §43.
+
+*** Basis
+Corpus-measured (2026-05-29): 23.07 opening parens per 1000 words across the commit corpus. Heavy parenthetical use is distinctive and consistent.
+
+*** Before (a cleanup pass stripping the aside)
+#+begin_example
+The sync runs on every startup. It skips lockfiles. It also skips build output.
+#+end_example
+
+*** After
+#+begin_example
+The sync runs on every startup (skipping lockfiles and build output).
+#+end_example
+
+*** Detection
+An edit pass that removed parenthetical asides present in the source text, or an em-dash replacement under §13 where parentheses fit better than a comma or period.
+
+*** History
+- 2026-05-29: surfaced by the Phase 1-2 corpus measurement as a "worth adding" trait; filed as suggested delta 5.
+- 2026-06-10: promoted from the suggested-deltas list into a numbered pattern, with the §13 landing-spot note. Craig's call, from the work-project session.
+
+** §45 Declarative Register Marker
+
+*** Modes
+Prose and personal modes, advisory. Flag only; no auto-rewrite. General mode skips.
+
+*** Rule
+Craig's prose is declarative. When a draft contains a rhetorical question, flag it for a second look — it's usually AI rhetoric, not his register. Genuine questions to the reader (a review asking the author's intent, an email asking for a decision) stay.
+
+*** Problem
+AI drafts reach for rhetorical questions ("So what does this mean for the build?") as a transition device. Craig states things; he rarely asks them. A rhetorical question in his voice is a tell, but a genuine question is legitimate content, so the pattern flags rather than rewrites.
+
+*** Basis
+Corpus-measured (2026-05-29): 0.33 question marks per 1000 words across the commit corpus. His prose register is declarative.
+
+*** Before (rhetorical transition flagged)
+#+begin_example
+So what does this change for the deploy flow? The staging gate now runs before the canary, which means a bad build never reaches it.
+#+end_example
+
+*** After
+#+begin_example
+The staging gate now runs before the canary, so a bad build never reaches it.
+#+end_example
+
+*** Detection
+A question mark in a draft in Craig's voice. Flag it; keep genuine questions to the reader, rewrite rhetorical ones as declarative claims.
+
+*** History
+- 2026-05-29: surfaced by the Phase 1-2 corpus measurement as a register marker; filed as suggested delta 6.
+- 2026-06-10: promoted from the suggested-deltas list into a numbered advisory pattern. Craig's call, from the work-project session.