Add roadmap documents for the initial architecture
This commit is contained in:
3
AGENTS.md
Normal file
3
AGENTS.md
Normal file
@@ -0,0 +1,3 @@
|
||||
Please carefully review the documents in `docs/policy` before making any changes to this repository.
|
||||
- `architecture.md` provides the canonical high-level architecture policy for this repository.
|
||||
- `documentation.md` provides the canonical documentation policy for this repository.
|
||||
@@ -1,39 +1,170 @@
|
||||
# Architecture
|
||||
|
||||
This document defines the development principles for this Go project. It is inward-facing: developers and LLM coding agents should use it to preserve the project’s shape, boundaries, and invariants as the code evolves.
|
||||
This document defines the development principles for Notarius. It is
|
||||
inward-facing: developers and LLM coding agents should use it to preserve the
|
||||
project's shape, boundaries, and invariants as the code evolves.
|
||||
|
||||
## Project Shape
|
||||
|
||||
Default to a small, explicit, dependency-light Go application. Keep the design modular enough to test and change safely, but do not add abstraction unless it protects a real boundary or enables a real extension point.
|
||||
Notarius is a small, explicit, dependency-light Go application for extracting
|
||||
structured artifacts from source material using modular extractors.
|
||||
|
||||
Business/domain logic should live outside CLI, transport, and external-adapter packages.
|
||||
The application should be contract-first but not abstraction-heavy. Add
|
||||
interfaces and extension points when they protect a real boundary:
|
||||
|
||||
- external source formats;
|
||||
- extractor modules;
|
||||
- validators;
|
||||
- LLM providers and runtime plumbing;
|
||||
- output schemas and embedded assets.
|
||||
|
||||
Avoid abstractions that only anticipate hypothetical complexity. Prefer narrow
|
||||
contracts that can be exercised by tests and real modules.
|
||||
|
||||
## Core Invariants
|
||||
|
||||
The core framework must remain source-agnostic and domain-agnostic.
|
||||
|
||||
Source-format details belong in input adapters. Transcript-specific concepts
|
||||
such as segments, speakers, timestamps, and transcript schemas must not spread
|
||||
into runner, extractor, or validator framework code.
|
||||
|
||||
Extraction-domain details belong in extractor packages. D&D-specific concepts
|
||||
such as spells, NPCs, items, combat turns, and encounters must not spread into
|
||||
core source, runner, or LLM framework packages.
|
||||
|
||||
Extracted facts should be grounded with source references. Source references
|
||||
should point to generic source units, not to transcript-only structures.
|
||||
|
||||
## Dependency Policy
|
||||
|
||||
Prefer the Go standard library where practical.
|
||||
|
||||
Use external dependencies only when justified by correctness, security, interoperability, or substantial complexity reduction. Good reasons include complex security-sensitive behavior, such as HTML sanitization, or widely used de facto standards, such as YAML parsing.
|
||||
Use external dependencies only when justified by correctness, security,
|
||||
interoperability, or substantial complexity reduction. Good reasons include
|
||||
widely used file formats, complex validation behavior, or secure transport
|
||||
handling.
|
||||
|
||||
Avoid dependencies for small conveniences. Do not let external dependency types leak across internal package boundaries unless the dependency is itself the explicit public contract of that package.
|
||||
Avoid dependencies for small conveniences. Do not let external dependency types
|
||||
leak across internal package boundaries unless the dependency is itself the
|
||||
explicit public contract of that package.
|
||||
|
||||
## Package Layout
|
||||
|
||||
Use this layout unless the project has a documented reason to differ:
|
||||
Use this layout unless a change documents a better project-specific reason.
|
||||
|
||||
- `internal/app`: application orchestration and top-level use cases.
|
||||
CLI and executable entrypoint:
|
||||
|
||||
- `cmd/notarius`: executable entrypoint.
|
||||
- `internal/cli`: CLI command definitions, flags, argument parsing, and command wiring.
|
||||
- `internal/config`: configuration structs, defaults, loading, precedence, and validation.
|
||||
- `internal/adapters/<name>`: adapters for external CLIs, APIs, databases, object stores, or libraries.
|
||||
- `internal/api`: HTTP API handlers and request/response types, when the application exposes an HTTP API.
|
||||
- `internal/transport/http`: HTTP client code, when the application calls HTTP services.
|
||||
|
||||
Package-private implementation constants may live near the package that owns them, preferably in `constants.go` when useful.
|
||||
Core deterministic model and policy:
|
||||
|
||||
- `internal/core/config`: configuration structs, defaults, loading, precedence, and validation.
|
||||
- `internal/core/source`: source document, source unit, and source reference types.
|
||||
- `internal/core/sourcechunking`: deterministic chunking of ordered source units.
|
||||
- `internal/core/artifacts`: artifact envelope, artifact candidates, rejected artifacts, and manifests.
|
||||
- `internal/core/diagnostics`: run directories and diagnostics artifact paths.
|
||||
- `internal/core/reporting`: process reports and report serialization.
|
||||
- `internal/core/inputcatalog`: known input adapter keys and metadata.
|
||||
- `internal/core/extractorcatalog`: known extractor keys and metadata.
|
||||
|
||||
External source and provider adapters:
|
||||
|
||||
- `internal/adapters/input/<name>`: source-format adapters that parse external input into core source documents.
|
||||
- `internal/transport/http`: shared HTTP client code, if needed by provider integrations.
|
||||
|
||||
Reusable framework plumbing:
|
||||
|
||||
- `internal/framework/contracts`: core interfaces and transport-neutral request/response contracts.
|
||||
- `internal/framework/runner`: orchestration across adapters, extractors, validators, and artifact output.
|
||||
- `internal/framework/extraction`: shared extraction helper code.
|
||||
- `internal/framework/validators`: shared validator runtime behavior and decision checks.
|
||||
- `internal/framework/llm`: LLM runtime, scheduling, and provider adapters.
|
||||
- `internal/framework/responseschema`: embedded structured-output schema registry.
|
||||
- `internal/framework/structuredoutput`: structured-output parsing and malformed-response handling.
|
||||
- `internal/framework/promptcontext`: source-document prompt rendering helpers.
|
||||
- `internal/framework/warnings`: shared warning records.
|
||||
|
||||
Domain implementations:
|
||||
|
||||
- `internal/extractors/<domain>/<extractor>`: domain-specific extractor packages.
|
||||
- `internal/validators/<validator>`: built-in validator implementations.
|
||||
- `internal/prompts`: embedded prompt assets and prompt metadata registry.
|
||||
|
||||
Package-private implementation constants may live near the package that owns
|
||||
them, preferably in `constants.go` when useful.
|
||||
|
||||
## Input Adapters
|
||||
|
||||
Use a hexagonal architecture style for source input.
|
||||
|
||||
Input adapters translate external source formats into the core source model.
|
||||
Adapters may know about external schema details, source-specific metadata, and
|
||||
format-specific validation rules. They should not own extraction-domain
|
||||
decisions.
|
||||
|
||||
Other packages should interact with source input through adapter contracts and
|
||||
core source types. Adapter implementation details and external dependency types
|
||||
must not leak into framework or extractor packages.
|
||||
|
||||
Adapter metadata may preserve source-specific facts such as transcript speaker,
|
||||
timestamps, Markdown heading path, page number, or block ID. Framework code may
|
||||
carry metadata through, but should not require a specific adapter's metadata
|
||||
shape.
|
||||
|
||||
## Extractors
|
||||
|
||||
Extractors are independent modules that produce one kind of structured artifact.
|
||||
Each extractor package owns:
|
||||
|
||||
- its artifact semantics;
|
||||
- its prompt usage;
|
||||
- its structured response schema selection;
|
||||
- its validator chain;
|
||||
- any domain-specific mapping or interpretation.
|
||||
|
||||
Extractors should depend on framework contracts and core source/artifact types.
|
||||
They should not depend on concrete input adapter packages.
|
||||
|
||||
The runner should be able to compose, skip, resume, or run individual extractors
|
||||
when their prerequisites are satisfied. Ordering should be explicit through
|
||||
configuration, a default sequence, or documented orchestration rules.
|
||||
|
||||
Extractor selection must go through a registry or equivalent mechanism rather
|
||||
than scattered conditionals.
|
||||
|
||||
## Validators
|
||||
|
||||
Validators should be independently testable and composable.
|
||||
|
||||
Deterministic validators should run before LLM-backed validators when both are
|
||||
present. Validator decision semantics should be explicit: each candidate
|
||||
artifact should receive exactly one decision from each validator that evaluates
|
||||
it.
|
||||
|
||||
Shared validator runtime mechanics belong under `internal/framework/validators`.
|
||||
Concrete validator behavior belongs under `internal/validators/<validator>`.
|
||||
|
||||
## LLM Runtime
|
||||
|
||||
LLM provider details belong behind transport-neutral framework contracts.
|
||||
|
||||
Provider-specific HTTP request and response types should stay inside the LLM
|
||||
runtime package. Prompt construction should stay in extractors, validators, or
|
||||
shared prompt-context helpers; provider adapters should not own domain prompt
|
||||
logic.
|
||||
|
||||
Errors, diagnostics, reports, and redacted config must not expose secrets.
|
||||
|
||||
## Configuration
|
||||
|
||||
Centralize configuration loading, processing, precedence, defaults, and validation in `internal/config`.
|
||||
Centralize configuration loading, processing, precedence, defaults, and
|
||||
validation in `internal/core/config`.
|
||||
|
||||
The goal is to make configuration discoverable and avoid implicit or hidden operational values. User-visible defaults and cross-package operational defaults should be defined in `internal/config/defaults.go`.
|
||||
The goal is to make configuration discoverable and avoid implicit or hidden
|
||||
operational values. User-visible defaults and cross-package operational defaults
|
||||
should be defined in config code.
|
||||
|
||||
Unless documented otherwise, precedence is:
|
||||
|
||||
@@ -42,57 +173,81 @@ Unless documented otherwise, precedence is:
|
||||
3. configuration file
|
||||
4. built-in defaults
|
||||
|
||||
Prefer YAML configuration unless the project has a strong reason to use another format. Config files should be discovered at `/usr/local/etc/<app_name>/config.yml`, with a CLI override via `--config`.
|
||||
Prefer YAML configuration unless the project has a strong reason to use another
|
||||
format. Config files should be discoverable at
|
||||
`/usr/local/etc/notarius/config.yml`, with a CLI override via `--config`.
|
||||
|
||||
Configuration files should not contain raw secrets unless the application is explicitly designed for that. Prefer environment variables or secret files for secrets.
|
||||
Configuration files should not contain raw secrets unless the application is
|
||||
explicitly designed for that. Prefer environment variables or secret files for
|
||||
secrets.
|
||||
|
||||
## Adapters and External Integrations
|
||||
|
||||
Use a hexagonal architecture style for external integrations.
|
||||
|
||||
External adapters belong under `internal/adapters/<name>`. If an adapter uses an external dependency, that dependency’s interface must not leak outside the adapter package. Other packages should interact only with the adapter’s API, so the dependency can be swapped, upgraded, or removed without touching unrelated code.
|
||||
|
||||
Adapters should be thin. Domain decisions belong in application/domain packages, not inside adapter glue.
|
||||
|
||||
## Modules, Stages, and Registries
|
||||
|
||||
When the application has stages or modules, each major stage/module should live in its own package and have an explicit input/output contract.
|
||||
|
||||
The orchestrator should be able to compose, skip, resume, or run individual stages/modules when their prerequisites are satisfied. Ordering should be explicit: use a default sequence, dependency graph, or documented orchestration rule.
|
||||
|
||||
If users can select modules, stages, validators, renderers, or adapters, selection should go through a registry or equivalent mechanism rather than scattered conditionals.
|
||||
Adapter-specific and extractor-specific configuration should remain grouped by
|
||||
the adapter or extractor that owns it.
|
||||
|
||||
## Embedded Assets
|
||||
|
||||
Store embedded JSON schemas, Markdown prompts, templates, and similar assets as separate files, not inline string literals, unless there is a strong reason otherwise.
|
||||
Store embedded JSON schemas, Markdown prompts, templates, and similar assets as
|
||||
separate files, not inline string literals, unless there is a strong reason
|
||||
otherwise.
|
||||
|
||||
Embedded prompts and response schemas should have stable IDs, versions, source
|
||||
metadata, and hashes suitable for diagnostics and run manifests.
|
||||
|
||||
## Errors and Logging
|
||||
|
||||
Errors should be actionable and preserve context. Wrap errors with operation and path/resource context. CLI code should convert internal errors into concise user-facing messages.
|
||||
Errors should be actionable and preserve context. Wrap errors with operation and
|
||||
path/resource context. CLI code should convert internal errors into concise
|
||||
user-facing messages.
|
||||
|
||||
Errors and logs must not expose secrets.
|
||||
|
||||
Use structured logging where practical. Logs should describe operations, paths, external calls, retries, and failure causes, but should not include large user data by default.
|
||||
Use structured logging where practical. Logs should describe operations, paths,
|
||||
external calls, retries, and failure causes, but should not include large source
|
||||
or artifact payloads by default.
|
||||
|
||||
## Context, Timeouts, and Cancellation
|
||||
|
||||
Long-running operations should accept `context.Context`. External calls, subprocesses, HTTP requests, storage operations, and multi-stage workflows should respect cancellation and timeouts.
|
||||
Long-running operations should accept `context.Context`. External calls,
|
||||
subprocesses, HTTP requests, storage operations, LLM calls, and multi-stage
|
||||
workflows should respect cancellation and timeouts.
|
||||
|
||||
## State, Files, and Safety
|
||||
|
||||
If the application writes durable state, writes should be atomic where practical. Multi-step workflows should preserve enough state to support inspection, retry, or resume after failure.
|
||||
If the application writes durable state, writes should be atomic where
|
||||
practical. Multi-step workflows should preserve enough state to support
|
||||
inspection, retry, or resume after failure.
|
||||
|
||||
Code that deletes, moves, or overwrites files must use narrow, explicit paths. Avoid broad parent-directory operations. Cleanup that can cause data loss must be opt-in.
|
||||
Code that deletes, moves, or overwrites files must use narrow, explicit paths.
|
||||
Avoid broad parent-directory operations. Cleanup that can cause data loss must
|
||||
be opt-in.
|
||||
|
||||
## Testing
|
||||
|
||||
Core logic should be testable without real external services. Use fakes, fixtures, or local test doubles for adapters where practical.
|
||||
Core logic should be testable without real external services. Use fakes,
|
||||
fixtures, or local test doubles for adapters, extractors, validators, and LLM
|
||||
clients where practical.
|
||||
|
||||
Config examples should be load-tested. Important CLI workflows should have parser or command tests. Stage/module contracts should have focused tests that do not require running the full application unless end-to-end coverage is intentional.
|
||||
Contract-first work should include fake implementations that prove interfaces
|
||||
compose before real adapters or extractors depend on them.
|
||||
|
||||
Config examples should be load-tested once config files exist. Important CLI
|
||||
workflows should have parser or command tests. Adapter, extractor, and validator
|
||||
contracts should have focused tests that do not require running the full
|
||||
application unless end-to-end coverage is intentional.
|
||||
|
||||
## Documentation
|
||||
|
||||
Documentation should follow the project documentation policy. Keep user docs focused on implemented behavior. Put future, planned, or aspirational work only under `docs/roadmap/`.
|
||||
Documentation should follow the project documentation policy. Keep user docs
|
||||
focused on implemented behavior. Put future, planned, or aspirational work only
|
||||
under `docs/roadmap/`.
|
||||
|
||||
When changing architecture, config, CLI behavior, adapters, or stage/module contracts, update the relevant docs and examples in the same change.
|
||||
Core documentation should use generic terms such as source document, source
|
||||
unit, source reference, input adapter, extractor, artifact, validator, and run
|
||||
manifest.
|
||||
|
||||
Source-format details belong in adapter or integration docs. Domain-specific
|
||||
extraction details belong in extractor or artifact docs.
|
||||
|
||||
When changing architecture, config, CLI behavior, adapters, extractor contracts,
|
||||
validator contracts, LLM runtime behavior, or artifact schemas, update the
|
||||
relevant docs and examples in the same change.
|
||||
|
||||
123
docs/roadmap/1-core-contracts-and-skeleton.md
Normal file
123
docs/roadmap/1-core-contracts-and-skeleton.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# Checkpoint 1: Core Contracts And Skeleton
|
||||
|
||||
## Status
|
||||
|
||||
This document describes planned work, not implemented behavior.
|
||||
|
||||
## Goal
|
||||
|
||||
Define the stable vocabulary and core interfaces that adapters, extractors,
|
||||
validators, and runners will build against.
|
||||
|
||||
This checkpoint should produce a compileable Go repository with a minimal CLI
|
||||
shell and contract-level tests. It does not need to process real input or
|
||||
produce useful artifacts.
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- Go module bootstrap;
|
||||
- executable entrypoint;
|
||||
- minimal CLI package;
|
||||
- core source, artifact, manifest, and contract types;
|
||||
- fake implementation tests proving the interfaces are usable.
|
||||
|
||||
Out of scope:
|
||||
|
||||
- real input adapters;
|
||||
- real extractors;
|
||||
- LLM provider calls;
|
||||
- prompt or response-schema assets;
|
||||
- diagnostics run directory;
|
||||
- production config loading.
|
||||
|
||||
## Proposed Stages
|
||||
|
||||
### Stage 1: Bootstrap Go Project
|
||||
|
||||
Create:
|
||||
|
||||
- `go.mod`;
|
||||
- `cmd/notarius/main.go`;
|
||||
- `internal/cli`;
|
||||
- a minimal CLI command surface that compiles.
|
||||
|
||||
Expected validation:
|
||||
|
||||
```sh
|
||||
go test ./...
|
||||
go build ./cmd/notarius
|
||||
```
|
||||
|
||||
### Stage 2: Source Core Types
|
||||
|
||||
Create `internal/core/source`.
|
||||
|
||||
Initial types:
|
||||
|
||||
- `SourceDocument`;
|
||||
- `SourceUnit`;
|
||||
- `SourceRef`;
|
||||
- source validation helpers for document ID, ordered units, unique unit IDs, and
|
||||
non-empty text.
|
||||
|
||||
Keep the model generic. Do not introduce transcript-specific field names into
|
||||
core source types.
|
||||
|
||||
### Stage 3: Artifact Core Types
|
||||
|
||||
Create `internal/core/artifacts`.
|
||||
|
||||
Initial types:
|
||||
|
||||
- artifact candidate;
|
||||
- approved artifact envelope;
|
||||
- rejected artifact record;
|
||||
- run manifest;
|
||||
- source-reference-bearing helper interfaces or conventions if useful.
|
||||
|
||||
Keep the artifact model extractor-neutral. D&D-specific fields should wait until
|
||||
the D&D spells extractor checkpoint.
|
||||
|
||||
### Stage 4: Framework Contract Types
|
||||
|
||||
Create `internal/framework/contracts`.
|
||||
|
||||
Initial contracts:
|
||||
|
||||
- `InputAdapter`;
|
||||
- `Extractor`;
|
||||
- `Validator`;
|
||||
- structured LLM client interface placeholder;
|
||||
- parse, extraction, and validation request/response types.
|
||||
|
||||
Interfaces should be small and should depend on core source/artifact types, not
|
||||
on concrete adapter or extractor packages.
|
||||
|
||||
### Stage 5: Contract Tests With Fakes
|
||||
|
||||
Add tests using fake adapter, extractor, and validator implementations.
|
||||
|
||||
These tests should prove:
|
||||
|
||||
- fake components can satisfy the interfaces;
|
||||
- source documents can flow into extraction requests;
|
||||
- artifact candidates can flow into validation requests;
|
||||
- the contracts are not forcing transcript or D&D assumptions.
|
||||
|
||||
## Done Criteria
|
||||
|
||||
- `go test ./...` passes.
|
||||
- `go build ./cmd/notarius` passes.
|
||||
- Core types and contracts exist in stable package locations.
|
||||
- Tests prove fake implementations can compose at the type-contract level.
|
||||
- No real Seriatim, D&D, LLM, or Audita-specific behavior has been added yet.
|
||||
|
||||
## Review Questions
|
||||
|
||||
- Are the interfaces small enough?
|
||||
- Are source-format details absent from core packages?
|
||||
- Are D&D concepts absent from framework and core packages?
|
||||
- Is the shell compileable without placeholder behavior that will be hard to
|
||||
unwind?
|
||||
108
docs/roadmap/2-framework-composition.md
Normal file
108
docs/roadmap/2-framework-composition.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Checkpoint 2: Framework Composition
|
||||
|
||||
## Status
|
||||
|
||||
This document describes planned work, not implemented behavior.
|
||||
|
||||
## Goal
|
||||
|
||||
Prove the core contracts compose before adding real adapters, real extractors,
|
||||
or portable Audita infrastructure.
|
||||
|
||||
This checkpoint should produce a minimal runner that can execute fake registered
|
||||
components from source input to artifact output in tests.
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- input adapter registry;
|
||||
- extractor registry;
|
||||
- validator decision model;
|
||||
- decision-cardinality checks;
|
||||
- minimal runner;
|
||||
- fake-component runner tests.
|
||||
|
||||
Out of scope:
|
||||
|
||||
- real input parsing;
|
||||
- real LLM calls;
|
||||
- prompt assets;
|
||||
- response schema assets;
|
||||
- diagnostics run directory;
|
||||
- real D&D artifact schemas.
|
||||
|
||||
## Proposed Stages
|
||||
|
||||
### Stage 1: Input Adapter Registry
|
||||
|
||||
Add a registry for `InputAdapter` constructors or instances.
|
||||
|
||||
The registry should:
|
||||
|
||||
- reject empty keys;
|
||||
- reject duplicate registrations;
|
||||
- return clear errors for unknown keys;
|
||||
- avoid importing concrete adapter packages from core contracts.
|
||||
|
||||
### Stage 2: Extractor Registry
|
||||
|
||||
Add a registry for extractor constructors or instances.
|
||||
|
||||
The registry should:
|
||||
|
||||
- support stable extractor keys;
|
||||
- support repeated extractor instances if needed later;
|
||||
- return clear errors for unknown keys;
|
||||
- avoid domain-specific logic.
|
||||
|
||||
### Stage 3: Validator Decisions
|
||||
|
||||
Add validator decision types and cardinality checks.
|
||||
|
||||
Each validator should return exactly one decision for each candidate artifact it
|
||||
receives.
|
||||
|
||||
Decision fields should include:
|
||||
|
||||
- candidate index;
|
||||
- approved flag;
|
||||
- reason code;
|
||||
- message;
|
||||
- optional diagnostics path.
|
||||
|
||||
### Stage 4: Minimal Runner
|
||||
|
||||
Add a runner that can:
|
||||
|
||||
1. receive a `SourceDocument`;
|
||||
2. execute configured extractors;
|
||||
3. validate candidate artifacts;
|
||||
4. return approved and rejected artifacts.
|
||||
|
||||
Keep source chunking optional or stubbed at this checkpoint. The runner may
|
||||
operate on whole documents only until source-unit chunking is added later.
|
||||
|
||||
### Stage 5: Runner Tests With Fakes
|
||||
|
||||
Add tests with fake components that prove:
|
||||
|
||||
- registered fake extractors run in configured order;
|
||||
- validators filter candidates deterministically;
|
||||
- decision cardinality failures are surfaced;
|
||||
- approved and rejected artifacts are returned in stable order.
|
||||
|
||||
## Done Criteria
|
||||
|
||||
- `go test ./...` passes.
|
||||
- Fake adapter/extractor/validator registrations work in tests.
|
||||
- The runner operates on `SourceDocument`, not transcript-specific structures.
|
||||
- The runner does not import concrete D&D extractor packages.
|
||||
|
||||
## Review Questions
|
||||
|
||||
- Does the runner know only about sources, extractors, validators, and artifacts?
|
||||
- Are registries simple enough to evolve?
|
||||
- Are validation decisions expressive enough for deterministic and LLM-backed
|
||||
validators?
|
||||
- Is any domain-specific behavior creeping into framework packages?
|
||||
122
docs/roadmap/3-portable-audita-infrastructure.md
Normal file
122
docs/roadmap/3-portable-audita-infrastructure.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# Checkpoint 3: Portable Audita Infrastructure
|
||||
|
||||
## Status
|
||||
|
||||
This document describes planned work, not implemented behavior.
|
||||
|
||||
## Goal
|
||||
|
||||
Port or adapt reusable Audita infrastructure that directly supports Notarius
|
||||
contracts while avoiding Audita's transcript-correction model.
|
||||
|
||||
This checkpoint should add reusable runtime plumbing, not real extraction
|
||||
behavior.
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- structured LLM client interface implementation;
|
||||
- LLM scheduler;
|
||||
- prompt registry pattern;
|
||||
- response-schema registry pattern;
|
||||
- diagnostics run directory pattern;
|
||||
- minimal config structs and defaults for implemented runtime pieces.
|
||||
|
||||
Out of scope:
|
||||
|
||||
- correction proposals;
|
||||
- replacement policies;
|
||||
- transcript mutation;
|
||||
- correction ledger terminology;
|
||||
- Audita module or validator behavior;
|
||||
- real D&D prompts or schemas unless needed as inert registry tests.
|
||||
|
||||
## Proposed Stages
|
||||
|
||||
### Stage 1: LLM Runtime
|
||||
|
||||
Port or adapt the OpenAI-compatible structured-output client and scheduler.
|
||||
|
||||
Keep the contract transport-neutral:
|
||||
|
||||
- framework code should depend on a `StructuredLLMClient` interface;
|
||||
- provider-specific HTTP details should remain in the LLM runtime package;
|
||||
- errors must redact configured secrets.
|
||||
|
||||
### Stage 2: Response Schema Registry
|
||||
|
||||
Port or adapt the embedded JSON response-schema registry pattern.
|
||||
|
||||
The registry should track:
|
||||
|
||||
- schema key;
|
||||
- schema ID;
|
||||
- schema version;
|
||||
- schema name;
|
||||
- JSON schema content;
|
||||
- schema hash.
|
||||
|
||||
Use placeholder or test schemas if real extractor schemas are not ready.
|
||||
|
||||
### Stage 3: Prompt Registry
|
||||
|
||||
Port or adapt the embedded prompt registry pattern.
|
||||
|
||||
The registry should track:
|
||||
|
||||
- prompt ID;
|
||||
- prompt version;
|
||||
- prompt source;
|
||||
- embedded path;
|
||||
- prompt hash.
|
||||
|
||||
Do not add D&D prompt assets here unless the implementation naturally overlaps
|
||||
with checkpoint 5. Test prompts are acceptable for registry tests.
|
||||
|
||||
### Stage 4: Diagnostics Run Directory
|
||||
|
||||
Port or adapt the diagnostics run directory pattern.
|
||||
|
||||
Initial diagnostics should cover:
|
||||
|
||||
- invocation metadata;
|
||||
- redacted effective config;
|
||||
- source document artifact;
|
||||
- run report placeholder;
|
||||
- error log on failure.
|
||||
|
||||
Avoid Audita-specific artifact names such as correction ledger.
|
||||
|
||||
### Stage 5: Minimal Runtime Config
|
||||
|
||||
Add config structs and defaults only for infrastructure that now exists.
|
||||
|
||||
Initial config areas:
|
||||
|
||||
- input adapter key;
|
||||
- extractor keys;
|
||||
- primary LLM settings;
|
||||
- validation LLM settings if needed;
|
||||
- concurrency;
|
||||
- work directory;
|
||||
- diagnostics retention.
|
||||
|
||||
Config loading can remain minimal unless the implementation needs full file/env
|
||||
precedence at this checkpoint.
|
||||
|
||||
## Done Criteria
|
||||
|
||||
- `go test ./...` passes.
|
||||
- Audita runtime pieces are adapted to Notarius package names and contracts.
|
||||
- No correction proposal, replacement policy, transcript mutation, or correction
|
||||
ledger code has been copied.
|
||||
- Runtime tests cover secret redaction, schema registry lookup, prompt metadata,
|
||||
and scheduler behavior where applicable.
|
||||
|
||||
## Review Questions
|
||||
|
||||
- Did we copy only reusable infrastructure?
|
||||
- Do provider-specific types stay behind adapter/runtime boundaries?
|
||||
- Are diagnostics names and report concepts extraction-oriented?
|
||||
- Is config limited to implemented behavior?
|
||||
116
docs/roadmap/4-seriatim-input-adapter.md
Normal file
116
docs/roadmap/4-seriatim-input-adapter.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# Checkpoint 4: Seriatim Input Adapter
|
||||
|
||||
## Status
|
||||
|
||||
This document describes planned work, not implemented behavior.
|
||||
|
||||
## Goal
|
||||
|
||||
Add the first real input source while keeping transcript-specific behavior
|
||||
isolated inside an input adapter.
|
||||
|
||||
This checkpoint should allow Seriatim minimal transcript JSON to become a
|
||||
generic `SourceDocument`.
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- `internal/adapters/input/seriatim`;
|
||||
- parser for Seriatim minimal output JSON;
|
||||
- mapping into `SourceDocument` and `SourceUnit`;
|
||||
- source-document validation;
|
||||
- adapter registry wiring;
|
||||
- fixtures and tests;
|
||||
- CLI/config path to select the adapter if the CLI shell exists.
|
||||
|
||||
Out of scope:
|
||||
|
||||
- D&D extraction;
|
||||
- LLM extraction calls;
|
||||
- transcript-specific behavior in runner/core packages;
|
||||
- support for every possible Seriatim schema variant.
|
||||
|
||||
## Proposed Stages
|
||||
|
||||
### Stage 1: Seriatim Source Model
|
||||
|
||||
Define adapter-local structs for the Seriatim minimal output schema.
|
||||
|
||||
Expected external shape:
|
||||
|
||||
- top-level `metadata`;
|
||||
- top-level `segments`;
|
||||
- segment `id`;
|
||||
- segment `start`;
|
||||
- segment `end`;
|
||||
- segment `speaker`;
|
||||
- segment `text`.
|
||||
|
||||
Keep these structs in the adapter package.
|
||||
|
||||
### Stage 2: Parse And Validate
|
||||
|
||||
Implement parser and validation behavior.
|
||||
|
||||
Validation should cover:
|
||||
|
||||
- valid JSON;
|
||||
- required metadata fields;
|
||||
- required segment fields;
|
||||
- unique segment IDs;
|
||||
- non-empty segment text;
|
||||
- valid start/end values as appropriate.
|
||||
|
||||
Prefer clear adapter-specific errors.
|
||||
|
||||
### Stage 3: Map To SourceDocument
|
||||
|
||||
Map Seriatim data into the generic source model:
|
||||
|
||||
- segment `id` becomes `SourceUnit.ID`;
|
||||
- segment `text` becomes `SourceUnit.Text`;
|
||||
- unit kind should identify transcript-like units without requiring core
|
||||
packages to know transcript semantics;
|
||||
- `speaker`, `start`, and `end` become unit metadata;
|
||||
- Seriatim metadata becomes document metadata.
|
||||
|
||||
The resulting `SourceDocument` should pass core source validation.
|
||||
|
||||
### Stage 4: Registry And CLI Wiring
|
||||
|
||||
Register the adapter under a stable key, likely `seriatim`.
|
||||
|
||||
If CLI support exists, add provisional selection:
|
||||
|
||||
```sh
|
||||
notarius extract ./transcript.json --input seriatim
|
||||
```
|
||||
|
||||
The command may still use fake extractors until checkpoint 5.
|
||||
|
||||
### Stage 5: Fixtures And Tests
|
||||
|
||||
Add fixtures and tests for:
|
||||
|
||||
- valid Seriatim minimal transcript;
|
||||
- malformed JSON;
|
||||
- missing metadata;
|
||||
- missing or duplicate segment IDs;
|
||||
- empty segment text;
|
||||
- source-reference compatibility with generated unit IDs.
|
||||
|
||||
## Done Criteria
|
||||
|
||||
- `go test ./...` passes.
|
||||
- Seriatim minimal transcript JSON maps into `SourceDocument`.
|
||||
- Transcript fields do not appear in core runner contracts.
|
||||
- The adapter is selectable through the registry.
|
||||
- Tests prove transcript-specific assumptions are isolated to the adapter.
|
||||
|
||||
## Review Questions
|
||||
|
||||
- Are segment, speaker, and timestamp assumptions contained inside the adapter?
|
||||
- Are unit IDs stable and suitable for source references?
|
||||
- Does the adapter preserve enough metadata for transcript-oriented output later?
|
||||
- Should the adapter accept only Seriatim minimal output for now?
|
||||
131
docs/roadmap/5-dnd-spells-extractor.md
Normal file
131
docs/roadmap/5-dnd-spells-extractor.md
Normal file
@@ -0,0 +1,131 @@
|
||||
# Checkpoint 5: D&D Spells Extractor
|
||||
|
||||
## Status
|
||||
|
||||
This document describes planned work, not implemented behavior.
|
||||
|
||||
## Goal
|
||||
|
||||
Implement the first useful extraction module: D&D spell casts from a Seriatim
|
||||
transcript source document.
|
||||
|
||||
This checkpoint should produce the first meaningful vertical slice from real
|
||||
source input to validated artifact output.
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- D&D spell artifact schema and Go structs;
|
||||
- structured response schema asset;
|
||||
- prompt assets;
|
||||
- `internal/extractors/dnd/spells`;
|
||||
- source-reference and schema validators in the extractor chain;
|
||||
- fake LLM tests;
|
||||
- CLI-level integration test if the CLI path is ready.
|
||||
|
||||
Out of scope:
|
||||
|
||||
- D&D item extraction;
|
||||
- NPC extraction;
|
||||
- combat extraction;
|
||||
- cross-slice deduplication beyond simple deterministic merging;
|
||||
- broad D&D rules validation.
|
||||
|
||||
## Proposed Stages
|
||||
|
||||
### Stage 1: Spell Artifact Schema
|
||||
|
||||
Define the D&D spell artifact model.
|
||||
|
||||
Initial shape:
|
||||
|
||||
```go
|
||||
type SpellCast struct {
|
||||
Player string `json:"player"`
|
||||
Spell string `json:"spell"`
|
||||
Effect string `json:"effect"`
|
||||
NarrativeDescription string `json:"narrative_description"`
|
||||
SourceRefs []SourceRef `json:"source_refs"`
|
||||
}
|
||||
```
|
||||
|
||||
Keep this schema inside the D&D spells extractor or a D&D artifact package, not
|
||||
inside core framework packages.
|
||||
|
||||
### Stage 2: Structured Response Schema
|
||||
|
||||
Add a structured response schema asset for spell extraction.
|
||||
|
||||
The schema should require:
|
||||
|
||||
- spell-cast array;
|
||||
- non-empty player, spell, effect, and narrative description fields;
|
||||
- at least one source reference per spell cast.
|
||||
|
||||
### Stage 3: Prompt Assets
|
||||
|
||||
Add embedded prompt assets for D&D spell extraction.
|
||||
|
||||
Prompts should:
|
||||
|
||||
- describe the generic source-unit input format;
|
||||
- explain that source references must use source-unit IDs;
|
||||
- avoid relying on transcript-specific fields except as optional metadata;
|
||||
- request only spell-cast artifacts.
|
||||
|
||||
### Stage 4: Extractor Implementation
|
||||
|
||||
Implement `internal/extractors/dnd/spells`.
|
||||
|
||||
The extractor should:
|
||||
|
||||
- satisfy the framework `Extractor` contract;
|
||||
- build LLM messages from a source document or source slice;
|
||||
- call the structured LLM client;
|
||||
- return artifact candidates with source references;
|
||||
- attach its validator chain.
|
||||
|
||||
### Stage 5: Validators And Tests
|
||||
|
||||
Wire deterministic validators:
|
||||
|
||||
- schema/shape validation;
|
||||
- source-reference validation;
|
||||
- required-field validation if not covered by schema handling.
|
||||
|
||||
Add tests using a fake structured LLM client:
|
||||
|
||||
- successful spell extraction;
|
||||
- empty result;
|
||||
- invalid source reference rejection;
|
||||
- malformed structured output handling;
|
||||
- stable output ordering.
|
||||
|
||||
### Stage 6: CLI Integration
|
||||
|
||||
If the CLI path is ready, add an end-to-end test using:
|
||||
|
||||
```sh
|
||||
notarius extract ./transcript.json --input seriatim --extractors dnd.spells --output ./artifacts.json
|
||||
```
|
||||
|
||||
The test should use fake LLM wiring and fixture input.
|
||||
|
||||
## Done Criteria
|
||||
|
||||
- `go test ./...` passes.
|
||||
- Seriatim input can flow through the runner into the D&D spells extractor.
|
||||
- Spell artifacts include valid source references.
|
||||
- D&D concepts are contained in extractor/artifact packages and docs.
|
||||
- The first meaningful vertical slice is available through tests, and through
|
||||
CLI if the CLI path is ready.
|
||||
|
||||
## Review Questions
|
||||
|
||||
- Is the spell extractor domain-specific without making the framework
|
||||
D&D-specific?
|
||||
- Are source references valid and useful for downstream validation?
|
||||
- Is prompt/schema ownership clear?
|
||||
- Does this vertical slice reveal contract changes needed before adding items,
|
||||
NPCs, or combat?
|
||||
174
docs/roadmap/documentation.md
Normal file
174
docs/roadmap/documentation.md
Normal file
@@ -0,0 +1,174 @@
|
||||
# Documentation Roadmap
|
||||
|
||||
## Status
|
||||
|
||||
This document captures planned documentation decisions for Notarius. It records
|
||||
policy choices while the application architecture is still being shaped. It does
|
||||
not describe implemented behavior.
|
||||
|
||||
## Documentation Goals
|
||||
|
||||
Notarius documentation should make three boundaries obvious:
|
||||
|
||||
- source-format support belongs to input adapters;
|
||||
- extraction-domain behavior belongs to extractor packages;
|
||||
- core framework behavior is source-agnostic and domain-agnostic.
|
||||
|
||||
Documentation should avoid making the MVP look more transcript-specific or
|
||||
D&D-specific than the architecture intends.
|
||||
|
||||
## Current Policy Decisions
|
||||
|
||||
### Planned Work Stays In Roadmap Docs
|
||||
|
||||
Until code exists, planned behavior belongs under `docs/roadmap/`.
|
||||
|
||||
Implemented behavior should later move into canonical docs. Roadmap files may
|
||||
then link to those docs or be reduced to remaining future work.
|
||||
|
||||
### Core Docs Should Use Generic Terms
|
||||
|
||||
Core architecture docs should prefer:
|
||||
|
||||
- source document;
|
||||
- source unit;
|
||||
- source reference;
|
||||
- input adapter;
|
||||
- extractor;
|
||||
- artifact;
|
||||
- validator;
|
||||
- run manifest.
|
||||
|
||||
Core docs should avoid transcript-specific terms such as segment, speaker,
|
||||
timestamp, and transcript range unless discussing an input adapter or an example.
|
||||
|
||||
Core docs should avoid D&D-specific terms such as spell, NPC, item, combat, and
|
||||
encounter unless discussing extractor packages or examples.
|
||||
|
||||
### Adapter Docs Own Source Formats
|
||||
|
||||
Each implemented input adapter should have a canonical integration document.
|
||||
|
||||
Likely future files:
|
||||
|
||||
```text
|
||||
docs/integrations/seriatim-transcript.md
|
||||
docs/integrations/markdown-source.md
|
||||
```
|
||||
|
||||
Adapter docs should cover:
|
||||
|
||||
- accepted external schema or file shape;
|
||||
- mapping into `SourceDocument` and `SourceUnit`;
|
||||
- metadata preserved by the adapter;
|
||||
- validation rules and failure behavior;
|
||||
- examples.
|
||||
|
||||
The Seriatim adapter doc should reference the Seriatim schema it supports and
|
||||
explain how transcript segment IDs become source-unit IDs.
|
||||
|
||||
### Extractor Docs Own Domains
|
||||
|
||||
Each implemented extractor family should have canonical internal or integration
|
||||
docs.
|
||||
|
||||
Likely future files:
|
||||
|
||||
```text
|
||||
docs/internal/extractors.md
|
||||
docs/integrations/artifacts-dnd.md
|
||||
```
|
||||
|
||||
Extractor docs should cover:
|
||||
|
||||
- extractor key;
|
||||
- artifact type;
|
||||
- schema version;
|
||||
- required source-reference behavior;
|
||||
- validator chain;
|
||||
- prompt and response-schema ownership;
|
||||
- examples.
|
||||
|
||||
D&D concepts should be documented in D&D extractor docs, not in generic runner
|
||||
or framework docs.
|
||||
|
||||
### CLI Docs Should Reflect Extensibility
|
||||
|
||||
The CLI reference should present input adapters and extractors as selectable
|
||||
components.
|
||||
|
||||
Provisional command shape:
|
||||
|
||||
```sh
|
||||
notarius extract ./source.json --input seriatim --extractors dnd.spells --output ./artifacts.json
|
||||
```
|
||||
|
||||
Once implemented, `docs/cli.md` should document:
|
||||
|
||||
- positional source input path;
|
||||
- input adapter selection;
|
||||
- extractor selection;
|
||||
- config path behavior;
|
||||
- output path behavior;
|
||||
- diagnostics and report behavior;
|
||||
- exit codes.
|
||||
|
||||
### Config Docs Should Separate Framework And Plugin-Like Options
|
||||
|
||||
`docs/config.md` should group fields by responsibility:
|
||||
|
||||
- input adapter selection and adapter-specific options;
|
||||
- extractor selection and extractor-specific options;
|
||||
- LLM runtime;
|
||||
- validation runtime;
|
||||
- source chunking;
|
||||
- output and diagnostics.
|
||||
|
||||
Adapter-specific and extractor-specific config should not leak into unrelated
|
||||
core config sections.
|
||||
|
||||
### Examples Should Stay Real
|
||||
|
||||
Examples should be added only when the matching behavior exists and should be
|
||||
covered by tests where practical.
|
||||
|
||||
Likely future examples:
|
||||
|
||||
```text
|
||||
examples/seriatim-minimal-transcript.json
|
||||
examples/minimal-config.yml
|
||||
examples/dnd-spells.artifacts.json
|
||||
```
|
||||
|
||||
Examples should be secret-free and should use the same command shapes documented
|
||||
in `docs/cli.md`.
|
||||
|
||||
## Canonical Documentation Targets
|
||||
|
||||
When the first vertical slice is implemented, add or update:
|
||||
|
||||
- `README.md`: concise purpose, shortest useful command, links.
|
||||
- `docs/cli.md`: implemented command behavior.
|
||||
- `docs/config.md`: implemented config behavior.
|
||||
- `docs/operations.md`: diagnostics, retention, failure inspection.
|
||||
- `docs/troubleshooting.md`: common failures.
|
||||
- `docs/internal/overview.md`: implemented package map.
|
||||
- `docs/internal/pipeline.md`: implemented extraction flow.
|
||||
- `docs/internal/adapters.md`: adapter contract and implemented adapters.
|
||||
- `docs/internal/extractors.md`: extractor contract and built-ins.
|
||||
- `docs/internal/validators.md`: validator contract and built-ins.
|
||||
- `docs/integrations/seriatim-transcript.md`: Seriatim input contract.
|
||||
- `docs/integrations/artifacts.md`: output artifact envelope.
|
||||
|
||||
## Review Checklist For Future Documentation Changes
|
||||
|
||||
Before merging docs, check:
|
||||
|
||||
- Does the document describe implemented behavior outside `docs/roadmap/`?
|
||||
- Are source-format details isolated to adapter docs?
|
||||
- Are D&D details isolated to extractor or artifact docs?
|
||||
- Is there one canonical home for the topic?
|
||||
- Do command examples match implemented CLI syntax?
|
||||
- Are examples valid, maintained, and free of secrets?
|
||||
- Did any architecture, config, CLI, adapter, extractor, validator, or artifact
|
||||
contract change require a docs update?
|
||||
407
docs/roadmap/initial-architecture.md
Normal file
407
docs/roadmap/initial-architecture.md
Normal file
@@ -0,0 +1,407 @@
|
||||
# Initial Architecture Roadmap
|
||||
|
||||
## Status
|
||||
|
||||
This document captures proposed architecture and implementation sequencing for
|
||||
Notarius. It describes planned work, not implemented behavior.
|
||||
|
||||
## Goal
|
||||
|
||||
Notarius should extract structured JSON artifacts from primary source inputs
|
||||
using modular, LLM-backed extractors.
|
||||
|
||||
The first MVP should target audio transcripts generated by Seriatim. That
|
||||
choice should be implemented as an input adapter, not as a transcript-specific
|
||||
assumption in the application core. Later input sources, such as unstructured
|
||||
Markdown notes or Obsidian documents, should be addable through new adapters and
|
||||
extractors without reshaping the framework.
|
||||
|
||||
The first extraction domain should be D&D session analysis, starting with spell
|
||||
casts. That domain should live in extractor packages and related schemas, not in
|
||||
core framework packages.
|
||||
|
||||
The application should follow the same broad architecture as Audita:
|
||||
|
||||
- deterministic core packages for config, source documents, artifacts, diagnostics, and reporting;
|
||||
- input adapters that translate external source formats into a small internal source model;
|
||||
- reusable framework packages for contracts, orchestration, LLM runtime, structured output, and validation;
|
||||
- independent extractor packages that own domain-specific behavior;
|
||||
- independent validator packages;
|
||||
- embedded prompt and JSON schema assets;
|
||||
- CLI orchestration that wires the pieces together without owning domain logic.
|
||||
|
||||
The main domain difference from Audita is that Notarius emits extracted
|
||||
artifacts rather than proposing and applying transcript corrections.
|
||||
|
||||
## Architectural Principles
|
||||
|
||||
- Keep the core input model generic: ordered text units plus metadata.
|
||||
- Keep source-format details in hexagonal input adapters.
|
||||
- Keep extraction-domain details in extractor packages.
|
||||
- Treat evidence as source references, not transcript references.
|
||||
- Prefer narrow, useful abstractions over a universal document model.
|
||||
- Preserve enough provenance for validation, replay, and downstream inspection.
|
||||
|
||||
## Proposed Package Shape
|
||||
|
||||
```text
|
||||
cmd/notarius
|
||||
internal/cli
|
||||
|
||||
internal/core/config
|
||||
internal/core/source
|
||||
internal/core/sourcechunking
|
||||
internal/core/artifacts
|
||||
internal/core/diagnostics
|
||||
internal/core/reporting
|
||||
internal/core/extractorcatalog
|
||||
internal/core/inputcatalog
|
||||
|
||||
internal/adapters/input/seriatim
|
||||
internal/adapters/input/markdown
|
||||
|
||||
internal/framework/contracts
|
||||
internal/framework/extraction
|
||||
internal/framework/runner
|
||||
internal/framework/validators
|
||||
internal/framework/llm
|
||||
internal/framework/responseschema
|
||||
internal/framework/structuredoutput
|
||||
internal/framework/promptcontext
|
||||
internal/framework/warnings
|
||||
|
||||
internal/extractors/dnd/spells
|
||||
internal/extractors/dnd/items
|
||||
internal/extractors/dnd/npcs
|
||||
internal/extractors/dnd/combat
|
||||
|
||||
internal/validators/source_refs
|
||||
internal/validators/schema_validity
|
||||
internal/validators/domain_consistency
|
||||
internal/validators/llm_review
|
||||
|
||||
internal/prompts
|
||||
examples
|
||||
docs/internal
|
||||
```
|
||||
|
||||
The `markdown` adapter is listed as a likely future package. The MVP should only
|
||||
implement the Seriatim adapter unless a second adapter is needed to test the
|
||||
boundary.
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### SourceDocument
|
||||
|
||||
Canonical internal representation of source material. This should be the object
|
||||
extractors receive, regardless of whether the original input was a transcript,
|
||||
Markdown file, note export, or another source type.
|
||||
|
||||
```go
|
||||
type SourceDocument struct {
|
||||
ID string `json:"id"`
|
||||
Kind string `json:"kind"`
|
||||
Format string `json:"format"`
|
||||
Digest string `json:"digest"`
|
||||
Units []SourceUnit `json:"units"`
|
||||
Metadata map[string]any `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
type SourceUnit struct {
|
||||
ID string `json:"id"`
|
||||
Kind string `json:"kind"`
|
||||
Text string `json:"text"`
|
||||
Metadata map[string]any `json:"metadata,omitempty"`
|
||||
}
|
||||
```
|
||||
|
||||
Initial source-unit assumptions:
|
||||
|
||||
- units are ordered;
|
||||
- unit IDs are stable within a source document;
|
||||
- each unit has extractable text;
|
||||
- adapter-specific metadata may carry speaker, timestamps, heading paths, page
|
||||
numbers, or other source details.
|
||||
|
||||
### Input Adapter
|
||||
|
||||
Hexagonal boundary for external source formats.
|
||||
|
||||
```go
|
||||
type InputAdapter interface {
|
||||
Key() string
|
||||
Parse(ctx context.Context, req ParseRequest) (*source.SourceDocument, error)
|
||||
}
|
||||
```
|
||||
|
||||
The MVP adapter should target Seriatim minimal transcript JSON. Seriatim segment
|
||||
fields should map as follows:
|
||||
|
||||
- `id` becomes `SourceUnit.ID`;
|
||||
- `text` becomes `SourceUnit.Text`;
|
||||
- `speaker`, `start`, and `end` become unit metadata;
|
||||
- Seriatim output metadata becomes document metadata.
|
||||
|
||||
The core runner should not know that these units came from transcript segments.
|
||||
|
||||
### SourceRef
|
||||
|
||||
Grounding reference from an extracted fact back to source units.
|
||||
|
||||
```go
|
||||
type SourceRef struct {
|
||||
SourceID string `json:"source_id"`
|
||||
StartUnitID string `json:"start_unit_id"`
|
||||
EndUnitID string `json:"end_unit_id"`
|
||||
}
|
||||
```
|
||||
|
||||
Initial source-reference validation should require:
|
||||
|
||||
- source ID exists for the current run;
|
||||
- start and end unit IDs exist;
|
||||
- start is less than or equal to end in document order;
|
||||
- the referenced range is contiguous within the source document;
|
||||
- every extracted fact has at least one source reference unless its schema
|
||||
explicitly allows ungrounded metadata.
|
||||
|
||||
Transcript-oriented output can still present these as transcript segment ranges
|
||||
when the adapter metadata makes that interpretation available.
|
||||
|
||||
### Extractor
|
||||
|
||||
Reusable module contract for producing one artifact type.
|
||||
|
||||
```go
|
||||
type Extractor interface {
|
||||
Key() string
|
||||
ArtifactType() string
|
||||
SchemaVersion() string
|
||||
Validators() []Validator
|
||||
Extract(ctx context.Context, req ExtractionRequest) (ExtractionResult, error)
|
||||
}
|
||||
```
|
||||
|
||||
An extractor should receive either a whole source document or a source slice,
|
||||
depending on runner configuration. It should return typed artifact candidates
|
||||
plus warnings. It should not mutate the source document.
|
||||
|
||||
Extractor packages own domain concepts. For example, D&D spell extraction should
|
||||
live under `internal/extractors/dnd/spells`; a future to-do extractor for notes
|
||||
should live under a different domain path and use the same framework contract.
|
||||
|
||||
### Validator
|
||||
|
||||
Reusable validation contract for artifact candidates.
|
||||
|
||||
Validators should cover:
|
||||
|
||||
- JSON/schema validity;
|
||||
- source-reference validity;
|
||||
- required-field and shape checks;
|
||||
- domain consistency;
|
||||
- optional LLM review for high-risk or ambiguous artifacts.
|
||||
|
||||
Validator output should follow Audita's decision-cardinality model: each
|
||||
candidate artifact receives exactly one decision per validator.
|
||||
|
||||
### Artifact
|
||||
|
||||
Final approved JSON output from one or more extractors.
|
||||
|
||||
Artifacts should preserve enough metadata to support downstream validation,
|
||||
debugging, and replay. The exact top-level envelope is still open, but should
|
||||
include artifact type, schema version, extracted records, source references, and
|
||||
run manifest data.
|
||||
|
||||
### RunManifest
|
||||
|
||||
Per-run provenance record.
|
||||
|
||||
```go
|
||||
type RunManifest struct {
|
||||
InputAdapter string `json:"input_adapter"`
|
||||
SourceDigests []string `json:"source_digests"`
|
||||
Extractors []string `json:"extractors"`
|
||||
SchemaVersion string `json:"schema_version"`
|
||||
ValidationStatus string `json:"validation_status"`
|
||||
}
|
||||
```
|
||||
|
||||
The manifest should eventually include model names, prompt IDs, prompt hashes,
|
||||
response schema versions, config source, started/completed timestamps, and
|
||||
diagnostics paths.
|
||||
|
||||
## Initial Extractor Targets
|
||||
|
||||
### D&D Spells
|
||||
|
||||
Recommended first vertical slice because it is narrow but representative.
|
||||
|
||||
```go
|
||||
type SpellCast struct {
|
||||
Player string `json:"player"`
|
||||
Spell string `json:"spell"`
|
||||
Effect string `json:"effect"`
|
||||
NarrativeDescription string `json:"narrative_description"`
|
||||
SourceRefs []SourceRef `json:"source_refs"`
|
||||
}
|
||||
```
|
||||
|
||||
The spell extractor should be D&D-specific. The framework should not know what a
|
||||
spell is.
|
||||
|
||||
### D&D Items
|
||||
|
||||
Tracks items gained, lost, transferred, consumed, or transformed.
|
||||
|
||||
Open questions:
|
||||
|
||||
- Should currency be represented as items or as its own artifact type?
|
||||
- Should item ownership be a required field?
|
||||
- How should ambiguous ownership changes be represented?
|
||||
|
||||
### D&D NPCs
|
||||
|
||||
Tracks NPCs interacted with, newly introduced, renamed, described, or otherwise
|
||||
made relevant to campaign state.
|
||||
|
||||
Open questions:
|
||||
|
||||
- Should NPC identity resolution happen inside this extractor or in a later
|
||||
deduplication stage?
|
||||
- Should location/faction/relationship facts be separate artifact types?
|
||||
|
||||
### D&D Combat
|
||||
|
||||
Likely warrants a dedicated schema rather than a generic event list.
|
||||
|
||||
Proposed first shape:
|
||||
|
||||
```go
|
||||
type CombatTurn struct {
|
||||
Actor string `json:"actor"`
|
||||
Action string `json:"action"`
|
||||
Outcome string `json:"outcome"`
|
||||
NarrativeDescription string `json:"narrative_description"`
|
||||
SourceRefs []SourceRef `json:"source_refs"`
|
||||
}
|
||||
```
|
||||
|
||||
Open questions:
|
||||
|
||||
- Should combat be extracted as turns, rounds, encounters, or all three?
|
||||
- Should mechanical fields such as damage, conditions, saves, attacks, and spell
|
||||
slots be normalized immediately or added later?
|
||||
- How should uncertain initiative order be represented?
|
||||
|
||||
### Future Non-D&D Extractors
|
||||
|
||||
The architecture should support extractors outside the D&D domain. Examples:
|
||||
|
||||
- to-do items from Markdown or Obsidian notes;
|
||||
- decisions and action items from meeting transcripts;
|
||||
- named people, places, and dates from research notes.
|
||||
|
||||
These should be addable as extractor packages without changing runner,
|
||||
validator, source-reference, or LLM framework contracts.
|
||||
|
||||
## Proposed Runner Flow
|
||||
|
||||
1. Load effective config.
|
||||
2. Create diagnostics run directory.
|
||||
3. Resolve the configured input adapter.
|
||||
4. Read source input.
|
||||
5. Parse source input into a `SourceDocument`.
|
||||
6. Validate source-document invariants.
|
||||
7. Chunk source units into deterministic source slices.
|
||||
8. Resolve configured extractor instances through a registry.
|
||||
9. Execute extractor instances in configured order.
|
||||
10. Run deterministic validators before LLM-backed validators.
|
||||
11. Retain approved artifacts and rejected-artifact diagnostics.
|
||||
12. Merge approved slice artifacts deterministically.
|
||||
13. Serialize final output JSON.
|
||||
14. Write run manifest, diagnostics, and optional report JSON.
|
||||
|
||||
The runner should operate on source documents and source slices only. Any
|
||||
transcript-specific behavior should happen before the runner, inside the input
|
||||
adapter, or after the runner, inside output rendering that understands source
|
||||
metadata.
|
||||
|
||||
## Audita Patterns To Reuse
|
||||
|
||||
Reuse these architectural patterns:
|
||||
|
||||
- deterministic parsing and schema validation style;
|
||||
- deterministic chunking of ordered source units;
|
||||
- explicit extractor registry;
|
||||
- `contracts` package for transport-neutral interfaces;
|
||||
- OpenAI-compatible structured LLM client;
|
||||
- scheduler for bounded LLM concurrency;
|
||||
- embedded prompt registry with prompt metadata and hashes;
|
||||
- embedded response-schema registry with schema metadata and hashes;
|
||||
- diagnostics run directory with redacted effective config;
|
||||
- validator decision cardinality and deterministic validator ordering;
|
||||
- CLI tests and fixture-driven integration tests.
|
||||
|
||||
Avoid copying these Audita concepts directly:
|
||||
|
||||
- transcript-specific core types;
|
||||
- correction proposals;
|
||||
- replacement policies;
|
||||
- deterministic transcript mutation;
|
||||
- correction ledger terminology.
|
||||
|
||||
Those concepts are specific to Audita's transcript-editing role and should be
|
||||
replaced with source-document, artifact-candidate, artifact-validation, and
|
||||
extraction-report concepts.
|
||||
|
||||
## Checkpoint Roadmap
|
||||
|
||||
The initial implementation should proceed through five coherent checkpoints.
|
||||
Each checkpoint should leave the repository in a reviewable state, with the code
|
||||
compiling and targeted tests covering the newly introduced contracts or behavior.
|
||||
|
||||
1. [Core Contracts And Skeleton](1-core-contracts-and-skeleton.md)
|
||||
2. [Framework Composition](2-framework-composition.md)
|
||||
3. [Portable Audita Infrastructure](3-portable-audita-infrastructure.md)
|
||||
4. [Seriatim Input Adapter](4-seriatim-input-adapter.md)
|
||||
5. [D&D Spells Extractor](5-dnd-spells-extractor.md)
|
||||
|
||||
The first useful vertical slice should arrive at checkpoint 5: Seriatim
|
||||
transcript input to validated D&D spell artifact output. Earlier checkpoints are
|
||||
intentionally contract-first and may not produce useful user output yet.
|
||||
|
||||
## Open Design Questions
|
||||
|
||||
- Should final output be one combined artifact envelope or one file per
|
||||
extractor?
|
||||
- Should extractor output use typed Go structs per artifact or a generic
|
||||
artifact record with `json.RawMessage` payloads?
|
||||
- Should schemas be versioned per extractor, globally, or both?
|
||||
- Should every record require source references, or should some top-level
|
||||
artifact metadata be allowed without source references?
|
||||
- Should overlapping source-reference ranges be merged, preserved exactly, or
|
||||
both?
|
||||
- Should extraction run independently per source slice only, or should some
|
||||
extractors receive whole-document context?
|
||||
- Should a later reconciliation stage deduplicate entities and events across
|
||||
source slices?
|
||||
- Should LLM review be part of each extractor's validator chain or a separate
|
||||
review phase?
|
||||
- Should the Seriatim adapter accept only its minimal schema initially or also
|
||||
support richer transcript schemas?
|
||||
- Should source-unit metadata be untyped `map[string]any`, typed extension
|
||||
structs, or both?
|
||||
|
||||
## Near-Term Documentation Tasks
|
||||
|
||||
Once behavior is implemented, move implemented contracts out of roadmap docs and
|
||||
into canonical docs:
|
||||
|
||||
- `README.md` for purpose and shortest useful command;
|
||||
- `docs/cli.md` for CLI behavior;
|
||||
- `docs/config.md` for config fields and precedence;
|
||||
- `docs/internal/` for implemented architecture and package boundaries;
|
||||
- `docs/integrations/` for source input and artifact file formats;
|
||||
- `examples/` for maintained source, config, and artifact examples.
|
||||
Reference in New Issue
Block a user