diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index a99776e..0622742 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,460 +1,19 @@ -# Step 7 Implementation Plan +# Step 7 Implementation Completion ## Status -Accepted for implementation. +Complete as of 2026-07-28. -Implement each stage in order. Do not begin a later stage until the current -stage's exit criteria pass. The -[Step 7 feature roadmap](step7.md) is the north star for scope, policy, desired -behavior, and completion. [ADR 0002](../adr/0002-split-promptkit-from-scriptorium.md) -controls the durable project boundary. +## Result -This plan changes Scriptorium only. Promptkit `v0.1.0` is a published, -read-only input to the cutover. Do not edit Promptkit, create a new Promptkit -tag, or use the sibling Promptkit checkout to make an intermediate -Scriptorium state pass. +Scriptorium now consumes +`gitea.maximumdirect.net/eric/promptkit v0.1.0` as an ordinary direct module +dependency. The published tag resolves to Promptkit commit +`9e68a2bbf779545995270c47842048a3bc6c85dc`; no workspace, replacement, +vendored dependency, or sibling-repository state is required. -## Implementation Rules - -Apply these rules throughout every stage: - -- Read both repositories' development, architecture, documentation, and - testing policies before implementation. -- Preserve unrelated working-tree changes. The removals of completed roadmap - files that predate this plan are user-owned changes and must not be restored. -- Run Scriptorium commands outside a Go workspace. Do not commit `go.work`, - `go.work.sum`, a local `replace`, vendored Promptkit source, or generated - dependency output. -- Depend only on - `gitea.maximumdirect.net/eric/promptkit v0.1.0` and its root `promptkit` - package. Do not import `promptkit/internal/...`. -- Treat the former Scriptorium Go package as intentionally removed. Do not add - aliases, forwarding wrappers, deprecated shims, or an application-local copy - of Promptkit values. -- Preserve CLI, HTTP, configuration, formatting, artifact-containment, - security, error-mapping, and process behavior unless the feature roadmap - explicitly says otherwise. -- Prefer adapting existing application tests to Promptkit values over adding - parallel test suites. Delete tests whose only owner is the removed framework. -- Keep permanent documentation aligned with implemented state. Do not describe - a later stage as complete before its code has landed. -- Use `gofmt` for Go formatting and `go mod tidy` for module metadata. Do not - hand-edit `go.sum`. - -If a required capability is absent from Promptkit `v0.1.0`, stop the Step 7 -implementation and report the exact public-boundary gap. Do not work around it -with a Scriptorium framework copy or an unpublished Promptkit revision. - -## Stage 1: Cut The Application Seam Over To Promptkit - -### Objective - -Make all retained Scriptorium application code and tests consume the published -Promptkit facade while the old local framework remains temporarily available -for comparison. This stage proves that `v0.1.0` is sufficient before deleting -the old implementation. - -### Module Dependency - -Add an exact direct requirement: - -```text -gitea.maximumdirect.net/eric/promptkit v0.1.0 -``` - -Resolve it from the configured module source with `GOWORK=off`. Do not add a -replacement. Do not prune the old framework-only dependencies yet; the local -framework still compiles during this stage. - -Confirm before changing imports that the selected module resolves to -`v0.1.0` and that its origin hash is the accepted Promptkit release commit -`9e68a2bbf779545995270c47842048a3bc6c85dc`. - -### Production Import And Type Migration - -Replace the former root-package import with -`gitea.maximumdirect.net/eric/promptkit` in every retained application package. -Use the package name `promptkit` in code rather than aliasing it back to -`scriptorium`. - -Update `internal/adapter/cli/run.go` so: - -- engine construction calls `promptkit.NewEngine` with `promptkit.Config`; -- `run` and `render` requests use `promptkit.RunRequest`; -- input mappings use `promptkit.File` and Promptkit artifact references; -- execution overrides use `promptkit.ExecutionTargetOverride`; -- the `serve` path injects the HTTP reader with - `promptkit.WithArtifactReader`; -- result summaries, validation classification, and exit-code selection use - Promptkit result and status values; and -- no CLI flag, precedence, output, or error wording changes solely because of - the import migration. - -Update `internal/adapter/http` so: - -- the adapter-owned `Runner` interface accepts `promptkit.RunRequest` and - returns `*promptkit.RunResult`; -- DTO mapping constructs Promptkit artifact references and execution - overrides; -- response mapping reads Promptkit artifact, validation, model, usage, and - metadata values directly; -- HTTP error mapping uses Promptkit's public sentinel errors with `errors.Is`; - and -- the restricted reader implements `promptkit.ArtifactReader` and uses - Promptkit artifact reference, artifact, and reference-type values. - -Keep `ErrFileNotAllowed`, `ErrFileOutsideRoot`, and `ErrFileTooLarge` in -Scriptorium. Confirm that Promptkit's artifact-load wrapping preserves those -underlying identities so the existing HTTP mappings continue to work. - -Update `internal/format` so every formatter interface, entry point, message -collection, and test fixture uses Promptkit prepared-run and message values -directly. - -### Test Migration - -Update retained CLI, HTTP, restricted-reader, and formatter tests to import and -construct Promptkit public values. In particular: - -- fake runners must use the Promptkit request/result signature; -- handler integration helpers must construct a real `promptkit.Engine`; -- test LLM clients must implement `promptkit.LLMClient`; -- engine options must use Promptkit options; -- error-mapping tables must use Promptkit sentinels; and -- formatting fixtures must use Promptkit public prepared-run types. - -Do not change expected CLI output, HTTP payloads, status codes, error codes, -artifact policy, or formatted render output merely to accommodate the new -package name. - -### Validation - -Run: - -```sh -go mod download gitea.maximumdirect.net/eric/promptkit@v0.1.0 -go list -m -f '{{.Path}} {{.Version}}' gitea.maximumdirect.net/eric/promptkit -go test ./internal/adapter/... ./internal/format/... -go test ./... -go vet ./... -go build ./cmd/scriptorium -``` - -Also run the maintained render script and the existing CLI command tests that -exercise built-in profiles, custom profiles, explicit zero-valued overrides, -restricted HTTP artifacts, public error mapping, and prepared-run formatting. - -### Exit Criteria - -- All retained application production code uses Promptkit public types. -- Application tests use Promptkit at the same boundaries as production. -- The exact direct `v0.1.0` dependency is selected without a replacement. -- The full repository still builds and tests while the local framework copy is - present but unused by retained application code. -- No Promptkit API gap has been discovered. - -## Stage 2: Remove The Duplicated Framework - -### Objective - -Delete every Promptkit-owned implementation, facade, test, fixture, and example -from Scriptorium, then reduce application defaults and module dependencies to -the slim repository boundary. - -### Remove The Former Root Package - -Delete the complete former root facade: - -- `artifact_reader.go` -- `artifact_reader_internal_test.go` -- `convert.go` -- `engine.go` -- `engine_test.go` -- `errors.go` -- `formatting.go` -- `json_copy.go` -- `llm_adapter.go` -- `profiles.go` -- `types.go` - -After deletion, the Scriptorium module root must contain no `.go` files and -must not be importable as package `gitea.maximumdirect.net/eric/scriptorium`. -Do not replace these files with a stub package or migration shim. - -### Remove Promptkit-Owned Internal Packages - -Delete these directories in full, including their package tests, testdata, and -embedded assets: - -- `internal/artifact` -- `internal/domain` -- `internal/filecatalog` -- `internal/llm` -- `internal/profile` -- `internal/prompt` -- `internal/promptdef` -- `internal/usecase` -- `internal/validate` - -Delete `testdata/framework`. Promptkit owns the framework contract corpus and -already contains its maintained copy. - -Delete `examples/go-library`. The Scriptorium Go-library example is obsolete; -Promptkit owns the maintained in-process preparation example. - -Do not delete the executable assets under `examples/config*.yml`, -`examples/prompts`, `examples/profiles`, `examples/schemas`, -`examples/fixtures`, `examples/http-run.json`, or -`examples/render-markdown-summary.sh`. Those remain Scriptorium application -examples even though Promptkit owns their file-format semantics. - -### Split Defaults By Ownership - -Reduce `internal/defaults/defaults.go` to values still owned and used by -Scriptorium: - -- `HTTPAddrDefault` -- `SchemaDirDefault`, which remains the application configuration default for - Scriptorium's schema source location; -- `HTTPMaxRequestBytesDefault` -- `HTTPMaxArtifactBytesDefault` -- `HTTPMaxResponseBytesDefault`; and -- `HTTPReadHeaderTimeoutDefault`. - -Remove framework-owned output-artifact names, content types, -OpenAI-compatible paths, execution defaults, model-client timeouts, domain -imports, and `ExecutionTargetDefault`. - -Do not copy constants from Promptkit merely to make tests convenient. When the -CLI does not supply a framework setting, continue passing the zero value so -Promptkit applies its own default. - -### Prune Module Metadata - -Run `go mod tidy` only after all Promptkit-owned source and tests are gone. -Keep `gopkg.in/yaml.v3` as a direct dependency because Scriptorium still -decodes application configuration. Allow `go mod tidy` to remove or reclassify -JSON Schema and other modules according to the actual remaining import graph. - -The final `go.mod` must have: - -- Promptkit `v0.1.0` as a direct dependency; -- no `replace` directive; -- no dependency retained solely for deleted framework code; and -- the existing compatible Go language version. - -### Validation - -Run: - -```sh -go mod tidy -go list ./... -go test ./... -go vet ./... -go build ./cmd/scriptorium -``` - -Inspect `go list ./...` and the filesystem. The package inventory must consist -only of the command and retained application packages: adapters, -configuration, defaults, and formatting. The module root and removed framework -package families must be absent. - -### Exit Criteria - -- Scriptorium exposes no root Go package. -- No duplicated framework package, built-in registry, framework testdata, or - Go-library example remains. -- Application defaults contain no Promptkit-owned behavior. -- Module metadata reflects the actual slim application graph. -- All remaining packages test, vet, and build against Promptkit `v0.1.0`. - -## Stage 3: Harden The Boundary And Rationalize Tests - -### Objective - -Make the slim dependency direction durable and leave Scriptorium with a lean -test suite that protects application behavior rather than retesting Promptkit. - -### Architecture Guard - -Rewrite `internal/adapter/dependency_test.go` as a repository-level -application-boundary guard. It may remain in the `internal/adapter` test -package, but it must locate the module root reliably and recursively inspect -all non-test production `.go` files under the repository. - -The scanner must: - -- skip `.git`, `vendor`, and other non-source output directories; -- parse imports with the Go parser instead of searching raw source text; -- reject the exact former root import - `gitea.maximumdirect.net/eric/scriptorium`; -- reject the former Scriptorium framework package families removed in Stage 2; -- reject `gitea.maximumdirect.net/eric/promptkit/internal` and every path below - it; and -- continue allowing retained Scriptorium application-internal imports such as - `internal/config`, `internal/defaults`, `internal/format`, and adapter - packages. - -Add focused scanner tests using temporary nested source trees to prove exact -root-package detection, nested former-family detection, Promptkit-internal -detection, and allowance of retained application packages. - -Add an architecture assertion that: - -- the module root has no production `.go` file; and -- each removed framework directory is absent. - -This is an intentional architecture invariant, not a generic assertion that -the whole repository tree can never change. - -### Test Ownership Audit - -Review every remaining test after the mechanical import migration: - -- `internal/adapter/cli` owns CLI parsing, configuration/flag mapping, command - output, summaries, exit codes, and representative real-engine command - workflows; -- `internal/adapter/http` owns DTO mapping, strict JSON, status/error mapping, - limits, restricted artifact policy, cancellation, and representative - real-engine handler workflows; -- `internal/config` owns strict application YAML, discovery, precedence, - validation, and application defaults; -- `internal/format` owns deterministic text/JSON presentation; and -- the architecture guard owns dependency direction and removal invariants. - -Retain the existing real Promptkit-engine adapter tests because they protect -the consumer integration seam. Keep their prompt and profile fixtures -package-local or generated with `t.TempDir`; do not recreate -`testdata/framework`. - -Delete or simplify any assertion that only duplicates Promptkit parser, -orchestration, profile, validation, model-client, or public-contract tests. -Do not add a Scriptorium table for every Promptkit sentinel or field. Preserve -only mappings Scriptorium exposes through CLI or HTTP behavior. - -Add a new test only when the cutover exposes an application-owned risk that is -not already covered. Prefer updating an existing adapter integration test over -creating a new end-to-end harness. - -### Release Workflow Check - -Inspect `.woodpecker/release.yml` and any packaging metadata for assumptions -about the removed root package or framework directories. Keep the release -target at `./cmd/scriptorium` (or its canonical module package path) and ensure -the workflow obtains Promptkit through ordinary module resolution. - -Do not add a Promptkit checkout, workspace, replacement, vendor step, or -cross-repository artifact to Scriptorium CI or release packaging. - -### Validation - -Run: - -```sh -go test ./... -go test -race ./... -go vet ./... -go build ./cmd/scriptorium -``` - -Run the architecture guard directly by name as a focused diagnostic. Confirm -that its negative fixtures fail the scanner for the intended import and that -the real repository produces no violation. - -Exercise the release workflow's Go build commands locally with temporary -outputs for its supported target platforms. Do not create `dist/` or another -tracked output directory during validation. - -### Exit Criteria - -- The repository guard protects the complete new dependency direction. -- Remaining tests have an explicit application-owned purpose. -- No deleted Promptkit behavior is redundantly reimplemented in tests or - fixtures. -- Race-enabled tests, vet, application builds, and release-equivalent builds - pass. - -## Stage 4: Reconcile Permanent Documentation And Examples - -### Objective - -Make all permanent Scriptorium documentation describe the implemented slim -application and route framework readers to the version of Promptkit the -application actually consumes. - -### Version-Appropriate Promptkit Links - -Use the tagged Promptkit `v0.1.0` documents as the canonical framework -references during this step. Link to the corresponding files under: - -```text -https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.1.0/ -``` - -Use these owners where applicable: - -- `docs/consumers/pkg-promptkit.md` for Go-library consumer guidance; -- `docs/formats.md` for prompt, profile, schema, execution-setting, built-in - profile, and framework credential contracts; and -- `docs/integrations/openai-compatible-chat.md` for outbound provider wire and - timeout behavior. - -Do not copy their field tables, defaults, error inventories, or timeout rules -into Scriptorium. Scriptorium documents only its own mapping or invocation -surface and links to the Promptkit owner for the framework definition. - -### Orientation And Policy - -Update: - -- `README.md` to present only the runnable CLI and HTTP application, remove the - Scriptorium Go-package link and Go-library example, and identify Promptkit as - the imported framework; -- `docs/policy/architecture.md` to define the current application-only shape, - retained package boundaries, Promptkit dependency direction, HTTP artifact - security boundary, application invariants, and non-goals; -- `docs/development.md` to route contributors to the remaining adapter, - configuration, formatting, packaging, and Promptkit-consumer boundaries; -- `docs/policy/documentation.md` where its ownership table or boundary rules - still imply that Scriptorium owns a public Go package or framework - integration; and -- `docs/policy/testing.md` where framework-domain, validator, model-client, or - orchestration examples imply those are still Scriptorium test owners. - -Do not rewrite accepted ADR decision content. ADR 0002 remains the permanent -decision record even where its context describes the pre-split state. - -### External And User Contracts - -Audit and update: - -- `docs/cli.md` -- `docs/api.md` -- `docs/config.md` -- `docs/operations.md` -- `docs/consumers/api.md` -- `docs/integrations/subprocess.md` - -Preserve Scriptorium-owned command syntax, configuration discovery and server -fields, HTTP schemas and mappings, operations, and subprocess behavior. Remove -claims that Scriptorium provides an in-process Go API. Where these documents -name prompt/profile fields, model semantics, built-in profiles, framework -credentials, or timeout behavior, keep only the Scriptorium mapping context -and link to the tagged Promptkit owner. - -Delete `docs/consumers/pkg-scriptorium.md`. Update every incoming link so Go -framework consumers are directed to Promptkit rather than to a compatibility -document. - -Delete `docs/integrations/openai-compatible-chat.md` after replacing all -incoming Scriptorium links with the tagged Promptkit integration contract. -Scriptorium no longer owns the outbound provider protocol. - -### Internal Documentation - -Update `docs/internal/overview.md` to inventory exactly: +The Scriptorium module root no longer exposes a Go package. The remaining +production boundary consists of: - `cmd/scriptorium`; - `internal/adapter/cli`; @@ -463,175 +22,43 @@ Update `docs/internal/overview.md` to inventory exactly: - `internal/defaults`; and - `internal/format`. -Update `docs/internal/adapters.md` for Promptkit request/result mapping, engine -construction, consumer-owned interfaces, error mapping, output behavior, and -restricted-reader injection. +The CLI constructs and invokes Promptkit engines, the HTTP adapter maps its +transport contract to Promptkit public values, and the HTTP-specific restricted +artifact reader is injected through Promptkit's public extension point. +Scriptorium retains application configuration, presentation, transport, +containment, process, packaging, and executable-example responsibilities. -Rewrite `docs/internal/sources.md` around Scriptorium-owned application source -locations and the restricted HTTP artifact reader. Link Promptkit for ordinary -artifact loading and framework source semantics. +The former root facade, duplicated framework packages, built-in profile copy, +framework tests and fixtures, Go-library example, and framework-owned +documentation were removed. Permanent Scriptorium documentation now describes +the CLI and HTTP application and links to the tagged Promptkit documentation +for framework contracts. -Delete: +## Validation Evidence -- `docs/internal/runner.md` -- `docs/internal/llm.md` +Scriptorium passed, outside a Go workspace and without a replacement: -Promptkit owns those subsystem documents. Remove all incoming links rather than -leaving placeholder internal documents. +- module identity, graph, tagged dependency, and `go mod tidy -diff` checks; +- ordinary and race-enabled tests, including retained HTTP decoding, limit, + restricted-file, error-mapping, and raw-output coverage; +- vet, formatting, whitespace, architecture, and tracked-tree hygiene checks; +- temporary native and release-equivalent Linux `amd64` and `arm64` builds; +- the maintained render script and both configuration examples without model + credentials; and +- all maintained local and tagged Promptkit documentation links. -### Examples And Navigation +A fresh temporary module and build cache resolved Promptkit remotely, reported +the expected `v0.1.0` origin commit, and passed the Scriptorium test suite and +build without reading the sibling Promptkit checkout. -Keep the executable configuration, prompt, profile, schema, fixture, HTTP, and -render-script examples. Confirm they still run against the tagged dependency -and that prose describes them as Scriptorium application examples. +Promptkit was reconfirmed independently at the exact published tag. Its local +and remote tag targets agree, its working tree remains clean, and its +documented test, race, vet, build, example, formatting, module, link, +whitespace, and repository-hygiene checks pass. -Remove every link to `examples/go-library`, root Go declarations, removed -framework directories, deleted Scriptorium consumer documentation, and deleted -internal or integration documents. +## Next Gate -Search all permanent Markdown outside `docs/roadmap/` for: - -- the former root import path used as a Go package; -- claims that Scriptorium owns or implements the framework; -- references to removed packages, tests, fixtures, or examples; and -- duplicate Promptkit framework contracts. - -The migration roadmap and accepted ADRs may retain historical and future -language appropriate to their lifecycle. - -### Validation - -Validate every local Markdown link and follow every new external Promptkit -link. Run: - -```sh -git diff --check -go test ./... -go vet ./... -go build ./cmd/scriptorium -``` - -Run the maintained render script and both `examples/config.yml` and -`examples/config.full.yml` through a credential-free `render` workflow. No -documentation validation may invoke a paid or live model endpoint. - -### Exit Criteria - -- Permanent docs describe only the implemented application boundary. -- Framework contracts have one Promptkit owner and version-appropriate links. -- Removed code and examples have no live incoming links. -- All retained examples are valid, secret-free, and runnable offline where - intended. -- Documentation links, whitespace, tests, vet, and the executable build pass. - -## Stage 5: Perform Independent Acceptance And Record Completion - -### Objective - -Validate the exact final state without sibling-repository coupling, then record -the Step 7 gate only after every feature-roadmap completion criterion is -satisfied. - -### Scriptorium Acceptance - -From the Scriptorium repository root, confirm no Go workspace is active and no -replacement or vendored dependency exists. Validate module identity and -selection: - -```sh -go list -m -f '{{.Path}} {{.GoVersion}}' -go list -m -f '{{.Path}} {{.Version}}' gitea.maximumdirect.net/eric/promptkit -go mod graph -go mod tidy -diff -``` - -Require the Scriptorium module path and existing Go version, and require -Promptkit to resolve exactly to `v0.1.0`. Inspect the graph for a normal tagged -module edge rather than a local path. - -Run: - -```sh -go test ./... -go test -race ./... -go vet ./... -go build ./cmd/scriptorium -gofmt -l $(git ls-files '*.go') -git diff --check -``` - -The formatting command must produce no paths. Build the executable to a -temporary directory rather than the repository. Reproduce the release -workflow's supported cross-compilation targets and linker flags with temporary -outputs. - -Run the maintained render script and credential-free render commands using -both configuration examples. Verify representative HTTP behavior through the -retained handler tests, including strict decoding, request/response size -limits, restricted file access, public error mapping, and optional raw output. - -Validate all maintained Markdown links, including the tagged Promptkit links. -Search the final tracked tree for former root-facade imports, removed framework -packages, built-in asset copies, framework fixtures, Go-library examples, -workspaces, replacements, generated binaries, credentials, and stale -documentation references. - -### Clean Remote-Dependency Verification - -Use a fresh temporary module cache with `GOWORK=off` and ordinary remote module -resolution to download dependencies and run at least the Scriptorium build and -test suite. The verification must not read the sibling Promptkit working tree. -Confirm the downloaded Promptkit module reports version `v0.1.0` and origin -commit `9e68a2bbf779545995270c47842048a3bc6c85dc`. - -Do not clear or destructively rewrite the maintainer's normal module cache. -Use a temporary directory and remove it after validation. - -### Independent Promptkit Reconfirmation - -Without changing Promptkit, validate the exact `v0.1.0` source from a temporary -detached worktree or the downloaded module directory. If the clean Promptkit -checkout still has `HEAD` exactly at the peeled `v0.1.0` commit, it may be used -directly. Run Promptkit's documented sequence from that exact source: - -```sh -go test ./... -go test -race ./... -go vet ./... -go build ./... -go run ./examples/go-library/prepare -``` - -Also check Promptkit formatting, links, whitespace, module tidiness, absence of -a workspace/replacement, clean status, and the local and remote `v0.1.0` tag -target. Remove any temporary detached worktree after validation. This proves -that Scriptorium's adoption did not introduce cross-repository state or require -an unpublished Promptkit change. - -### Completion Records - -Only after all acceptance checks pass: - -- update `docs/roadmap/step7.md` status from Proposed to Complete and replace - future-oriented starting-state material as needed with a concise result, - retained application boundary, validation evidence, and Step 8 handoff; -- update `docs/roadmap/migration.md` so its status says Steps 1 through 7 are - complete and its Step 7 gate records the tagged dependency, removal of the - framework copy and public facade, independent validation, and readiness for - downstream migration; and -- replace this staged checklist with a concise Step 7 implementation - completion record containing the dependency version, resulting package - boundary, removed ownership, validation evidence, and next gate. - -Do not mark Step 8 or Step 9 complete. Do not publish a Scriptorium release or -claim that external consumers have migrated. - -### Exit Criteria - -- Every completion criterion in `docs/roadmap/step7.md` is demonstrably true. -- Scriptorium passes release-grade validation against remotely resolved - Promptkit `v0.1.0`. -- Promptkit remains independently clean and valid at its published tag. -- Permanent documentation, examples, module metadata, and architecture checks - match the final slim application. -- Completion records accurately authorize Step 8 without claiming later work. +[Step 8](migration.md#step-8-migrate-downstream-consumers-to-promptkit) may +now inventory and migrate downstream Go consumers. Step 7 did not migrate +external consumers, publish a breaking Scriptorium release, or complete the +release and documentation cutover assigned to Step 9. diff --git a/docs/roadmap/migration.md b/docs/roadmap/migration.md index 815be10..4b50dc7 100644 --- a/docs/roadmap/migration.md +++ b/docs/roadmap/migration.md @@ -2,8 +2,8 @@ ## Status -Accepted plan. Steps 1 through 6 are complete. Steps 7 through 9 remain -proposed and are not yet implemented. +Accepted plan. Steps 1 through 7 are complete. Steps 8 and 9 remain proposed +and are not yet implemented. ## Objective @@ -259,6 +259,14 @@ Retain only Scriptorium-owned executable and transport behavior. In particular: dependency, contains no duplicate framework implementation, and its current documentation describes only the slimmed application. +**Gate status:** Complete as of 2026-07-28. Scriptorium directly resolves +Promptkit `v0.1.0`, no longer contains the framework copy or public Go facade, +and retains only its application, adapter, configuration, presentation, +transport, packaging, and executable-example responsibilities. Release-grade +Scriptorium validation passed with a fresh remote dependency cache, and the +published Promptkit tag passed its documented validation independently. The +application is ready for the downstream-consumer migrations in Step 8. + ### Step 8: Migrate Downstream Consumers To Promptkit Inventory downstream Go consumers and migrate each from the Scriptorium package diff --git a/docs/roadmap/step7.md b/docs/roadmap/step7.md index 7d20ca4..c199d94 100644 --- a/docs/roadmap/step7.md +++ b/docs/roadmap/step7.md @@ -2,338 +2,63 @@ ## Status -Proposed. +Complete as of 2026-07-28. -## Purpose +## Result -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. +Scriptorium is now an application-only consumer of the published +`gitea.maximumdirect.net/eric/promptkit v0.1.0` module. The command, CLI and +HTTP adapters, restricted artifact reader, and prepared-run formatter use +Promptkit's supported public API. The dependency resolves normally to +Promptkit commit `9e68a2bbf779545995270c47842048a3bc6c85dc` without a workspace, +replacement, vendored copy, or unpublished revision. -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. +The Scriptorium module root no longer provides an importable Go package or +compatibility facade. The reusable framework packages, embedded built-in +profiles, framework contract tests and fixtures, and Go-library example were +removed. Architecture tests prevent production imports of the former root +facade, removed framework package families, and Promptkit internals. -## Starting Point +## Retained Application Boundary -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 owns only its runnable process and application concerns: -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. +- command and CLI parsing, assembly, streams, summaries, and exit behavior; +- HTTP routes, DTOs, strict decoding, limits, public error mapping, and + restricted artifact access; +- application configuration discovery, validation, precedence, and transport + defaults; +- prepared-run text and JSON presentation; +- executable examples, operations guidance, and binary packaging. -## Desired End State +Promptkit owns prompt execution, framework sources and formats, validation, +model integration, built-in profiles, and ordinary artifact loading. +Scriptorium's permanent documentation reflects that boundary and links to the +tagged Promptkit contracts rather than duplicating them. -Scriptorium is an application-only Go module with this dependency direction: +## Acceptance -```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 completed cutover passed: -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. +- module graph and tidiness checks selecting exactly Promptkit `v0.1.0`; +- ordinary and race-enabled Scriptorium tests, vet, formatting, whitespace, + architecture, and repository-hygiene checks; +- temporary native and release-equivalent cross-builds; +- maintained offline render workflows with both application configurations; +- maintained local and tagged-documentation link checks; +- fresh-cache remote dependency resolution, tests, and build with the expected + Promptkit origin commit; and +- Promptkit's complete documented validation independently at its clean local + and remote `v0.1.0` tag. -## Promptkit Dependency +These checks cover the retained CLI, HTTP, configuration, containment, +formatting, error-mapping, security, and representative executable behavior. +The working trees contain no generated binaries, temporary workspaces, +replacement directives, credentials, or migration residue. -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. +## Handoff -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. +The Step 7 gate is satisfied. [Step 8](migration.md#step-8-migrate-downstream-consumers-to-promptkit) +owns downstream consumer inventory and migration. Step 9 remains responsible +for the breaking Scriptorium release and final documentation cutover; neither +later gate is complete.