Files
narratio/docs/internal/adapters.md

126 lines
5.8 KiB
Markdown

# Internal: Adapters
## Purpose
Explain the adapter interfaces and production composition used by application
and stage orchestration. Externally observable protocols and formats belong in
the [integration contracts](../integrations/).
## Adapter Boundaries
Narratio stage logic depends on adapter interfaces, not transport-specific details.
Primary adapters:
- `whisperx.Client`
- `seriatim.Runner`
- `audita.Runner`
- `scriptorium.Runner`
- `notarius.Runner`
- `storage.ObjectStore`
- `notify.Sender`
## Ownership
Adapters own:
- HTTP/subprocess/SDK argument and transport details.
- Backend-specific request/response mapping.
Adapters do not own:
- stage ordering/skip/force logic;
- manifest transitions;
- canonical path policy.
## Default Wiring
The application composes default adapters per invocation when they were not
injected through the stage environment, and only when the selected execution
plan needs them:
- WhisperX HTTP client for `transcribe`.
- Seriatim subprocess runner for `merge`, `normalize`, `trim`, or `render`.
- Audita subprocess runner for `polish`.
- Scriptorium subprocess runner for `trim` or `analyze`.
- Notarius subprocess runner for `extract` when extraction is enabled.
- Noop notifier (`notify.NoopSender`) for `notify`.
- Object store only when required by selected stages/config.
Remote publish locks are loaded only for a selected, enabled publish that
uploads a run. Shared session lifecycle setup still applies to every selected
range, but an unselected integration is neither initialized nor validated by
application-owned composition. Constructor, clock, randomness, remote-lock,
and post-publish deletion boundaries are scoped to the invocation; stages still
receive their collaborators through the stage environment. Each selected stage
retains its own fail-fast configuration and input validation.
`session plan` is outside production adapter composition. It performs
resume validation and models selected transitions against cloned manifest
state without constructing or invoking stage-execution adapters. The shared
command configuration loader may still use object storage to retrieve a missing
remote session file before planning begins.
Notarius is composed only when extraction is enabled; the extract stage owns
prepared reference resolution, receipt, bundle, and configured-lane policy.
The adapter validates the ordered selector/absolute-path pairs and is the sole
owner of serializing them as repeated `--reference` arguments before `--json`.
It also serializes an effective resume request as `--resume` and a nonempty
validated chunk mode as `--chunk_cache <mode>`. The extract stage, not the
adapter, resolves force precedence before constructing the request.
Its request may also carry already-resolved ConfigKit secret references.
Audita and Scriptorium requests carry the same kind of list. All three adapters use the shared
subprocess helper to convert their selected references into exact-name child
environment overrides and sensitive-name registration. That helper rejects
unresolved or empty programmatic references, but no adapter rereads the
parent environment or inspects downstream configuration to discover names.
Empty lists add no credential overrides. See the public [Audita](../integrations/audita.md)
[Notarius](../integrations/notarius.md), and [Scriptorium](../integrations/scriptorium.md) contracts for selection and
downstream-file boundaries.
Application-owned object-store construction loads configured filesystem
secrets before invoking the invocation's storage factory. Production commands
use the concrete storage adapter constructor; focused tests can supply an
in-memory backend without changing package state.
## Failure Semantics
- Constructor errors fail stage execution setup early.
- Runtime adapter errors propagate to stage code and then manifest failure handling.
- Subprocess adapters persist stage logs/generated configs through stage-managed paths.
- Shared subprocess execution keeps private lifecycle mechanics separate from
Narratio's environment, diagnostics, redaction, and error policy. It starts
an owned process group on Linux and macOS. Every terminal path disposes of
that owned tree before returning. After a natural leader exit, the runner checks
for remaining group members and uses bounded graceful then forceful termination.
Cancellation, deadlines, and
diagnostic limits use the same terminal disposal path without losing their
original result classification. Child environments contain only the execution
baseline and adapter-specified values; configured credentials are resolved
once by ConfigKit and passed explicitly as sensitive values. Adapters do not
re-read their named environment references. Stdout and stderr are redacted while streaming into separate
8 MiB diagnostic captures; a bounded wait closes a stream retained by a
departed leader's descendant. Unsupported platforms reject owned command
execution.
## Implementation And Tests
- Composition: `internal/app/runner_composition.go`,
`internal/app/runner_dependencies.go`, `internal/app/object_store.go`
- Shared subprocess mechanics: `internal/adapters/subprocess`
- Focused adapters: `internal/adapters/{whisperx,seriatim,audita,scriptorium,notarius,storage,notify}`
- `internal/adapters/whisperx/http_test.go`
- `internal/adapters/seriatim/subprocess_test.go`
- `internal/adapters/audita/subprocess_test.go`
- `internal/adapters/scriptorium/subprocess_test.go`
- `internal/adapters/notarius/subprocess_test.go`
- `internal/adapters/storage/*_test.go`
- `internal/app/runner_test.go`
See the [WhisperX](../integrations/whisperx.md),
[Seriatim](../integrations/seriatim.md), [Audita](../integrations/audita.md),
[Scriptorium](../integrations/scriptorium.md), and
[Notarius](../integrations/notarius.md) contracts before changing an
externally visible boundary. Operator-selected values belong in
[Configuration](../config.md).