# Architecture This document is the development architecture policy for Scriptorium. It is for developers and LLM coding agents. User-facing behavior belongs in `README.md` and the docs under `docs/` that target operators/users. ## System Shape Scriptorium is a narrow prompt-execution application with three executable entry paths: CLI `run`, CLI `render`, and the HTTP service started by `serve`. It also provides a public Go package for in-process use. Its current component inventory is maintained in the [internal overview](../internal/overview.md). Domain behavior is centralized in `internal/usecase` and `internal/domain`. ## Core Principles - Keep orchestration narrow: Scriptorium executes one prompt request; it is not a multi-step workflow engine. - Keep adapter logic thin: adapters map external shapes to domain requests/results and should not hold domain decisions. - Keep boundaries explicit: repositories/loaders/renderers/validators/LLM client stay behind package interfaces. - Keep config strict: YAML/JSON decoding for external inputs should reject unknown fields. - Keep secrets out of payloads: raw API key values must not be accepted or emitted. ## Dependency Direction - Adapters translate external shapes and IO concerns; they do not make use-case decisions. - Use-case and domain code depend on explicit repository, renderer, validator, and LLM interfaces rather than adapter implementations. - Source, rendering, validation, and LLM implementations remain behind their package boundaries. - Dependency-specific types must not leak across unrelated package boundaries. - Prefer the standard library; add an external dependency only when it materially reduces risk or complexity. ## State And Persistence Policy Scriptorium has no durable run-state store. - No built-in resume/checkpoint/archive behavior. - Recovery model is rerun after correcting inputs/config/environment. ## Contract Ownership The [CLI](../cli.md), [configuration](../config.md), [HTTP API](../api.md), [public Go package](../consumers/pkg-scriptorium.md), and [integration](../integrations/) documents own their respective external contracts. This policy keeps only the architectural boundaries that govern their implementation. ## Error Handling And Logging - Wrap errors with domain/operation context. - Map domain errors to adapter-appropriate statuses/codes without leaking sensitive internals. - Never emit raw secret values. ## Testing And Documentation Testing philosophy and change-validation expectations are defined by the [testing policy](testing.md). Documentation ownership and maintenance rules are defined by the [documentation policy](documentation.md). ## Architectural Invariants - `Runner.Run` reuses `Runner.Prepare` flow. - Unknown input fields in config/prompt/profile/http JSON should be rejected by strict decoding. - Raw API key values must not be accepted through external configuration or request payloads, and resolved secret values must not be emitted. ## Non-Goals - Do not move orchestration responsibilities from external callers into Scriptorium. - Do not add adapter-specific business logic in `internal/adapter/*` packages. - Do not bypass repository/renderer/validator/LLM boundaries by introducing cross-package coupling. Work that is not implemented belongs in `docs/roadmap/`.