Add an implementation plan and roadmap for Step 6 of the migration plan
This commit is contained in:
987
docs/roadmap/implementation.md
Normal file
987
docs/roadmap/implementation.md
Normal file
@@ -0,0 +1,987 @@
|
||||
# Step 6 Implementation Plan
|
||||
|
||||
## Status
|
||||
|
||||
Proposed.
|
||||
|
||||
This plan implements
|
||||
[Migration Step 6: Extract And Stabilize Promptkit](step6.md). The feature
|
||||
roadmap is the canonical source for the target state and migration policy; this
|
||||
document owns implementation order, exact work boundaries, validation gates,
|
||||
and release coordination.
|
||||
|
||||
## Repository Roles
|
||||
|
||||
Step 6 changes two sibling repositories:
|
||||
|
||||
- **Scriptorium** is the source of the characterized framework and the
|
||||
controlling repository for ADRs and migration status.
|
||||
- **Promptkit** receives the reusable framework, tests, assets, public
|
||||
contracts, examples, and first release tag.
|
||||
|
||||
Paths in this plan are relative to the named repository. Run commands from the
|
||||
repository root named by each stage.
|
||||
|
||||
Stages 1 through 7 change Promptkit only. They do not delete or refactor
|
||||
Scriptorium framework code. Stage 8 publishes Promptkit and then updates only
|
||||
Scriptorium's roadmap documents to record completion. Scriptorium does not
|
||||
import Promptkit until Step 7.
|
||||
|
||||
## Preconditions And Execution Rules
|
||||
|
||||
Before Stage 1:
|
||||
|
||||
1. Read `docs/development.md` and all files under `docs/policy/` in both
|
||||
repositories.
|
||||
2. Confirm the Scriptorium Step 6 feature roadmap and this plan are the only
|
||||
intended planning changes.
|
||||
3. Confirm Promptkit starts clean on its intended default branch.
|
||||
4. Confirm there is no active Go workspace affecting either repository:
|
||||
|
||||
```sh
|
||||
gowork=$(go env GOWORK)
|
||||
test -z "$gowork" || test "$gowork" = off
|
||||
```
|
||||
|
||||
5. Record the starting Scriptorium and Promptkit commit IDs in implementation
|
||||
notes. The Scriptorium commit is the extraction source snapshot and must be
|
||||
included in the eventual Step 6 completion record.
|
||||
6. Run the current baselines before copying code.
|
||||
|
||||
From Scriptorium:
|
||||
|
||||
```sh
|
||||
go test ./...
|
||||
go vet ./...
|
||||
go build ./cmd/scriptorium
|
||||
```
|
||||
|
||||
From Promptkit:
|
||||
|
||||
```sh
|
||||
go test ./...
|
||||
go vet ./...
|
||||
go build ./...
|
||||
```
|
||||
|
||||
Stop and correct or explicitly disposition any baseline failure before
|
||||
extraction. Do not interpret a pre-existing failure as an extraction defect.
|
||||
|
||||
Apply these rules throughout:
|
||||
|
||||
- Copy the characterized framework into Promptkit; do not remove its
|
||||
Scriptorium source during Step 6.
|
||||
- Rewrite imports to `gitea.maximumdirect.net/eric/promptkit`; Promptkit code
|
||||
and tests must never import Scriptorium.
|
||||
- Preserve observable behavior unless the package/module rename requires a
|
||||
Promptkit identity change or the feature roadmap explicitly requires a
|
||||
boundary correction.
|
||||
- Do not combine extraction with dependency upgrades, public API redesign,
|
||||
renaming for taste, or unrelated cleanup.
|
||||
- Move tests and repository-local fixtures with the behavior they protect.
|
||||
- Keep each stage independently buildable and testable.
|
||||
- Update Promptkit's README, architecture policy, and internal overview in the
|
||||
same stage whenever their current-state statements become inaccurate.
|
||||
- Keep exact public API contracts in Go declarations and GoDoc. Consumer and
|
||||
internal documents summarize tasks and link to canonical owners rather than
|
||||
duplicating declarations.
|
||||
- Do not create a Promptkit command, inbound HTTP adapter, application
|
||||
configuration package, compatibility facade, hosted CI configuration,
|
||||
`go.work`, `go.work.sum`, or committed local `replace`.
|
||||
- Do not create, move, or publish a version tag before Stage 8.
|
||||
- Do not push either repository until the publication stage unless the user
|
||||
separately directs otherwise.
|
||||
- Review Promptkit and Scriptorium diffs independently. Never create a
|
||||
cross-repository commit.
|
||||
|
||||
If Scriptorium framework code changes after the recorded source snapshot and
|
||||
before publication, inspect the intervening diff. Port any relevant correctness
|
||||
or security change to Promptkit and rerun all affected stage gates. Do not
|
||||
silently extract from two different source states.
|
||||
|
||||
## Stage 1: Extract Domain Types, Framework Defaults, And File Catalog
|
||||
|
||||
### Objective
|
||||
|
||||
Create the internal foundation on which the remaining Promptkit framework
|
||||
packages depend without introducing a public API prematurely.
|
||||
|
||||
### Promptkit Implementation
|
||||
|
||||
Create these package groups from the recorded Scriptorium source snapshot:
|
||||
|
||||
- `internal/domain`
|
||||
- `internal/defaults`
|
||||
- `internal/filecatalog`
|
||||
|
||||
Copy `internal/domain/domain.go` and
|
||||
`internal/domain/prepared_run_test.go`, changing only module imports or
|
||||
Promptkit-specific package references required for compilation.
|
||||
|
||||
Copy the file catalog implementation and tests:
|
||||
|
||||
- `internal/filecatalog/catalog.go`
|
||||
- `internal/filecatalog/catalog_test.go`
|
||||
|
||||
Create Promptkit's `internal/defaults/defaults.go` as a responsibility split,
|
||||
not a blind copy. It contains only:
|
||||
|
||||
- `SchemaDirDefault`;
|
||||
- `OutputArtifactName`;
|
||||
- `ContentTypeTextPlain`;
|
||||
- `ContentTypeTextMarkdown`;
|
||||
- `ContentTypeApplicationJSON`;
|
||||
- `OpenAIChatCompletionsPath`;
|
||||
- the four execution defaults;
|
||||
- `LLMRequestTimeoutDefault`; and
|
||||
- `ExecutionTargetDefault`.
|
||||
|
||||
Do not copy:
|
||||
|
||||
- `HTTPAddrDefault`;
|
||||
- `HTTPReadHeaderTimeoutDefault`;
|
||||
- `HTTPMaxRequestBytesDefault`;
|
||||
- `HTTPMaxArtifactBytesDefault`; or
|
||||
- `HTTPMaxResponseBytesDefault`.
|
||||
|
||||
Those values remain Scriptorium application or transport concerns.
|
||||
|
||||
Retain existing literal values and behavior. Do not add exported public facade
|
||||
symbols for internal defaults.
|
||||
|
||||
### Current-State Documentation
|
||||
|
||||
Update Promptkit in the same stage:
|
||||
|
||||
- `README.md` states that extraction is in progress, identifies the internal
|
||||
foundation now present, and still states that no usable public framework API
|
||||
exists.
|
||||
- `docs/policy/architecture.md` no longer claims that the root package is the
|
||||
only implemented package. It identifies the implemented foundation and keeps
|
||||
downstream-to-facade dependency direction as the target for later stages.
|
||||
- `docs/internal/overview.md` lists the root package, `internal/domain`,
|
||||
`internal/defaults`, and `internal/filecatalog` with only their implemented
|
||||
responsibilities.
|
||||
|
||||
Do not document later packages as implemented.
|
||||
|
||||
### Stage 1 Validation
|
||||
|
||||
From Promptkit:
|
||||
|
||||
```sh
|
||||
go test ./internal/domain ./internal/filecatalog
|
||||
go test ./...
|
||||
go vet ./...
|
||||
go build ./...
|
||||
gofmt -l $(git ls-files '*.go')
|
||||
git diff --check
|
||||
```
|
||||
|
||||
The formatting command must produce no paths. Also confirm:
|
||||
|
||||
- no external dependency was added;
|
||||
- `internal/defaults` contains no CLI, server, or HTTP-limit constant;
|
||||
- no file imports Scriptorium;
|
||||
- all changed Markdown links resolve; and
|
||||
- the README, architecture policy, and internal overview describe the same
|
||||
implemented package set.
|
||||
|
||||
### Stage 1 Completion Gate
|
||||
|
||||
Proceed only when the foundational packages pass independently in Promptkit and
|
||||
the Promptkit repository makes no claim that later sources, orchestration, or
|
||||
public APIs already exist.
|
||||
|
||||
## Stage 2: Extract Prompt Definitions, Profiles, Built-Ins, And Rendering
|
||||
|
||||
### Objective
|
||||
|
||||
Move the YAML-backed prompt and profile source stack, embedded default registry,
|
||||
and prompt renderer onto the Promptkit foundation.
|
||||
|
||||
### Promptkit Implementation
|
||||
|
||||
Extract these package trees with their tests and test data:
|
||||
|
||||
- `internal/promptdef`
|
||||
- `internal/profile`
|
||||
- `internal/profile/builtin`
|
||||
- `internal/prompt`
|
||||
|
||||
The extraction includes:
|
||||
|
||||
- filesystem and `fs.FS` prompt-definition repositories;
|
||||
- strict prompt YAML decoding and validation;
|
||||
- prompt selection by ID and optional version;
|
||||
- contained `content_file` resolution;
|
||||
- filesystem and `fs.FS` profile repositories;
|
||||
- profile validation and raw-key rejection;
|
||||
- overlay behavior and error-preserving fallback;
|
||||
- the embedded built-in repository;
|
||||
- all 24 current built-in YAML assets from the recorded source snapshot; and
|
||||
- Go-template rendering, session IDs, and cache-control behavior.
|
||||
|
||||
Rewrite all internal imports to the Promptkit module path. Preserve package
|
||||
boundaries; do not export repository or renderer implementations.
|
||||
|
||||
Add `gopkg.in/yaml.v3` at the currently validated version used by Scriptorium.
|
||||
Run `go mod tidy`; allow Go to generate the corresponding `go.sum` entries.
|
||||
Do not copy Scriptorium's complete `go.sum` or introduce unused dependencies.
|
||||
|
||||
The built-in asset tree must be byte-for-byte equivalent to the recorded source
|
||||
snapshot at extraction. Asset additions, removals, model renames, or semantic
|
||||
profile changes are separate work.
|
||||
|
||||
### Current-State Documentation
|
||||
|
||||
Update Promptkit's architecture policy and internal overview to include the
|
||||
implemented source and rendering packages. Keep the README accurate that the
|
||||
repository now contains internal framework behavior but still has no usable
|
||||
exported engine.
|
||||
|
||||
Do not create the public format contract yet. These loaders are internal until
|
||||
the root facade exposes supported source construction in Stage 6.
|
||||
|
||||
### Stage 2 Validation
|
||||
|
||||
From Promptkit:
|
||||
|
||||
```sh
|
||||
go test ./internal/filecatalog ./internal/promptdef ./internal/profile/... ./internal/prompt
|
||||
go test ./...
|
||||
go vet ./...
|
||||
go build ./...
|
||||
go mod tidy
|
||||
gofmt -l $(git ls-files '*.go')
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Also:
|
||||
|
||||
1. Compare the Promptkit built-in asset tree with the recorded Scriptorium
|
||||
source tree and require no content difference.
|
||||
2. Confirm there are exactly 24 embedded YAML assets.
|
||||
3. Confirm the registry test loads every asset, detects duplicate IDs, and
|
||||
verifies the expected catalog.
|
||||
4. Confirm prompt and profile tests use only Promptkit-local test data.
|
||||
5. Confirm strict unknown-field, invalid YAML, duplicate, containment, raw-key,
|
||||
and overlay-failure cases remain covered.
|
||||
6. Confirm no package imports Scriptorium.
|
||||
7. Check every changed Markdown link and run `git diff --check` after module
|
||||
tidying.
|
||||
|
||||
### Stage 2 Completion Gate
|
||||
|
||||
Proceed only when Promptkit independently owns and tests prompt loading, profile
|
||||
loading, the unchanged built-in registry, and rendering without exposing
|
||||
internal implementations as public packages.
|
||||
|
||||
## Stage 3: Extract Artifact Reading And Output Validation
|
||||
|
||||
### Objective
|
||||
|
||||
Move Promptkit's ordinary artifact boundary and validation implementation while
|
||||
leaving Scriptorium's restricted HTTP policy behind.
|
||||
|
||||
### Promptkit Implementation
|
||||
|
||||
Extract:
|
||||
|
||||
- `internal/artifact/reader.go`
|
||||
- `internal/artifact/reader_test.go`
|
||||
- the complete `internal/validate` package and tests
|
||||
|
||||
Promptkit's artifact package includes only the ordinary inline and unrestricted
|
||||
caller-selected file reader. Preserve artifact copying, metadata, hashing,
|
||||
content-type fallback, cancellation, and error behavior.
|
||||
|
||||
Do not copy:
|
||||
|
||||
- `internal/adapter/http/artifact_reader.go`;
|
||||
- its rooted containment implementation;
|
||||
- HTTP byte limits;
|
||||
- HTTP denial policy; or
|
||||
- Scriptorium status/error mapping.
|
||||
|
||||
Extract the standard filesystem validator, `fs.FS` validator, validator
|
||||
interface, schema loading, JSON and JSON Schema behavior, and all associated
|
||||
tests.
|
||||
|
||||
Add `github.com/santhosh-tekuri/jsonschema/v6` at Scriptorium's currently
|
||||
validated version. Run `go mod tidy` and accept only required transitive module
|
||||
entries.
|
||||
|
||||
### Current-State Documentation
|
||||
|
||||
Create `docs/internal/sources.md` as the current internal source document. It
|
||||
describes implemented prompt, profile, built-in, schema, renderer, and ordinary
|
||||
artifact behavior. It must:
|
||||
|
||||
- link to the architecture policy;
|
||||
- distinguish ordinary file reading from Scriptorium's restricted HTTP
|
||||
reader;
|
||||
- identify the package-local test owners;
|
||||
- avoid presenting the future public facade as implemented; and
|
||||
- avoid linking to Scriptorium-local filesystem paths.
|
||||
|
||||
Update the internal overview and architecture policy with artifact and
|
||||
validation responsibilities.
|
||||
|
||||
### Stage 3 Validation
|
||||
|
||||
From Promptkit:
|
||||
|
||||
```sh
|
||||
go test ./internal/artifact ./internal/validate
|
||||
go test ./...
|
||||
go vet ./...
|
||||
go build ./...
|
||||
go mod tidy
|
||||
gofmt -l $(git ls-files '*.go')
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Confirm:
|
||||
|
||||
- artifact tests cover inline, file, missing-file, unsupported-reference,
|
||||
cancellation, metadata, and copying behavior retained from the source;
|
||||
- validator tests retain basic, JSON, schema success, content-failure, source,
|
||||
registration, compilation, and operational-error distinctions;
|
||||
- no rooted HTTP reader, request-size limit, response mapping, or inbound HTTP
|
||||
package exists;
|
||||
- the module graph contains only the YAML and JSON Schema dependency families
|
||||
needed by implemented code;
|
||||
- no source, test, or documentation path reaches into Scriptorium; and
|
||||
- all changed Markdown links resolve.
|
||||
|
||||
### Stage 3 Completion Gate
|
||||
|
||||
Proceed only when artifact and validation behavior is independently tested in
|
||||
Promptkit and the Scriptorium-specific HTTP security boundary remains entirely
|
||||
outside Promptkit.
|
||||
|
||||
## Stage 4: Extract The OpenAI-Compatible Model Client
|
||||
|
||||
### Objective
|
||||
|
||||
Move the provider-neutral internal client boundary and built-in
|
||||
OpenAI-compatible implementation with its complete wire, timeout, security, and
|
||||
failure contract.
|
||||
|
||||
### Promptkit Implementation
|
||||
|
||||
Extract:
|
||||
|
||||
- `internal/llm/client.go`
|
||||
- `internal/llm/openai_compatible_client.go`
|
||||
- `internal/llm/openai_compatible_client_test.go`
|
||||
|
||||
Rewrite module imports only. Preserve:
|
||||
|
||||
- endpoint selection and `/chat/completions` construction;
|
||||
- request mapping, reserved fields, extra parameters, cache control, session
|
||||
IDs, and structured output;
|
||||
- direct API-key precedence over environment lookup;
|
||||
- response and token-usage decoding;
|
||||
- non-success and malformed-response categories;
|
||||
- response-body suppression for non-success statuses;
|
||||
- supplied-client cloning and non-mutation; and
|
||||
- layered caller-context, transport-cap, and generation-deadline behavior.
|
||||
|
||||
Retain deterministic deadline-capturing transport tests. Do not replace them
|
||||
with short wall-clock sleeps. Keep live providers, real credentials, and paid
|
||||
requests out of the default suite.
|
||||
|
||||
Do not add retries, tool calls, provider catalogs, inbound HTTP behavior, or a
|
||||
stateful session store.
|
||||
|
||||
### Current-State Documentation
|
||||
|
||||
Create:
|
||||
|
||||
- `docs/internal/llm.md`
|
||||
- `docs/integrations/openai-compatible-chat.md`
|
||||
|
||||
The integration document owns the observable outbound wire and timeout
|
||||
contract. The internal document owns implementation flow, collaborators, error
|
||||
categories, and tests. At this stage both documents must accurately note that
|
||||
the client is implemented internally but is not yet assembled through a usable
|
||||
public engine.
|
||||
|
||||
Update the architecture policy and internal overview to include
|
||||
`internal/llm`.
|
||||
|
||||
### Stage 4 Validation
|
||||
|
||||
From Promptkit:
|
||||
|
||||
```sh
|
||||
go test ./internal/llm
|
||||
go test ./...
|
||||
go vet ./...
|
||||
go build ./...
|
||||
gofmt -l $(git ls-files '*.go')
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Confirm the moved client tests still cover:
|
||||
|
||||
- configuration validation and endpoint behavior;
|
||||
- supplied-client cloning and timeout precedence;
|
||||
- caller deadlines and explicit generation timeout zero;
|
||||
- direct and environment-based authentication;
|
||||
- field inclusion, structured output, extra parameters, and collisions;
|
||||
- malformed payload and response cases;
|
||||
- non-success status handling without body disclosure; and
|
||||
- cancellation and public-facing internal error identity needed by the runner.
|
||||
|
||||
Check all new documentation links and verify that no document claims the root
|
||||
facade is usable before Stage 6.
|
||||
|
||||
### Stage 4 Completion Gate
|
||||
|
||||
Proceed only when the outbound client and its exact integration contract are
|
||||
independently implemented, deterministic, and free of Scriptorium transport or
|
||||
application policy.
|
||||
|
||||
## Stage 5: Extract Framework Orchestration
|
||||
|
||||
### Objective
|
||||
|
||||
Assemble the internal source, rendering, artifact, model, and validation
|
||||
components under Promptkit's use-case runner while keeping the runner internal.
|
||||
|
||||
### Promptkit Implementation
|
||||
|
||||
Extract:
|
||||
|
||||
- `internal/usecase/runner.go`
|
||||
- `internal/usecase/repairer.go`
|
||||
- `internal/usecase/runner_test.go`
|
||||
|
||||
Rewrite imports to Promptkit and make no unrelated algorithmic changes.
|
||||
Preserve:
|
||||
|
||||
- request validation and prompt/profile selection;
|
||||
- source loading and hashing;
|
||||
- execution-setting and presence resolution;
|
||||
- schema loading before generation when structured output is required;
|
||||
- `Run` reuse of `Prepare`;
|
||||
- one-call generation and result construction;
|
||||
- content-validation results versus operational validation errors;
|
||||
- internal optional repair behavior;
|
||||
- error wrapping and identity;
|
||||
- direct-key handling and redaction boundaries; and
|
||||
- per-request state with no durable run store.
|
||||
|
||||
The public engine still does not enable the optional repairer and this stage
|
||||
does not add a public repair option.
|
||||
|
||||
### Current-State Documentation
|
||||
|
||||
Create `docs/internal/runner.md` for implemented orchestration, dependencies,
|
||||
flows, failure categories, guarantees, tests, and change guidance. Link to the
|
||||
source and LLM internal documents rather than repeating their contracts.
|
||||
|
||||
Update the architecture policy and internal overview. The README continues to
|
||||
state that internal framework behavior exists but the public facade is not yet
|
||||
usable.
|
||||
|
||||
### Stage 5 Validation
|
||||
|
||||
From Promptkit:
|
||||
|
||||
```sh
|
||||
go test ./internal/usecase
|
||||
go test ./...
|
||||
go test -race ./internal/usecase
|
||||
go vet ./...
|
||||
go build ./...
|
||||
gofmt -l $(git ls-files '*.go')
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Confirm runner coverage retains:
|
||||
|
||||
- preparation order and `Run`-through-`Prepare`;
|
||||
- default, profile, and explicit override precedence;
|
||||
- explicit zero and negative-value handling;
|
||||
- prompt/profile/source errors and credential validation;
|
||||
- input and rendered-prompt hashes;
|
||||
- structured schema loading before generation;
|
||||
- generation, validation, and repair outcomes;
|
||||
- cancellation and error categories; and
|
||||
- output artifact names, content types, usage, and timing.
|
||||
|
||||
Confirm all collaborators remain behind internal interfaces and no internal
|
||||
package has been exported merely for wiring.
|
||||
|
||||
### Stage 5 Completion Gate
|
||||
|
||||
Proceed only when the complete internal framework workflow passes in Promptkit
|
||||
and remains inaccessible except through the future root facade.
|
||||
|
||||
## Stage 6: Extract And Characterize The Root Public Facade
|
||||
|
||||
### Objective
|
||||
|
||||
Publish the implemented framework through Promptkit's supported root package
|
||||
with the characterized Scriptorium API shape and Promptkit identity.
|
||||
|
||||
### Promptkit Public Implementation
|
||||
|
||||
Extract and adapt these Scriptorium root files:
|
||||
|
||||
- `artifact_reader.go`
|
||||
- `convert.go`
|
||||
- `engine.go`
|
||||
- `errors.go`
|
||||
- `formatting.go`
|
||||
- `json_copy.go`
|
||||
- `llm_adapter.go`
|
||||
- `profiles.go`
|
||||
- `types.go`
|
||||
|
||||
Replace the foundation-only `doc.go` comment with accurate package-level GoDoc
|
||||
for the implemented Promptkit library.
|
||||
|
||||
Extract and adapt:
|
||||
|
||||
- `engine_test.go`
|
||||
- `artifact_reader_internal_test.go`
|
||||
- `testdata/framework/**`
|
||||
|
||||
Use package `promptkit` for implementation and `promptkit_test` where the source
|
||||
uses external-package contract tests. Change imports from the Scriptorium root
|
||||
to the Promptkit root.
|
||||
|
||||
Preserve the complete exported facade described by the feature roadmap:
|
||||
|
||||
- `Engine`, `Config`, `Option`, `NewEngine`, `Prepare`, and `Run`;
|
||||
- source and injection options;
|
||||
- request, result, artifact, execution, output, validation, rendering, cache,
|
||||
structured-output, usage, and profile values;
|
||||
- serialized constants and helper constructors;
|
||||
- `ArtifactReader` and `LLMClient`;
|
||||
- built-in OpenAI-compatible profile construction; and
|
||||
- all public sentinel errors and `errors.Is` relationships.
|
||||
|
||||
Do not export internal repositories, domain types, concrete validators,
|
||||
concrete internal clients, or public subpackages.
|
||||
|
||||
Make only these intentional identity changes:
|
||||
|
||||
- module imports use `gitea.maximumdirect.net/eric/promptkit`;
|
||||
- package names and GoDoc say Promptkit;
|
||||
- `String` and `GoString` outputs identify `promptkit.RunRequest` and
|
||||
`promptkit.GenerateRequest`; and
|
||||
- examples embedded in GoDoc use the Promptkit qualifier.
|
||||
|
||||
Do not retain the Scriptorium package name or provide an alias/forwarder.
|
||||
|
||||
Preserve:
|
||||
|
||||
- nil engine and option handling;
|
||||
- source replacement and overlay precedence;
|
||||
- empty schema-directory fallback;
|
||||
- client cloning and timeout behavior;
|
||||
- public value copying and mutation isolation;
|
||||
- JSON-compatible extra-parameter validation;
|
||||
- secret omission and redacted formatting;
|
||||
- artifact-reader nil-response handling;
|
||||
- public error mapping and wrapped collaborator identity; and
|
||||
- preparation and run results characterized in Scriptorium.
|
||||
|
||||
### Dependency Guard
|
||||
|
||||
Add a focused Promptkit architecture test that recursively walks repository Go
|
||||
source files, parses their imports, and fails when production or test code imports
|
||||
`gitea.maximumdirect.net/eric/scriptorium` or a subpackage. The test must:
|
||||
|
||||
- inspect nested packages, not only the root;
|
||||
- ignore `.git` and generated or vendor directories that are not maintained
|
||||
source;
|
||||
- report the offending file and import;
|
||||
- avoid encoding the full current package inventory; and
|
||||
- remain useful after legitimate internal reorganization.
|
||||
|
||||
Do not add a brittle test that rejects ordinary standard-library `net/http`
|
||||
use, because Promptkit's outbound client legitimately requires it.
|
||||
|
||||
### Current-State Documentation
|
||||
|
||||
Update immediately:
|
||||
|
||||
- `README.md` now states that Promptkit provides a usable public engine and
|
||||
links to the forthcoming/final consumer documentation only when that file
|
||||
exists in the same stage.
|
||||
- `docs/policy/architecture.md` describes the implemented root-facade-to-
|
||||
internal dependency direction as current state.
|
||||
- `docs/internal/overview.md` inventories the root facade and every implemented
|
||||
internal package.
|
||||
- `docs/integrations/openai-compatible-chat.md` and internal documents remove
|
||||
any temporary statement that the client or runner is not publicly assembled.
|
||||
|
||||
Create `docs/consumers/pkg-promptkit.md` in this stage so task-oriented
|
||||
consumers have a current owner when the public API lands. Derive it from the
|
||||
characterized Scriptorium consumer contract, but:
|
||||
|
||||
- use the Promptkit module and package names;
|
||||
- link exact exported declarations to GoDoc ownership rather than restating
|
||||
signatures unnecessarily;
|
||||
- retain construction, sources, preparation, execution, profiles, credentials,
|
||||
extensions, redaction, and error guidance;
|
||||
- do not mention the Scriptorium CLI or HTTP contract except as a downstream
|
||||
consumer boundary; and
|
||||
- link file-format and outbound integration details only after their canonical
|
||||
documents exist.
|
||||
|
||||
If `docs/formats.md` is deferred to Stage 7, do not add a broken link; add it
|
||||
when that document is created.
|
||||
|
||||
### Stage 6 Validation
|
||||
|
||||
From Promptkit:
|
||||
|
||||
```sh
|
||||
go test .
|
||||
go test ./...
|
||||
go test -race ./...
|
||||
go vet ./...
|
||||
go build ./...
|
||||
gofmt -l $(git ls-files '*.go')
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Also:
|
||||
|
||||
1. Run `go doc .` and compare the exported inventory with the characterized
|
||||
Scriptorium facade, allowing only the package/module identity change.
|
||||
2. Run focused public contract tests for construction, source options, profile
|
||||
precedence, preparation, execution, validation, timeout layering, custom
|
||||
clients, custom artifact readers, copying, redaction, and errors.
|
||||
3. Confirm `String` and `GoString` never expose raw API keys and contain no
|
||||
`scriptorium.` type prefix.
|
||||
4. Confirm the recursive dependency guard detects a temporary nested
|
||||
Scriptorium import when deliberately exercised, then remove the temporary
|
||||
violation.
|
||||
5. Search every tracked Go file for the Scriptorium module path and require no
|
||||
matches.
|
||||
6. Confirm no public subpackage, command, application config, inbound HTTP
|
||||
adapter, or compatibility shim exists.
|
||||
7. Check every changed Markdown link and every new GoDoc example.
|
||||
|
||||
### Stage 6 Completion Gate
|
||||
|
||||
Proceed only when an external Go consumer can construct and exercise the
|
||||
Promptkit engine through the module root and the complete public contract suite
|
||||
passes without Scriptorium or repository-local coupling.
|
||||
|
||||
## Stage 7: Complete Durable Documentation, Examples, And Release Readiness
|
||||
|
||||
### Objective
|
||||
|
||||
Finish Promptkit's current-state documentation and provide a maintained,
|
||||
offline consumer workflow before release validation.
|
||||
|
||||
### Framework Format Contract
|
||||
|
||||
Create `docs/formats.md` as the canonical owner for:
|
||||
|
||||
- prompt-definition YAML fields and strict decoding;
|
||||
- inputs, messages, inline content, `content_file`, cache control, session IDs,
|
||||
default profiles, and output contracts;
|
||||
- profile YAML fields, ranges, overlays, `api_key_env`, raw-key prohibition,
|
||||
and execution settings;
|
||||
- the current built-in profile catalog;
|
||||
- schema references and supported validation modes;
|
||||
- credential behavior that belongs to framework formats; and
|
||||
- relationships among file values, in-memory profiles, and request overrides.
|
||||
|
||||
Derive framework-format content from the implemented code and the framework
|
||||
sections of Scriptorium's `docs/config.md`. Do not copy:
|
||||
|
||||
- Scriptorium config discovery;
|
||||
- `prompt_dir`, `profile_dir`, or `schema_dir` application precedence;
|
||||
- server settings;
|
||||
- render-output settings;
|
||||
- CLI flags; or
|
||||
- Scriptorium operations behavior.
|
||||
|
||||
Update Promptkit's documentation policy to assign framework formats to
|
||||
`docs/formats.md`. Update all consumer, integration, and internal documents to
|
||||
link to that canonical owner rather than duplicate its field tables and
|
||||
defaults.
|
||||
|
||||
### Consumer Example
|
||||
|
||||
Create a self-contained offline example at:
|
||||
|
||||
- `examples/go-library/prepare/main.go`
|
||||
- `examples/go-library/prepare/prompt.yaml`
|
||||
|
||||
The example:
|
||||
|
||||
- imports `gitea.maximumdirect.net/eric/promptkit`;
|
||||
- uses `WithPromptFile` for its repository-local prompt;
|
||||
- supplies a valid in-memory `Profile` with `WithProfiles`;
|
||||
- uses an inline synthetic input;
|
||||
- calls `Prepare`, not a live provider;
|
||||
- prints deterministic JSON containing only stable summary fields;
|
||||
- requires no credential or environment variable;
|
||||
- reads no Scriptorium path; and
|
||||
- runs from the Promptkit repository root with
|
||||
`go run ./examples/go-library/prepare`.
|
||||
|
||||
Keep the prompt asset minimal and copyable. Do not duplicate Scriptorium's full
|
||||
executable example tree.
|
||||
|
||||
### Documentation Reconciliation
|
||||
|
||||
Reconcile these Promptkit documents with the final implemented tree:
|
||||
|
||||
- `README.md`
|
||||
- `docs/development.md`
|
||||
- `docs/policy/architecture.md`
|
||||
- `docs/policy/documentation.md`
|
||||
- `docs/policy/testing.md`
|
||||
- `docs/release.md`
|
||||
- `docs/consumers/pkg-promptkit.md`
|
||||
- `docs/formats.md`
|
||||
- `docs/integrations/openai-compatible-chat.md`
|
||||
- `docs/internal/overview.md`
|
||||
- `docs/internal/runner.md`
|
||||
- `docs/internal/sources.md`
|
||||
- `docs/internal/llm.md`
|
||||
|
||||
Requirements:
|
||||
|
||||
- The README provides a minimal current quickstart and links to the maintained
|
||||
example and consumer guide.
|
||||
- The development guide routes public API, source, model-client, validation,
|
||||
test, example, documentation, and release work to current owners.
|
||||
- Architecture and the internal overview agree on every package and dependency
|
||||
boundary.
|
||||
- The testing policy describes the actual consumer-workflow and package test
|
||||
types without copying a test inventory.
|
||||
- The release procedure adds `go test -race ./...` to pre-tag validation while
|
||||
retaining ordinary test, vet, build, formatting, links, and hygiene checks.
|
||||
- The release procedure still requires a clean checkout, no workspace or
|
||||
replacement, an annotated semantic tag, and remote verification.
|
||||
- The first release remains `v0.1.0`; do not create it in this stage.
|
||||
- No permanent Promptkit document relies on the temporary Scriptorium roadmap
|
||||
as its current contract.
|
||||
- No document claims Promptkit provides a command, inbound HTTP service,
|
||||
application configuration, or binary release.
|
||||
- Exact Go declarations stay in GoDoc; exact format and wire definitions stay
|
||||
in their canonical documents.
|
||||
|
||||
### Stage 7 Validation
|
||||
|
||||
From Promptkit:
|
||||
|
||||
```sh
|
||||
go test ./...
|
||||
go test -race ./...
|
||||
go vet ./...
|
||||
go build ./...
|
||||
go run ./examples/go-library/prepare
|
||||
gofmt -l $(git ls-files '*.go')
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Also:
|
||||
|
||||
1. Validate every maintained local Markdown link.
|
||||
2. Compile or run fenced Go snippets that are represented as runnable.
|
||||
3. Confirm the example output is deterministic and contains no secret,
|
||||
timestamp, absolute path, or machine-specific value.
|
||||
4. Search maintained files for:
|
||||
|
||||
- the Scriptorium module import;
|
||||
- `scriptorium.RunRequest` and `scriptorium.GenerateRequest`;
|
||||
- stale claims that framework APIs are unimplemented;
|
||||
- template residue;
|
||||
- absolute maintainer filesystem paths;
|
||||
- live credentials; and
|
||||
- claims of hosted CI or binary releases.
|
||||
|
||||
5. Confirm `docs/formats.md` owns framework field tables and that other
|
||||
documents summarize and link.
|
||||
6. Confirm the README, architecture policy, development guide, internal
|
||||
overview, consumer guide, and release procedure agree that Promptkit is a
|
||||
usable library validated by maintainers.
|
||||
|
||||
### Stage 7 Completion Gate
|
||||
|
||||
Proceed only when Promptkit can be understood, used, tested, and prepared for
|
||||
release solely from its own maintained documentation and example.
|
||||
|
||||
## Stage 8: Validate, Publish `v0.1.0`, And Close Step 6
|
||||
|
||||
### Objective
|
||||
|
||||
Validate the complete extraction from clean independent checkouts, publish the
|
||||
first immutable Promptkit module tag, verify remote consumption, and record the
|
||||
completed migration gate in Scriptorium.
|
||||
|
||||
### Prepare The Promptkit Release Candidate
|
||||
|
||||
Before release:
|
||||
|
||||
1. Review every Promptkit change against the recorded Scriptorium source
|
||||
commit.
|
||||
2. Confirm all Stages 1 through 7 are committed in Promptkit with a clean
|
||||
working tree.
|
||||
3. Use plain-English commit messages and keep Promptkit commits in the
|
||||
Promptkit repository only.
|
||||
4. Confirm no `go.work`, `go.work.sum`, local `replace`, generated output, or
|
||||
temporary extraction script is tracked.
|
||||
5. Confirm the release candidate commit is published through Promptkit's normal
|
||||
branch workflow before tagging, as required by `docs/release.md`.
|
||||
|
||||
Do not amend, force-push, or retag an already published version to correct a
|
||||
late failure. Correct the source and repeat validation before the first tag is
|
||||
published.
|
||||
|
||||
### Independent Promptkit Acceptance
|
||||
|
||||
Create a fresh temporary checkout of the exact Promptkit release candidate
|
||||
outside both repositories. Ensure `GOWORK` is empty or `off`. From that
|
||||
checkout run:
|
||||
|
||||
```sh
|
||||
go mod tidy
|
||||
go test ./...
|
||||
go test -race ./...
|
||||
go vet ./...
|
||||
go build ./...
|
||||
go run ./examples/go-library/prepare
|
||||
gofmt -l $(git ls-files '*.go')
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Require the checkout to remain clean after validation.
|
||||
|
||||
Verify module identity:
|
||||
|
||||
```sh
|
||||
go list -m -f '{{.Path}} {{.GoVersion}}'
|
||||
go list -f '{{.Name}} {{.ImportPath}}' .
|
||||
```
|
||||
|
||||
Verify dependency independence:
|
||||
|
||||
- `go list -m all` contains no Scriptorium module;
|
||||
- `go list -deps ./...` contains no Scriptorium package;
|
||||
- a recursive source search contains no Scriptorium module import;
|
||||
- `go.mod` has no `replace`;
|
||||
- no workspace file is tracked; and
|
||||
- no source, fixture, example, or documentation read depends on a sibling
|
||||
checkout.
|
||||
|
||||
Verify architecture and assets:
|
||||
|
||||
- the root is the only supported public Promptkit package;
|
||||
- all implementation packages are under `internal/`;
|
||||
- no `cmd`, inbound adapter, application config, restricted HTTP reader, or
|
||||
executable artifact exists;
|
||||
- the 24 built-in assets match the recorded extraction source and all load;
|
||||
- the architecture dependency test passes;
|
||||
- the public Go inventory and sentinel errors match the accepted initial
|
||||
facade;
|
||||
- all local Markdown links and runnable examples pass; and
|
||||
- GPLv3 and Promptkit-specific notices remain unchanged by extraction.
|
||||
|
||||
If any check fails, fix the owning stage, commit the correction, and repeat the
|
||||
entire fresh-checkout acceptance suite.
|
||||
|
||||
### Preserve The Pre-Cutover Scriptorium
|
||||
|
||||
Before tagging, validate Scriptorium from its own repository without a
|
||||
workspace or replacement:
|
||||
|
||||
```sh
|
||||
go test ./...
|
||||
go vet ./...
|
||||
go build ./cmd/scriptorium
|
||||
git diff --check
|
||||
```
|
||||
|
||||
Run maintained configuration and example checks required by Scriptorium's
|
||||
current documentation when affected by any intervening source correction.
|
||||
Confirm:
|
||||
|
||||
- `go.mod` has no Promptkit dependency or local replacement;
|
||||
- the CLI and HTTP adapters still use the current Scriptorium facade;
|
||||
- no framework implementation was deleted;
|
||||
- no current Scriptorium contract was redirected prematurely; and
|
||||
- only roadmap documentation is awaiting the Step 6 completion update.
|
||||
|
||||
### Publish And Verify `v0.1.0`
|
||||
|
||||
Follow Promptkit's `docs/release.md` exactly:
|
||||
|
||||
1. create annotated tag `v0.1.0` on the accepted Promptkit commit;
|
||||
2. record in the annotation that documented validation passed for that commit;
|
||||
3. inspect the tag and its resolved commit;
|
||||
4. push the tag to the configured Promptkit origin; and
|
||||
5. verify the remote annotated tag object and resolved commit.
|
||||
|
||||
Do not publish a binary or hosting-provider-specific release artifact.
|
||||
|
||||
After the remote tag is available, create a temporary Go consumer module
|
||||
outside both repositories with `GOWORK=off`. Require
|
||||
`gitea.maximumdirect.net/eric/promptkit@v0.1.0` from the configured remote,
|
||||
compile a minimal program that imports the root package and uses an exported
|
||||
value such as `promptkit.Inline`, and confirm:
|
||||
|
||||
- the module resolves without a local replacement;
|
||||
- the selected version is exactly `v0.1.0`; and
|
||||
- the program builds against the published tag.
|
||||
|
||||
This temporary smoke module is validation only. Do not commit it or use it to
|
||||
begin Scriptorium adoption.
|
||||
|
||||
### Scriptorium Completion Records
|
||||
|
||||
Only after the tag and remote-consumption check succeed, update Scriptorium:
|
||||
|
||||
- change `docs/roadmap/step6.md` to Complete and replace active planning prose
|
||||
with a concise completion record that includes the source Scriptorium commit,
|
||||
accepted Promptkit commit, published tag, validation outcome, retained
|
||||
application boundary, and Step 7 gate;
|
||||
- update `docs/roadmap/migration.md` to mark Steps 1 through 6 complete and
|
||||
identify tagged Promptkit adoption and Scriptorium framework removal in Step
|
||||
7 as next;
|
||||
- revise this file into a concise `Completed Work` record rather than leaving
|
||||
an active stage checklist; and
|
||||
- remove stale “next step” language from older completed gate summaries if any
|
||||
has reappeared.
|
||||
|
||||
Do not update Scriptorium production code, imports, `go.mod`, consumer
|
||||
documentation, or executable examples in this stage.
|
||||
|
||||
Validate all changed Scriptorium links and run `git diff --check`. Keep the
|
||||
completion-record commit in Scriptorium's history and separate from all
|
||||
Promptkit commits.
|
||||
|
||||
### Stage 8 Completion Gate
|
||||
|
||||
Step 6 is complete only when:
|
||||
|
||||
- all feature-roadmap completion criteria are satisfied;
|
||||
- Promptkit passes the full suite from a clean independent checkout;
|
||||
- Scriptorium remains valid in its pre-cutover state;
|
||||
- remote tag `v0.1.0` resolves to the accepted Promptkit commit;
|
||||
- a clean temporary consumer resolves and builds against that tag without a
|
||||
replacement;
|
||||
- both repositories have clean, independent histories; and
|
||||
- Scriptorium's migration roadmap authorizes Step 7 and no earlier adoption.
|
||||
|
||||
## Open Questions
|
||||
|
||||
None. The accepted ADRs, Step 6 feature roadmap, characterized facade, and
|
||||
current repository policies resolve the extraction, public boundary,
|
||||
validation, documentation, and release decisions required for implementation.
|
||||
Reference in New Issue
Block a user