590 lines
34 KiB
Markdown
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.
|