Refocus internal component documentation

This commit is contained in:
2026-07-26 14:20:06 +00:00
parent c927b7819d
commit ff31f8daf8
6 changed files with 297 additions and 384 deletions

View File

@@ -2,148 +2,86 @@
## Purpose
Adapters translate external interfaces into domain requests and translate domain results back out. They wire dependencies, apply app config, and own IO concerns, but they do not make runner decisions.
Adapters translate external inputs into domain requests, compose dependencies,
and translate domain results or errors back to their interface. They own IO and
presentation mechanics; use-case decisions remain in `internal/usecase`.
Source-loading behavior belongs in `docs/internal/sources.md`. User-facing CLI, HTTP, and package contracts belong in `docs/cli.md`, `docs/api.md`, and `docs/consumers/pkg-scriptorium.md`.
External contracts are canonical in the [CLI reference](../cli.md), [HTTP API
reference](../api.md), and [Go package contract](../consumers/pkg-scriptorium.md).
## Adapter Map
## Components And Collaborators
- `cmd/scriptorium`: process entrypoint.
- `internal/adapter/cli`: command parsing, config handoff, runner construction, stdout/stderr, exit codes.
- `internal/adapter/http`: `POST /v1/runs` request/response mapping and HTTP error/status mapping.
- root package `scriptorium`: public Go facade over internal runner types and dependencies.
- `cmd/scriptorium` passes process arguments and streams to
`internal/adapter/cli`.
- `internal/adapter/cli` parses commands, resolves application settings through
`internal/config`, constructs a runner, and owns process output handling.
- `internal/adapter/http` decodes DTOs, maps them to `domain.RunRequest`, calls
a runner interface, and maps errors and results to HTTP DTOs.
- The root `scriptorium` package maps its public types and options to internal
collaborators and maps selected internal errors to public sentinels.
- `internal/format` formats prepared runs for the CLI; `internal/llm`,
`internal/prompt`, and source packages supply runner dependencies.
Supporting implementation packages used during adapter wiring:
## Wiring Flows
- `internal/config`
- `internal/defaults`
- `internal/format`
- `internal/llm`
- `internal/prompt`
### CLI
## Inputs And Outputs
The CLI resolves configuration before constructing dependencies. `run` builds a
runner with the ordinary composite artifact reader and invokes `Runner.Run`;
`render` uses the same wiring and invokes `Runner.Prepare`; `serve` replaces the
file reader with the restricted artifact reader, builds an HTTP handler, and
starts the server.
CLI adapter:
Parser state records whether numeric runtime values were explicitly supplied.
That presence is carried into `domain.ExecutionTargetOverride`, allowing the
runner to distinguish omitted values from explicit zero overrides.
- Input: process args, optional config file, filesystem sources, environment variables.
- Output: process exit code, stdout artifact/prepared output, stderr summaries and errors.
### HTTP
HTTP adapter:
The handler first enforces transport limits, strict JSON decoding, and the
minimal request shape. It maps DTO values to domain types without deciding
prompt selection, source behavior, or validation semantics. On success it maps
the domain result to the response DTO; on failure it uses `errors.Is` over
runner, source, artifact, and profile errors to choose the public error mapping.
- Input: HTTP request method/path/headers/body for `POST /v1/runs`.
- Output: JSON success or error body with mapped status code.
The [HTTP API reference](../api.md) owns the route, DTO schema, status codes,
and externally observable limit behavior.
Public Go facade:
### Public Go Facade
- Input: typed `scriptorium.Config`, `Option`, and `RunRequest` values.
- Output: typed `PreparedRun` and `RunResult` values plus public sentinel errors.
`NewEngine` applies public options, selects filesystem, `fs.FS`, single-file,
or in-memory dependencies, and constructs a runner. The conversion functions
copy maps and slices across the boundary so callers do not receive internal
domain values. The facade maps selected internal errors to the public sentinel
set and keeps direct request API keys out of public results.
## Boundaries
## Package-Local Guarantees
- Adapters convert external shapes to `domain.RunRequest` and back.
- Runner orchestration remains in `internal/usecase`.
- Prompt/profile/schema/artifact source rules remain in repository, validator, and artifact packages.
- LLM provider request serialization remains in `internal/llm`.
- Public package types are facade types; internal domain types do not leak across the package boundary.
- Adapters do not embed runner orchestration or source-loading decisions.
- Configuration is resolved before adapter dependency composition.
- CLI and HTTP create runners without a repairer; a repairer is available only
through explicit internal runner construction.
- DTO conversion preserves explicit numeric-override presence.
- Error mapping matches error identities, not error text.
- No adapter creates durable run state; caller-selected output files are not
application state.
## Config Fields Used
## Failure And Verification Boundaries
Adapter app settings:
Keep external error payloads concise, preserve strict external decoding, and do
not serialize resolved secret values. Validation content failures remain result
state; runtime failures remain errors for the relevant adapter to map.
- `prompt_dir`
- `profile_dir`
- `schema_dir`
- `server.addr`
- `server.artifact_root`
- `server.max_request_bytes`
- `server.max_artifact_bytes`
- `server.max_response_bytes`
- `defaults.render_format`
Execution request/profile settings passed through the runner:
- `endpoint`
- `model`
- `temperature`
- `max_tokens`
- `top_p`
- `timeout_seconds`
- `service_tier`
- `api_key_env`
- `reasoning_effort`
- `extra_params`
CLI and HTTP preserve numeric override presence so omitted values and explicit zero values remain distinct.
## CLI Adapter
Implemented commands:
- `run`
- `render`
- `serve`
Behavior:
- `run` constructs a runner with direct filesystem artifact reading and calls `Runner.Run`.
- `render` constructs a runner and calls `Runner.Prepare`; it does not call the LLM.
- `serve` constructs a restricted artifact reader and HTTP handler, then starts an unauthenticated HTTP server.
- `run` exits `2` when generation succeeds but validation fails.
- parse, runtime, and output-write errors exit `1`.
- deprecated `--prompt-id` and `--profile-id` aliases are accepted.
## HTTP Adapter
Behavior:
- Accepts only `POST /v1/runs`.
- Decodes JSON strictly and rejects unknown fields and trailing JSON tokens.
- Rejects empty `prompt_id` and empty `inputs` before calling the runner.
- Does not accept raw API key values in the request body.
- Returns validation failures as `200` responses with failed validation details.
- Maps request-body, artifact, and encoded-response size failures to `413`.
- Maps domain and repository errors to stable error codes without returning wrapped internal cause text.
The HTTP adapter has no built-in authentication or authorization. Deployment controls must be provided outside the process.
## Public Go Facade
Behavior:
- `NewEngine` wires the same default runner components as CLI/HTTP unless options override them.
- Prompt, profile, and schema sources may come from directories, single files, or `fs.FS` roots.
- `WithProfiles` adds in-memory profiles ahead of file-backed and built-in profiles.
- `WithLLMClient` injects custom model behavior.
- `RunRequest.APIKey` is request-scoped and direct; it is used only for generation and is stripped from public results.
- internal errors are mapped to public sentinels in `errors.go`.
## Failure Behavior
Adapters should:
- keep external error payloads concise and stable.
- avoid leaking raw secret values.
- use sentinels and typed errors for mapping.
- preserve strict external input decoding.
- keep validation content failures distinct from runtime errors.
CLI writes human-readable summaries to stderr. HTTP writes JSON error envelopes. The public Go facade returns typed errors.
## State And Manifests
Adapters do not add durable run state.
- No adapter writes run manifests.
- No adapter implements checkpoint, skip, or resume behavior.
- CLI output files are caller-selected artifacts, not internal state.
## Tests To Inspect
Inspect focused tests when changing this area:
- `internal/adapter/cli/run_test.go`
- `internal/adapter/http/handler_test.go`
- `engine_test.go`
- `internal/format/prepared_run_test.go`
- `internal/llm/openai_compatible_client_test.go`
Run the affected adapter package tests and recheck the relevant canonical
contract. The [testing policy](../policy/testing.md) owns global test
sufficiency guidance.
## Change Recipes
@@ -154,33 +92,22 @@ Adapters do not add durable run state.
precedence while wiring it through its consuming adapter.
3. Add focused configuration and adapter tests for parsing, mapping, and
effective behavior.
4. Update the [configuration contract](../config.md) and any external contract
affected by the new behavior.
4. Update the [configuration contract](../config.md) and any affected external
contract.
### CLI Flags
1. Add the flag to the relevant command in `internal/adapter/cli/run.go`.
1. Add the flag to the relevant parser in `internal/adapter/cli/run.go`.
2. Keep command scope and application-configuration precedence intentional.
3. Add or update parser and command tests in
`internal/adapter/cli/run_test.go`.
4. Update the [CLI contract](../cli.md) and any maintained examples affected by
the invocation.
4. Update the [CLI contract](../cli.md) and affected maintained examples.
### Adapter Capabilities
1. Define or reuse the appropriate domain or use-case interface boundary.
2. Implement translation and IO behavior in the adapter without moving
use-case decisions out of `internal/usecase`.
2. Implement translation and IO behavior without moving use-case decisions out
of `internal/usecase`.
3. Add focused mapping, parsing, and error-behavior tests.
4. Update this document and the affected canonical public or integration
contract. Update [source internals](sources.md) when source-loading behavior
changes.
## Architectural Invariants
- Adapter packages stay thin and translation-focused.
- App config is resolved before dependency construction.
- External input strictness is part of contract stability.
- CLI and HTTP construct runners without a repairer.
- HTTP endpoint details remain canonical in `docs/api.md`.
- Public Go package details remain canonical in `docs/consumers/pkg-scriptorium.md`.
4. Update this document and the affected public or integration contract. Update
[source internals](sources.md) when source-loading behavior changes.