Plan ConfigKit and PromptKit upgrades
This commit is contained in:
336
docs/roadmap/upgrade-kit.md
Normal file
336
docs/roadmap/upgrade-kit.md
Normal file
@@ -0,0 +1,336 @@
|
||||
# ConfigKit And PromptKit Upgrades
|
||||
|
||||
## Purpose
|
||||
|
||||
Adopt ConfigKit v0.4.0 and PromptKit v0.11.0 in one coordinated work set:
|
||||
|
||||
- Consistently call ConfigKit's selected configuration layer an **overlay**,
|
||||
distinct from PromptKit LLM profiles.
|
||||
- Adopt configurable transient HTTP retries, provider-neutral failure
|
||||
classifications, and execution observations from PromptKit.
|
||||
|
||||
Preserve application/framework boundaries and keep the two upgrades as distinct
|
||||
implementation workstreams. Neither requires a redesign of pipeline execution.
|
||||
|
||||
This is a feature roadmap describing the target state and required changes,
|
||||
not an implementation sequence. It does not authorize release publication.
|
||||
|
||||
## Current Baseline
|
||||
|
||||
The reviewed baseline is Notarius v0.7.1 (`53d9284`):
|
||||
|
||||
- `go.mod` pins ConfigKit v0.3.0 and PromptKit v0.10.0.
|
||||
- `internal/core/config/load.go` passes `LoadOptions.Profile` into
|
||||
`configkit.Options[Document].Profile`.
|
||||
- `--config-profile` selects `profiles/<name>.yml` beneath the configuration
|
||||
root for `run`, `config validate`, `config effective`, `config explain`, and
|
||||
`pipelines list`.
|
||||
- The maintained selected-layer example is
|
||||
`examples/profiles/development.yml`; configuration and CLI tests create
|
||||
equivalent directories and exercise selection and inspection.
|
||||
- ConfigKit owns composition and inspection metadata. Notarius owns its
|
||||
version 5 document, defaults, validation, source-relative path resolution,
|
||||
runtime conversion, and CLI discovery.
|
||||
|
||||
A dependency-only trial against v0.4.0 fails to compile at `load.go:33` because
|
||||
`configkit.Options.Profile` no longer exists. The review found no direct
|
||||
Notarius references to `LayerProfile`, `CodeProfile*`, or `LoadSecretsDir`.
|
||||
|
||||
An isolated dependency-only trial against PromptKit v0.11.0 passes the complete
|
||||
Notarius test suite and `go vet ./...`. That proves baseline compatibility, not
|
||||
adoption of the new controls or observations. The current adapter does not
|
||||
configure transient retries or attach an execution observer. It classifies
|
||||
generation errors broadly and records successful-result usage and structural
|
||||
repair counts. The outer scheduler holds a permit for the whole completion.
|
||||
|
||||
## Upstream Changes
|
||||
|
||||
### ConfigKit v0.4.0
|
||||
|
||||
The [ConfigKit v0.4.0 release guide](https://gitea.maximumdirect.net/eric/ConfigKit/src/tag/v0.4.0/docs/releases/v0.4.0.md)
|
||||
defines four breaking naming changes:
|
||||
|
||||
| Surface | Previous | Target |
|
||||
| --- | --- | --- |
|
||||
| Selection API | `Options.Profile` | `Options.Overlay` |
|
||||
| Selected file | `profiles/<name>.yml` | `overlays/<name>.yml` |
|
||||
| Provenance layer | `LayerProfile` / `profile` | `LayerOverlay` / `overlay` |
|
||||
| Diagnostic identifiers | `CodeProfile*` / `profile.*` | `CodeOverlay*` / `overlay.*` |
|
||||
|
||||
There are no legacy aliases or directory fallback. Explicit imports from a
|
||||
directory named `profiles` remain valid ordinary imports. Merge rules,
|
||||
precedence, lifecycle, source-origin APIs, minimum Go version, and YAML parser
|
||||
dependency are unchanged.
|
||||
|
||||
The intervening v0.3.1 release makes the opt-in `LoadSecretsDir` API ignore
|
||||
dot-prefixed entries. Notarius does not use this API; adding secrets-directory
|
||||
bootstrap is outside this work.
|
||||
|
||||
### PromptKit v0.11.0
|
||||
|
||||
The [PromptKit v0.11.0 release guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.11.0/docs/releases/v0.11.0.md)
|
||||
introduces additive runtime APIs and one changed default:
|
||||
|
||||
- Built-in generation defaults to two additional transient HTTP attempts for
|
||||
statuses 429, 500, 502, 503, and 504. Engine and request controls can override
|
||||
the count, including zero. Injected `LLMClient` implementations are not
|
||||
automatically replayed; a custom HTTP client on the built-in path still is.
|
||||
- Backoff is cancellable and honors valid provider `Retry-After` timing.
|
||||
Generation and HTTP timeouts apply per attempt; the caller context bounds
|
||||
the whole operation. Transport failures, malformed responses, other HTTP
|
||||
statuses, and invalid generated content are not transient-retry candidates.
|
||||
- `RunRequest.Observer` reports lifecycle metadata, attempts, waits, outcomes,
|
||||
and presence-aware usage, including work before a failed execution. It works
|
||||
with prepared execution; preparation itself emits no execution events.
|
||||
- `ErrTransport`, `ErrMalformedResponse`, `ErrRetriesExhausted`, and
|
||||
`RetryExhaustedError` support typed classification without parsing error text.
|
||||
- The license changes to LGPL-3.0-or-later. Catalog selections and the minimum
|
||||
Go version are unchanged from v0.10.0.
|
||||
|
||||
## Target End State
|
||||
|
||||
### Dependency And Ownership
|
||||
|
||||
Pin ConfigKit v0.4.0 and PromptKit v0.11.0 and tidy the dependency graph.
|
||||
Continue using only ConfigKit's
|
||||
public root API behind `internal/core/config`. No compatibility parser,
|
||||
application-owned composition engine, or new configuration abstraction is
|
||||
needed. PromptKit remains behind `internal/framework/llm`; its types must not
|
||||
leak into domain modules or pipeline contracts. Retain the existing prepared
|
||||
execution path, profile choices, and D&D model settings.
|
||||
|
||||
### Consistent Overlay Selection
|
||||
|
||||
- Replace the configuration-selection CLI flag with `--config-overlay` on all
|
||||
commands that currently accept `--config-profile`.
|
||||
- Rename application-owned fields, variables, helpers, help text, and test
|
||||
descriptions that specifically represent this selection to overlay terms.
|
||||
- Pass the selection through `configkit.Options.Overlay`.
|
||||
- Select files only from `overlays/<name>.yml`, following ConfigKit's contract.
|
||||
- Preserve empty and `default` selection as the composed base configuration
|
||||
without a selected overlay.
|
||||
- Use a clean cutover: no old CLI alias, directory fallback, automatic file
|
||||
moves, or custom migration machinery. Normal unknown-flag handling is
|
||||
sufficient for the retired flag; explain migration in documentation.
|
||||
|
||||
This rename is deliberately narrow. Preserve `llm_profile`, `--llm-profile`,
|
||||
`promptkit.profile_dir`, `promptkit.profile_file`, `base_profile`, embedded
|
||||
`dnd-extraction` profiles, and `examples/llm-profiles/`. Other application
|
||||
concepts named `Profile`, including pipeline/runtime types, must not be renamed
|
||||
merely because they share the word.
|
||||
|
||||
### Preserved Behavior
|
||||
|
||||
Retain configuration version 5, with the additive retry setting described below.
|
||||
Preserve existing defaults other than the explicitly adopted transient retry policy,
|
||||
imports, overlay merge behavior (including sequence replacement), explicit CLI
|
||||
override precedence, strict decoding, domain validation, and secret redaction.
|
||||
Do not add new restrictions or relax existing explicit contracts as part of the
|
||||
rename.
|
||||
|
||||
Relative paths continue to resolve from the file supplying the surviving
|
||||
declaration, including overlay files. Invocation-relative CLI paths and
|
||||
main-file-relative built-in defaults retain their current behavior.
|
||||
|
||||
Effective configuration, explanations, and configuration-load diagnostics use
|
||||
the new upstream overlay provenance and diagnostic vocabulary. Preserve source
|
||||
file labels and actionable error context; do not translate the new metadata
|
||||
back into legacy profile terminology.
|
||||
|
||||
Pipeline stage order, semantic acceptance, LLM selection, domain artifact
|
||||
schemas, and subprocess result receipts remain unchanged. No blanket checkpoint
|
||||
invalidation is added merely for the ConfigKit rename. Update the existing
|
||||
PromptKit-version identity used by checkpoint fingerprinting with its dependency
|
||||
pin, following the current adapter convention; no cache redesign is needed.
|
||||
|
||||
### Transient Retry Policy
|
||||
|
||||
Expose `promptkit.transient_retries` as a nonnegative integer setting with a
|
||||
Notarius default of **2 additional attempts**. Explicit zero disables transient
|
||||
retries. Apply the resolved setting to the shared PromptKit engine so modules,
|
||||
normalizers, validators, and semantic correction calls receive the same policy.
|
||||
Include the effective value in configuration inspection. Do not impose an
|
||||
arbitrary application maximum or add per-binding controls in this work set.
|
||||
|
||||
Maintain three separate budgets and owners:
|
||||
|
||||
| Budget | Owner | Repeated work |
|
||||
| --- | --- | --- |
|
||||
| Transient retries | PromptKit | The same generation request after eligible HTTP failures |
|
||||
| Structural repairs | PromptKit | A corrective generation for invalid structured output |
|
||||
| Producer/validator retries | Notarius | The configured stage or validator operation, with semantic feedback where applicable |
|
||||
|
||||
Do not silently reduce, repurpose, or remove existing stage/validator budgets.
|
||||
Each structural repair generation receives its own transient budget. For a
|
||||
single-completion producer, two additional stage attempts, one structural
|
||||
repair, and two transient retries permit up to 18 HTTP attempts, excluding any
|
||||
separate validator calls. Document this multiplication and the possibility of
|
||||
additional cost; retries do not imply exactly-once provider execution.
|
||||
|
||||
Preserve caller cancellation throughout generation and waiting. Do not describe
|
||||
a profile's generation timeout as a total completion deadline: provider
|
||||
`Retry-After` can extend waits beyond local backoff, and each HTTP attempt has
|
||||
its own timeout. A new total-deadline configuration surface is outside this
|
||||
upgrade; accurately document the current controls and limitations.
|
||||
|
||||
Retain Notarius's completion-scoped scheduler permit during upstream backoff.
|
||||
PromptKit releases its active backend permit during that wait, but this does
|
||||
not release the outer Notarius permit. This remains bounded and correct; do
|
||||
not add an attempt-level scheduler redesign.
|
||||
|
||||
### Provider-Neutral Failure Diagnostics
|
||||
|
||||
Translate the new typed errors into application-owned classifications for
|
||||
transport failures and malformed provider responses. Represent transient retry
|
||||
exhaustion separately from its underlying failure/status, retaining the actual
|
||||
attempt count where available. Preserve existing HTTP-status reporting,
|
||||
capacity classification, cancellation, deadline handling, and redaction.
|
||||
|
||||
Do not turn a malformed provider envelope into a semantic rejection or confuse
|
||||
it with a structurally invalid model response. Do not expose PromptKit error
|
||||
types across the adapter boundary or parse prose to recover classifications.
|
||||
Existing stage disposition policies continue to decide what happens after a
|
||||
completion fails; this work does not redesign those policies.
|
||||
|
||||
### Execution Observations
|
||||
|
||||
Attach a request-local observer through the existing prepared-execution path.
|
||||
Translate selected metadata into Notarius-owned completion/debug summaries:
|
||||
|
||||
- dispatched attempt, transient retry, and structural repair-call counts;
|
||||
- capacity-wait, generation, retry-delay, and total execution durations;
|
||||
- terminal outcome, failure classification, HTTP status, and exhaustion state;
|
||||
- observed token counts with explicit known/complete indicators.
|
||||
|
||||
Retain available summaries on failed completions, including cancellation, rather
|
||||
than discarding them with the absent `RunResult`. Preparation failures have no
|
||||
execution observation; do not fabricate one. Keep existing successful-result
|
||||
usage fields and their meanings unchanged. Observation totals are separate
|
||||
presence-aware metadata, not a second set of tokens to add to existing usage.
|
||||
Unknown counts are not known zero; partial totals are not a billing ledger.
|
||||
|
||||
Use lightweight per-request accumulation with no unbounded event history or
|
||||
asynchronous queue. Callbacks are synchronous: avoid blocking I/O or acquisition
|
||||
of scheduler resources inside them, and isolate concurrent requests. Persist
|
||||
the projection through the existing opt-in debug path, including safe terminal
|
||||
summaries where applicable. Do not serialize upstream event structs directly;
|
||||
their JSON layout is not a public contract. Allowlist metadata and preserve
|
||||
existing identifier/content handling and redaction boundaries.
|
||||
|
||||
Successful transient recovery is ordinary success, not a warning. This work
|
||||
does not add routine console messages, change the warning policy, introduce a
|
||||
new durable telemetry artifact, or add complete cost accounting.
|
||||
|
||||
## Required Changes
|
||||
|
||||
### Code And Examples
|
||||
|
||||
- Update `go.mod` and `go.sum` and the configuration loader/options boundary.
|
||||
- Update CLI selection plumbing in `internal/cli/run.go` and
|
||||
`configkit_commands.go`, including usage, flag parsing, argument classification,
|
||||
explicit empty-value handling, and error paths.
|
||||
- Move the maintained example to `examples/overlays/development.yml` and update
|
||||
example discovery and related fixtures. Inspect relative paths when moving
|
||||
files; do not assume all occurrences of `profiles` are configuration overlays.
|
||||
- Update affected configuration and CLI tests, particularly document paths,
|
||||
operational defaults, safe inspection, command selection, diagnostic source
|
||||
labels, run contracts, and maintained-example coverage.
|
||||
- Add the retry setting through the typed configuration document, defaults,
|
||||
validation, runtime conversion, and CLI client-construction boundary. Update
|
||||
the complete example to demonstrate it without adding unnecessary settings
|
||||
to the minimal example.
|
||||
- Update the PromptKit adapter's engine construction, request observation,
|
||||
error conversion, and checkpoint version identity. Extend transport-neutral
|
||||
response/debug contracts only with the application-owned metadata needed.
|
||||
- Carry observations through the pipeline debug wrapper and safe terminal
|
||||
reporting without double-counting usage or losing failed-call summaries.
|
||||
|
||||
### Documentation
|
||||
|
||||
Update current documentation with the implementation, keeping canonical
|
||||
ownership under [Documentation Policy](../policy/documentation.md):
|
||||
|
||||
- `docs/cli.md`: new flag on every affected command and matching help behavior.
|
||||
- `docs/config.md`: overlay terminology, directory layout, precedence, and the
|
||||
explicit distinction from LLM profiles; transient retry setting and default.
|
||||
- `docs/integrations/pkg-configkit.md`: pinned release and supported upstream
|
||||
naming/inspection contract.
|
||||
- `docs/internal/configuration.md` and relevant CLI internals: new selection
|
||||
terminology and unchanged boundaries.
|
||||
- `docs/consumers/subprocess.md` and any other current callers/examples: updated
|
||||
invocation syntax. Review operations and README references where applicable.
|
||||
- `docs/integrations/pkg-promptkit.md`: updated pin, typed errors, observer
|
||||
support, and retry contract. Refresh pinned upstream links, including its
|
||||
relocated release-policy document.
|
||||
- `docs/internal/llm.md` and relevant pipeline/debug internals: observation
|
||||
projection, failure handling, scheduler interaction, and separate retry
|
||||
budgets. Remove the obsolete claim that PromptKit has no provider retry loop.
|
||||
- `docs/operations.md`: latency/cost implications, timeout limits, opt-in debug
|
||||
evidence, and how to disable transient retries.
|
||||
|
||||
Preserve historical release notes and the accepted text of ADR-0018. Its
|
||||
ConfigKit ownership decision remains valid; a terminology migration alone does
|
||||
not require a new ADR or supersession. Current documentation must not portray
|
||||
the old dependency pin as the current supported version.
|
||||
|
||||
Record PromptKit's LGPL-3.0-or-later change in the integration documentation and
|
||||
eventual release note. Review its notices and distribution implications within
|
||||
Notarius's source-only release model. Do not silently relicense Notarius, copy
|
||||
upstream release policy into this repository, or introduce binary packaging.
|
||||
Any future binary distribution needs its own license-compliance review.
|
||||
|
||||
## Operator Migration And Release Impact
|
||||
|
||||
This work belongs in the next **minor** Notarius release, not a patch, because
|
||||
both the documented selected-file layout and CLI syntax change.
|
||||
|
||||
Operators move selected configuration files from `profiles/` to `overlays/`
|
||||
and replace `--config-profile` with `--config-overlay` in scripts, service
|
||||
definitions, and subprocess callers. Preserve unrelated PromptKit profile
|
||||
directories and explicit imports. Review relative paths and explicit imports
|
||||
that refer to moved files. No YAML body version migration is required.
|
||||
|
||||
The eventual release note must explain this cutover, the newly enabled transient
|
||||
retries and zero-value opt-out, and the dependency license change. PromptKit's
|
||||
catalogs are unchanged from v0.10.0; this upgrade adds no further profile-name
|
||||
migration or change to the D&D model defaults. Release preparation,
|
||||
tagging, and publication remain a separately requested task under
|
||||
[Source Releases](../release.md).
|
||||
|
||||
## Acceptance And Verification
|
||||
|
||||
- Notarius builds against ConfigKit v0.4.0 and PromptKit v0.11.0 without
|
||||
compatibility shims.
|
||||
- All five affected commands use the new flag; non-default overlay selection,
|
||||
omitted selection, empty selection, and `default` retain their intended
|
||||
behavior. The old flag is not accepted.
|
||||
- Selected overlays load from the new directory. A legacy-only selected file
|
||||
does not silently load; ordinary explicit imports remain supported.
|
||||
- Representative tests demonstrate overlay precedence, CLI overrides,
|
||||
declaration-relative paths, redacted inspection, and source-aware failures.
|
||||
- Maintained examples validate, including the development overlay. LLM profile
|
||||
loading and defaults remain unaffected.
|
||||
- Tests prove the default transient retry policy, explicit zero, configured
|
||||
counts, and negative-value rejection through the relevant configuration and
|
||||
adapter boundaries. Use local HTTP test servers for eligible/noneligible
|
||||
statuses, exhaustion, cancellation, and interaction with structural repair;
|
||||
an injected LLM fake alone does not exercise built-in HTTP retries.
|
||||
- Provider-neutral errors preserve underlying status and cancellation identity
|
||||
without leaking credentials or upstream types.
|
||||
- Observations are available for success and failure, preserve unknown versus
|
||||
known-zero usage, avoid aggregate double-counting, and stay isolated under
|
||||
concurrent completions. Successful retry recovery emits no warning.
|
||||
- Representative scheduler/repair/retry checks preserve bounded execution and
|
||||
cancellation; use existing coverage where it already proves the contract.
|
||||
- Current documentation, help text, examples, and tests agree. Searches for old
|
||||
vocabulary are reviewed semantically, excluding intentional historical and
|
||||
LLM-profile references rather than enforcing a blanket text ban.
|
||||
- Run focused `go test ./internal/core/config ./internal/cli ./internal/framework/llm ./internal/framework/pipeline`, followed by
|
||||
`go test ./...`, `go vet ./...`, `go build ./...`, `go mod tidy -diff`, and
|
||||
`git diff --check`, with `GOWORK=off`. Run race-enabled tests for the modified
|
||||
adapter, scheduler, and observation integration. Validate both maintained configurations
|
||||
and the complete configuration with `--config-overlay development`.
|
||||
|
||||
Use existing behavioral tests where possible, following
|
||||
[Testing Policy](../policy/testing.md). No live model calls or production API
|
||||
credentials are needed to validate this migration.
|
||||
Reference in New Issue
Block a user