Files
scriptorium/docs/roadmap/implementation.md

34 KiB

Step 6 Implementation Plan

Status

Proposed.

This plan implements Migration Step 6: Extract And Stabilize Promptkit. 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:

    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:

    go test ./...
    go vet ./...
    go build ./cmd/scriptorium
    

    From Promptkit:

    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:

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:

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:

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:

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:

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:

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:

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:

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:

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:

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.