2026-04-06-interaction-control-layer-design.md 14 KB

Interaction Control Layer Design

Goal

Build a shared interaction control layer for InkOS so that TUI and Studio stop acting like separate products and instead become two shells over the same writing control brain.

This layer must let users:

  • create a book through natural conversation
  • continue an active book inside a project workspace
  • see exactly what the system is doing right now
  • intervene safely on chapters, truth files, and direction
  • choose how much autonomy the system has

Why This Exists

Current InkOS has strong execution primitives but weak control ergonomics.

Today the user experience is split across:

  • CLI commands
  • Studio buttons and pages
  • a shallow /api/agent chat box
  • daemon logs
  • direct truth-file editing

That produces the exact failures users complain about:

  • the system keeps writing when the user expected it to stop
  • the user cannot tell what stage the system is in
  • edits to truth files do not feel authoritative
  • rejecting or revising a chapter does not feel like part of one coherent flow
  • Studio chat does not hold enough session context to feel like a real assistant

The solution is not “more buttons” and not “just add a TUI”. The solution is a single interaction control layer that owns:

  • session context
  • book binding
  • autonomy policy
  • natural-language intent routing
  • execution status
  • human edit transactions

Product Principles

1. Project-first

InkOS should behave like a writing version of Coding CLI.

The user opens a project directory and runs:

inkos

The current working directory is the project context. The control layer restores:

  • project config
  • books in the project
  • active book, if one exists
  • current running task, if one exists

The user should not be thrown into a global dashboard first.

2. Conversation-first, not form-first

When there is no active task, the interface should be quiet.

It should not dump a questionnaire. It should wait for the user to speak first. The system then gradually narrows the task by asking only the most important next question.

Bad:

  • “Choose language / genre / length / mode / trend scanning / source mode”

Good:

  • user: “I want to write a cold urban mystery”
  • system: “I’ll hold it as a cold urban mystery. Do you want something long-running, or something that can close within about 10-20 chapters?”

3. Status must stay visible at all times

The user must always be able to answer:

  • which book is active?
  • what chapter is being worked on?
  • which stage is running right now?
  • why is the system waiting or blocked?

4. Human edits are transactions, not raw file writes

Users must be able to change:

  • a person name
  • a chapter
  • a paragraph
  • current_focus
  • author_intent
  • truth files

But these changes cannot be “write to one file and hope the rest follows”. The control layer must route human edits through a consistency-preserving edit controller.

5. TUI and Studio share the same brain

TUI and Studio may have different layouts, but they must share:

  • session model
  • intent routing
  • autonomy policy
  • control actions
  • execution status
  • pending decisions

No duplicate business logic in both shells.

User Journeys

Journey A: New book from a vague idea

  1. User runs inkos inside a project.
  2. No active book exists.
  3. User types: “I want to write a quiet harbor mystery.”
  4. The control layer opens a book-creation conversation.
  5. Through a few turns, the system gathers enough intent to draft:
    • title direction
    • genre
    • target scale
    • language
    • source mode: original / continuation / fanfic
    • autonomy preference
  6. System proposes a structured book draft.
  7. User confirms or adjusts.
  8. System runs foundation generation.
  9. If the autonomy policy allows, it proceeds into writing; otherwise it waits for outline review.

Journey B: Continue an active book

  1. User runs inkos in a project that already has books.
  2. The control layer restores the active book.
  3. The interface opens on that book’s current session.
  4. User types “continue”.
  5. Control layer maps that to write_next.
  6. Status stream shows:
    • planning
    • composing
    • writing
    • assessing
    • repairing
    • persisting
  7. If a stop condition is met, the task switches to waiting_human.

Journey C: Intervene on a chapter

  1. User types: “Rewrite chapter 3, but keep the ending reveal.”
  2. Control layer identifies:
    • action: rewrite_chapter
    • chapter: 3
    • constraint: keep ending reveal
  3. It builds an edit transaction.
  4. Runtime executes rewrite + reanalysis + truth/state rebuild for affected scope.
  5. User sees diff, updated status, and any downstream invalidations.

Journey D: Fix authority confusion

  1. User types: “Why is the protagonist still called Lu Chen?”
  2. Control layer resolves authoritative sources:
    • story bible
    • current state
    • book rules
    • recent chapters
    • active entity state
  3. It explains which source currently wins.
  4. User can then say:
    • “Rename the protagonist to Lin Yan everywhere”
  5. Control layer opens an entity-level rename transaction instead of editing random files manually.

Architecture

There should be one new subsystem spanning core, cli, and studio.

Layer 1: Interaction Core

New core module family that owns conversation state and intent routing.

Responsibilities:

  • maintain InteractionSession
  • bind current project and active book
  • classify user messages into intent types
  • ask follow-up questions when required
  • emit structured requests for execution

This layer does not directly run writing logic.

Layer 2: Control Runtime

Execution orchestrator for interaction requests.

Responsibilities:

  • turn a request into an executable action plan
  • call existing pipeline capabilities
  • track stage transitions
  • publish execution events
  • manage waiting-human transitions

This layer is the bridge between conversation and pipeline.

Layer 3: Execution Substrate

Existing InkOS capabilities remain underneath:

  • PipelineRunner
  • writer
  • review
  • repair-state
  • truth file read/write
  • scheduler

This design avoids rewriting the execution engine from scratch.

Layer 4: Shells

Two shells sit above the same control layer:

  • TUI
  • Studio

Both subscribe to the same session and status model.

Core Objects

InteractionSession

Represents one project-scoped working conversation.

Fields:

  • sessionId
  • projectRoot
  • activeBookId?
  • activeChapterNumber?
  • messages
  • automationMode
  • pendingDecision?
  • currentExecution?
  • lastResolvedIntent?

AutomationMode

Three explicit modes:

  • auto
  • semi
  • manual

Meaning:

  • auto: continue chapters automatically unless a true hard stop occurs
  • semi: user starts each chapter; chapter-internal loop stays automatic
  • manual: no autonomous progression; only explicit user commands run

InteractionIntent

Normalized intent categories:

  • create_book
  • select_book
  • continue_book
  • write_next
  • pause_book
  • resume_book
  • revise_chapter
  • rewrite_chapter
  • edit_truth
  • update_focus
  • update_author_intent
  • explain_status
  • explain_failure
  • export_book
  • switch_mode

InterventionRequest

The structured handoff from interaction core to runtime.

Fields:

  • intent
  • bookId
  • chapterNumber?
  • instruction?
  • truthFile?
  • modeOverride?
  • constraints

ExecutionStatus

Normalized, shell-friendly runtime state:

  • idle
  • planning
  • composing
  • writing
  • assessing
  • repairing
  • persisting
  • waiting_human
  • blocked
  • completed
  • failed

PendingDecision

Represents a human decision that must be surfaced clearly.

Examples:

  • approve current chapter before continuing
  • choose whether to rewrite or keep a chapter
  • resolve a truth authority conflict
  • confirm a project-level change

Edit Controller

This is required. Without it, human intervention will keep poisoning consistency.

Why It Exists

Users need to change:

  • names
  • chapters
  • paragraphs
  • direction
  • truth files

Those changes can affect:

  • chapter text
  • current state
  • hook state
  • chapter summaries
  • future chapter assumptions

So edits must be transactional.

Edit Types

1. Entity edits

Examples:

  • rename protagonist
  • change a character attribute

These are not text replacements. They must update the authoritative entity definition and then determine which downstream material must be rebuilt or flagged.

2. Chapter edits

Examples:

  • rewrite chapter 3
  • revise chapter 5

These rebuild chapter-derived truth outputs.

3. Local text edits

Examples:

  • rewrite one paragraph
  • change the ending sentence

These still require reanalysis of the affected chapter.

4. Direction/rule edits

Examples:

  • update current_focus
  • update author_intent
  • edit book_rules
  • edit volume_outline

These do not always require rewriting old chapters, but they must affect future planning deterministically.

Consistency Rules

The edit controller should enforce:

  • chapter body is authoritative for “what happened in this chapter”
  • explicit user override is authoritative for user-owned fields
  • truth projections must be regenerated from edited content where applicable
  • downstream chapters may be marked stale if an upstream edit invalidates assumptions

Status, Events, and Interaction Feedback

This system needs explicit event flow, not ad-hoc log strings.

Event Stream

New shared execution events should include:

  • session.bound
  • book.selected
  • task.started
  • task.progress
  • task.waiting_human
  • task.completed
  • task.failed
  • edit.applied
  • truth.updated
  • mode.changed

Stage Visibility

The user should always see:

  • active book
  • active chapter
  • stage
  • last successful action
  • current warning/block reason

Interaction Animation

Animations should communicate process, not decoration.

Required feedback:

  • active stage indicator
  • progress/event stream
  • visible waiting_human state
  • clear acceptance / rollback / rewrite transitions

No decorative motion that does not improve process readability.

TUI Shape

The TUI is the first shell, but it must be designed as a reusable client for the shared control layer.

Main layout

  • Top status bar
    • project
    • active book
    • automation mode
    • current stage
  • Center conversation pane
    • user messages
    • assistant responses
    • system event summaries
  • Right or bottom process pane
    • current task
    • last 10 events
    • pending decisions
    • current warnings
  • Input row
    • natural-language input
    • optional slash commands

Slash commands

Support a small, stable command layer:

  • /books
  • /open <book>
  • /new
  • /write
  • /pause
  • /resume
  • /mode
  • /revise
  • /rewrite
  • /focus
  • /intent
  • /truth
  • /export
  • /status

Natural language remains primary.

Studio Shape

Studio should stop treating chat as a side widget over a page collection.

Instead:

  • chat becomes a first-class surface over the same interaction core
  • book pages become supporting views, not the only control mechanism
  • daemon/log/truth views subscribe to the same execution event model

Studio should preserve its richer visual editing affordances, but it should not own separate orchestration logic.

File and Module Boundaries

This task is large, so file size control must be a design constraint from day one.

New core modules

Create a focused module family, for example:

  • packages/core/src/interaction/session.ts
  • packages/core/src/interaction/intents.ts
  • packages/core/src/interaction/router.ts
  • packages/core/src/interaction/runtime.ts
  • packages/core/src/interaction/events.ts
  • packages/core/src/interaction/modes.ts
  • packages/core/src/interaction/edit-controller.ts
  • packages/core/src/interaction/truth-authority.ts

New CLI/TUI modules

  • packages/cli/src/tui/app.tsx
  • packages/cli/src/tui/layout.tsx
  • packages/cli/src/tui/session-view.tsx
  • packages/cli/src/tui/status-pane.tsx
  • packages/cli/src/tui/input-bar.tsx
  • packages/cli/src/tui/commands.ts

Studio changes

Keep Studio changes shallow:

  • replace /api/agent one-shot orchestration with shared control-layer API
  • adapt existing pages to subscribe to shared events
  • move current ChatBar toward a shared interaction client

File size guardrails

Hard constraints:

  • New files should target < 250 lines.
  • Orchestrator files may reach <= 350 lines if unavoidable.
  • No new monolith comparable to runner.ts.
  • Shared types go in dedicated model files, not in shells.
  • UI shells should remain thin and call shared control-layer modules.

Rollout Plan

Phase 1: Shared models and runtime bridge

Build:

  • session model
  • intent model
  • execution status/events
  • automation modes
  • runtime bridge to existing pipeline actions

No UI replacement yet.

Phase 2: TUI shell

Build the project-scoped TUI:

  • project startup
  • active book binding
  • chat input
  • process/status pane
  • core commands

Phase 3: Human edit transactions

Add:

  • chapter-level edit controller
  • truth-file-aware edit flow
  • entity rename flow

Phase 4: Studio adoption

Refit Studio:

  • shared conversation brain
  • shared event/status model
  • replace one-shot chat behavior

What This Design Explicitly Avoids

  • no separate Studio and TUI orchestration stacks
  • no top-heavy onboarding questionnaire
  • no raw file editing as the primary mutation model
  • no giant new “god file”
  • no rewriting the entire pipeline before the control layer exists

Recommendation

Implement this as a new long-running branch rooted in an isolated worktree.

The order should be:

  1. shared interaction/control models
  2. runtime bridge
  3. TUI shell
  4. edit controller
  5. Studio migration

That keeps the architecture correct while still delivering the writing-workbench experience early through TUI.