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