Эх сурвалжийг харах

chore: untrack docs/ and add to .gitignore

Ma 7 сар өмнө
parent
commit
44b5e52e50

+ 1 - 0
.gitignore

@@ -17,3 +17,4 @@ docs/
 novel-to-comic-research.docx
 .pnpm-store/
 tmp/
+docs/

+ 0 - 171
docs/plans/2026-03-28-v0.6.3-hardening-plan.md

@@ -1,171 +0,0 @@
-# v0.6.3 Hardening Implementation Plan
-
-> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
-
-**Goal:** Close the remaining 0.6.3 safety gaps around agent tool misuse, final-content paragraph checks, duplicate chapter titles, migration hints, and rewrite regression coverage.
-
-**Architecture:** Keep the current v2 pipeline, but tighten the remaining soft spots at the edges. Add deterministic guards in the agent dispatch layer, run final-content validation at the last safe point before persist, surface migration status in user-facing CLI flows, and add targeted regressions for the exact user-visible failures.
-
-**Tech Stack:** TypeScript, Vitest, Commander CLI
-
----
-
-### Task 1: Guard the remaining agent path
-
-**Files:**
-- Modify: `packages/core/src/__tests__/pipeline-agent.test.ts`
-- Modify: `packages/core/src/pipeline/agent.ts`
-
-**Step 1: Write the failing tests**
-
-Add tests that prove:
-- `write_full_pipeline` is rejected when the chapter sequence is inconsistent
-- `write_truth_file` cannot use `current_state.md` to mutate progress
-
-**Step 2: Run test to verify it fails**
-
-Run:
-
-```bash
-pnpm vitest run src/__tests__/pipeline-agent.test.ts
-```
-
-**Step 3: Write minimal implementation**
-
-Reuse the same guard logic currently applied to `write_draft` and block `write_full_pipeline` before it calls `writeNextChapter()`.
-
-**Step 4: Run test to verify it passes**
-
-Run:
-
-```bash
-pnpm vitest run src/__tests__/pipeline-agent.test.ts
-```
-
-**Step 5: Commit**
-
-```bash
-git add packages/core/src/pipeline/agent.ts packages/core/src/__tests__/pipeline-agent.test.ts
-git commit -m "fix: guard write_full_pipeline in agent dispatch"
-```
-
-### Task 2: Validate final persisted chapter shape
-
-**Files:**
-- Modify: `packages/core/src/__tests__/post-write-validator.test.ts`
-- Modify: `packages/core/src/__tests__/pipeline-runner.test.ts`
-- Modify: `packages/core/src/agents/post-write-validator.ts`
-- Modify: `packages/core/src/pipeline/runner.ts`
-
-**Step 1: Write the failing tests**
-
-Add tests that prove:
-- final persisted content can trigger `段落过碎` / `连续短段`
-- duplicate titles are handled as a real final-stage action, not a passive warning
-
-**Step 2: Run tests to verify they fail**
-
-Run:
-
-```bash
-pnpm vitest run src/__tests__/post-write-validator.test.ts src/__tests__/pipeline-runner.test.ts
-```
-
-**Step 3: Write minimal implementation**
-
-Export a reusable final paragraph-shape detector and run it on `finalContent` before persist. Upgrade duplicate-title handling from a passive warning to an explicit final-stage resolution path.
-
-**Step 4: Run tests to verify they pass**
-
-Run:
-
-```bash
-pnpm vitest run src/__tests__/post-write-validator.test.ts src/__tests__/pipeline-runner.test.ts
-```
-
-**Step 5: Commit**
-
-```bash
-git add packages/core/src/agents/post-write-validator.ts packages/core/src/pipeline/runner.ts packages/core/src/__tests__/post-write-validator.test.ts packages/core/src/__tests__/pipeline-runner.test.ts
-git commit -m "fix: harden final content validation and title handling"
-```
-
-### Task 3: Surface migration status in user-facing CLI flows
-
-**Files:**
-- Modify: `packages/cli/src/__tests__/cli-integration.test.ts`
-- Modify: `packages/cli/src/commands/status.ts`
-- Modify: `packages/cli/src/commands/write.ts`
-- Modify: `packages/cli/src/utils.ts`
-
-**Step 1: Write the failing tests**
-
-Add tests that prove:
-- `inkos status` shows a migration hint for legacy books
-- `inkos write next` warns before auto-migrating a legacy book
-
-**Step 2: Run tests to verify they fail**
-
-Run:
-
-```bash
-pnpm vitest run src/__tests__/cli-integration.test.ts
-```
-
-**Step 3: Write minimal implementation**
-
-Add a shared CLI helper that detects legacy pre-v0.6 books and emits a clear hint in `status` and `write next`.
-
-**Step 4: Run tests to verify they pass**
-
-Run:
-
-```bash
-pnpm vitest run src/__tests__/cli-integration.test.ts
-```
-
-**Step 5: Commit**
-
-```bash
-git add packages/cli/src/utils.ts packages/cli/src/commands/status.ts packages/cli/src/commands/write.ts packages/cli/src/__tests__/cli-integration.test.ts
-git commit -m "feat: show migration hints in status and write flows"
-```
-
-### Task 4: Verify rewrite from user path
-
-**Files:**
-- Modify: `packages/cli/src/__tests__/cli-integration.test.ts`
-
-**Step 1: Write the failing test**
-
-Add a CLI-level regression covering:
-- create 3 chapters
-- rewrite chapter 2
-- assert next chapter number is 2 again
-
-**Step 2: Run test to verify it fails**
-
-Run:
-
-```bash
-pnpm vitest run src/__tests__/cli-integration.test.ts
-```
-
-**Step 3: Write minimal implementation**
-
-Prefer no production change unless the new CLI regression exposes a real gap.
-
-**Step 4: Run tests to verify it passes**
-
-Run:
-
-```bash
-pnpm vitest run src/__tests__/cli-integration.test.ts
-```
-
-**Step 5: Commit**
-
-```bash
-git add packages/cli/src/__tests__/cli-integration.test.ts
-git commit -m "test: cover rewrite flow from CLI path"
-```

+ 0 - 76
docs/plans/2026-03-29-book-create-atomic-init-design.md

@@ -1,76 +0,0 @@
-# Book Create Atomic Init Design
-
-**Goal:** Eliminate half-initialized books by making `inkos book create` fail-closed: foundation generation must either produce a complete book or leave no book directory behind.
-
-## Problem
-
-Current `book create` is not atomic:
-
-- `PipelineRunner.initBook()` writes `book.json` before foundation generation.
-- `ArchitectAgent.parseSections()` silently substitutes placeholder text when a required section is missing.
-- CLI treats an existing but incomplete directory as resumable state.
-
-This creates dirty `books/<bookId>/` directories with partial files. Re-running create on the same title can then behave unpredictably.
-
-## Design
-
-### 1. Stage to a temporary book directory
-
-`initBook()` should build the full book in a temporary directory under `books/`:
-
-- write `book.json`
-- generate foundation
-- write foundation files
-- initialize control docs
-- create chapter index
-- snapshot chapter 0
-
-Only after all of that succeeds should the temp directory be renamed to the final `books/<bookId>/`.
-
-If any step fails, the temp directory is deleted.
-
-### 2. Treat missing Architect sections as hard failure
-
-`ArchitectAgent.parseSections()` should no longer emit placeholder text like:
-
-- `[book_rules 生成失败,需要重新生成]`
-
-Missing required sections should throw an error immediately. This prevents malformed foundations from being persisted as if they were valid content.
-
-### 3. Remove resumable incomplete-init semantics
-
-CLI should no longer “resume incomplete book creation”.
-
-If `books/<bookId>/` exists:
-
-- if it looks complete, `book create` should fail with “already exists”
-- if it looks incomplete, it should be treated as stale partial state and removed before a fresh atomic create starts
-
-This keeps the behavior simple:
-
-- success => complete book exists
-- failure => no book directory remains
-
-## Scope
-
-In scope:
-
-- `book create`
-- `PipelineRunner.initBook()`
-- Architect foundation parsing
-- stale incomplete directory cleanup
-- regression tests
-
-Out of scope:
-
-- `initFanficBook()` atomic staging
-- state-validator robustness
-- interactive-fiction work
-
-## Validation
-
-Add regressions for:
-
-1. `ArchitectAgent` throws when a required section is missing.
-2. `PipelineRunner.initBook()` leaves no final book directory when foundation generation fails.
-3. CLI `book create` removes stale incomplete directories and does not keep a dirty directory when create fails downstream.

+ 0 - 116
docs/plans/2026-03-29-book-create-atomic-init-implementation-plan.md

@@ -1,116 +0,0 @@
-# Book Create Atomic Init Implementation Plan
-
-> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
-
-**Goal:** Make `book create` atomic so malformed Architect output or failed initialization never leaves a half-built book directory behind.
-
-**Architecture:** Stage new books in a temporary directory, require Architect to return all mandatory sections, and delete stale incomplete directories instead of resuming them. Promote the staged directory into place only after all initialization steps succeed.
-
-**Tech Stack:** TypeScript, Vitest, Commander CLI, Node `fs/promises`
-
----
-
-### Task 1: Lock down Architect missing-section failure
-
-**Files:**
-- Modify: `packages/core/src/__tests__/architect.test.ts`
-- Modify: `packages/core/src/agents/architect.ts`
-
-**Step 1: Write the failing test**
-
-Add a test showing `generateFoundation()` rejects when `book_rules` is missing from the LLM response.
-
-**Step 2: Run test to verify it fails**
-
-Run: `pnpm vitest run src/__tests__/architect.test.ts -t "throws when a required foundation section is missing"`
-
-**Step 3: Write minimal implementation**
-
-Change `parseSections()` to throw on missing required sections instead of returning placeholder content.
-
-**Step 4: Run test to verify it passes**
-
-Run the same Vitest command and confirm it passes.
-
-### Task 2: Lock down atomic init rollback
-
-**Files:**
-- Modify: `packages/core/src/__tests__/pipeline-runner.test.ts`
-- Modify: `packages/core/src/state/manager.ts`
-- Modify: `packages/core/src/pipeline/runner.ts`
-
-**Step 1: Write the failing test**
-
-Add a regression showing `initBook()` leaves no final `books/<bookId>/` when foundation generation fails.
-
-**Step 2: Run test to verify it fails**
-
-Run: `pnpm vitest run src/__tests__/pipeline-runner.test.ts -t "cleans staged files when initBook fails before foundation is complete"`
-
-**Step 3: Write minimal implementation**
-
-Implement staged initialization in a temporary directory, then rename into place only after success. Add helper methods in `StateManager` as needed for path-based control-doc/index/snapshot writes.
-
-**Step 4: Run test to verify it passes**
-
-Run the same Vitest command and confirm it passes.
-
-### Task 3: Lock down stale incomplete-directory cleanup at CLI level
-
-**Files:**
-- Modify: `packages/cli/src/__tests__/cli-integration.test.ts`
-- Modify: `packages/cli/src/commands/book.ts`
-
-**Step 1: Write the failing test**
-
-Add a CLI regression where a stale incomplete `books/<bookId>/` exists before `book create`, and verify the command does not preserve that stale directory when create later fails.
-
-**Step 2: Run test to verify it fails**
-
-Run: `pnpm vitest run src/__tests__/cli-integration.test.ts -t "removes stale incomplete book directories before retrying create"`
-
-**Step 3: Write minimal implementation**
-
-Replace “resume incomplete book creation” behavior with stale-directory cleanup plus fresh atomic create.
-
-**Step 4: Run test to verify it passes**
-
-Run the same Vitest command and confirm it passes.
-
-### Task 4: Run focused verification
-
-**Files:**
-- No production changes expected
-
-**Step 1: Run targeted suite**
-
-Run:
-
-```bash
-pnpm vitest run src/__tests__/architect.test.ts src/__tests__/pipeline-runner.test.ts
-```
-
-in `packages/core`, and:
-
-```bash
-pnpm vitest run src/__tests__/cli-integration.test.ts
-```
-
-in `packages/cli`.
-
-**Step 2: Run typecheck**
-
-Run:
-
-```bash
-pnpm typecheck
-```
-
-in `packages/core` and `packages/cli`.
-
-**Step 3: Commit**
-
-```bash
-git add docs/plans/2026-03-29-book-create-atomic-init-design.md docs/plans/2026-03-29-book-create-atomic-init-implementation-plan.md packages/core/src/agents/architect.ts packages/core/src/pipeline/runner.ts packages/core/src/state/manager.ts packages/core/src/__tests__/architect.test.ts packages/core/src/__tests__/pipeline-runner.test.ts packages/cli/src/commands/book.ts packages/cli/src/__tests__/cli-integration.test.ts
-git commit -m "fix: make book creation fail closed"
-```

+ 0 - 356
docs/plans/2026-03-30-interactive-fiction-v1-design.md

@@ -1,356 +0,0 @@
-# Interactive Fiction V1 Design
-
-**Goal:** Add a first-class interactive-fiction mode to InkOS by introducing chapter-end branching while preserving the existing chapter-based writing, audit, revise, truth-file, and runtime-state pipeline.
-
-## Summary
-
-Interactive fiction v1 should not replace InkOS's chapter-writing core. It should add a branch system around that core.
-
-The recommended v1 shape is:
-
-- chapters remain the unit of generation
-- each completed chapter can produce 2-4 grounded reader choices
-- each choice creates a persistent branch node
-- only the selected branch continues generating new chapters
-- unselected branches remain dormant but recoverable later
-
-This gives InkOS real branching narrative structure without forcing a rewrite into a node-by-node text-adventure engine.
-
-## Why This Shape
-
-### Do not rewrite the chapter engine first
-
-InkOS already has valuable infrastructure:
-
-- chapter writing
-- revise / audit
-- truth-file rebuild
-- runtime state
-- snapshots / rewrite / rollback
-- export / review / eval
-
-If v1 changes the smallest unit from "chapter" to "scene node", all of those systems become unstable at once.
-
-So the right heavy refactor is:
-
-- rebuild branching
-- rebuild branch state management
-- keep the chapter-writing engine intact
-
-### Why not free-form player input first
-
-Free-form actions look attractive, but they explode ambiguity:
-
-- action parsing
-- branch normalization
-- invalid-action handling
-- state mutation safety
-- prompt drift
-
-Reader-choice branching gives InkOS a constrained interaction surface first. Later, free-form player input can be added as a higher-risk edge type on top of the same branch tree.
-
-## Narrative Mode
-
-Add a new book-level mode in `book.json`:
-
-- `narrativeMode: "linear" | "interactive-tree"`
-
-Default remains `linear`.
-
-Interactive branching behavior only activates when `narrativeMode === "interactive-tree"`.
-
-## Core Model
-
-### 1. Branch Tree
-
-Create a new persistent artifact:
-
-- `story/interactive/branch-tree.json`
-
-This is the source of truth for interactive structure.
-
-It contains:
-
-- book-level metadata
-- active branch pointer
-- branch nodes
-- branch edges / choices
-
-### 2. Branch Nodes
-
-A branch node represents a recoverable narrative state, not necessarily a fully written branch.
-
-Recommended fields:
-
-- `nodeId`
-- `parentNodeId`
-- `sourceChapterId`
-- `sourceChapterNumber`
-- `branchDepth`
-- `branchLabel`
-- `status: active | awaiting-choice | dormant | completed`
-- `snapshotRef`
-- `selectedChoiceId`
-- `chapterIds: string[]`
-- `displayPath`
-
-Important meaning:
-
-- a node is the point from which writing can continue
-- multiple child nodes may initially share the same chapter-end snapshot
-- only the active node is projected into live truth files
-
-### 3. Branch Choices
-
-Choices are explicit edges between nodes.
-
-Recommended fields:
-
-- `choiceId`
-- `fromNodeId`
-- `toNodeId`
-- `label`
-- `intent`
-- `immediateGoal`
-- `expectedCost`
-- `expectedRisk`
-- `hookPressure`
-- `characterPressure`
-- `tone`
-- `selected: boolean`
-
-Choices are not cosmetic strings. They are structured next-chapter directions.
-
-## Chapter Identity
-
-### Internal IDs
-
-Use globally unique internal chapter IDs for storage.
-
-Do not try to make each branch own an independent global chapter-number namespace.
-
-Recommended split:
-
-- internal: globally unique chapter id / monotonic storage number
-- display: branch-local sequence index for UX
-
-Why:
-
-- preserves existing storage, export, review, and audit assumptions
-- avoids collisions across branches
-- lets linear tools keep working with minimal change
-
-## Snapshot Strategy
-
-Reuse the existing snapshot system.
-
-After chapter `N` finishes:
-
-- current state is snapshotted exactly once
-- all generated child branch nodes reference that same snapshot
-- no child branch pre-generates chapter `N+1`
-
-So for a chapter with choices A/B/C:
-
-- chapter 12 ends
-- snapshot 12 exists
-- child nodes A/B/C all point to snapshot 12
-- user selects B
-- only then does branch B generate its next chapter
-
-This keeps branching persistent without duplicating a full book state tree at choice generation time.
-
-## Choice Generation
-
-Choice generation should be its own step, not something the writer casually appends.
-
-### ChoiceGenerator
-
-Inputs:
-
-- current chapter content
-- active branch runtime state
-- current focus
-- planner/composer intent
-- active hooks / dormant pressure
-- character pressure
-
-Outputs:
-
-- 2-4 structured choices
-
-### ChoiceAuditor
-
-Audits choice quality:
-
-- choices must be meaningfully different
-- no obviously fake branch set
-- no nonsense or "bad joke" option
-- choices must be grounded in chapter-end state
-
-### Recommended choice policy
-
-Prefer:
-
-- 1 lower-risk / stabilizing option
-- 1 higher-risk / high-payoff option
-- 1 relationship / emotional option
-- optional 4th only if naturally justified
-
-This avoids both "three paraphrases of the same branch" and gimmicky fake interactivity.
-
-## Truth Files And Runtime State
-
-The live truth files for an interactive book represent the active branch only.
-
-That means files like:
-
-- `current_state.md`
-- `pending_hooks.md`
-- `chapter_summaries.md`
-
-are branch-local projections, not universal whole-book truth.
-
-Persistent cross-branch truth is stored in:
-
-- `branch-tree.json`
-- snapshots
-- chapter lineage attached to branch nodes
-
-### Branch switch behavior
-
-Switching branch should perform:
-
-1. restore the referenced snapshot
-2. restore branch-local projected state
-3. update active branch pointer
-4. continue writing from that branch
-
-The branch tree is canonical. The live markdown truth files are the active projection.
-
-## CLI Flow
-
-Keep `write next`, but add branch control commands.
-
-Recommended commands:
-
-- `inkos branch choices`
-- `inkos branch choose <choice-id>`
-- `inkos branch tree`
-- `inkos branch switch <node-id>`
-
-### Main loop
-
-1. `write next`
-2. chapter completes
-3. choice generation runs
-4. current node becomes `awaiting-choice`
-5. user inspects choices
-6. user chooses one
-7. selected child node becomes active
-8. next `write next` continues that branch
-
-### Important gating rule
-
-If the active node is `awaiting-choice`, `write next` must refuse to continue until a branch is selected.
-
-This prevents accidental silent continuation down an undefined path.
-
-## Compatibility Rules
-
-### Linear books
-
-Linear books should behave exactly as today.
-
-### Interactive books
-
-Interactive books reuse:
-
-- writer
-- reviser
-- continuity auditor
-- state validator
-- snapshots
-- rewrite
-
-But commands operate on the active branch by default.
-
-Later versions can add `--branch`, but v1 should keep default behavior simple.
-
-## Export And Review
-
-Do not solve full branch-aware export in v1.
-
-V1 export and review policy should be:
-
-- default export = active branch only
-- default review = active branch only
-- tree visualization = separate command / future enhancement
-
-This keeps v1 bounded.
-
-## Error Handling
-
-### Branch tree missing or corrupt
-
-- interactive commands fail closed
-- linear commands remain unaffected
-
-### Snapshot missing for target node
-
-- branch switch fails
-- active branch remains unchanged
-
-### Choice generation fails
-
-Recommended v1 behavior:
-
-- chapter is still saved
-- node is marked `awaiting-choice-generation`
-- user can retry choice generation explicitly
-
-Do not lose the chapter because choice generation failed.
-
-### Invalid choose
-
-- reject with a clear error
-- do not mutate branch state
-
-## Non-Goals For V1
-
-Out of scope:
-
-- free-form player action parsing
-- scene/node-level engine
-- branch-aware EPUB for all paths
-- auto-generating all child branches in parallel
-- full interactive UI
-- branch-local manga export
-
-These belong to v2+.
-
-## Testing Strategy
-
-Minimum required regressions:
-
-1. interactive book writes one chapter and persists choice nodes
-2. unselected choices persist as dormant branch nodes with shared snapshot refs
-3. `write next` refuses when active node awaits choice
-4. `branch choose` activates the selected child branch
-5. `branch switch` restores the correct snapshot
-6. linear books remain unaffected
-
-## Recommendation
-
-Build interactive fiction v1 as a chapter-tree system:
-
-- branch-heavy
-- stateful
-- recoverable
-- chapter-based
-
-Do not build a free-form adventure engine first.
-
-Do not rebuild InkOS around scene nodes in v1.
-
-The right first step is a formal branch tree wrapped around the existing chapter pipeline.

+ 0 - 505
docs/plans/2026-03-30-interactive-fiction-v1-implementation-plan.md

@@ -1,505 +0,0 @@
-# Interactive Fiction V1 Implementation Plan
-
-> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
-
-**Goal:** Add an `interactive-tree` narrative mode where chapter-end reader choices create persistent branch nodes, while keeping InkOS's chapter-writing pipeline intact.
-
-**Architecture:** Reuse the existing chapter generation pipeline and snapshots. Add a branch-tree persistence layer, branch-aware state activation, chapter-end choice generation, and CLI branch commands. Keep live truth files as the active-branch projection only.
-
-**Tech Stack:** TypeScript, Commander CLI, Vitest, existing InkOS pipeline/state/snapshot system
-
----
-
-### Task 1: Add the narrative mode model
-
-**Files:**
-- Modify: `packages/core/src/models/book.ts`
-- Test: `packages/core/src/__tests__/fanfic-models.test.ts` or a new book-model test
-
-**Step 1: Write the failing test**
-
-Add a test that parses:
-
-- `narrativeMode: "linear"`
-- `narrativeMode: "interactive-tree"`
-
-and rejects unknown values.
-
-**Step 2: Run test to verify it fails**
-
-Run: `pnpm vitest run src/__tests__/...`
-
-Expected: FAIL because `interactive-tree` is not yet allowed.
-
-**Step 3: Write minimal implementation**
-
-Add:
-
-- `NarrativeModeSchema`
-- `narrativeMode` on `BookConfigSchema`
-- default to `linear`
-
-**Step 4: Run test to verify it passes**
-
-Run the targeted Vitest file again.
-
-**Step 5: Commit**
-
-```bash
-git add packages/core/src/models/book.ts packages/core/src/__tests__/...
-git commit -m "feat: add interactive narrative mode"
-```
-
-### Task 2: Define branch-tree persistence schema
-
-**Files:**
-- Create: `packages/core/src/models/interactive-fiction.ts`
-- Test: `packages/core/src/__tests__/interactive-fiction-models.test.ts`
-
-**Step 1: Write the failing test**
-
-Add schema tests for:
-
-- branch tree metadata
-- branch nodes
-- branch choices
-- `activeNodeId`
-- shared `snapshotRef`
-
-**Step 2: Run test to verify it fails**
-
-Run the new test file.
-
-Expected: FAIL because schema file does not exist.
-
-**Step 3: Write minimal implementation**
-
-Create schema/types for:
-
-- tree metadata
-- node status
-- choice record
-- branch node
-- branch tree
-
-**Step 4: Run test to verify it passes**
-
-Run the targeted schema test.
-
-**Step 5: Commit**
-
-```bash
-git add packages/core/src/models/interactive-fiction.ts packages/core/src/__tests__/interactive-fiction-models.test.ts
-git commit -m "feat: define branch tree schemas"
-```
-
-### Task 3: Add state-manager helpers for interactive storage
-
-**Files:**
-- Modify: `packages/core/src/state/manager.ts`
-- Test: `packages/core/src/__tests__/state-manager.test.ts`
-
-**Step 1: Write the failing test**
-
-Add tests for helpers that:
-
-- load/save `story/interactive/branch-tree.json`
-- initialize an empty root branch
-- return the active node
-
-**Step 2: Run test to verify it fails**
-
-Run the targeted tests.
-
-Expected: FAIL because helper methods do not exist.
-
-**Step 3: Write minimal implementation**
-
-Add helpers such as:
-
-- `interactiveDir(bookId)`
-- `loadBranchTree(bookId)`
-- `saveBranchTree(bookId, tree)`
-- `ensureInteractiveTree(bookId)`
-
-**Step 4: Run test to verify it passes**
-
-Run the targeted state-manager tests.
-
-**Step 5: Commit**
-
-```bash
-git add packages/core/src/state/manager.ts packages/core/src/__tests__/state-manager.test.ts
-git commit -m "feat: add interactive branch tree persistence helpers"
-```
-
-### Task 4: Initialize interactive books correctly at create time
-
-**Files:**
-- Modify: `packages/core/src/pipeline/runner.ts`
-- Modify: `packages/cli/src/commands/book.ts`
-- Test: `packages/core/src/__tests__/pipeline-runner.test.ts`
-- Test: `packages/cli/src/__tests__/cli-integration.test.ts`
-
-**Step 1: Write the failing test**
-
-Add tests that:
-
-- create an interactive book
-- verify `branch-tree.json` exists
-- verify the tree contains a root node and active pointer
-
-**Step 2: Run test to verify it fails**
-
-Run the targeted test files.
-
-Expected: FAIL because create flow does not initialize interactive metadata.
-
-**Step 3: Write minimal implementation**
-
-When `narrativeMode === "interactive-tree"`:
-
-- create interactive storage during book initialization
-- seed a root branch node
-
-**Step 4: Run test to verify it passes**
-
-Run the targeted tests again.
-
-**Step 5: Commit**
-
-```bash
-git add packages/core/src/pipeline/runner.ts packages/cli/src/commands/book.ts packages/core/src/__tests__/pipeline-runner.test.ts packages/cli/src/__tests__/cli-integration.test.ts
-git commit -m "feat: initialize interactive books with root branch tree"
-```
-
-### Task 5: Add chapter-end choice generation models and parser
-
-**Files:**
-- Create: `packages/core/src/agents/choice-generator.ts`
-- Create: `packages/core/src/agents/choice-auditor.ts`
-- Test: `packages/core/src/__tests__/choice-generator.test.ts`
-- Test: `packages/core/src/__tests__/choice-auditor.test.ts`
-
-**Step 1: Write the failing test**
-
-Add tests that require generated choices to include:
-
-- `label`
-- `intent`
-- `immediateGoal`
-- `expectedCost`
-- `expectedRisk`
-- `hookPressure`
-- `characterPressure`
-- `tone`
-
-Also add a failure case for near-duplicate choices.
-
-**Step 2: Run test to verify it fails**
-
-Run both targeted test files.
-
-Expected: FAIL because these agents do not exist.
-
-**Step 3: Write minimal implementation**
-
-Implement:
-
-- choice generation prompt/output parsing
-- choice auditing for duplicate/fake branches
-
-**Step 4: Run test to verify it passes**
-
-Run targeted tests again.
-
-**Step 5: Commit**
-
-```bash
-git add packages/core/src/agents/choice-generator.ts packages/core/src/agents/choice-auditor.ts packages/core/src/__tests__/choice-generator.test.ts packages/core/src/__tests__/choice-auditor.test.ts
-git commit -m "feat: add interactive choice generation agents"
-```
-
-### Task 6: Persist branch children after chapter completion
-
-**Files:**
-- Modify: `packages/core/src/pipeline/runner.ts`
-- Modify: `packages/core/src/state/manager.ts`
-- Test: `packages/core/src/__tests__/pipeline-runner.test.ts`
-
-**Step 1: Write the failing test**
-
-Add a test for interactive mode where:
-
-- `writeNextChapter()` saves chapter 1
-- generates 2-4 choices
-- creates child nodes
-- all child nodes reference the same `snapshotRef`
-- active node becomes `awaiting-choice`
-
-**Step 2: Run test to verify it fails**
-
-Run the targeted runner test.
-
-Expected: FAIL because chapters do not yet emit branch nodes.
-
-**Step 3: Write minimal implementation**
-
-In interactive mode, after successful chapter persistence:
-
-- run choice generation
-- run choice audit
-- create child nodes and choices
-- store them in the branch tree
-- leave only one active pointer
-
-**Step 4: Run test to verify it passes**
-
-Run the targeted runner test.
-
-**Step 5: Commit**
-
-```bash
-git add packages/core/src/pipeline/runner.ts packages/core/src/state/manager.ts packages/core/src/__tests__/pipeline-runner.test.ts
-git commit -m "feat: persist branch choices after interactive chapters"
-```
-
-### Task 7: Block write-next when a choice is pending
-
-**Files:**
-- Modify: `packages/core/src/pipeline/runner.ts`
-- Modify: `packages/core/src/pipeline/agent.ts`
-- Test: `packages/core/src/__tests__/pipeline-runner.test.ts`
-- Test: `packages/core/src/__tests__/pipeline-agent.test.ts`
-
-**Step 1: Write the failing test**
-
-Add tests that:
-
-- refuse `writeNextChapter()` on interactive books when active node is `awaiting-choice`
-- refuse agent `write_draft` / `write_full_pipeline` in the same state
-
-**Step 2: Run test to verify it fails**
-
-Run the targeted tests.
-
-Expected: FAIL because write flow still continues linearly.
-
-**Step 3: Write minimal implementation**
-
-Add fail-closed guards before chapter generation starts.
-
-**Step 4: Run test to verify it passes**
-
-Run targeted tests again.
-
-**Step 5: Commit**
-
-```bash
-git add packages/core/src/pipeline/runner.ts packages/core/src/pipeline/agent.ts packages/core/src/__tests__/pipeline-runner.test.ts packages/core/src/__tests__/pipeline-agent.test.ts
-git commit -m "fix: require branch choice before continuing interactive writing"
-```
-
-### Task 8: Add CLI branch commands
-
-**Files:**
-- Create: `packages/cli/src/commands/branch.ts`
-- Modify: `packages/cli/src/index.ts`
-- Test: `packages/cli/src/__tests__/cli-integration.test.ts`
-
-**Step 1: Write the failing test**
-
-Add CLI integration tests for:
-
-- `inkos branch tree`
-- `inkos branch choices`
-- `inkos branch choose <choice-id>`
-- `inkos branch switch <node-id>`
-
-**Step 2: Run test to verify it fails**
-
-Run the targeted CLI test(s).
-
-Expected: FAIL because `branch` command does not exist.
-
-**Step 3: Write minimal implementation**
-
-Add a new CLI command group that:
-
-- lists current branch tree
-- shows pending choices
-- selects a choice
-- switches active node
-
-**Step 4: Run test to verify it passes**
-
-Run targeted CLI tests again.
-
-**Step 5: Commit**
-
-```bash
-git add packages/cli/src/commands/branch.ts packages/cli/src/index.ts packages/cli/src/__tests__/cli-integration.test.ts
-git commit -m "feat: add interactive branch CLI commands"
-```
-
-### Task 9: Restore the correct snapshot on branch switch
-
-**Files:**
-- Modify: `packages/core/src/state/manager.ts`
-- Modify: `packages/core/src/pipeline/runner.ts`
-- Test: `packages/core/src/__tests__/state-manager.test.ts`
-- Test: `packages/core/src/__tests__/pipeline-runner.test.ts`
-
-**Step 1: Write the failing test**
-
-Add tests that switching to another branch:
-
-- restores the referenced snapshot
-- reprojects active branch truth files
-- leaves other branch nodes unchanged
-
-**Step 2: Run test to verify it fails**
-
-Run the targeted tests.
-
-Expected: FAIL because switch only updates metadata or is not implemented.
-
-**Step 3: Write minimal implementation**
-
-Implement branch activation as:
-
-- restore snapshot
-- mark branch active
-- persist active branch pointer
-
-**Step 4: Run test to verify it passes**
-
-Run targeted tests again.
-
-**Step 5: Commit**
-
-```bash
-git add packages/core/src/state/manager.ts packages/core/src/pipeline/runner.ts packages/core/src/__tests__/state-manager.test.ts packages/core/src/__tests__/pipeline-runner.test.ts
-git commit -m "feat: restore snapshots when switching interactive branches"
-```
-
-### Task 10: Keep linear-mode behavior unchanged
-
-**Files:**
-- Modify: `packages/core/src/__tests__/pipeline-runner.test.ts`
-- Modify: `packages/cli/src/__tests__/cli-integration.test.ts`
-
-**Step 1: Write the failing test**
-
-Add regressions proving:
-
-- linear books still write chapters exactly as before
-- no branch metadata is required for linear books
-- branch commands reject linear books cleanly
-
-**Step 2: Run test to verify it fails**
-
-Run the targeted tests.
-
-Expected: FAIL because interactive checks leak into linear mode or commands are too permissive.
-
-**Step 3: Write minimal implementation**
-
-Tighten mode checks so interactive behavior is gated strictly by `narrativeMode`.
-
-**Step 4: Run test to verify it passes**
-
-Run targeted tests again.
-
-**Step 5: Commit**
-
-```bash
-git add packages/core/src/__tests__/pipeline-runner.test.ts packages/cli/src/__tests__/cli-integration.test.ts
-git commit -m "test: lock linear compatibility for interactive mode"
-```
-
-### Task 11: Add minimal docs for user flow
-
-**Files:**
-- Modify: `README.md`
-- Modify: `README.en.md`
-- Modify: `skills/SKILL.md`
-
-**Step 1: Write the failing test**
-
-No automated doc test required. Instead, write a short checklist of required user-facing docs:
-
-- create interactive book
-- write chapter
-- inspect choices
-- choose branch
-- switch branch
-
-**Step 2: Run manual verification**
-
-Check README/skill docs are missing or outdated.
-
-Expected: missing interactive instructions.
-
-**Step 3: Write minimal implementation**
-
-Document:
-
-- what interactive-tree mode is
-- the branch CLI flow
-- what remains out of scope in v1
-
-**Step 4: Run manual verification**
-
-Read both READMEs and `skills/SKILL.md` to verify the flow is discoverable.
-
-**Step 5: Commit**
-
-```bash
-git add README.md README.en.md skills/SKILL.md
-git commit -m "docs: add interactive fiction branch workflow"
-```
-
-### Task 12: End-to-end acceptance and release note prep
-
-**Files:**
-- Modify: `packages/core/src/__tests__/pipeline-runner.test.ts`
-- Modify: `packages/cli/src/__tests__/cli-integration.test.ts`
-- Optional: `docs/plans/...` if acceptance notes are appended
-
-**Step 1: Write the failing test**
-
-Add one narrow end-to-end acceptance test that:
-
-- creates an interactive book
-- writes chapter 1
-- persists branch choices
-- chooses a branch
-- writes chapter 2 on that branch
-
-**Step 2: Run test to verify it fails**
-
-Run the targeted acceptance tests.
-
-Expected: FAIL until all pieces are wired together.
-
-**Step 3: Write minimal implementation**
-
-Fill any missing wiring only if acceptance still fails.
-
-**Step 4: Run test to verify it passes**
-
-Run:
-
-- targeted acceptance tests
-- focused branch CLI tests
-- focused runner tests
-- `pnpm typecheck` in `packages/core`
-- `pnpm typecheck` in `packages/cli`
-
-**Step 5: Commit**
-
-```bash
-git add packages/core/src/__tests__/pipeline-runner.test.ts packages/cli/src/__tests__/cli-integration.test.ts
-git commit -m "test: cover interactive fiction v1 end-to-end flow"
-```