114 lines
6.1 KiB
Markdown
114 lines
6.1 KiB
Markdown
# 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, execution class, required and provided capabilities, artifact kind, and
|
|
accepted reference slots. The execution class states whether a module is
|
|
`deterministic` or `llm_backed`; registries retain it for catalog inspection and
|
|
resolved-pipeline debug data without constructing the module. The framework
|
|
uses the declaration to resolve a configured binding before it builds the
|
|
implementation. After selection, the resolver applies profile inheritance only
|
|
to bindings whose declared execution class is `llm_backed` and rejects a
|
|
binding-specific profile on a deterministic module. The user-facing precedence
|
|
contract belongs in [Configuration](../config.md#pipelines).
|
|
|
|
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.
|
|
|
|
An artifact family can register an optional typed evidence projector alongside
|
|
its codec. The projector returns defensive copies of the artifact's direct
|
|
generic source references and must use the codec's exact Go type. It does not
|
|
interpret surrounding context or publish files; the pipeline validates the
|
|
capability during preparation and the output boundary owns publication. See
|
|
the [Published Evidence Context contract](../integrations/evidence-context.md)
|
|
for the durable result.
|
|
|
|
## 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, fallback profile asset, 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 an explicit execution class, 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/...
|
|
~~~
|