From fa0cd9a73b7e683581b7bf750cd0ecaa3f2caf62 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Mon, 12 Oct 2026 16:24:43 +0000 Subject: [PATCH] Plan PromptKit requirements inspection --- docs/roadmap/requirements.md | 348 +++++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 docs/roadmap/requirements.md diff --git a/docs/roadmap/requirements.md b/docs/roadmap/requirements.md new file mode 100644 index 0000000..0678573 --- /dev/null +++ b/docs/roadmap/requirements.md @@ -0,0 +1,348 @@ +# 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.