Simplify requirement inspection plan
This commit is contained in:
@@ -1,55 +1,46 @@
|
||||
# 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.
|
||||
Implement the [feature roadmap](inspection.md) in order. Each numbered stage is
|
||||
scoped for one Luna coding-agent prompt. This plan replaces the earlier
|
||||
interpreter-style analysis scope with simple enumeration and conservative
|
||||
classification. The completed ReleaseKit 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
|
||||
- Planning baseline: `e459c7d`. The inspection API is not implemented.
|
||||
`InspectPrompt` reports declarations, `Prepare` needs artifacts, and the
|
||||
configured engine already captures compiled templates.
|
||||
- Start with [development](../development.md), then 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.
|
||||
policies. Reuse unchanged policies already read.
|
||||
- Follow [ADR 0001](../adr/0001-configuration-boundary.md): interpret only final
|
||||
effective configuration at the ConfigKit handoff. Operator provenance is
|
||||
separate; inspection does not examine raw sources or intermediate values.
|
||||
- Preserve unrelated work and commit completed, verified units under the agent
|
||||
policy. Keep implemented internal documentation accurate as stages land.
|
||||
- Preserve existing construction, inspection, preparation, rendering, and
|
||||
execution contracts. An inspection limitation is not a definition error.
|
||||
- Use captured parsed syntax, direct traversal, and maps keyed by exact name.
|
||||
No general evaluator, assignment-value propagation, branch-environment joins,
|
||||
possible-name sets, branch combinations, analysis budget, or global cache is
|
||||
needed. Do not add caller limits, defaults, input schemas, or authoring bans.
|
||||
- The root package owns public declarations/conversion. `internal/prompt`
|
||||
owns discovery, `internal/usecase` coordinates selection, and
|
||||
`internal/configuration` supplies captured syntax/metadata. Runtime/domain
|
||||
values remain independent of ConfigKit.
|
||||
- No new dependency, upstream ConfigKit change, provider access, CLI/HTTP
|
||||
feature, application wire format, or publication is part of these stages.
|
||||
|
||||
## Concrete API And Result Decisions
|
||||
## Concrete Public Values
|
||||
|
||||
Add root `requirements.go` in Stage 8. The method is:
|
||||
Add root `requirements.go` in Stage 5:
|
||||
|
||||
```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
|
||||
@@ -58,7 +49,7 @@ type RequirementInspectionRequest struct {
|
||||
SessionID string
|
||||
}
|
||||
|
||||
type RequirementKind string // constants: required, optional, conditional
|
||||
type RequirementKind string // values: required, conditional, optional
|
||||
|
||||
type InputRequirement struct {
|
||||
Name string
|
||||
@@ -70,9 +61,10 @@ type InputRequirement struct {
|
||||
}
|
||||
|
||||
type VariableRequirement struct {
|
||||
Name string
|
||||
Kind RequirementKind
|
||||
Supplied bool
|
||||
Name string
|
||||
Kind RequirementKind
|
||||
Supplied bool
|
||||
Explanation string
|
||||
}
|
||||
|
||||
type RequirementIssueCode string
|
||||
@@ -95,495 +87,355 @@ type RequirementInspection struct {
|
||||
}
|
||||
```
|
||||
|
||||
Use `RequirementRequired`, `RequirementOptional`, and
|
||||
`RequirementConditional` as the kind constant names. Use these issue constants:
|
||||
Use root-owned values and internal counterparts in
|
||||
`internal/domain/requirements.go`; do not expose internal aliases.
|
||||
Kind constants are `RequirementRequired`, `RequirementConditional`, and
|
||||
`RequirementOptional`. Retain four useful issue categories:
|
||||
|
||||
| Constant | Value | Meaning when discovery is affected |
|
||||
| Constant | Value | Discovery limitation |
|
||||
| --- | --- | --- |
|
||||
| `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. |
|
||||
| `RequirementIssueMissingVariable` | `missing_variable` | An absent value prevents determining a dependency decision/name. |
|
||||
| `RequirementIssueInputContent` | `input_content` | Unavailable artifact content affects dependencies. |
|
||||
| `RequirementIssueDynamicInputName` | `dynamic_input_name` | A referenced input name cannot be determined. |
|
||||
| `RequirementIssueUnsupportedConstruct` | `unsupported_construct` | Analysis does not cover a dependency-relevant expression or scope. |
|
||||
|
||||
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.
|
||||
An empty associated name means that no particular entry was identified.
|
||||
Descriptions and explanations are safe human-readable summaries, not strings
|
||||
callers must parse. There is no expression tree, source offset, JSON tag/schema,
|
||||
or stable diagnostic wording contract.
|
||||
|
||||
### Classification, Metadata, And Ownership
|
||||
### Classification 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.
|
||||
- Seed declared inputs from final effective definitions. Required declarations
|
||||
stay required independently of syntax. Others start optional.
|
||||
- Collect occurrences with definite, possible, or inactive reachability.
|
||||
Definite helper/direct required-variable accesses are required; possible ones
|
||||
are conditional; recognizable inactive references are optional. A lookup
|
||||
that execution permits to be absent remains optional unless another access
|
||||
establishes a stronger requirement.
|
||||
- Aggregate exact names with required > conditional > optional. No proof that
|
||||
a name in both unresolved branches is required is necessary: conditional is
|
||||
acceptable until an independent definite access/declaration establishes it.
|
||||
- Include recognizable inactive inputs and caller variables in both inventories.
|
||||
Give inactive-only entries an `Explanation`, independent of declared input
|
||||
`Description`. Any applicable occurrence, including an optional lookup,
|
||||
removes the inactive-only explanation; required/conditional uses also
|
||||
override optional classification. Inactivity is not an uncertainty issue.
|
||||
- Input metadata pointers distinguish absence/null from an explicit string,
|
||||
including an empty string. `Declared` distinguishes metadata ownership from
|
||||
a helper-only reference. Do not infer new input formats.
|
||||
- `Supplied` means presence of the exact caller key, including empty strings.
|
||||
It is independent of classification and completeness; do not echo values.
|
||||
- Sort input and variable entries lexically by exact name. Deduplicate issues
|
||||
by code/input-name/variable-name and sort by that tuple. Do not promise a
|
||||
nil-versus-empty slice distinction.
|
||||
- Return independent slices and metadata pointers, copy request variables at
|
||||
the facade as for `RunRequest`, and keep captured syntax immutable. Retain
|
||||
callers' existing responsibility for concurrently mutating requests.
|
||||
|
||||
### Completeness And Uncertainty
|
||||
### Deliberately Small Recognition Scope
|
||||
|
||||
`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.
|
||||
Use the standard template parse tree and `template.IsTrue` for known values.
|
||||
Only determine a value when needed for a recognized name or simple condition.
|
||||
|
||||
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 |
|
||||
| Syntax | 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. |
|
||||
| Literal `input "name"` | Collect the exact name without reading its body. Parenthesized literal wrappers and a literal piped directly to `input` are equivalent. |
|
||||
| Direct root `.name` or `$.name` | Collect a required caller key when active; supplied strings are known, absence is unresolved rather than an inspection error. |
|
||||
| `index` of the root map with one literal string key | Collect an optional lookup; its value is supplied text or the string zero value if absent, following execution. |
|
||||
| `input .name`, `input $.name`, or `input (index . "name")` | Resolve a directly available string as an input identifier on applicable paths. |
|
||||
| One simple value piped directly to `input`, or parenthesized simple expressions | Recognize the same bounded forms without evaluating arbitrary pipelines. |
|
||||
| String/Boolean/nil literals and simple direct values | Use known values for conditions; no coercion of caller strings. |
|
||||
| `not` of a simple predicate; two-string `eq`/`ne` | Recognize negation and ordinary equality/inequality without adding the full comparison family. |
|
||||
| `if`/`else`, `with` | Classify branch occurrences using a recognized condition; unresolved branches are possible, not guesses. |
|
||||
| Locals, changed dot, and root binding | Retain scope identity sufficient to distinguish root-map accesses from local/string/unknown values; no local-value propagation is required. |
|
||||
| Other pipelines/functions, `and`/`or`, assignments, ranges, invoked named templates, or complex names | Collect safely identifiable references conservatively and record dependency-relevant limitations; do not interpret their execution. |
|
||||
|
||||
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.
|
||||
An unsupported expression does not automatically make every argument a definite
|
||||
access: short-circuiting or unknown scopes can make references merely possible.
|
||||
Keep complex forms outside complete analysis instead of emulating their rules.
|
||||
Do not interpret `$local` as a caller key or `.field` on a string/unknown dot as
|
||||
a root lookup. Explicit root accesses remain recognizable only while the root
|
||||
binding's identity is known. Unsupported changes to a binding make its identity
|
||||
unknown where affected; no assignment-value or cross-branch reconstruction is
|
||||
needed.
|
||||
|
||||
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.
|
||||
Walk known inactive subtrees for syntactically identifiable literal input names
|
||||
and caller keys. Do not evaluate skipped expressions, resolve skipped dynamic
|
||||
input names, or produce uncertainty solely from skipped constructs. Names
|
||||
hidden behind unsupported scopes need not be invented. Exclude bypassed session
|
||||
templates and never-invoked definitions entirely.
|
||||
|
||||
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.
|
||||
### Simple Algorithm And Completeness
|
||||
|
||||
## Stage 1 — Retain Effective Declaration Metadata And Inspection Snapshots
|
||||
1. Seed declaration entries and visit each selected template.
|
||||
2. Maintain only reachability and the scope identity needed to recognize caller
|
||||
keys; collect names and minimal classification evidence in indexed summaries.
|
||||
3. For simple conditions, visit both branches with definite/possible/inactive
|
||||
reachability as appropriate. A possible parent never becomes definite just
|
||||
because an inner predicate is known true; a known inactive parent stays
|
||||
inactive. No branch environment or assignment-value joins are needed.
|
||||
4. Aggregate/finalize names, metadata, presence, explanations, and limitations.
|
||||
|
||||
**Outcome:** Inspection can obtain captured templates and metadata without
|
||||
changing execution definitions, hashes, or existing public inspection values.
|
||||
Use shared traversal helpers for active/possible/inactive syntax rather than
|
||||
separate interpreters. Do not enumerate execution combinations. Prefer a direct
|
||||
pass through syntax and final aggregation; no special machinery is warranted
|
||||
by ordinary prompt sizes.
|
||||
|
||||
`Complete` means that the supported analysis established the requirement
|
||||
inventory/classifications. Conservative false is acceptable for difficult cases.
|
||||
Missing direct text-substitution values alone do not make discovery incomplete.
|
||||
Unresolved branches with dependency-bearing references return conditional
|
||||
entries and incomplete status; no proof of identical branches is required.
|
||||
Unknown pure text without a dependency effect need not change completeness.
|
||||
|
||||
An unsupported call that may hide dependencies or an unresolved active input
|
||||
name makes discovery incomplete. Preserve recognized names; do not create a
|
||||
wildcard entry. Maintain simple flags for possible unknown input/caller-key
|
||||
effects, promoting affected optional entries to conditional at finalization,
|
||||
rather than repeatedly rescanning the inventory. Known required entries remain
|
||||
required. Clear inactive-only explanations where those unknown effects undermine
|
||||
the conclusion.
|
||||
|
||||
A complete empty or all-optional input inventory needs no artifact bindings.
|
||||
An incomplete inventory does not prove that no others are needed. A complete
|
||||
result is not a rendering/readiness/provider guarantee.
|
||||
|
||||
## Stage 1 — Capture Effective Metadata And Template Snapshots
|
||||
|
||||
**Outcome:** The analyzer can obtain existing compiled templates and declaration
|
||||
metadata without artifact reads or changing old inspection/execution behavior.
|
||||
|
||||
**Read:** `internal/configuration/load.go`, `prompts.go`,
|
||||
`internal/prompt/template.go`, `internal/domain/domain.go`,
|
||||
`internal/promptdef/hash.go`, and the source document.
|
||||
`internal/promptdef/hash.go`, and the internal 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`.
|
||||
1. Retain content-type/description presence alongside configuration
|
||||
`promptEntry`, rather than changing the hashed prompt definition or old
|
||||
public inspection shape.
|
||||
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.
|
||||
existing Resolve callback before prompt normalization. Use final
|
||||
prompt-ID/version/input-index paths, following the existing presence-capture
|
||||
pattern. Materialize values from the normalized final declaration.
|
||||
3. Add `prompt.RequirementSnapshot` with captured templates and metadata, and
|
||||
narrow internal `GetRequirementSnapshot(id, version string)
|
||||
(RequirementSnapshot, bool)` access on the captured configuration adapter.
|
||||
Use selected exact keys, without reparsing or reopening resources.
|
||||
4. Preserve renderer/constructor paths and update internal source documentation.
|
||||
|
||||
**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;
|
||||
**Verify:** Focused final-value metadata tests for absent/null, empty, and
|
||||
nonempty values, plus equivalent-definition hashes and old inspection behavior.
|
||||
Use actual configuration capture rather than another source-loading matrix.
|
||||
Run `go test ./internal/configuration ./internal/promptdef ./internal/prompt`;
|
||||
commit.
|
||||
|
||||
## Stage 9 — Protect Public Semantics, Isolation, And Execution Parity
|
||||
## Stage 2 — Enumerate Literal Inputs And Caller Keys
|
||||
|
||||
**Outcome:** Consumer-facing tests cover the acceptance outcomes without
|
||||
duplicating the analyzer's detailed case matrix.
|
||||
**Outcome:** An internal syntax walker produces deduplicated inventories and
|
||||
does not confuse caller variables with template locals.
|
||||
|
||||
**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.
|
||||
1. Add internal result counterparts in `internal/domain/requirements.go` and
|
||||
an analyzer entry in `internal/prompt/requirements.go`, taking context,
|
||||
selected definition/snapshot, supplied variables, and session bypass.
|
||||
2. Seed declarations, visit executable message roots and the applicable session
|
||||
root, and collect literal input references and direct/literal-index caller
|
||||
keys. Exclude uncalled definitions and a bypassed session template.
|
||||
3. Implement aggregation, exact names, supplied-key presence, independent
|
||||
metadata, sorting, and safe issues/explanations. Add ordinary traversal
|
||||
cancellation checks without stronger interruption promises or workers.
|
||||
4. Track scope identity, not local values: root-map versus nonroot/unknown dot
|
||||
and local bindings. For unsupported scope changes, keep safely recognizable
|
||||
references and report incomplete analysis rather than inventing caller keys.
|
||||
5. Until Stage 3, classify branch references conservatively as possible and
|
||||
unsupported dependency-bearing expressions as limitations.
|
||||
6. Update the implemented internal component/source descriptions.
|
||||
|
||||
**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.
|
||||
**Verify:** Literal declared/undeclared input names, repeated references,
|
||||
required unused declarations, optional declarations/lookups, missing versus
|
||||
empty direct variables, root versus local references, and empty input-free
|
||||
templates. Test unsupported-scope uncertainty, not assignment interpretation.
|
||||
Run `go test ./internal/prompt ./internal/domain`; commit.
|
||||
|
||||
## Stage 10 — Document The Boundary And Verify The Assembled Feature
|
||||
## Stage 3 — Classify Simple Branches And Inactive References
|
||||
|
||||
**Outcome:** Canonical documentation accurately describes the new capability,
|
||||
and the complete feature is ready for review, not automatically published.
|
||||
**Outcome:** Ordinary supplied-context branches give useful classifications;
|
||||
inactive inputs and variables remain optional inventory.
|
||||
|
||||
**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:
|
||||
1. Add only the simple condition recognition in the scope table: direct values,
|
||||
literal-key lookups, literals, negation, and two-string equality/inequality.
|
||||
Use Go truthiness; a supplied `"false"` string is truthy.
|
||||
2. For `if`/`with`, collect the predicate's references under the parent's
|
||||
reachability. Visit selected and skipped bodies with the appropriate
|
||||
reachability and dot identity. In unresolved branches, mark accesses possible.
|
||||
3. Collect syntactically recognizable inactive input/caller names without
|
||||
evaluating skipped expressions. Add inactive-only explanations; required
|
||||
declarations or other definite/possible uses take precedence.
|
||||
4. Unknown/content-dependent conditions preserve known entries and limitations.
|
||||
An unresolved text-only branch need not be incomplete; dependency-bearing
|
||||
unresolved branches can remain incomplete without cross-branch proofs.
|
||||
5. Do not add assignment environments, alias-value propagation, branch joins,
|
||||
more comparison families, or short-circuit evaluation for complex conditions.
|
||||
|
||||
**Verify:** Known true/false branches, nested reachability, string truthiness,
|
||||
simple comparisons, `with` dot versus explicit root, missing decision values,
|
||||
and content-dependent conditions. Include inactive literal input and caller
|
||||
references, promotion by active reuse, and declared required inputs.
|
||||
Confirm skipped unsupported/dynamic expressions do not introduce uncertainty
|
||||
and an all-optional complete inventory needs no artifacts.
|
||||
Compare a few supported cases with the real renderer.
|
||||
Run `go test ./internal/prompt`; commit.
|
||||
|
||||
## Stage 4 — Resolve Direct Names And Finish Limitation Reporting
|
||||
|
||||
**Outcome:** Simple supplied names resolve exactly; complicated names and
|
||||
constructs return useful partial inventories without speculative analysis.
|
||||
|
||||
**Work:**
|
||||
|
||||
1. Recognize the direct variable/lookup-derived helper names, simple
|
||||
parentheses, and direct-to-input pipelines in the scope table.
|
||||
Use a known string as an identifier without trimming or coercion.
|
||||
2. Missing decision/name values, input-body dependence, unresolved helper
|
||||
names, and dependency-relevant unsupported syntax produce the four issue
|
||||
categories. Collect recognized references conservatively from unsupported
|
||||
subtrees without executing functions, loops, or named calls.
|
||||
3. Keep skipped computed input names unresolved without inventing an entry or
|
||||
marking incompleteness from inactivity alone. The syntactically visible
|
||||
caller key can still appear as an optional variable.
|
||||
4. Finalize unknown-name/scope effects on affected optional entries using the
|
||||
simple flags described above. Required declarations/definite accesses stay
|
||||
required; uncertainty overrides misleading inactive-only explanations.
|
||||
5. Finish independent result values and safe diagnostics. No possible-name
|
||||
sets, underlying expression/value traces, placeholder names, or payload reads.
|
||||
|
||||
**Verify:** Exact direct names, optional literal-key lookups, empty versus
|
||||
absent supplied names, and equivalent simple parenthesized/piped forms.
|
||||
Use a few complex assignment/pipeline/range/named-call examples to prove
|
||||
incomplete-success behavior, not broad interpretation coverage.
|
||||
Check unresolved-name effects on optional entries and absent unrelated values
|
||||
in results/explanations. Run `go test ./internal/prompt`; commit.
|
||||
|
||||
## Stage 5 — Wire Selection And The Public Facade
|
||||
|
||||
**Outcome:** Consumers can inspect a selected captured prompt before artifacts
|
||||
exist, without execution collaborators or readiness checks.
|
||||
|
||||
**Work:**
|
||||
|
||||
1. Add `internal/usecase/requirements_inspection.go` and an internal request.
|
||||
Check the nonblank prompt ID, use existing session normalization, honor
|
||||
context cancellation, and select via `resolvePromptDefinition`.
|
||||
2. Reuse request-profile/default-profile selection and
|
||||
`resolveProfileSelection` for identity only. Share a small private selector
|
||||
helper with preparation if needed, preserving its error identities/order.
|
||||
3. Obtain the captured snapshot through the narrow repository capability and
|
||||
invoke the analyzer. Missing required internal capability/snapshot is
|
||||
operational `ErrPromptLoad`, not a successful partial result or source fallback.
|
||||
4. Do not call preparation, target-completeness/credential checks, environment
|
||||
lookups, artifact/schema readers, renderer, validator, admission, generation,
|
||||
observations, or run-ID machinery.
|
||||
5. Forward through `internal/engine` and add root `requirements.go` with the
|
||||
planned values/method, conversion/copy helpers, GoDoc, and `mapPublicError`.
|
||||
Nil engine follows `ErrInvalidConfig`. Operational errors return no result;
|
||||
discovery limitations return an incomplete result and nil error.
|
||||
6. Preserve public selection/session/cancellation error categories. Do not add
|
||||
an error sentinel for incomplete discovery. Update internal runner/component
|
||||
documents for the implemented method.
|
||||
|
||||
**Verify:** Focused selection tests cover explicit/default/partial profiles,
|
||||
exact versions/ambiguity, direct-session bypass, cancellation, nil engine,
|
||||
operational errors, and incomplete success. Use failing/counting execution
|
||||
collaborators only to prove absence of the relevant effects.
|
||||
Run affected use-case/engine tests and `go test ./...` for assembled facade
|
||||
wiring; commit.
|
||||
|
||||
## Stage 6 — Protect Public Inventory And Ownership
|
||||
|
||||
**Outcome:** Public contract coverage protects the consumer need without
|
||||
duplicating the syntax walker's detailed cases.
|
||||
|
||||
**Work:**
|
||||
|
||||
1. Add external-package `requirements_inspection_contract_test.go` with real
|
||||
configured engines and minimal synthetic definitions.
|
||||
2. Cover exact required `transcript`, undeclared literals, declaration metadata,
|
||||
simple context-selected names, and inactive input/variable entries with safe
|
||||
explanations. Missing required variables and complete discovery are separate.
|
||||
3. Cover conditional/incomplete results and empty/all-optional complete
|
||||
inventories. A direct session ID excludes its template-only inventory
|
||||
entries; declarations/message references remain.
|
||||
4. Prove inspection before artifacts exist and without credentials/schema
|
||||
preparation/provider access. Use a valid partial profile and, where useful,
|
||||
an explicit direct-key-required profile without its key.
|
||||
5. Compare a small set of supported definite requirements with later preparation
|
||||
using synthetic artifacts. Optional inactive inventory is not an executed
|
||||
access; incomplete cases need not satisfy complete-analysis parity.
|
||||
6. Verify captured file-backed content survives later file change/removal.
|
||||
Mutate returned slices/metadata and repeat inspection; exercise simultaneous
|
||||
inspections alongside preparation to protect captured-state ownership.
|
||||
7. Check disclosure with marker values: unrelated variable values, direct
|
||||
session values, template text, and credentials stay absent. Binding names,
|
||||
caller keys, declared descriptions, and safe inactive explanations are allowed.
|
||||
8. Root tests own public values/errors/assembled behavior; analyzer tests own
|
||||
recognition/classification. Avoid duplicated interpretation matrices.
|
||||
|
||||
**Verify:** Run focused contract/affected package tests and `-race` for
|
||||
ownership cases. Reuse unchanged prior checks rather than rerunning the full
|
||||
suite solely for this unit; commit.
|
||||
|
||||
## Stage 7 — Document And Verify The Assembled Feature
|
||||
|
||||
**Outcome:** Implemented semantics and analysis limits are documented in their
|
||||
canonical owners, with final verification ready for user review.
|
||||
|
||||
**Work:**
|
||||
|
||||
1. Finish GoDoc for classifications, presence, metadata, explanations, issues,
|
||||
completeness, errors/ownership, and the deliberately small supported scope.
|
||||
Complex valid templates may yield partial results; no authoring ban is added.
|
||||
2. Update the consumer guide to compare the inspection APIs and preparation.
|
||||
Show required input discovery, optional inactive input/variable inventory,
|
||||
missing required variables, and explicit incomplete discovery.
|
||||
3. Update relevant format cross-references and internal source/runner/component
|
||||
documents. Keep exact implemented API contracts in GoDoc rather than copying
|
||||
them into every guide.
|
||||
4. Add a small inspection use to the maintained preparation example, preserving
|
||||
its existing assertions. Verify it locally without adding another release gate.
|
||||
5. Review roadmap acceptance against implementation/tests. Confirm no general
|
||||
interpreter, stronger caller restriction, raw/intermediate configuration
|
||||
validation, execution-readiness check, or speculative completeness promise
|
||||
was introduced.
|
||||
6. On final changed code, run one assembled offline verification using the local
|
||||
Go installation 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.
|
||||
Release-tool fixtures need not rerun when tooling is unchanged.
|
||||
7. Record implemented status and verification in these temporary review
|
||||
documents, commit, and report remaining limitations honestly. Release
|
||||
preparation later owns version selection, notes, retirement, tags, and pushes.
|
||||
|
||||
## 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.
|
||||
- The separate public operation returns input and caller-variable inventories
|
||||
classified required, conditional, or optional for the selected context.
|
||||
- Recognizable inactive references remain optional entries in both inventories,
|
||||
with safe explanations and aggregation that preserves stronger requirements.
|
||||
- Simple branches/direct names agree with execution; complex cases preserve
|
||||
recognized names and explicit limitations without assignment/path solving.
|
||||
- Effective metadata/captured templates come from final configuration and remain
|
||||
immutable; existing inspection, hashes, and execution behavior remain intact.
|
||||
- Selection, session bypass, missing versus empty caller keys, metadata presence,
|
||||
classification, and completeness have distinct documented meanings.
|
||||
- No artifacts, credentials, provider access, schemas, or execution state are
|
||||
needed for inspection. Results preserve disclosure and public error boundaries.
|
||||
- Focused tests, the maintained example, canonical docs, and final assembled
|
||||
checks demonstrate the feature. No significant design questions remain open.
|
||||
|
||||
@@ -1,273 +1,227 @@
|
||||
# Effective Prompt Requirement Inspection
|
||||
|
||||
Status: Implementation planned; the feature is not implemented. The
|
||||
[implementation plan](implementation.md) owns the ordered migration steps and
|
||||
implements the agreed analysis scope and inventory below. This document owns
|
||||
the target end state and migration scope.
|
||||
[implementation plan](implementation.md) owns the ordered implementation steps.
|
||||
This document owns the purpose, scope, and target end state.
|
||||
|
||||
## Purpose
|
||||
|
||||
Let consumers discover a selected prompt's caller requirements before its input
|
||||
artifacts exist. Scriptorium can expose that information to operators and to
|
||||
Narratio, which can compare its planned bindings with Promptkit's exact input
|
||||
names before undertaking expensive pipeline work.
|
||||
Let consumers enumerate a selected prompt's inputs and caller variables before
|
||||
its input artifacts exist, with each name classified as required, conditional,
|
||||
or optional for the supplied context. Scriptorium can present that inventory
|
||||
to operators and Narratio can compare planned bindings with exact input names
|
||||
before undertaking expensive pipeline work.
|
||||
|
||||
The originating request is `docs/roadmap/scriptorium-feature-request.md`.
|
||||
The capability is application-neutral: Promptkit describes prompt requirements;
|
||||
consumers interpret them for their own configuration, presentation, and workflow.
|
||||
The originating request is [Scriptorium's feature request](scriptorium-feature-request.md).
|
||||
Promptkit supplies application-neutral inspection; consumers own presentation,
|
||||
binding checks, and their own workflows.
|
||||
|
||||
## Current Baseline
|
||||
|
||||
At review baseline `b595dca`:
|
||||
|
||||
- [InspectPrompt](../consumers/pkg-promptkit.md#inspect-a-prompt-before-preparation)
|
||||
selects a captured prompt and reports declared inputs and output metadata.
|
||||
It does not analyze templates or resolve the execution profile.
|
||||
selects a captured prompt and reports declared inputs and output metadata,
|
||||
without analyzing templates or resolving an execution profile.
|
||||
- [InspectProfile](../consumers/pkg-promptkit.md#inspect-a-profile-before-prompt-work)
|
||||
reports one captured profile's effective target separately.
|
||||
reports a captured profile's effective target separately.
|
||||
- [Prepare](../consumers/pkg-promptkit.md#prepare-without-model-execution)
|
||||
selects the execution context, checks target requirements, loads artifacts
|
||||
and applicable schemas, and renders messages. It needs actual input data.
|
||||
- The configuration adapter captures final effective definitions, message
|
||||
contents, and compiled message/session templates during engine construction.
|
||||
Runtime rendering uses Go templates, string-valued caller variables, and the
|
||||
`input` helper. Declared required inputs are checked independently of template
|
||||
branches; active helper calls also require their named inputs.
|
||||
- Declared input metadata currently uses string fields for content type and
|
||||
description. The new result needs to identify a declaration and distinguish
|
||||
available metadata from absent metadata, including effective presence where
|
||||
necessary; current empty strings alone do not establish source-field presence.
|
||||
selects an execution context, loads artifacts and applicable schemas, and
|
||||
renders messages. It needs actual input data.
|
||||
- Engine construction captures final definitions and compiled message/session
|
||||
templates. Rendering uses Go templates, string-valued caller variables, and
|
||||
the `input` helper. Required input declarations are checked independently of
|
||||
branches; an executed helper also needs its named input.
|
||||
- Declared content types and descriptions currently use string fields. The
|
||||
new inspection needs declaration information and effective metadata presence,
|
||||
including the difference between an absent field and an explicitly empty one.
|
||||
|
||||
The [format reference](../formats.md#messages-and-templates),
|
||||
[internal source document](../internal/sources.md), and existing GoDoc own the
|
||||
implemented semantics. No existing operation provides artifact-free,
|
||||
context-sensitive requirement discovery.
|
||||
The [format reference](../formats.md#messages-and-templates), existing GoDoc,
|
||||
and [internal source document](../internal/sources.md) own current behavior.
|
||||
|
||||
## Target Public Operation
|
||||
|
||||
Add a separate read-only engine operation, planned as
|
||||
`Engine.InspectRequirements`, with a dedicated request and result. Preserve
|
||||
`InspectPrompt`, `InspectProfile`, preparation, and execution contracts.
|
||||
Add `Engine.InspectRequirements` with dedicated public request/result values.
|
||||
Preserve `InspectPrompt`, `InspectProfile`, preparation, and execution.
|
||||
|
||||
The request supplies a prompt ID, optional version, optional profile selector,
|
||||
supplied template variables, and an optional direct session ID. It needs no
|
||||
artifact references or contents, output path, API key, or execution settings
|
||||
unrelated to discovery.
|
||||
The request supplies a prompt ID, optional version and profile selectors,
|
||||
caller variables, and an optional direct session ID. It needs no artifact
|
||||
references or contents, output path, or credentials.
|
||||
|
||||
Selection follows equivalent execution semantics: exact identities, omitted
|
||||
version ambiguity, request profile or prompt default, and direct session-ID
|
||||
normalization and bypass. Return selected prompt ID/version and effective
|
||||
profile ID. Profile selection establishes identity, not generation readiness;
|
||||
profiles that depend on later execution overrides need not be completed here.
|
||||
Use execution's selection semantics: exact identities, omitted-version
|
||||
ambiguity, request profile or prompt default, and normalized direct session-ID
|
||||
bypass. Report the selected prompt ID/version and effective profile ID.
|
||||
Selecting a profile establishes identity, not generation readiness; partial
|
||||
profiles remain inspectable.
|
||||
|
||||
Use the configured engine's captured definitions. Source discovery and layering
|
||||
remain consumer choices. Results describe that captured context, not a promise
|
||||
about a later engine or later execution with changed variables.
|
||||
Use the configured engine's captured definitions. Source selection remains a
|
||||
consumer choice. Results describe that captured context, not a later engine or
|
||||
execution with different variables.
|
||||
|
||||
## Result And Requirement Meanings
|
||||
## Result And Classification
|
||||
|
||||
Expose public Go values with documented classifications and predictable ordering.
|
||||
Exact symbol and field spelling belongs in the implementation plan
|
||||
and GoDoc. No Promptkit JSON wire schema is part of this feature.
|
||||
Return an inventory of inputs and a separate inventory of caller variables.
|
||||
Each entry has one of three requirement classifications:
|
||||
|
||||
The result contains:
|
||||
- **Required:** A declaration or recognized definite access establishes that
|
||||
the caller must supply it.
|
||||
- **Conditional:** Its necessity remains unresolved, including references on
|
||||
paths whose applicability the supported analysis cannot determine.
|
||||
- **Optional:** It is known not to be required, including recognizable references
|
||||
used only on known inactive paths and nonrequired declarations or lookups.
|
||||
|
||||
- Selected prompt and profile identities.
|
||||
- Known input names, preserving execution identity, with required, optional,
|
||||
or conditional classification for the supplied context.
|
||||
- Declaration information, descriptions, and content-type metadata where
|
||||
available. A template-discovered undeclared input must not look like a
|
||||
declared input with known metadata. Report existing media-type metadata,
|
||||
not an invented input schema or inferred format constraint.
|
||||
- An inactive-use explanation for statically identifiable undeclared inputs
|
||||
referenced only on known inactive paths. These are optional inventory entries,
|
||||
not bindings the current context needs. Keep this explanation separate from
|
||||
declared descriptions.
|
||||
- Variable requirements separately from artifact inputs, with requirement
|
||||
classification and whether supplied values satisfy the known requirement.
|
||||
Report presence and actual supported semantics, not the supplied values.
|
||||
- A discovery-completeness indicator and structured uncertainty reasons, with
|
||||
safe explanations and relevant identifiers where available.
|
||||
A required declaration stays required even in an inactive branch. A definite
|
||||
helper use promotes an optional input declaration to required. Aggregate repeated
|
||||
occurrences by exact name: required takes precedence over conditional, which
|
||||
takes precedence over optional. Conservative conditional classification is
|
||||
acceptable where analysis cannot establish necessity; inspection need not prove
|
||||
equivalence between alternative execution paths.
|
||||
|
||||
Required means the caller must supply the input for this context. A declared
|
||||
required input stays required even if no active template references it. A
|
||||
declared optional input becomes required when an active template use needs it.
|
||||
Optional means it is known not to be required for this context; conditional
|
||||
means its requirement depends on unresolved context. Do not use optional to
|
||||
hide uncertainty. Known required declarations retain that classification even
|
||||
when other requirements are conditional or undiscoverable.
|
||||
Input entries distinguish declarations from discovered undeclared references
|
||||
and preserve available descriptions/content types. They do not infer input
|
||||
schemas or introduce format enforcement. Variables identify caller-map keys,
|
||||
not template-local symbol names, and report whether each key was supplied.
|
||||
An empty supplied string is present; absence is separate from classification.
|
||||
|
||||
Include statically identifiable undeclared references on known inactive paths
|
||||
as optional entries with an inactive-use explanation. A required or conditional
|
||||
use elsewhere takes precedence over that inactive-only classification and
|
||||
explanation. Inactivity itself is not discovery uncertainty.
|
||||
Include recognizable references on known inactive paths in both inventories
|
||||
as optional entries with an inactive-use explanation. Keep explanations separate
|
||||
from declared input descriptions. An applicable required or conditional use
|
||||
elsewhere overrides the optional classification. Any applicable occurrence,
|
||||
including an optional lookup, removes an inactive-only explanation. Known
|
||||
inactivity introduces neither an execution requirement nor discovery uncertainty.
|
||||
|
||||
An unresolved dynamic name can refer to an otherwise optional input entry. Its
|
||||
absence from recognized active uses alone does not establish that it is
|
||||
definitely optional; classification and uncertainty must account for that
|
||||
possibility.
|
||||
Deduplicate names and provide predictable ordering. Results also identify the
|
||||
selected context and provide discovery completeness with machine-readable
|
||||
limitation categories and safe explanations. Exact public spellings belong in
|
||||
the implementation plan and, once implemented, GoDoc. No Promptkit JSON wire
|
||||
schema is part of this feature.
|
||||
|
||||
Known input names should be deduplicated across declarations, messages, and
|
||||
session templates. Aggregate uses without discarding an established required
|
||||
use. Conditions need not expose raw expressions; machine-readable reason
|
||||
categories and safe summaries are sufficient for basic consumer handling.
|
||||
## Simple Discovery Boundary
|
||||
|
||||
Completeness describes discovery, not readiness or satisfaction. For example,
|
||||
a missing variable used only to insert text can be a known unsatisfied
|
||||
requirement while the complete input set is still discoverable. If that
|
||||
variable selects an input name or branch, its absence can also make discovery
|
||||
incomplete. An empty complete input set means no artifact bindings are needed;
|
||||
a complete inventory containing only optional entries also needs no artifact
|
||||
bindings. An empty incomplete set does not establish that fact. Consumers must
|
||||
distinguish the inventory from applicable requirements, rather than treating
|
||||
every reported name as a needed binding.
|
||||
Use parsed template syntax, not raw-text matching or rendering with placeholder
|
||||
artifacts. The intended algorithm is straightforward:
|
||||
|
||||
## Context-Sensitive Discovery Boundary
|
||||
1. Seed the inventory from input declarations and their effective metadata.
|
||||
2. Visit the selected message templates and applicable session template,
|
||||
collecting recognizable input and caller-variable references.
|
||||
3. Classify occurrences using their surrounding path and a small amount of
|
||||
supplied-context evaluation.
|
||||
4. Aggregate entries and report any unresolved discovery.
|
||||
|
||||
Analyze parsed templates rather than searching raw text or rendering with
|
||||
placeholder artifacts. Use supplied variable values where they determine
|
||||
branches and input names, following execution's presence, truthiness, scope,
|
||||
and evaluation semantics. An empty string is not an absent variable, and a
|
||||
nonempty string must not be reinterpreted as a Boolean merely from its spelling.
|
||||
The source inventory is finite and ordinarily small. Direct traversal and
|
||||
name-indexed aggregation are sufficient; no size caps, analysis budgets,
|
||||
branch-combination enumeration, or global analysis cache are needed.
|
||||
|
||||
Include dependencies from messages and the applicable session-ID template.
|
||||
A direct nonblank session ID bypasses that template, removing only requirements
|
||||
introduced solely by it; declarations and message uses remain relevant.
|
||||
The bypassed session template is also excluded from the inactive inventory.
|
||||
Recognize literal input names, direct caller-variable access, literal-key root
|
||||
lookups, direct variable-derived input names, and ordinary `if`/`with` branches.
|
||||
Use simple truthiness, negation, and equality/inequality where straightforward.
|
||||
Empty strings and the nonempty string `"false"` follow actual Go truthiness.
|
||||
The implementation plan defines this small initial coverage precisely.
|
||||
|
||||
Literal `input` references are discoverable without reading bodies, including
|
||||
undeclared references. Artifact content being unavailable does not by itself
|
||||
make discovery incomplete: it does so when the content affects which further
|
||||
requirements apply. Variable-derived names are discoverable when supported
|
||||
analysis can determine the exact name from the supplied context.
|
||||
Retain enough lexical/dot scope awareness to distinguish caller variables from
|
||||
locals. Complicated assignments, pipelines, computed names, ranges, or invoked
|
||||
named templates can remain outside complete analysis. Preserve identifiable
|
||||
references and report limitations rather than implementing a general template
|
||||
interpreter, joining assignment environments, or propagating possible-name sets.
|
||||
No cross-branch proof of a common required dependency is necessary.
|
||||
|
||||
When missing variables, content-dependent decisions, unresolved names, or
|
||||
analysis limitations prevent determination, preserve known requirements and
|
||||
return successful incomplete discovery. Structured reasons should distinguish
|
||||
these situations without requiring diagnostic-text matching. Unsupported
|
||||
analysis is not a new prompt-validity rule. Completeness is asserted only when
|
||||
the supported analysis establishes the requirement set; it does not promise
|
||||
universal analysis of every valid Go template.
|
||||
On a known inactive path, collect names visible in syntax without evaluating
|
||||
its expressions. Literal input names and recognizable caller keys remain in
|
||||
the inventory; skipped dynamic input names need not be resolved. Unsupported
|
||||
skipped expressions do not themselves make discovery incomplete.
|
||||
|
||||
The selected practical analysis core and inactive inventory are described below.
|
||||
They do not change execution or expand the template language.
|
||||
A direct nonblank session ID excludes the bypassed session template from both
|
||||
inventories. Never-invoked template definitions do not create requirements.
|
||||
Declarations and references in selected messages remain relevant.
|
||||
|
||||
Complex computed names may be missed by the inventory. That is an accepted
|
||||
analysis limitation, not a reason to reject an otherwise valid prompt.
|
||||
Inspection must expose potential incompleteness rather than imply that unknown
|
||||
names are absent. Template authors benefit from keeping dependency expressions
|
||||
simple, but this feature adds no template-authoring prohibition.
|
||||
|
||||
## Completeness And Limitations
|
||||
|
||||
Completeness describes discovery, not satisfaction or readiness. A missing
|
||||
variable used only for direct text substitution can be a known required entry
|
||||
with complete discovery. A missing value used to select a branch or name can
|
||||
leave dependencies unresolved.
|
||||
|
||||
When unavailable input content, unresolved names, missing decision values, or
|
||||
unsupported analysis affect discovery, return known entries with successful
|
||||
incomplete status and structured reasons. Conservative incompleteness is
|
||||
acceptable; inspection need not prove an exact requirement set through complex
|
||||
expressions. Unsupported pure text with no effect on dependencies need not
|
||||
introduce uncertainty.
|
||||
|
||||
Unresolved names can potentially refer to existing optional entries. Account
|
||||
for that possibility in classification, while leaving established required
|
||||
entries required. Do not label a potentially needed entry definitively optional.
|
||||
|
||||
An empty complete input inventory, or a complete input inventory containing
|
||||
only optional entries, establishes that no artifact bindings are needed.
|
||||
An empty incomplete inventory does not. Consumers must use classifications,
|
||||
not inventory length, to identify bindings that need preparation.
|
||||
|
||||
## Effects, Errors, And Disclosure
|
||||
|
||||
Inspection uses captured prompt resources and needs no future artifact files,
|
||||
credential lookup, model access, capacity admission, or execution artifact
|
||||
creation. It does not prepare an output-validation schema or validate future
|
||||
input bytes. Necessary configuration/resource failures can still prevent engine
|
||||
construction or inspection; this is not a general resource preflight.
|
||||
Inspection uses captured resources without future artifact reads, schema
|
||||
preparation, credential lookup, model calls, capacity admission, observations,
|
||||
run IDs, or execution artifact creation. Necessary configuration/resource
|
||||
failures can still prevent engine construction or inspection.
|
||||
|
||||
Use existing public selection/error identities wherever applicable, including
|
||||
invalid requests, missing prompt/profile selections, and ambiguous versions.
|
||||
Preserve ordinary context cancellation behavior. Discovery uncertainty is a
|
||||
result state, distinct from an operational or selection error. Expose any
|
||||
additional necessary classifications through the public facade, not diagnostic
|
||||
text parsing or internal types.
|
||||
Preserve publicly classifiable selection errors and ordinary context
|
||||
cancellation. Discovery uncertainty is a successful result, not an operational
|
||||
error or a new definition-validity rule. A complete result does not promise
|
||||
successful rendering, generation, future artifact validity, or provider
|
||||
availability.
|
||||
|
||||
Results and safe diagnostics exclude credential values, artifact payloads,
|
||||
raw/rendered prompt content, and unrelated supplied variable values. Selected
|
||||
identities, input/variable names, and declared descriptions are intentional
|
||||
operator metadata. A resolved dynamic input identifier may equal a supplied
|
||||
variable value; reporting that identifier is necessary to describe the binding.
|
||||
Keep the disclosure exception limited to its role as an identifier, without
|
||||
echoing the variable map or the expression that produced it. Scriptorium owns
|
||||
the presentation and disclosure of this metadata to its callers.
|
||||
|
||||
A complete result describes requirements, not successful rendering or generation,
|
||||
future artifact validity, or provider availability. Incomplete results remain
|
||||
useful without authorizing consumers to treat unknown dependencies as absent.
|
||||
Results and diagnostics exclude credential values, artifact payloads,
|
||||
raw/rendered prompt content, and unrelated supplied values. Selected identities,
|
||||
input/variable names, and declared descriptions are intentional operator
|
||||
metadata. A directly resolved input identifier may equal a supplied variable
|
||||
value; reporting that binding name is necessary, without echoing its originating
|
||||
expression or variable map.
|
||||
|
||||
## Work Needed From The Baseline
|
||||
|
||||
Add public request/result values and the engine method through the existing
|
||||
facade. Put selection coordination and analysis in internal components with
|
||||
cohesive ownership. Reuse existing prompt/profile selection, session override,
|
||||
and template parsing semantics rather than introducing a second preparation
|
||||
path or a general-purpose template interpreter.
|
||||
Add request/result values and the engine method through the root facade.
|
||||
Keep selection coordination internal and place syntax discovery with the
|
||||
existing prompt-template component. Reuse captured templates and selection
|
||||
helpers rather than creating another preparation path.
|
||||
|
||||
Make the captured templates and effective declaration metadata available to
|
||||
internal inspection. Retain any required metadata presence at the ConfigKit
|
||||
handoff. Apply [ADR 0001](../adr/0001-configuration-boundary.md): inspection
|
||||
interprets final effective definitions, not raw sources, configuration history,
|
||||
or intermediate artifacts. Operator provenance remains a separate explicit API.
|
||||
Capture required metadata presence at the final ConfigKit handoff and retain it
|
||||
alongside inspection snapshots. Apply [ADR 0001](../adr/0001-configuration-boundary.md):
|
||||
interpret final effective definitions, not raw/intermediate configuration or
|
||||
history. Operator provenance remains a separate explicit API.
|
||||
|
||||
Implement requirement aggregation, context-sensitive analysis, and safe public
|
||||
uncertainty/error conversion. Keep request-specific analysis separate from
|
||||
shared captured state. Prefer direct traversals and indexed aggregation; avoid
|
||||
enumerating every possible branch combination or repeated full-template scans.
|
||||
Predictable result ordering does not require a stronger complexity guarantee
|
||||
or a new global cache.
|
||||
|
||||
Add focused analyzer tests and public-facade contract coverage under the
|
||||
[testing policy](../policy/testing.md). Use real captured definitions and
|
||||
templates, synthetic variables, and explicit unavailable artifacts. Compare
|
||||
complete discovery with representative execution semantics. Test incomplete
|
||||
results separately from errors and verify disclosure boundaries and absence
|
||||
of artifact reads/provider calls. Do not retest ConfigKit's loading matrix.
|
||||
Implement a small syntax walker, simple context tests, classification
|
||||
aggregation, and safe limitation reporting. Keep request-specific state separate
|
||||
from captured definitions. Focus tests on representative enumeration,
|
||||
classifications, scope mistakes, selection, capture/ownership, and absence of
|
||||
execution effects, under the [testing policy](../policy/testing.md). Do not test
|
||||
a general interpreter or repeat ConfigKit's source-loading matrix.
|
||||
|
||||
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. The implementation plan owns implementation sequencing.
|
||||
cross-references, internal documents, and a maintained example. Canonical owners
|
||||
document the implemented boundary; release notes summarize rather than own it.
|
||||
|
||||
## Acceptance Outcomes
|
||||
|
||||
- A required `transcript` is reported exactly, allowing a consumer to detect a
|
||||
planned binding under the wrong name before the transcript exists.
|
||||
- Literal undeclared helper references are discoverable without making their
|
||||
absence from declarations a new definition error.
|
||||
- Declared required inputs remain required in inactive branches; optional
|
||||
declarations remain optional where no applicable use makes them required.
|
||||
- Statically identifiable inactive undeclared references are optional entries
|
||||
with an inactive-use explanation; active and unresolved uses of the same name
|
||||
take precedence. These entries do not introduce variable requirements or
|
||||
incompleteness solely from skipped expressions.
|
||||
- Supported variable-dependent branches and names agree with execution;
|
||||
unresolved content/name/analysis cases retain known entries and uncertainty.
|
||||
- Version/profile/default selection and session-template bypass agree with
|
||||
execution without credential or generation-readiness checks.
|
||||
- Variables are reported separately, with absent and empty supplied values
|
||||
interpreted according to the existing template semantics.
|
||||
- Artifact-free complete results, including all-optional inventories, are
|
||||
distinguishable from empty partial discovery.
|
||||
- Errors remain publicly classifiable; results and safe diagnostics disclose
|
||||
identifiers and declared metadata without unrelated content or secret values.
|
||||
- Existing inspection and execution APIs retain their contracts. Pipeline
|
||||
planning, binding validation, CLI/HTTP exposure, presentation, JSON schemas,
|
||||
graph rendering, batch interfaces, and provider preflight remain downstream.
|
||||
|
||||
## Selected Analysis Scope And Inventory
|
||||
|
||||
### Initial Template Analysis Coverage
|
||||
|
||||
Implement a documented practical core: literal input calls,
|
||||
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. 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.
|
||||
|
||||
### Inactive Undeclared Reference Inventory
|
||||
|
||||
Always include declarations and discovered active or unresolved dependencies.
|
||||
Also include statically identifiable undeclared references on known inactive
|
||||
paths as optional entries with an inactive-use explanation. This broader
|
||||
inventory helps operators explore prompt behavior while preserving the
|
||||
distinction between inventory and applicable dependencies.
|
||||
|
||||
Collect inactive names from syntax without evaluating skipped expressions.
|
||||
The initial scope covers literal helper names and equivalent parenthesized or
|
||||
piped literal forms. Skipped dynamic names need not be resolved, and skipped
|
||||
variable accesses do not become caller requirements or uncertainty reasons.
|
||||
Include known skipped branches and short-circuit operands, without expanding
|
||||
analysis to never-invoked template definitions or a bypassed session template.
|
||||
Preserve declared optional metadata and required declarations; when another
|
||||
use makes a name required or conditional, its inactive occurrence does not
|
||||
override that classification or imply that the name is inactive-only.
|
||||
- Required `transcript` is reported exactly before its artifact exists.
|
||||
- Literal undeclared helper names are discoverable without definition rejection.
|
||||
- Input and variable references are classified as required, conditional, or
|
||||
optional, including recognizable inactive references in both inventories.
|
||||
- Required declarations stay required; definite uses promote optional entries;
|
||||
other occurrences never erase an established required use.
|
||||
- Simple supplied-context branches and direct dynamic names follow execution;
|
||||
complicated or content-dependent cases preserve known entries and limitations.
|
||||
- Caller keys remain distinct from template locals, and supplied empty values
|
||||
remain distinct from absent keys.
|
||||
- Selection and session bypass follow execution without readiness checks.
|
||||
- Complete artifact-free inventories remain distinguishable from empty partial
|
||||
discovery; completeness remains separate from supplied-variable presence.
|
||||
- Results/errors preserve the disclosure and public classification boundaries.
|
||||
- Existing inspection/execution contracts remain intact. Application APIs,
|
||||
pipeline planning, binding validation, presentation, provider preflight, input
|
||||
schemas, and a general-purpose template evaluator remain outside this scope.
|
||||
|
||||
Reference in New Issue
Block a user