Files
narratio/docs/roadmap/implementation.md

202 lines
11 KiB
Markdown

# ConfigKit v0.3.0 Implementation Plan
Status: Not started
Implement the [feature roadmap](configkit-v0.3.0.md) in sequential stage order.
Each stage is a bounded assignment for a gpt-5.6-terra coding agent. Mark it
complete only after its acceptance checks pass, and record the commands and
results beside its status. This replaces the completed original ConfigKit
migration plan; that history remains in Git.
## Working rules and fixed decisions
- Read `docs/development.md`, all documents under `docs/policy/`, the feature
roadmap, and the stage-specific sources before editing.
- Scope is the ConfigKit upgrade and the identified configuration-discovery test
isolation gaps. Do not implement the separate Notarius credential-forwarding
proposal, remove other roadmaps, or refactor unrelated command infrastructure.
- Keep production configuration semantics unchanged: root-relative pipeline
paths, current schema identifiers, imports/profiles, presence-aware defaults,
historical ownership checks, effective-only secret resolution, safe inspection,
and domain expansion. Do not adopt `Resolution.InputInfo` or
`Resolution.Source` without a separate feature requirement.
- Use the released ConfigKit v0.3.0 root API, not internal packages or sibling
checkout state. No replace directive, workspace dependency, vendoring, parser
fallback, or additional base load.
- Preserve the Go 1.26 baseline and Linux amd64/arm64 plus best-effort macOS arm64
targets. Do not change CI toolchains or upstream repositories in this work.
- Tests use real configuration/discovery logic and temporary files. Synthetic
credentials only; no real system configuration, cloud services, or adapter
executables. Do not mutate global search paths in the tests being repaired.
- Keep each stage buildable. Diagnose unexpected failures rather than skipping
tests, weakening invariants, or changing snapshots indiscriminately.
- Update canonical documentation only for implemented changes. Published release
notes, including v2.0.0, are immutable. No tag, push, release, or CI polling is
authorized by this plan.
## Stage 1 — Isolate command configuration discovery
Status: Not started
Purpose: Make missing-config command tests deterministic before changing the
dependency, while exercising the real discovery logic.
Read:
`internal/app/command_dependencies.go`, `commands.go`, `config_loader.go`,
`pipeline_config_path.go`, `pipeline_config_path_test.go`,
`analyze_artifacts_commands_test.go`, `commands_test.go`,
`operator_helpers_test.go`; configuration discovery in `docs/cli.md` and
`docs/config.md`.
Implementation:
1. Add a private `resolvePipelineConfigPath func(string) (string, error)` field
to `commandDependencies`. Normalize a nil value to the existing
`resolvePipelineConfigPath` function. Keep that function's production default
candidates and explicit-path behavior unchanged.
2. In `loadPipelineConfigWithDependencies`, call the normalized dependency
instead of the free function. Discovery must still precede secret bootstrap
and typed configuration loading. Preserve the selected path and all existing
error propagation. Verify all command-loading paths continue through this
shared owner; do not add per-command discovery implementations.
3. Repair the analyze and publish missing-config tests and the
`run missing config uses defaults` case in `TestExecuteMissingRequiredFlags`.
Call `executeWithDependencies` with a discovery closure that invokes
`resolvePipelineConfigPathWithCandidates` on an invocation-owned list of
missing paths under `t.TempDir()`. Use fresh dependencies per invocation.
A small shared test helper is appropriate for this repeated fixture.
Do not merely inject a prewritten discovery error or add an explicit
`--config` argument: these tests must still exercise default discovery.
4. Convert `TestExecuteSessionInitMissingDefaultConfigReportsSearchedPaths`
to the same seam, removing its global search-path mutation. Change
`TestResolvePipelineConfigPathWithCandidatesMissing` to temporary missing
paths rather than assumed-nonexistent absolute host paths.
Inspect adjacent missing-config tests and apply the same treatment where
needed; do not turn this into a general rewrite of unrelated successful
command fixtures.
5. Preserve the existing resolver tests for explicit precedence and first
existing candidate. Add one representative command-boundary case using a
temporary existing default pipeline and the real resolver to prove that
successful discovery reaches the configured loader with that selected path.
Stop at a controlled loader boundary; do not initialize runtime services.
In a representative missing-path case, guard the loader/bootstrap/executor
boundaries so accidental continuation after discovery failure fails the test.
6. Assert nonzero exit status, command context, a short missing-config diagnostic,
and the controlled searched path. Avoid complete prose snapshots. Keep all
test fixtures outside real system configuration and secrets directories.
Acceptance:
- `go test ./internal/app -run 'TestResolvePipelineConfigPath|TestExecute.*Missing|TestExecuteSessionInitMissingDefaultConfig'`
- `go test -race ./internal/app`
- `go test ./...` on the existing ConfigKit v0.1.2 dependency.
- The repaired tests own their candidate paths and do not depend on installed
configuration being absent. Do not create/remove an actual system config to
demonstrate this. Ordinary `Execute` still uses the production defaults.
## Stage 2 — Adopt the released dependency and version diagnostics
Status: Not started
Purpose: Upgrade without altering the set of valid Narratio configurations.
Read: `go.mod`, `go.sum`, `internal/config/party.go`,
`party_test.go`, `pipeline_configkit.go`, `pipeline_configkit_test.go`,
`document_configkit.go`, and ConfigKit's tagged v0.2.0/v0.3.0 release notes
and public API documentation. The downloaded module is authoritative; a sibling
checkout is reference material only.
Implementation:
1. Run `GOWORK=off go get gitea.maximumdirect.net/eric/ConfigKit@v0.3.0`
and `GOWORK=off go mod tidy`. Review the dependency diff; this task does not
authorize unrelated module or Go-version upgrades.
2. Change the integer-version case in
`TestParsePartyCanonicalRejectsInvalidDocuments` from a `version.type`
expectation to unsupported-version rejection. Rename it to identify an
unsupported integer version. Preserve `PartySchemaVersion =
"narratio.party.v1"` and the existing application checker.
3. Retain successful canonical-party coverage and ordinary-string strictness.
Add one boolean schema-version case if no equivalent malformed-kind coverage
exists, so the suite distinguishes an unsupported identifier from an invalid
version kind. Do not duplicate ConfigKit's numeric grammar matrix.
4. Run existing profile credential replacement/null-removal, hidden duplicate
ordinary/family definition, safe inspection, provenance, digest, bootstrap,
and maintained-example tests unchanged. In particular, keep the
`Metadata.HistoricalPaths()` check and the single effective pipeline load.
No production migration is expected beyond Stage 1's dependency seam.
5. Investigate any additional behavior difference against the roadmap before
changing production policy. Do not introduce private-engine imports or restore
old parsing to preserve incidental error wording.
Acceptance:
- `GOWORK=off go mod tidy -diff` and `GOWORK=off go mod verify`.
- `GOWORK=off go test ./internal/config ./internal/app`.
- `GOWORK=off go test -race ./internal/config ./internal/app`.
- Valid configurations and effective secret handling remain unchanged; integer
party versions still fail. No temporary module file, test overlay, local
replacement, or skipped failing case is needed.
## Stage 3 — Document and verify the completed adoption
Status: Not started
Purpose: Establish a clean, reproducible handoff for later release preparation.
Read: `docs/development.md`, `docs/internal/configuration.md`,
`docs/internal/overview.md`, `docs/config.md`, `docs/release.md`,
`scripts/build-release-assets.sh`, and `scripts/check-release-candidate.sh`.
Implementation:
1. Update internal command-dependency documentation to include the new
invocation-local discovery seam where the dependency inventory is described.
Update other current documentation only if a claim is actually affected.
The unchanged pipeline path policy and party identifier need no migration
instructions. Do not rewrite historical version pins in completed audit records.
2. Record in this plan's completion notes the released dependency, diagnostic
adjustment, test-isolation repair, and absence of operator migration.
If a genuinely unreleased release note already exists, update it. There is
currently no such note: v2.0.0 is already tagged. Do not invent a release
version or modify v2.0.0; transfer this summary into the new note when a
separate release task chooses its version.
3. Run all checks below against the normal module files, with no overlays or
skipped tests. Review the final diff for scope, formatting, whitespace,
credentials, and accidental dependency changes. Record results and limitations.
4. Mark the implementation stages complete and update the feature roadmap's
status only after acceptance succeeds. Do not delete roadmap/audit records
or implement the adjacent Notarius roadmap.
Required checks:
```sh
GOWORK=off go mod tidy -diff
GOWORK=off go mod verify
GOWORK=off go test -count=1 ./...
GOWORK=off go test -race -count=1 ./...
GOWORK=off go vet ./...
GOWORK=off go build ./...
GOWORK=off go test ./internal/doccheck
GOWORK=off go test ./internal/config -run '^TestExamplesLoadAndValidate$'
git diff --check
```
Also check formatting with `gofmt -l` on changed Go files. Use
`scripts/build-release-assets.sh v0.0.0-test OUTPUT_DIR`, where
`OUTPUT_DIR` is an empty absolute directory created with `mktemp -d`, to
exercise the maintained Linux amd64/arm64 and macOS arm64 build path without
choosing or publishing a release. Report macOS as cross-build evidence only.
Acceptance: All checks pass without access to an installed Narratio configuration
or real credentials. The implementation no longer needs evaluation-only
workarounds. The later release task must create its note, commit/push its candidate,
and run the normal release-candidate checker; this plan does not claim those
publication steps are complete.
## Open Questions
None. Dependency version, configuration behavior, discovery seam, test scope,
and validation gates are decided. Release version selection is deliberately
outside this implementation's scope and does not block the work.