Files
commandkit/docs/roadmap/requirements.md

349 lines
19 KiB
Markdown
Raw Normal View History

2026-10-12 16:24:43 +00:00
# PromptKit requirements inspection
Status: proposed feature roadmap; no implementation in this document. The
recommended command placement reflects the user's preference. The remaining
API and presentation recommendations are identified under
[Open Decisions](#open-decisions).
## 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 proposes an additional PromptKit operation;
ADR 0004 does not already specify its command spelling.
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 would expose that API, rather than establishing a separate discovery
specification.
## Current baseline
Baseline: CommandKit commit
[`12b52b3`](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/12b52b3174545d22960c91c3a782a151ab813447).
| Area | Current implementation | Gap to target |
| --- | --- | --- |
| 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 | `Suite[I, S]` provides optional prompt/profile inspection and prompt/profile catalog callbacks. `FromEngine` supplies those four callbacks. | Add an independently optional requirements callback and its engine adapter. |
| Command assembly | `ckprompt.Command` installs 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 [deferred-work record](deferred.md#promptkit-requirement-inspection) records
this capability's prior deferral. This roadmap takes it up for planning;
the command remains unimplemented. Existing configuration, catalog, and named
definition operations are not prerequisites for enabling 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
Recommended 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 operation displays requirements for one selected prompt context. It accepts
the existing configuration selection flags (`--config` and repeatable
`--overlay`) and the suite's application selectors. Its namespace already
identifies PromptKit; an additional configuration `--scope` selector is not
needed.
| Proposed 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 recommended 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. The exact variable grammar and
report format remain recommendations in the decisions below.
## 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 proposed 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
Extend `Suite[I, S]` with an optional `InspectRequirements` callback returning
`commandkit.Acquired[*promptkit.RequirementInspection]` and an error. It receives
the invocation context, a requirements request, the selected application input
`I`, and shared state `S`. The recommended request representation is described
under OD-2.
`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.
## Recommended report
Use YAML only initially, with a CommandKit-owned report representation rather
than serialization that relies on incidental Go field names. Proposed 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: []
```
Structured discovery issues stay in this report. Engine acquisition diagnostics
continue through the diagnostic stream. The implemented CLI reference will own
the final schema; this example does not define PromptKit discovery behavior.
## Work needed from the baseline
### Public contracts and adaptation
Finalize the open API choices, extend the suite and its GoDoc, and adapt
`FromEngine` through the existing acquisition path. Preserve native errors and
diagnostics. Reuse ckconfig selection instead of adding parallel configuration
loading or asking providers to construct a CommandKit-specific discovery model.
### Command assembly and invocation
Add the optional requirements group and handler, bind the prompt operand and
discovery-context flags, and integrate selected input/state preparation. Update
the empty-suite check to include the new callback. Reuse captured declarations
and binding composition; introduce a helper only where the concrete reuse makes
the flow simpler.
### Presentation and delivery
Map the native result to the selected report representation and use the existing
buffered delivery and failure paths. Keep discovery limitations separate from
acquisition diagnostics and readiness claims.
### Validation evidence
During implementation, add focused coverage using real native inspection where
practical, together with boundary doubles for lifecycle and delivery failures.
Cover independently enabled and disabled capabilities, help without acquisition,
request forwarding, exact/empty variable presence, selected profile/version and
session context, complete and partial inventories, structured issues, nullable
metadata, native error identity, and invocation isolation. Exercise acquisition
diagnostics and writer failures through existing outcome paths.
Extend the maintained composed consumer with a useful requirements example and
fixtures. Validate the affected integration and composed example under the
repository's existing module/workspace procedures. Reuse established core and
configuration coverage; this feature does not justify new generic validation
infrastructure, performance guarantees, or release gates.
### Documentation and durable decisions
When implementation lands, update ckprompt GoDoc, the CLI reference, consumer
guidance, and relevant internal summaries under their existing ownership rules.
Reconcile the deferred-work entry with this feature's actual status. Assess
whether extending ADR 0004's recorded surface needs a focused new ADR; preserve
accepted decision content under the documentation policy rather than silently
editing it. Report/API details that evolve within the existing architecture can
remain with their canonical owners.
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.
## Open Decisions
### OD-1: Command placement
**Recommendation (user-selected):**
`app promptkit requirements show PROMPT_ID`.
This gives requirements an explicit resource namespace and follows the
resource-first pattern of `config show`. Future requirements operations have a
clear location without being selected by this roadmap.
**Alternative:** `app promptkit show requirements PROMPT_ID`.
This matches the existing `promptkit show prompt` and `show profile` layout and
keeps display operations together. Requirements would sit beneath a verb,
however, and later requirements verbs would need separate locations. The
recommended shape accepts the small vocabulary difference within PromptKit in
exchange for a coherent requirements resource.
### OD-2: Public request representation
**Recommendation:** introduce a small ckprompt request with
`Selection ckconfig.Selection` and
`Inspection promptkit.RequirementInspectionRequest`. This deliberately uses
the owning library's public request for domain context, avoids duplicating its
model, and makes 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.
**Alternative:** define CommandKit-owned request fields, using
`commandkit.Supplied[string]` for version, profile, and session ID, then translate
to the native request in `FromEngine`. This resembles existing `PromptRequest`
and lets custom providers distinguish omitted and explicitly empty flags.
It requires another maintained domain-context representation and conversion,
although native inspection currently treats those cases the same. Prefer it if
that distinction is useful to an actual custom-provider contract.
### OD-3: Caller-variable CLI representation
**Recommendation:** repeatable `--var KEY=VALUE`, splitting at the first `=` and
preserving the exact key and remaining value, including empty strings and
additional `=` characters. A missing separator is a usage error. Repeated keys
use the last supplied value, consistent with the suite's existing singleton
override convention. Do not add key normalization or an identifier whitelist
that the native caller map does not require. This is a small, transparent
representation of the native string map.
**Alternative:** accept a YAML variable-context file, potentially alongside
explicit flag overrides. Files are convenient for large or repeatedly used
contexts and reduce shell quoting. They add file acquisition, map/value
validation, and precedence decisions to this feature. They are a viable later
extension if inline variables prove insufficient; adding both now expands the
initial delivery without an established consumer need.
### OD-4: Initial report formats
**Recommendation:** YAML only, defaulting to YAML and accepting explicit
`--format yaml`, using the report representation above. YAML expresses partial
inventories, metadata presence, and structured issues readably and supports
automation. Existing catalog and comparison operations already use this format
policy, so the new operation need not duplicate presentation logic.
**Alternative:** text and YAML, with text as the default, matching existing
named prompt/profile display. A tailored text summary could be easier to scan
for large inventories. It requires an additional renderer and decisions about
which evidence to retain in that summary. Add it if operator experience shows a
clear benefit; the native structured result does not require it.