134 lines
7.1 KiB
Markdown
134 lines
7.1 KiB
Markdown
# Architecture Policy
|
|
|
|
**Base Policy Version:** 1.3
|
|
|
|
**Last Updated**: 2026-09-28
|
|
|
|
**Upstream Source:** https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/architecture.md
|
|
|
|
## Purpose And Ownership
|
|
|
|
The adopted policy defines the application's purpose and the architectural
|
|
constraints contributors must follow. It owns system boundaries, responsibility
|
|
and dependency rules, established invariants, and explicit non-goals.
|
|
|
|
Describe the concrete package inventory and implementation mechanics in internal
|
|
documentation. Link to canonical public contracts for their exact behavior and
|
|
to ADRs for decision rationale.
|
|
|
|
## Architectural Approach
|
|
|
|
Hexagonal architecture is strongly recommended, including encapsulating external
|
|
integrations and APIs within internal adapters. Keep domain and application
|
|
logic independent of external integration details, and make dependency direction
|
|
clear in the adopted policy.
|
|
|
|
Implement that separation with proportionate, idiomatic code. Choose interfaces
|
|
and package layout to serve the application's actual boundaries. Use adapters
|
|
for collaborators with external integration responsibilities.
|
|
|
|
## Adopted Constraints And Implemented Structure
|
|
|
|
Architectural constraints govern current and future development. Record
|
|
implemented structure accurately, proposals and implementation status in the
|
|
roadmap, and significant decisions and rationale in ADRs. Describe a target
|
|
structure as implemented when its changes land.
|
|
|
|
Constraints must reflect deliberately selected requirements and decisions.
|
|
Do not promote incidental implementation choices into architectural invariants.
|
|
|
|
## Scriptorium's Purpose And System Shape
|
|
|
|
Scriptorium is an executable application with CLI `run`, `render`,
|
|
`inspect`, and `config` command families and an HTTP service started by
|
|
`serve`. It offers simple, request-independent execution of predefined
|
|
prompts, not a reusable Scriptorium root Go API or a workflow framework.
|
|
The [internal overview](../internal/overview.md) owns the concrete package
|
|
inventory; [adapter internals](../internal/adapters.md) and
|
|
[source internals](../internal/sources.md) own implementation mechanics.
|
|
|
|
## Framework And Application Boundaries
|
|
|
|
Scriptorium consumes
|
|
[Promptkit v0.11.1](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.11.1/docs/consumers/pkg-promptkit.md)
|
|
through its supported public root package. Promptkit owns prompt execution,
|
|
preparation, prompt and profile formats, built-in profiles, model-client
|
|
behavior, validation, and framework defaults. Scriptorium owns application
|
|
configuration, executable CLI and HTTP adapters, prepared-run and
|
|
definition-inspection presentation, process behavior, and HTTP deployment
|
|
policy. The [format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.11.1/docs/formats.md)
|
|
and [outbound integration contract](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.11.1/docs/integrations/openai-compatible-chat.md)
|
|
remain Promptkit's contracts.
|
|
|
|
Scriptorium uses ConfigKit v0.4.1 for strict application YAML decoding,
|
|
resolution, and validation flow. Scriptorium retains its application schema,
|
|
defaults, normalization, validation rules, source selection, and CLI override
|
|
mapping. ConfigKit does not own Promptkit framework sources or HTTP artifact
|
|
containment. The [configuration contract](../config.md) owns externally
|
|
observable configuration behavior.
|
|
|
|
Application code may import Promptkit's public root package, but not its
|
|
`internal` packages or catalog modules. It must not recreate the removed
|
|
Scriptorium framework facade or former framework package families. Use
|
|
consumer-owned interfaces only where substitution at an adapter boundary is
|
|
needed. Omitted framework settings pass as zero values so Promptkit applies
|
|
its own defaults. Cross-project changes land and release in Promptkit before
|
|
Scriptorium adopts its tagged dependency; do not commit Go workspaces, local
|
|
replacements, vendored Promptkit source, or unpublished dependency assumptions.
|
|
The repository's architecture guard protects these import and removal
|
|
boundaries. Adapter separation does not require an interface for every type,
|
|
extra wrappers, or a fixed directory tree.
|
|
|
|
## Definition Support And Request State
|
|
|
|
As decided in [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 Scriptorium's simple predefined-prompt execution model.
|
|
|
|
External YAML and JSON decoding remains strict. Adapters map external values
|
|
through Promptkit public requests and results without taking over framework
|
|
orchestration. Explicit numeric request overrides preserve presence, including
|
|
zero. Adapters map Promptkit public error identities to 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.
|
|
|
|
Each execution request is self-contained from the caller's perspective; no
|
|
conversation or workflow state is retained from completed requests. This
|
|
does not preclude process-scoped operational state. A server shares its
|
|
Promptkit engine, backend registry, capacity admission and queue accounting
|
|
across relevant concurrent requests so configured backend limits cannot be
|
|
bypassed by per-request construction. In-flight coordination, cancellation,
|
|
and server lifecycle state must be concurrency-safe. None of this creates a
|
|
durable workflow, checkpoint, cache, or resume contract; recovery is a new
|
|
request after correcting inputs, configuration, or environment.
|
|
|
|
## 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.
|
|
## Trust Boundaries And Threat Scope
|
|
|
|
Ordinary CLI file loading belongs to Promptkit. For untrusted inbound HTTP
|
|
artifact references, Scriptorium injects a restricted
|
|
`promptkit.ArtifactReader`. It denies file references without an artifact
|
|
root, applies the configured byte limit, and enforces lexical root containment.
|
|
The operating system follows symlinks after that lexical check. This is not a
|
|
filesystem sandbox or a defense against a privileged actor concurrently
|
|
modifying the host filesystem; that threat is outside the adopted scope.
|
|
Do not infer stronger defenses from hypothetical threats. Raise unsettled
|
|
scope decisions under the [agent policy](agents.md).
|
|
|
|
The [HTTP API](../api.md) owns observable request outcomes, the
|
|
[configuration contract](../config.md) owns credential supply, and
|
|
[operations](../operations.md) owns deployment permissions and root selection.
|
|
The [source internals](../internal/sources.md) describe reader mechanics.
|