Files
scriptorium/docs/policy/architecture.md

4.5 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/runs through serve

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:

  • 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: Runner prepare/run orchestration and repair-hook boundary.
  • internal/promptdef: filesystem prompt-definition repository.
  • internal/profile: filesystem execution-profile repository.
  • 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.md
  • docs/internal/adapters.md

Configuration And Precedence

Application settings are resolved as:

  1. built-in defaults
  2. config file values
  3. 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
  • outbound model contract: OpenAI-compatible chat completions subset
  • subprocess contract for integrators: CLI run/render

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.Run reuses Runner.Prepare flow.
  • CLI and HTTP currently instantiate Runner without a repairer.
  • Artifact reading supports inline and file references.
  • 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/.