253 lines
13 KiB
Markdown
253 lines
13 KiB
Markdown
# ConfigKit v0.3.0 Implementation Plan
|
|
|
|
Status: Complete — 2026-09-16
|
|
|
|
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: Complete — 2026-09-16
|
|
|
|
Completion: Added an invocation-local pipeline discovery dependency with the
|
|
production resolver as its default, then moved the affected missing-config tests
|
|
onto real resolver calls over temporary candidate paths. The command-boundary
|
|
coverage verifies successful default selection reaches the configured loader and
|
|
that discovery failures stop before bootstrap, typed loading, or execution.
|
|
|
|
Checks:
|
|
|
|
- `go test ./internal/app -run 'TestResolvePipelineConfigPath|TestExecute.*Missing|TestExecuteSessionInitMissingDefaultConfig'` — pass.
|
|
- `GOWORK=off go test -race ./internal/app` — pass.
|
|
- `GOWORK=off go test ./...` — pass with ConfigKit v0.1.2.
|
|
|
|
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: Complete — 2026-09-16
|
|
|
|
Completion: Upgraded the normal module graph from ConfigKit v0.1.2 to the
|
|
released v0.3.0 without production-code migration. Party schema version `1`
|
|
remains invalid through Narratio's unsupported-version check, while a boolean
|
|
case preserves malformed-kind coverage. Existing credential, ownership,
|
|
inspection, provenance, digest, bootstrap, and maintained-example regressions
|
|
pass unchanged.
|
|
|
|
Checks:
|
|
|
|
- `GOWORK=off go mod tidy -diff` — pass.
|
|
- `GOWORK=off go mod verify` — pass.
|
|
- `GOWORK=off go test ./internal/config ./internal/app` — pass.
|
|
- `GOWORK=off go test -race ./internal/config ./internal/app` — pass.
|
|
- Targeted preserved-behavior regression selections in `internal/config` and
|
|
`internal/app` — pass.
|
|
|
|
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: Complete — 2026-09-16
|
|
|
|
Completion: Narratio now uses released ConfigKit v0.3.0. The implementation
|
|
adds invocation-local pipeline discovery for isolated command tests and adjusts
|
|
the integer party-version expectation to Narratio's unsupported-version
|
|
diagnostic; it requires no operator configuration migration. The internal
|
|
command-dependency inventory documents the new seam. No unreleased Narratio
|
|
release note exists, and the immutable v2.0.0 note was not changed.
|
|
|
|
Checks:
|
|
|
|
- `GOWORK=off go mod tidy -diff` — pass.
|
|
- `GOWORK=off go mod verify` — pass.
|
|
- `GOWORK=off go test -count=1 ./...` — pass.
|
|
- `GOWORK=off go test -race -count=1 ./...` — pass.
|
|
- `GOWORK=off go vet ./...` — pass.
|
|
- `GOWORK=off go build ./...` — pass.
|
|
- `GOWORK=off go test ./internal/doccheck` — pass.
|
|
- `GOWORK=off go test ./internal/config -run '^TestExamplesLoadAndValidate$'` — pass.
|
|
- `git diff --check` — pass.
|
|
- `gofmt -l` on the changed Go files — no output.
|
|
- `scripts/build-release-assets.sh v0.0.0-test OUTPUT_DIR` — pass with
|
|
Linux amd64, Linux arm64, and macOS arm64 assets. The macOS result is
|
|
cross-build evidence only, not native runtime validation.
|
|
|
|
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.
|