Files
scriptorium/docs/roadmap/step7.md

340 lines
16 KiB
Markdown

# Migration Step 7: Slim Scriptorium And Adopt Promptkit
## Status
Proposed.
## Purpose
Complete Scriptorium's application-side cutover to the independently published
Promptkit library. After this work, Scriptorium is a runnable CLI and HTTP
application built on Promptkit's supported public API rather than a second
owner of the prompt-execution framework.
This roadmap defines the required end state for Step 7. The
[main migration roadmap](migration.md) owns the overall migration sequence,
while
[ADR 0002](../adr/0002-split-promptkit-from-scriptorium.md) owns the durable
project, package, configuration, compatibility, and documentation boundaries.
## Starting Point
Promptkit is independently published as module
`gitea.maximumdirect.net/eric/promptkit` at annotated tag `v0.1.0`. That release
contains the characterized framework, root public facade, built-in profile
registry, maintained framework tests, and consumer documentation extracted in
Step 6.
Scriptorium intentionally still contains the pre-cutover copy of that
framework. Its executable adapters already consume framework behavior through
the local root facade, which provides a narrow migration seam. Step 7 replaces
that local facade with Promptkit and removes the duplicated implementation; it
does not redesign the framework or the executable interfaces.
## Desired End State
Scriptorium is an application-only Go module with this dependency direction:
```text
scriptorium command
|
v
CLI and HTTP adapters, application config, and output formatting
|
v
gitea.maximumdirect.net/eric/promptkit public package
|
v
Promptkit-owned framework implementation
```
The Scriptorium module root no longer provides an importable Go package.
Scriptorium has no compatibility facade, type aliases, forwarding functions,
or deprecated wrappers for the former `scriptorium` public API. Go consumers
must import Promptkit; consumers that have not migrated may remain pinned to a
previous framework-bearing Scriptorium version as established by ADR 0002.
## Promptkit Dependency
Scriptorium must declare
`gitea.maximumdirect.net/eric/promptkit v0.1.0` as a direct module dependency.
Production code, tests, examples, builds, and release configuration must
resolve that published tag without a committed workspace, local filesystem
replacement, vendored Promptkit copy, or unpublished revision.
The cutover must use only Promptkit's supported root package. Scriptorium must
not import, copy, or depend conceptually on Promptkit implementation packages.
No Promptkit API expansion is expected for this step: Step 4 established the
required application seam, and Step 6 published it. If implementation discovers
a genuine missing Promptkit capability, that is a cross-repository blocker:
the capability must be accepted, implemented, validated, and tagged in
Promptkit before Scriptorium can depend on it.
Dependencies used only by the removed framework must leave Scriptorium's
`go.mod` and `go.sum`. Scriptorium retains only dependencies required by its
application-owned code. The module's Go version remains compatible with the
selected Promptkit release.
## Application Assembly And Adapter Boundary
The CLI must construct `promptkit.Engine` values from Scriptorium's resolved
application settings. It must translate Scriptorium CLI inputs and execution
overrides into `promptkit.RunRequest`, `promptkit.ArtifactRef`, and
`promptkit.ExecutionTargetOverride` values without introducing a parallel
application model.
The `run` command must invoke `promptkit.Engine.Run`; the `render` command must
invoke `promptkit.Engine.Prepare`. The `serve` command must inject
Scriptorium's restricted artifact reader through
`promptkit.WithArtifactReader` and pass the engine to the HTTP adapter through
the adapter-owned consumer interface.
The HTTP adapter's `Runner` interface remains owned by Scriptorium because it
is a consumer-side test and substitution boundary. Its method uses Promptkit
request and result types. Request DTOs, response DTOs, strict JSON decoding,
HTTP limits, error-to-status mapping, response encoding, and route behavior
remain Scriptorium concerns and must not move into Promptkit.
Prepared-run formatting remains in Scriptorium because text and JSON output
selection is an executable presentation concern. The formatter operates
directly on Promptkit public prepared-run values; it must not introduce copied
framework types.
## Artifact And Security Boundary
Scriptorium retains its HTTP-specific restricted artifact reader. The reader
must implement `promptkit.ArtifactReader` and consume and return Promptkit
artifact values directly.
The cutover must preserve the current HTTP artifact policy:
- an empty artifact root permits inline artifacts and denies file references;
- configured byte limits apply to file artifacts, with zero meaning unlimited;
- file paths are checked using the documented lexical root-containment rule;
- symlinks retain their currently documented behavior;
- content type, size, hash, name, URI, and cancellation behavior remain
observable through the same HTTP contract; and
- Scriptorium reader errors remain identifiable so the HTTP adapter can
preserve its existing status and error-code mappings.
Ordinary in-process and CLI file reading belongs to Promptkit. Scriptorium must
not retain its former general-purpose artifact reader or framework artifact
package after the cutover.
## Configuration And Defaults
Scriptorium continues to own:
- configuration discovery and strict YAML decoding;
- configuration-file and CLI precedence;
- `prompt_dir`, `profile_dir`, and `schema_dir` as application source
locations;
- `server.*` settings and transport byte limits;
- the default prepared-run output format; and
- CLI, HTTP server, and process defaults.
These settings are translated into Promptkit construction options and request
values at the application boundary. When omission means “use Promptkit's
framework default,” Scriptorium must leave the value unset rather than
redeclare a Promptkit constant.
Promptkit owns prompt, profile, and output-contract file semantics; built-in
profiles; execution-setting resolution; validation behavior; output-artifact
and framework content-type defaults; OpenAI-compatible request behavior; and
generation and transport timeout semantics. Scriptorium's defaults package
must be reduced to application and transport defaults still used by the CLI,
HTTP server, configuration loader, or output formatter.
The cutover must not change documented configuration discovery, CLI
precedence, source-path interpretation, server limits, or render-format
behavior.
## Package And Asset Disposition
The following Scriptorium components remain:
| Component | Retained responsibility |
| --- | --- |
| `cmd/scriptorium` | Runnable process entrypoint. |
| `internal/adapter/cli` | CLI parsing, application assembly, streams, files, summaries, and exit codes. |
| `internal/adapter/http` | Routes, DTOs, strict decoding, HTTP limits and mappings, and restricted artifact reading. |
| `internal/config` | Application configuration discovery, decoding, validation, defaults, and CLI precedence. |
| `internal/format` | Prepared-run text and JSON presentation using Promptkit public values. |
| `internal/defaults` | Scriptorium-only CLI, HTTP, server, and application defaults. |
| `.woodpecker`, release metadata, and executable packaging | Scriptorium build and binary-release behavior. |
The following duplicated framework components must be removed from
Scriptorium:
- all root-package facade source and tests;
- `internal/artifact`, `internal/domain`, `internal/filecatalog`,
`internal/llm`, `internal/profile`, `internal/prompt`,
`internal/promptdef`, `internal/usecase`, and `internal/validate`;
- embedded built-in profile assets and framework-package test fixtures;
- the root framework contract tests and `testdata/framework`; and
- `examples/go-library`, which is owned and maintained by Promptkit.
Tests remain with the behavior they protect. Scriptorium retains and adapts
application configuration, adapter, formatting, HTTP containment, command, and
representative executable-workflow coverage. It must not retain duplicate
Promptkit unit or contract tests merely to exercise dependency internals.
The executable examples under `examples/` remain when they support
Scriptorium's CLI or HTTP workflows. This includes application configuration,
render scripts, HTTP requests, prompt/profile/schema inputs, and synthetic
fixtures needed by those workflows. Their format semantics are owned by
Promptkit documentation even though the files remain runnable Scriptorium
assets.
## Observable Behavior To Preserve
Step 7 is an ownership and dependency cutover, not an intentional CLI or HTTP
contract change. Subject to the deliberate removal of the public Scriptorium
Go package, preserve:
- the `run`, `render`, and `serve` command names, flags, precedence, output
destinations, summaries, exit classifications, and process behavior;
- application configuration schema, discovery, validation, and defaults;
- HTTP route, method, request and response shapes, strict decoding, media
types, size enforcement, status codes, and stable error codes;
- prompt, profile, execution-setting, request-override, and validation
behavior as supplied by Promptkit `v0.1.0`;
- built-in profile availability and custom-profile overlay behavior;
- presence-aware zero-valued execution overrides;
- the rule that explicit timeout zero disables only the generation deadline,
while caller cancellation and the transport cap remain active;
- public error identity as consumed by Scriptorium's CLI and HTTP mappings;
- structured-output requests, output validation, and validation-failure
classification;
- strict external YAML and JSON decoding;
- secret resolution and redaction; and
- deterministic prepared-run formatting and output metadata.
Any observable application change discovered during implementation must be
treated as a regression unless this roadmap, an accepted ADR, or a separately
approved feature decision authorizes it.
## Architecture Enforcement
Repository checks must make the new dependency direction durable. They must
detect production imports of:
- the removed Scriptorium root facade;
- former Scriptorium framework package families; and
- Promptkit `internal` packages.
The checks must cover the command, adapters, configuration, formatting, and
other remaining production packages recursively without treating test-only
fixtures as the application architecture. Go's own `internal` enforcement is
useful but does not replace a repository-level check that explains the intended
boundary.
The final tree must contain no duplicate framework directories, embedded
built-in registry, copied Promptkit source, or dormant compatibility package.
## Documentation End State
Permanent Scriptorium documentation must describe the implemented slim
application only:
- `README.md` presents the runnable CLI and HTTP application and contains no
in-process Go-library positioning;
- `docs/policy/architecture.md` defines Scriptorium as a Promptkit consumer and
removes the single-repository framework architecture;
- `docs/development.md` routes contributors through the retained application
packages and the Promptkit contracts relevant to cross-project work;
- `docs/internal/overview.md` inventories only the remaining Scriptorium
packages;
- CLI, HTTP, configuration, operations, adapter, source, and subprocess
documents retain their application-owned contracts and mechanics;
- the former Scriptorium Go-package consumer guide is retired, and incoming
navigation directs Go framework consumers to Promptkit;
- framework format and OpenAI-compatible behavior are linked to their
canonical Promptkit owners rather than redefined in Scriptorium;
- former runner, model-client, source, and other internal framework
documentation is removed or reduced to the application-owned boundary where
such a boundary still exists;
- maintained examples and all documentation links refer only to files and
commands that remain; and
- future release and downstream-consumer work remains in the migration roadmap
until Steps 8 and 9 are completed.
Promptkit's existing references to Scriptorium as a downstream application
become accurate when this cutover lands. Step 7 does not otherwise change
Promptkit's public API, implementation, version, or release documentation.
## Validation Expectations
Validation must demonstrate the resulting boundary and behavior, not the
deleted implementation structure.
Scriptorium must pass:
- all ordinary and race-enabled Go tests;
- `go vet` for all remaining packages;
- an executable build to a temporary output path;
- formatting, module-tidiness, whitespace, documentation-link, and repository
hygiene checks;
- maintained executable examples other than the retired Go-library example;
- both maintained application configuration examples;
- representative HTTP handler and restricted-artifact workflows; and
- architecture checks proving the absence of the former framework dependency
direction.
Validation must run with no active Go workspace and no module replacement.
Module inspection must show the tagged Promptkit dependency selected directly.
Promptkit must continue to pass its own documented validation independently;
Scriptorium validation must not rely on the sibling Promptkit checkout.
Scriptorium's hosted validation and executable release workflow must remain
capable of resolving the public Promptkit tag and building the command without
cross-repository filesystem state.
## Non-Goals
Step 7 does not:
- redesign or broaden Promptkit's public API;
- preserve source compatibility for the former Scriptorium Go package;
- migrate downstream repositories other than Scriptorium;
- publish the breaking Scriptorium release or general downstream migration
guide assigned to Steps 8 and 9;
- change CLI, HTTP, configuration, prompt, profile, schema, validation, model,
or timeout contracts;
- move Scriptorium transport, deployment, or presentation policy into
Promptkit;
- add hosted CI or binary releases to Promptkit; or
- retain duplicated code or documentation as a fallback.
## Completion Criteria
Step 7 is complete only when all of the following are true:
- Scriptorium declares and resolves
`gitea.maximumdirect.net/eric/promptkit v0.1.0` as a direct dependency with no
workspace, replacement, vendored copy, or unpublished revision.
- The command, CLI adapter, HTTP adapter, restricted artifact reader, and
prepared-run formatter use Promptkit public values and interfaces.
- The Scriptorium module root exposes no Go package or compatibility facade.
- Every Promptkit-owned framework package, built-in asset copy, framework test,
fixture corpus, and Go-library example has been removed from Scriptorium.
- Only application-owned configuration, adapter, formatting, transport,
process, packaging, and executable-example responsibilities remain.
- CLI, HTTP, configuration, containment, formatting, error-mapping, security,
and representative end-to-end behavior remain protected by passing
Scriptorium-owned tests.
- Architecture checks prevent imports of the former local framework and
Promptkit internals.
- Scriptorium's current documentation describes the slim application and links
to Promptkit for framework contracts without duplicating them.
- Both repositories validate independently, and Scriptorium's full test, race,
vet, build, example, link, module, and hygiene checks pass against the
published Promptkit tag.
- The working tree contains no generated binaries, temporary workspaces,
replacement directives, credentials, or migration residue.
**Gate:** Scriptorium is a clean, independently buildable CLI and HTTP consumer
of the published Promptkit module, contains no reusable framework
implementation or public Go facade, preserves its application contracts, and
is ready for the out-of-band downstream-consumer migrations in Step 8.