Remove completed requirements planning records

This commit is contained in:
2026-10-12 21:08:42 +00:00
parent 40499a4360
commit 700f10d78e
4 changed files with 3 additions and 1036 deletions

View File

@@ -61,8 +61,9 @@ canonical documentation owners.
Read all applicable rows for cross-cutting work. Go declarations and GoDoc own
current exported contracts; the CLI reference owns operator behavior. The
[maintainer release procedure](release.md) owns current release operations.
Completed roadmaps and implementation evidence remain available in Git history;
they are not assignments to restart completed work. The
Completed roadmaps and implementation evidence remain available in Git history,
including [PromptKit requirements implementation and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/40499a43608bf60d1104cd8ee24caf18ac0e9e66/docs/roadmap).
These records are not assignments to restart completed work. The
[deferred-work record](roadmap/deferred.md) preserves future capability targets
and unselected proposals separately from current contracts.

View File

@@ -1,535 +0,0 @@
# Implement PromptKit requirements inspection
Status: complete; Stages 1 through 7 are complete.
## Authority and working rules
The accepted [feature roadmap](requirements.md) owns the target state and product
choices. This document owns the ordered work to reach that state. Start from
commit [`49b7e68`](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/49b7e686b3072037834574738441e14d3ce061bc),
whose implementation is unchanged from the baseline described in the roadmap.
Read [development guidance](../development.md) and the applicable
[agent](../policy/agents.md), [architecture](../policy/architecture.md),
[documentation](../policy/documentation.md), and [testing](../policy/testing.md)
policies before changing their governed areas.
Follow Stage 1 through Stage 7 in order. Each stage is sized for a separate Luna
implementation prompt. Complete its work and focused validation, then record
brief completion evidence beneath that stage: files changed, commands actually
run, results, and material limitations. Commit completed nonempty units under
the existing commit policy. Distinguish focused checks from final whole-module
validation; never label an unrun check as passing.
The implementation is an unreleased prototype. Do not add compatibility shims
or require every intermediate commit to satisfy the complete final suite.
Preserve explicitly selected contracts and existing unrelated operations. Prefer
the simplest coherent final implementation over preserving incidental private
structure. Any temporary integration gap must have a named later stage that
closes it.
Use the graph tools for code discovery as instructed by AGENTS.md. Source symbols
below are starting points, not restrictions on private helper organization.
Keep work in ckprompt and its documentation/example unless an actual defect in
an existing shared path prevents the selected behavior. Do not introduce a new
module, core domain API, backend abstraction, or upstream discovery model.
## Settled implementation choices
These choices come from the accepted feature roadmap; do not reopen them merely
to match backend defaults:
- Install `app promptkit requirements show PROMPT_ID` when the requirements
callback is present. Do not install an alias under `promptkit show`.
- Add `ckprompt.RequirementsRequest` with `Selection ckconfig.Selection` and
`Inspection promptkit.RequirementInspectionRequest`, and add the optional
`Suite[I, S].InspectRequirements` callback specified by the roadmap.
- Forward native discovery context through that request. Keep configuration
and application-selector presence; native version/profile/session strings
retain native empty-value semantics.
- Accept singleton `--config`, `--overlay`, `--version`, `--profile`,
`--session-id`, and `--format`, plus suite selectors and repeatable
`--var KEY=VALUE`. Overlays do not accumulate. Default the format to YAML and
accept only YAML for this operation.
- Split each variable occurrence at its first `=`; retain exact keys and values,
including whitespace, commas, extra `=` characters, and empty keys/values.
Missing separators are usage errors. Parse every occurrence and apply
duplicate keys in occurrence order, so the last value wins.
- Render the complete native evidence in the selected YAML schema. Successful
delivery of a partial inspection is success; completeness and issues do not
independently establish readiness or failure.
- Use existing preparation, diagnostic, error-identity, cancellation, and
buffered-delivery paths. Application callbacks retain their own effects.
PromptKit v0.14.0 already supplies this capability. Keep the current dependency
versions and Go 1.26.0 consumer minimum. Use the existing Go 1.26.8 maintainer
toolchain. No dependency upgrade, release-version selection, publication,
consumer migration, policy change, or ADR revision is assigned by this plan.
## Stage 1: Add the public request and native engine adapter
**Outcome:** callers can supply requirements inspection independently, and
`FromEngine` exposes PromptKit's native inspection through that callback.
**Starting points:** `Suite`, `PromptRequest`, `FromEngine`, and
`loadPromptKitEngine` in
[adapters.go](../../integrations/ckprompt/adapters.go), and existing adapter
coverage in [adapters_test.go](../../integrations/ckprompt/adapters_test.go).
**Steps**
1. Preserve existing local changes and an ignored `go.work`. Ensure the workspace
includes core, ckconfig, and ckprompt using the developer guide's procedure.
Do not add sibling-module replacements to distributed manifests. Record any
baseline validation limitation that will affect later stages.
2. Add the exported `RequirementsRequest` type and the exact optional callback:
```go
InspectRequirements func(
context.Context, RequirementsRequest, I, S,
) (commandkit.Acquired[*promptkit.RequirementInspection], error)
```
Document selection, native context, optional availability, and the ordinary
suite input/state lifecycle. Extend existing suite comments that mention
only catalogs and named definitions to include requirements inspection.
3. In `FromEngine`, supply the callback. Call `loadPromptKitEngine` with the
request's configuration selection, supplied `I` and `S`, and the ordinary
diagnostic heading, then call `engine.InspectRequirements(ctx,
request.Inspection)`. Return the native result/error and reached diagnostics
in the existing `Acquired` form.
4. Retain nil-loader construction issues, nil-engine failures, native
`errors.Is`/`errors.As` identity, and post-load cancellation handling. Reuse
the current helper rather than implementing another loader or performing
named profile inspection as a prerequisite.
5. Add focused adapter coverage through public PromptKit APIs. Use a small real
engine fixture and compare the callback's returned inspection with the
engine's direct native result for the same request. Observe loader selection,
input, and state; exercise supplied profile/version/variables/session context.
Cover a load failure with ConfigKit diagnostics, nil engine, and a reachable
native selection error.
**Validation and handoff**
Format changed Go files and run the affected adapter tests in ckprompt. Reuse
existing fixture helpers such as `adapterEngineFrom` where useful. This stage
adds the callback; its CLI availability arrives in Stage 3. Update existing
absence tests when the command assembly starts counting the fifth callback in
that stage, rather than treating their old four-callback assumption as policy.
**Completed:** Added `RequirementsRequest`, the optional suite callback, and
the `FromEngine` native adapter in `integrations/ckprompt/adapters.go`; added
adapter coverage in `adapters_test.go`. The ignored workspace already included
core, ckconfig, and ckprompt, and the baseline ckprompt suite passed. After the
change, `GOTOOLCHAIN=local go test ./integrations/ckprompt -run
'TestFromEngine(InspectsRequirementsWithNativeRequest|RequirementsRetainLoadDiagnosticsAndSelectionErrors|RequirementsHonorCancellationAfterLoad|PassesRequestsAndRetainsNilLoaderIssue)$'
-count=1` and `GOTOOLCHAIN=local go test ./...` from `integrations/ckprompt`
passed. The tests verify native result equivalence, loader arguments, retained
ConfigKit diagnostics, nil-engine handling, native selection error identity, and
cancellation after loading. No material limitations were encountered.
## Stage 2: Implement the requirements YAML report
**Outcome:** native inspections map to the accepted YAML shape without losing
partial evidence or metadata presence.
**Starting points:** `promptReportFromInspection`, `encodePromptYAMLBytes`,
`encodePromptYAML`, and existing report tests in
[command.go](../../integrations/ckprompt/command.go) and
[command_test.go](../../integrations/ckprompt/command_test.go).
**Steps**
1. Add private report types with explicit YAML tags for the exact field inventory
in [the roadmap's report section](requirements.md#initial-report). Keep these
types private; the callback already returns the native public inspection.
2. Add a straightforward conversion from `*promptkit.RequirementInspection` to
those report types. Preserve selected identities, returned collection order,
classifications, explanations, structured issue associations, and issue
descriptions. Do not recompute completeness or sort/deduplicate native data.
3. Populate input, variable, and issue slices as non-nil empty slices when the
native inventory is empty. Emit `complete`, `declared`, and `supplied` even
when false. Keep nullable metadata fields present: nil pointers render null
and pointers to empty strings render empty strings. Include the other listed
fields even when their values are empty; avoid `omitempty` on this schema.
4. Carry native kind and issue-code strings without a CommandKit enum whitelist.
Do not add supplied variable values, artifact payloads, prompt contents, or
a readiness field to the report. Native resolved input identifiers remain
part of the evidence.
5. Encode through the existing YAML v4 buffer helper. Add report coverage for
empty inventories, false values, null versus empty metadata, complete and
partial results, and preservation of strings that YAML might otherwise
interpret as numbers or booleans. Decode YAML semantically; assert neither
incidental indentation/key order nor exact upstream explanatory wording.
**Validation and handoff**
Run the focused report tests. Use only the module's declared
`go.yaml.in/yaml/v4` package in new tests. Stage 3 will connect this report to
invocation and delivery; do not create a parallel public report writer.
**Completed:** Added private requirements report types and a direct conversion
from PromptKit's native inspection in `integrations/ckprompt/command.go`, with
semantic YAML coverage in `command_test.go`. `GOTOOLCHAIN=local go test
./integrations/ckprompt -run 'TestRequirementsReport' -count=1` passed. Coverage
confirms empty sequences, present false/empty values, nullable metadata,
ordering, unrecognized kind/code strings, and complete and partial results.
No material limitations were encountered.
## Stage 3: Assemble and invoke the optional requirements command
**Outcome:** an installed requirements capability has the selected command,
flags, input lifecycle, and buffered report delivery.
**Starting points:** `Command`, `newDefinitionCommand`, `newCatalogListCommand`,
`prepareSuiteInput`, `definitionFailure`, and `writePromptReport` in ckprompt's
`command.go`; public `CaptureFlags`, `ValueFlag`, `RepeatFlag`, and
`ValueArgument` in core.
**Steps**
1. Add a private requirements command input containing configuration selection,
captured suite selectors, selected `I`, native discovery context, and format.
Give the core declaration a private input factory as existing inspection
commands do; the application's `Suite.NewInput` still runs only when selected
input preparation is reached.
2. Capture suite selectors with the existing `CaptureFlags` composition. Bind
one required prompt operand to native `PromptID`. Bind config and overlay to
their `Supplied[string]` fields, preserving explicit empty selection. Bind
version, profile, and session ID to native request strings with empty defaults.
Bind format with a `yaml` default. Add no built-in `--scope` flag.
3. Use `RepeatFlag` for `--var` with a private assignment parser using
`strings.Cut(raw, "=")` and a small private key/value representation. Return
a parse error when no separator exists. In the setter, build a fresh map for
that invocation from all converted occurrences, in order. Keep zero
assignments equivalent to the native empty context; do not invent a public
nil-versus-empty-map distinction.
4. In command input checking, reject formats other than YAML before preparing
application input. Call `prepareSuiteInput` for the captured selectors and
configuration selection, retaining its error handling. Cache that selected
input for the handler. Core's required-operand and converted-value paths
handle syntax; do not parse raw argv inside the handler.
5. Implement the handler following existing inspection flow: check cancellation
at the established operation boundaries, initialize state after checks pass,
invoke only `InspectRequirements`, retain diagnostics on errors, reject a
nil inspection with no error as an operational provider failure, and check
cancellation after acquisition. Convert/encode through Stage 2 and deliver
through `writePromptReport`; use `definitionFailure` for operational failures.
Completeness and structured issues do not select a failure status.
6. Extend `Command`'s absence test to include `InspectRequirements`. Add
`Group("requirements", ..., showCommand)` only when that callback is present,
beneath the existing root-only `promptkit` declaration. Retain its attached
construction errors, copied selectors, and optional existing groups. Adjust
root help summaries to describe the expanded inspection surface.
7. Add installed-command coverage for requirements alone, all callbacks present,
requirements omitted, and all callbacks absent. Update existing tests that
clear a `FromEngine` suite to clear the fifth callback where they intend total
absence. Preserve tests' actual intended capability subsets.
8. Test the accepted variable table through public `App.Execute`, including
comma/whitespace preservation, empty key/value, additional separators,
duplicate keys, and an earlier malformed occurrence followed by valid input.
Test missing/extra operands, unsupported format, singleton last-value behavior,
and request forwarding. Parse failures and format preflight leave the
application factories/provider uninvoked.
**Validation and handoff**
Run focused requirements command tests and existing optional-family tests.
Confirm help shows the requirements group and its operands/flags without invoking
suite factories or loaders. Normal flag conversion still applies on help;
do not add a special bypass for malformed variable occurrences. Namespace
collision/root-placement enforcement stays with the existing core installer.
**Completed:** Added the optional `promptkit requirements show` command, typed
bindings, per-invocation variable assignment parsing, format preflight, and
buffered YAML delivery in `integrations/ckprompt/command.go`. Extended
`command_test.go` for requirements-only and all-capability trees, help, request
forwarding, selector/configuration presence, variable grammar, singleton
overrides, repeated executions, and usage preflight. Focused optional-family and
requirements command tests passed with `GOTOOLCHAIN=local go test
./integrations/ckprompt -run
'Test(CommandBuildsIndependentOptionalTrees|CatalogCommandTreesAreIndependentAndOmitShow|RequirementsCommandCapturesContextAndVariableAssignments|RequirementsCommandUsageFailuresPrecedeApplicationPreparation)$'
-count=1`; `GOTOOLCHAIN=local go test ./...` from `integrations/ckprompt` also
passed. No material limitations were encountered.
## Stage 4: Verify native semantics, lifecycle, and failure delivery
**Outcome:** the installed command demonstrably delegates discovery to PromptKit
and preserves the existing coordination and failure contracts.
**Starting points:** new requirements tests from Stages 1–3, ckprompt's existing
lifecycle and delivery tests, and external composition tests. Keep generic
parser/backend behavior with its current test owner.
**Steps**
1. Install a real `FromEngine` suite in a public App. Use a prompt with the
roadmap's conditional template and no input declarations, plus a selected
profile. Compare decoded report evidence with direct native inspection for
missing `mode` and supplied `mode=full`. Both delivered invocations return
success; the first is incomplete and contains its native issue, while the
second resolves the dependency. Also protect complete discovery with an
unsupplied required variable, using a native fixture that demonstrates it.
2. Cover omitted versus explicit prompt version/profile selection through the
native request. Demonstrate that a profile need not be execution-ready and
that a supplied session ID changes session-template discovery as the native
API defines. Test missing/ambiguous native selections with error identity,
rather than duplicating upstream's full recognition or selection matrix.
3. Exercise a custom requirements callback with captured suite selectors,
input checks, and state. Observe one selected input and one state when their
lifecycle points are reached; checks precede state/provider acquisition.
Preserve omitted-factory zero values, including nil pointer types, without
automatic allocation. Repeated executions start with fresh core-owned
variable values and selector capture. Do not assert distinct caller-owned
factory results or concurrent dispatch.
4. Verify command capture keeps later suite metadata edits and callback
replacement from changing the captured declaration, while retaining the
existing ownership of callback-referenced objects. Cover a failed input check
and cancellation before acquisition using the established classifications.
5. Use a small custom callback for success with warning diagnostics, provider
failure with diagnostics, and cancellation observed after callback return.
Verify reached diagnostics and supported cause identity survive. Structured
requirement issues stay in YAML rather than being presented a second time as
CommandKit errors.
6. Exercise a nil-result provider, failing/short report writer, and diagnostic
writer failure. Confirm existing operational status, `ReportIncomplete`,
`DeliveryError`, and diagnostic ownership where applicable. Preserve partial
bytes on a report failure without promising transactional output. Reuse
generic delivery coverage where it already protects the path.
**Validation and handoff**
Run the ckprompt module suite, including its existing composed example tests.
Use native APIs and deterministic in-memory/filesystem fixtures; no model calls
or real credentials are needed. PromptKit v0.14.0 has no public path for adding
warnings to a successfully acquired engine configuration. Use custom callback
diagnostics for the command path and existing helper evidence for that native
limitation; do not add a test-only engine injection API or claim an unavailable
native warning scenario was exercised.
**Completed:** Added installed-command coverage in
`integrations/ckprompt/requirements_command_test.go` for native report
equivalence across conditional discovery, selected/default identities,
session-template discovery and bypass, and complete discovery with an
unsupplied required variable. The tests also cover captured selectors and
callback data, repeated invocation lifecycles, omitted pointer factories,
input rejection and pre-acquisition cancellation, warning diagnostics,
provider error identity, post-callback cancellation, nil results, partial report
delivery, short writes, and diagnostic writer failure. The focused command
`GOTOOLCHAIN=local go test ./integrations/ckprompt -run
'TestRequirementsCommand(MatchesNativePromptKitDiscovery|PreservesNativeSelectionErrors|KeepsLifecycleAndCapturedDeclaration|ChecksInputAndCancellationBeforeAcquisition|PreservesDiagnosticsCancellationAndDelivery)$'
-count=1` passed. `GOTOOLCHAIN=local go test ./...` from
`integrations/ckprompt` passed, including the composed example suite. Native
successful-acquisition warnings remain unavailable through PromptKit v0.14.0's
public API; custom callback diagnostics exercise the installed command path.
## Stage 5: Demonstrate requirements in the maintained composed consumer
**Outcome:** the existing consumer shows partial discovery and contextual
resolution through the ordinary public registration API.
**Starting points:**
[composed main.go](../../integrations/ckprompt/examples/composed/main.go),
[main_test.go](../../integrations/ckprompt/examples/composed/main_test.go), and
its fixtures. `newApp` already installs the suite returned by `FromEngine`.
**Steps**
1. Keep the existing public `FromEngine`/`Command` composition; the new default
callback makes the command available without another registration block.
2. Extend the loader's synthetic prompt message with a conditional dependency
using `{{if .mode}}{{input "notes"}}{{end}}`. Retain the existing briefing
prompt identity, campaign-selected profile, declared topic input, and
configuration comparison fixtures. The absence of a `notes` declaration
makes that reference distinguishable from the existing declared input.
This example does not execute or need payloads for either input.
3. Add consumer coverage for these invocations:
```sh
go run . promptkit requirements show briefing --campaign spring
go run . promptkit requirements show briefing --campaign spring --var mode=full --format yaml
```
In tests, invoke the assembled App directly and decode YAML. Observe the
spring identity, missing versus supplied `mode`, conditional versus required
`notes`, incomplete versus complete discovery, and success for both reports.
Retain other native inventory entries rather than expecting an artificial
one-entry report.
4. Preserve the existing config diff, catalogs, named inspections, and custom
session restore tests. Adjust fixture-derived expectations only where the
deliberate message change affects them. Avoid position-based catalog or
inventory assertions when only membership is intended.
**Validation and handoff**
Run the composed example's tests and both commands from its directory. Record
actual report semantics, not explanatory wording snapshots. Documentation of
these copyable commands belongs in Stage 6.
**Completed:** Extended the synthetic prompt in
`integrations/ckprompt/examples/composed/main.go` with the conditional
`notes` dependency while retaining the declared `topic` input. Added assembled
App coverage in `main_test.go` for selected spring identity, missing and
supplied `mode`, conditional versus required classification of undeclared
`notes`, incomplete versus complete discovery, and success for both reports.
`GOTOOLCHAIN=local go test ./examples/composed -run
'TestComposedRequirementsDiscoveryUsesSelectedCampaign$' -count=1` and
`GOTOOLCHAIN=local go test ./examples/composed` passed from
`integrations/ckprompt`. Both roadmap commands passed from
`integrations/ckprompt/examples/composed`: the first report was incomplete with
a missing `mode` issue and conditional `notes`; the second was complete with
`mode` supplied and required `notes`. No material limitations were encountered.
## Stage 6: Align canonical documentation with the delivered feature
**Outcome:** API, operator, and consumer documentation describes the implemented
capability without leaving four-callback assumptions or stale deferral claims.
**Steps**
1. Finish GoDoc in `adapters.go`, `command.go`, and
[doc.go](../../integrations/ckprompt/doc.go): the optional callback, thin native
request, selected input/state timing, capability capture, and adapter meaning.
Keep exact exported contracts there rather than in consumer walkthroughs.
2. Extend [the CLI reference](../cli.md) with the installed command, all its
operands/flags/defaults, variable grammar, report schema, and outcome rules.
Explain discovery completeness versus satisfaction/readiness and native
profile/default/version/session interpretation with a pinned upstream API
link. Document partial reports and their successful status. Other formats are
unsupported for this operation, not prohibited across CommandKit.
3. Update [consumer guidance](../consumers/guide.md), the module README, and root
README summaries as needed. Show independent requirements availability and
ordinary wrapping/clearing/replacement of the callback. Fix narrowing examples:
a suite described as catalogs-only must now also clear `InspectRequirements`.
Keep operator grammar/schema in the CLI owner and exact API in GoDoc.
4. Update [internal inventory](../internal/overview.md) and relevant developer
orientation summaries to include requirements. Extend the composed example's
README with the two Stage 5 commands and a short explanation of their results.
Keep complete runnable artifacts in that maintained example.
5. Remove the now-delivered requirements deferral from
[deferred.md](deferred.md), retaining unrelated deferred targets. Reconcile the
feature roadmap's historical deferral link so it points to an existing owner
or an immutable historical record rather than a removed fragment.
6. Leave accepted ADR 0004 and the architecture policy unchanged: this operation
fits their selected ownership/capability boundaries. Dependency versions and
incorporated material are unchanged; do not churn attribution or manifests.
Release notes/version selection remain with actual release preparation under
the feature roadmap and current release procedure.
**Validation and handoff**
Review changed examples against observed behavior. Check local links/fragments,
whitespace, and remaining references to four callbacks or deferred requirements.
Historical release notes and pinned retired plans remain historical evidence;
do not rewrite them as current reference pages. Current canonical docs must not
depend on this temporary plan for their implemented contracts.
**Completed:** Updated the exported API comments in
`integrations/ckprompt/adapters.go`, `command.go`, and `doc.go`; the command and
report contract in `docs/cli.md`; optional callback guidance in
`docs/consumers/guide.md`; module, root, internal, and contributor summaries;
and the composed example README. Removed the delivered capability from
`docs/roadmap/deferred.md` and updated
`docs/roadmap/requirements.md` to describe its historical baseline and point to
the immutable commit that contains the prior deferral. The two example commands
and their semantics match the Stage 5 test and observed output. `gofmt -w
integrations/ckprompt/adapters.go integrations/ckprompt/command.go
integrations/ckprompt/doc.go` and `git diff --check -- '*.md' COPYRIGHT` passed.
A local link and fragment check across nine changed Markdown documents passed;
the stale four-callback and deferred-requirement claim search found no current
documentation claims. No material limitations were encountered.
## Stage 7: Validate the final module boundaries and complete the sprint
**Outcome:** the implemented feature works with its committed dependency graph,
the complete repository remains coherent, and completion evidence is accurate.
**Steps**
1. Format changed Go files. With the ignored local workspace, run each module's
suite separately; root traversal misses the nested modules:
```sh
GOTOOLCHAIN=local go test ./...
(cd integrations/ckconfig && GOTOOLCHAIN=local go test ./...)
(cd integrations/ckprompt && GOTOOLCHAIN=local go test ./...)
```
These suites include the maintained consumers. No new race, benchmark,
coverage threshold, platform matrix, or release gate is required.
2. Run root tests with `GOWORK=off GOTOOLCHAIN=local` and `-mod=readonly`.
For each integration, copy its committed `go.mod` and `go.sum` into a separate
temporary directory as `go.mod` and `go.sum`. With `go mod edit -modfile=...`,
add only replacements for unpublished CommandKit prerequisites: core for
ckconfig; core and ckconfig for ckprompt. Use absolute checkout paths. Do not
replace PromptKit/ConfigKit with sibling checkouts or tidy these copies to
make undeclared test dependencies pass.
3. From each integration's own directory, run its tests, module graph, and
production/test import enumeration with that prepared module file:
```sh
GOWORK=off GOTOOLCHAIN=local go test -mod=readonly -modfile=<temporary-go.mod> ./...
GOWORK=off GOTOOLCHAIN=local go list -mod=readonly -modfile=<temporary-go.mod> -m all
GOWORK=off GOTOOLCHAIN=local go list -mod=readonly -modfile=<temporary-go.mod> -deps -test ./...
```
Also enumerate root graph/imports with workspace disabled. Verify temporary
module/sum bytes remain unchanged during the readonly checks, after the
intentional replacements. If a check reveals a genuine distributed-metadata
problem, fix and explain it in the owning module, then repeat the relevant
checks; never hide it with extra temporary requirements or fabricated sums.
4. Confirm ckprompt still selects PromptKit v0.14.0 and ConfigKit v0.7.1,
ckconfig acquires no ckprompt/PromptKit dependency, and core acquires no optional
integration or owning-library dependency through production/tests/examples/
tools. Disposable replacements establish compatibility with local prerequisite
sources, not availability of future CommandKit tags. Retain workspace files
and temporary graph artifacts outside the tracked distribution.
5. Exercise both requirements example commands alongside representative existing
catalog, named inspection, config diff, and session restore commands. Use
semantic report assertions and the existing example fixtures. Reuse unchanged
successful checks from preceding stages where they apply to the final state.
6. Audit the roadmap target against code, coverage, examples, and canonical docs.
Check changed-document links/fragments and staged/unstaged whitespace with
the developer guide's commands. Record environmental limits as pending checks
rather than declaring them successful.
7. Record final evidence here and update the feature roadmap's status to reflect
actual delivery. Stage only this sprint's intended files, review the final
diff, and commit the last nonempty unit. Report remaining worktree changes
accurately. Do not push, tag, publish, or delete the planning documents as an
implicit part of implementation.
**Completed:** The root, ckconfig, and ckprompt workspace suites all passed
with `GOTOOLCHAIN=local go test ./...` from each module, including the maintained
consumers. Root tests and root module/import enumeration passed with
`GOWORK=off GOTOOLCHAIN=local` and `-mod=readonly`. Isolated ckconfig and
ckprompt checks passed using copies of their committed module files and only
the prescribed local CommandKit prerequisite replacements; for each, readonly
tests, `go list -m all`, and `go list -deps -test ./...` passed, and the copied
`go.mod`/`go.sum` hashes remained unchanged. The graphs confirm PromptKit
v0.14.0 and ConfigKit v0.7.1 for ckprompt, no PromptKit/ckprompt dependency in
ckconfig, and no optional integration or owning-library imports in core. The
ignored `go.work` remains untracked and distributed module files are unchanged.
Both requirements commands, prompt catalog, named prompt and profile
inspections, app config diff, and session restore succeeded from the composed
example. Existing semantic tests verify partial and complete report contents.
Changed-document local links/fragments and staged/unstaged whitespace checks
passed. No required check remains pending and no material limitations were
encountered.
**Completion criteria**
- Independent requirements capability, optional groups, complete absence, and
retained wiring errors follow the existing installation contracts.
- Native discovery context reaches the selected callback/engine accurately;
variable parsing and selected input/state lifecycle match the accepted roadmap.
- YAML retains the native evidence and metadata presence; partial inspection is
successful when acquisition and delivery succeed.
- Actual failures preserve diagnostics, supported error identity, and established
outcome/delivery handling without a readiness checker or extra domain rules.
- The composed consumer and canonical documentation demonstrate the implemented
behavior. Relevant module and isolated dependency/import checks pass, or any
uncompleted required check is explicitly reported as pending.
- No new owning-library dependency appears in core or in the reverse integration
direction, and no local workspace/replacements enter distributed metadata.
All product and API decisions required for this plan are settled. Private helper
names and equivalent implementation organization remain ordinary coding choices.

View File

@@ -1,160 +0,0 @@
# PromptKit requirements inspection review
Status: all three findings completed. This document records review and remediation
evidence; production behavior and selected contracts are unchanged.
## Review scope and authority
Reviewed the requirements-inspection implementation from planning baseline
[`3935dcd`](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/3935dcd)
through implemented state
[`cfc2d1d`](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/cfc2d1dfd0c17c35ffe0d0a1a46f4dc2df8be5bb).
The review compared production changes, tests, examples, and documentation with
the accepted [feature roadmap](requirements.md), completed
[implementation plan](implementation.md), and applicable
[architecture](../policy/architecture.md),
[documentation](../policy/documentation.md), and
[testing](../policy/testing.md) policies.
The targeted runtime architecture is present: the optional ckprompt suite owns
requirements registration, selection, coordination, and YAML presentation;
its engine adapter delegates discovery to PromptKit's public API. Core and
ckconfig retain their existing responsibilities and dependency boundaries.
No production defect or additional domain restriction was identified in this
review. The findings concern canonical documentation and one test that constrains
presentation beyond the selected contract.
## R-1: Correct singleton wording for requirements flags
Status: completed. Priority: normal. Category: documentation contract.
**Evidence:** [CLI reference](../cli.md), lines 418–420, says that the built-in
flags are singleton bindings and that the last value is used when repeated.
The same section lists `--var` as repeatable. In
[command.go](../../integrations/ckprompt/command.go), `newRequirementsCommand`
uses `RepeatFlag` for variables and builds the map from every occurrence, with
last-value replacement only for repeated keys.
The unqualified singleton statement contradicts the implemented and accepted
behavior. For example, `--var audience=internal --var mode=full` retains both
keys; the second occurrence does not replace the entire variable context.
**Required work:** qualify the singleton description to exclude `--var`, or
identify the singleton flags explicitly. Retain the existing explanation that
variable occurrences accumulate and only duplicate keys use the last value.
Suite selectors continue to follow their declared bindings. No parser or handler
change is required.
**Completion evidence:** the CLI reference gives consistent repetition rules in
its flag table and prose. Check the wording against the existing assignment and
singleton coverage; new generic parser tests are unnecessary.
**Completed:** Qualified the CLI singleton statement to exclude `--var`, retaining
the existing per-key replacement and selector-binding descriptions. Reviewed the
wording against `newRequirementsCommand` and the existing request/assignment
coverage. Local links/fragments and `git diff --check` passed. No parser, handler,
or test changes were needed.
## R-2: Complete the canonical requirements YAML schema
Status: completed. Priority: normal. Category: incomplete documentation delivery.
**Evidence:** [CLI reference](../cli.md), lines 428–451, describes the report
shape but illustrates `variables: []` without defining variable-entry fields
anywhere in the requirements section. The implemented
`requirementVariableReport` in
[command.go](../../integrations/ckprompt/command.go) emits `name`, `kind`,
`supplied`, and `explanation`. Those fields were selected by the feature roadmap
and are covered by `TestRequirementsReportPreservesNativeFieldsAndMetadata` in
[command_test.go](../../integrations/ckprompt/command_test.go).
Operators and automated consumers cannot obtain the complete CommandKit YAML
schema from its canonical owner. PromptKit's Go API defines native meanings,
but it does not define CommandKit's YAML field names. The missing fields should
remain documented after temporary planning records are retired.
**Required work:** add a representative variable entry to the CLI example or
provide a compact field inventory for the full report. Define the existing
`supplied` field as native exact-key presence, including an explicitly empty
value, independently of `kind` and `complete`. Keep explanations as upstream
human-readable evidence rather than text to parse.
Use a coherent partial-discovery example if retaining the illustrated
`missing_variable` issue for `mode`: include its variable entry as native
inspection does. Preserve all already selected fields, false values, empty
sequences, and nullable metadata semantics. Do not change the report or add
new disclosure, completeness, or readiness guarantees.
**Completion evidence:** all selected report fields are documented in the CLI
owner, and the example matches the existing native/consumer evidence. Review
local links and document whitespace. Production serialization and test fixtures
need no changes to repair this omission.
**Completed:** Documented all four variable-entry fields and native exact-key
presence independently of classification/completeness. The partial-report example
now includes the unsupplied `mode` entry and upstream human-readable summaries.
Reviewed all example fields against the private report types and existing native
and report coverage; a field-inventory check, local links/fragments, and
`git diff --check` passed. Production serialization and fixtures are unchanged.
## R-3: Remove an incidental YAML key-order requirement from a test
Status: completed. Priority: low. Category: inadvertently strengthened test contract.
**Evidence:** `TestRequirementsCommandCapturesContextAndVariableAssignments` in
[command_test.go](../../integrations/ckprompt/command_test.go), lines 190–192,
uses `strings.HasPrefix(output.String(), "prompt_id:")` to establish that an
omitted format defaults to YAML.
That check also requires `prompt_id` to be the first serialized mapping key and
excludes an otherwise valid YAML document-start marker. Neither presentation
detail was selected by the user. A semantic-equivalent report would fail this
test, contrary to the implementation plan's instruction to avoid incidental
key-order assertions and the testing policy's behavior-focused approach.
**Required work:** replace the prefix assertion with YAML decoding of the second
invocation's output and an assertion on the relevant semantic fields, such as
the selected prompt identity. Retain the existing success, fresh input/state,
and empty discovery-context assertions. Do not add a new key-order guarantee to
the CLI documentation to justify the current test.
**Completion evidence:** the test proves default YAML output without constraining
mapping-key order or document-marker style. Run the affected requirements test
and owning module suite after changing the assertion.
**Completed:** Replaced the prefix assertion with decoding into a fresh YAML map
and checking the selected prompt identity. Existing success, invocation lifecycle,
and empty-context assertions remain intact. `gofmt` and `git diff --check` passed.
From `integrations/ckprompt`, both
`GOTOOLCHAIN=local go test -count=1 -run '^TestRequirementsCommandCapturesContextAndVariableAssignments$' .`
and `GOTOOLCHAIN=local go test -count=1 ./...` passed, including the composed
consumer. The test no longer requires a mapping-key order or document-marker style.
## Review validation
At reviewed commit `cfc2d1d`, on Go 1.26.8:
- All three workspace module suites passed with `GOTOOLCHAIN=local go test ./...`
from their respective module directories.
- Fresh root tests passed with `GOWORK=off GOTOOLCHAIN=local`, `-mod=readonly`,
and `-count=1`. Root module and production/test import enumeration confirmed
no optional integration or owning-library dependency.
- Fresh ckconfig and ckprompt suites, module graphs, and production/test import
enumeration passed with workspace disabled and readonly disposable copies of
committed module/sum files. Only unpublished CommandKit prerequisites were
replaced with local sources. Temporary metadata hashes remained unchanged
during validation, and distributed manifests were not edited.
- The isolated ckprompt graph selects PromptKit v0.14.0 and ConfigKit v0.7.1;
ckconfig has no ckprompt or PromptKit dependency. Local prerequisite
replacements establish source compatibility, not future tag availability.
- Composed requirements invocations produced the expected partial and complete
inventories with status `0`. The complete report still contained an unsupplied
required variable, consistent with native discovery semantics.
- Changed Markdown local links/fragments and commit-range whitespace checks
passed. No tests or production code were added or changed for this review.
PromptKit v0.14.0's known lack of a public fixture path for successful engine
configuration warnings remains a validation limitation, not a new implementation
gap. Existing custom-callback coverage exercises command diagnostic handling.
Those review-time checks preceded remediation; completion evidence is recorded
under each finding above.

View File

@@ -1,339 +0,0 @@
# PromptKit requirements inspection
Status: implemented in CommandKit. Command
placement, public API, caller-variable syntax, and initial presentation are
settled and delivered. The implementation plan records completion evidence.
The [implementation plan](implementation.md) owns the ordered delivery steps and
stage completion evidence.
## Purpose and authority
Expose PromptKit's prompt requirements inspection through the optional ckprompt
integration. An operator should be able to select a prompt, supply discovery
context, and inspect the resulting input and caller-variable inventory before
input artifacts exist.
The governing principle is: **CommandKit provides useful, consistent access to
capabilities owned elsewhere.** PromptKit owns requirement discovery and the
meaning of its results. CommandKit owns command vocabulary, registration,
selection, coordination, presentation, and invocation outcomes.
The [architecture policy](../policy/architecture.md),
[standard inspection decision](../adr/0004-standard-inspection-surface.md),
[outcome decision](../adr/0005-invocation-outcomes.md),
[module boundary decision](../adr/0010-optional-integration-modules.md), and
[declaration and input decision](../adr/0011-captured-declarations-and-installation.md)
control this work. This roadmap selects an additional PromptKit operation within
the established architecture. ADR 0004 remains unchanged; the command spelling
and report belong in this roadmap until their canonical documentation is updated
with implementation.
PromptKit's adopted public
[requirements API](https://gitea.maximumdirect.net/eric/promptkit/src/commit/143c6e9b3a675872117b0471e2ff8bcb25055a54/requirements.go)
is the authority for discovery semantics. Descriptions below explain how
CommandKit will expose that API, rather than establishing a separate discovery
specification.
## Baseline at roadmap acceptance
This table records the pre-implementation state at CommandKit commit
[`12b52b3`](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/12b52b3174545d22960c91c3a782a151ab813447).
| Area | State then | Gap the roadmap addressed |
| --- | --- | --- |
| Dependencies | ckprompt already adopts PromptKit v0.14.0, ConfigKit v0.7.1, and YAML v4. Modules require Go 1.26.0. | No dependency or toolchain upgrade is needed for this capability. |
| Native capability | PromptKit exposes `Engine.InspectRequirements`, its request, and its structured result. | Adapt this existing public API. |
| Public integration | The accepted baseline had optional prompt/profile inspection and prompt/profile catalog callbacks. | Add an independently optional requirements callback and its engine adapter. |
| Command assembly | The accepted baseline installed available `show` and `list` operations beneath the owned `promptkit` namespace. | Assemble the requirements operation from its own capability. |
| Invocation infrastructure | Typed selectors, configuration selection, input checks, shared state, diagnostics, and buffered report delivery already exist. | Apply those paths to the new operation. |
| Presentation | Named prompt/profile reports support text and YAML; catalogs use YAML only. | Define a requirements report with the native evidence and discovery context identities. |
The former deferral is retained as an
[immutable historical record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/ee038df530bfd3518906dc77e8e8f55eef237dda/docs/roadmap/deferred.md).
This roadmap takes the capability up for delivery. Existing configuration,
catalog, and named definition operations are not prerequisites for requirements
inspection.
## Target ownership and package boundaries
| Owner | Responsibility |
| --- | --- |
| PromptKit | Prompt/profile/version selection semantics, context interpretation, discovery, classifications, completeness, structured issues, disclosure rules, and native errors. |
| `integrations/ckprompt` | The optional callback, request adaptation, command declaration, engine adapter, requirements report, and integration-specific outcome coordination. |
| `integrations/ckconfig` | Existing configuration selection and reusable configuration adaptation paths consumed by ckprompt. |
| CommandKit core | Captured declarations, bindings, parsing, installation, dispatch, help, diagnostics, and outcomes. |
| Consuming application | Engine acquisition, application selectors and checks, runtime state, custom providers, and any application-owned effects. |
Keep the dependency direction `ckprompt → ckconfig → core`, with ckprompt also
using core and PromptKit directly. This feature belongs in ckprompt; it does not
require PromptKit types in core, a reverse ckconfig dependency, or a new module.
Use the existing public facade and internal backend boundary.
## Target operator surface
Selected operation:
```sh
app promptkit requirements show PROMPT_ID
app promptkit requirements show briefing --version 2 --profile editorial --var audience=internal --var language=en
app promptkit requirements show briefing --session-id session-42 --var note= --format yaml
```
The `requirements` resource namespace follows the resource-first pattern of
`config show` and gives future requirements operations a location without
selecting them for this delivery.
The operation displays requirements for one selected prompt context. It accepts
the existing singleton configuration selection flags (`--config` and
`--overlay`) and the suite's application selectors. Repeated occurrences of
either singleton use the last value; overlays do not accumulate. Its namespace
already identifies PromptKit; an additional configuration `--scope` selector is
not needed.
| Input | Meaning |
| --- | --- |
| `PROMPT_ID` | One required prompt identifier, passed to PromptKit with its exact spelling. |
| `--version VERSION` | An exact prompt version; omission uses PromptKit's native selection rule. |
| `--profile PROFILE_ID` | A profile identity; omission uses the selected prompt's default under the native API. |
| Repeatable `--var KEY=VALUE` | Caller-variable discovery context, including explicitly empty string values. |
| `--session-id SESSION_ID` | Session context passed to PromptKit for its native normalization and discovery behavior. |
| `--format yaml` | Explicit selection of the initial report format, also the default. |
The existing grammar and binding contracts apply. CommandKit should not add
independent prompt/profile lookup rules, infer a profile from the catalog, or
reinterpret native session validity. Parse the new CLI representation, then
delegate domain interpretation to PromptKit.
### Caller-variable syntax
Use repeatable `--var KEY=VALUE`, splitting each assignment at the first `=` and
preserving the exact key and remaining value. A missing separator is a usage
error. Repeated keys use the last supplied value, consistent with the existing
singleton override convention. Every occurrence is parsed, so a later valid
assignment does not erase an earlier malformed one.
| Invocation fragment | Result |
| --- | --- |
| `--var note=` | Key `note` is supplied with an empty string value. |
| `--var token=a=b` | Key `token` has value `a=b`. |
| `--var =value` | The empty key has value `value`. |
| `--var mode=brief --var mode=full` | Key `mode` has value `full`. |
| `--var 'note=hello, world'` | Key `note` has value `hello, world`. |
| `--var broken --var mode=full` | Usage error because `broken` has no separator. |
Preserve whitespace and commas literally after shell processing. Do not normalize
keys or impose an identifier whitelist beyond the native string-map contract.
Variable-context files can be considered later if inline assignments prove
insufficient; file acquisition and override precedence are outside this delivery.
## Native meaning and invocation outcomes
Return the native input and variable inventories, including optional and
conditional entries. Carry selected identities, metadata presence,
classifications, completeness, explanations, and structured issues into the
report. Preserve the returned inventories and issues without introducing a
second analyzer, filtering out partial evidence, or interpreting explanation
strings as machine-readable rules.
`Complete` describes discovery coverage. It does not mean that dependencies are
supplied, artifacts are valid, templates will render, or execution is ready.
A complete inspection can contain an unsupplied required variable. An incomplete
inspection can still provide a useful inventory. The command's documentation
should explain this distinction and link to the adopted PromptKit contract.
For a successfully acquired and delivered inspection, return success (status
`0`), including when `Complete` is false or structured issues are present.
Discovery issues are report data; they do not independently become fatal
CommandKit diagnostics. Existing acquisition diagnostics and diagnostic delivery
rules still apply.
Apply the established outcomes to actual failures:
- CLI syntax, operand, format, and variable-assignment parsing failures are usage
failures (status `2`).
- Engine acquisition, native selection or inspection, cancellation, and report
delivery failures use the existing operational paths (status `1`), preserving
supported public error identity. Input checks and application-supplied
classifications retain their existing handling.
- A provider that returns no inspection and no error is a provider failure,
consistent with existing named inspection handling.
The default adapter calls the native inspection API. It does not add request
preparation, artifact loading, template rendering, execution, credential probes,
or a separate readiness verdict. These are limits of the selected standard
operation, not new restrictions on application loaders or custom callbacks.
PromptKit does not return supplied variable values as a separate inventory of
values. A resolved input identifier can nevertheless equal a supplied value and
is intentionally included. Preserve the adopted disclosure contract; do not
invent blanket masking or a guarantee that application content can never appear
in output.
## Target public integration and lifecycle
Add this request type in ckprompt:
```go
type RequirementsRequest struct {
Selection ckconfig.Selection
Inspection promptkit.RequirementInspectionRequest
}
```
Extend `Suite[I, S]` with this optional callback field:
```go
InspectRequirements func(
context.Context, RequirementsRequest, I, S,
) (commandkit.Acquired[*promptkit.RequirementInspection], error)
```
The callback receives invocation context, configuration selection and native
discovery context, selected application input `I`, and shared state `S`. Reusing
the owning library's public request avoids duplicating its domain model and
keeps forwarding and future adoption straightforward.
Configuration and application-selector presence retain their existing contracts;
variable presence is represented by exact map keys. Native version/profile/session
string fields use their native empty-value semantics, so this representation
does not distinguish omission from explicit empty for those fields.
`FromEngine` supplies this callback using the same loader and diagnostics
adaptation as its existing inspection callbacks, followed by
`Engine.InspectRequirements`. Applications can clear, wrap, or replace it using
ordinary suite composition. No additional registration mechanism is needed.
When only this callback is present, `ckprompt.Command` installs a usable
`promptkit requirements show` command without empty catalog or named-definition
groups. A nil requirements callback omits its operation without disabling the
others. When every callback is absent, retain the existing absent-family
behavior and attached wiring errors. Namespace ownership continues to follow
actual installation.
Apply captured selector metadata and the existing preparation lifecycle: prepare
one application input, apply applicable selectors, finish preflight and input
checks, then initialize shared state and invoke the selected provider. Omitted
factories retain zero-value behavior. Construction, installation, help, and
version leave factories and acquisition callbacks uninvoked, as required by the
existing contracts.
Keep parsed variable storage local to the invocation. Do not introduce arbitrary
deep-copy promises for caller input/state or inspection results. Reuse existing
diagnostic ownership and buffered report delivery, including cancellation checks
and incomplete-delivery reporting, without claiming rollback of written bytes or
interruption of a blocking writer.
## Initial report
Use YAML only initially, defaulting to YAML and accepting `--format yaml`
explicitly. YAML expresses partial inventories, metadata presence, and structured
issues readably and supports automation. Additional formats can follow operator
needs. Define a CommandKit-owned report representation with these fields:
| Report area | Fields |
| --- | --- |
| Selected context and coverage | `prompt_id`, `prompt_version`, `profile_id`, `complete` |
| `inputs` entries | `name`, `kind`, `declared`, `content_type`, `description`, `explanation` |
| `variables` entries | `name`, `kind`, `supplied`, `explanation` |
| `issues` entries | `code`, `input_name`, `variable_name`, `description` |
Include false boolean values and represent empty inventories as sequences
(`[]`). For nullable input metadata, preserve the distinction available from
PromptKit: nil becomes YAML null, while an explicitly empty string remains
`""`. Do not attempt to distinguish absent metadata from an explicit upstream
null when the native API does not distinguish them. Preserve native kind and
issue-code values rather than rejecting future values solely because they are
not in today's set.
Illustrative shape, showing that complete discovery can still identify an
unsupplied variable:
```yaml
prompt_id: briefing
prompt_version: "2"
profile_id: editorial
complete: true
inputs: []
variables:
- name: audience
kind: required
supplied: false
explanation: ""
issues: []
```
For a prompt with the captured template
`{{if .mode}}{{input "notes"}}{{end}}`, no input declarations, and profile
`editorial`, omitting `mode` produces a useful partial inventory under the
adopted native API. Its initial YAML presentation is illustrated here:
```yaml
prompt_id: briefing
prompt_version: "2"
profile_id: editorial
complete: false
inputs:
- name: notes
kind: conditional
declared: false
content_type: null
description: null
explanation: This reference is not known to be reached on every execution path.
variables:
- name: mode
kind: required
supplied: false
explanation: ""
issues:
- code: missing_variable
input_name: ""
variable_name: mode
description: A missing variable prevents selecting a dependency-bearing branch.
```
For that same prompt, supplying `--var mode=full` lets native discovery select
the branch: `notes` becomes required, `mode` is supplied, discovery is complete,
and the issues sequence is empty. Both successfully delivered inspections return
status `0`. The human-readable explanation and description above illustrate the
adopted upstream output; their wording remains upstream-owned.
Structured discovery issues stay in this report. Engine acquisition diagnostics
continue through the diagnostic stream. The implemented CLI reference will own
the final schema; these examples do not define PromptKit discovery behavior.
## Delivery and documentation targets
The [implementation plan](implementation.md) defines adaptation, command
assembly, presentation, validation, and documentation work from the baseline.
The maintained composed consumer should demonstrate a partial inventory and how
supplying discovery context changes it, with both delivered reports returning
status `0`. Focused native and boundary coverage should substantiate the selected
contracts without duplicating upstream's full analysis suite or adding new
validation infrastructure, performance guarantees, or release gates.
At delivery, ckprompt GoDoc, the CLI reference, consumer guidance, and relevant
internal summaries describe the implemented capability under their existing
ownership rules. The deferred-work record reflects its actual status. The new
operation fits the existing ownership and registration boundaries and requires
no new ADR; ADR 0004 remains unchanged. Command spelling and report/API details
belong with their canonical owners when implemented.
Release documentation and module version selection follow the existing release
procedure when a release is prepared. No upstream release, dependency bump,
publication, or consumer migration is required by this roadmap.
## Completion boundary
The target is reached when an application can independently enable the new
operation, select native discovery context, and receive the requirements report
with the established lifecycle, diagnostic, error, and delivery handling. The
maintained example and canonical documentation should demonstrate its purpose
and explain completeness accurately.
Initial delivery does not include a requirements assertion mode, execution
readiness checker, artifact binding workflow, or additional analysis beyond the
native API. Further capabilities can be considered for concrete needs; these
scope boundaries do not prohibit future extensions.
The decisions needed for an implementation plan are settled.