Align architecture and testing policies with upstream
This commit is contained in:
@@ -1,147 +1,109 @@
|
||||
# Architecture Policy
|
||||
|
||||
**Base Policy Version:** 1.1
|
||||
**Base Policy Version:** 1.3
|
||||
|
||||
**Last Updated:** 2026-09-26
|
||||
**Last Updated**: 2026-09-28
|
||||
|
||||
**Upstream Source:** https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/architecture.md
|
||||
|
||||
## 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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## System Shape
|
||||
## Architectural Approach
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
The application consumes
|
||||
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 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.
|
||||
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 also consumes ConfigKit v0.4.1 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.
|
||||
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.
|
||||
|
||||
The concrete package inventory is maintained in the
|
||||
[internal overview](../internal/overview.md).
|
||||
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.
|
||||
|
||||
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.
|
||||
## Definition Support And Request State
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## 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.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)
|
||||
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
|
||||
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.
|
||||
|
||||
## 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.
|
||||
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
|
||||
|
||||
@@ -153,5 +115,19 @@ secrets must not be emitted.
|
||||
- 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
|
||||
|
||||
Work that is not implemented belongs in `docs/roadmap/`.
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user