Record proposed CLI decisions and clarify CommandKit boundaries

This commit is contained in:
2026-10-06 23:36:06 +00:00
parent 6a0467148e
commit 84234275eb
15 changed files with 1243 additions and 331 deletions

View File

@@ -16,6 +16,12 @@ future work.
- Use namespace/resource first: `app config show` and `app promptkit show`.
Whether the first noun describes a resource or a library namespace does not
change the command grammar or its ownership boundary.
- Assemble families from declared capabilities. Each family defines its own
supported verbs; configuration scopes expose their available operations.
- Keep ordinary version output focused on the application. Explicit
`version --scope commandkit` reports embedded CommandKit identity.
- Govern CommandKit's own behavior and provider contracts. Shared loading and
callback organization are consumer guidance.
- Put PromptKit definition inspection under the single `promptkit` family.
CommandKit does not reserve the root `prompt` and `profile` names.
- Support `config show --scope all`, with the application configuration followed
@@ -39,11 +45,12 @@ provide configuration schemas, source acquisition, domain resolution, validation
build metadata, and PromptKit engine construction. These collaborators supply data
and perform domain work; they do not replace CommandKit's handlers or renderers.
An application's registration of a standard family adopts its complete contract.
It cannot redefine `config show`, add a private `config artifacts` operation, or
choose a different meaning for `config sources`. Domain reports belong outside
the reserved family. New shared operations become part of CommandKit through an
explicit standard change.
CommandKit assembles standard families from registered capabilities and preserves
its contracts for enabled operations. It rejects replacement standard handlers
and private operations under its reserved families. Each family defines its own
operation set; providers can supply supported subsets. Help and discovery expose
that availability. New shared operations enter through versioned library changes.
[ADR 0001](../adr/0001-command-dispatch-and-inputs.md) owns this decision.
Applications may register context selectors and typed configuration overrides
through the extension mechanism described in section 5. This is a defined input
@@ -100,7 +107,7 @@ CommandKit rather than relying on sibling checkout links.
## 3. Recommended command inventory
### Required core suite
### Standard configuration operation inventory
| Command | Operator question or task |
| --- | --- |
@@ -132,8 +139,9 @@ to applications.
**Recommendation:** use explicit resource operands after `list` and `show`.
Plural collection names select catalogs; singular names select one definition.
This keeps prompt IDs and execution profile IDs unambiguous even when they overlap.
Registering the suite reserves the complete `promptkit` family, supplies all four
operations, and registers the `promptkit` configuration scope.
Registration reserves the `promptkit` family and supplies handlers for its
declared definition capabilities. Its configuration scope is a separate capability;
definition operations and configuration inspection can be integrated independently.
Configuration inspection remains `config show --scope promptkit`; the definition
commands report metadata and resolved execution targets, not a second configuration
display path.
@@ -159,8 +167,8 @@ implementation dependency, not evidence against a useful command standard.
configuration with backend-completed execution settings and gives `config` an
unrelated resource vocabulary.
- **Include only the core suite initially.** A reasonable delivery phase. Keep
the PromptKit suite explicitly pending until its public APIs are available;
avoid independent replacement inspection commands in the applications.
individual PromptKit capabilities pending until their public APIs are available;
their absence leaves existing inspection capabilities available.
`run`, `execute`, `render`, `serve`, `session`, and artifact catalogs are not
CommandKit-owned commands in this proposal. Recommend `run` for a new application's
@@ -193,7 +201,8 @@ configuration check. An operator can request the combined inspection explicitly.
Help must state these defaults prominently.
`config scopes` lists scope ID, description, and whether it is the default for
inspection. It uses registration metadata, so it works when files are missing or
inspection, together with supported operations. It uses registration metadata,
so it works when files are missing or
configuration is invalid. List `app` first, `promptkit` second when registered,
then additional scopes sorted by ID; use this same order for `show --scope all`.
It accepts `--format text|yaml` and no loading selectors. Unsupported scope names
@@ -201,11 +210,17 @@ are usage errors, with the
available names in the diagnostic; there is no fallback to `app`.
Scopes use stable semantic names rather than executable names such as `notarius`.
Applications may register additional independently meaningful configuration scopes
through the same complete contract. A scope must supply an effective snapshot,
sources, explanations, and comparison support; a custom formatted report does not
qualify as a scope. Scope dependencies must be explicit, and one invocation must
reuse already loaded dependencies rather than reread them unnecessarily.
Additional independently meaningful configuration scopes declare their supported
inspection operations and applicable providers. CommandKit validates declared
wiring and coordinates explicit dependencies, reusing compatible provider results
within an invocation. Scope inventory and help report the supported operations.
An unsupported scope-operation selection receives a usage diagnostic before
acquisition. `all` retains its all-scope meaning and checks coverage for the
requested operation. [ADR 0009](../adr/0009-configuration-scopes.md) owns the model.
A configuration scope targets configuration, while a command family targets its
own resources. A future FeedKit family could supply `list` and `show`; FeedKit
configuration inspection could separately register a configuration scope.
**Alternatives:**
@@ -219,17 +234,19 @@ reuse already loaded dependencies rather than reread them unnecessarily.
in one document, but requires additional presentation work and indentation of
the native reports. The accepted initial approach keeps separate native YAML
documents; its output and ordering contract are defined below.
- **Permit partial scopes with different operations.** Accommodates legacy
implementations, but makes `config` behave differently across applications.
Adapt or improve the inspection provider instead.
- **Require every inspection operation per scope.** Gives a uniform inventory.
A missing upstream operation then blocks useful existing capabilities. The
selected approach exposes operation availability explicitly.
## 5. Shared inputs and command syntax
### Configuration selection and overrides
**Recommendation:** every loading configuration operation accepts `--config PATH`,
`--overlay NAME`, and `--scope NAME`. These have the same meanings for validation,
display, source inventory, explanation, and comparison.
**Recommendation:** register selection inputs according to provider applicability.
`--scope NAME` selects the configuration. Providers using an application root
accept `--config PATH`; ConfigKit overlay integrations accept `--overlay NAME`.
These names retain the same meanings wherever applicable. Additional source models
can declare their own selectors through the standard input extension mechanism.
`--config` selects the application root configuration even for `promptkit` scope;
the application constructs the selected framework inputs from that root and its
@@ -238,12 +255,12 @@ missing or invalid file is a load failure and never triggers discovery fallback.
Relative CLI paths use the invocation working directory. File-relative resources
retain the owning library's source-context semantics.
When `--config` is omitted, use the application's registered discovery policy
identically across these commands and ordinary execution. CommandKit must not
hard-code a second search policy. Discovery order, environment-variable support,
default-only operation, and packaging paths must be visible in help. This proposes
a uniform selection interface; a universal filesystem discovery convention is a
separate decision because the applications have different deployment layouts.
When `--config` is omitted, CommandKit invokes the registered acquisition callback
with that absence preserved. It exposes supplied discovery, environment, and
default-only metadata in help. Sharing acquisition code with ordinary execution is
recommended consumer practice; execution loading and filesystem discovery remain
application choices. [ADR 0010](../adr/0010-configuration-selection.md) owns the
parsing and propagation contract.
`--overlay` always selects a configuration overlay, never a PromptKit execution
profile. Follow ConfigKit's naming and resolution semantics: omission, an empty
@@ -251,17 +268,18 @@ name, and the exact name `default` select the base; other names select one overl
An overlay name is not a file path. Replace `--config-overlay` with this standard
spelling rather than silently maintaining two conventions.
Applications register domain context selectors, such as Narratio's `--campaign`
and `--campaign-file`, and typed configuration overrides. CommandKit owns their
registration, parsing, help exposure, and propagation; applications own their
field mappings and domain checks. A selector must be offered on each operation
where it is meaningful, with the same meaning. Invalid combinations fail before
loading. Selectors that do not affect a chosen scope must be rejected rather than
silently ignored. Registration cannot shadow a standard flag.
The registration API accepts domain context selectors, such as Narratio's
`--campaign` and `--campaign-file`, and typed configuration overrides. CommandKit
parses them, exposes their declared applicability in help, and passes values to
the selected callback. Field mapping and domain checks remain callback behavior.
CommandKit validates declared combinations and applicability before loading and
reports collisions with standard flags. Shared selector names keep their defined
meaning on the operations where they are registered.
Preserve explicit flag presence. Omission, an empty string, false, zero, and null
are not interchangeable. Send configuration changes through ConfigKit's override
records and resolution mechanisms so effective output and provenance agree.
CommandKit preserves explicit flag presence. Omission, an empty string, false,
zero, and null retain their registered meanings. Using ConfigKit's recorded
overrides and domain resolution is recommended for coherent values and provenance;
CommandKit passes typed inputs to the registered integration callback.
Execution-only controls such as resume, output directories for generated artifacts,
or lane execution do not belong on generic configuration commands.
@@ -334,18 +352,19 @@ registered flag metadata, honor `--`, and correctly handle values beginning with
### `config validate`
**Recommendation:** validate all selected scopes completely through their owning
loaders. Include acquisition, composition, defaults, typed decoding, recorded
resolution, and domain configuration checks. PromptKit scope constructs the engine
and validates all effective definitions, including unused ones. Application scope
includes configured references and catalog relationships that can be checked
without executing a request.
**Recommendation:** invoke each selected scope's declared validation capability.
CommandKit checks support and coordinates required provider calls. The provider
implements acquisition, composition, defaults, decoding, and domain resolution
according to its public result contract. The PromptKit adapter requests upstream
configuration validation with all-definition coverage. Missing upstream support
is a dependency of that capability, rather than the entire integration.
[ADR 0008](../adr/0008-inspection-lifecycle.md) owns this boundary.
Validation does not execute a pipeline, prepare request-specific prompts, read
request inputs, contact a provider, or create runtime state. Do not add generic
pipeline or lane selectors to this operation. An application's operational
preflight, such as `session validate`, can perform additional context-dependent
checks outside the standard suite.
CommandKit's validation handler requests the declared configuration-validation
operation and writes its result. Request preparation, execution, and operational
preflight belong to custom domain handlers, such as `session validate`. Source
acquisition and effects inside callbacks remain provider behavior. Registered
input applicability determines the selectors used by standard validation.
Default text output is one concise success line identifying the validated scopes.
`--format yaml` returns a structured success report containing the scope IDs.
@@ -360,7 +379,8 @@ environment values, whereas PromptKit inspection does not itself resolve provide
credentials. Describe these requirements in scope help. Offline means no provider
or remote execution; it does not promise credential-independent loading. Existing
explicit credential-file bootstrap may run as part of acquisition, with its safe
report on stderr; it must not create durable application runtime state.
report through the supplied diagnostic channel. Callback effects and bootstrap
policy remain application-owned; focused acquisition is recommended practice.
**Alternatives:**
@@ -416,7 +436,8 @@ multiple documents. Comments are human labels, not parsed metadata; scope identi
for automated consumers follows the documented order. This is suitable YAML for
automation, but it is not one configuration document or a reloadable combined file.
Load and validate all selected scopes before starting output. A scope load failure
Check operation availability, acquire all selected views, and complete validation
required by their provider contracts before starting output. A scope load failure
returns `1` without a partial successful report. Writer failures can still leave
partial output. A broken PromptKit configuration can therefore prevent `--scope all`
from displaying otherwise usable application settings; `--scope app` remains
@@ -522,7 +543,8 @@ app config diff --config ./config.yml --overlay staging --against-overlay produc
app config diff --config ./old.yml --against-config ./new.yml --against-overlay default
```
Both sides must load and validate. Compare semantic effective values, including
For a scope declaring safe comparison support, acquire both views through the
registered provider's loading/validation contract. Compare effective values, including
defaults and recorded domain resolution, rather than YAML formatting, source IDs,
file order, or overlay names. Recursively compare mappings; keep sequences atomic,
preserving their order. Distinguish absence, null, empty mappings, and empty
@@ -615,8 +637,11 @@ raw `InspectProfile` results have native configuration redaction.
### Help
**Recommendation:** `app`, `app help`, `app --help`, and `app -h` print root help
and succeed. A family invoked without an operation, such as `app config`, prints
family help and succeeds. `app help config explain` and
and succeed. A command group with no execution handler, such as `app config`,
prints group help on bare invocation and succeeds. Runnable commands follow their
registered handler and operand requirements, including when they also have
subcommands. [ADR 0006](../adr/0006-command-grammar.md) records this distinction.
`app help config explain` and
`app config explain --help` print the same leaf help with status `0`.
Help never acquires configuration, constructs PromptKit, resolves credentials,
@@ -638,17 +663,21 @@ command or unknown flag valid.
### Version
**Recommendation:** `app version` prints `app VERSION` and a newline. Standardize
`app --version` as a root-only shortcut, rather than retaining it merely as a
Notarius compatibility alias. Neither form loads configuration. Recommend
`version --format yaml` with application name/version, optional revision and build
time, and the CommandKit standard revision implemented by the binary.
**Accepted:** `app version` prints `app VERSION` and a newline; root
`app --version` reports the same application identity. The version command defaults
to `--scope app`. `app version --scope commandkit` explicitly reports the embedded
CommandKit release version. `--format yaml` changes presentation of the selected
identity. Version subjects are separate from configuration scopes. CommandKit
uses build metadata with acquisition callbacks left uninvoked.
Future component identities can use registered version metadata.
[ADR 0004](../adr/0004-standard-inspection-surface.md) records version selection.
Applications supply build identity, with tagged Go build information usable when
available. An unversioned development build reports `dev`; unknown revision or
build time stays absent rather than being invented. The CLI standard revision is
distinct from application version and from the CommandKit module version. It
identifies observable command/report contracts, not application artifact formats.
build time stays absent rather than being invented. The CommandKit release version
identifies the library and its standard CLI contracts. Compatibility changes
follow the [release policy](../policy/release.md#versioning-and-compatibility).
**Alternatives:**
@@ -657,8 +686,13 @@ identifies observable command/report contracts, not application artifact formats
- **Emit all build and dependency information by default.** Helpful for debugging,
but unnecessarily verbose and unstable for a simple identity check. Structured
output should expose the selected fields.
- **Use the application version as the sole compatibility signal.** Insufficient
to distinguish independent CLI-standard and application-artifact changes.
- **List dependency versions alongside application version by default.** Adds
diagnostic detail to an identity check. Explicit subject selection keeps each
report focused.
- **Use a combined dependency-version option.** Useful for a broad inventory.
Scoped selection also supports querying one embedded component.
- **Add a separate integer CLI standard revision.** Rejected during ADR review.
The tagged CommandKit release version provides the shared compatibility identity.
## 9. Output, diagnostics, and failures
@@ -698,7 +732,7 @@ semantics rather than promising that every report is safe for public disclosure.
Default to stdout and shell redirection; do not initially add `--out` or `--output`
to standard reports. Ordinary writer failures may leave partial output and return
`1`; consumers must check status before decoding. This avoids adding filesystem
`1`; checking status before decoding is recommended caller practice. This avoids adding filesystem
creation, replacement, and retention behavior to inspection.
| Status | CommandKit-owned command meaning |
@@ -742,14 +776,14 @@ Existing public APIs already support native YAML, native explanation text,
structured explanation records, source records, and named definition inspection.
They do not yet provide everything recommended here:
| Needed capability | Implementation work before the complete standard can ship |
| Needed capability | Implementation work for that capability |
| --- | --- |
| Semantic diff | A safe structured effective snapshot from ConfigKit, preserving value semantics and per-path sensitivity; expose it through PromptKit inspection. This serves comparison rather than JSON output. |
| Combined configuration display | Compose native writers as labeled separate YAML documents after all selected scopes load; no new snapshot API is needed just to concatenate these reports. |
| Prompt/profile catalogs | Public PromptKit methods enumerating captured IDs and prompt versions without reparsing source YAML. |
| Safe rich profile reports | PromptKit-owned redacted inspection data for provider parameters. |
| Narratio's final application snapshot | Adapt its configuration boundary so campaign-derived effective values and provenance are recorded in the inspected result; avoid an unrelated typed-struct dump. |
| Full cross-scope validation | Application integration registering dependencies and offline configuration checks, with clear credential requirements. |
| Cross-scope validation | Registered validation capabilities and dependencies, with their actual acquisition and credential requirements exposed in help. |
Suggested sequence:
@@ -762,18 +796,19 @@ Suggested sequence:
display (including `show --scope all`), source inventory, and explanation using
existing APIs.
4. Integrate Scriptorium and Notarius to exercise both scopes and remove duplicated
handlers. Partial adoption remains development work, not conformance to the
complete proposed standard.
5. Add safe semantic comparison and the optional complete PromptKit definition
suite once the upstream APIs are released.
handlers. Register and report the supported capabilities; additional upstream
features can be integrated independently.
5. Add safe semantic comparison and additional PromptKit definition capabilities
as their upstream APIs are released.
6. Integrate Audita and Narratio, moving domain reports outside reserved families
and aligning their standard operations. Update consumer adapters and docs for
the intentional breaking releases.
A complete core adopter exposes every required core command for every registered
scope. A complete PromptKit-suite adopter additionally exposes all four definition
commands. Do not ship placeholder commands, claim unsupported formats, or silently
omit required operations.
CommandKit installs supported operations with their standard meanings and exposes
actual capabilities in help and scope metadata. Missing comparison or catalog
support leaves other operations available. Each family's resources determine its
supported verb set. Initial ConfigKit/PromptKit reports retain their chosen formats;
future families define suitable report contracts for their own resources.
Later implementation validation should exercise genuine contract risks: help with
invalid configuration, leaf flag placement and `--`, explicit empty/false/zero