158 lines
7.2 KiB
Markdown
158 lines
7.2 KiB
Markdown
# Architecture Policy
|
|
|
|
**Base Policy Version:** 1.1
|
|
|
|
**Last Updated:** 2026-09-26
|
|
|
|
## Purpose And Ownership
|
|
|
|
This policy defines Scriptorium's purpose, responsibility and dependency
|
|
boundaries, established invariants, and non-goals. Concrete component inventory
|
|
and implementation mechanics belong in [internal documentation](../internal/overview.md);
|
|
public behavior belongs in its canonical contracts.
|
|
|
|
Adopted constraints govern future development without implying that every
|
|
capability they could govern exists or is planned. Keep proposed structure and
|
|
implementation status in roadmaps, and decision rationale in ADRs. Acceptance
|
|
of a decision is not proof of implementation. Do not turn incidental choices
|
|
into architectural invariants.
|
|
|
|
## System Shape
|
|
|
|
Scriptorium is an executable application with four command entry paths: CLI
|
|
`run`, CLI `render`, CLI `inspect`, and the HTTP service started by `serve`.
|
|
The `inspect` command has prompt and profile modes. Scriptorium does not expose
|
|
a reusable root Go package.
|
|
|
|
The application consumes
|
|
[Promptkit v0.11.0](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.11.0/docs/consumers/pkg-promptkit.md)
|
|
through its supported root package. Promptkit owns prompt execution,
|
|
preparation, source formats, built-in profiles, model-client behavior, and
|
|
validation. Scriptorium owns application configuration, executable adapters,
|
|
prepared-run and definition-inspection presentation, process behavior, and HTTP
|
|
deployment policy.
|
|
|
|
Scriptorium also consumes ConfigKit v0.4.0 for application configuration
|
|
decoding, resolution, and validation flow. Scriptorium owns its application
|
|
schema, defaults, normalization, validation rules, source selection, and CLI
|
|
flag mapping; ConfigKit does not own Promptkit framework sources or HTTP
|
|
artifact containment.
|
|
|
|
The concrete package inventory is maintained in the
|
|
[internal overview](../internal/overview.md).
|
|
|
|
As established by [ADR 0004](../adr/0004-definition-boundary.md), Scriptorium
|
|
aims to support the complete set of features in valid Promptkit prompt and
|
|
profile definitions for its selected upstream version. Promptkit remains the
|
|
canonical parser and validator. Library-only features are considered
|
|
individually against the simple predefined-prompt execution model.
|
|
|
|
Maintain adapter boundaries with proportionate, idiomatic code. This approach
|
|
does not require an interface for every type, additional wrappers, or a fixed
|
|
directory tree for integrations that do not exist.
|
|
|
|
## Dependency Direction
|
|
|
|
```text
|
|
cmd/scriptorium
|
|
|
|
|
v
|
|
CLI and HTTP adapters, configuration, defaults, and formatting
|
|
|
|
|
v
|
|
Promptkit (execution) and ConfigKit (application configuration)
|
|
```
|
|
|
|
- Retained application packages may import Promptkit's root package.
|
|
- They must not import Promptkit `internal` packages.
|
|
- They must not import Promptkit catalog modules directly.
|
|
- They must not import the removed Scriptorium root facade or recreate former
|
|
framework package families.
|
|
- Adapter-owned interfaces use Promptkit public values when a consumer-side
|
|
substitution boundary is needed.
|
|
- Scriptorium passes omitted framework settings as zero values so Promptkit
|
|
applies its own defaults.
|
|
|
|
The repository architecture guard enforces these import and removal
|
|
invariants.
|
|
|
|
Cross-project changes land and release in Promptkit before Scriptorium adopts
|
|
the tagged dependency. Do not commit Go workspaces, local replacements,
|
|
vendored Promptkit implementation, or unpublished dependency assumptions.
|
|
|
|
## Retained Boundaries
|
|
|
|
- `internal/adapter/cli` owns commands, flags, configuration precedence,
|
|
process streams, output files, summaries, and exit codes.
|
|
- `internal/adapter/http` owns routes, strict JSON DTOs, size limits, response
|
|
mapping, status mapping, and the restricted artifact reader.
|
|
- `internal/config` owns discovery and Scriptorium's application definition;
|
|
ConfigKit owns strict YAML decoding and the load/override pipeline.
|
|
- `internal/defaults` owns Scriptorium application and HTTP defaults only.
|
|
- `internal/format` owns deterministic prepared-run and definition-inspection
|
|
text and JSON presentation.
|
|
- Promptkit owns framework orchestration and contracts. Its
|
|
[format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.11.0/docs/formats.md)
|
|
and
|
|
[outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.11.0/docs/integrations/openai-compatible-chat.md)
|
|
are canonical.
|
|
|
|
## HTTP Artifact Security Boundary
|
|
|
|
Ordinary CLI file loading is provided by Promptkit. Scriptorium's HTTP adapter
|
|
injects a restricted `promptkit.ArtifactReader` for inbound HTTP requests.
|
|
That reader denies file references without an artifact root, enforces the
|
|
configured byte limit, and applies Scriptorium's lexical root-containment rule.
|
|
The operating system still follows symlinks after the lexical check.
|
|
|
|
This boundary handles untrusted request references under the documented
|
|
deployment model; it is not a filesystem sandbox. Defending against a
|
|
privileged actor concurrently modifying the host filesystem is outside the
|
|
adopted scope, not a claim that such activity cannot occur. Do not infer
|
|
additional defenses or guarantees from hypothetical threats; raise unsettled
|
|
scope decisions under the [agent policy](agents.md).
|
|
|
|
The [HTTP API](../api.md) owns observable request outcomes, and
|
|
[operations](../operations.md) owns deployment permissions and root selection.
|
|
|
|
## State, Errors, And Secrets
|
|
|
|
Scriptorium has no durable run-state store, checkpoint, cache, or resume
|
|
mechanism. Recovery is a new request after correcting inputs, configuration, or
|
|
environment.
|
|
|
|
Each request is self-contained from the caller's perspective, without
|
|
conversation or workflow state retained from completed requests. This does
|
|
not mean the process is internally stateless. Shared engines, backend capacity
|
|
and queue accounting, in-flight coordination, cancellation, and server
|
|
lifecycle resources are permitted and must be shared where necessary to
|
|
enforce configured backend limits across concurrent requests. Such state must
|
|
be concurrency-safe and does not create a durable user-workflow contract.
|
|
|
|
Adapters map Promptkit public error identities into CLI exits or HTTP statuses
|
|
without classifying by message text. Raw API keys are not accepted in
|
|
Scriptorium configuration, CLI arguments, or HTTP payloads, and resolved
|
|
secrets must not be emitted.
|
|
|
|
## Architectural Invariants
|
|
|
|
- External YAML and JSON decoding remains strict.
|
|
- CLI and HTTP behavior remains presentation and transport logic rather than
|
|
framework orchestration.
|
|
- Explicit numeric request overrides preserve presence, including zero.
|
|
- HTTP artifact containment and byte limits remain Scriptorium policy.
|
|
- No application package depends on Promptkit implementation packages.
|
|
|
|
## Non-Goals
|
|
|
|
- Do not recreate an in-process Scriptorium framework API or compatibility
|
|
facade.
|
|
- Do not copy Promptkit types, defaults, built-in profiles, or implementation
|
|
into Scriptorium.
|
|
- Do not move CLI, inbound HTTP, process, or deployment policy into Promptkit.
|
|
- Do not add durable workflow, archive, or resume behavior.
|
|
- Do not add application-managed prompt modification, follow-up message flows,
|
|
conversation management, or multi-step workflow orchestration.
|
|
|
|
Work that is not implemented belongs in `docs/roadmap/`.
|