Three changes:
1. Architect fanfic prompt now requires a "new spacetime":
- Explicit divergence point from source material
- Original core conflict (not retelling original plot)
- 5-chapter ignition constraint
- 50% fresh scene locations
2. New FoundationReviewerAgent reviews architect output before
writing begins. Scores 5 dimensions (source DNA, new space,
core conflict, opening momentum, pacing feasibility).
Threshold: 80 total, 60 floor per dimension.
Rejects with specific feedback, architect regenerates.
Max 2 retries before accepting best effort.
3. Review loop integrated into initBook (original mode) and
initFanficBook (fanfic mode). Both now go through
generate → review → (reject → regenerate) cycle.
This addresses the #2 problem (斗破同人 75.5): fanfic architect
was retelling original plot because nothing required it to create
new narrative space.
Hook budget: planner intent now shows "N/12 active hooks" in the
Hook Agenda section. When N >= 10, adds explicit guidance to
prioritize resolving old debt over opening new threads.
Soft hint only — no hard cap.
Ending trail: composer now extracts the last meaningful sentence
from the 3 most recent chapter files and injects it as context,
so the writer can see "ch3: buried under rubble | ch4: buried
under rubble" and know to vary the chapter ending structure.
Post-merge regression: bootstrapStructuredStateFromMarkdown still
included currentState.chapter in lastAppliedChapter, allowing a
hallucinated chapter number in current_state.md to override the
contiguous durable progress.
Changes:
- state-bootstrap.ts: derivedProgress and lastAppliedChapter now
come exclusively from durableStoryProgress (contiguous artifact
chain), currentState.chapter is no longer trusted
- manager.ts: getNextChapterNumber returns durableChapter + 1
without consulting manifest
- story-markdown.ts: hook startChapter/lastAdvancedChapter parsed
with parseStrictChapterInteger (rejects "第141号文明" style prose)
- Tests updated to provide durable chapter artifacts matching the
chapter numbers they expect
Removes the hook lifecycle/pressure scoring system (5-level timing,
pressure formulas, pressure map tables) and replaces it with:
1. Simple stalest-first sorting for mustAdvance (same as iter-001)
2. Hook seed excerpts in composer — for each hookAgenda target, finds
the original chapter where it was planted and the latest advancement
chapter, extracts the hookActivity text, and injects it as an
evidence block the writer can directly build on.
The writer now sees concrete narrative material ("original seed (ch2):
萧炎右手碰到戒面时,有一丝温热渗出") instead of abstract metadata
("pressure: high, movement: partial-payoff, reason: stale-promise").
This addresses the hook execution problem: writer knew WHICH hooks to
advance but not HOW. Seed excerpts provide the "how" material.
The settler may extract a chapter number from story content rather than
using the pipeline's authoritative value (e.g. parsing year "1988" from
a contemporary fiction novel as "第1988章"). This corrupts the manifest's
lastAppliedChapter, causing all subsequent chapters to use absurd numbers.
buildRuntimeStateArtifactsIfPresent now accepts an authoritative chapter
number and replaces the delta's chapter field when it disagrees.
Root cause of 旧城暗号v4's ch4→ch1988 numbering jump.
Long-span-fatigue warnings (mood monotony, title clustering, pacing
repetition, opening/ending pattern similarity) are sequence-level
properties that cannot be fixed by revising the current chapter's text.
Previously these warnings inflated blockingCount in evaluateMergedAudit,
causing the revision gate to trigger or reject revisions for issues that
no single-chapter edit can resolve.
Now blockingCount only counts chapter-level issues (LLM audit, AI tells,
sensitive words). Sequence-level warnings still appear in the audit
report but no longer drive revision decisions.
Reverts 822708e, 4248e1d, eb288b3 which:
- Softened all directive language from "must/do not" to "try/prefer"
- Compressed writer context into compact Story Briefs
- Removed selectedEvidenceBlock from governed mode
- Extended compact briefs to auditor/reviser
Control experiment showed these 3 commits are the primary regression
suspects: iter-001 build + gpt-5.4 scored 75.5/66.5, while iter-002
(with these commits) scored 71.5/37.5 on the same model.
Restores imperative directive language and full context sections.
Some API providers (e.g. openclaudecode.cn) require a specific
User-Agent header for external clients. Without it requests get 403.
Adds INKOS_LLM_HEADERS (JSON object) which is injected as
defaultHeaders into the OpenAI SDK client. No effect when unset.
Also adds an optional `headers` field to LLMConfigSchema.
Adds StateManager.rollbackToChapter(bookId, targetChapter) which:
- Restores the snapshot at targetChapter
- Deletes chapter files, snapshots, and runtime artifacts beyond it
- Updates the chapter index to remove discarded entries
review reject now calls rollbackToChapter(chapterNum - 1) by default,
undoing the rejected chapter's state mutations and any subsequent chapters
that depended on them. --keep-subsequent preserves legacy behavior.
review approve now re-snapshots the approved chapter to ensure a clean
rollback target exists.
This prevents bad drafts from permanently polluting truth files — the
core "audit-then-commit" invariant that was missing.
Three changes:
1. FanficCanonImporter now extracts a writing_style section from source
material — narration voice, sentence rhythm, dialogue markers, imagery
preferences, emotional expression patterns, with source-text citations.
2. initFanficBook calls generateStyleGuide after canon import so fanfic
books start with both style_profile.json and style_guide.md.
3. importCanon reads up to 5 parent chapters and generates a style guide
for the target book. importChapters does the same on first run.
These ensure continuation and fanfic books have style reference data
available to the writer from the first chapter onward.
Implements buildMoodDirective — detects when 3+ recent chapters share
high-tension mood keywords (紧张/冷硬/压抑/tense/grim/etc.) and emits
a structured directive forcing the writer to downshift to a quieter scene.
Completes the moodDirective slot that was declared but left as undefined
in the previous structured-directives commit.