5.0 KiB
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.
Project Shape
Scriptorium is a narrow prompt-execution application with three entry paths:
- CLI
run - CLI
render - HTTP
POST /v1/runsthroughserve - public Go package
gitea.maximumdirect.net/eric/scriptorium
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.
Package Boundaries
Current package map:
- root package
scriptorium: public Go facade over engine construction, source options, request/result types, and error mapping. cmd/scriptorium: process entrypoint.internal/adapter/cli: command parsing, app wiring for CLI commands, output behavior.internal/adapter/http: HTTP DTO mapping and error/status mapping.internal/config: application settings loading and CLI override precedence.internal/defaults: compile-time default constants.internal/domain: core request/result and contract types.internal/usecase:Runnerprepare/run orchestration and repair-hook boundary.internal/promptdef: filesystem prompt-definition repository.internal/profile: filesystem,fs.FS, and overlay execution-profile repositories.internal/profile/builtin: embedded built-in execution profiles.internal/filecatalog: shared YAML discovery andfs.FSsource helpers.internal/artifact: artifact reference readers.internal/prompt: template renderer.internal/llm: provider-neutral LLM client interface and OpenAI-compatible implementation.internal/validate: validator interfaces and standard implementation.internal/format: prepared-run output formatting.
Detailed component behavior is documented in:
docs/internal/runner.mddocs/internal/adapters.mddocs/internal/sources.md
Configuration And Precedence
Application settings are resolved as:
- built-in defaults
- config file values
- CLI overrides
config.yml is for application wiring (directories, server address, render default format), not prompt/profile runtime execution settings.
Profile selection and runtime model resolution remain use-case concerns.
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.
External Integration Policy
Current external contracts:
- inbound HTTP contract:
POST /v1/runs, documented canonically indocs/api.md - outbound model contract: OpenAI-compatible chat completions subset
- subprocess contract for integrators: CLI
run/render - public Go package contract:
docs/consumers/pkg-scriptorium.md
Integration docs belong under docs/integrations/.
Error Handling And Logging
- Wrap errors with domain/operation context.
- Map domain errors to adapter-appropriate statuses/codes without leaking sensitive internals.
- Keep stderr summaries concise for CLI success/error paths.
- Never emit raw secret values.
Testing Expectations
- Core runner behavior should be covered with isolated unit tests and fixture-based integration tests.
- Adapter behavior should be tested for parse/mapping/error semantics.
- Config parsing, prompt/profile loading, validator behavior, and LLM client error handling should remain covered by package tests.
- Repository-level docs/examples that claim runnable behavior should be validated by tests or smoke commands.
Documentation Expectations
- Document implemented behavior only outside
docs/roadmap/. - Keep canonical reference locations stable (
docs/cli.md,docs/config.md,docs/operations.md,docs/troubleshooting.md,docs/internal/). - Update docs in the same change when architecture-relevant behavior changes.
Architectural Invariants
Runner.RunreusesRunner.Prepareflow.- CLI and HTTP currently instantiate
Runnerwithout a repairer. - Artifact reading supports
inlineandfilereferences. - Unknown input fields in config/prompt/profile/http JSON should be rejected by strict decoding.
- Raw API key values must not be accepted through config/HTTP payloads.
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/.