Refocus developer and internal documentation
This commit is contained in:
@@ -1,268 +1,194 @@
|
||||
# Modules
|
||||
|
||||
Production modules live under `internal/modules`. Each module implements one
|
||||
contract from `internal/framework/contracts`, exposes a `ModuleSpec`, and
|
||||
registers itself with the matching pipeline registry.
|
||||
# Module And Validator Internals
|
||||
|
||||
The CLI production catalog currently registers only the modules listed here.
|
||||
Validator implementations live under `internal/validators` and are registered
|
||||
separately from modules. Production default validator chains are central CLI
|
||||
catalog policy; module packages do not own their default validation chains.
|
||||
Production stage implementations live under `internal/modules`; production
|
||||
validators live under `internal/validators`. The selectable keys, configuration
|
||||
options, reference slots, and default validator chain are canonical in the
|
||||
[module](../config.md#implemented-production-modules) and
|
||||
[validator](../config.md#implemented-production-validators) catalogs in
|
||||
Configuration.
|
||||
|
||||
## Contract Pattern
|
||||
## Extension Pattern
|
||||
|
||||
A production module package should provide:
|
||||
A stage module package provides a stable key, constructor, contract
|
||||
implementation, `ModuleSpec`, `Register`, and focused behavior and registration
|
||||
tests. A validator package follows the same pattern with `ValidatorSpec` and the
|
||||
validator registry.
|
||||
|
||||
- a stable module key;
|
||||
- a constructor such as `New`;
|
||||
- the relevant contract implementation;
|
||||
- `ModuleSpec`;
|
||||
- `Register`;
|
||||
- focused tests for registration, options, contract behavior, and errors.
|
||||
Specs expose capability and execution metadata without constructing an
|
||||
implementation. Chunk, extract, merge, and normalize modules that accept
|
||||
auxiliary material declare identical reference slots from both
|
||||
`ReferenceSlots()` and `ModuleSpec().ReferenceSlots`; registration tests enforce
|
||||
that agreement. Runtime delivery uses the corresponding stage request's
|
||||
`References` field.
|
||||
|
||||
Module specs should describe capabilities accurately. Resolution uses specs to
|
||||
reject incompatible pipelines before execution.
|
||||
LLM-backed extensions own their prompt definitions and response schemas under
|
||||
package-local embedded assets. Shared filesystem composition belongs in
|
||||
`internal/modules/sharedassets`; reusable D&D prompt fragments, reference
|
||||
declarations, prompt-input assembly, and source-unit helpers belong in
|
||||
`internal/modules/sharedassets/dnd`. Stage contracts expose only Notarius
|
||||
structured-completion types, not Scriptorium public types.
|
||||
|
||||
Chunk, extract, merge, and normalize modules that accept auxiliary reference material
|
||||
must declare slots through both `ReferenceSlots()` and
|
||||
`ModuleSpec().ReferenceSlots`. The runtime slot list and registry metadata
|
||||
should match so config validation can inspect slots without constructing module
|
||||
instances. A slot declaration names the slot, whether it is required, accepted
|
||||
media types, whether multiple items are allowed, and any byte limit. Empty
|
||||
`AcceptedMediaTypes` means any inferred media type is accepted, though the file
|
||||
must still be UTF-8 text. When a slot declares accepted media types, Notarius
|
||||
compares the canonical base media type inferred from the file extension,
|
||||
case-insensitively and without parameters.
|
||||
Reference material may inform a module or prompt but must not become source
|
||||
evidence. The resolver and materializer behavior is described in
|
||||
[Pipeline Internals](pipeline.md#reference-materialization).
|
||||
|
||||
The resolver materializes reference content for chunk, extractor, merger, and
|
||||
normalizer targets. Runtime delivery uses `contracts.ChunkRequest.References`,
|
||||
`contracts.ExtractionRequest.References`, `contracts.MergeRequest.References`,
|
||||
and `contracts.NormalizeRequest.References`. Reference material is not source
|
||||
evidence and must not be converted into `SourceRef` values. If a module prompt
|
||||
uses references, pass them as prompt input materials through the structured LLM
|
||||
request. Prompt metadata hashes remain based on prompt asset source, not
|
||||
rendered reference bytes.
|
||||
## Input Adapter
|
||||
|
||||
LLM-backed modules own Scriptorium prompt definitions and response schemas in
|
||||
their embedded assets. Module-owned prompts live under each module's shallow
|
||||
`assets/prompts` tree and schemas live under `assets/schemas`. Generic shared
|
||||
prompt filesystem composition lives under `internal/modules/sharedassets`.
|
||||
Common D&D prompt fragments, reference slot helpers, prompt input assembly, and
|
||||
reference rendering live under `internal/modules/sharedassets/dnd`. Module
|
||||
contracts should expose prompt IDs, versions, input material names, and
|
||||
non-secret prompt/schema hashes through manifest metadata; they should not
|
||||
expose Scriptorium public types through chunk, extract, merge, or normalize contracts.
|
||||
### `internal/modules/input/seriatim`
|
||||
|
||||
Chunk modules receive the structured LLM client, configured Scriptorium profile
|
||||
ID, prompt session ID, and raw source input material through
|
||||
`contracts.ChunkRequest` when they need model-backed chunking. The pipeline
|
||||
runner validates generic chunk result invariants before extraction; module-owned
|
||||
policies may be stricter but must stay within the module package.
|
||||
The adapter decodes the supported transcript JSON, selects the source identity,
|
||||
computes the raw-input digest, validates segments, and maps each segment into a
|
||||
generic source unit with speaker and timestamp metadata. Its spec advertises the
|
||||
transcript capabilities consumed by D&D modules.
|
||||
|
||||
Normalize modules receive the structured LLM client, configured Scriptorium
|
||||
profile ID, prompt session ID, and reference material through
|
||||
`contracts.NormalizeRequest` when they need model-backed reconciliation.
|
||||
Parsing is strict about required values and duplicate unit IDs but deliberately
|
||||
ignores unrelated Seriatim fields. The external format and derived-identity
|
||||
rules are defined in the
|
||||
[Seriatim contract](../integrations/seriatim.md).
|
||||
|
||||
Merge modules receive the structured LLM client, configured Scriptorium profile
|
||||
ID, prompt session ID, raw source input material, and reference material through
|
||||
`contracts.MergeRequest` when they need model-backed merge behavior.
|
||||
## Chunkers
|
||||
|
||||
## `seriatim` Input
|
||||
### `internal/modules/chunk/generic`
|
||||
|
||||
Package: `internal/modules/input/seriatim`
|
||||
The generic chunker validates the source document, walks units in configured
|
||||
windows, clones each selected unit, and emits deterministic ordered chunk IDs.
|
||||
Overlap changes the next window start but never reorders units. It records the
|
||||
first and last unit and unit count in chunk metadata.
|
||||
|
||||
The `seriatim` adapter parses Seriatim transcript JSON into a generic source
|
||||
document. It owns transcript JSON details, source ID selection, source digest
|
||||
creation, transcript segment validation, and segment metadata mapping.
|
||||
The accepted options and defaults are defined in
|
||||
[Configuration](../config.md#implemented-production-modules). Generic
|
||||
framework validation canonicalizes the returned unit slices before extraction.
|
||||
|
||||
Provides:
|
||||
### `internal/modules/chunk/dnd/scenes`
|
||||
|
||||
- `source.transcript`
|
||||
- `transcript.speaker`
|
||||
- `transcript.timestamps`
|
||||
The scene chunker prepares a structured Scriptorium request from the full
|
||||
transcript, session, and optional D&D reference inputs. It validates the model's
|
||||
scene boundaries against source-unit IDs and converts them into deterministic
|
||||
chunks.
|
||||
|
||||
External JSON shape belongs in the Seriatim integration doc.
|
||||
Scene validation requires sequential, contiguous, non-overlapping coverage from
|
||||
the first source unit through the last. Each chunk contains JSON scene content
|
||||
and module-owned metadata for the scene description, boundaries, confidence,
|
||||
participants, and unit count. Boundary caveats become warnings. Malformed
|
||||
structured output is returned as an error; there is no fallback chunker.
|
||||
|
||||
## `generic` Chunker
|
||||
The package embeds its prompt and response schema and reports their non-secret
|
||||
identity and hashes through singleton module metadata. Shared D&D assets supply
|
||||
reference declarations and prompt inputs; their user-facing keys and accepted
|
||||
file types remain canonical in [Configuration](../config.md).
|
||||
|
||||
Package: `internal/modules/chunk/generic`
|
||||
## Extractor
|
||||
|
||||
The `generic` chunker splits source units into ordered chunks. It validates the
|
||||
source document, clones source units, assigns chunk IDs such as `chunk-000001`,
|
||||
and records chunk metadata for start unit, end unit, and unit count.
|
||||
### `internal/modules/extract/dnd/spells`
|
||||
|
||||
The pipeline runner canonicalizes chunk units from the source document by
|
||||
integer ID before extractors and mergers run. Chunkers also populate chunk
|
||||
start and end unit IDs, content bytes, and media type. Chunker-owned context
|
||||
should stay in `SourceChunk.Metadata`.
|
||||
The spell extractor prepares a structured request from one chunk, the
|
||||
chunk-scoped source input, the session, and optional D&D reference inputs. It
|
||||
decodes the model response, assigns the generic source identity to every source
|
||||
reference, canonicalizes duplicate references, orders spell casts by their
|
||||
earliest cited unit, and returns raw JSON plus response-schema provenance.
|
||||
|
||||
Options:
|
||||
The package owns its embedded prompt, response schemas, and prompt/schema
|
||||
manifest metadata. Shared D&D helpers keep prompt input names and source-unit
|
||||
reference conversion consistent with the scene chunker. The extractor produces
|
||||
raw output; production validators own approval policy.
|
||||
|
||||
- `max_units`: positive integer, default `50`;
|
||||
- `overlap_units`: non-negative integer, default `0`, and less than
|
||||
`max_units`.
|
||||
The durable payload and manifest metadata shapes are defined in the
|
||||
[D&D spell artifact contract](../integrations/dnd-spell-artifacts.md).
|
||||
|
||||
Provides:
|
||||
## Merger And Normalizer
|
||||
|
||||
- `chunks`
|
||||
### `internal/modules/merge/appendorder`
|
||||
|
||||
## `dnd/scenes` Chunker
|
||||
The merger preserves extract-result order. It passes through one JSON result,
|
||||
concatenates a common top-level array field across multiple JSON objects, and
|
||||
otherwise emits an array of the decoded values. It rejects invalid JSON and
|
||||
non-JSON media types, and it preserves compatible schema provenance.
|
||||
|
||||
Package: `internal/modules/chunk/dnd/scenes`
|
||||
### `internal/modules/normalize/noop`
|
||||
|
||||
The `dnd/scenes` chunker uses the structured LLM client to divide transcript
|
||||
source units into coherent D&D scenes. It supplies the embedded Scriptorium
|
||||
prompt ID, prompt version, transcript input material, response schema, and
|
||||
session ID to the runtime; validates model-authored source-unit boundaries; and
|
||||
converts each scene into a deterministic source chunk.
|
||||
The normalizer defensively clones the accepted merge result, including payload
|
||||
bytes, metadata, warnings, and schema provenance, without changing its logical
|
||||
content.
|
||||
|
||||
Its prompt definition lives under `assets/prompts` and its schema under
|
||||
`assets/schemas`. Shared reusable D&D prompt fragments are provided by
|
||||
`internal/modules/sharedassets/dnd` and referenced from prompt definitions under
|
||||
`./sharedassets/`.
|
||||
## Output Encoder
|
||||
|
||||
Requires:
|
||||
### `internal/modules/output/json`
|
||||
|
||||
- `source.transcript`
|
||||
The JSON encoder sorts normalized results by lane, derives collision-checked
|
||||
safe logical names, pretty-prints JSON payloads, and assembles the logical index,
|
||||
manifest, rejected-result, warning, and lane files. Invalid JSON, unsupported
|
||||
media types, unsafe names, and sanitized-name collisions are errors.
|
||||
|
||||
Provides:
|
||||
The encoder returns logical files only. The CLI places them on disk, and the
|
||||
[JSON output contract](../integrations/json-output.md) defines their external
|
||||
paths and schemas.
|
||||
|
||||
- `chunks`
|
||||
- `chunks.scenes`
|
||||
## Generic Validators
|
||||
|
||||
Options: none. Non-empty options are rejected.
|
||||
The unconditional accept and reject validators provide deterministic production
|
||||
registrations used primarily for controlled composition and tests.
|
||||
|
||||
The chunker enforces full source-unit coverage from the first source unit to the
|
||||
last, sequential contiguous scenes, and no overlap. Its LLM-facing schema uses
|
||||
integer `start_unit_id` and `end_unit_id` values matching source-unit IDs. It
|
||||
assigns chunk IDs such as `scene-000001`, emits JSON chunk content, and stores
|
||||
scene metadata including title, primary mode, participants, summary, boundary
|
||||
note, confidence, boundary unit IDs, and unit count. Boundary caveats become
|
||||
warnings with reason code
|
||||
`scene_boundary_caveat`. Whitespace-only caveats are treated as malformed
|
||||
structured output rather than silently dropped.
|
||||
The JSON syntax validator uses `encoding/json` to reject malformed payloads. The
|
||||
JSON Schema validator requires schema bytes on the validation request, parses
|
||||
the instance and schema with `jsonschema`, and distinguishes payload rejection
|
||||
from schema loading or compilation errors. Neither validator calls the LLM.
|
||||
|
||||
Malformed model output fails explicitly rather than falling back to another
|
||||
chunker. The chunker exposes prompt and response-schema provenance through
|
||||
top-level `module_metadata.chunker` without raw prompts, raw schemas, source
|
||||
text, or secrets.
|
||||
## D&D Spell Validators
|
||||
|
||||
## `dnd/spells` Extractor
|
||||
`internal/validators/extract/dnd/spells/spellpayload` provides strict decoding,
|
||||
shape checks, source-reference candidates, and cited-text lookup shared by the
|
||||
three validators.
|
||||
|
||||
Package: `internal/modules/extract/dnd/spells`
|
||||
The shape validator rejects malformed JSON, unknown fields, missing or empty
|
||||
spell fields, and empty reference lists. The source-reference validator applies
|
||||
generic source-reference validation to every cited range. The relatedness
|
||||
validator approves structurally valid payloads but warns when a case-insensitive
|
||||
spell name is absent from all cited source text. It leaves malformed payloads to
|
||||
the earlier validators in the configured chain.
|
||||
|
||||
The `dnd/spells` extractor owns D&D spell-cast extraction semantics. It
|
||||
supplies the embedded Scriptorium prompt ID, prompt version, chunk-scoped
|
||||
transcript input material, reference input materials, response schema, and
|
||||
session ID to the runtime; then returns the structured LLM `spell_casts`
|
||||
response as raw JSON.
|
||||
Its LLM-facing source-reference schema uses integer `start_unit_id` and
|
||||
`end_unit_id` values matching source-unit IDs.
|
||||
|
||||
Its prompt definition lives under `assets/prompts` and its schema under
|
||||
`assets/schemas`. Shared reusable D&D prompt fragments are provided by
|
||||
`internal/modules/sharedassets/dnd` and referenced from prompt definitions under
|
||||
`./sharedassets/`.
|
||||
|
||||
Requires:
|
||||
|
||||
- `chunks`
|
||||
- `source.transcript`
|
||||
|
||||
Provides:
|
||||
|
||||
- `dnd.spell_casts`
|
||||
|
||||
Response schema identity:
|
||||
|
||||
- schema ID: `notarius.dnd.spells`
|
||||
- schema name: `notarius_dnd_spells_v1`
|
||||
- schema version: `v1`
|
||||
|
||||
The extractor adds prompt and response-schema provenance to lane manifest
|
||||
metadata under `artifact_lanes[].metadata.extractor`. Durable raw output
|
||||
details belong in the
|
||||
[D&D spell raw output contract](../integrations/dnd-spell-artifacts.md).
|
||||
|
||||
The production catalog validates `dnd/spells` raw extract output with generic
|
||||
JSON validators followed by D&D spell validators under
|
||||
`internal/validators/extract/dnd/spells`. The extractor itself remains
|
||||
responsible for prompt, schema, and raw output production rather than
|
||||
approve/reject policy.
|
||||
|
||||
The `dnd/scenes` chunker and `dnd/spells` extractor declare optional `players`,
|
||||
`party`, and `glossary` reference slots accepting UTF-8 plain text, Markdown,
|
||||
YAML, or JSON. They also accept `roster` as a deprecated compatibility alias for
|
||||
`party`. Their prompts frame references as supporting disambiguation material
|
||||
only; spell-cast artifacts must still be grounded in the source transcript.
|
||||
|
||||
## `appendorder` Merger
|
||||
|
||||
Package: `internal/modules/merge/appendorder`
|
||||
|
||||
The `appendorder` merger preserves chunk order for raw extract outputs. A
|
||||
single JSON extract output is passed through as the merge output. Multiple JSON
|
||||
object outputs with one common top-level array field are merged by concatenating
|
||||
that array field in chunk order. Other valid JSON shapes are merged as a JSON
|
||||
array of decoded values in chunk order. Non-JSON media types and invalid JSON
|
||||
are rejected.
|
||||
|
||||
Provides:
|
||||
|
||||
- `merged`
|
||||
|
||||
## `noop` Normalizer
|
||||
|
||||
Package: `internal/modules/normalize/noop`
|
||||
|
||||
The `noop` normalizer clones the raw merge output and returns it unchanged.
|
||||
|
||||
Requires:
|
||||
|
||||
- `merged`
|
||||
|
||||
Provides:
|
||||
|
||||
- `normalized`
|
||||
|
||||
## `json` Output
|
||||
|
||||
Package: `internal/modules/output/json`
|
||||
|
||||
The `json` output encoder converts normalized raw outputs, rejected raw outputs,
|
||||
warnings, and the run manifest into logical JSON output files. It writes one
|
||||
payload file per lane under `lanes/` and sanitizes lane IDs for file names.
|
||||
Normalized output payloads must be valid `application/json`.
|
||||
|
||||
Requires:
|
||||
|
||||
- `normalized`
|
||||
|
||||
Provides:
|
||||
|
||||
- `encoded`
|
||||
|
||||
Durable output file shapes belong in the
|
||||
[JSON output contract](../integrations/json-output.md). Operator behavior
|
||||
belongs in [Operations](../operations.md).
|
||||
These validators are deterministic. Their selectable keys and production order
|
||||
are defined in
|
||||
[Configuration](../config.md#implemented-production-validators); their durable
|
||||
payload rules are defined in the
|
||||
[artifact contract](../integrations/dnd-spell-artifacts.md).
|
||||
|
||||
## Production Registration
|
||||
|
||||
Production registration is centralized in `internal/cli/catalog.go`.
|
||||
`internal/cli/catalog.go` builds the production registries, registers module and
|
||||
validator constructors, installs default validator-chain mappings, and exposes
|
||||
the matching catalog for resolution. It also collects prompt assets from
|
||||
LLM-backed packages before constructing the production client.
|
||||
|
||||
Do not make framework code import production modules. The CLI wires production
|
||||
modules at the application boundary; tests may provide fake registries or fake
|
||||
catalogs directly.
|
||||
Framework packages must not import production extensions. Tests may compose
|
||||
registries and catalogs directly with fakes.
|
||||
|
||||
## Adding A Module
|
||||
## Adding An Extension
|
||||
|
||||
When adding a module, keep source-format and extraction-domain boundaries clear:
|
||||
When adding a production module or validator:
|
||||
|
||||
- input modules may know external source formats;
|
||||
- extract modules may know artifact semantics and prompt/schema assets;
|
||||
- merge and normalize modules own raw output combination and reconciliation;
|
||||
- output modules own serialization, not diagnostics or CLI reporting.
|
||||
1. implement the stage or validator contract and package-local key;
|
||||
2. expose and test its spec, constructor, and registration function;
|
||||
3. keep format or domain parsing inside the concrete package;
|
||||
4. add package-owned prompt/schema assets when the extension is LLM-backed;
|
||||
5. register it in `internal/cli/catalog.go` and add a default chain only when
|
||||
production policy requires one;
|
||||
6. add resolution and composition coverage for capabilities, options,
|
||||
references, and validation behavior;
|
||||
7. update the selectable-key catalog in [Configuration](../config.md), the
|
||||
relevant external contract, this inventory, and maintained examples when
|
||||
user-visible behavior changes.
|
||||
|
||||
Update [Development](../development.md), [Configuration](../config.md),
|
||||
internal docs, integration docs, and examples when the new module becomes
|
||||
implemented production behavior.
|
||||
Do not add the extension to `docs/development.md`; that file routes by task and
|
||||
does not inventory implementations.
|
||||
|
||||
## Tests To Inspect
|
||||
|
||||
- Package-local `*_test.go` files under the module or validator being changed.
|
||||
- `internal/framework/pipeline/registry_integration_test.go`: registry and spec
|
||||
composition.
|
||||
- `internal/framework/pipeline/default_modules_test.go`: framework binding
|
||||
defaults.
|
||||
- `internal/cli/run_test.go`: production catalog, config resolution, and
|
||||
end-to-end CLI composition.
|
||||
- `internal/modules/sharedassets/**/*_test.go`: shared prompt and reference
|
||||
assembly.
|
||||
|
||||
Reference in New Issue
Block a user