Complete the public facade adapter boundary
This commit is contained in:
@@ -113,11 +113,16 @@ counts. `RenderedPrompt`, `RenderedMessage`, `CacheControl`, and
|
|||||||
|
|
||||||
`ArtifactReader` implements
|
`ArtifactReader` implements
|
||||||
`Read(context.Context, ArtifactRef) (*Artifact, error)`. Supplying it through
|
`Read(context.Context, ArtifactRef) (*Artifact, error)`. Supplying it through
|
||||||
`WithArtifactReader` replaces the engine's default inline and file reader for
|
`WithArtifactReader` replaces, rather than extends, the engine's default inline
|
||||||
all inputs. Reader errors remain available through `errors.Is` alongside
|
and file reader for every input. Omitting the option retains that default;
|
||||||
`ErrArtifactLoad`; a nil artifact with no error is treated as an artifact-load
|
`WithArtifactReader(nil)` makes engine construction fail with
|
||||||
failure. Readers must supply artifact metadata and should not retain or mutate
|
`ErrInvalidConfig`.
|
||||||
the caller's values.
|
|
||||||
|
Reader failures are surfaced as errors matching `ErrArtifactLoad` while
|
||||||
|
preserving the reader's original error identity for `errors.Is`. A `(nil, nil)`
|
||||||
|
reader response is also an artifact-load failure. Readers are responsible for
|
||||||
|
artifact metadata, although the engine assigns the input-map name when the
|
||||||
|
returned name is empty; readers should not retain or mutate caller values.
|
||||||
|
|
||||||
## Requests, Inputs, And Overrides
|
## Requests, Inputs, And Overrides
|
||||||
|
|
||||||
@@ -191,5 +196,8 @@ Public methods preserve these sentinel checks through `errors.Is`:
|
|||||||
- `ErrLLMGenerate`
|
- `ErrLLMGenerate`
|
||||||
- `ErrValidation`
|
- `ErrValidation`
|
||||||
|
|
||||||
For interface selection and operational responsibilities, see the
|
`ErrProfileRequired` and `ErrAPIKeyEnvMissing` each also match
|
||||||
[consumer integration overview](api.md).
|
`ErrInvalidRequest`, so callers can select either the broad request category or
|
||||||
|
the specific condition.
|
||||||
|
|
||||||
|
For the HTTP interface, see the [HTTP API reference](../api.md).
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
Adapters translate external inputs into domain requests, compose dependencies,
|
Adapters translate external inputs into public engine requests and translate
|
||||||
and translate domain results or errors back to their interface. They own IO and
|
public results or errors back to their interface. They own IO and presentation
|
||||||
presentation mechanics; use-case decisions remain in `internal/usecase`.
|
mechanics; use-case decisions remain behind the root `scriptorium` facade.
|
||||||
|
|
||||||
External contracts are canonical in the [CLI reference](../cli.md), [HTTP API
|
External contracts are canonical in the [CLI reference](../cli.md), [HTTP API
|
||||||
reference](../api.md), and [Go package contract](../consumers/pkg-scriptorium.md).
|
reference](../api.md), and [Go package contract](../consumers/pkg-scriptorium.md).
|
||||||
@@ -14,35 +14,37 @@ reference](../api.md), and [Go package contract](../consumers/pkg-scriptorium.md
|
|||||||
- `cmd/scriptorium` passes process arguments and streams to
|
- `cmd/scriptorium` passes process arguments and streams to
|
||||||
`internal/adapter/cli`.
|
`internal/adapter/cli`.
|
||||||
- `internal/adapter/cli` parses commands, resolves application settings through
|
- `internal/adapter/cli` parses commands, resolves application settings through
|
||||||
`internal/config`, constructs a runner, and owns process output handling.
|
`internal/config`, constructs the public engine, and owns process output
|
||||||
- `internal/adapter/http` decodes DTOs, maps them to `domain.RunRequest`, calls
|
handling.
|
||||||
a runner interface, and maps errors and results to HTTP DTOs.
|
- `internal/adapter/http` decodes DTOs, maps them to public run requests,
|
||||||
|
calls its local public `Runner` interface, and maps public errors and results
|
||||||
|
to HTTP DTOs.
|
||||||
- The root `scriptorium` package maps its public types and options to internal
|
- The root `scriptorium` package maps its public types and options to internal
|
||||||
collaborators and maps selected internal errors to public sentinels.
|
collaborators and maps selected internal errors to public sentinels.
|
||||||
- `internal/format` formats prepared runs for the CLI; `internal/llm`,
|
- `internal/format` formats public prepared runs for the CLI.
|
||||||
`internal/prompt`, and source packages supply runner dependencies.
|
|
||||||
|
|
||||||
## Wiring Flows
|
## Wiring Flows
|
||||||
|
|
||||||
### CLI
|
### CLI
|
||||||
|
|
||||||
The CLI resolves configuration before constructing dependencies. `run` builds a
|
The CLI resolves configuration before constructing the public engine. `run`
|
||||||
runner with the ordinary composite artifact reader and invokes `Runner.Run`;
|
calls `Engine.Run` with a public request and `render` calls `Engine.Prepare`
|
||||||
`render` uses the same wiring and invokes `Runner.Prepare`; `serve` replaces the
|
with the same request mapping. `serve` constructs the HTTP-owned restricted
|
||||||
file reader with the restricted artifact reader, builds an HTTP handler, and
|
artifact reader, injects it with `WithArtifactReader`, passes the resulting
|
||||||
starts the server.
|
engine directly to the HTTP handler, and starts the server.
|
||||||
|
|
||||||
Parser state records whether numeric runtime values were explicitly supplied.
|
Parser state records whether numeric runtime values were explicitly supplied.
|
||||||
That presence is carried into `domain.ExecutionTargetOverride`, allowing the
|
That presence is carried into `scriptorium.ExecutionTargetOverride`, allowing
|
||||||
runner to distinguish omitted values from explicit zero overrides.
|
the engine to distinguish omitted values from explicit zero overrides.
|
||||||
|
|
||||||
### HTTP
|
### HTTP
|
||||||
|
|
||||||
The handler first enforces transport limits, strict JSON decoding, and the
|
The handler first enforces transport limits, strict JSON decoding, and the
|
||||||
minimal request shape. It maps DTO values to domain types without deciding
|
minimal request shape. It maps DTO values to public types without deciding
|
||||||
prompt selection, source behavior, or validation semantics. On success it maps
|
prompt selection, source behavior, or validation semantics. On success it maps
|
||||||
the domain result to the response DTO; on failure it uses `errors.Is` over
|
the public result to the response DTO; on failure it uses `errors.Is` over
|
||||||
runner, source, artifact, and profile errors to choose the public error mapping.
|
public framework errors and HTTP-local artifact-policy errors to choose the
|
||||||
|
public error mapping.
|
||||||
|
|
||||||
The [HTTP API reference](../api.md) owns the route, DTO schema, status codes,
|
The [HTTP API reference](../api.md) owns the route, DTO schema, status codes,
|
||||||
and externally observable limit behavior.
|
and externally observable limit behavior.
|
||||||
@@ -57,10 +59,10 @@ set and keeps direct request API keys out of public results.
|
|||||||
|
|
||||||
## Package-Local Guarantees
|
## Package-Local Guarantees
|
||||||
|
|
||||||
- Adapters do not embed runner orchestration or source-loading decisions.
|
- Adapters do not embed framework orchestration or source-loading decisions.
|
||||||
- Configuration is resolved before adapter dependency composition.
|
- Configuration is resolved before adapter dependency composition.
|
||||||
- CLI and HTTP create runners without a repairer; a repairer is available only
|
- CLI and HTTP consume the public engine without a repairer; a repairer remains
|
||||||
through explicit internal runner construction.
|
available only through explicit internal runner construction.
|
||||||
- DTO conversion preserves explicit numeric-override presence.
|
- DTO conversion preserves explicit numeric-override presence.
|
||||||
- Error mapping matches error identities, not error text.
|
- Error mapping matches error identities, not error text.
|
||||||
- No adapter creates durable run state; caller-selected output files are not
|
- No adapter creates durable run state; caller-selected output files are not
|
||||||
@@ -105,9 +107,10 @@ sufficiency guidance.
|
|||||||
|
|
||||||
### Adapter Capabilities
|
### Adapter Capabilities
|
||||||
|
|
||||||
1. Define or reuse the appropriate domain or use-case interface boundary.
|
1. Define or reuse an adapter-local consumer interface with public facade
|
||||||
2. Implement translation and IO behavior without moving use-case decisions out
|
types when a test seam is needed.
|
||||||
of `internal/usecase`.
|
2. Implement translation and IO behavior without moving framework decisions out
|
||||||
|
of the public engine.
|
||||||
3. Add focused mapping, parsing, and error-behavior tests.
|
3. Add focused mapping, parsing, and error-behavior tests.
|
||||||
4. Update this document and the affected public or integration contract. Update
|
4. Update this document and the affected public or integration contract. Update
|
||||||
[source internals](sources.md) when source-loading behavior changes.
|
[source internals](sources.md) when source-loading behavior changes.
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ and invariants; public behavior belongs in the linked contracts.
|
|||||||
|
|
||||||
| Component | Implemented responsibility | References |
|
| Component | Implemented responsibility | References |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `internal/adapter/cli` | Parses CLI commands, applies application wiring, and handles process input and output. | [CLI contract](../cli.md), [adapter internals](adapters.md) |
|
| `internal/adapter/cli` | Parses CLI commands, constructs the public engine from application settings, and handles process input and output. | [CLI contract](../cli.md), [adapter internals](adapters.md) |
|
||||||
| `internal/adapter/http` | Maps HTTP requests and responses to domain operations and maps public errors. | [HTTP API contract](../api.md), [adapter internals](adapters.md) |
|
| `internal/adapter/http` | Maps HTTP requests and responses through public engine values, maps public errors, and owns restricted HTTP artifact policy. | [HTTP API contract](../api.md), [adapter internals](adapters.md) |
|
||||||
| `internal/domain` | Defines core request, result, output-contract, and LLM-boundary types. | [runner internals](runner.md) |
|
| `internal/domain` | Defines core request, result, output-contract, and LLM-boundary types. | [runner internals](runner.md) |
|
||||||
| `internal/usecase` | Implements `Runner` preparation, execution, validation coordination, and the repairer boundary. | [runner internals](runner.md) |
|
| `internal/usecase` | Implements `Runner` preparation, execution, validation coordination, and the repairer boundary. | [runner internals](runner.md) |
|
||||||
|
|
||||||
@@ -32,14 +32,14 @@ and invariants; public behavior belongs in the linked contracts.
|
|||||||
| `internal/profile` | Loads filesystem and `fs.FS` execution profiles and combines profile repositories. | [configuration contract](../config.md), [source internals](sources.md) |
|
| `internal/profile` | Loads filesystem and `fs.FS` execution profiles and combines profile repositories. | [configuration contract](../config.md), [source internals](sources.md) |
|
||||||
| `internal/profile/builtin` | Provides embedded built-in execution profiles as a repository. | [configuration contract](../config.md), [source internals](sources.md) |
|
| `internal/profile/builtin` | Provides embedded built-in execution profiles as a repository. | [configuration contract](../config.md), [source internals](sources.md) |
|
||||||
| `internal/filecatalog` | Provides shared YAML discovery and source-root helpers. | [source internals](sources.md) |
|
| `internal/filecatalog` | Provides shared YAML discovery and source-root helpers. | [source internals](sources.md) |
|
||||||
| `internal/artifact` | Reads inline and file-backed input artifacts. | [configuration contract](../config.md), [HTTP API contract](../api.md), [source internals](sources.md) |
|
| `internal/artifact` | Provides the framework's ordinary inline and unrestricted file artifact reader. | [configuration contract](../config.md), [source internals](sources.md) |
|
||||||
| `internal/prompt` | Renders prompt templates into messages. | [runner internals](runner.md) |
|
| `internal/prompt` | Renders prompt templates into messages. | [runner internals](runner.md) |
|
||||||
|
|
||||||
## Formatting, Validation, And Model Access
|
## Formatting, Validation, And Model Access
|
||||||
|
|
||||||
| Component | Implemented responsibility | References |
|
| Component | Implemented responsibility | References |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `internal/format` | Formats prepared-run information for CLI output. | [CLI contract](../cli.md), [adapter internals](adapters.md) |
|
| `internal/format` | Formats public prepared-run information for CLI output. | [CLI contract](../cli.md), [adapter internals](adapters.md) |
|
||||||
| `internal/validate` | Defines validation interfaces and provides standard filesystem and `fs.FS` schema validation. | [configuration contract](../config.md), [source internals](sources.md), [runner internals](runner.md) |
|
| `internal/validate` | Defines validation interfaces and provides standard filesystem and `fs.FS` schema validation. | [configuration contract](../config.md), [source internals](sources.md), [runner internals](runner.md) |
|
||||||
| `internal/llm` | Defines the provider-neutral LLM client boundary and its OpenAI-compatible implementation. | [OpenAI-compatible integration](../integrations/openai-compatible-chat.md), [LLM internals](llm.md), [runner internals](runner.md) |
|
| `internal/llm` | Defines the provider-neutral LLM client boundary and its OpenAI-compatible implementation. | [OpenAI-compatible integration](../integrations/openai-compatible-chat.md), [LLM internals](llm.md), [runner internals](runner.md) |
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,9 @@ contracts.
|
|||||||
- an optional `OutputRepairer`.
|
- an optional `OutputRepairer`.
|
||||||
|
|
||||||
`NewRunner` constructs a runner without a repairer. `NewRunnerWithRepairer`
|
`NewRunner` constructs a runner without a repairer. `NewRunnerWithRepairer`
|
||||||
accepts one explicitly. Adapters and the public engine choose concrete
|
accepts one explicitly. The public engine chooses concrete repositories and
|
||||||
repositories and readers; the runner does not load application configuration.
|
readers; executable adapters reach the runner only through that engine. The
|
||||||
|
runner does not load application configuration.
|
||||||
|
|
||||||
## Prepare Flow
|
## Prepare Flow
|
||||||
|
|
||||||
@@ -68,8 +69,9 @@ validation mode is JSON or JSON Schema. Each repair receives the previous
|
|||||||
output, validation errors, effective target, structured-output specification,
|
output, validation errors, effective target, structured-output specification,
|
||||||
and attempt metadata; every repaired result is validated again.
|
and attempt metadata; every repaired result is validated again.
|
||||||
|
|
||||||
`NewDefaultOutputRepairer` delegates to the injected LLM client. CLI, HTTP, and
|
`NewDefaultOutputRepairer` delegates to the injected LLM client. The public
|
||||||
the public engine use `NewRunner` and therefore do not inject this repairer.
|
engine, and therefore CLI and HTTP, uses `NewRunner` and does not inject this
|
||||||
|
repairer.
|
||||||
|
|
||||||
## Error Translation
|
## Error Translation
|
||||||
|
|
||||||
@@ -104,7 +106,6 @@ values in prepared or run results.
|
|||||||
Inspect:
|
Inspect:
|
||||||
|
|
||||||
- `internal/usecase/runner_test.go`
|
- `internal/usecase/runner_test.go`
|
||||||
- `internal/usecase/integration_test.go`
|
|
||||||
- `engine_test.go`
|
- `engine_test.go`
|
||||||
|
|
||||||
When changing orchestration:
|
When changing orchestration:
|
||||||
|
|||||||
@@ -50,14 +50,11 @@ failures are operational errors.
|
|||||||
|
|
||||||
## Artifacts
|
## Artifacts
|
||||||
|
|
||||||
`internal/artifact` composes inline and file readers. The ordinary composite
|
`internal/artifact` owns the framework's ordinary inline and unrestricted file
|
||||||
reader used by CLI and the public engine reads file references from the process
|
reader. The public engine uses it by default and permits consumers to replace it
|
||||||
filesystem. `internal/adapter/http` provides the restricted public artifact
|
for every input through the public `ArtifactReader` extension. The
|
||||||
reader for HTTP containment: it combines inline reading with a rooted file
|
HTTP adapter owns its restricted reader for HTTP containment: `serve` injects
|
||||||
reader and optional byte limit. The existing internal restricted composite
|
that reader into the public engine with `WithArtifactReader`.
|
||||||
reader remains a temporary bridge for the current handler and serve wiring; it
|
|
||||||
does not define the HTTP reader's long-term boundary or carry a compatibility
|
|
||||||
promise.
|
|
||||||
|
|
||||||
The rooted reader cleans paths and applies lexical containment without resolving
|
The rooted reader cleans paths and applies lexical containment without resolving
|
||||||
symlinks. It checks relative references against the configured root and accepts
|
symlinks. It checks relative references against the configured root and accepts
|
||||||
@@ -70,8 +67,9 @@ by the [HTTP API reference](../api.md); deployment permissions belong in
|
|||||||
|
|
||||||
Source packages report repository, decoding, duplicate, validation, and read
|
Source packages report repository, decoding, duplicate, validation, and read
|
||||||
failures to their callers. They do not select public status codes or response
|
failures to their callers. They do not select public status codes or response
|
||||||
schemas. The runner wraps source failures with use-case categories; adapters map
|
schemas. The runner categorizes source failures and the public engine preserves
|
||||||
them to their own external contract.
|
the corresponding public error identities; adapters map those identities to
|
||||||
|
their own external contract.
|
||||||
|
|
||||||
Source reads use current filesystem or `fs.FS` content for each request. These
|
Source reads use current filesystem or `fs.FS` content for each request. These
|
||||||
packages create no manifests, checkpoints, or durable run state.
|
packages create no manifests, checkpoints, or durable run state.
|
||||||
@@ -86,7 +84,6 @@ Inspect:
|
|||||||
- `internal/artifact/reader_test.go`
|
- `internal/artifact/reader_test.go`
|
||||||
- `internal/adapter/http/artifact_reader_test.go`
|
- `internal/adapter/http/artifact_reader_test.go`
|
||||||
- `internal/validate/standard_validator_test.go`
|
- `internal/validate/standard_validator_test.go`
|
||||||
- `internal/usecase/integration_test.go`
|
|
||||||
- `engine_test.go`
|
- `engine_test.go`
|
||||||
|
|
||||||
When updating prompt, profile, schema, or built-in assets:
|
When updating prompt, profile, schema, or built-in assets:
|
||||||
|
|||||||
@@ -8,15 +8,18 @@ It is for developers and LLM coding agents. User-facing behavior belongs in `REA
|
|||||||
|
|
||||||
Scriptorium is a narrow prompt-execution application with three executable
|
Scriptorium is a narrow prompt-execution application with three executable
|
||||||
entry paths: CLI `run`, CLI `render`, and the HTTP service started by `serve`.
|
entry paths: CLI `run`, CLI `render`, and the HTTP service started by `serve`.
|
||||||
It also provides a public Go package for in-process use. Its current component
|
It also provides a public Go package for in-process use. Executable adapters
|
||||||
inventory is maintained in the [internal overview](../internal/overview.md).
|
consume framework behavior through that public facade; the facade continues to
|
||||||
|
compose the framework implementation inside this single repository. Its current
|
||||||
|
component inventory is maintained in the [internal overview](../internal/overview.md).
|
||||||
|
|
||||||
Domain behavior is centralized in `internal/usecase` and `internal/domain`.
|
Domain behavior is centralized in `internal/usecase` and `internal/domain`.
|
||||||
|
|
||||||
## Core Principles
|
## Core Principles
|
||||||
|
|
||||||
- Keep orchestration narrow: Scriptorium executes one prompt request; it is not a multi-step workflow engine.
|
- 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 adapter logic thin: adapters map external shapes to public engine
|
||||||
|
requests/results and should not hold framework decisions.
|
||||||
- Keep boundaries explicit: repositories/loaders/renderers/validators/LLM client stay behind package interfaces.
|
- Keep boundaries explicit: repositories/loaders/renderers/validators/LLM client stay behind package interfaces.
|
||||||
- Keep external decoding strict: configuration, prompt, and profile YAML and
|
- Keep external decoding strict: configuration, prompt, and profile YAML and
|
||||||
HTTP JSON should reject unknown fields.
|
HTTP JSON should reject unknown fields.
|
||||||
@@ -26,6 +29,9 @@ Domain behavior is centralized in `internal/usecase` and `internal/domain`.
|
|||||||
|
|
||||||
- Adapters translate external shapes and IO concerns; they do not make
|
- Adapters translate external shapes and IO concerns; they do not make
|
||||||
use-case decisions.
|
use-case decisions.
|
||||||
|
- Executable adapters and prepared-run formatting use the public facade for
|
||||||
|
framework behavior rather than importing framework implementation packages
|
||||||
|
directly.
|
||||||
- Use-case and domain code depend on explicit repository, renderer, validator,
|
- Use-case and domain code depend on explicit repository, renderer, validator,
|
||||||
and LLM interfaces rather than adapter implementations.
|
and LLM interfaces rather than adapter implementations.
|
||||||
- Source, rendering, validation, and LLM implementations remain behind their
|
- Source, rendering, validation, and LLM implementations remain behind their
|
||||||
@@ -52,7 +58,8 @@ their implementation.
|
|||||||
## Error Handling And Logging
|
## Error Handling And Logging
|
||||||
|
|
||||||
- Wrap errors with domain/operation context.
|
- Wrap errors with domain/operation context.
|
||||||
- Map domain errors to adapter-appropriate statuses/codes without leaking sensitive internals.
|
- Map public error identities to adapter-appropriate statuses/codes without
|
||||||
|
leaking sensitive internals.
|
||||||
- Never emit raw secret values.
|
- Never emit raw secret values.
|
||||||
|
|
||||||
## Testing And Documentation
|
## Testing And Documentation
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Proposed. Implement each stage in order and satisfy its gate before continuing.
|
Complete as of 2026-07-28. All implementation gates, the dependency guard,
|
||||||
|
documentation reconciliation, and required validation passed. Migration Step 5
|
||||||
|
repository creation is the next gate; it was not started here.
|
||||||
|
|
||||||
## Objective
|
## Objective
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Accepted plan. Steps 1 through 3 are complete. Steps 4 through 9 remain
|
Accepted plan. Steps 1 through 4 are complete. Steps 5 through 9 remain
|
||||||
proposed and are not yet implemented.
|
proposed and are not yet implemented.
|
||||||
|
|
||||||
## Objective
|
## Objective
|
||||||
@@ -125,8 +125,8 @@ is accepted and records the required ownership and coordination decisions.
|
|||||||
Strengthen or add contract-focused tests where needed so extraction can be
|
Strengthen or add contract-focused tests where needed so extraction can be
|
||||||
verified without relying on package placement.
|
verified without relying on package placement.
|
||||||
|
|
||||||
The accepted implementation scope and intended completion state are in the
|
The completed Step 3 gate records the accepted implementation scope and
|
||||||
[Step 3 framework-characterization roadmap](step3.md).
|
intended completion state.
|
||||||
|
|
||||||
Preserve coverage of:
|
Preserve coverage of:
|
||||||
|
|
||||||
@@ -172,6 +172,12 @@ implementations.
|
|||||||
**Gate:** The CLI and HTTP adapters use only the public framework API for
|
**Gate:** The CLI and HTTP adapters use only the public framework API for
|
||||||
framework behavior, and all tests and documented smoke commands pass.
|
framework behavior, and all tests and documented smoke commands pass.
|
||||||
|
|
||||||
|
**Gate status:** Complete as of 2026-07-28. CLI `run`, `render`, and `serve`,
|
||||||
|
the HTTP handler, and prepared-run formatting use the public facade; the
|
||||||
|
restricted HTTP reader is injected through the public extension point. The
|
||||||
|
dependency guard, full tests, vet, build, race checks, maintained examples, and
|
||||||
|
configuration smoke checks passed. Step 5 repository creation is next.
|
||||||
|
|
||||||
### Step 5: Create The Promptkit Repository
|
### Step 5: Create The Promptkit Repository
|
||||||
|
|
||||||
Create the Promptkit repository and Go module as an explicit out-of-band
|
Create the Promptkit repository and Go module as an explicit out-of-band
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Proposed. Migration Steps 1 through 3 are complete; this roadmap defines the
|
Complete as of 2026-07-28. The public-facade adapter boundary is established;
|
||||||
required target state for Step 4. The separate
|
the [implementation plan](implementation.md) records the completed work, and
|
||||||
[implementation plan](implementation.md) defines the ordered work.
|
the [main migration roadmap](migration.md) identifies repository creation as
|
||||||
|
the next gate.
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
@@ -19,31 +20,18 @@ owns the long-term project boundary. The
|
|||||||
[main migration roadmap](migration.md) owns the overall sequence. This feature
|
[main migration roadmap](migration.md) owns the overall sequence. This feature
|
||||||
roadmap defines the desired Step 4 state, not an implementation sequence.
|
roadmap defines the desired Step 4 state, not an implementation sequence.
|
||||||
|
|
||||||
## Current Gap
|
## Achieved Boundary
|
||||||
|
|
||||||
The public `Engine` facade already supports the ordinary `Prepare` and `Run`
|
The CLI, HTTP handler, and prepared-run formatter now consume public engine
|
||||||
workflows, directory and alternate framework sources, injected model clients,
|
values and errors. `serve` injects Scriptorium's HTTP-owned restricted artifact
|
||||||
public result values, and broad public error classification. The executable
|
reader through the public extension point, while the root facade continues to
|
||||||
adapters do not yet use that boundary consistently:
|
compose the framework implementation inside this repository. A repository-level
|
||||||
|
dependency test protects the direct-import boundary.
|
||||||
- the CLI constructs framework repositories, readers, renderer, validator, and
|
|
||||||
OpenAI-compatible client directly, then calls the internal runner;
|
|
||||||
- the HTTP handler accepts internal domain request and result values;
|
|
||||||
- HTTP error mapping inspects framework-internal sentinels;
|
|
||||||
- the HTTP artifact-containment reader implements the internal artifact-reader
|
|
||||||
interface;
|
|
||||||
- prepared-run formatting accepts an internal domain value; and
|
|
||||||
- adapter tests frequently construct internal runners or use internal domain
|
|
||||||
values.
|
|
||||||
|
|
||||||
Those dependencies would prevent Scriptorium from compiling after the
|
|
||||||
framework packages move to Promptkit. They also allow the executable to exercise
|
|
||||||
a different composition path from downstream Go consumers.
|
|
||||||
|
|
||||||
## Target State
|
## Target State
|
||||||
|
|
||||||
At completion, Scriptorium's executable path is an ordinary consumer of the
|
Scriptorium's executable path is an ordinary consumer of the same public
|
||||||
same public framework boundary used by other Go applications:
|
framework boundary used by other Go applications:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
cmd/scriptorium
|
cmd/scriptorium
|
||||||
|
|||||||
64
internal/adapter/dependency_test.go
Normal file
64
internal/adapter/dependency_test.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package adapter_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go/parser"
|
||||||
|
"go/token"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestScriptoriumAdaptersUseOnlyPublicFrameworkBoundary(t *testing.T) {
|
||||||
|
_, testFile, _, ok := runtime.Caller(0)
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("locate dependency guard source")
|
||||||
|
}
|
||||||
|
|
||||||
|
adapterDir := filepath.Dir(testFile)
|
||||||
|
directories := []string{
|
||||||
|
filepath.Join(adapterDir, "cli"),
|
||||||
|
filepath.Join(adapterDir, "http"),
|
||||||
|
filepath.Join(adapterDir, "..", "format"),
|
||||||
|
}
|
||||||
|
forbidden := map[string]struct{}{
|
||||||
|
"gitea.maximumdirect.net/eric/scriptorium/internal/domain": {},
|
||||||
|
"gitea.maximumdirect.net/eric/scriptorium/internal/usecase": {},
|
||||||
|
"gitea.maximumdirect.net/eric/scriptorium/internal/promptdef": {},
|
||||||
|
"gitea.maximumdirect.net/eric/scriptorium/internal/prompt": {},
|
||||||
|
"gitea.maximumdirect.net/eric/scriptorium/internal/profile": {},
|
||||||
|
"gitea.maximumdirect.net/eric/scriptorium/internal/profile/builtin": {},
|
||||||
|
"gitea.maximumdirect.net/eric/scriptorium/internal/validate": {},
|
||||||
|
"gitea.maximumdirect.net/eric/scriptorium/internal/llm": {},
|
||||||
|
"gitea.maximumdirect.net/eric/scriptorium/internal/artifact": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, directory := range directories {
|
||||||
|
entries, err := os.ReadDir(directory)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("read source directory %s: %v", directory, err)
|
||||||
|
}
|
||||||
|
for _, entry := range entries {
|
||||||
|
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".go") || strings.HasSuffix(entry.Name(), "_test.go") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
path := filepath.Join(directory, entry.Name())
|
||||||
|
file, err := parser.ParseFile(token.NewFileSet(), path, nil, parser.ImportsOnly)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parse imports in %s: %v", path, err)
|
||||||
|
}
|
||||||
|
for _, imported := range file.Imports {
|
||||||
|
importPath, err := strconv.Unquote(imported.Path.Value)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parse import path in %s: %v", path, err)
|
||||||
|
}
|
||||||
|
if _, found := forbidden[importPath]; found {
|
||||||
|
t.Errorf("%s directly imports forbidden framework package %s", path, importPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user