Narratological Algorithmic Lenses
Formalized narrative analysis as executable theory
The Problem: Narrative Theory Without Computational Infrastructure
Narrative analysis has operated for a century on frameworks that are structurally precise but computationally inert. Vladimir Propp demonstrated in 1928 that Russian wondertales could be decomposed into thirty-one sequential functions — a formal grammar of plot — yet his morphology remained a paper artifact, executed only by human readers marking up texts by hand.[1] Gerard Genette's taxonomy of narrative discourse — distinguishing order, duration, frequency, mood, and voice — provided an analytical apparatus of extraordinary precision, yet it too remained confined to close reading, applicable only at the pace of a single scholar working through a single text.[2] This project asks what happens when these frameworks stop being interpretive vocabularies and become executable algorithms: typed Python models with diagnostic outputs, confidence scores, and testable assertions. The goal is not to automate literary criticism but to give narrative theory the same computational infrastructure that other formal disciplines — linguistics, logic, mathematics — have long taken for granted.
Analytical Frameworks as Algorithms
The core intellectual challenge is translating humanistic frameworks into computational primitives without flattening the interpretive richness that makes them valuable. Propp's morphology provides the clearest entry point: his thirty-one functions (Absentation, Interdiction, Violation, Reconnaissance, and so on) form an ordered sequence with defined transition rules — essentially a finite state machine for plot.[1] Algirdas Julien Greimas's actantial model abstracts further, reducing any narrative to six actantial roles (Subject, Object, Sender, Receiver, Helper, Opponent) organized into three axes of desire, communication, and power — a structural semantics that applies across genres and media.[3] Roland Barthes's distinction between five narrative codes — hermeneutic, proairetic, semantic, symbolic, and cultural — provides yet another decomposition, one that foregrounds the reader's experience of meaning-construction rather than the text's internal grammar.[4] Each framework becomes a separate analysis module in the core library, with its own typed models, detection heuristics, and output schemas — but all sharing a common interface contract that allows frameworks to be composed, compared, and cross-referenced.
from dataclasses import dataclass, field
from enum import Enum
from typing import Optional
class ActantialRole(Enum):
SUBJECT = "subject"
OBJECT = "object"
SENDER = "sender"
RECEIVER = "receiver"
HELPER = "helper"
OPPONENT = "opponent"
class ActantialAxis(Enum):
DESIRE = "desire" # Subject <-> Object
COMMUNICATION = "communication" # Sender <-> Receiver
POWER = "power" # Helper <-> Opponent
@dataclass
class ActantDetection:
"""A detected actantial role assignment."""
entity: str
role: ActantialRole
axis: ActantialAxis
confidence: float # 0.0 to 1.0
evidence: list[str] = field(default_factory=list)
structural_relations: dict[str, str] = field(default_factory=dict)
@dataclass
class ActantialDiagnostic:
"""Complete actantial analysis of a narrative segment."""
detections: list[ActantDetection]
axis_completeness: dict[ActantialAxis, float]
unresolved_entities: list[str]
framework_version: str = "greimas-1966"
overall_confidence: float = 0.0
def validate(self) -> list[str]:
"""Return structural violations — e.g., axis with Subject but no Object."""
violations = []
roles_by_axis = {axis: [] for axis in ActantialAxis}
for d in self.detections:
roles_by_axis[d.axis].append(d.role)
if ActantialRole.SUBJECT in roles_by_axis[ActantialAxis.DESIRE] \
and ActantialRole.OBJECT not in roles_by_axis[ActantialAxis.DESIRE]:
violations.append("Desire axis: Subject without Object")
return violations Four-Package Architecture
The monorepo is structured as four distinct packages, each serving a different consumer while sharing the same analytical core. This separation follows the ports-and-adapters pattern: the core library contains all domain logic — models, algorithms, diagnostics, the unified compendium of narratological definitions — while the CLI, API, and frontend are adapters that expose that logic through different interfaces.[5] The Python core bundles a unified compendium of narratological algorithms as structured JSON, with a loader that resolves packaged resources first and falls back to repository paths for local development. The CLI (built on Typer) enables terminal-based analysis for researchers who work in scripts and pipelines. The FastAPI service provides programmatic access for downstream systems — ORGAN-II's generative art tools, ORGAN-III's product prototypes — that need to call narratological analysis as a microservice. The React frontend enables interactive exploration, letting users select frameworks, adjust confidence thresholds, and visually inspect structural mappings.[6] Source material — chat transcripts, primary texts, structured JSON exports — lives in a specs/ directory organized by research stage: primary sources, completed studies, templates, and open drafts.
| Package | Technology | Purpose | Interface Type |
|---|---|---|---|
narratological-core | Python, Pydantic, dataclasses | Domain models, algorithms, diagnostics, compendium loader | Library (import) |
narratological-cli | Typer, Rich | Terminal-based analysis for researchers and scripted pipelines | Command-line |
narratological-api | FastAPI, Uvicorn | Programmatic access for downstream systems and microservice calls | REST API |
narratological-frontend | React, Vite, TypeScript | Interactive exploration with visual framework selection and threshold tuning | Web UI |
Diagnostic Output: Beyond Classification
The system's output is not a label but a diagnostic — a structured report that tells the analyst not just what was detected but how confident the detection is, what evidence supports it, and what structural relations connect it to other detections. When the engine runs a Proppian analysis, it does not simply say "this is a hero's journey." It reports precisely which morphological functions were detected, at what confidence level, with what ordering violations (if any), and which functions are expected but absent.[7] Moretti's argument for "distant reading" — analyzing literature not through close attention to individual texts but through computational aggregation of patterns across thousands — requires exactly this kind of structured, machine-readable output. The diagnostic model enables composability: an actantial analysis can be cross-referenced with a Proppian analysis to identify where Greimas's Subject maps onto Propp's Hero function, revealing structural homologies that close reading might miss.[8] Jockers's macroanalytic method depends on the ability to aggregate and compare structured outputs across corpora — the diagnostic format is designed to feed precisely this kind of computational literary scholarship.
Composable Frameworks and Cross-Reference
The most powerful analytical results emerge not from applying a single framework but from composing multiple frameworks against the same text and examining where their outputs converge, diverge, or complement each other. A Proppian analysis detects sequential plot functions; an actantial analysis detects role assignments on axes of desire, communication, and power; a Genettean analysis detects focalization shifts and temporal ordering. When all three run against the same narrative segment, the diagnostic engine can map Propp's "Hero" function onto Greimas's Subject role and Genette's internal focalization, revealing that a protagonist's agency is simultaneously a plot function, a structural position, and a perspective anchor.[2] This compositional approach reflects a design principle borrowed from software architecture: each framework is a module with a stable interface, and the system's value grows combinatorially as modules are composed rather than linearly as they are added.[5] Cross-referencing also surfaces disagreements — cases where frameworks assign contradictory structural roles to the same entity — and these disagreements are diagnostically valuable, pointing to genuine ambiguities in the narrative rather than analytical errors.
from narratological_core.frameworks import (
ProppianAnalyzer,
ActantialAnalyzer,
FocalizationAnalyzer,
)
from narratological_core.models.cross_reference import CorrespondenceMap
def compose_analysis(
text: str,
frameworks: list[str] | None = None,
confidence_threshold: float = 0.5,
) -> CorrespondenceMap:
"""Run multiple frameworks and map structural correspondences."""
analyzers = {
"propp": ProppianAnalyzer(),
"actantial": ActantialAnalyzer(),
"focalization": FocalizationAnalyzer(),
}
selected = frameworks or list(analyzers.keys())
results = {
name: analyzers[name].analyze(text, threshold=confidence_threshold)
for name in selected
if name in analyzers
}
# Build correspondence map across framework outputs
correspondence = CorrespondenceMap(framework_results=results)
correspondence.map_entity_roles() # Propp Hero <-> Greimas Subject
correspondence.map_perspectives() # Genette focalization <-> role agency
correspondence.detect_conflicts() # Contradictory role assignments
return correspondence The Specs Directory: Research as First-Class Data
The monorepo treats source material with the same architectural rigor as code. The specs/ directory is organized by research stage — primary sources, completed studies, templates, and open drafts — creating a clear lifecycle for analytical work. Primary sources include chat transcripts, literary texts, and structured JSON exports from other systems. Completed studies are finalized analyses with frozen diagnostic outputs, serving as regression baselines: if a code change alters the diagnostic output for a completed study, the test suite catches it.[7] Templates provide scaffolding for new analyses, encoding best practices about which frameworks to apply in which order and what confidence thresholds to use for different genres. Open drafts are work-in-progress analyses that have not yet been validated. This organization means that the repository is not just a codebase but a research archive — the analytical history is versioned alongside the analytical tools, making every study reproducible and every methodological change traceable.[8]
Bridge to Generative Work
The narratological lenses project occupies a specific position within the eight-organ system: it is ORGAN-I (Theoria) infrastructure that enables work in ORGAN-II (Poiesis) and ORGAN-III (Ergon). When narrative theory is encoded as executable algorithms with typed outputs, those outputs become inputs for generative systems. A Proppian analysis that identifies the "Villainy" and "Lack" functions at specific text positions can drive a generative music system to shift harmonic mode at those structural inflection points. An actantial analysis that maps Subject-Object-Opponent relations can inform the spatial layout of an interactive visualization, positioning entities according to their structural roles.[9] Murray's vision of the computer as a medium for procedural, participatory, spatial, and encyclopedic storytelling requires exactly this kind of machine-readable narrative intelligence — not stories generated by algorithms, but analytical structures that algorithms can consume and transform. The lenses project makes theory operational: it turns ORGAN-I's scholarly frameworks into API endpoints that ORGAN-II's art tools and ORGAN-III's product prototypes can call.[10] Manovich's thesis that software has become the engine of cultural production implies that the boundary between analysis and generation is permeable — the same typed models that describe a narrative's structure can be used to synthesize new structures that satisfy the same constraints.
Why This Approach Matters
The digital humanities have produced remarkable tools for corpus analysis — topic modeling, sentiment analysis, named entity recognition — but these tools largely bypass the rich structural vocabularies that narratologists have spent a century developing. Propp's functions, Greimas's actants, Genette's focalization categories, and Barthes's codes represent decades of careful theoretical work about how stories actually organize meaning, yet computational literary studies have largely ignored them in favor of statistical methods borrowed from natural language processing.[4] This project fills that gap by encoding narratological frameworks as first-class computational objects — not approximations or metaphors, but faithful implementations with typed models, validation logic, and confidence scoring. The result is a system where disagreements between frameworks become debuggable, where analytical claims are testable assertions, and where the entire history of narrative theory becomes a composable toolkit rather than a bibliography.[3] When a narratological claim is encoded as a function with assertions, scholarly debate gains a new modality: not just argument and counter-argument, but test case and counter-example.
References
- Propp, Vladimir. Morphology of the Folktale. University of Texas Press, 1928.
- Genette, Gerard. Narrative Discourse: An Essay in Method. Cornell University Press, 1972.
- Greimas, Algirdas Julien. Structural Semantics: An Attempt at a Method. University of Nebraska Press, 1966.
- Barthes, Roland. S/Z: An Essay. Hill and Wang, 1970.
- Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1994.
- Fowler, Martin. Patterns of Enterprise Application Architecture. Addison-Wesley, 2002.
- Moretti, Franco. Distant Reading. Verso Books, 2013.
- Jockers, Matthew L.. Macroanalysis: Digital Methods and Literary History. University of Illinois Press, 2013.
- Murray, Janet H.. Hamlet on the Holodeck: The Future of Narrative in Cyberspace. MIT Press, 1997.
- Manovich, Lev. Software Takes Command. Bloomsbury Academic, 2013.