feat: gate every agent prompt on projectType (fiction vs non-fiction) - #93
Merged
Conversation
The editor was running the same fiction-tuned criteria against non-fiction prose. Observed signal from the Phoenix Three book run (issue #30) showed the editor demanding "scene-grade rendering" and "close-third character beats" on prose constrained to public record — putting the reviser in an impossible bind: either fabricate (which the editor would also flag) or stay analytical (which the editor would call "all summary, no scene"). The fight drove 4-5 review rounds per chapter. This adds a projectType gate to buildEditorPrompt: - Optional projectType param defaults to fiction behavior (existing tests still pass with no change). - NOVEL / NOVELLA / SHORT_STORY_COLLECTION go through buildFictionCriteria, which keeps the existing scene-structure / character-voice / subtext / climax-execution criteria. - NON_FICTION goes through buildNonFictionCriteria, which: - Drops scene-grade demands explicitly ("do NOT demand scene-grade rendering or show-vs-tell beats here"). - Replaces "Character Voice" with "Subject Fidelity" (real-people rendering from public record; quotes verbatim from citable sources). - Replaces "Pacing and Scene Structure" with "Argument and Flow" (claim / evidence / implication for analytical prose). - Promotes SOURCING to a CRITICAL primary criterion with four explicit sub-classes: FABRICATION, CITATION, HEDGING, UNSOURCED SPECIFIC. Each names the fix action. - Reframes CONTINUITY as factual continuity (date math, tenure, organizational structure, direction-of-time errors). - Reference-Materials section also reframes per genre. Shared scaffolding stays identical: header, style guide, continuity state injection, output format (severity + confidence tags), verdict-via-gh-pr-review, self-owned-PR fallback, instructions, guard rails. The category list also swaps: - Fiction: PLOT, CHARACTER, PACING, WORD_COUNT, STYLE, PROSE, CONTINUITY - Non-fiction: PLOT, SOURCING, SUBJECT, ARGUMENT, WORD_COUNT, STYLE, PROSE, CONTINUITY Handler change: review-chapter.ts now passes projectType: project.config.projectType to buildEditorPrompt. Tests: existing fiction assertions (148 prompt tests) unchanged; 14 new tests cover the gate (default → fiction; each fiction projectType → fiction; NON_FICTION → non-fiction criteria, SOURCING sub-classes, explicit no-scene-grade demand, reframed reference materials, shared scaffolding preserved, series mode works on non-fiction). Full suite: 1043 passed. This is the small-first-cut from the editor-gate design discussion: gate just the editor to validate the dispatch shape on a real run, then extend to the writer / outliner / continuity-checker if signal supports it.
Extends the editor-gate pattern to the remaining six agents so the entire
pipeline can adapt to NON_FICTION projects. Same shape across all of
them: optional projectType param defaults to fiction behavior, gate
swaps the agent-specific block(s), shared scaffolding (header, file
paths, completion, self-check skeletons, gh CLI commands, guard rails)
stays identical.
Per-agent changes:
- outliner.ts — replaces fictional Story Architecture (dramatic
question + character arcs with want/need/flaw/lie/ghost + 8-point
Climax Checklist + genre-aware predictability contracts + climax
failure modes) with Reporting Architecture for non-fiction
(central argument + structural anchors + subject portraits drawn
from public record only + research mandate + structural-anchor
chapter concept + non-fiction failure modes including
"fabricated dramatization", "hagiography", "tell-all",
"imagined interior on real people"). The character bible spec
becomes a subject bible (no want/need/flaw/lie/ghost — explicitly
forbidden); the world bible becomes the institutional landscape
with cited histories; the research notes spec demands a working
bibliography and an On Sourcing front-matter draft.
- writer.ts — replaces scene-structure (objective/obstacle/escalation/
turn) and "show pivotal moments / tell connective tissue" with
paragraph-grade analytical structure (claim/evidence/implication)
and "where scene-grade rendering IS allowed" rules
(only on documented moments). Replaces the AI-fiction-cliche
watchlist with the AI-non-fiction-tic watchlist actually observed
in editor reviews of the Phoenix Three book run ("the kind of X",
"What X taught/bought/added", inversion-aphorism patterns,
hyphen-stack noun phrases, sourcing meta-commentary inside the
prose, imagined interior on real people). Replaces climax handling
with structural-anchor handling. Mandates WebSearch / WebFetch
use in the writing instructions.
- continuity-checker.ts — keeps the shared ContinuityState JSON
schema (so writer/editor pipeline keeps consuming a uniform shape)
but reframes the SEMANTICS for non-fiction. Issue types swap from
CHARACTER/TIMELINE/WORLD_STATE/PLOT_THREAD to SUBJECT/TIMELINE/
ENTITY/CITATION/SOURCING. Schema field comments document the
non-fiction mapping (characters → subjects, plotThreads →
analytical threads, worldState → cited factual claims keyed by
topic). Chapter summary becomes a factual summary keyed to
the chapter's claims rather than a narrative summary.
- auditor.ts — issue categories swap to CONTRADICTION/
UNSUPPORTED_CLAIM/TIMELINE_ERROR/SUBJECT_INCONSISTENCY/
ENTITY_ERROR/CITATION_ERROR. World-state schema example shows
non-fiction semantics (publicTitle, source pointers in timeline
entries, analytical threads).
- continuity-fixer.ts — reconciliation principles swap: "the bibles
win" becomes "the public record wins" (with bibles as the cited
reference); "never edit the climax for hygiene" becomes "never
edit the structural-anchor chapter". Per-category fix guidance
covers SUBJECT_INCONSISTENCY, ENTITY_ERROR, CITATION_ERROR (with
WebFetch verification mandated), and UNSUPPORTED_CLAIM (hedge or
cut, do not fabricate provenance). Self-check verifies the fix is
grounded in the public record.
- reviser.ts — light. Reference materials reframe (subject bible,
institutional landscape, working bibliography). Revision
instructions add a SOURCING-aware diagnose-before-changing step
that distinguishes FABRICATION / CITATION / HEDGING / UNSOURCED
SPECIFIC sub-classes. Self-check requires citation, hedging, and
forbids new fabrication.
- planner.ts — light. "Climax convergence" dependency rule becomes
"Structural-anchor convergence". Reference-materials guidance and
the parallel-storyline rule reframe for non-fiction.
Handlers updated to pass project.config.projectType into each prompt
builder: plan-chapters, trigger-chapter, revise-chapter,
continuity-check, continuity-audit, continuity-fixer.
(generate-outline already passed it; review-chapter was updated in
the prior commit for the editor gate.)
Tests: 41 new non-fiction-gate tests (one block per gated builder),
with assertions covering both what the non-fiction path adds (e.g.
"Sourcing discipline" in writer; "Subject bible" / "institutional
landscape" / "structural-anchor chapter" in outliner;
"UNSUPPORTED_CLAIM" / "CITATION_ERROR" in auditor) and what it
removes (e.g. the fictional "Climax — the chapter that justifies
every chapter before it" header is absent in non-fiction outliner;
"UNRESOLVED_THREAD" / "CHARACTER_INCONSISTENCY" / "LOCATION_ERROR"
absent in non-fiction auditor; "Scene structure / Build each scene"
absent in non-fiction writer). Existing 162 fiction tests unchanged
and still pass. Total prompt-builder tests: 203. Full suite: 1084
passed.
Design choice: kept ContinuityState JSON schema shared rather than
forking. The non-fiction prompts use the same fields with documented
non-fiction semantics. This avoids a large coordinated change to the
writer/editor/reviser/auditor/fixer code that all read or write the
state. Trade-off accepted: the field names (characters, plotThreads,
worldState) read awkwardly for non-fiction, but the cost of forking
the schema across the whole pipeline is much higher than the
readability cost of overloaded field names.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Gates all seven agent prompts on
projectTypeso the entire pipeline adapts toNON_FICTIONprojects. Same shape across every gated builder: optionalprojectTypeparam defaulting to fiction behavior, helper functions emit fiction or non-fiction blocks, shared scaffolding (header, file paths, completion, gh CLI, guard rails) stays identical.This was driven by signal from the Phoenix Three book run (
tdrml/auto-graph-books#30, repotdrml/the-phoenix-three), where the fiction-tuned editor demanded scene-grade rendering on non-fiction prose constrained to public record — putting the reviser in an impossible bind that drove 4-5 review rounds per chapter. The editor gate (commitc0792c2— first commit on this branch) addressed the immediate friction; this commit extends the same dispatch shape to outliner, writer, continuity-checker, auditor, fixer, reviser, and planner so non-fiction prose is generated and audited on its own terms from the start.Per-agent changes (most → least)
Outliner. Replaces the fictional Story Architecture (dramatic question + want/need/flaw/lie/ghost arcs + 8-point Climax Checklist + genre-aware predictability contracts + climax failure modes) with Reporting Architecture for non-fiction: central argument, structural anchors (founding decision / recognition payoff / pivot / near-failure averted), subject portraits drawn from public record only (no invented arcs on living people), research mandate (WebSearch/WebFetch), and non-fiction failure modes ("fabricated dramatization", "hagiography", "tell-all", "imagined interior on real people"). Character bible spec becomes a subject bible with public-record biographical facts and verbatim quotes; world bible becomes the institutional landscape; research notes spec demands a working bibliography and an "On Sourcing" front-matter draft.
Writer. Replaces scene structure (objective/obstacle/escalation/turn) and "show pivotal moments / tell connective tissue" with paragraph-grade analytical structure (claim/evidence/implication) and explicit "where scene-grade rendering IS allowed" rules (only on documented moments). The AI-fiction-cliché watchlist swaps for the AI-non-fiction-tic watchlist actually observed in Phoenix Three editor reviews ("the kind of X", "What X taught/bought/added", inversion-aphorism patterns, hyphen-stack noun phrases, sourcing meta-commentary in third-limited, imagined interior on real people, invented named participants in real meetings). Climax handling → structural-anchor handling. WebSearch/WebFetch mandated in writing instructions.
Continuity-checker. Issue types swap from
CHARACTER / TIMELINE / WORLD_STATE / PLOT_THREADtoSUBJECT / TIMELINE / ENTITY / CITATION / SOURCING. Schema kept shared (the writer/editor pipeline reads a uniform shape) but field comments document the non-fiction mapping:characters→ subjects,plotThreads→ analytical threads,worldState→ cited factual claims keyed by topic. Chapter summary becomes a factual summary keyed to claims rather than narrative.Auditor. Issue categories swap to
CONTRADICTION / UNSUPPORTED_CLAIM / TIMELINE_ERROR / SUBJECT_INCONSISTENCY / ENTITY_ERROR / CITATION_ERROR. World-state schema example shows non-fiction semantics (publicTitle, source pointers in timeline entries, analytical threads).Continuity-fixer. Reconciliation principles shift: "the bibles win" → "the public record wins"; "never edit the climax for hygiene" → "never edit the structural-anchor chapter". Per-category fix guidance covers
SUBJECT_INCONSISTENCY,ENTITY_ERROR,CITATION_ERROR(WebFetch verification required before applying), andUNSUPPORTED_CLAIM(hedge or cut; never fabricate provenance).Reviser (light). Reference materials reframe (subject bible, institutional landscape, working bibliography). Revision instructions add a SOURCING-aware diagnose-before-changing step distinguishing FABRICATION / CITATION / HEDGING / UNSOURCED SPECIFIC sub-classes. Self-check forbids new fabrication.
Planner (light). "Climax convergence" dependency rule → "Structural-anchor convergence". Reference-materials and parallel-storyline rule reframe.
Editor (already shipped in commit
c0792c2— first commit on this branch). Gate uses fiction criteria for NOVEL/NOVELLA/SHORT_STORY_COLLECTION; SOURCING-driven non-fiction criteria with FABRICATION / CITATION / HEDGING / UNSOURCED SPECIFIC sub-classes for NON_FICTION.Handlers
Updated
plan-chapters.ts,trigger-chapter.ts,revise-chapter.ts,continuity-check.ts,continuity-audit.ts,continuity-fixer.tsto passproject.config.projectTypeinto their respective prompt builders. (generate-outline.tsalready did;review-chapter.tswas updated in the editor-gate commit.)Design choice: shared ContinuityState schema
Kept the
ContinuityStateJSON schema shared rather than forking. The non-fiction prompts use the same fields with documented non-fiction semantics in comments. Trade-off: field names (characters,plotThreads,worldState) read awkwardly for non-fiction, but forking the schema across writer/editor/reviser/auditor/fixer code that all read or write the state is a much larger coordinated change. Readability cost accepted; can revisit if a real run signals it's actually causing confusion.Test plan
pnpm vitest run packages/core/src/prompts/__tests__/prompts.test.ts— 203/203 pass (162 existing fiction + 41 new non-fiction-gate)pnpm vitest run— 1084/1084 actual tests passpnpm --filter @auto-graph/core build— cleanpnpm --filter @auto-graph/lambdas build— clean (only the pre-existing cloudwatch dep issue in reconcile-enqueuer.test.ts)Files changed
c0792c2— editor gate (3 files, 226 / 26 lines)2d6e3dc— outliner / writer / continuity-checker / auditor / fixer / reviser / planner gates + handler wiring + tests (14 files, 1685 / 256 lines)🤖 Generated with Claude Code