# Module Internals This guide owns the mechanics for implementing and registering production modules. [Configuration](../config.md) owns selectable keys, binding syntax, reference configuration, and default validator chains. Durable input and output shapes belong in [integration contracts](../integrations/). The D&D family has additional shared conventions and domain-specific exceptions. See [D&D Module Internals](dnd.md) rather than adding them here. ## Module Boundary A module is a typed implementation registered for one pipeline stage. Its `ModuleSpec` is the public-to-the-framework declaration of its stable key, stage, required and provided capabilities, artifact kind, and accepted reference slots. The framework uses that declaration to resolve a configured binding before it builds the implementation. Implementations that accept options must provide both an option validator and a builder. The validator is used while resolving configuration; the builder decodes the same options and constructs the implementation from the prepared `BuildRequest`. Reject unknown options in both paths. A builder receives only the dependencies and materialized references that the framework prepared for that operation, so it must not re-read configuration or files. Registry helpers register the typed builder for a stage-specific registry. They are preferable to hand-written untyped registration because they retain the artifact type at the framework boundary. Registrars validate the registries they need, register each leaf implementation, and add any family-owned assets or default validator chains. They return contextual errors so production composition fails at startup rather than at the first run. ## Production Composition Production composition is intentionally split by family: - The generic registrar provides the unit chunker, generic JSON validators, and JSON output encoder. - The Seriatim registrar provides the transcript input adapter. Its external input behavior is defined by the [Seriatim contract](../integrations/seriatim.md). - The D&D registrar provides its codecs, extractors, mergers, normalizers, validators, prompt assets, and default chains. Its behavioral conventions are documented in [D&D Module Internals](dnd.md). The CLI owns the composition that invokes these registrars. A module package may register its own family but must not assemble the CLI or make framework packages depend on production extensions. ## Adding Or Changing A Module 1. Choose the pipeline stage and the typed artifact boundary. Put external input or durable artifact formats in the relevant integration contract, not in this guide or in a private LLM response type. 2. Define a stable `ModuleSpec` with the exact capabilities and reference slots needed for the operation. Model a producer/consumer handoff as an artifact-compatible slot; configuration then chooses an external file or a generated binding. 3. Implement strict option decoding, construction, and the typed stage interface. Preserve caller ownership: do not retain mutable request data and return defensive copies where an implementation exposes stored data. 4. Register the module through its typed registry helper and add it to the owning family registrar. Add a default validator chain only when that family owns the behavior; otherwise require an explicit compatible chain. 5. Update the selectable-key and chain reference in [Configuration](../config.md#production-module-keys), the applicable integration contract, and focused tests. Keep the configuration document as the sole list of production keys and validator order. ## Validation And References Validators operate on the value produced at their configured stage. A default chain is ordered behavior, not a set: JSON parsing, structural checks, domain-specific checks, durable-schema checks, and advisory checks may have different responsibilities and failure handling. The active default chains and override rules are maintained in [Configuration](../config.md#production-validator-keys-and-default-chains). Reference slots are part of the module specification. They describe the accepted artifact kind, media type, size, and whether a binding is required; the framework validates those constraints before construction. An external reference is materialized during preparation. A generated reference is a compatible normalized artifact handed from an earlier pipeline step at operation time. The configuration reference rules, including precedence and ordered-handoff requirements, are maintained in [Configuration](../config.md#references-and-ordered-handoffs). ## Focused Verification Exercise the leaf implementation and its registration path when changing a module. Registry and registrar tests cover duplicate keys, required registries, and typed construction; pipeline resolution tests cover capabilities, options, and reference compatibility. Domain packages should additionally test their codecs, validators, normalizers, and any integration handoffs they own. Run the affected package tests while iterating. The complete module suite is: ~~~sh go test ./internal/modules/... ~~~