Atticus · Voice Lab · Spec review

Voice Lab spec: what changed and what needs your call

A review of Docs/mockups/voice-lab-spec.md against the nine-screen prototype and the shipped code, with the revisions applied to the spec.

2026-09-27 · The original spec is untracked in git. A pre-revision copy exists only in the session scratchpad, so this page is the record of every change.
Appliedfixed in the spec Your callwritten into the spec as an Open (n) item with a recommendation Codea fact about shipped code the spec now accounts for
4internal contradictions resolved
9open decisions for you
10code facts that change the spec
2shipped bugs the spec depends on fixing

Decisions: resolved 2026-09-27

You accepted every recommendation, and the spec now states each one as decided. For stakes, the call is mode alone selects the register. Pairs 3 and 8 received neutral-topic rewrites, and two refusals that divide writers were added. The implementation plan is .claude/plans/voice-lab-room.md.

  1. Replacement pairs 4, 7, 8, 10 (§4.1). Four pairs differ on more than one axis. The spec includes candidate rewrites.
  2. An adaptive second pair (§4.1). With one pair per axis, every hunch rests on one click. Recommended: show a second pair only where the first pick disagrees with something already written.
  3. The reflective prompt (§4.3). The prompt asks for recall, which Principle 2 rules out. The spec includes a present-tense candidate.
  4. The ceiling-overrun signal (§4.3). It is confounded with Clipped/Rolling. Recommended: record overruns and give them zero weight until drafts validate them.
  5. More discriminating refusals (§4.4). Nearly everyone refuses four of the five.
  6. Where the proposed verdict comes from (§5.3). Recommended: a fixed mode × axis default table the writer can edit.
  7. The "step back" trigger (§7.2). Recommended: sending to Critique or saving a version.
  8. Stakes (§7.1). The field exists but is never set. Discovery either starts setting it, or mode alone selects the register.
  9. Moving the backup folder into its own spec (§8.4). It covers every piece of writing and needs a new entitlement.

Two decisions stay with the implementation plan, as you chose: retiring or keeping the five-dimension analysis and MentorStance (§11), and phase order.

Contradictions

AppliedThe ink rule mixed actual and aspirational evidence

The old rule said a mark inks when "the pairs plus a draft" agree. Pairs measure reach and drafts measure writing, so their agreement means no gap. It confirms neither mark. The prototype's mirror copy reads "Pencil to ink: the pairs and the draft agree" on the screen where they disagree.

§5.2 now has three ink rules: one each for the write dot, the reach ring, and the gap. The paragraph screen's copy changes to "no distance here, so far."

Spec §5.2 · Prototype screens 2, 7

Applied"Say it first" wrote in the aspirational voice, and the result counted as the writer's

§7.4.3 forbids generating in the aspirational voice, and the thread's Say it first does exactly that. An accepted suggestion also had no stated authorship. Counted as the writer's, it would close the gap on sentences Atticus wrote, which is the caricature loop §7.4.1 exists to prevent.

The accepted suggestion is now named as the one exception to 7.4.3. It carries the generated-text mark, never feeds the portrait, and never counts as progress (§6.4, §6.5). Students get the question form instead.

Spec §6.4, §6.5, §7.4

Applied"Two sentences. Both yours." is false

The left sentence on the mirror came from a pair. Atticus wrote it and the writer chose it. The mirror is where trust is decided (§9), so the headline has to be exact.

The spec now prefers the writer's own Write it your way sentence when one exists. Otherwise the headline is "One you chose. One you wrote."

Spec §6.2 · Prototype screen 7

AppliedThe hunch says "each time" about a single pair

The portrait copy says "In the pairs you chose the unqualified sentence each time." Only pair 2 measures hedging.

§6.1 now requires hunch copy to describe the evidence it has. The underlying thinness is decision 2 above.

Measurement validity

AppliedThe analytical page's margin note coaches the axis it measures

"Say the true thing first. Decide afterward how much cushioning it needs" appears while the writer answers the page that decides Hedged/Committed. The spark "you don't need to be polite" leans the same way. The worked-example hunch depends on that page reading as hedged.

New Principle 7: nothing Atticus says during an exercise may lean toward a pole that exercise measures. Page notes now arrive on Keep this page, not during typing.

Your callFour pairs break the single-axis rule

Pair 4's warm pole adds "you" and joins two sentences. Pair 7's wry pole reverses the claim, so its gist ("moving is hard") fits only one side. Pairs 8 and 10 differ in sentence count, and pair 8's oblique line is the more striking sentence, which measures quality-taste. Pairs 3 and 8 also break the neutral-topic rule.

The spec adds a rule that sentence count must match unless count is the axis, and lists candidate rewrites for all four.

AppliedThe voiceless paragraph measures in one direction

The source is abstract, absent, formal, and unfolded, so almost any edit moves toward the other pole. A writer who leaves it abstract hasn't shown they write abstractly.

§4.2 states that the paragraph can confirm a lean toward concrete, present, conversational, or compressed, and nothing about a lean away.

AppliedThree axes had no detection method

§8.1 listed five detectable axes and two model-judgment axes. Plain/Ornate, Concrete/Abstract, and Cool/Warm were unassigned.

All ten axes are now classified in a table. Plain/Ornate reuses RegisterScorer's lexical rarity. Only detectable axes can host a hunch, since a model-judgment hunch could never be confirmed on a draft.

AppliedThe hedge lexicon has to separate hedges from scope

The prototype rewrites "I suspect most teachers would probably agree, at least in part" as "Most teachers would agree." That removes a scope qualifier, which changes the claim.

§6.4 distinguishes epistemic hedges from scope qualifiers. Suggestions change only the axis.

AppliedThe mirror's example is the extreme one

The fairness rule said "never the writer's worst sentence," which can't be measured. The prototype then chose the triple-hedged sentence.

The rule is now operational: pick the median-hedged qualifying sentence, excluding justified hedges and quotations.

Missing states

AppliedA hunch could only be confirmed

No path existed for a draft that doesn't show the gap. §6.2 now has disconfirmation copy, and the hunch is withdrawn when it fails.

AppliedNo ending for a sitting with no gap

The sitting "ends on a hunch," with no ending for a writer whose choices and pages agree. §6.1 now has one.

AppliedA gap lifecycle

Don't listen for this, Leave it, Pause, and three correction branches were separate off-switches with no shared model. §6 opens with a state table and a one-active-gap rule. It also specifies how the hunch is chosen, scopes Leave it to one axis in one mode, and matches the mirror to the hunch's mode.

AppliedSmaller gaps filled

What the shipped code changes

FactWhereSpec effect
BugApplied revisions and whole-draft review changes are saved as .writerOriginal. They already feed the voice fingerprint.CompositionViewModel.swift:1270-1283, :2432, :2938§7.4 prerequisite. The portrait can't learn from drafts until this is fixed.
BugStudents can request passage and whole-draft rewrites. Only first-draft generation is gated.CompositionViewModel.swift:1949, :2589§7.4 prerequisite.
The editor draws one highlight at a time, and applyRevision can't be undone.CompositionEditorView.swift:146-154, :317-340§8.7. Threads need new editor capability.
Project.stakes is stored but never set.Project.swift:153§7.1, decision 8.
VoiceDrift checks the opposite direction and is disabled.VoiceDrift.swift:34§7.2. Drift detection is new work.
No step-back event exists. The candidates are Critique send, version save, and leaving Composition.CompositionViewModel.swift:1817, MintTrigger.swift§7.2, decision 7.
VoiceWorkType has no email, letter, or report case, although the entry copy invites them.VoiceWorkType.swift§3. Uploads are tagged by Mode.
The only sentence splitter over-splits on abbreviations.RegisterScorer.swift§8.1.
No persistent folder permission or bookmark entitlement exists.Atticus.entitlements§8.4, decision 9.
Modifier.voiceLoaded and .formallyConventionalized already approximate "your voice or the occasion's."Modifier.swift:13-21§7.1. Reuse them instead of adding a parallel flag.

Unchanged

The principles, the three doors, the exercise order, the core/register split, the mirror-and-fork structure, the generation policy, and the risks are unchanged. The prompt tables and pair table keep your text, and proposed rewrites appear only as Open candidates.