146 lines
7.6 KiB
Markdown
146 lines
7.6 KiB
Markdown
# CLI Internals
|
|
|
|
This document describes **internal/cli**, Notarius's production composition
|
|
root. The [CLI reference](../cli.md) owns command syntax and exit statuses;
|
|
[Configuration](../config.md) owns configuration values; and
|
|
[Operations](../operations.md) owns filesystem layout, recovery, and operator
|
|
procedures.
|
|
|
|
## Inputs, Outputs, And Boundaries
|
|
|
|
The CLI accepts process arguments, standard streams, and injectable options
|
|
used by tests and embedding code. It writes command results to the supplied
|
|
streams and returns a process exit status. For a run, it also creates the
|
|
production catalog and runtime collaborators, hands a prepared pipeline and
|
|
source bytes to the framework, and places the logical files returned by the
|
|
runner.
|
|
|
|
It is the only boundary allowed to compose concrete registries, LLM clients,
|
|
cache/checkpoint collaborators, debug recorders, and physical output paths.
|
|
Pipeline modules receive interfaces and request data rather than CLI streams or
|
|
filesystem roots. The [Architecture](../policy/architecture.md) defines this
|
|
composition-root boundary; [Pipeline Internals](pipeline.md) owns resolution,
|
|
preparation, and runner mechanics after their inputs are supplied.
|
|
|
|
## Dispatch And Configuration Handoff
|
|
|
|
The root dispatcher handles help, configuration validation, pipeline listing,
|
|
and a pipeline run. It normalizes injectable options before dispatch so that a
|
|
missing production dependency fails as a command error rather than reaching
|
|
execution.
|
|
|
|
Commands that need configuration use one shared loader. The CLI discovers the
|
|
file, parses it through **internal/core/config**, starts from defaults, applies
|
|
the file and supported environment overrides, and then validates it for the
|
|
command. The configured discovery and precedence contract is in
|
|
[Configuration](../config.md), while the loading and resolution mechanics are
|
|
in [Configuration Internals](configuration.md).
|
|
|
|
Configuration validation without a selected pipeline checks structural
|
|
configuration only. Validation with a selected pipeline also builds the
|
|
effective catalog, resolves the pipeline, and verifies explicitly selected
|
|
Scriptorium profiles. Pipeline listing validates configuration before returning
|
|
normalized, sorted identifiers.
|
|
|
|
## Production Composition
|
|
|
|
The production composition helper allocates every framework registry and the
|
|
prompt-asset registry, then registers the generic, Seriatim, and D&D module
|
|
families in that order. The resulting registries provide both the module
|
|
catalog used for resolution and the concrete constructors used for preparation.
|
|
Tests may provide a catalog or registries instead; production code must not
|
|
silently merge an injected partial catalog with production registrations.
|
|
|
|
The production LLM factory builds the Scriptorium-backed client from resolved
|
|
configuration, creates one scheduler from the effective global LLM limit, and
|
|
wraps the client before it reaches modules. Registration and LLM construction
|
|
errors are returned before a pipeline is prepared. Concrete module keys and
|
|
validator chains are public configuration choices and remain documented in
|
|
[Configuration](../config.md).
|
|
|
|
## Run Orchestration
|
|
|
|
After parsing and validating a run invocation, the CLI performs this ordered
|
|
handoff:
|
|
|
|
1. load and validate configuration, then apply command-level operational
|
|
overrides;
|
|
2. create and validate a safe run identity, then allocate a debug bundle only
|
|
when requested;
|
|
3. build the effective catalog, resolve requested reference changes, resolve
|
|
the effective pipeline, and verify explicit Scriptorium profiles;
|
|
4. materialize external or generated references and record redacted invocation
|
|
and resolution provenance when debug capture is enabled;
|
|
5. construct registries, the scheduled LLM client, prepared modules, and the
|
|
requested cache/checkpoint collaborators;
|
|
6. read the source input and invoke the framework runner; and
|
|
7. write the runner's logical output files only after a successful run, then
|
|
complete the command report and user-facing result.
|
|
|
|
Preparation happens before source parsing, so module construction and
|
|
dependency failures cannot begin stage execution. The CLI also preserves the
|
|
framework's result and warning information when it writes summaries and the
|
|
final command result. Detailed state lifecycle, resume handling, and physical
|
|
path confinement are maintained in [Run State Internals](state.md) and
|
|
[Operations](../operations.md).
|
|
|
|
For `run --json`, the CLI constructs and encodes its private run-result receipt
|
|
after a successful runner result is available, before it publishes logical
|
|
output files. It writes the prepared receipt to standard output only after
|
|
output publication and requested debug terminalization succeed. A receipt-write
|
|
failure exits with runtime status 1 and may leave partial standard-output bytes,
|
|
but the already-published output bundle remains complete and requested debug
|
|
reporting remains successfully terminalized. The CLI reports a bounded
|
|
command-owned error and does not repeat terminal reporting. The receipt remains
|
|
a CLI reporting concern rather than a framework or output-module responsibility;
|
|
its public contract is the
|
|
[run-result receipt](../integrations/run-result.md).
|
|
|
|
## Failure Mapping And Terminal Reporting
|
|
|
|
Argument, flag, and invocation-combination failures are reported to standard
|
|
error before runtime composition and use the syntax error class. Once an
|
|
invocation is syntactically valid, configuration loading and validation,
|
|
resolution, registration, profile checks, reference materialization, module
|
|
construction, input reads, runner failures, output publication, and requested
|
|
debug handling use the runtime failure class. The public status numbers and
|
|
stream contract are defined in the [CLI reference](../cli.md#output-streams-and-exit-statuses).
|
|
|
|
When debug capture has been allocated, one command-state value records the
|
|
known run result. Guarded terminalization writes a success report once, or
|
|
attempts a failure report and error record once. A persistence failure is
|
|
reported in addition to the original failure and never replaces it. If a debug
|
|
path exists, failure output includes that path so the retained diagnostic data
|
|
is discoverable.
|
|
|
|
## Invariants To Preserve
|
|
|
|
- Only the CLI composes production implementations and physical runtime roots.
|
|
- Configuration and resolved composition failures occur before module
|
|
preparation or source parsing.
|
|
- A runner's logical files are published only after a successful run.
|
|
- Production registries and a caller-supplied catalog or registries are
|
|
alternative composition sources, not an implicit mixture.
|
|
- A requested debug bundle has one terminal report attempt; its persistence
|
|
errors supplement rather than obscure the primary command error.
|
|
- User-facing flags, paths, exit codes, and configuration fields are defined
|
|
by their public documentation, not duplicated here.
|
|
|
|
## Focused Tests
|
|
|
|
- **internal/cli/command_contract_test.go** covers dispatch, help, syntax and
|
|
runtime error classes, discovery, validation, and listing.
|
|
- **internal/cli/run_contract_test.go** covers the run handoff, publication,
|
|
debug reporting, and command-owned state collaborators.
|
|
- **internal/cli/production_contract_test.go** covers registrar composition,
|
|
production catalog contents, assets, and representative configuration
|
|
validation.
|
|
- **internal/cli/reference_contract_test.go** covers CLI reference overrides,
|
|
origin separation, and materialization boundaries.
|
|
- **internal/cli/state_hardening_test.go** covers safe run identity, state
|
|
roots, and failure ordering.
|
|
|
|
Run **go test ./internal/cli** after changing command composition or command
|
|
behavior. Pair it with **go test ./internal/core/config** when the configuration
|
|
handoff changes.
|