diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index d6abb1b..81f30f8 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -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. diff --git a/docs/roadmap/inspection.md b/docs/roadmap/inspection.md index dca144a..b111080 100644 --- a/docs/roadmap/inspection.md +++ b/docs/roadmap/inspection.md @@ -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. diff --git a/docs/roadmap/releasekit.md b/docs/roadmap/releasekit.md index 8729824..8acaecb 100644 --- a/docs/roadmap/releasekit.md +++ b/docs/roadmap/releasekit.md @@ -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 diff --git a/docs/roadmap/scriptorium-feature-request.md b/docs/roadmap/scriptorium-feature-request.md new file mode 100644 index 0000000..d06c790 --- /dev/null +++ b/docs/roadmap/scriptorium-feature-request.md @@ -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.