Skip to content

API: Core Models

Data structures that define the shape of the narrative system.

Core data models for the Novel Testbed.

These classes define the structural representation of: - Parsed novels - Fiction modules - Reader state - Narrative contracts

They are deliberately lightweight and side-effect free.

Module dataclass

Atomic unit of a novel.

A module is a scene, exposition block, or transition segment that represents a single narrative operation.

ModuleContract dataclass

Executable narrative contract for a single module.

It defines: - What the reader state is before the passage - What it should be after - What the author claims this passage is meant to do

ModuleType

Bases: str, Enum

Recognized fiction module types.

Novel dataclass

Parsed novel container.

ReaderState dataclass

Reader-facing narrative state.

This describes what the reader currently believes and feels.

These classes form the semantic backbone of the application:

  • Module → atomic unit of fiction
  • Novel → collection of modules
  • ReaderState → reader response model
  • ModuleContract → executable narrative specification

CLI

Command-line orchestration.

Command-line interface for the Novel Testbed.

This module provides four commands:

  • segment: Segment raw Markdown into annotated Markdown with structural boundaries.

  • parse: Parse annotated Markdown and generate a blank contract YAML.

  • infer: Parse annotated Markdown, infer a full narrative contract using an LLM-backed inferencer, and write the populated contract YAML.

  • assess: Assess a filled contract YAML and emit a JSON report.

The CLI is intentionally thin. All domain logic lives elsewhere.

The CLI is intentionally thin.
It wires together the parser, inferencer, and assessment engine.

No logic should live here.

Logging

Centralized logging configuration.

Central logging configuration for the Novel Testbed package.

This module configures a single root logger for the application. It is intentionally minimal and defensive: if logging is already configured, it will not override existing handlers.

All other modules in the package should obtain loggers via:

logger = logging.getLogger(__name__)

configure_logging

configure_logging(level=logging.INFO)

Configure package-wide logging.

This function initializes the root logger with a StreamHandler and a consistent format. If handlers are already present, the function exits without modifying existing configuration.

:param level: Logging level (e.g., logging.INFO, logging.DEBUG).

All modules are expected to emit meaningful, structured log messages.
Debugging narrative structure should be observable, not mystical.