Plan effective requirement inspection implementation

This commit is contained in:
2026-10-08 17:28:04 +00:00
parent 7827ca043b
commit 71f6683fda
4 changed files with 715 additions and 362 deletions

View File

@@ -1,392 +1,567 @@
# ReleaseKit Adoption Implementation Plan
# Effective Prompt Requirement Inspection Implementation Plan
Implement the agreed [adoption roadmap](releasekit.md) in the stages below,
in order. Each stage is scoped for one Luna coding-agent prompt. This document
owns the implementation steps; the roadmap owns purpose and selected policy.
Status: Stage 1's tool selection and dependency preparation are complete in
`3ca01ae`. The agreed series-based Go minimum supersedes the original patch-based
requirement. Stage 2's example checker and shared validation profile are
complete in `0d163f8`. Stage 3's native tool bootstrap is complete in
`d594085`. Stage 4's successful-publication fixture is complete in `51b0729`.
Stage 5's failure-propagation fixture is complete in `05082c6`. Stage 6's
publication cutover and documentation are complete in `b186694`. Stage 7's
final source-snapshot validation passed. The implementation is complete and
awaiting review; keep this roadmap available until review is complete.
Implement the [feature roadmap](inspection.md) in order. Each numbered stage
is scoped for one Luna coding-agent prompt. This plan replaces the completed
ReleaseKit adoption plan; that plan remains available in Git history.
## Baseline And Working Rules
- Planning baseline: PromptKit commit
`41b2021d8cd90b8dc15483f63fb1979642acad3a`. ReleaseKit is not yet a dependency;
publication and validation live in `scripts/release.sh` and
`scripts/release-check.sh`.
- Select released ReleaseKit `v0.2.0`, whose commit is
`e030794969fb7787e647a90bbc4eb81bd0610f07`. Use its
[profile](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.2.0/docs/config.md),
[CLI](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.2.0/docs/cli.md),
and [candidate validation](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.2.0/docs/consumers/check.md)
contracts. No upstream changes or sibling-checkout dependency are needed.
- Baseline: `7827ca043b5de84a18199ac8f4b3056691aacbb5`. There is no effective
requirement-inspection API yet. `InspectPrompt` reports declarations;
`Prepare` needs artifacts. The configured engine captures compiled templates.
- The stages use the roadmap's recommended practical analysis core and
active-context inventory. The previously open scope choices and alternatives
are recorded under Open Questions; do not silently substitute broader analysis
or an all-reference inventory.
- Start with [development](../development.md), then read the
[agent](../policy/agents.md) policy and applicable
[architecture](../policy/architecture.md),
[testing](../policy/testing.md),
[documentation](../policy/documentation.md),
[release](../policy/release.md), and [OSS](../policy/oss.md) policies.
Reuse already-read, unchanged policies and preserve unrelated work.
- Inspect current files before each stage. Validate and commit each completed
unit under the agent policy. Follow later explicit user instructions about
commits if they differ.
- All Git publication during implementation verification targets disposable
local remotes. Implementing this plan does not authorize publishing to
PromptKit's actual origin, creating a real release tag, or modifying ReleaseKit.
- Keep PromptKit's runtime API and business logic unchanged. The approved Go
requirement update and tool dependency are module changes, not runtime
ReleaseKit integration.
- Retain source-only publication, the main-before-tag workflow, and completion
at confirmed tag publication. Hosted pages and CI deployment are outside
this adoption. Retire the credential regex without adding a replacement gate.
- Use the latest Go installation available in the development environment.
Activate it as `go`, set `GOTOOLCHAIN=local`, and use it for tool builds,
candidate tests, and examples. At planning time the active local version is
`go1.26.8`; derive the version during implementation instead of freezing it
in scripts. Do not query `go@latest` or download another toolchain to find it.
- Keep dependency preparation separate from offline validation. Reuse successful
checks for unchanged content; do not add parallel validators, a persistent
validation cache, or additional human release sign-offs.
[agent](../policy/agents.md), [architecture](../policy/architecture.md),
[testing](../policy/testing.md), and [documentation](../policy/documentation.md)
policies. Reuse unchanged policies already read. Follow
[ADR 0001](../adr/0001-configuration-boundary.md): interpret final effective
configuration at the ConfigKit handoff, never raw/intermediate sources or
configuration history.
- Inspect the current worktree before each stage; preserve unrelated work.
Validate and commit each completed unit under the agent policy. Keep current
internal documentation accurate as each internal capability lands.
- Preserve all existing inspection, construction, preparation, rendering, and
execution contracts. Discovery limitations must not invalidate templates.
Do not add variable defaults, input schemas, name restrictions, count/size
limits, a branch-expansion budget, or generation-readiness checks.
- No provider calls, actual publication, new dependency, CLI/HTTP layer, upstream
ConfigKit change, or application-specific pipeline concept is needed.
- Public declarations belong in the root facade; analysis belongs in
`internal/prompt`, selection coordination in `internal/usecase`, and metadata
capture in `internal/configuration`. Runtime/domain values remain independent
of ConfigKit. Use the standard parser and `template.IsTrue`; do not implement
a replacement template language or execute whole prompts with fake artifacts.
## Stage 1 — Declare The Released Tool And Advance The Go Requirement
## Concrete API And Result Decisions
**Outcome:** Module metadata selects ReleaseKit as a maintainer tool and records
the initial stable version of the development environment's current Go series
as the consumer minimum, subject to required higher patch minima.
Add root `requirements.go` in Stage 8. The method is:
**Read:** `go.mod`, `go.sum`, the runbook's
[preparation step](../release.md#prepare-the-candidate), and the OSS policy.
```go
func (e *Engine) InspectRequirements(
ctx context.Context, req RequirementInspectionRequest,
) (*RequirementInspection, error)
```
**Changes:**
Define ordinary root-owned values, mirrored by execution-owned internal values
in `internal/domain/requirements.go`; do not export aliases to internal types:
1. From the repository root, use the active latest local Go installation:
`export GOTOOLCHAIN=local`; capture `go env GOVERSION`.
2. Follow the runbook's series-based requirement update: strip the `go` prefix
and final patch component from the captured version, then use
`go mod edit "-go=${release_go_series}.0"`. For example, local Go 1.26.8
normally records `go 1.26.0`. Retain a higher patch minimum if required by a
dependency or a specific correctness fix. This is preparation before the
resulting candidate commit, not an operation performed inside publication.
3. Add the tool with
`go get -tool gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit@v0.2.0`.
Use a Go `tool` declaration, not an artificial runtime import or a
`tools.go` workaround.
4. Prepare dependencies with `GOTOOLCHAIN=local go mod download`. Review the
module and checksum changes; retain necessary tool/transitive dependencies
without opportunistic unrelated upgrades.
5. Apply the OSS policy according to actual use. This is tool-only use, with
no copied ReleaseKit implementation or documentation; that alone requires
no new attribution entry. If a necessary existing dependency selection
changes, maintain its applicable existing notices in this unit.
6. Preserve repository independence: no committed workspace or local
filesystem replacement. Do not select a PromptKit release version or write
a prospective versioned release note in this stage.
```go
type RequirementInspectionRequest struct {
PromptID string
PromptVersion string
ProfileID string
Vars map[string]string
SessionID string
}
**Verification:**
type RequirementKind string // constants: required, optional, conditional
- `GOTOOLCHAIN=local go list -m gitea.maximumdirect.net/eric/ReleaseKit` identifies
`v0.2.0`; module metadata declares the intended tool.
- Run `GOTOOLCHAIN=local go test -mod=readonly ./...` for the Go/module change.
- Inspect `go list -deps .` to confirm the runtime facade has no ReleaseKit
import dependency. Review the diff and commit the unit.
type InputRequirement struct {
Name string
Kind RequirementKind
Declared bool
ContentType *string
Description *string
}
## Stage 2 — Extract The Consumer Check And Declare Shared Validation
type VariableRequirement struct {
Name string
Kind RequirementKind
Supplied bool
}
**Outcome:** One focused example checker and one profile express the selected
validation without changing the publication entry point yet.
type RequirementIssueCode string
**Read:** The example-assertion block in `scripts/release-check.sh`, the three
maintained examples, the testing policy, and ReleaseKit's profile reference.
type RequirementIssue struct {
Code RequirementIssueCode
InputName string
VariableName string
Description string
}
**Changes:**
type RequirementInspection struct {
PromptID string
PromptVersion string
ProfileID string
Inputs []InputRequirement
Variables []VariableRequirement
Complete bool
Issues []RequirementIssue
}
```
1. Create `scripts/check-examples.py`, runnable as
`python3 scripts/check-examples.py`. Use Python's standard library, derive
the repository root from the script location, and run from that root.
2. Move the existing semantic assertions into that checker. Preserve all current
expectations: preparation ID/profile/model/message count; execution output,
validity, validation status, model and token count; observation attempt/retry
counts, usage completeness, and accepted assessment outcome.
3. Execute each example once, parse its JSON, propagate compilation/process and
assertion failures as nonzero results, and provide useful failure context.
Keep the checker narrow; it does not run tests, vet, formatting, links,
module inspection, or publication.
4. Use the selected local Go installation for example execution. Set native
host `GOOS`/`GOARCH` from that installation's `go env GOHOSTOS GOHOSTARCH`
for the example children so ambient cross-build settings do not select an
unexecutable target. Keep normal native cgo/cache settings.
5. Create root `releasekit.json` with these exact selections:
Use `RequirementRequired`, `RequirementOptional`, and
`RequirementConditional` as the kind constant names. Use these issue constants:
| Profile field | Value |
| --- | --- |
| `product` | `"Promptkit"` |
| `remote` | `"origin"` |
| `validation.go.race` | `true` |
| `validation.go.full_vet` | `true` |
| `validation.go_format` | `true` |
| `validation.markdown` | `{}` |
| `validation.module_distribution.workspace_files` | `true` |
| `validation.module_distribution.local_replacements` | `true` |
| Constant | Value | Meaning when discovery is affected |
| --- | --- | --- |
| `RequirementIssueMissingVariable` | `missing_variable` | An absent caller value prevents resolving a dependency decision/name. |
| `RequirementIssueInputContent` | `input_content` | Unavailable artifact content affects further dependencies. |
| `RequirementIssueDynamicInputName` | `dynamic_input_name` | A helper's exact selected name remains unresolved. |
| `RequirementIssueUnsupportedConstruct` | `unsupported_construct` | A construct outside the analysis core prevents discovery. |
| `RequirementIssueExpressionUnresolved` | `expression_unresolved` | An expression cannot be evaluated within the supported semantics, including an incompatible operation. |
Set `checks` to one command whose argument vector is
`["python3", "./scripts/check-examples.py"]`. Its environment map selects
`GOTOOLCHAIN=local`, `GOWORK=off`, `GOFLAGS=-mod=readonly`,
`GOPROXY=off`, `GONOPROXY=none`, and `GOSUMDB=off`. These settings apply to
the additional check; ReleaseKit owns its own shared Go environment.
6. Omit `build`, `delivery`, `expected_push_url`, package-compilation targets,
file-size selection, and Markdown boundary enforcement. Accept the upstream
default out-of-scope handling for outside-checkout Markdown destinations.
7. Add a concise standalone example-check command to the development guide.
Keep the existing publication/checker documentation until the cutover.
Use safe, fixed-category descriptions, optionally identifying reported names.
Do not expose the expression, its literals unrelated to identifiers, its
evaluated values, raw template text, or a Go template execution error. An empty
associated name means no particular named entry is identified; it does not
establish that an input/variable is absent.
**Verification:**
### Classification, Metadata, And Ownership
- Run the new example checker using the offline environment above.
- Check profile JSON syntax and the selected fields against the released
reference. Detailed API/profile equivalence tests belong upstream.
- Review the extracted assertions against the old block, then commit.
- Always report declarations. A declared required input stays required.
Active template accesses can promote an optional declaration to required.
Undeclared references on known inactive paths are omitted.
- An entry is required when its use is established for the context, conditional
when a possible use depends on unresolved analysis, and optional when no
applicable use needs it and unresolved effects do not undermine that conclusion.
An established required use dominates conditional/optional uses.
- Aggregate inputs and variables by exact execution name. Do not trim request
variable keys or discovered helper names. Configuration normalization remains
with the existing configuration adapter.
- Metadata pointers distinguish absent/cleared metadata from an explicit
value, including an explicitly empty value. `Declared` distinguishes a known
declaration from a helper-only reference. No new input-format enforcement.
- `Supplied` is key presence in the caller's variable map, including an empty
string. A required variable's presence satisfies that known presence
requirement; a conditional variable's necessity is unresolved. Optional
lookup absence is not a missing required value. Do not infer Boolean values,
nonblank constraints, or other variable validation from names.
- Sort inputs and variables lexicographically by exact name. Deduplicate issues
by code/input-name/variable-name and sort by that tuple. Diagnostics need no
public expression tree, node offsets, or JSON tags. No stable wire format or
nil-versus-empty slice distinction is promised.
- Return independent slices and metadata pointers; copy request variables at the
facade like `RunRequest`. Never expose or mutate shared template trees.
Callers retain the existing responsibility for concurrent mutation of requests.
## Stage 3 — Add The Native Tool Bootstrap
### Completeness And Uncertainty
**Outcome:** A small shared invocation script builds and runs the module-selected
native executable. Legacy source publication remains active until Stage 6.
`Complete` concerns discovery of both input and variable requirements, not
whether they are satisfied. `{{.audience}} {{input "note"}}` can yield complete
discovery with a missing required `audience` and known required `note`.
Reading the body of `note` is unnecessary to identify that dependency.
**Read:** `.gitignore`, the new module declaration and profile, and the
upstream CLI contract.
Unknown values carry their cause internally. Emit issues and mark incomplete
when uncertainty affects a dependency decision/name, or an opaque construct
can hide requirements. Unknown output text alone does not cause incompleteness.
An unknown branch containing only text need not make discovery incomplete.
**Changes:**
For an unresolved branch, analyze both paths once and combine access summaries:
a name definitely needed on both paths can stay required; names possible on
only some paths are conditional. Merge branch-local unresolved issues.
Compare requirement summaries, not rendered content, and do not enumerate
combinations of independent conditions. Conservative incompleteness is valid
where the core cannot prove an exact set; do not claim completeness there.
1. Create executable POSIX-shell `scripts/releasekit.sh`. Its role is:
enter its repository root, build the declared tool, and invoke the native
executable with the supplied CLI arguments.
2. Use `set -eu`, `GOTOOLCHAIN=local`, `GOWORK=off`, and
`GOFLAGS=-mod=readonly`. Build
`gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit` with
`go build -mod=readonly` into `.releasekit/bin/releasekit`.
Select the native host `GOOS`/`GOARCH` for that build using the active Go
installation's host values.
3. Rebuild through Go's normal build cache on each invocation. This ensures the
executable uses the active Go compiler and module selection, without a
custom cache/version-validation protocol.
4. Use `exec` to invoke the built executable and forward `"$@"` unchanged.
Delegate command/version parsing, candidate guards, and exit classifications
to ReleaseKit. Do not use `go run` for publication.
5. Ignore the root `.releasekit/` directory. Do not commit the built tool or
describe it as a PromptKit binary deliverable.
6. Bootstrap may use ordinary module access if preparation has not populated
caches, while readonly mode preserves module files. Candidate validation and
examples remain offline. Bootstrap does not edit the Go requirement, fetch
Git refs itself, create tags, or add publication guards.
7. Add an optional diagnostic `./scripts/releasekit.sh check VERSION` invocation
to the current runbook, linked to upstream requirements for a committed
candidate. Make clear it is not required before publication.
Unresolved dynamic names/opaque input effects must not leave otherwise optional
declarations falsely definitive. Mark affected declared optional inputs
conditional; an unrestricted unknown input name can affect all such declarations.
An unknown-name issue also describes potential undiscovered undeclared names.
Known required declarations remain required.
**Verification:**
### Initial Analysis Core
- Run `sh -n scripts/releasekit.sh`.
- Run `./scripts/releasekit.sh version`; inspect the executable with
`go version -m` to confirm its recorded Go build version matches the selected
installation and its module selection is the released ReleaseKit.
- Check that bootstrap leaves `go.mod`/`go.sum` unchanged and the tool output
ignored. No real publication is performed. Commit.
Analyze each selected template's executable root. Definitions that are never
invoked do not themselves create requirements.
## Stage 4 — Add A Small Successful Publication Fixture
| Construct | Initial handling |
| --- | --- |
| Text/comments and sequences | No text output; visit executable actions in order. |
| String, Boolean, nil literals; dot/root | Track known values needed for dependencies; root is the supplied string map. |
| Root-map field access, including `$.name` | Record a required named caller variable; absent key produces an unknown value, not an inspection error. |
| Dot inside `with` | Follow the selected pipeline value; do not reinterpret string fields as caller root keys. |
| `index` on the root map with a known string key | Record an optional named lookup, unless another use requires it; absent lookup yields the Go string zero value. |
| Local variables | Single-variable declarations and assignments, root `$`, aliases, lexical scope, and pipeline results; locals are not caller variables. |
| `input` | Known string names, including direct variable/alias-derived names; record the dependency and return an unknown body value. |
| Pipelines/parenthesized expressions | Respect argument order and the previous value's final-argument position. |
| `and`, `or`, `not` | Go truthiness and short-circuit access semantics; return Go-compatible operand/Boolean values. |
| `eq`, `ne`, `lt`, `le`, `gt`, `ge` | String comparisons, including `eq`'s multiple comparison operands; all ordinary arguments are evaluated as Go does. |
| `if`, `else`, `with` | Known-path selection and unresolved-path joining, with correct dot/local scope. |
| Numeric operations, other built-ins, ranges, invoked named templates, other constructs outside the core | Keep discovered dependencies and expose uncertainty when they affect discovery. Do not reject the definition or execute loops/calls speculatively. |
**Outcome:** A standalone offline integration check protects local bootstrap,
profile wiring, and successful source publication.
A numeric literal or unsupported pure output expression is not itself a caller
requirement. Discover its evaluated arguments where that is safe; its value can
remain unknown until a later dependency decision needs it. Known short-circuit
paths must not collect dependencies from skipped operands or branches.
**Read:** The production profile/bootstrap, the testing policy, and the
upstream source-publication contract.
Use a small private known/unknown value model. Branch joins retain identical
known values and can retain finite possible string names from direct
string-valued branch assignments. Different possible names are conditional;
a missing variable/body or opaque value can introduce other unknown names.
Do not evaluate cross-products of possible expression values or build a symbolic
predicate system. Unsupported scopes must not invent root variable names:
preserve explicit root accesses and literal helper references where identifiable,
and report incompleteness for the rest.
**Changes:**
## Stage 1 — Retain Effective Declaration Metadata And Inspection Snapshots
1. Create `scripts/test-release.py`, invoked explicitly with Python 3 during
tooling development. Keep it outside the default Go suite and outside the
profile's release checks. It is not a new per-release gate.
2. Use standard-library temporary directories and subprocesses with real Git
and the released tool. Use a synthetic working repository on `main` and a
local bare `origin`; all identities and release versions are fixture data.
3. Copy the production bootstrap, profile, and relevant ignore rule into the
fixture. Copy the selected `go.mod`/`go.sum` so tool selection follows
production metadata without a local replacement.
4. Add a tiny formatted Go package and test. The test writes an invocation
marker outside the checkout and records `runtime.Version()`. Use small
race/non-race build-tag files so the test can prove the selected suite was
race-enabled. This fixture never imports or retests PromptKit's full library.
5. At the configured example-check path, install a fixture-only Python stand-in
that writes an external invocation marker. Keep the real profile command
and validation selections unchanged. Stage 2 verifies the real examples;
this fixture verifies additional-check wiring.
6. Add a simple version-matched release note, commit the fixture, and push its
`main` to the local bare remote. Run the copied bootstrap's `publish`
command from outside the fixture's repository root to exercise path handling.
7. Keep the test invocation offline with prepared module caches,
`GOTOOLCHAIN=local`, `GOPROXY=off`, `GONOPROXY=none`, and `GOSUMDB=off`.
Format generated Go files before committing them.
8. Assert native status 0, exactly one suite marker and one additional-check
marker, and equal selected/tool-build/test Go versions. Verify that the
local and remote tag are annotated and identify the fixture candidate,
with the committed note as annotation. Confirm module bytes are unchanged
and the fixture remains clean apart from ignored tool output.
**Outcome:** Inspection can obtain captured templates and metadata without
changing execution definitions, hashes, or existing public inspection values.
**Verification:**
- Run `python3 scripts/test-release.py` after dependency preparation.
- Inspect that fixtures and markers use only temporary paths/local remotes.
- Do not add upstream's full tag/recovery/checker matrix or test framework.
Commit the focused success-path test.
## Stage 5 — Cover Local Failure Propagation
**Outcome:** The same fixture demonstrates that failed product validation cannot
publish a tag and that native argument failures remain classified.
**Read:** Stage 4's fixture and ReleaseKit's CLI exit classifications.
**Changes:**
1. Extend the fixture stand-in to select failure through a test-owned
environment value. In a fresh candidate/version, let shared validation pass
and then fail that additional check.
2. Assert nonzero native publication status 1, one suite and one additional-check
invocation, useful failure context, and no selected tag locally or remotely.
Keep the fixture clean and module metadata unchanged.
3. Add one malformed/unsupported invocation case that exercises native status 2.
Check the classification and a useful diagnostic fragment, not a complete
output snapshot.
4. Reuse the small fixture setup and production profile. Do not simulate CI,
live push errors, uncertain-write reconciliation, hosted delivery, or
malicious concurrent mutation; those are upstream responsibilities.
5. Preserve cleanup of the temporary repositories and external markers.
Failures must not modify the actual PromptKit checkout or its remote.
**Verification:**
- Run the completed standalone integration check.
- Review coverage for the three risks: successful wiring, failed additional
validation, and native usage classification. Commit.
## Stage 6 — Cut Over Publication And Its Canonical Documentation
**Outcome:** One publication command uses ReleaseKit; obsolete local validators
and their documented gates are retired in the same unit.
**Read:** `scripts/release.sh`, `scripts/release-check.sh`, the released CLI
and recovery guidance, and the affected canonical documentation.
**Changes:**
1. Replace `scripts/release.sh` with a thin executable wrapper that delegates to
`scripts/releasekit.sh publish`, forwarding supplied arguments through
`exec`. Keep the familiar `./scripts/release.sh VERSION` entry point.
Add no duplicate argument, branch, remote, note, tag, or status machinery.
2. Delete `scripts/release-check.sh`. The shared suite, vet, formatting,
Markdown parser, and module checks now belong to ReleaseKit. The example
assertions already have their focused owner.
3. Remove the credential-pattern gate, clean-candidate diff-whitespace gates,
ambient-workspace rejection, blanket vendor-path check, blanket replacement
prohibition, mandatory four-heading note validator, and extra annotation
commit line. Retain ordinary credential-aware change review and useful
development `git diff --check` commands.
4. Update `scripts/test-release.py` to copy and invoke the actual
`scripts/release.sh` entry point for publication cases. The generic native
invocation can continue to own the CLI classification case.
5. Update `docs/policy/release.md` locally where needed:
shared selections, source-only deliverables, main-before-tag publication,
the simpler note convention, native recovery states, and retired gates.
Preserve SemVer/compatibility rules, immutable records, catalog exceptions,
the Go-update/same-toolchain requirement, and successful-tag-push completion.
Preserve upstream provenance/base-policy metadata; update the local date.
6. Update `docs/policy/testing.md` to describe selected race/full vet and
consumer workflows, with shared machinery upstream. Document the standalone
wiring check as focused development validation, not a recurring release
requirement or part of default Go tests.
7. Rewrite the relevant `docs/release.md` sections around:
activate the latest available local Go; record its series-based minimum
(or a required higher patch minimum) before the candidate commit;
prepare module caches; author the note/footer; retire
completed roadmaps; ordinary review/commit; push `main`; run the single
publication command. Preparation commands may update module metadata before
commit; bootstrap/validation preserve the final candidate.
8. Document native statuses 0/1/2/3 and the upstream captured-endpoint recovery
model. Link to upstream detail and include a concise usable recovery command.
Never resolve uncertainty by deleting a tag before confirming authoritative
absence. No CI wait, successful-push read-back, or installation check is added.
9. Update `docs/development.md`: remove the old checker command/inventory and
scanner reference; retain proportionate tests, formatting, examples and
ordinary review for dirty development work. Identify the optional committed
candidate diagnostic and the separate tooling integration command.
10. Repair links to the removed checker. Keep existing historical release notes,
licenses, runtime inventory, and public API documentation unchanged unless
a concrete affected reference requires correction. No prospective release
note, hosted workflow, or new consumer restriction is part of this unit.
**Verification:**
- Run `sh -n` on the two wrappers and the completed integration check using the
final publication entry point.
- Review the diff for policy/procedure agreement and removal of the listed
duplicate gates. Check links and whitespace without running a second complete
package suite solely for these documentation edits. Commit the cutover.
## Stage 7 — Verify The Actual Profile Against The Complete Source Snapshot
**Outcome:** The assembled adoption is verified without publishing a real
PromptKit release.
**Read:** The final roadmap, profile, wrappers, runbook, and this plan's
completion criteria.
**Read:** `internal/configuration/load.go`, `prompts.go`,
`internal/prompt/template.go`, `internal/domain/domain.go`,
`internal/promptdef/hash.go`, and the source document.
**Work:**
1. Confirm prior stages are committed and the working checkout is clean.
Use the same active local Go installation and prepared module cache.
2. Make a disposable local clone of the final committed PromptKit source,
checkout `main`, and add/commit only a synthetic unused version's release
note there. The note follows the adopted product/version convention and
footer paths. Do not add that note to the actual checkout.
3. Run the clone's `scripts/releasekit.sh check VERSION` with the real profile
and actual example checker. This is the one complete final smoke check:
the real race-enabled suite, full vet, formatting, Markdown, committed
distribution checks, and three examples. Do not also run the old full
checker or another full test/vet/example sequence for that same snapshot.
4. Confirm module files remain unchanged, actual example checks succeed,
shared Markdown/format checks inspect the final source, and the clone remains
clean. This local `check` creates no tag and needs no remote publication.
5. If supported upstream checks expose affected formatting or documentation
defects, correct those specific issues and commit the changed candidate
before repeating the snapshot check. Do not disable the selected validation
to make the smoke check pass.
6. Audit completion against the roadmap: module tool selection, native/same-Go
bootstrap, all six optional validation selections, one local example check,
retired validators/gates, accurate runbooks/policies, and successful fixture
publication/failure protection. Reuse Stage 6's unchanged integration results.
7. Report the implementation commits, checks, and any remaining issues. Update
temporary roadmap/plan status to reflect implemented work awaiting review;
keep the documents available for the user's review. Release preparation and
completed-roadmap retirement remain later maintainer work.
1. Add internal metadata/snapshot values. Retain content-type/description
presence alongside `promptEntry`, not inside the JSON-hashed
`domain.PromptDefinition` or the existing public `PromptInputDefinition`.
2. Capture effective per-input presence from `Resolution.InputInfo` during the
existing Resolve callback before `resolvePrompts` can record normalized
sequences. Use final prompt-ID/version/input-index paths only, following the
existing backend/profile presence-capture pattern. Do not inspect history.
3. Materialize metadata values from the normalized final declaration. Treat
absent/null as no metadata and an explicit empty string as available metadata;
preserve existing accepted/rejected configuration semantics.
4. Define `prompt.RequirementSnapshot` containing compiled templates and
declaration metadata, plus the narrow internal lookup
`GetRequirementSnapshot(id, version string) (RequirementSnapshot, bool)`.
Implement it on the captured configuration adapter. Use exact selected keys
and read-only template access; do not parse/reopen content during lookup.
5. Keep the existing renderer's lookup and all old constructor/API paths intact.
Update the internal source document for the implemented metadata capability.
**Completion criteria:**
**Verify:** Focused configuration tests cover absent, empty, nonempty, and
normalization-sensitive metadata, with real final-value layering/resource capture.
Confirm old inspection shape and definition hashes remain unchanged for equivalent
existing definitions. Run `go test ./internal/configuration ./internal/promptdef ./internal/prompt`.
Commit this unit; do not implement the public method yet.
- The final source-only publication command delegates to released ReleaseKit;
the committed profile is the single local declaration of selected checks.
- Go metadata records the series-based minimum or a required higher patch
minimum; tool build, native validation and examples use the same selected
latest-local-patch Go installation, independently of that consumer minimum.
- Profile-selected shared validation and the real consumer examples pass on the
complete source snapshot, while fixture failures prevent publication.
- No runtime ReleaseKit import, local module replacement, extra release gate,
hosted workflow, provider call, real origin push, or real release tag has
been introduced.
- Canonical docs agree with implemented tooling and preserve the accepted
compatibility, catalog, licensing-footer and release-completion policies.
## Stage 2 — Add Internal Result Values And Literal Dependency Discovery
No significant product decisions remain open. Implementation choices above
settle the filenames, bootstrap, profile, validation boundaries, and test
strategy needed to carry out the agreed scope.
**Outcome:** Straight-line literal helper requirements and declarations are
discoverable through an internal analyzer.
**Work:**
1. Add internal counterparts of the result kinds, metadata, and issue values
defined above in `internal/domain/requirements.go`.
2. Add `internal/prompt/requirements.go` and focused tests. Provide one analyzer
entry taking context, selected definition, captured snapshot, variables, and
whether session-template analysis is bypassed; return internal analysis data.
Selected public identities will be added by the runner later.
3. Seed declarations, walk executable root actions, recognize literal
`input "name"` calls, deduplicate names, and aggregate required accesses.
Analyze the session first when applicable and messages in their existing order.
4. Add aggregation/finalization helpers for classification, independent metadata,
ordering, safe issue construction, and `Complete`. Do not produce prompt text.
5. Until later stages implement control flow, return conservative incomplete
results for constructs that can hide dependencies. Temporary partial coverage
is internal implementation status, not a new public promise.
6. Check context at ordinary traversal boundaries; return the context error,
not a successful partial result after cancellation. Do not introduce workers,
hard analysis limits, or stronger interruption promises.
7. Describe implemented analysis ownership in the component/source documents.
**Verify:** Straight-line declared/undeclared references, duplicates, declared
required unused inputs, optional unused declarations, literal body independence,
empty input-free templates, and session-only references. Run
`go test ./internal/prompt ./internal/domain`; commit.
## Stage 3 — Resolve Caller Values, Map Lookups, And Local Aliases
**Outcome:** Caller variable requirements are distinct from input requirements;
simple names and pipeline values can be tracked without rendering.
**Work:**
1. Implement private value/environment records for known strings/Booleans/nil,
root-map identity, local symbols, and unknown values with causes.
2. Handle direct root field accesses and `$.name`, absent versus empty string,
root-map `index` with known string keys, local declarations/assignments, and
parenthesized/pipeline argument binding.
3. Caller requirements arise from accesses to the root variable map, not local
symbol names. Direct field access is required; optional `index` access is
promoted if another active use requires that same caller key.
4. Keep missing values unknown without aborting discovery. Do not mark incomplete
solely because a text-substitution variable is absent.
5. Preserve exact keys and values internally; return only requirement metadata
and key-presence information. Add no coercion, trimming, or field-name limits.
**Verify:** Direct supplied/missing/empty values, optional lookups, duplicate
access promotion, root versus local names, and pipeline argument position.
Use small comparisons with real Go-template execution for presence behavior;
do not duplicate the standard library's entire test matrix. Run
`go test ./internal/prompt`; commit.
## Stage 4 — Add Core Comparisons And Short-Circuit Semantics
**Outcome:** Common context expressions select values and dependencies consistently
with Go templates.
**Work:**
1. Implement `not`, string comparison families, and the operand-returning
`and`/`or` behavior specified in the core table. Use `template.IsTrue`.
2. Evaluate ordinary command arguments in order; `eq`'s multiple comparison
operands are not an `or` shortcut. Short-circuit only the appropriate
`and`/`or` operands.
3. Once a preceding operand leaves access uncertain, treat later potentially
evaluated operands conditionally rather than definitely accessed or skipped.
Preserve unknown causes for later dependency decisions.
4. Keep unsupported/incompatible evaluation as an internal unknown value with
a safe category. Do not leak values through errors or convert it into a new
construction/request rejection.
5. Inspect safe eager arguments of out-of-core built-ins for dependencies.
Their output may remain unknown; never execute arbitrary functions or whole
templates merely to determine a dependency.
**Verify:** Empty/nonempty strings, the truthiness of the string `"false"`,
comparisons, multi-operand `eq`, and `and`/`or` skips containing helper calls
or missing variables. Compare representative supported expressions with the
existing Go renderer. Run `go test ./internal/prompt`; commit.
## Stage 5 — Analyze Known Branches And Lexical Scope
**Outcome:** Supplied context resolves ordinary `if`/`with` dependencies;
known inactive uses are omitted.
**Work:**
1. Add `if`/`else` and `with` traversal for known predicate values.
Analyze only the selected path.
2. Preserve root `$`, `with` dot changes, pipeline-declared symbols, block
shadowing, and assignments to outer symbols. Follow Go's lexical lifetimes.
3. Never reinterpret `.field` against a known string dot as a root-map lookup.
Unsupported field operations have unknown values, not invented variables.
4. Retain declarations regardless of branch activity; omit undeclared helper
and variable accesses solely on a known inactive path.
5. Keep uncertain predicates using the temporary conservative handling until
Stage 6; do not guess their truth from placeholders.
**Verify:** Both known branches, nested `if`/`with`, root access from changed dot,
declarations versus assignments/shadowing, and inactive helpers/missing variables.
Include declared-required and declared-optional inputs in these cases.
Run `go test ./internal/prompt`; commit.
## Stage 6 — Join Unresolved Paths And Finalize Completeness
**Outcome:** Missing values and content-dependent branching return useful partial
results without inventing definitive classifications.
**Work:**
1. Analyze unknown branches once each in forked local environments. Join their
requirement summaries and any assignments visible after the block. Preserve
identical known values; retain direct possible string names where available.
2. Required accesses shared definitely across both paths can remain required.
Otherwise possible accesses are conditional. An unconditional use elsewhere
or a declared required input still dominates.
3. Emit uncertainty only when it affects discovered requirements. An unresolved
text-only branch can still have a complete requirement set; no output rendering
is needed to establish that.
4. Support input-body-caused unknown conditions without reading the body:
the predicate's known helper name is required; dependent branches are partial.
5. Handle out-of-core controls/calls conservatively. Inspect identifiable
literal helper and explicit root-variable accesses where scope is known.
Do not follow recursive named calls, unroll ranges, or mark unrelated locals
as caller variables. Opaque hidden requirements must keep the result incomplete.
6. Ensure supported and unsupported analysis does not mutate compiled templates
or change definition acceptance. No new parser/compiler validation rule.
**Verify:** Unknown branch unions and shared accesses, missing text variables
with complete discovery, branch-sensitive missing variables, content predicates,
unknown `with` dot, assignment joins, and valid range/named-template examples
returning incomplete rather than errors. Run `go test ./internal/prompt`; commit.
## Stage 7 — Finish Dynamic Names And Conservative Inventory Aggregation
**Outcome:** Direct variable/alias names resolve exactly; unresolved names
preserve known candidates and correctly affect declaration classifications.
**Work:**
1. Resolve `input .input_name`, root `index` results, aliases, parenthesized
arguments, and piped names when the supported value is one known string.
Supplied name values are used as identifiers, never normalized anew.
2. For joined finite possible string names, report their possible input entries
conditionally. For unrestricted unknown names, retain all already known
entries and report undiscovered-name uncertainty.
3. Emit dynamic-name issues together with useful missing-variable, input-content,
unsupported, or expression-unresolved categories from the underlying value.
Do not echo values beyond a resolved/known possible binding identifier.
4. Make potentially targeted declared optional inputs conditional: candidate-only
uncertainty affects matching declarations; unrestricted/opaque input effects
can affect all optional declarations. Leave known required inputs required.
5. Finalize deduplication, lexical ordering, metadata propagation, variable
`Supplied` flags, and completeness. No placeholder `"*"` input name,
invented variable default, payload read, or binding-validation API.
**Verify:** Exact dynamic names, empty supplied values versus missing values,
aliases selected by known branches, finite names from unknown assignments,
unrestricted names, repeated uses across messages/session, and optional
declaration uncertainty. Verify results contain no unrelated variable values.
Run `go test ./internal/prompt`; commit.
## Stage 8 — Wire Selection And The Public Engine Facade
**Outcome:** A configured consumer can call the new operation without artifacts,
credentials, schema preparation, or execution collaborators.
**Work:**
1. Add `internal/usecase/requirements_inspection.go` and the internal request.
Check nonblank prompt ID, normalize the direct session ID using the existing
domain helper, and honor context cancellation before selection work.
2. Use `resolvePromptDefinition` for exact version/default ambiguity behavior.
Factor the existing request-profile/default-profile choice into a small
shared private helper at its existing preparation location, retaining its
error identities and preparation error ordering.
3. Use `resolveProfileSelection` only to select identity. Do not call
`resolvePreparation`, target-completeness checks, API-key validation,
credential environment lookups, artifact/schema readers, renderer,
validator, admission, generation, or observation/run-ID machinery.
4. Obtain the captured requirement snapshot through the narrow lookup capability
on the selected repository. A configured production engine always provides
it. Missing internal capability/snapshot is an operational `ErrPromptLoad`,
not successful incomplete discovery or a raw-template fallback.
5. Analyze the messages and applicable session template; direct nonblank session
bypass removes only that template's uses. Build the internal result with the
selected identities and forward through `internal/engine`.
6. Add the public values/method in root `requirements.go`, conversion helpers,
GoDoc, and normal `mapPublicError` translation. Copy mutable values as above.
Nil engine matches `ErrInvalidConfig`; operational errors return no partial
result. Successful incomplete discovery returns a result and nil error.
7. Preserve existing public error categories for absent prompt/profile,
ambiguous versions, absent selected/default profile, invalid session ID, and
cancellation. Add no new sentinel merely for uncertainty.
8. Update internal component/runner documentation for the implemented method.
**Verify:** Focused runner tests with failing/counting execution collaborators
prove selection-only behavior. Check explicit/default/partial profiles,
exact selectors and ambiguity, session bypass, cancelled contexts, nil engine,
and incomplete-success behavior. Run
`go test ./internal/usecase ./internal/engine ./...` once for facade wiring;
commit.
## Stage 9 — Protect Public Semantics, Isolation, And Execution Parity
**Outcome:** Consumer-facing tests cover the acceptance outcomes without
duplicating the analyzer's detailed case matrix.
**Work:**
1. Add external-package `requirements_inspection_contract_test.go` using real
configured engines and minimal synthetic definitions. Use the existing
mapping/profile helpers, not a downstream checkout.
2. Prove exact `transcript` discovery, undeclared literal inputs, required and
optional declarations in inactive branches, context-selected names, and
session-only requirements removed by a direct session ID.
3. Cover complete-but-unsatisfied variable requirements, conditional/unknown
dependencies, and empty complete versus empty incomplete input sets.
4. Preserve classifiable errors for selection/cancellation. Test inspection
against a valid partial profile and an explicit direct-key-required profile
without an API key; missing runtime schemas and future artifact files must
not prevent inspection. Inject fail-if-called artifact/model/validator
collaborators where supported to prove the relevant absence of execution.
5. Use a small parity table: known-context inspector requirements must agree
with `Prepare`/the renderer's input and variable semantics when actual
synthetic artifacts are later supplied. Do not use execution failure order
as the definition of all discovered requirements.
6. Test source capture using a file-backed message changed/deleted after engine
construction. New inspection uses the captured content, like existing runs.
7. Mutate returned metadata/slices and repeat inspection; run representative
simultaneous inspections alongside preparation to verify no shared-state
mutation. Test this ownership risk, not a new scheduling/order guarantee.
8. Verify safe diagnostics/result formatting with marker values: unrelated
variable values, direct session value, template text, and credential values
are absent; input identifiers and declared descriptions are allowed.
9. Keep analyzer tests as the owner of detailed expression/branch semantics;
root tests own public values, errors, ownership, and assembled behavior.
**Verify:** Run focused new contract tests and affected package tests, with
`-race` for the isolation tests. Reuse Stage 8 results for unchanged cases;
commit. Avoid full-suite repetition solely to produce this commit.
## Stage 10 — Document The Boundary And Verify The Assembled Feature
**Outcome:** Canonical documentation accurately describes the new capability,
and the complete feature is ready for review, not automatically published.
**Work:**
1. Finish GoDoc for every new public field, kind, issue category, method,
ownership/error behavior, and supported discovery boundary. State that
inspection is not generation readiness or future-byte validation.
2. Add task-oriented consumer guidance comparing the three inspection methods
and preparation. Demonstrate required `transcript`, missing variables, and
explicit incomplete discovery without a Promptkit JSON format.
3. Update relevant format cross-references, internal source/runner/component
documents, and development reading guidance. Do not duplicate the exact
public contract outside GoDoc or describe unsupported constructs as invalid.
4. Extend the maintained preparation example with a small inspection use before
actual artifact preparation, preserving all existing example output
assertions. Verify the example's semantic inspection result locally without
adding a second recurring release gate or replacing the other examples.
5. Check every roadmap acceptance outcome against implementation/tests. Confirm
the old inspection API/hash shapes and execution behavior are retained and
no raw-source/history validation or new caller restriction was introduced.
6. On final changed code, run one assembled offline verification using the
selected local Go and prepared module caches:
`go test -race -vet=off -mod=readonly -count=1 ./...`,
`go vet -mod=readonly ./...`, and
`python3 scripts/check-examples.py`. Set `GOTOOLCHAIN=local`, `GOWORK=off`,
`GOPROXY=off`, `GONOPROXY=none`, and `GOSUMDB=off`.
Check changed Go formatting, local documentation links, and `git diff --check`.
There is no need to rerun release-tool publication fixtures for unchanged tools.
7. Record verification and implemented status in the temporary roadmap/plan
for user review. Do not tag, push, select a release version, write a prospective
release note, or retire the review artifacts in this implementation stage.
Release preparation owns those later decisions.
8. Review the final change, commit the unit, and report remaining issues honestly.
Do not mark unsupported constructs complete merely to make tests pass.
## Completion Criteria
- The root operation and dedicated public values implement the selected
artifact-free, context-sensitive inspection contract.
- Definitions/templates and required metadata presence come from the final
captured configuration; current inspection/execution and hashes remain intact.
- Practical-core complete results agree with execution semantics; uncertainty
remains a structured successful partial result, not guessed absence or error.
- Missing values, conditional requirements, metadata absence, and session bypass
are distinguishable without leaking unrelated content.
- Public classification and ownership tests pass; no provider/resource preflight,
arbitrary limit, application wire schema, or new template-validity rule was added.
- Canonical documentation and maintained examples reflect the implemented
discovery boundary. Successful checks for the final snapshot are reported.
## Open Questions
### Confirm The Practical-Core Scope
The roadmap still records this as open. This plan uses the recommended core,
made precise in the table above, and treats other dependency-relevant constructs
as incomplete without affecting their execution validity.
**Recommendation:** Use that practical core for this feature. It addresses the
consumer scenarios and gives maintainable, testable completeness while avoiding
a full interpreter. Extend coverage later when concrete prompts justify it.
**Alternative:** Include ranges, invoked named templates, numeric comparison,
and more built-in value pipelines in this implementation. That improves complete
discovery for more prompts, but needs additional independent stages and more
semantic parity coverage. It still cannot resolve artifact-content-dependent
decisions before artifacts exist.
### Confirm The Inactive-Reference Inventory
This plan uses the roadmap recommendation: declarations are always reported,
while undeclared references solely on known inactive paths are omitted.
**Recommendation:** Keep that effective-context inventory. It avoids confusing
potential future prompt uses with bindings the current context needs.
**Alternative:** Include statically identifiable inactive undeclared references
as optional entries with an inactive-use explanation. That is useful for broader
operator exploration, but expands result/issue semantics and requires tests and
documentation distinguishing inventory from applicable dependencies.
These questions concern the two previously open scope choices, not a new
publication or human sign-off gate. The stages above consistently implement the
recommended baseline; revise that baseline if a different option is selected.

View File

@@ -1,9 +1,10 @@
# Effective Prompt Requirement Inspection
Status: Proposed feature scope; implementation has not started. The
recommendations under Open Decisions need agreement before implementation
planning. This document owns the target end state and migration scope, not a
staged implementation sequence.
Status: Implementation planned; the feature is not implemented. The
[implementation plan](implementation.md) owns the ordered migration steps and
uses the recommended scope below. Open Decisions still records the alternative
scope choices for confirmation. This document owns the target end state and
migration scope.
## Purpose
@@ -45,7 +46,7 @@ context-sensitive requirement discovery.
## Target Public Operation
Add a separate read-only engine operation, provisionally
Add a separate read-only engine operation, planned as
`Engine.InspectRequirements`, with a dedicated request and result. Preserve
`InspectPrompt`, `InspectProfile`, preparation, and execution contracts.
@@ -67,7 +68,7 @@ about a later engine or later execution with changed variables.
## Result And Requirement Meanings
Expose public Go values with documented classifications and predictable ordering.
Exact symbol and field spelling belongs in the subsequent implementation plan
Exact symbol and field spelling belongs in the implementation plan
and GoDoc. No Promptkit JSON wire schema is part of this feature.
The result contains:
@@ -198,7 +199,7 @@ When implementation lands, update GoDoc, the consumer guide, relevant format
cross-references, and the internal component/source documents. Describe the
analysis boundary and examples of complete, unsatisfied, and incomplete results
in their canonical owners. Release notes explain the new capability; they do
not own its contract. A separate staged plan will own implementation sequencing.
not own its contract. The implementation plan owns implementation sequencing.
## Acceptance Outcomes
@@ -230,8 +231,8 @@ direct caller-variable access, ordinary `if`/`with` control flow, and simple
variable-derived names and comparisons where their values are determinable.
Account for template variable scope and short-circuit behavior for supported
expressions. Additional constructs can be supported where straightforward;
otherwise report incompleteness when they affect requirement discovery. Specify
the exact supported expression families before writing the implementation plan.
otherwise report incompleteness when they affect requirement discovery. The
implementation plan specifies the exact expression families for this baseline.
This covers the representative consumer needs while keeping completeness
honest and avoiding a second general-purpose interpreter.

View File

@@ -1,7 +1,8 @@
# ReleaseKit Adoption Roadmap
Status: Tool dependency selected; remaining adoption work is pending.
The [implementation plan](implementation.md) owns the ordered migration steps.
The completed [implementation plan](https://gitea.maximumdirect.net/eric/promptkit/src/commit/d5f34642d74a220d3ae61eaeb9f0fb4b0b71a173/docs/roadmap/implementation.md)
is retained in Git history; the current implementation plan covers another feature.
## Purpose

View File

@@ -0,0 +1,176 @@
# Feature Request: Inspect Effective Prompt Requirements
Status: proposed consumer request from Scriptorium, recorded 2026-10-08.
This document specifies requested public API behavior. API names and types are
open for agreement; implementation structure is left to Promptkit.
## Consumer Need
Scriptorium exposes Promptkit through CLI and HTTP interfaces for executing
predefined prompts. A subprocess consumer, Narratio, uses Scriptorium to produce
D&D session analysis from transcripts and other pipeline products.
Narratio needs to check its input bindings before starting expensive upstream
work. At that point, the eventual input files often do not exist. A pipeline
source ID and a prompt input name are separate identities: a transcript product
may need to be bound under the exact prompt input name `transcript`.
Scriptorium needs Promptkit to describe the selected execution context's input
and variable requirements through a supported public API. Scriptorium can then
present those requirements to operators and executable consumers without
interpreting prompt definitions or duplicating framework semantics.
## Public API Gap
The [consumer guide](../consumers/pkg-promptkit.md#inspect-a-prompt-before-preparation)
describes `InspectPrompt` as declared-input inspection without profile
resolution. That is useful, but declared inputs alone do not describe all
requirements introduced by templates. `InspectProfile` addresses profile
inspection separately, and `Prepare` loads inputs and renders messages.
The requested operation serves a different purpose: discover effective caller
requirements before input artifacts are available. Existing inspection and
execution operations should retain their established contracts.
## Requested Operation And Selection
Provide a read-only public operation on a configured engine. Scriptorium needs
to supply:
- A prompt ID and optional version selector.
- An optional execution profile selector.
- Supplied template variables.
- An optional direct session ID, because it can bypass a session-ID template.
Selection and interpretation should follow the same public semantics as an
equivalent execution request, including omitted selectors, exact identities,
variable values, and session-ID override behavior. The result should identify
the selected prompt ID/version and effective profile ID, including selection
through the prompt's default profile.
Inspection uses the engine's configured sources. Scriptorium continues to own
application configuration discovery, CLI flags, and source selection. The API
should require neither input references or contents nor an output path.
## Required Result Information
Expose public values with documented meanings that Scriptorium can project into
its own versioned JSON response and readable text output:
- Selected prompt and profile identities.
- Discoverable caller-supplied input names, including declared inputs and
references in message and applicable session-ID templates.
- Whether each input is required, optional, or conditional for the supplied
context, with an explanation where available. Preserve exact execution names.
- Declared input descriptions and content-type metadata, distinguishing absent
metadata from a known declaration.
- Caller-supplied variable requirements separately from artifact inputs,
including whether supplied values satisfy the known requirements.
- Whether discovery is complete for the supplied context, together with
machine-readable reasons and safe explanations for unresolved requirements.
Provide predictable ordering for repeatable presentation and enough public
classification information that callers do not need to parse diagnostic prose.
Exact type names, fields, and ordering conventions remain API design choices.
Scriptorium owns its subprocess JSON schema; a Promptkit-specific JSON wire
format is not required by this request.
The [format reference](../formats.md#inputs) currently provides input
content-type metadata, rather than an input-schema declaration. Report the
meaning of existing metadata accurately. This request does not introduce input
format enforcement, input schemas, or variable defaults. Where a supported
format provides defaults or constraints, inspection should reflect their actual
execution semantics rather than infer them from names.
## Context-Sensitive And Incomplete Discovery
A declared required input remains required independently of whether a template
branch references it. An input whose only requirement comes from an inactive
branch should not be classified as required for that context.
Use supplied variables when they determine active branches or dynamically
selected names. Variable interpretation must agree with execution, including
template truthiness and presence semantics. Include requirements from an active
session-ID template; account for its bypass by a direct session ID.
Where unavailable input contents, missing variables, dynamic names, or other
analysis limitations prevent a complete determination, return the known
requirements with explicit uncertainty. Explain conditions through public
information where possible, without revealing template text or supplied values.
A valid prompt remains valid when its requirements cannot be fully discovered.
An undeclared template input reference is not, by itself, a new definition error.
An empty complete result establishes that no caller-supplied inputs are needed
for the inspected context. An empty incomplete result does not. Completeness
describes discovery, not satisfaction: a known required variable may still be
missing, even when its requirement has been fully identified. If its absence
also leaves input dependencies unknown, report that uncertainty separately.
Incomplete discovery should be a successful result with explicit status, rather
than a selection error. Document the discovery boundary so Scriptorium can
distinguish a fully determined requirement set from a useful partial result.
## Effects, Errors, And Safety
Inspection should work without future input artifacts, generation credentials,
model access, capacity reservation, or creation of execution artifacts. Reading
configuration and prompt resources needed for inspection is expected.
Profile selection establishes identity; this operation is not a generation
readiness or credential check.
Invalid selectors, unknown or ambiguous selections, unreadable necessary
resources, and invalid definitions that prevent inspection should produce
publicly classifiable errors consistent with existing selection semantics.
Scriptorium needs stable categories or error identities and safe descriptions
to produce structured CLI failures. It should not need to match error-message
text or access implementation packages.
Results and consumer-facing diagnostics should exclude credential values,
input payloads, supplied variable values, and rendered or raw prompt contents.
Identifiers and declared descriptions remain useful operator-facing metadata.
For a complete result, the reported requirements should agree with execution
for the same effective configuration and supplied context. An incomplete
result should accurately describe what is known and what remains uncertain.
Neither result guarantees generation success or validates future input bytes.
Later configuration or prompt-resource changes may change a later execution's
requirements.
## Consumer Acceptance Scenarios
1. A required `transcript` input is reported with its exact name, allowing
Scriptorium's caller to detect a binding named `session_transcript` instead.
2. A literal template reference to an undeclared input is discoverable without
requiring that input's contents or rejecting the reference as undeclared.
3. A declared optional glossary remains optional when no active template use
makes it required. A declared required input remains required in an inactive
template branch.
4. Supplied variables determine conditional requirements and dynamic names
where discoverable. Content-dependent or otherwise unresolved cases return
known entries with explicit incompleteness.
5. Changing the prompt version or profile reports the corresponding selected
identities. Omitted selections follow execution's defaults and ambiguity
rules.
6. Session-template dependencies are reported when applicable; a direct session
ID removes requirements introduced solely by the bypassed template.
7. Missing caller variables are reported separately from missing artifact
bindings, without returning supplied values or prompt contents.
8. Inspection succeeds before artifacts exist and without credentials or
provider access, assuming necessary configuration and resources are valid
and readable.
9. Unknown prompts, ambiguous versions, and invalid profile selections yield
classifiable failures; analysis uncertainty yields an incomplete result.
10. A genuinely input-free context is distinguishable from an incomplete
discovery that happened to find no input names.
## Scope And Ownership
Promptkit supplies the public requirement-discovery semantics. Scriptorium owns
CLI exposure, text and JSON presentation, stream handling, and exit statuses.
Narratio owns its source catalog, bindings, pipeline ordering, dependency graph,
and session availability checks.
No Narratio-specific identifiers or pipeline concepts are needed in Promptkit's
API. A graph renderer, HTTP endpoint, batch interface, changes to generation
behavior, and execution-resource preflight are outside this request. This is a
consumer capability request, not an implementation plan.