Add an implementation plan and roadmap for Step 3 of the migration plan
This commit is contained in:
339
docs/roadmap/implementation.md
Normal file
339
docs/roadmap/implementation.md
Normal file
@@ -0,0 +1,339 @@
|
|||||||
|
# Migration Step 3 Implementation Plan
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Ready for implementation. No implementation work described here has started.
|
||||||
|
|
||||||
|
## Objective
|
||||||
|
|
||||||
|
Implement the target state in the
|
||||||
|
[Step 3 framework-characterization roadmap](step3.md): make
|
||||||
|
Promptkit-destined tests independent of Scriptorium-owned executable examples,
|
||||||
|
close the identified public contract gaps, and leave every migration-critical
|
||||||
|
behavior with a clear test owner.
|
||||||
|
|
||||||
|
Follow the accepted ownership boundary in
|
||||||
|
[ADR 0002](../adr/0002-split-promptkit-from-scriptorium.md) and the test-value
|
||||||
|
and non-duplication rules in the [testing policy](../policy/testing.md).
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
|
||||||
|
- Execute the stages in order and satisfy each gate before proceeding.
|
||||||
|
- Do not change production behavior, public types, method signatures, package
|
||||||
|
boundaries, or application interfaces.
|
||||||
|
- Limit implementation changes to testdata, tests, and roadmap status.
|
||||||
|
- Keep all default-suite tests deterministic, offline, and independent of real
|
||||||
|
credentials.
|
||||||
|
- Preserve unrelated working-tree changes.
|
||||||
|
- Do not copy the complete `examples/` tree into testdata.
|
||||||
|
- Do not add tests merely to raise statement coverage.
|
||||||
|
- Prefer extending or consolidating an existing test over adding a parallel
|
||||||
|
test for the same behavior.
|
||||||
|
|
||||||
|
## Stage 1: Create The Framework Contract Corpus
|
||||||
|
|
||||||
|
Create this Promptkit-destined fixture tree:
|
||||||
|
|
||||||
|
```text
|
||||||
|
testdata/framework/
|
||||||
|
├── fixtures/
|
||||||
|
│ ├── glossary.yml
|
||||||
|
│ └── transcript.md
|
||||||
|
├── profiles/
|
||||||
|
│ ├── contract-fast.yaml
|
||||||
|
│ └── contract-quality.yaml
|
||||||
|
├── prompts/
|
||||||
|
│ ├── contract.markdown_summary.system.md
|
||||||
|
│ ├── contract.markdown_summary.user.md
|
||||||
|
│ ├── contract.markdown_summary.yaml
|
||||||
|
│ ├── contract.structured_events.system.md
|
||||||
|
│ ├── contract.structured_events.user.md
|
||||||
|
│ └── contract.structured_events.yaml
|
||||||
|
└── schemas/
|
||||||
|
└── structured_events.schema.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Define the corpus as follows:
|
||||||
|
|
||||||
|
- `contract.markdown_summary`
|
||||||
|
- version `1.0.0`;
|
||||||
|
- default profile `contract-fast`;
|
||||||
|
- required `transcript` input and optional `glossary` input;
|
||||||
|
- system and user messages loaded through relative `content_file` paths; and
|
||||||
|
- Markdown output with basic validation and no repair attempts.
|
||||||
|
- `contract.structured_events`
|
||||||
|
- version `1.0.0`;
|
||||||
|
- default profile `contract-quality`;
|
||||||
|
- the same two inputs;
|
||||||
|
- system and user messages loaded through relative `content_file` paths; and
|
||||||
|
- JSON output with JSON Schema validation through
|
||||||
|
`structured_events.schema.json` and no repair attempts.
|
||||||
|
- `contract-fast`
|
||||||
|
- endpoint `http://localhost:8000/v1`;
|
||||||
|
- model `contract-fast-model`;
|
||||||
|
- temperature `0.2`, max tokens `500`, top-p `1`, and timeout `90`; and
|
||||||
|
- no credential requirement.
|
||||||
|
- `contract-quality`
|
||||||
|
- endpoint `http://localhost:8000/v1`;
|
||||||
|
- model `contract-quality-model`;
|
||||||
|
- temperature `0.1`, max tokens `1000`, top-p `0.9`, and timeout `120`; and
|
||||||
|
- no credential requirement.
|
||||||
|
- The schema requires an object containing an `events` array. Keep it small but
|
||||||
|
valid for the same JSON Schema draft currently used by the maintained
|
||||||
|
structured-output example.
|
||||||
|
- The transcript and glossary contain short synthetic values suitable for
|
||||||
|
rendering and hash assertions. They must contain no private or real-world
|
||||||
|
data.
|
||||||
|
|
||||||
|
Do not add application configuration, HTTP requests, executable scripts, or
|
||||||
|
provider credentials to this corpus.
|
||||||
|
|
||||||
|
In `engine_test.go`, add shared constants for the contract root, prompt IDs,
|
||||||
|
profile IDs, and fixture paths. Replace
|
||||||
|
`TestPrepareWorksWithExampleDirectoriesAndFileInputs` with
|
||||||
|
`TestPrepareWorksWithFrameworkContractCorpus`, using table cases for the
|
||||||
|
ordinary and structured prompts. Construct the public engine from the new
|
||||||
|
directories, use the new file artifacts, and assert that each prompt renders
|
||||||
|
with its intended profile. For the structured case, also assert that
|
||||||
|
`PreparedRun.StructuredOutput` contains the loaded JSON Schema specification.
|
||||||
|
This test is the real-parser acceptance check for the corpus.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go test .
|
||||||
|
go test ./internal/promptdef ./internal/profile ./internal/validate
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stage 1 Gate
|
||||||
|
|
||||||
|
- Every corpus file loads through its real owning parser.
|
||||||
|
- Relative prompt content resolves from the prompt file location.
|
||||||
|
- The structured schema decodes through the real validator's schema-document
|
||||||
|
loader and appears in the prepared structured-output specification.
|
||||||
|
- No production or executable-example file changed.
|
||||||
|
|
||||||
|
## Stage 2: Move Framework Tests Onto Framework-Owned Fixtures
|
||||||
|
|
||||||
|
Update `engine_test.go` to use the new corpus.
|
||||||
|
|
||||||
|
1. Reuse the contract constants introduced in Stage 1.
|
||||||
|
2. Rename:
|
||||||
|
- `newExampleEngine` to `newContractEngine`;
|
||||||
|
- `newExampleEngineWithOptions` to `newContractEngineWithOptions`; and
|
||||||
|
- `exampleConfig` to `contractConfig`.
|
||||||
|
3. Make `contractConfig` point at the corpus prompt, profile, and schema
|
||||||
|
directories.
|
||||||
|
4. Replace each `./examples/...` dependency in `engine_test.go` with the
|
||||||
|
matching contract fixture or a purpose-built `t.TempDir`,
|
||||||
|
`fstest.MapFS`, or in-memory profile.
|
||||||
|
5. Update assertions that intentionally identify fixture prompt IDs, profile
|
||||||
|
IDs, models, rendered text, or hashes to the contract values. Do not change
|
||||||
|
assertions that express independent public behavior.
|
||||||
|
6. Rename tests whose names say “example” when they now exercise contract
|
||||||
|
testdata.
|
||||||
|
|
||||||
|
Add `TestEngineRunWithDirectorySourcesAndFileInputs` to `engine_test.go`. It
|
||||||
|
must assemble the public engine from the contract prompt, profile, schema, and
|
||||||
|
file-artifact directories; inject a deterministic `LLMClient`; run
|
||||||
|
`contract.structured_events`; and assert:
|
||||||
|
|
||||||
|
- the prompt-selected `contract-quality` profile;
|
||||||
|
- a non-empty run ID, prompt hash, rendered-prompt hash, and both input hashes;
|
||||||
|
- provider-level JSON Schema structured output on the captured generation
|
||||||
|
request;
|
||||||
|
- passed JSON Schema validation;
|
||||||
|
- `application/json` artifact content;
|
||||||
|
- preserved raw output and injected token usage; and
|
||||||
|
- non-zero ordered timestamps with non-negative duration.
|
||||||
|
|
||||||
|
Move the unique protection from
|
||||||
|
`internal/usecase/integration_test.go` into this public test, then delete that
|
||||||
|
internal integration test. Do not retain both assembled workflows.
|
||||||
|
|
||||||
|
The only test references to `examples/` after this stage should be
|
||||||
|
Scriptorium-owned adapter or maintained-example checks. In particular, this
|
||||||
|
command must return no matches:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rg -n 'examples/' engine_test.go internal/usecase
|
||||||
|
```
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go test .
|
||||||
|
go test ./internal/usecase
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stage 2 Gate
|
||||||
|
|
||||||
|
- Public and framework-internal tests pass without reading Scriptorium-owned
|
||||||
|
executable examples.
|
||||||
|
- The new public assembled workflow subsumes the deleted internal integration
|
||||||
|
test.
|
||||||
|
- Scriptorium's maintained examples are unchanged.
|
||||||
|
- No production file changed.
|
||||||
|
|
||||||
|
## Stage 3: Consolidate And Complete Public Characterization
|
||||||
|
|
||||||
|
### Execution-Setting Precedence
|
||||||
|
|
||||||
|
Add a table-driven `TestEngineExecutionSettingPrecedence` in `engine_test.go`.
|
||||||
|
Run through the public engine with an injected recording `LLMClient`. Cover
|
||||||
|
these cases:
|
||||||
|
|
||||||
|
1. a profile with zero-valued optional settings receives the documented
|
||||||
|
framework numeric defaults;
|
||||||
|
2. non-zero profile settings replace those defaults;
|
||||||
|
3. request settings replace profile settings; and
|
||||||
|
4. explicit request numeric zero replaces non-zero profile settings.
|
||||||
|
|
||||||
|
Across the table, verify the effective endpoint, model, temperature,
|
||||||
|
max-tokens, top-p, timeout, service tier, reasoning effort, API-key environment
|
||||||
|
name, and `extra_params` where the relevant layer supplies them. Verify
|
||||||
|
`ExecutionTargetPresence` is false for omitted numeric request settings and
|
||||||
|
true for every explicitly supplied numeric setting, including zero.
|
||||||
|
|
||||||
|
Use relationally distinct values for each layer. Assert literal framework
|
||||||
|
defaults only in the framework-default case because those values are part of
|
||||||
|
the documented public contract. Use `t.Setenv` for every non-empty profile or
|
||||||
|
request API-key environment name, assert only the environment-variable names,
|
||||||
|
and never expose the test secret values.
|
||||||
|
|
||||||
|
Consolidate overlapping assertions:
|
||||||
|
|
||||||
|
- remove `TestPreparePreservesExplicitZeroExecutionOverrides` once the new
|
||||||
|
table protects that behavior; and
|
||||||
|
- retain `TestRunPassesPreparedRequestToInjectedLLMClient` for rendered prompt,
|
||||||
|
direct-key, and structured-output handoff, but remove execution-precedence
|
||||||
|
assertions now owned by the table.
|
||||||
|
|
||||||
|
### Caller Cancellation
|
||||||
|
|
||||||
|
Add `TestEngineRunPropagatesCallerCancellation` using the built-in
|
||||||
|
OpenAI-compatible client and a custom `RoundTripper`.
|
||||||
|
|
||||||
|
- The transport must signal through a channel when `RoundTrip` begins.
|
||||||
|
- It must block on `req.Context().Done()` and return the context error.
|
||||||
|
- Start `Engine.Run` in a goroutine, wait for the transport signal, cancel the
|
||||||
|
caller context, and collect the result through a buffered channel.
|
||||||
|
- Assert that the call returns and the error matches `ErrLLMGenerate`.
|
||||||
|
- Do not use sleeps or elapsed-time assertions.
|
||||||
|
|
||||||
|
### Injected Nil Response
|
||||||
|
|
||||||
|
Add a valid-request case to `TestPublicErrorsSupportErrorsIs` whose injected
|
||||||
|
`LLMClient` returns `(nil, nil)`. Assert `ErrLLMGenerate`. Extend the existing
|
||||||
|
fake only as needed to express this case; do not create a mock framework.
|
||||||
|
|
||||||
|
### Reserved Provider Parameters
|
||||||
|
|
||||||
|
Add `TestRunRejectsReservedExtraParamsBeforeProviderCall`.
|
||||||
|
|
||||||
|
- Use the built-in client with a custom immediate `RoundTripper` that records
|
||||||
|
whether it was invoked.
|
||||||
|
- Supply a valid contract prompt and profile plus request
|
||||||
|
`ExtraParams: map[string]any{"model": "collision"}`.
|
||||||
|
- Assert `ErrInvalidRequest`.
|
||||||
|
- Assert that the transport was not invoked.
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go test .
|
||||||
|
go test -count=20 .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Stage 3 Gate
|
||||||
|
|
||||||
|
- The four-layer precedence table and presence assertions pass.
|
||||||
|
- Cancellation is deterministic and contains no wall-clock sleeps.
|
||||||
|
- Nil injected responses and reserved parameters preserve their public error
|
||||||
|
categories.
|
||||||
|
- Superseded assertions or tests have been removed rather than duplicated.
|
||||||
|
- No production file changed.
|
||||||
|
|
||||||
|
## Stage 4: Audit Ownership And Validate The Baseline
|
||||||
|
|
||||||
|
### Ownership Audit
|
||||||
|
|
||||||
|
Review the behavior list in [step3.md](step3.md) against the final suite.
|
||||||
|
Confirm:
|
||||||
|
|
||||||
|
- root facade and public contract tests are Promptkit-destined;
|
||||||
|
- `internal/domain`, `internal/usecase`, `internal/promptdef`,
|
||||||
|
`internal/prompt`, `internal/profile`, `internal/profile/builtin`,
|
||||||
|
`internal/filecatalog`, general `internal/artifact`, `internal/validate`, and
|
||||||
|
`internal/llm` tests move with Promptkit-owned behavior;
|
||||||
|
- CLI, application configuration, prepared formatting, HTTP DTO, strict JSON,
|
||||||
|
HTTP limit, and rooted artifact-containment tests remain Scriptorium-owned;
|
||||||
|
- HTTP and CLI tests that currently construct internal runners or inspect
|
||||||
|
internal sentinels retain their observable assertions and are explicitly
|
||||||
|
deferred for boundary rewrites in Migration Step 4; and
|
||||||
|
- no consequential behavior in the feature roadmap lacks a test owner.
|
||||||
|
|
||||||
|
Do not create a permanent test-inventory document. Record any unexpected
|
||||||
|
ownership exception in `step3.md`; otherwise the ownership table there is the
|
||||||
|
complete disposition.
|
||||||
|
|
||||||
|
### Full Validation
|
||||||
|
|
||||||
|
Run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go test ./...
|
||||||
|
go vet ./...
|
||||||
|
build_dir="$(mktemp -d)"
|
||||||
|
go build -o "$build_dir/scriptorium" ./cmd/scriptorium
|
||||||
|
go test -count=20 .
|
||||||
|
go test ./internal/adapter/http -run TestMaintainedHTTPRunExampleMatchesRequestContract
|
||||||
|
bash ./examples/render-markdown-summary.sh
|
||||||
|
go run ./cmd/scriptorium render \
|
||||||
|
--config ./examples/config.full.yml \
|
||||||
|
--prompt generic.markdown_summary \
|
||||||
|
--input transcript=./examples/fixtures/transcript.md \
|
||||||
|
--input glossary=./examples/fixtures/glossary.yml \
|
||||||
|
--format text
|
||||||
|
go run ./examples/go-library/prepare
|
||||||
|
git diff --check
|
||||||
|
```
|
||||||
|
|
||||||
|
Validate every local Markdown link and path in the changed roadmap files.
|
||||||
|
Confirm both configuration examples were accepted through the real
|
||||||
|
configuration loader by the two render commands.
|
||||||
|
|
||||||
|
Inspect the final diff and confirm the implementation changed only:
|
||||||
|
|
||||||
|
- `testdata/framework/**`;
|
||||||
|
- `engine_test.go`;
|
||||||
|
- `internal/usecase/integration_test.go` by deletion;
|
||||||
|
- `docs/roadmap/step3.md`;
|
||||||
|
- `docs/roadmap/implementation.md`; and
|
||||||
|
- the Step 3 status in `docs/roadmap/migration.md`.
|
||||||
|
|
||||||
|
If a necessary change falls outside that list, stop and revise the plan or
|
||||||
|
request direction rather than expanding scope implicitly.
|
||||||
|
|
||||||
|
### Completion Bookkeeping
|
||||||
|
|
||||||
|
After every check passes:
|
||||||
|
|
||||||
|
1. update `step3.md` to state that the target state is complete and summarize
|
||||||
|
the characterized baseline without reintroducing an implementation log;
|
||||||
|
2. add a Step 3 gate-status entry to `migration.md` with the completion date
|
||||||
|
and a short validation summary; and
|
||||||
|
3. mark this implementation plan complete.
|
||||||
|
|
||||||
|
Do not begin Migration Step 4 in the same change.
|
||||||
|
|
||||||
|
### Stage 4 Gate
|
||||||
|
|
||||||
|
- Every completion criterion in `step3.md` is satisfied.
|
||||||
|
- The full suite and maintained examples pass offline.
|
||||||
|
- The diff contains no production behavior or API change.
|
||||||
|
- The main migration roadmap identifies Step 3 as complete and Step 4 as next.
|
||||||
|
|
||||||
|
## Open Questions
|
||||||
|
|
||||||
|
None.
|
||||||
@@ -125,6 +125,9 @@ is accepted and records the required ownership and coordination decisions.
|
|||||||
Strengthen or add contract-focused tests where needed so extraction can be
|
Strengthen or add contract-focused tests where needed so extraction can be
|
||||||
verified without relying on package placement.
|
verified without relying on package placement.
|
||||||
|
|
||||||
|
The accepted implementation scope and intended completion state are in the
|
||||||
|
[Step 3 framework-characterization roadmap](step3.md).
|
||||||
|
|
||||||
Preserve coverage of:
|
Preserve coverage of:
|
||||||
|
|
||||||
- `Prepare` and `Run` behavior;
|
- `Prepare` and `Run` behavior;
|
||||||
|
|||||||
177
docs/roadmap/step3.md
Normal file
177
docs/roadmap/step3.md
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
# Migration Step 3: Framework Characterization
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted scope. Implementation has not started. The ordered execution plan is
|
||||||
|
in [implementation.md](implementation.md).
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Characterize the framework and adapter contracts that must survive the
|
||||||
|
Promptkit extraction. The work should make those contracts portable across the
|
||||||
|
future repository boundary without duplicating behavior at every test layer or
|
||||||
|
changing production APIs ahead of Migration Step 4.
|
||||||
|
|
||||||
|
The [testing policy](../policy/testing.md) governs test value, ownership, and
|
||||||
|
sufficiency. The [accepted split decision](../adr/0002-split-promptkit-from-scriptorium.md)
|
||||||
|
governs which project will own each behavior.
|
||||||
|
|
||||||
|
## Baseline Findings
|
||||||
|
|
||||||
|
The current suite already provides broad coverage at the public facade,
|
||||||
|
framework package, CLI, HTTP, source, validation, and model-client boundaries.
|
||||||
|
Step 3 is therefore a portability and risk-closing exercise rather than a
|
||||||
|
general coverage expansion.
|
||||||
|
|
||||||
|
The principal extraction risk is fixture ownership:
|
||||||
|
|
||||||
|
- public `Engine` tests rely extensively on executable assets under
|
||||||
|
`examples/`;
|
||||||
|
- the assembled runner integration test also reads those assets; and
|
||||||
|
- the accepted split leaves executable examples in Scriptorium while moving
|
||||||
|
the public facade and framework tests to Promptkit.
|
||||||
|
|
||||||
|
Those dependencies would either prevent the tests from moving or create
|
||||||
|
unwanted cross-repository fixture coupling. A smaller set of public-boundary
|
||||||
|
gaps also remains around complete setting precedence, cancellation, malformed
|
||||||
|
injected-client behavior, and reserved provider parameters.
|
||||||
|
|
||||||
|
## Target State
|
||||||
|
|
||||||
|
At completion:
|
||||||
|
|
||||||
|
- tests destined for Promptkit use only Promptkit-destined testdata or
|
||||||
|
fixtures generated within the test;
|
||||||
|
- Scriptorium's maintained executable examples remain independently validated
|
||||||
|
by Scriptorium-owned checks;
|
||||||
|
- each behavior named in the main migration roadmap has one clear test owner;
|
||||||
|
- representative public `Engine` tests protect assembled framework behavior;
|
||||||
|
- focused package tests continue to own strict parsing, source mechanics,
|
||||||
|
validation rules, and provider mapping without higher-level duplication;
|
||||||
|
- Scriptorium adapter tests continue to protect CLI, HTTP, containment, limits,
|
||||||
|
and transport mappings; and
|
||||||
|
- no production API or package boundary has changed as part of Step 3.
|
||||||
|
|
||||||
|
## Policy Choices
|
||||||
|
|
||||||
|
### Framework-Owned Testdata
|
||||||
|
|
||||||
|
Promptkit-destined tests will use a compact framework contract corpus under root
|
||||||
|
`testdata/` or a purpose-built fixture created inside the test. The shared
|
||||||
|
corpus will contain only the assets needed to express durable framework
|
||||||
|
behavior:
|
||||||
|
|
||||||
|
- one ordinary prompt definition;
|
||||||
|
- one JSON Schema structured-output prompt definition;
|
||||||
|
- representative execution profiles;
|
||||||
|
- one JSON Schema document; and
|
||||||
|
- small file-artifact inputs.
|
||||||
|
|
||||||
|
The corpus should exercise directory-backed loading and relative prompt content
|
||||||
|
where those behaviors matter. Use small inline `fstest.MapFS` or temporary
|
||||||
|
fixtures for cases that do not benefit from shared files.
|
||||||
|
|
||||||
|
The complete executable example tree will not be copied. Testdata will remain
|
||||||
|
minimal, synthetic, secret-free, and distinct from user-facing examples.
|
||||||
|
|
||||||
|
### Test Boundaries And Consolidation
|
||||||
|
|
||||||
|
Representative assembled behavior belongs at the public `Engine` boundary.
|
||||||
|
Focused parsing, source, validation, provider, and adapter mechanics remain
|
||||||
|
with their package-level owners. Existing tests should be consolidated when a
|
||||||
|
new public contract test would otherwise duplicate the same risk.
|
||||||
|
|
||||||
|
The assembled runner integration behavior will be protected through the public
|
||||||
|
facade rather than through a second test tied to internal domain and runner
|
||||||
|
types. Promptkit-destined tests will not read Scriptorium-owned `examples/`
|
||||||
|
assets. Scriptorium adapter and maintained-example checks may continue to do so
|
||||||
|
where the example itself is the contract under test.
|
||||||
|
|
||||||
|
### Required Public Characterization
|
||||||
|
|
||||||
|
The public suite will characterize:
|
||||||
|
|
||||||
|
- an assembled directory-backed `Engine.Run` workflow with file inputs,
|
||||||
|
structured output, schema validation, hashes, usage, and timing;
|
||||||
|
- framework-default, profile, and request execution-setting precedence;
|
||||||
|
- explicit numeric-zero propagation and target-presence metadata;
|
||||||
|
- caller-context cancellation at the outbound generation boundary and its
|
||||||
|
public error classification;
|
||||||
|
- nil responses from injected model clients; and
|
||||||
|
- reserved provider parameters failing before a provider call.
|
||||||
|
|
||||||
|
These tests will use deterministic synchronization, real local collaborators
|
||||||
|
where inexpensive, and fakes only at the model-provider boundary.
|
||||||
|
|
||||||
|
## Target Test Ownership
|
||||||
|
|
||||||
|
| Test category | Future disposition |
|
||||||
|
| --- | --- |
|
||||||
|
| Public `Engine`, facade, model-client extension, and public error contracts | Move to Promptkit. |
|
||||||
|
| Framework domain, runner, prompt, profile, built-in registry, general artifact, validation, and LLM package tests | Move with their Promptkit-owned implementation. |
|
||||||
|
| CLI parsing, application configuration, prepared-run formatting, and process behavior | Remain in Scriptorium. |
|
||||||
|
| HTTP DTOs, strict JSON, limits, response mapping, and rooted artifact containment | Remain in Scriptorium. |
|
||||||
|
| Tests that construct internal runners or classify internal framework sentinels from Scriptorium adapters | Preserve their observable assertions, then rewrite against the public Promptkit boundary during Step 4. |
|
||||||
|
| Maintained Go consumer example | Move to Promptkit. |
|
||||||
|
| Maintained executable configuration, render, HTTP, and fixture examples | Remain in Scriptorium. |
|
||||||
|
|
||||||
|
Existing focused tests remain the owners of:
|
||||||
|
|
||||||
|
- strict prompt, profile, and application YAML decoding;
|
||||||
|
- strict HTTP JSON decoding;
|
||||||
|
- prompt, profile, schema, and artifact source mechanics;
|
||||||
|
- built-in profile validation and overlay fallback;
|
||||||
|
- structured-output encoding and schema validation;
|
||||||
|
- validation content failures versus operational failures;
|
||||||
|
- credential handling and redaction;
|
||||||
|
- OpenAI-compatible wire behavior; and
|
||||||
|
- HTTP artifact restrictions and transport mappings.
|
||||||
|
|
||||||
|
Coverage will be added only if the ownership audit identifies a consequential
|
||||||
|
behavior with no credible existing owner.
|
||||||
|
|
||||||
|
## Required Validation Outcome
|
||||||
|
|
||||||
|
The characterized baseline must pass the complete Go test and vet suites, a
|
||||||
|
temporary-output executable build, repeated public contract tests, both
|
||||||
|
maintained application configurations, maintained render and Go consumer
|
||||||
|
examples, the maintained HTTP request-example check, documentation-link
|
||||||
|
validation, and whitespace validation. All checks must remain offline and
|
||||||
|
independent of real credentials.
|
||||||
|
|
||||||
|
## Out Of Scope
|
||||||
|
|
||||||
|
Step 3 does not:
|
||||||
|
|
||||||
|
- add artifact-reader, repository, validator, or other production extension
|
||||||
|
APIs;
|
||||||
|
- refactor CLI or HTTP adapters to consume the public facade;
|
||||||
|
- move restricted HTTP artifact behavior out of its current package;
|
||||||
|
- create the Promptkit repository or change the Go module path;
|
||||||
|
- move implementation packages between repositories;
|
||||||
|
- create compatibility aliases or forwarding APIs;
|
||||||
|
- redesign the public facade; or
|
||||||
|
- add tests solely to increase a coverage percentage.
|
||||||
|
|
||||||
|
Those changes belong to later migration steps.
|
||||||
|
|
||||||
|
## Completion Criteria
|
||||||
|
|
||||||
|
Step 3 is complete when:
|
||||||
|
|
||||||
|
- Promptkit-destined tests have no dependency on Scriptorium-owned executable
|
||||||
|
examples;
|
||||||
|
- the targeted public contract gaps are covered with deterministic tests;
|
||||||
|
- the full roadmap behavior list has a clear, non-duplicative test owner;
|
||||||
|
- tests that require Step 4 rewrites are explicitly identified;
|
||||||
|
- no production behavior or public API changed;
|
||||||
|
- all validation in Stage 5 passes; and
|
||||||
|
- the main migration roadmap records the Step 3 gate as complete.
|
||||||
|
|
||||||
|
Migration Step 4 must not begin until these criteria are satisfied.
|
||||||
|
|
||||||
|
## Lifecycle
|
||||||
|
|
||||||
|
This is a temporary implementation roadmap. Once Step 3 is complete and its
|
||||||
|
gate status is recorded in the main migration roadmap, this file may be removed;
|
||||||
|
repository history retains the detailed implementation record.
|
||||||
Reference in New Issue
Block a user