Files
promptkit/docs/roadmap/implementation.md

590 lines
34 KiB
Markdown

# Effective Prompt Requirement Inspection Implementation Plan
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
- Baseline: `7827ca043b5de84a18199ac8f4b3056691aacbb5`. There is no effective
requirement-inspection API yet. `InspectPrompt` reports declarations;
`Prepare` needs artifacts. The configured engine captures compiled templates.
- The agreed scope is the practical analysis core, with statically identifiable
inactive undeclared input references included as optional inventory entries
and explained as inactive. Distinguish this inventory from applicable
dependencies; it does not require evaluating skipped expressions or adopting
broader Go-template interpretation.
- Start with [development](../development.md), then read the
[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.
## Concrete API And Result Decisions
Add root `requirements.go` in Stage 8. The method is:
```go
func (e *Engine) InspectRequirements(
ctx context.Context, req RequirementInspectionRequest,
) (*RequirementInspection, error)
```
Define ordinary root-owned values, mirrored by execution-owned internal values
in `internal/domain/requirements.go`; do not export aliases to internal types:
```go
type RequirementInspectionRequest struct {
PromptID string
PromptVersion string
ProfileID string
Vars map[string]string
SessionID string
}
type RequirementKind string // constants: required, optional, conditional
type InputRequirement struct {
Name string
Kind RequirementKind
Declared bool
ContentType *string
Description *string
Explanation string
}
type VariableRequirement struct {
Name string
Kind RequirementKind
Supplied bool
}
type RequirementIssueCode string
type RequirementIssue struct {
Code RequirementIssueCode
InputName string
VariableName string
Description string
}
type RequirementInspection struct {
PromptID string
PromptVersion string
ProfileID string
Inputs []InputRequirement
Variables []VariableRequirement
Complete bool
Issues []RequirementIssue
}
```
Use `RequirementRequired`, `RequirementOptional`, and
`RequirementConditional` as the kind constant names. Use these issue constants:
| 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. |
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.
### Classification, Metadata, And Ownership
- Always report declarations. A declared required input stays required.
Active template accesses can promote an optional declaration to required.
Include statically identifiable undeclared references on known inactive paths
as optional entries with an inactive-use explanation.
- 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.
- `Explanation` is a safe human-readable summary of inactive-only use, separate
from declared `Description`. Its wording is not a machine-readable contract.
Do not add an uncertainty issue for known inactivity. Required or conditional
uses elsewhere override inactive-only classification and explanation.
Caller variables used solely on known inactive paths are not requirements.
- 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.
### Completeness And Uncertainty
`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.
An empty complete input set, or a complete inventory containing only optional
entries, establishes that no artifact bindings are needed. Nonempty inventory
alone does not establish that artifacts are needed; incomplete discovery does
not establish their absence.
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.
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 applicable requirement summaries, not inactive inventory or 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.
Unresolved dynamic names/opaque input effects must not leave otherwise optional
input entries falsely definitive. Mark affected optional entries conditional,
including previously inactive-only undeclared entries; an unrestricted unknown
input name can affect all such entries. Clear inactive-only explanations where
possible active uses undermine them.
An unknown-name issue also describes potential undiscovered undeclared names.
Known required declarations remain required.
### Initial Analysis Core
Analyze each selected template's executable root. Definitions that are never
invoked do not themselves create requirements.
| 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. |
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.
They can contribute optional inactive inventory as described below, without
collecting skipped caller-variable requirements or uncertainty.
For a known inactive path, use a non-evaluating syntax walk to collect literal
`input` names, including equivalent parenthesized/piped literal forms. Walk
skipped branch bodies and short-circuit operands without reading caller values,
mutating local environments, or invoking templates/functions. Unresolved
dynamic names and unsupported expressions in these skipped paths do not make
discovery incomplete. Never-invoked definitions and a directly bypassed session
template remain outside this inventory. Track inactive-only occurrences
separately from definite/possible uses so aggregation can classify a shared
name correctly.
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.
## Stage 1 — Retain Effective Declaration Metadata And Inspection Snapshots
**Outcome:** Inspection can obtain captured templates and metadata without
changing execution definitions, hashes, or existing public inspection values.
**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. 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.
**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.
## Stage 2 — Add Internal Result Values And Literal Dependency Discovery
**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 explanations/issue construction, and `Complete`. Keep
inactive-only occurrence information separate from applicable accesses for
Stage 5. 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.
Stage 5 adds optional inventory for definitely skipped helper expressions;
these are not applicable input or variable dependencies.
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, Scope, And Inactive Inventory
**Outcome:** Supplied context resolves ordinary `if`/`with` dependencies;
statically identifiable inactive input references remain optional inventory.
**Work:**
1. Add `if`/`else` and `with` traversal for known predicate values.
Evaluate only the selected path for applicable dependencies.
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. Add the non-evaluating inactive syntax walk specified above. Include literal
helper names from skipped branches and short-circuit operands as optional
entries with a safe inactive-use explanation. Preserve declarations and
aggregate other uses of the same name; required/conditional uses dominate.
5. Do not evaluate skipped predicates, resolve skipped dynamic names, mutate
branch environments, or collect skipped caller-variable requirements/issues.
Do not inspect uncalled definitions or a bypassed session template.
6. 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.
Test inactive undeclared literal and equivalent parenthesized/piped names,
inactive explanations, active reuse overriding inactivity, and skipped dynamic
or unsupported expressions causing no uncertainty. Verify that a complete
all-optional inventory requires no artifacts.
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. Inactive inventory entries alone do not change
applicable dependency summaries or introduce incompleteness.
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 optional inventory 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 optional input entries conditional: candidate-only
uncertainty affects matching entries; unrestricted/opaque input effects
can affect all optional entries, including inactive undeclared inventory.
Remove inactive-only explanations when possible active uses undermine them.
Leave known required inputs required.
5. Finalize deduplication, lexical ordering, metadata propagation, variable
`Supplied` flags, inactive-use explanations, 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/inactive inventory uncertainty. Verify results contain no unrelated
variable values or skipped-variable requirements.
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.
Document inactive inventory and `Explanation` separately from declaration
metadata and structured uncertainty; do not promise diagnostic wording.
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.
Include optional inactive undeclared entries with explanations, active reuse
overriding inactivity, and bypassed session names absent from the inventory.
3. Cover complete-but-unsatisfied variable requirements, conditional/unknown
dependencies, and empty complete versus empty incomplete input sets.
Cover complete all-optional inventories and no caller requirements from
solely inactive variable accesses.
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 applicable 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.
Do not compare optional inventory entries to actual renderer helper accesses.
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.
Include inactive explanations in the disclosure checks.
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.
Explain optional inactive inventory and reading requirement classifications
rather than treating every input entry as a binding to prepare.
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.
- Inactive undeclared references appear as optional entries with explanations;
they do not introduce skipped-variable requirements or uncertainty. Complete
all-optional inventories remain distinguishable from incomplete discovery.
- 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.