Adopt shared policies and record CommandKit architecture
This commit is contained in:
819
docs/roadmap/01-cli-plan.md
Normal file
819
docs/roadmap/01-cli-plan.md
Normal file
@@ -0,0 +1,819 @@
|
||||
# CommandKit CLI standard proposal
|
||||
|
||||
Status: proposed; no commands in this document are implemented by CommandKit.
|
||||
|
||||
Date: 2026-10-06.
|
||||
|
||||
This proposal defines the command suite, operator behavior, and ownership boundary
|
||||
recommended for CommandKit. Audita, Narratio, Notarius, and Scriptorium provide
|
||||
evidence, rather than compatibility requirements. Adoption is expected to produce
|
||||
breaking changes. The decisions recorded below are accepted; other recommendations
|
||||
remain proposed. Implementation details and exact Go API declarations remain
|
||||
future work.
|
||||
|
||||
### Accepted planning decisions
|
||||
|
||||
- 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.
|
||||
- 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
|
||||
by the PromptKit configuration when registered, as separate YAML documents.
|
||||
- Defer JSON output from the initial implementation. YAML supports automated
|
||||
consumption as well as operator inspection; JSON may never be needed and is
|
||||
not a promised later milestone. JSON Pointer remains the configuration path
|
||||
syntax and is independent of report format.
|
||||
|
||||
## 1. Purpose and ownership
|
||||
|
||||
**Recommendation:** CommandKit owns the entire `config` command family, root help,
|
||||
and version reporting. It also offers the standard `promptkit` inspection family
|
||||
for applications that integrate PromptKit. Applications own commands
|
||||
outside these families, such as `narratio session restore`, `narratio publish`,
|
||||
`audita process`, and `scriptorium serve`.
|
||||
|
||||
Ownership includes command names, accepted flags and arguments, defaults, help,
|
||||
report shapes, diagnostic presentation, streams, and exit behavior. Applications
|
||||
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.
|
||||
|
||||
Applications may register context selectors and typed configuration overrides
|
||||
through the extension mechanism described in section 5. This is a defined input
|
||||
extension, not permission to alter standard operations or output.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Share helpers while applications own their handlers.** Easy to integrate,
|
||||
but permits the same naming, scope, and output drift that motivates CommandKit.
|
||||
- **Allow arbitrary subcommands beneath standard families.** Convenient initially,
|
||||
but makes the standard unpredictable and creates future name collisions.
|
||||
- **Own every command in every application.** Unnecessary for the stated goals;
|
||||
domain operations have responsibilities that a shared inspection library cannot
|
||||
usefully prescribe. CommandKit can supply common parsing and help machinery
|
||||
without owning their business semantics.
|
||||
|
||||
## 2. Evidence and conclusions
|
||||
|
||||
The current checkouts demonstrate both reuse opportunities and choices that need
|
||||
to be replaced rather than preserved.
|
||||
|
||||
| Evidence | Conclusion for the standard |
|
||||
| --- | --- |
|
||||
| Audita uses `config print-effective`; Notarius uses `config effective`; Narratio and Scriptorium use `config show`. | Select one verb: `show`. |
|
||||
| Audita combines settings, selected profiles, and provenance under `--view`; Notarius uses `--scope`; Scriptorium has a separate framework configuration family. | Separate the operation from the inspected configuration scope. |
|
||||
| Narratio's `config sources` reports field ownership; Scriptorium lists acquired source records. | Give source inventory and field explanation distinct contracts. |
|
||||
| Scriptorium's application and framework handlers repeat parsing, loading, warnings, dispatch, and output handling. | CommandKit should implement one inspection command family. |
|
||||
| Notarius and Scriptorium inspect named PromptKit profiles; Scriptorium also inspects prompts. | Definition inspection is another demonstrated shared capability. |
|
||||
| Narratio compares resolved overlays, rather than YAML file text. | Include semantic comparison of effective configuration. |
|
||||
| Help, flag placement, validation success output, and error statuses differ. | Specify those behaviors centrally. |
|
||||
| Narratio invokes the other applications and interprets Scriptorium's status `2` as output validation failure. | Breaking adoption requires coordinated consumer updates. |
|
||||
|
||||
Evidence sources, relative to this roadmap in the sibling workspace checkouts:
|
||||
|
||||
- [Audita CLI contract](../../../audita/docs/cli.md) and
|
||||
[configuration parsing](../../../audita/internal/cli/config_input.go).
|
||||
- [Narratio CLI contract](../../../narratio/docs/cli.md),
|
||||
[configuration inspection](../../../narratio/internal/app/config_commands.go),
|
||||
and [comparison](../../../narratio/internal/app/config_diff.go).
|
||||
- [Notarius CLI contract](../../../notarius/docs/cli.md) and
|
||||
[configuration commands](../../../notarius/internal/cli/configkit_commands.go).
|
||||
- [Scriptorium CLI contract](../../../scriptorium/docs/cli.md),
|
||||
[application inspection](../../../scriptorium/internal/adapter/cli/config.go),
|
||||
and [framework inspection](../../../scriptorium/internal/adapter/cli/framework_config.go).
|
||||
- [ConfigKit inspection API](../../../ConfigKit/inspection.go),
|
||||
[source records](../../../ConfigKit/records.go), and
|
||||
[configuration contract](../../../ConfigKit/docs/config.md).
|
||||
- [PromptKit configuration inspection](../../../promptkit/configuration_inspection.go)
|
||||
and [consumer guide](../../../promptkit/docs/consumers/pkg-promptkit.md).
|
||||
|
||||
These links document review evidence; they are not build dependencies. When the
|
||||
standard becomes implemented behavior, its durable reference should be owned by
|
||||
CommandKit rather than relying on sibling checkout links.
|
||||
|
||||
## 3. Recommended command inventory
|
||||
|
||||
### Required core suite
|
||||
|
||||
| Command | Operator question or task |
|
||||
| --- | --- |
|
||||
| `app help [COMMAND ...]` | How do I use this command? |
|
||||
| `app version` | Which application build am I running? |
|
||||
| `app config scopes` | Which configuration scopes can I inspect? |
|
||||
| `app config validate` | Is the selected configuration valid? |
|
||||
| `app config show [--scope app\|promptkit\|all]` | What effective configuration will the application use? |
|
||||
| `app config sources` | Which inputs contributed to this configuration? |
|
||||
| `app config explain --path POINTER` | Why does this path have this value, or why was it removed? |
|
||||
| `app config diff --against-config PATH` or `--against-overlay NAME` | How do two effective configurations differ? |
|
||||
|
||||
`app` is a placeholder for the application's executable name. Section 4 defines
|
||||
scope defaults; section 5 defines selectors shared by configuration operations.
|
||||
|
||||
### Optional PromptKit suite
|
||||
|
||||
| Command | Operator question or task |
|
||||
| --- | --- |
|
||||
| `app promptkit list prompts` | Which prompt IDs and versions are available? |
|
||||
| `app promptkit list profiles` | Which execution profiles are available? |
|
||||
| `app promptkit show prompt ID [--prompt-version VERSION]` | What is the selected prompt's definition metadata? |
|
||||
| `app promptkit show profile ID` | What execution target does this named profile resolve to? |
|
||||
|
||||
**Accepted:** put this suite under `promptkit`, using the same namespace/resource
|
||||
first pattern as `config`. The root names `prompt` and `profile` remain available
|
||||
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.
|
||||
Configuration inspection remains `config show --scope promptkit`; the definition
|
||||
commands report metadata and resolved execution targets, not a second configuration
|
||||
display path.
|
||||
|
||||
Definition catalogs require upstream API work; their absence today is an
|
||||
implementation dependency, not evidence against a useful command standard.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Bare `promptkit list`.** Could display a combined catalog with resource type,
|
||||
ID, and prompt version. Useful for discovery, but potentially noisy. An explicit
|
||||
resource gives each catalog a clear report shape; a combined listing can be
|
||||
considered as an additional operation later.
|
||||
- **`promptkit show ID --type profile`.** Explicit and compact, but places the
|
||||
resource identity partly in a flag. Prefer the resource operand.
|
||||
- **`promptkit show ID`.** Requires cross-collection lookup and ambiguity rules.
|
||||
Do not make inspection depend on prompt and profile IDs being globally unique.
|
||||
- **`promptkit profiles list/show`.** Retains the accepted namespace boundary and
|
||||
is viable, but adds another resource grouping before the operation. The proposed
|
||||
`promptkit list/show RESOURCE` layout puts the operation immediately after its
|
||||
owning namespace, as in `config show`.
|
||||
- **Put definitions under `config`, such as `config profile`.** Mixes source
|
||||
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.
|
||||
|
||||
`run`, `execute`, `render`, `serve`, `session`, and artifact catalogs are not
|
||||
CommandKit-owned commands in this proposal. Recommend `run` for a new application's
|
||||
principal execution operation, but retain application ownership of that choice.
|
||||
|
||||
## 4. Configuration scopes
|
||||
|
||||
**Recommendation:** use `--scope NAME` on configuration operations, with these
|
||||
standard identifiers:
|
||||
|
||||
- `app`: the application's effective configuration, including defaults,
|
||||
imports, the selected overlay, explicit overrides, and recorded domain
|
||||
resolution. Each application's configuration schema remains its own.
|
||||
- `promptkit`: the captured configuration of the PromptKit engine assembled
|
||||
from that application's selected inputs and registered assets, when integrated.
|
||||
- `all`: a selector available to `config validate` and `config show`, meaning every
|
||||
registered scope. It is not itself a configuration scope or a merged document.
|
||||
|
||||
`show`, `sources`, `explain`, and `diff` default to `app`. `validate` defaults to
|
||||
`all`: a bare validation command should establish that the configured application
|
||||
and its integrated framework definitions are valid. `--scope app` provides the
|
||||
explicit narrower check without constructing PromptKit. A non-PromptKit
|
||||
application's `all` selection consists only of `app`. `show --scope all` is an
|
||||
explicit request for a YAML stream of all selected scopes. `sources`, `explain`,
|
||||
and `diff` continue to select one scope and reject `all` in this proposal.
|
||||
|
||||
The differing default for validation is intentional: routine inspection starts
|
||||
with the application configuration, while general validation performs a complete
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Default every operation to `app`, requiring `validate --scope all`.** Very
|
||||
uniform syntax, but easy to mistake application-only validation for validation
|
||||
of all definitions needed by the application.
|
||||
- **Separate paths, such as `config promptkit show`.** Makes the scope visible in
|
||||
the command path; produces duplicated operation trees and complicates adding
|
||||
scopes. This remains a viable alternative if scope flags feel too indirect.
|
||||
- **A scope-keyed wrapper for `show --scope all`.** Scope identity survives parsing
|
||||
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.
|
||||
|
||||
## 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.
|
||||
|
||||
`--config` selects the application root configuration even for `promptkit` scope;
|
||||
the application constructs the selected framework inputs from that root and its
|
||||
other explicit selectors. A supplied empty path is a usage error. A supplied
|
||||
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.
|
||||
|
||||
`--overlay` always selects a configuration overlay, never a PromptKit execution
|
||||
profile. Follow ConfigKit's naming and resolution semantics: omission, an empty
|
||||
name, and the exact name `default` select the base; other names select one overlay.
|
||||
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.
|
||||
|
||||
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.
|
||||
Execution-only controls such as resume, output directories for generated artifacts,
|
||||
or lane execution do not belong on generic configuration commands.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Require `--config` on every operation.** Simple and explicit, but makes
|
||||
inspection use a different entry path from normal execution and limits
|
||||
defaults-only applications.
|
||||
- **Prescribe one global discovery sequence now.** Could improve consistency,
|
||||
but expands this command proposal into deployment and configuration discovery
|
||||
policy. Evaluate that separately rather than preserving current differences
|
||||
by assumption or inventing paths without deployment evidence.
|
||||
- **Only expose root, overlay, and scope flags.** Keeps the surface small but
|
||||
cannot inspect Narratio's resolved campaign contributions or explicit settings
|
||||
used by execution. A controlled registration mechanism is more effective.
|
||||
- **Offer a generic `--set path=value`.** Convenient for advanced operators, but
|
||||
requires a new value syntax and typing contract and makes overrides harder to
|
||||
discover. Defer until typed, documented flags prove insufficient.
|
||||
|
||||
### Flag placement and repeated flags
|
||||
|
||||
**Recommendation:** put the complete command path before its options; allow flags
|
||||
and operands to be interspersed within the selected leaf command. For example:
|
||||
|
||||
```sh
|
||||
app config show --config ./config.yml --scope promptkit
|
||||
app promptkit show profile team.summary --config ./config.yml
|
||||
app promptkit show profile --config ./config.yml team.summary
|
||||
```
|
||||
|
||||
Standard flags use `--long-name`; `-h` is the standard help shorthand. Accept
|
||||
`--name value` and `--name=value`; boolean false uses `--name=false`. `--` ends
|
||||
option parsing and makes subsequent tokens operands. Standard configuration
|
||||
operations reject positional operands; `promptkit list` accepts a collection name,
|
||||
and `promptkit show` accepts a resource name and its one documented ID. Flags may
|
||||
appear before or after these operands. `help` accepts command-path operands.
|
||||
|
||||
Singleton flags reject repeated occurrences, including mixed `--name value` and
|
||||
`--name=value` spellings. Repeatable source or domain flags combine in documented
|
||||
order. Do not infer singleton presence from its parsed value. Unknown flags are
|
||||
usage errors. New names use hyphens rather than underscores.
|
||||
|
||||
This is the contract for CommandKit-owned commands. Recommend the same grammar
|
||||
for application commands and supply reusable parsing machinery, while leaving
|
||||
their operand counts and domain rules application-owned.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Verb first, such as `app show config`.** Considered and not selected. It groups
|
||||
operations by action but spreads one namespace across root verb families and
|
||||
requires ownership at individual routes. Namespace/resource first gives each
|
||||
standard family a clear ownership boundary.
|
||||
- **Require flags before all operands.** Fits Go's `flag` parser directly but
|
||||
retains the ordering burden the user wants to remove.
|
||||
- **Allow common flags before or between command-path components.** Familiar
|
||||
in some command frameworks; increases command routing complexity. A single
|
||||
documented position after the complete path is sufficient initially.
|
||||
- **Let the last singleton occurrence win.** Convenient for argument assembly,
|
||||
but conceals conflicting operator instructions. Applications already have
|
||||
useful repeatable inputs; declare those explicitly instead.
|
||||
|
||||
Go's [standard flag parser](https://pkg.go.dev/flag#hdr-Command_line_flag_syntax)
|
||||
stops at the first operand; [pflag](https://github.com/spf13/pflag#command-line-flag-syntax)
|
||||
supports interspersed options. The accepted [backend decision](03-backend.md)
|
||||
selects Cobra with pflag for the initial implementation. Any required adaptation must use
|
||||
registered flag metadata, honor `--`, and correctly handle values beginning with
|
||||
`-`; do not replicate Notarius's hand-maintained flag-name lists in every consumer.
|
||||
|
||||
## 6. Configuration command contracts
|
||||
|
||||
### `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.
|
||||
|
||||
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.
|
||||
|
||||
Default text output is one concise success line identifying the validated scopes.
|
||||
`--format yaml` returns a structured success report containing the scope IDs.
|
||||
Warnings go to stderr and do not alone make configuration invalid. Failure emits
|
||||
no success report and returns status `1`. Complete each scope's dependency loading
|
||||
once; stop on a fatal loading failure rather than promising a report of every
|
||||
possible defect across invalid inputs.
|
||||
|
||||
Credential requirements follow the genuine configuration lifecycle: ConfigKit
|
||||
loads can resolve typed secret references and therefore require the referenced
|
||||
environment values, whereas PromptKit inspection does not itself resolve provider
|
||||
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.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Only check decoding/schema validity.** Useful as a distinct lower-level
|
||||
operation, but too weak for an unqualified application validation command.
|
||||
- **Validate only definitions selected by a planned run.** Audita provides useful
|
||||
evidence for selected-profile checks, but a generic configuration command should
|
||||
find invalid configured definitions before a later selection reaches them.
|
||||
- **Silent success.** Scriptorium demonstrates this and scripts can use the exit
|
||||
status. A short scope summary is clearer for interactive use; structured output
|
||||
supports automation without parsing prose.
|
||||
- **Skip secret resolution by default.** Valuable for inspection without runtime
|
||||
credentials, but requires an explicit upstream ConfigKit lifecycle design. Do
|
||||
not simulate credentials or bypass native validation to deliver it.
|
||||
|
||||
### `config show`
|
||||
|
||||
**Recommendation:** show the complete final effective configuration for the selected
|
||||
scope, or each registered scope when `--scope all` is supplied.
|
||||
Use the captured inspection snapshot, including recorded resolution, rather than
|
||||
raw file text, an application-selected subset, or a fresh marshal of mutable
|
||||
runtime structs. Loading necessarily performs the validation required to obtain
|
||||
a usable snapshot. Single-scope display loads only that scope and its dependencies;
|
||||
`all` loads every registered scope and reuses their shared dependencies.
|
||||
|
||||
Output is native redacted YAML without a status line. A single-scope report has no
|
||||
heading or document marker added by CommandKit. Preserve ConfigKit's distinction
|
||||
between null, empty containers, and absent values, its
|
||||
stable mapping order, and sequence order. This is an inspection document, not a
|
||||
guaranteed reloadable configuration file.
|
||||
|
||||
**Accepted:** `--scope all` writes the application configuration followed by the
|
||||
PromptKit configuration when registered, then any additional scopes in the order
|
||||
reported by `config scopes`. Each scope is a separate document, introduced by
|
||||
`---` and a `# scope: NAME` comment. CommandKit adds those separators and labels
|
||||
around the native writer output without merging mappings or serializing runtime
|
||||
structs. Even a one-scope `all` report uses this labeled document form.
|
||||
|
||||
```yaml
|
||||
---
|
||||
# scope: app
|
||||
server:
|
||||
addr: localhost:8080
|
||||
---
|
||||
# scope: promptkit
|
||||
profiles: {}
|
||||
```
|
||||
|
||||
The stream provides a complete inspection in one invocation, preserves native
|
||||
rendering and redaction, and avoids collisions between scopes' mapping keys.
|
||||
Its tradeoffs are larger output and the need for automated consumers to decode
|
||||
multiple documents. Comments are human labels, not parsed metadata; scope identity
|
||||
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
|
||||
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
|
||||
available for that narrower inspection.
|
||||
|
||||
`config show` has one initial report format, YAML, and does not need a `--format`
|
||||
selector. JSON is deferred without a delivery commitment. The combined display
|
||||
uses existing native writers and does not require a new structured effective
|
||||
snapshot API solely for formatting.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **A scope-keyed single YAML document.** Scope names become machine-readable keys,
|
||||
but the renderer must wrap and indent each native document. This could replace
|
||||
comment/order identification if consumers need scope identity in parsed data.
|
||||
- **Emit each scope as soon as it loads.** Reduces waiting before output, but a
|
||||
later load failure would leave an incomplete combined report. Prefer loading
|
||||
all scopes first.
|
||||
- **Raw composed input.** Shows directives and authored values, but omits defaults
|
||||
and resolution and therefore answers a different question.
|
||||
- **Application-defined compact views.** Audita's selected-profile summary is
|
||||
useful domain reporting, but does not replace a complete effective snapshot.
|
||||
- **A reloadable export command.** Potential future feature with a different
|
||||
contract; do not imply that inspection output supports round trips.
|
||||
|
||||
### `config sources`
|
||||
|
||||
**Recommendation:** list the acquired and synthetic input sources for the selected
|
||||
scope in the owning library's recorded order. Preserve every source's ID, label,
|
||||
path when available, layer, kind, underlay index, and import parent location.
|
||||
Do not sort sources alphabetically or flatten them into one winning file per
|
||||
field. Composite and inheritance provenance belongs to explanation records.
|
||||
|
||||
Default text output is a readable table; `--format yaml` returns the common source
|
||||
report with an ordered `sources` sequence. Defaults-only loading may legitimately
|
||||
produce an empty sequence. Defaults and domain derivations are not fabricated file
|
||||
sources. Both application and PromptKit scopes use the same complete record
|
||||
shape, replacing Scriptorium's differing source projections.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Field ownership under `sources`.** Narratio's report is useful but answers
|
||||
why a field has its value. Use `config explain` for that task.
|
||||
- **Only list filenames.** Short, but loses underlays, non-file sources, import
|
||||
relationships, and CLI contributions that help diagnose configuration.
|
||||
- **YAML by default.** Suitable for automation and consistent with native
|
||||
configuration reports. Prefer a table for interactive discovery and an explicit
|
||||
YAML format for structured consumption. Scriptorium's current JSON default is
|
||||
evidence to evaluate, not a format requirement for CommandKit.
|
||||
|
||||
### `config explain`
|
||||
|
||||
**Recommendation:** require `--path POINTER`; an explicitly supplied empty string
|
||||
selects the root. Use ConfigKit JSON Pointer semantics, including `~0` and `~1`
|
||||
escaping, mapping keys containing dots, and effective or historical paths. Omitted
|
||||
path and malformed pointer are usage errors; a well-formed unknown path is a
|
||||
command failure. Do not impose additional canonical-spelling restrictions beyond
|
||||
the owning library's supported path contract without a demonstrated need.
|
||||
|
||||
Default text output delegates to the native safe explanation writer. It includes
|
||||
the effective value and presence, effective origin, composite source locations,
|
||||
inheritance, chronological before/after values, resolution reasons and dependencies,
|
||||
and safe secret-reference metadata when available. Historical deleted paths remain
|
||||
explainable. Values receive native historical redaction.
|
||||
|
||||
`--format yaml` projects the native structured explanation into CommandKit's
|
||||
structured report. Keep value snapshots as records with `present`, `redacted`, and
|
||||
`yaml` fields, matching the upstream representation rather than inventing a typed
|
||||
value model for historical values. The `yaml` field holds native snapshot text
|
||||
as a string rather than decoding it into a new value. History remains chronological.
|
||||
|
||||
```sh
|
||||
app config explain --path /server/addr
|
||||
app config explain --scope promptkit --path '/profiles/team~1summary/model'
|
||||
app config explain --path ''
|
||||
```
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **One positional pointer.** Notarius demonstrates this and it is concise, but
|
||||
a named flag makes the required empty root explicit and allows a future distinct
|
||||
operand without ambiguity. Either convention could work if used everywhere.
|
||||
- **Value-free provenance only.** Audita and Narratio demonstrate useful compact
|
||||
reports; native redacted history gives a more complete explanation. A future
|
||||
summary format could omit values without changing this command's meaning.
|
||||
- **`explain --all` listing every field.** Useful for audits but potentially very
|
||||
large and expensive. Root explanation provides a starting point; defer exhaustive
|
||||
field-origin reporting until its traversal and summary contract are designed.
|
||||
|
||||
### `config diff`
|
||||
|
||||
**Recommendation:** compare two independently resolved effective configurations in
|
||||
the same scope. The ordinary selectors define the left side. At least one of
|
||||
`--against-config PATH` or `--against-overlay NAME` explicitly defines the right
|
||||
side; together they can change both root and overlay. Unspecified selectors are
|
||||
copied from the resolved left selection, rather than running discovery again.
|
||||
An omitted right overlay inherits the left overlay; `--against-overlay default`
|
||||
explicitly selects the base. Domain context selectors and typed overrides apply
|
||||
identically to both sides in this version.
|
||||
|
||||
```sh
|
||||
app config diff --config ./config.yml --overlay staging --against-overlay production
|
||||
app config diff --config ./old.yml --against-config ./new.yml --against-overlay default
|
||||
```
|
||||
|
||||
Both sides must load and validate. Compare semantic 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
|
||||
sequences. Sort differences by JSON Pointer and report `added`, `removed`, and
|
||||
`changed` with safe before/after snapshots. Root or container replacement must not
|
||||
produce redundant descendant differences.
|
||||
|
||||
Default text output is a readable change report, or `no differences` when
|
||||
appropriate. `--format yaml` supplies a structured report with selection metadata,
|
||||
an ordered differences sequence, and explicit information about redacted comparison
|
||||
gaps. Successful comparison returns `0` whether differences exist or not.
|
||||
|
||||
Compare only values that the owning library makes available for inspection.
|
||||
Secret bytes must never be fetched to improve a comparison. A masked value is
|
||||
not an ordinary literal string and identical masks do not prove secret equality.
|
||||
Apply the union of both sides' sensitivity classifications to before/after
|
||||
values so a value classified on either side cannot leak from the other report.
|
||||
When sensitivity prevents comparison, identify the path as not comparable; do
|
||||
not print `no differences` as an unqualified equality claim. This needs upstream
|
||||
structured sensitivity metadata, not string matching on `[REDACTED]`.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Two positional overlay names.** Narratio demonstrates a simple interface,
|
||||
but it cannot also compare different root files without another syntax.
|
||||
- **Fully separate left/right domain selector sets.** More flexible for campaign
|
||||
comparisons; adds substantial flag duplication. Shared context covers the
|
||||
existing overlay use case. Add independent contexts later if needed.
|
||||
- **Diff rendered YAML lines.** Easy to implement, but formatting changes obscure
|
||||
meaningful changes and identical masks conceal comparison gaps.
|
||||
- **Return a special nonzero status for differences.** Useful for CI assertions,
|
||||
but makes a successful inspection look like a failed command. Consider an
|
||||
explicit future check mode; keep ordinary comparison successful.
|
||||
|
||||
## 7. PromptKit definition inspection
|
||||
|
||||
**Recommendation:** optional definition commands use the same application root,
|
||||
overlay, and registered framework source selectors as `config --scope promptkit`.
|
||||
They always target PromptKit, so they do not accept `--scope`. They load the engine
|
||||
once and use its captured definitions without provider calls, capacity admission,
|
||||
request preparation, artifact loading, or credential lookup by PromptKit.
|
||||
|
||||
`promptkit list prompts` reports available `(ID, version)` pairs sorted by ID then
|
||||
version; `promptkit list profiles` reports exact profile IDs sorted lexically.
|
||||
IDs are identifiers, not filesystem paths, and prompt versions need not be semantic
|
||||
versions.
|
||||
|
||||
`promptkit show prompt ID` uses PromptKit's existing version-selection rules:
|
||||
omission of `--prompt-version` works only when that ID has one available version.
|
||||
Show the definition ID, selected
|
||||
version, opaque equality hash, declared default profile, declared inputs, and
|
||||
output contract. It does not resolve the declared default profile or render
|
||||
request-specific message templates. A command to show fully rendered requests
|
||||
would need inputs and belongs to application preparation such as `render`.
|
||||
|
||||
`promptkit show profile ID` reports the backend-completed named execution target:
|
||||
profile ID, backend, endpoint, model, configured provider controls, credential
|
||||
reference name,
|
||||
and whether a direct credential will be required. Do not suggest that a named
|
||||
profile is the profile selected by every request, that zero indicates a provider
|
||||
default, or that credential references establish credential availability.
|
||||
|
||||
All four commands default to readable text and accept `--format yaml`. Report
|
||||
fields and their structured YAML shapes are defined by CommandKit; arbitrary
|
||||
public Go structs are not an output contract. Unknown IDs or unavailable versions
|
||||
return `1`; missing
|
||||
or empty required IDs and invalid argument counts return `2`.
|
||||
|
||||
Provider parameter redaction belongs upstream in PromptKit. Notarius's curated
|
||||
profile report is useful evidence, while Scriptorium's profile output does not
|
||||
share configuration inspection's redaction contract. Establish a supported safe
|
||||
profile reporting API before adding arbitrary provider parameters to the standard
|
||||
report. Do not duplicate credential-name heuristics in CommandKit or assume that
|
||||
raw `InspectProfile` results have native configuration redaction.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Inspect definitions only through `config show/explain`.** Adequate for source
|
||||
presence and history, but does not clearly expose backend-completed targets or
|
||||
catalog discovery.
|
||||
- **Show raw prompt message content by default.** Can help authors, but the current
|
||||
public prompt inspection reports metadata, and request rendering is a different
|
||||
operation. Add content inspection deliberately upstream if needed.
|
||||
- **List definitions by parsing effective YAML in CommandKit.** Avoids new APIs,
|
||||
but takes ownership of PromptKit's schema and version model. Public catalog
|
||||
methods are the better boundary.
|
||||
|
||||
## 8. Help and version
|
||||
|
||||
### 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
|
||||
`app config explain --help` print the same leaf help with status `0`.
|
||||
|
||||
Help never acquires configuration, constructs PromptKit, resolves credentials,
|
||||
or allocates runtime state. Generate it from registered commands and flags,
|
||||
including application-owned commands, available scopes, selector applicability,
|
||||
format choices, and examples. An unknown command path is a usage error. A help
|
||||
request bypasses missing required operands; it does not make an otherwise unknown
|
||||
command or unknown flag valid.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Only root help.** Notarius's current leaf help errors demonstrate why this is
|
||||
insufficient for an operator trying to discover arguments.
|
||||
- **Error on a bare root or family.** Narratio and Scriptorium do this in some
|
||||
cases. Printing help successfully makes exploration consistent; an explicitly
|
||||
malformed leaf invocation still fails.
|
||||
- **Maintain separate help strings.** Straightforward, but they drift from
|
||||
parsing definitions. Registration should be the shared source.
|
||||
|
||||
### 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.
|
||||
|
||||
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.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Only the command or only the flag.** Either could be consistent; supporting
|
||||
both familiar discovery paths costs little and gives them one implementation.
|
||||
- **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.
|
||||
|
||||
## 9. Output, diagnostics, and failures
|
||||
|
||||
**Recommendation:** successful reports go to stdout; warnings, loading diagnostics,
|
||||
bootstrap reports, and errors go to stderr. Emit each diagnostic once, retain
|
||||
library source coordinates and source-ID legends, and use library-safe messages.
|
||||
No progress messages or banners may enter report output.
|
||||
|
||||
| Operation | Default | Other initial format |
|
||||
| --- | --- | --- |
|
||||
| `help` | text | none |
|
||||
| `version` | text | YAML |
|
||||
| `config scopes`, `validate`, `sources`, `explain`, `diff` | text | YAML |
|
||||
| `config show` (one scope or `all`) | YAML | none |
|
||||
| `promptkit list/show` | text | YAML |
|
||||
|
||||
Format names are lowercase. Unsupported formats are usage errors. Use `--format`
|
||||
consistently for commands that offer text and YAML; do not add a selector to
|
||||
YAML-only `config show`. Structured reports other than the native `config show`
|
||||
documents use a defined operation-specific schema and the applicable scope or
|
||||
selection metadata. Define their exact YAML field shapes before implementation;
|
||||
do not make native explanation prose or Go struct field spelling a machine
|
||||
contract. Structured YAML reports contain one document with a trailing newline;
|
||||
`config show --scope all` deliberately uses a multi-document stream.
|
||||
|
||||
**Accepted:** defer JSON output for the initial implementation across the suite.
|
||||
YAML is suitable for automated consumption, and the native inspection writers
|
||||
already preserve its value semantics. There are no initial JSON format flags,
|
||||
JSON-specific report schemas, or JSON-driven upstream API requirements. Adding
|
||||
JSON is optional future work only if a concrete need emerges; it may never be
|
||||
needed. JSON Pointer paths remain supported independently of output format.
|
||||
|
||||
Inspection formats use upstream secret classification; there is no unredacted
|
||||
output option in this standard. Redaction does not classify every sensitive prompt
|
||||
or arbitrary application value. The proposal preserves library confidentiality
|
||||
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
|
||||
creation, replacement, and retention behavior to inspection.
|
||||
|
||||
| Status | CommandKit-owned command meaning |
|
||||
| --- | --- |
|
||||
| `0` | Successful operation, including help, valid configuration, or comparison that found differences. |
|
||||
| `1` | Loading, validation, lookup, explanation, comparison, cancellation, diagnostics delivery, or output failed after valid syntax. |
|
||||
| `2` | Unknown command/flag/scope, invalid format, missing or malformed argument, repeated singleton, or invalid flag combination. |
|
||||
|
||||
Applications retain domain result statuses for their own commands. CommandKit must
|
||||
not globally reinterpret Scriptorium's execution validation status or Notarius's
|
||||
artifact rejection semantics. Common usage errors can use the shared status `2`,
|
||||
but business outcomes remain explicit application mappings.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Structured YAML everywhere by default.** Works for automation, but text help,
|
||||
tables, and native explanations are useful for interactive inspection. Offer
|
||||
YAML explicitly where the default is text.
|
||||
- **JSON as an additional output format.** Deferred by the accepted decision.
|
||||
It would add serializers, report contracts, and possible representation issues
|
||||
without a demonstrated benefit over the initial YAML reports.
|
||||
- **An output-file flag on every command.** Convenient but duplicates shell
|
||||
redirection and introduces file semantics. Add it later if concrete consumers
|
||||
need behavior beyond redirection.
|
||||
- **One nonzero status for every failure.** Narratio and Scriptorium demonstrate
|
||||
simplicity, but distinguishing malformed invocation from a failed valid command
|
||||
is useful and already demonstrated by Notarius.
|
||||
- **One exit policy for all application execution outcomes.** Would exceed the
|
||||
ownership boundary. Coordinate changes to owned commands without claiming domain
|
||||
statuses for unrelated commands.
|
||||
|
||||
## 10. Implementation dependencies and delivery
|
||||
|
||||
**Recommendation:** implement the common command behavior against narrow inspection
|
||||
providers, with ConfigKit and PromptKit retaining ownership of configuration
|
||||
semantics. Publish upstream API improvements before adopting them in CommandKit
|
||||
and the applications. Do not import sibling `internal` packages or turn source
|
||||
checkout proximity into an architectural dependency.
|
||||
|
||||
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 |
|
||||
| --- | --- |
|
||||
| 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. |
|
||||
|
||||
Suggested sequence:
|
||||
|
||||
1. Resolve the remaining proposed command contracts and alternatives, preserving
|
||||
the accepted planning decisions above.
|
||||
2. Define the structured YAML report schemas and minimal upstream inspection
|
||||
additions. Record accepted ownership decisions in durable architecture
|
||||
documentation.
|
||||
3. Implement core dispatch, syntax, help, version, scopes, validation, native
|
||||
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.
|
||||
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.
|
||||
|
||||
Later implementation validation should exercise genuine contract risks: help with
|
||||
invalid configuration, leaf flag placement and `--`, explicit empty/false/zero
|
||||
overrides, source order, historical paths, independent diff selections, sensitivity
|
||||
changes between sides, multi-document scope order, all-scope load failures before
|
||||
output, warning delivery and failed writers, and Narratio's subprocess consumers.
|
||||
|
||||
Breaking adoption replaces divergent spellings and behavior. Compatibility aliases
|
||||
are not required; introduce one only for a concrete transition need with an explicit
|
||||
retirement decision. Application execution commands outside the reserved suite
|
||||
remain independently owned, even when their implementations use CommandKit helpers.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Extract one existing application's command family unchanged.** Fast, but
|
||||
carries its omissions and incidental decisions into the standard. Use existing
|
||||
implementations to inform and exercise the selected contract instead.
|
||||
- **Build one universal runtime/application framework.** Could absorb more code,
|
||||
but would expand ownership into lifecycle and domain execution without improving
|
||||
the demonstrated inspection boundary.
|
||||
- **Implement missing upstream semantics inside CommandKit.** Avoids release
|
||||
coordination, but duplicates configuration projection, redaction, and definition
|
||||
knowledge. Those responsibilities should remain with the libraries that own them.
|
||||
|
||||
## 11. Explicitly deferred commands
|
||||
|
||||
**Recommendation:** defer configuration mutation (`set`, `edit`, `init`, `migrate`),
|
||||
reloadable export, credential diagnostics, live provider probes, completion
|
||||
installation, exhaustive field-origin inventories, request preparation, and domain
|
||||
artifact catalogs from this standard. Their semantics are not established by the
|
||||
repeated inspection code under review. Add a shared command when its operator
|
||||
purpose and ownership can be specified as clearly as the suite above.
|
||||
|
||||
JSON output is also deferred, with no assumption that it will eventually be added.
|
||||
|
||||
**Alternatives:**
|
||||
|
||||
- **Add a generic `doctor` command now.** Attractive for troubleshooting, but
|
||||
mixes offline configuration, credentials, network health, and domain resources.
|
||||
Specify those checks before choosing a shared name and success meaning.
|
||||
- **Standardize `run` in this first suite.** Could further improve vocabulary,
|
||||
but requires comparing execution semantics and their consumer contracts. A
|
||||
recommended verb is useful now; reserving its complete contract is separate work.
|
||||
98
docs/roadmap/02-dispatch.md
Normal file
98
docs/roadmap/02-dispatch.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# CommandKit dispatcher implementation
|
||||
|
||||
Status: accepted architecture; implementation pending.
|
||||
|
||||
Date: 2026-10-06.
|
||||
|
||||
[ADR 0001](../adr/0001-command-dispatch-and-inputs.md) owns the accepted dispatcher,
|
||||
registry, and handler-input decisions, their alternatives, and rationale. The
|
||||
[architecture policy](../policy/architecture.md) owns normative boundaries.
|
||||
This roadmap owns pending API design, implementation status, and sequencing.
|
||||
The [CLI plan](01-cli-plan.md) retains operator-contract proposals and their
|
||||
individual approval status.
|
||||
|
||||
## 1. Current status
|
||||
|
||||
The registry and typed-input model are selected but have no Go implementation.
|
||||
Exact constructors, registration/group APIs, bindings, factories, handler
|
||||
signatures, and application outcome/error interfaces remain open. No illustrative
|
||||
API declaration is a supported contract.
|
||||
|
||||
The [backend roadmap](03-backend.md) tracks Cobra/pflag integration, and the
|
||||
[facade roadmap](04-facade.md) tracks the accepted public/internal boundary.
|
||||
|
||||
## 2. Public API design
|
||||
|
||||
1. Design explicit instance construction, individual command registration,
|
||||
composable groups, and invocation using application context and streams.
|
||||
2. Express nested paths, descriptions, typed flags and defaults, repeatable
|
||||
inputs, presence, operands, and typed handlers in one definition.
|
||||
3. Define capability-provider registration that installs complete standard
|
||||
families without executing providers. Design wiring diagnostics separately
|
||||
from invocation-time loading failures.
|
||||
4. Specify the outcome/error interface so common usage errors, standard-command
|
||||
failures, and application-specific domain outcomes remain distinguishable.
|
||||
5. Demonstrate bindings against the proposed `config show`, `promptkit show
|
||||
profile`, and Narratio's application-owned `session restore`. These examples
|
||||
exercise standard selectors, resource operands, and application flags without
|
||||
approving unresolved command details.
|
||||
6. Evaluate simple and complex consumers against consistency and removed
|
||||
infrastructure. Constructor options or initial command collections can be
|
||||
conveniences over the same registry if they reduce assembly work.
|
||||
|
||||
### Illustrative presence and inputs
|
||||
|
||||
The selected model keeps presence alongside values where omission matters. One
|
||||
possible shape remains:
|
||||
|
||||
```go
|
||||
// Illustration only; these are not established public API declarations.
|
||||
type Supplied[T any] struct {
|
||||
Value T
|
||||
Set bool
|
||||
}
|
||||
|
||||
type RestoreInput struct {
|
||||
SessionID string
|
||||
DryRun bool
|
||||
Force bool
|
||||
Overlay Supplied[string]
|
||||
}
|
||||
```
|
||||
|
||||
Select exact public types, binding functions, and input factories during API
|
||||
work. Keep context, streams, and execution dependencies separate from CLI fields.
|
||||
Design domain value parsing within shared bindings without returning the complete
|
||||
argv to handlers.
|
||||
|
||||
## 3. Implementation sequence
|
||||
|
||||
1. Implement the root facade and internal command definitions under
|
||||
[ADR 0003](../adr/0003-public-facade.md). Add the per-instance registry and
|
||||
conflict checks without global or import-time registration.
|
||||
2. Translate definitions through the internal Cobra/pflag adapter. Allocate fresh
|
||||
input and backend state per invocation; do not bind registrations permanently
|
||||
to shared mutable inputs.
|
||||
3. Implement help/version and capability installation without configuration or
|
||||
runtime construction. Providers load only when the selected operation needs
|
||||
their results.
|
||||
4. Resolve remaining grammar and outcome proposals in the CLI plan before
|
||||
implementing them. Do not adopt parser defaults as accidental contracts.
|
||||
5. Implement the selected standard handlers through owning-library inspection
|
||||
APIs, following the upstream dependencies and delivery sequence in the CLI plan.
|
||||
6. Replace application routers and parser plumbing with registration and handlers.
|
||||
Coordinate the intentional breaking changes with application docs and
|
||||
subprocess consumers. Partial integrations remain development work rather
|
||||
than conformance to an unsupported complete suite.
|
||||
|
||||
## 4. Implementation evidence
|
||||
|
||||
As behavior lands, select meaningful checks under the testing policy for nested
|
||||
routing and collisions, help without configuration, flag placement and `--`,
|
||||
explicit empty/false/zero input, repetition, fresh values and presence across
|
||||
invocations, cancellation, output errors, and preserved application outcomes.
|
||||
Fresh state alone does not promise concurrent dispatch.
|
||||
|
||||
Update exact API GoDoc, consumer guidance, implemented CLI reference, and internal
|
||||
inventory with their corresponding implementation. Keep rationale in the ADR;
|
||||
retire completed implementation tasks without losing pending proposals.
|
||||
88
docs/roadmap/03-backend.md
Normal file
88
docs/roadmap/03-backend.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# CommandKit CLI backend implementation
|
||||
|
||||
Status: accepted backend; implementation pending.
|
||||
|
||||
Date: 2026-10-06.
|
||||
|
||||
[ADR 0002](../adr/0002-cobra-backend.md) owns the Cobra/pflag selection, alternatives,
|
||||
and rationale. [ADR 0003](../adr/0003-public-facade.md) owns the root facade and
|
||||
internal adapter boundary. This roadmap tracks dependency selection, adaptation,
|
||||
and implementation evidence. The [CLI plan](01-cli-plan.md) retains command and
|
||||
grammar proposals; [dispatcher work](02-dispatch.md) tracks the public input and
|
||||
invocation API.
|
||||
|
||||
## 1. Current status
|
||||
|
||||
Cobra with pflag is selected as the sole initial backend. No module dependency,
|
||||
adapter, or executable behavior is implemented. Select versions and attribution
|
||||
when dependencies are incorporated. There is no initial public backend selection
|
||||
or plugin facility.
|
||||
|
||||
## 2. Adapter work
|
||||
|
||||
### Typed inputs and fresh state
|
||||
|
||||
Translate CommandKit's explicit bindings into backend flag bindings and operand
|
||||
assignments. Create a fresh backend command tree and fresh input storage for each
|
||||
invocation from registered definitions. Construction must not load configuration,
|
||||
resolve credentials, or create execution dependencies.
|
||||
|
||||
### Presence and repetition
|
||||
|
||||
Record CLI presence independently of parsed defaults, preserving explicit empty,
|
||||
false, and zero values. Transfer presence into the typed fields selected by each
|
||||
command; handlers must not need backend flag lookups.
|
||||
|
||||
Resolve repetition and grammar choices before enforcing them. The CLI plan's
|
||||
singleton-repetition rejection is still a proposal. If selected, enforce it
|
||||
explicitly using registered metadata while preserving ordered accumulation for
|
||||
repeatable inputs. Exercise interspersed flags, values beginning with `-`, and
|
||||
`--` against the selected contract; avoid application-maintained flag-name lists.
|
||||
|
||||
### Help and command discovery
|
||||
|
||||
Generate help from one registry's metadata for standard and application commands,
|
||||
using backend machinery with the selected CommandKit presentation. Keep help and
|
||||
version usable without configuration or runtime construction.
|
||||
|
||||
Configure automatic backend behavior to match the chosen inventory. Backend
|
||||
completion support does not itself add a standard completion command. Parent and
|
||||
family help, unknown-command handling, operands, and leaf help need explicit
|
||||
contract choices rather than incidental defaults.
|
||||
|
||||
### Diagnostics and outcomes
|
||||
|
||||
Use backend context and stream support. Translate backend-owned syntax failures
|
||||
into CommandKit diagnostics/outcomes and avoid duplicate emission. Preserve the
|
||||
selected distinctions among usage errors, valid-invocation failures, and custom
|
||||
application outcomes. Do not match domain error strings or print usage for every
|
||||
runtime failure. Return control to the application for process termination.
|
||||
|
||||
### Provider integration and native reports
|
||||
|
||||
Install selected standard families from supplied providers and acquire their data
|
||||
lazily. Scope dependencies and native YAML rendering remain CommandKit integration
|
||||
work through ConfigKit/PromptKit public inspection APIs.
|
||||
|
||||
Implement accepted `config show --scope all` using native writers and the YAML
|
||||
stream contract in the CLI plan. Preserve the initial JSON deferral. A parser
|
||||
backend creates no need for another configuration loader or public backend-specific
|
||||
provider types.
|
||||
|
||||
## 3. Delivery sequence and evidence
|
||||
|
||||
1. Select and pin Cobra/pflag versions and record their actual licensing/notices.
|
||||
2. Design the neutral internal definitions required by the public registry and
|
||||
typed-binding API, then implement translation within the adapter boundary.
|
||||
3. Exercise representative standard and application command definitions, including
|
||||
the examples in the dispatcher roadmap, against selected semantics.
|
||||
4. Introduce meaningful integration evidence for conflicts, nested routing, help
|
||||
with invalid configuration, repetition, presence, `--`, fresh state, context
|
||||
and streams, failed writers, and application outcomes. Adapt defaults as needed
|
||||
without treating that work as grounds to reopen the accepted selection.
|
||||
5. Integrate standard handlers and coordinate breaking application adoption under
|
||||
the CLI delivery plan. Update consumer docs and subprocess adapters.
|
||||
|
||||
The testing policy owns check selection; the architecture policy owns boundaries.
|
||||
The ADR owns the backend-selection rationale and reviewed primary references.
|
||||
No second backend or generalized backend framework is a prerequisite.
|
||||
77
docs/roadmap/04-facade.md
Normal file
77
docs/roadmap/04-facade.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# CommandKit public facade implementation
|
||||
|
||||
Status: accepted facade and adapter boundary; implementation pending.
|
||||
|
||||
Date: 2026-10-06.
|
||||
|
||||
[ADR 0003](../adr/0003-public-facade.md) owns the root facade, internal adapter,
|
||||
alternatives, and rationale. The [architecture policy](../policy/architecture.md)
|
||||
owns normative dependency and public-surface rules. This roadmap tracks exact API
|
||||
work, illustrative package organization, and implementation evidence.
|
||||
|
||||
The [dispatcher roadmap](02-dispatch.md) tracks registry and typed inputs; the
|
||||
[backend roadmap](03-backend.md) tracks Cobra/pflag translation. The CLI plan
|
||||
retains command and operator-contract proposals and their approval status.
|
||||
|
||||
## 1. Current status
|
||||
|
||||
The root `commandkit` facade and internal Cobra/pflag isolation are accepted.
|
||||
No public declarations, implementation packages, adapter, dependency versions,
|
||||
or boundary checker exist yet. There is no public backend selection facility.
|
||||
|
||||
## 2. API and internal representation design
|
||||
|
||||
1. Design root-owned registration, binding, provider, invocation, and outcome
|
||||
contracts around demonstrated consumer needs. Application input types remain
|
||||
application-owned.
|
||||
2. Identify internal definitions and private callbacks that let implementation
|
||||
invoke typed handlers without importing the root facade or exposing backend
|
||||
structures. Separate fresh input lifetime from registration and dependencies.
|
||||
3. Use private state and explicit forwarding/conversions, preserving ownership,
|
||||
callback lifetime, presence, supported error identity, and cancellation.
|
||||
4. Translate backend-owned failures without returning backend objects, including
|
||||
through errors or loosely typed values. Preserve useful application error
|
||||
identity according to the selected invocation contract.
|
||||
5. Select any public dependency types deliberately. Standard context/stream
|
||||
contracts are appropriate; ConfigKit/PromptKit types require an API choice.
|
||||
|
||||
### Illustrative package layout
|
||||
|
||||
| Package | Possible responsibility |
|
||||
| --- | --- |
|
||||
| Root `commandkit` | Consumer facade, selected contracts, and conversions. |
|
||||
| `internal/engine` | Registry, ownership checks, capability installation, and invocation coordination. |
|
||||
| `internal/command`, if needed | Shared definitions and contracts independent of the backend. |
|
||||
| `internal/cobra` | Cobra/pflag integration, bindings, and diagnostic translation. |
|
||||
|
||||
These names and splits are illustrative, not an implemented inventory or required
|
||||
package-per-concern layout. Select cohesive packages during implementation. A
|
||||
narrow internal engine/adapter interface may be useful where actual interaction
|
||||
justifies it. Do not require a public backend interface or a second implementation.
|
||||
|
||||
## 3. Boundary protection and consumer evidence
|
||||
|
||||
With implementation, introduce proportionate checks for:
|
||||
|
||||
- Compiled public exports, including aliases, fields, signatures, constraints,
|
||||
callbacks, and promoted methods exposing internal or backend types.
|
||||
- Import direction: internal production code must not import root, and Cobra/pflag
|
||||
types and operations belong in the adapter.
|
||||
- Consumer behavior through the actual adapter, including conversions, fresh
|
||||
state, public error identity, and selected invocation semantics.
|
||||
|
||||
ConfigKit and ReleaseKit provide precedents for compiled API and import checks;
|
||||
reuse the approach where it protects this boundary without copying their entire
|
||||
validation suites or domain restrictions.
|
||||
|
||||
## 4. Completion and later replacement
|
||||
|
||||
Introduce GoDoc, consumer guidance, implemented CLI reference, and internal
|
||||
inventory with their corresponding code. Those become canonical owners of exact
|
||||
API and current behavior; ADRs retain decision rationale.
|
||||
|
||||
A later backend replacement should preserve the public Go API and selected CLI
|
||||
behavior, or follow the release policy for deliberate incompatible behavior.
|
||||
Protecting signatures alone is insufficient evidence for parsing, help,
|
||||
diagnostics, report, and status compatibility. This is future maintenance scope,
|
||||
not an instruction to implement or exercise a replacement now.
|
||||
106
docs/roadmap/policy.md
Normal file
106
docs/roadmap/policy.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# CommandKit policy adoption and follow-up
|
||||
|
||||
Status: initial adoption and decision alignment complete; implementation-specific
|
||||
follow-up pending.
|
||||
|
||||
Date: 2026-10-06.
|
||||
|
||||
This document records completion of the initial adoption and retains work tied to
|
||||
future library implementation. Local policies are authoritative. Architectural
|
||||
rationale now belongs in ADRs, and the implementation roadmaps retain pending
|
||||
work. The CLI proposal keeps its accepted choices and remaining recommendations.
|
||||
|
||||
## 1. Adopted baseline
|
||||
|
||||
The seven policies were adapted from Standard Repository Policies at:
|
||||
|
||||
`d84a38ebab26f048cafbe59a2246700c35d29843`
|
||||
|
||||
The selected commit is available in the local upstream checkout and is the
|
||||
baseline used by PromptKit, ConfigKit, and ReleaseKit. Adoption used that fixed
|
||||
revision rather than relying on remote freshness. Each local policy preserves its
|
||||
base version, records the actual adoption date, and links to its source file at
|
||||
that commit. Updates require deliberate review under
|
||||
[policy provenance](../policy/meta.md) and the upstream adoption guide.
|
||||
|
||||
| Adopted policy | Base version | Adaptation |
|
||||
| --- | --- | --- |
|
||||
| [Meta](../policy/meta.md) | 1.0 | Local authority, provenance, and upstream navigation. |
|
||||
| [Agents](../policy/agents.md) | 1.3 | Proportionate implementation, explicit contract authority, and local commits. |
|
||||
| [Architecture](../policy/architecture.md) | 1.3 | Dispatcher, registry, typed inputs, root facade, adapter, and ownership constraints. |
|
||||
| [Testing](../policy/testing.md) | 1.3 | Offline behavioral evidence and CommandKit-specific risk priorities. |
|
||||
| [Documentation](../policy/documentation.md) | 1.11 | Go API and CLI owners, ADR rationale, and roadmap implementation status. |
|
||||
| [Release](../policy/release.md) | 1.4 | Source-only module publication and Go/CLI compatibility. |
|
||||
| [OSS](../policy/oss.md) | 1.8 | Library grant, policy-document license scope, and factual attribution. |
|
||||
|
||||
Template adoption sections were removed. Reference examples remain upstream;
|
||||
source and example links are pinned, while discovery links may track upstream
|
||||
main. No automatic synchronization, recurring synchronization gate, or separate
|
||||
license approval flow was added.
|
||||
|
||||
## 2. Initial adoption outcomes
|
||||
|
||||
- Root [AGENTS.md](../../AGENTS.md) preserves the supplied knowledge-graph
|
||||
instructions and adds adopted contributor orientation.
|
||||
- The [developer guide](../development.md) routes tasks to relevant policies and
|
||||
gives proportionate current documentation validation guidance.
|
||||
- [COPYRIGHT](../../COPYRIGHT) records the `LGPL-3.0-or-later` library grant and
|
||||
separate CC-BY-SA-4.0 scope for adopted policies and copied orientation/reading
|
||||
guidance. Existing independently supplied instructions remain outside that
|
||||
copied-material scope.
|
||||
- Root [LICENSE](../../LICENSE) retains the existing complete LGPL/GPL texts.
|
||||
- [Attribution](../oss/attribution.md) identifies the exact adapted material and
|
||||
commit-specific source/notices, with the standard CC-BY-SA text copied locally.
|
||||
- The [README](../../README.md) gives truthful current status, navigation, and
|
||||
grant/attribution links. No public API, executable, or release tooling is claimed.
|
||||
|
||||
The adopted agents policy authorizes local commits for completed units by default,
|
||||
subject to explicit user instructions. It does not authorize pushing, publishing,
|
||||
or history rewriting. Review and preserve unrelated work before committing.
|
||||
|
||||
## 3. Decision alignment
|
||||
|
||||
| Accepted decision | Durable owner | Pending implementation |
|
||||
| --- | --- | --- |
|
||||
| Dispatcher ownership, explicit per-instance registry, namespace boundary, and typed inputs | [ADR 0001](../adr/0001-command-dispatch-and-inputs.md) | [Dispatcher roadmap](02-dispatch.md) |
|
||||
| Cobra/pflag as the sole initial backend | [ADR 0002](../adr/0002-cobra-backend.md) | [Backend roadmap](03-backend.md) |
|
||||
| Root-owned public contracts and an internal Cobra adapter | [ADR 0003](../adr/0003-public-facade.md) | [Facade roadmap](04-facade.md) |
|
||||
|
||||
The architecture policy owns normative boundaries. Accepted ADRs preserve context,
|
||||
choices, alternatives, and consequences without asserting that implementation
|
||||
exists. The three implementation roadmaps now link to those records instead of
|
||||
maintaining duplicate architectural rationale.
|
||||
|
||||
The [CLI proposal](01-cli-plan.md) remains the owner of future operator-contract
|
||||
proposals and their individual approval status. Adoption did not approve the
|
||||
remaining command inventory, grammar, exit statuses, or illustrative APIs.
|
||||
|
||||
## 4. Follow-up with implementation
|
||||
|
||||
| Work | Introduce when |
|
||||
| --- | --- |
|
||||
| Exact API declarations and GoDoc | Public registration, binding, provider, and invocation operations are implemented. |
|
||||
| Task-oriented consumer guides and maintained examples | There are substantive supported consumer workflows. |
|
||||
| `docs/cli.md` | Standard commands and operator contracts are implemented. |
|
||||
| Internal inventory and subsystem documentation | Actual packages and mechanisms exist. |
|
||||
| Cobra/pflag versions, notices, and license texts | Dependencies are incorporated; selection alone is not incorporation. |
|
||||
| Proportionate boundary and consumer checks | Code introduces the public facade and backend adapter. |
|
||||
| `docs/release.md`, publication tooling, and release notes | A releasable source module and working publication workflow exist. |
|
||||
|
||||
ConfigKit and PromptKit keep ownership of configuration and prompt semantics.
|
||||
CommandKit documents their CLI exposure and links to their canonical contracts.
|
||||
Select meaningful checks for actual CommandKit risks; do not inherit another
|
||||
library's platform matrix, scanners, or validation gates automatically.
|
||||
|
||||
ReleaseKit remains a candidate for publication mechanics, not a selected
|
||||
integration. Source-only releases are sufficient. Compatibility covers published
|
||||
Go and CLI contracts, including parser behavior and YAML reports, even when Go
|
||||
signatures are unchanged.
|
||||
|
||||
## 5. Completion boundary
|
||||
|
||||
Initial adoption comprises the customized policy set, supporting notices,
|
||||
contributor navigation, and alignment of already accepted decisions. That work is
|
||||
complete. The follow-up above remains future implementation scope; empty CLI/API
|
||||
references, checker code, release scripts, and speculative dependency entries are
|
||||
not prerequisites to policy adoption.
|
||||
Reference in New Issue
Block a user