Plan the PromptKit upgrade in nine stages
This commit is contained in:
@@ -1,246 +1,460 @@
|
|||||||
# Implementation Plan: ConfigKit v0.5.0 Adoption
|
# Implementation Plan: PromptKit v0.12.0 Adoption
|
||||||
|
|
||||||
**Last updated:** 2026-10-03
|
**Last updated:** 2026-10-03
|
||||||
**Status:** Complete.
|
**Status:** Ready for implementation; no stages completed.
|
||||||
**Audience:** Luna coding agent.
|
**Audience:** Luna coding agent.
|
||||||
|
|
||||||
## Scope and Execution
|
## Scope and Execution
|
||||||
|
|
||||||
Implement the target state in the [ConfigKit roadmap](configkit.md), which owns
|
Implement the accepted target in the [PromptKit roadmap](promptkit.md). That
|
||||||
feature intent, scope, and compatibility considerations. Execute the numbered
|
document owns feature intent and policy choices; this plan owns the ordered
|
||||||
stages below in order. Each stage is a bounded implementation prompt; the
|
implementation work. The planning baseline is Audita commit
|
||||||
complete feature comprises all five stages. Commit each completed unit with a
|
`b31955fc97adec707b4e5f9a1b0c43c4cbc66750`: ConfigKit v0.5.0 is adopted,
|
||||||
short, plain English message under the [agent policy](../policy/agents.md).
|
PromptKit is v0.11.2, and the finalized roadmap includes the selected-profile,
|
||||||
No approval gate is needed between stages.
|
operator-override, example-layout, and major-release clarifications.
|
||||||
|
|
||||||
Begin with [development guidance](../development.md) and the applicable agent,
|
This replaces the completed ConfigKit plan at this path. Its
|
||||||
|
[completed implementation record](https://gitea.maximumdirect.net/eric/audita/src/commit/b31955fc97adec707b4e5f9a1b0c43c4cbc66750/docs/roadmap/implementation.md)
|
||||||
|
remains available for readers following the ConfigKit completion roadmap.
|
||||||
|
|
||||||
|
Execute Stage 1 through Stage 9 in order. Each is sized as one bounded Luna
|
||||||
|
implementation prompt. Commit completed units with short, plain English messages
|
||||||
|
under the [agent policy](../policy/agents.md); no approval round is needed between
|
||||||
|
stages. Record actual checks and any remaining expected migration failures.
|
||||||
|
Stages 1 and 2 change formats before Stage 3 changes their consumer. Intermediate
|
||||||
|
commits need not be runnable or release-ready. Do not add temporary readers,
|
||||||
|
compatibility shims, fallback engines for execution, or scaffolding to make them
|
||||||
|
so. Later stages complete the same migration rather than separate product modes.
|
||||||
|
|
||||||
|
Start with [development guidance](../development.md) and the applicable agent,
|
||||||
[architecture](../policy/architecture.md), [testing](../policy/testing.md),
|
[architecture](../policy/architecture.md), [testing](../policy/testing.md),
|
||||||
[documentation](../policy/documentation.md), and [OSS](../policy/oss.md)
|
[documentation](../policy/documentation.md), and [OSS](../policy/oss.md)
|
||||||
policies. Use graph-first discovery and read the relevant current contracts.
|
policies. Use graph-first discovery. Read the current
|
||||||
The planning baseline is Audita commit
|
[configuration](../config.md), [LLM runtime](../internal/llm-runtime.md),
|
||||||
`23e1df4cfb844d3fdeb1fb64483c1038cc4f2e21`; application code remains at the
|
[prompt registry](../internal/prompts.md), and
|
||||||
roadmap's reviewed revision. Target released ConfigKit v0.5.0, source commit
|
[LLM integration](../integrations/openai-compatible-llm.md) contracts for the
|
||||||
`dc09959cca4e105f49ec316c6d4ba585bd2340bd`.
|
established behavior this migration preserves.
|
||||||
|
|
||||||
|
Target the released PromptKit v0.12.0 at commit
|
||||||
|
`4b8169da286917fde7875425bb32b799b12c6af3`, ConfigKit v0.5.0, and both
|
||||||
|
maintained `/v3` catalogs at `v3.20260930.0`. Read the pinned
|
||||||
|
[format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.12.0/docs/formats.md)
|
||||||
|
and [migration guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.12.0/docs/consumers/pkg-promptkit.md#migrate-from-the-previous-configuration-api).
|
||||||
|
The sibling checkout is reference material, not a dependency replacement.
|
||||||
|
|
||||||
### Selected Implementation Decisions
|
### Selected Implementation Decisions
|
||||||
|
|
||||||
- Keep `internal/core/config.Load` using ordinary `ck.Load`. Native inheritance
|
- Keep Go 1.25.5, application `version: 2`, current flags, role selection,
|
||||||
already runs before decoding and application resolution; another resolver or
|
application overlays, and main-file-relative path rules. Retain the
|
||||||
`LoadLayered` conversion is unnecessary.
|
`profiles_dir` name and default; broaden its accepted documents as agreed.
|
||||||
- Keep PromptKit at v0.11.2 and its `/v2` catalogs at their existing versions.
|
- Use PromptKit's catalog and owned defaults, then caller underlays for embedded
|
||||||
Retain Go 1.25.5, configuration `version: 2`, existing profile syntax, role
|
Audita prompts and operator directory inputs, then `Sources.Main` for
|
||||||
selection, CLI flags, file discovery, overlays, and main-file-relative paths.
|
application backend settings. Directory inputs compose strictly within their
|
||||||
- Preserve absence-based defaults. Inherited input is explicit input, including
|
group; discovery order supplies no field precedence. Keep imports disabled.
|
||||||
zero, false, empty, and null; existing field rules still decide validity.
|
- Use one ConfigKit mapping for the final application source. For each
|
||||||
Every backend, including inheritance parents and unselected backends, remains
|
application backend, supply its endpoint, `concurrency_limit`,
|
||||||
subject to ordinary validation and surviving credential resolution.
|
`queue_capacity`, and explicit `api_key_env: null`. The null suppresses
|
||||||
- Preserve existing explanation fields and add an optional `inheritance`
|
lower-tier credential lookup. Leave other supported provider fields available
|
||||||
sequence to each field record. Each step has `from`, `to`, and `reference`
|
to native layering. Do not put resolved credential values in this mapping.
|
||||||
string paths copied from `Origin.Inheritance` through `Path.String()`.
|
- Keep selected-role registration, endpoint-match, competing-credential, and
|
||||||
This additive, value-free projection serves both `--view explain` and debug
|
required-key checks. Add explicit nonblank effective model and endpoint checks
|
||||||
configuration origins through their existing shared function. It is not a
|
for both selected roles. Valid unselected partial profiles remain permitted.
|
||||||
new inspection command or a complete upstream metadata serialization.
|
- Preserve the adapter's complete per-call schemas, configured repairs/retries,
|
||||||
- The `extends` keyword is reserved by the library throughout application input
|
operation context, shared variables, observation, and prepare/check/run flow.
|
||||||
mappings. Document its compatibility impact, including legacy backend IDs
|
Operator messages can omit shared-variable references; do not append the
|
||||||
named `extends`; do not add a compatibility translator or a second naming
|
shared text unconditionally or require particular message counts or roles
|
||||||
restriction to application validation.
|
beyond PromptKit's own format rules.
|
||||||
|
- Use captured source inspection for consumed host configuration and message
|
||||||
|
paths. Keep source-relative resource resolution with PromptKit and ConfigKit;
|
||||||
|
Audita projects paths for its existing output collision checks.
|
||||||
|
- Replace the old profile-reload test expectation with snapshot behavior.
|
||||||
|
Successful construction uses only final effective definitions. A failed
|
||||||
|
construction may make an embedded-only diagnostic construction to distinguish
|
||||||
|
asset defects from operator errors; it never executes or substitutes for the
|
||||||
|
requested configuration.
|
||||||
|
- Maintained example roots are `examples/profiles/local/` and
|
||||||
|
`examples/profiles/service/`. Service testing profiles stay in the service
|
||||||
|
root. Keep the literal `temperature: 0` in examples as an explicit outbound
|
||||||
|
setting, and use native presence semantics without a compatibility translator.
|
||||||
|
|
||||||
Follow existing ownership boundaries. Production changes beyond the dependency
|
This unit is an intentional major-release migration. Exact version selection,
|
||||||
and explanation projection are warranted only if focused integration checks
|
release notes, tag/push, and publication timing remain release preparation under
|
||||||
expose a defect in the agreed behavior. Do not change report schemas, provider
|
the [release policy](../policy/release.md). Guided recovery, new report formats,
|
||||||
policy, debug enablement, or application validation to accommodate test fixtures.
|
hot reload, extra configuration commands, and scheduling changes remain outside
|
||||||
Do not add live-provider checks or permanent release gates. This plan does not
|
this plan. Tests should protect changed integration behavior and established
|
||||||
select a release version, modify release policy, publish, tag, or push.
|
contracts, not reproduce the libraries' entire validation matrices.
|
||||||
|
|
||||||
## Stage 1 — Upgrade the Dependency and Its Attribution
|
## Stage 1 — Convert Embedded Prompt Definitions
|
||||||
|
|
||||||
**Completion:** Complete.
|
**Primary files:** The seven YAML files under
|
||||||
|
`internal/prompts/assets/prompts/`.
|
||||||
|
|
||||||
**Primary files:** `go.mod`, `go.sum`, `docs/oss/attribution.md`.
|
1. Wrap each existing definition beneath `prompts`, its exact current ID, and
|
||||||
|
the string version `v1`. Remove the old inner `id` and `version` fields.
|
||||||
|
Keep filenames and Audita registry identifiers unchanged; filenames are
|
||||||
|
asset locations rather than PromptKit identities.
|
||||||
|
2. Preserve messages, block-scalar text, variable references, task examples,
|
||||||
|
output settings, and schema paths. Preserve the applicable references to
|
||||||
|
`HardeningPolicy`, `ProposalContract`, and `ValidationContract`. Do not edit
|
||||||
|
shared fragments, response schemas, or domain policies to accommodate the
|
||||||
|
new container format.
|
||||||
|
3. Review each before/after definition structurally, including YAML indentation
|
||||||
|
inside block scalars. Do not introduce default profile selections or new
|
||||||
|
repair counts. The adapter continues to own the runtime output contract.
|
||||||
|
|
||||||
1. Review the current dependency declarations and upgrade only ConfigKit:
|
**Verification and completion:** Check all seven migrated identities and
|
||||||
`go get gitea.maximumdirect.net/eric/ConfigKit@v0.5.0`. Review the resolved
|
version keys against `RegisteredMetadata`, and run `git diff --check`. Registry
|
||||||
module diff; preserve PromptKit, both catalog modules, the Go minimum, and
|
preparation tests become runnable with the new constructor in Stage 3. Commit
|
||||||
unrelated dependency selections. Do not add a local replacement.
|
the asset conversion; do not introduce an old-format reader to test it here.
|
||||||
2. Check the selected release's `COPYRIGHT`, `LICENSE`, and `go.mod` against the
|
|
||||||
pinned upstream revision. Update the ConfigKit attribution entry's version
|
## Stage 2 — Migrate Operator Profiles, Example Roots, and YAML Fixtures
|
||||||
and commit-pinned source and notice links. Preserve its verified copyright,
|
|
||||||
LGPL-3.0-or-later expression, and existing LGPL/GPL text links when unchanged.
|
**Primary files:** `examples/profiles/`, the three maintained configuration
|
||||||
Follow the existing House Format; no additional licensing machinery is needed.
|
examples, and profile-producing test fixtures in
|
||||||
3. Leave the loader and profile integration intact. If the dependency introduces
|
`internal/framework/llm/{runtime_inspection,adapter,adapter_capacity}_test.go`,
|
||||||
a compilation failure, make only the API adjustment needed for this upgrade,
|
`internal/framework/proposal_generation/adapter_integration_test.go`,
|
||||||
recording the actual difference rather than broadening scope.
|
`internal/framework/validators/llm_integration_test.go`,
|
||||||
|
`internal/framework/runner/cancellation_test.go`, and
|
||||||
|
`cmd/audita/main_integration_test.go`.
|
||||||
|
|
||||||
|
1. Move local proposal/validation examples beneath `profiles/local/`; move the
|
||||||
|
four service proposal/validation and testing files beneath
|
||||||
|
`profiles/service/`. Convert each to `profiles: {<ID>: <fields>}` in readable
|
||||||
|
YAML. Keep IDs, models, positive timeouts, and controls, including explicit
|
||||||
|
zero temperature. No example needs a real credential or live model.
|
||||||
|
2. Set `profiles_dir: profiles/local` in `examples/minimal-config.yml` and
|
||||||
|
`examples/configkit-inheritance.yml`; set `profiles_dir: profiles/service`
|
||||||
|
in `examples/production-config.yml`. Preserve the testing overlay's role IDs
|
||||||
|
and the existing ConfigKit inheritance example. Select the leaf root, since
|
||||||
|
recursive discovery at their common parent would still load both groups.
|
||||||
|
3. Convert profile YAML emitted by the listed fixtures to keyed definitions.
|
||||||
|
Search for remaining old profile construction strings and removed
|
||||||
|
`base_profile` syntax, and migrate any genuine profile fixture found.
|
||||||
|
Do not rewrite transcript/proposal `id` fields or domain schema fixtures.
|
||||||
|
Keep test source names independent of profile IDs where already exercised.
|
||||||
|
4. Keep negative tests negative for their selected behavioral reason. Give
|
||||||
|
cases clean temporary layouts or replace their contribution completely
|
||||||
|
rather than leaving an unrelated invalid definition behind for later cases.
|
||||||
|
Eager validation now reads unselected final definitions too. Do not remove
|
||||||
|
such definitions merely to simulate the old lazy loader where the test is
|
||||||
|
intended to exercise eager validation.
|
||||||
|
|
||||||
|
**Verification and completion:** Review the six profiles, explicit root
|
||||||
|
selections, and changed fixture text; run `git diff --check` and format touched
|
||||||
|
Go test files. These formats become consumable in Stage 3. Commit this unit.
|
||||||
|
Current documentation links and recipes are updated together in Stage 8.
|
||||||
|
|
||||||
|
## Stage 3 — Adopt the Released Source API and Selected-Role Checks
|
||||||
|
|
||||||
|
**Primary files:** `go.mod`, `go.sum`,
|
||||||
|
`internal/framework/llm/runtime.go`, and `internal/prompts/registry_test.go`.
|
||||||
|
|
||||||
|
1. Upgrade with `go get gitea.maximumdirect.net/eric/promptkit@v0.12.0` and
|
||||||
|
reconcile the module files. Verify ConfigKit stays v0.5.0, the catalog
|
||||||
|
dependencies become `/v3` at `v3.20260930.0`, and obsolete `/v2` requirements
|
||||||
|
are removed when unused. Retain the Go minimum and unrelated selections;
|
||||||
|
introduce no local replacements.
|
||||||
|
2. Resolve `profiles_dir` exactly as the current runtime does. Obtain embedded
|
||||||
|
inputs with `pk.FilesystemInputs` and operator inputs with `pk.DirectoryInputs`.
|
||||||
|
An unavailable selected root is an operator error; an empty directory can
|
||||||
|
contribute no definitions. Do not require one profile per file, IDs matching
|
||||||
|
filenames, or profile-only top-level content.
|
||||||
|
3. Construct the agreed `pk.ConfigurationSources`: two ordered caller underlays
|
||||||
|
for embedded and operator groups, and one highest-priority application
|
||||||
|
`ck.Input` whose source is the mapping specified above. Retain
|
||||||
|
`pk.WithSchemaFS`, the supplied HTTP client, and configured transient retries.
|
||||||
|
Remove old prompt/profile/backend registration options.
|
||||||
|
4. Inspect registered prompt ID/version selections, then both selected roles.
|
||||||
|
Reject a selected role whose effective model or endpoint is empty or
|
||||||
|
whitespace-only. Retain backend registration, normalized endpoint equality,
|
||||||
|
nonblank effective `APIKeyEnv` rejection, and required-credential checks.
|
||||||
|
Preserve literal IDs; do not trim/re-key identities or require all profiles
|
||||||
|
to be complete. Populate the same role inspection map for both clients.
|
||||||
|
5. Migrate the registry test engine to `FilesystemInputs` and a programmatic
|
||||||
|
`ProfileSource` fixture in its own tier, retaining its schema filesystem.
|
||||||
|
A complete endpoint/model fixture without an application backend is valid
|
||||||
|
for this direct library test; Audita's selected-role guard belongs in its
|
||||||
|
runtime tests. Keep the embedded prompt preparation assertions scoped to
|
||||||
|
embedded prompts.
|
||||||
|
6. Remove the old `profileSourceFS` wrapper once unused. Source accounting is
|
||||||
|
completed in Stage 5. Preserve the adapter boundary; change other production
|
||||||
|
callers only to resolve actual API incompatibilities. Search for remaining
|
||||||
|
uses of removed source options and old `pk.Profile`/`pk.Backend` values.
|
||||||
|
Run `go mod tidy` after migrating construction callers and review its diff.
|
||||||
|
|
||||||
|
**Verification and completion:** Run `go test ./internal/prompts` and the
|
||||||
|
existing offline profile assembly, unsafe-selection, and absolute-directory
|
||||||
|
tests in `internal/framework/llm`. Run `git diff --check` and review the module
|
||||||
|
diff. The obsolete file-reload assertion is intentionally replaced in Stage 6;
|
||||||
|
do not restore reload behavior to make that assertion pass. Commit the runtime
|
||||||
|
API migration.
|
||||||
|
|
||||||
|
## Stage 4 — Preserve Startup Failure Classification and Validate Assembly
|
||||||
|
|
||||||
|
**Primary files:** `internal/framework/llm/runtime.go`,
|
||||||
|
`internal/framework/llm/runtime_inspection_test.go`, and configuration-command
|
||||||
|
tests in `internal/cli`. Update `internal/cli/run.go` only where the changed
|
||||||
|
startup path needs existing exit behavior preserved.
|
||||||
|
|
||||||
|
1. Treat embedded discovery failures as `AssetError`; treat operator-directory
|
||||||
|
discovery failures as configuration input errors. Preserve wrapped causes
|
||||||
|
for `errors.Is`/`errors.As` and retain configured-secret redaction at CLI
|
||||||
|
boundaries. Caller cancellation remains a runtime exit, not an operator
|
||||||
|
mistake, and should not trigger further diagnostic loading.
|
||||||
|
2. PromptKit wraps both definition-loading and template/content failures in
|
||||||
|
`ErrInvalidConfig`; some materialization errors have no public source/path
|
||||||
|
type. Do not classify by parsing error strings or by that sentinel alone.
|
||||||
|
On final engine-construction failure, perform an embedded-only diagnostic
|
||||||
|
construction with the same embedded prompt/schema sources and library
|
||||||
|
defaults, excluding operator inputs and application backend mappings. If
|
||||||
|
that also fails, surface an `AssetError` with the asset cause; otherwise
|
||||||
|
return the original final-construction error as an operator/configuration
|
||||||
|
error. The diagnostic engine does no provider work and is never retained
|
||||||
|
for execution. Keep a small unexported assembly seam accepting an embedded
|
||||||
|
filesystem so tests can exercise asset failures without modifying shipped
|
||||||
|
files or creating a global test hook.
|
||||||
|
3. Do not run this diagnostic construction as a successful-path preflight.
|
||||||
|
A valid final snapshot remains accepted even if an operator contribution
|
||||||
|
repairs an otherwise invalid lower-tier prompt. Verify that property with
|
||||||
|
the same small assembly test seam. This avoids strengthening upstream
|
||||||
|
final-value validation into mandatory validation of displaced definitions.
|
||||||
|
4. Cover incomplete selected profiles using omitted, empty, and null model
|
||||||
|
contributions and a cleared selected endpoint. Exercise proposal and
|
||||||
|
validation selection, including omission-derived validation selection, with
|
||||||
|
a rejecting HTTP transport. Confirm valid unselected partial profiles are
|
||||||
|
accepted; malformed unselected definitions, undefined backend references,
|
||||||
|
and conflicting directory contributions still fail under native rules.
|
||||||
|
5. Add focused boundary coverage that invalid operator YAML/template/resource
|
||||||
|
input produces configuration exit `2`, and test the asset classification
|
||||||
|
directly at the runtime seam. Reuse existing CLI handling of `AssetError`
|
||||||
|
for exit `1`; no damaged-binary subprocess fixture is needed. Cover the
|
||||||
|
shared `NewRuntime` validation route and preserve cancellation exit `1` in
|
||||||
|
configuration commands if the new error path would otherwise classify it
|
||||||
|
as `2`. Avoid exact complete diagnostic wording assertions.
|
||||||
|
|
||||||
|
**Verification and completion:** Run targeted startup/inspection tests and
|
||||||
|
`go test ./internal/cli`; check whitespace and commit. Preserve the original
|
||||||
|
failure cause where available rather than flattening it to a generic error.
|
||||||
|
|
||||||
|
## Stage 5 — Protect Consumed Configuration and Message Files
|
||||||
|
|
||||||
|
**Primary files:** `internal/framework/llm/runtime.go` or a focused source-path
|
||||||
|
helper in that package, `internal/cli/process.go`, runtime source-accounting
|
||||||
|
tests, and `cmd/audita/main_integration_test.go`.
|
||||||
|
|
||||||
|
1. Rename the internal `Runtime.ProfilePaths` field to `SourcePaths` and update
|
||||||
|
its process caller. It now covers consumed host YAML and message resources,
|
||||||
|
rather than profiles alone. Populate it from the successfully captured final
|
||||||
|
engine; do not expose source metadata as a new public output.
|
||||||
|
2. Call `InspectConfiguration`. Index `Sources()` by source ID, and collect
|
||||||
|
paths with `Kind == ck.SourceKindFile`; embedded filesystem and synthetic
|
||||||
|
sources are not host paths. All loaded host YAML counts, including unused
|
||||||
|
definitions and files whose contributions were later overlaid. Deduplicate
|
||||||
|
paths and sort for a stable internal projection.
|
||||||
|
3. For message resources, enumerate `Metadata().HistoricalPaths()` and retain
|
||||||
|
effective, nonnull paths shaped as
|
||||||
|
`/prompts/<id>/<version>/messages/<index>/content_file`. Use `Lookup` and the
|
||||||
|
effective field's origin, not an inherited destination's guessed source.
|
||||||
|
PromptKit successfully captures these fields only with a unique usable
|
||||||
|
source context. Obtain the effective scalar from `Explain(path).Effective`
|
||||||
|
and decode that scalar YAML into a string with the existing YAML dependency.
|
||||||
|
This decodes captured inspection data; it is not a second configuration
|
||||||
|
loader. When the contributing source is a host file, join the untrimmed
|
||||||
|
resource name against that source file's directory and add it to the ledger.
|
||||||
|
Ignore displaced references and non-host resources. Do not reread operator
|
||||||
|
YAML, infer IDs from filenames, or reimplement resource-root validation.
|
||||||
|
4. Pass `SourcePaths` through existing `diagnostics.PrepareOutput` protection.
|
||||||
|
Leave canonicalization, symlink/hardlink checks, permitted in-place transcript
|
||||||
|
handling, and output initialization with their current owner. Do not protect
|
||||||
|
every unrelated file in the selected directory or add filesystem mutation
|
||||||
|
guarantees beyond the existing collision contract.
|
||||||
|
5. Extend `TestSubprocessProfileSources` and a focused runtime case to cover an
|
||||||
|
arbitrarily named YAML contribution, a consumed source-relative message
|
||||||
|
file, and conflicting transcript/report destinations. Use a non-YAML message
|
||||||
|
filename, such as `instruction.md`, so directory discovery does not mistake
|
||||||
|
plain prompt text for a configuration document. Include an inherited message
|
||||||
|
reference from a different directory and a prompt ID/version with a JSON
|
||||||
|
Pointer escape character so source provenance and literal keys determine
|
||||||
|
the path. Check rejection before provider dispatch and unchanged input bytes.
|
||||||
|
Preserve acceptance of an unused alternate output filename; do not turn the
|
||||||
|
whole directory into a forbidden output location.
|
||||||
|
|
||||||
|
**Verification and completion:** Run focused source-ledger tests and subprocess
|
||||||
|
collision cases, plus `git diff --check`, then commit. Check that resource
|
||||||
|
accounting uses the frozen snapshot and never changes the engine's source or
|
||||||
|
resource-resolution behavior to facilitate tracking.
|
||||||
|
|
||||||
|
## Stage 6 — Verify Operator Prompt Overrides and Captured Execution
|
||||||
|
|
||||||
|
**Primary files:** `internal/framework/llm/adapter_test.go` and focused runtime
|
||||||
|
tests. Change `adapter.go` only for an actual integration defect.
|
||||||
|
|
||||||
|
1. Add a native keyed operator contribution overriding messages for an active
|
||||||
|
prompt/version. Use the real runtime and controlled HTTP responses to prove
|
||||||
|
the operator text reaches both the prepared snapshot and dispatched request.
|
||||||
|
One case deliberately omits shared-variable references and still succeeds;
|
||||||
|
do not require Audita to inject their text. A reference-bearing case renders
|
||||||
|
the adapter-supplied value and retains existing protection against caller
|
||||||
|
variables replacing the reserved shared variables.
|
||||||
|
2. Override the prompt's definition-level output contract with another valid
|
||||||
|
upstream contract. Prove that Audita's per-call JSON schema and configured
|
||||||
|
repair budget still govern execution: a structurally invalid response is
|
||||||
|
repaired or exhausted as the controlled budget dictates. Domain validators
|
||||||
|
remain downstream. Reuse existing validator/proposal integration coverage
|
||||||
|
for their rules rather than weakening them to fit an operator prompt.
|
||||||
|
3. Replace the reload portion of
|
||||||
|
`TestPreparedAdapterRejectsTargetDriftAndPreparationErrors`. After successful
|
||||||
|
construction, change a profile or message file and verify the existing
|
||||||
|
runtime still uses its captured settings/text. Construct a new runtime to
|
||||||
|
observe a valid edit or reject a newly mismatched endpoint. Keep the missing
|
||||||
|
prompt preparation failure case.
|
||||||
|
4. Retain a focused test of the prepared-target check independently of reload:
|
||||||
|
deliberately change the test runtime's application backend endpoint after
|
||||||
|
construction and verify the inconsistency is blocked before dispatch. This
|
||||||
|
tests the existing guard, not a supported live mutation/reload feature.
|
||||||
|
Continue executing the same prepared handle whose details were inspected;
|
||||||
|
do not add another preparation or an application-side retry loop.
|
||||||
|
|
||||||
|
**Verification and completion:** Run the prompt override, snapshot, and
|
||||||
|
prepared-adapter tests. Compare semantic messages and selected targets, not old
|
||||||
|
hash values or exact YAML formatting. Check whitespace and commit.
|
||||||
|
|
||||||
|
## Stage 7 — Verify Native Profiles, Backend Authority, and Resilience
|
||||||
|
|
||||||
|
**Primary files:** Runtime inspection and adapter tests,
|
||||||
|
`internal/framework/llm/adapter_capacity_test.go`, and existing framework/CLI
|
||||||
|
integration tests where their established behavior is affected.
|
||||||
|
|
||||||
|
1. Add a compact native profile inheritance fixture with literal keyed IDs
|
||||||
|
unrelated to filenames, multiple definitions in one file, a partial parent,
|
||||||
|
and a complete selected child. Verify inherited controls survive a child
|
||||||
|
model change and child overrides win. Reuse the metadata-facing literal-key
|
||||||
|
coverage from Stage 5 rather than repeating it in profile tests.
|
||||||
|
2. Use controlled HTTP request bodies to distinguish explicit zero temperature
|
||||||
|
from omission and inherited-control suppression by null. Check a
|
||||||
|
representative recursively overlaid provider parameter and null clearing;
|
||||||
|
do not promise that all providers accept every valid configured zero.
|
||||||
|
Reuse existing deadline/cancellation coverage for unchanged outer deadlines;
|
||||||
|
explicit zero profile timeout must not disable the operation context.
|
||||||
|
3. Verify an operator backend contribution can add supported provider fields,
|
||||||
|
while a conflicting endpoint/concurrency/queue/environment contribution
|
||||||
|
cannot displace the final application fields. Preserve an explicit profile
|
||||||
|
environment lookup as a selected-role error rather than hiding it with an
|
||||||
|
adapter override. Include an application backend using a catalog ID to show
|
||||||
|
it is allowed and its catalog credential lookup is suppressed. Use synthetic
|
||||||
|
environment values and local HTTP fixtures, not provider catalog endpoints.
|
||||||
|
4. Reuse `TestRolesShareBackendCapacityAndReleaseAfterCancellation` and
|
||||||
|
`TestDistinctBackendsHaveIndependentCapacity`; verify the final mapped
|
||||||
|
limits, including zero queue capacity, still coordinate both roles and
|
||||||
|
remain backend-local. Strengthen a fixture with conflicting lower-tier
|
||||||
|
capacity only where needed to prove the new mapping wins. Keep existing
|
||||||
|
synchronization; do not infer admission with sleeps or add another limiter.
|
||||||
|
5. Preserve offline selected-profile inspection and value-free application
|
||||||
|
explanations. Check configured secrets, endpoint strings, arbitrary provider
|
||||||
|
fields, and prompt text remain outside the current safe profile summary.
|
||||||
|
Do not replace it with a full upstream dump. Its numeric projection is not
|
||||||
|
proof that an omitted provider setting is sent; wire presence belongs to
|
||||||
|
the HTTP coverage above.
|
||||||
|
6. Run the existing transient retry, structural repair, attempt-count,
|
||||||
|
observation, partial-validation, and all-model-failure subprocess cases
|
||||||
|
after fixture migration. Preserve their error/recovery/debug classifications,
|
||||||
|
cancellation, and continued output. Fix proven integration regressions;
|
||||||
|
do not rewrite domain outcomes or reduce budgets to obtain a passing suite.
|
||||||
|
|
||||||
**Verification and completion:** Run
|
**Verification and completion:** Run
|
||||||
`go test ./internal/core/config ./internal/cli ./internal/framework/llm` and
|
`go test ./internal/framework/llm ./internal/framework/proposal_generation ./internal/framework/validators ./internal/framework/runner ./internal/cli ./cmd/audita`
|
||||||
`git diff --check`. Review the dependency and attribution diff, then commit.
|
and `git diff --check`. Review whether each new test addresses a distinct changed
|
||||||
This establishes the upgraded baseline; it does not establish feature completion
|
boundary. Commit the native-profile and runtime verification unit.
|
||||||
or replace the final suite in Stage 5.
|
|
||||||
|
|
||||||
## Stage 2 — Verify Inherited Configuration, Defaults, and Credentials
|
## Stage 8 — Document the Migration and Update Attribution
|
||||||
|
|
||||||
**Completion:** Complete.
|
**Primary files:** `docs/config.md`, `docs/internal/llm-runtime.md`,
|
||||||
|
`docs/internal/prompts.md`, `docs/integrations/openai-compatible-llm.md`,
|
||||||
|
`docs/operations.md`, `docs/internal/cli-config.md`, `README.md`, and
|
||||||
|
`docs/oss/attribution.md`.
|
||||||
|
|
||||||
**Primary files:** `internal/core/config/config_test.go`; change
|
1. Update the configuration contract for unified `profiles_dir` content, exact
|
||||||
`internal/core/config/config.go` only if these checks expose an integration defect.
|
keyed identities, directory composition, agreed tier precedence, profile
|
||||||
|
inheritance/presence, selected-role completeness, eager validation of all
|
||||||
|
final definitions, selected-root failures, and construction-time capture.
|
||||||
|
Replace the obsolete statement that PromptKit profiles do not gain ConfigKit
|
||||||
|
inheritance. Retain application overlays, defaults, and credential ownership.
|
||||||
|
2. Include concise migration instructions in the profile section: wrap old
|
||||||
|
profile fields beneath `profiles/<id>`, remove inner `id`, change
|
||||||
|
`base_profile` to `extends`, review explicit values/nulls, and select roots
|
||||||
|
whose final definitions have valid backend references. Show a small keyed
|
||||||
|
inheritance/override snippet and link complete maintained examples. Explain
|
||||||
|
explicit zero temperature versus omitted or null controls and link upstream
|
||||||
|
for the full field table. State that this ships as an Audita major migration;
|
||||||
|
do not invent an exact release version or automatic file conversion.
|
||||||
|
3. Document intentional prompt overrides and optional shared-variable references.
|
||||||
|
Supplying shared variables does not inject omitted text, while per-call
|
||||||
|
schemas and domain validators remain enforced. Internal prompt documentation
|
||||||
|
distinguishes shipped asset instructions from operator-effective messages;
|
||||||
|
no prompt-quality rewrite or new global prompt-policy requirement is added.
|
||||||
|
4. Describe layered runtime assembly, source accounting, snapshot use, and
|
||||||
|
startup classification in their internal owner. Update the pinned PromptKit
|
||||||
|
consumer link in the LLM integration contract. Expand operations' loaded
|
||||||
|
source description to include consumed operator message files; keep physical
|
||||||
|
output/collision rules with operations and diagnostics.
|
||||||
|
5. Repair example navigation for separate local/service roots, especially the
|
||||||
|
README's local-profile link. Update validation recipes to use the maintained
|
||||||
|
config files' explicit roots and keep the service testing overlay workflow.
|
||||||
|
Review other affected links without rewriting historical release notes.
|
||||||
|
6. Update the PromptKit and both catalog attribution entries to selected versions
|
||||||
|
and exact commit-pinned source/notice URLs. Resolve catalog tag commits from
|
||||||
|
the selected module origins or authoritative upstream refs, not annotated
|
||||||
|
tag object IDs. Check the releases' COPYRIGHT/LICENSE files and retain the
|
||||||
|
applicable unchanged local LGPL/GPL and MIT texts. Keep the existing House
|
||||||
|
Format; no new license selection, policy rewrite, or attribution inventory
|
||||||
|
is needed. Review `go.mod`/`go.sum` against those entries.
|
||||||
|
|
||||||
1. Read `Load`, its resolver, and domain validation. Existing backend capacity
|
**Verification and completion:** Check affected local links/anchors, format
|
||||||
defaults use `Resolution.IsExplicit`; omitted validation-role selection uses
|
examples against the implemented loader, verify source revisions/notices, and
|
||||||
`ck.Default` against the final proposal selection. Keep those mechanisms if
|
run `git diff --check`. Commit the documentation and attribution unit.
|
||||||
they already handle inherited presence correctly.
|
|
||||||
2. Add a focused real-loader fixture with valid parent and child backends. The
|
|
||||||
child inherits an endpoint, concurrency, zero queue capacity, and a synthetic
|
|
||||||
credential reference. Check effective values and inherited explicitness;
|
|
||||||
in another case, let the child override concurrency. This protects against
|
|
||||||
replacing inherited capacity with Audita's absent-field defaults. Reuse
|
|
||||||
current tests for ordinary omitted defaults.
|
|
||||||
3. Exercise precedence with a selected overlay that changes a parent's setting
|
|
||||||
and a child override that wins over its resolved parent. Preserve coverage
|
|
||||||
that an explicit proposal-profile override wins over the overlay and omitted
|
|
||||||
validation-profile selection derives from that final value. Use the existing
|
|
||||||
`TestOverlayOverrideAndInheritance` fixture where useful; its current
|
|
||||||
"inheritance" check covers role derivation, not native sibling inheritance.
|
|
||||||
4. Extend credential coverage using controlled environment variables. Check that
|
|
||||||
an inherited reference resolves and that effective YAML excludes its resolved
|
|
||||||
value. A child's `credential: null` removes only that child's reference;
|
|
||||||
the parent's surviving reference still must resolve, even if the parent is
|
|
||||||
unselected. Check that an unset surviving reference fails and a missing
|
|
||||||
reference removed by final precedence is not resolved. Reuse
|
|
||||||
`TestSurvivingCredentials` rather than duplicating all secret cases.
|
|
||||||
5. Include a representative inherited setting that violates existing Audita
|
|
||||||
validation, such as zero backend concurrency. Inheritance must not bypass
|
|
||||||
validation of either the parent or child. Existing explicit-empty/null role
|
|
||||||
validation cases remain applicable; extend them only if inherited presence
|
|
||||||
exposes an uncovered interaction.
|
|
||||||
6. If a regression appears, correct the owning default or resolution integration
|
|
||||||
using ConfigKit presence/path APIs. Do not parse raw YAML, exempt parent
|
|
||||||
backends, or introduce abstract backend templates. Do not reproduce upstream
|
|
||||||
cycle, nesting, or expansion-limit tests.
|
|
||||||
|
|
||||||
**Verification and completion:** Run `go test ./internal/core/config` and
|
## Stage 9 — Validate the Integrated End State and Close the Plan
|
||||||
`git diff --check`. Review assertions for new validation rules or duplicated
|
|
||||||
library tests, then commit the focused configuration unit.
|
|
||||||
|
|
||||||
## Stage 3 — Expose Compact Inheritance Evidence in Safe Inspection
|
**Primary files:** This plan and the feature roadmap; correct an implementation
|
||||||
|
file only if the final checks reveal an actual gap.
|
||||||
|
|
||||||
**Completion:** Complete.
|
1. Verify the full roadmap acceptance criteria against the landed code and the
|
||||||
|
distinct tests from these stages. Review for unintended requirements:
|
||||||
|
profile-only filtering, mandatory shared text in operator messages,
|
||||||
|
filename-derived IDs, complete unselected profiles, catalog ID bans,
|
||||||
|
successful-path asset preflights, compatibility readers, and new output
|
||||||
|
guarantees are not part of the accepted target.
|
||||||
|
2. Run `go build -o ./bin/audita ./cmd/audita` and `go test ./...`. Keep the
|
||||||
|
generated binary out of commits. Reuse successful checks on unchanged
|
||||||
|
content; rerun checks affected by any corrective code changes.
|
||||||
|
3. Validate the maintained examples offline using the built binary:
|
||||||
|
|
||||||
**Primary files:** `internal/framework/llm/safe_view.go`,
|
```sh
|
||||||
`internal/framework/llm/runtime_inspection_test.go`, `docs/cli.md`, and the
|
./bin/audita config validate --config examples/minimal-config.yml
|
||||||
relevant explanation description in `docs/internal/llm-runtime.md` if needed.
|
./bin/audita config validate --config examples/configkit-inheritance.yml
|
||||||
|
AUDITA_SERVICE_KEY=synthetic-example ./bin/audita config validate --config examples/production-config.yml
|
||||||
|
AUDITA_SERVICE_KEY=synthetic-example ./bin/audita config validate --config examples/production-config.yml --overlay testing
|
||||||
|
./bin/audita config print-effective --config examples/minimal-config.yml --view profiles
|
||||||
|
./bin/audita config print-effective --config examples/configkit-inheritance.yml --view explain
|
||||||
|
```
|
||||||
|
|
||||||
1. Extend `explanationView` with `inheritance,omitempty` and a small step view
|
Confirm local/service roots and testing selections work without provider
|
||||||
containing `from`, `to`, and `reference`. For effective field records, project
|
dispatch. Check safe views exclude resolved secrets and preserve the
|
||||||
`info.Origin.Inheritance` in its upstream order. Preserve existing `path`,
|
established explanation fields. Do not call a model to validate examples.
|
||||||
`source`, `layer`, and application `derivations` behavior. Do not serialize
|
4. Check the selected dependency graph, attribution, affected links, and final
|
||||||
field values, whole `Explanation` objects, resolved credentials, or arbitrary
|
diff. Run `git diff --check`. Confirm only the released modules are used and
|
||||||
configuration content into this view.
|
no obsolete `/v2` catalog or removed construction API remains in active code.
|
||||||
2. Continue to use `Metadata.Lookup`, `HistoricalPaths`, and existing derivation
|
Historical release documents and historical roadmap links may retain old
|
||||||
mapping. Do not infer ancestry from labels or YAML, flatten a chain to one
|
versions as accurate records.
|
||||||
guessed parent, or reinterpret inheritance as an application-derived default.
|
5. Mark this plan and the feature roadmap complete only after the full target
|
||||||
This addition describes effective inheritance; complete displaced ancestry
|
passes. Record the tested implementation revision and checks accurately;
|
||||||
and upstream source-coordinate reporting are not new requirements.
|
distinguish a subsequent documentation-only completion commit. Commit the
|
||||||
3. Test decoded YAML for one inherited field's source/destination/reference paths
|
completion documentation and report remaining work, if any. Do not select
|
||||||
and a child field that directly overrides its parent. Include an inherited
|
a release number, publish, tag, push, poll CI, or add permanent release gates.
|
||||||
credential reference with a distinctive synthetic resolved value and prove
|
|
||||||
that value is absent. Retain existing application-derived role explanations
|
|
||||||
and safe profile-view coverage. Assert meaningful records, not complete
|
|
||||||
YAML snapshots or upstream-generated identifiers.
|
|
||||||
4. Check the existing shared callers: CLI explain uses `ExplanationYAML`, and
|
|
||||||
`processState.startDebug` uses it for configuration origins. Keep this shared
|
|
||||||
path; no separate debug projection is needed. Update the CLI contract with
|
|
||||||
the optional inheritance step fields and their value-free meaning once they
|
|
||||||
are implemented. Link internal documentation to that contract for exact shape.
|
|
||||||
|
|
||||||
**Verification and completion:** Run
|
**End state:** Native PromptKit configuration and catalogs are adopted,
|
||||||
`go test ./internal/framework/llm ./internal/cli` and `git diff --check`.
|
operator overrides and captured resources work through the real runtime,
|
||||||
Review emitted fields and affected documentation, then commit the inspection unit.
|
application backend/domain ownership and resilience remain effective, and
|
||||||
|
maintained examples and migration documentation match the implementation.
|
||||||
## Stage 4 — Verify CLI Failures and Runtime Use of Inherited Backends
|
No implementation-blocking decisions remain; exact major-release numbering
|
||||||
|
and publication timing remain outside this implementation unit.
|
||||||
**Completion:** Complete.
|
|
||||||
|
|
||||||
**Primary files:** `internal/framework/llm/adapter_capacity_test.go`,
|
|
||||||
`internal/cli/config_input_test.go`, and
|
|
||||||
`cmd/audita/main_integration_test.go`. Touch production wiring only to fix a
|
|
||||||
proven integration defect.
|
|
||||||
|
|
||||||
1. Reuse `TestRolesShareBackendCapacityAndReleaseAfterCancellation` or its
|
|
||||||
existing fixture to load a valid parent and a selected child backend through
|
|
||||||
`config.Load`. Both existing-format role profiles select that child. Inherit
|
|
||||||
the controlled server endpoint, a test-selected positive capacity, zero
|
|
||||||
queue capacity, and a synthetic credential; keep the parent valid too.
|
|
||||||
2. Verify actual requests reach the inherited endpoint and carry the inherited
|
|
||||||
credential. Existing overlapping role-call coverage proves that the two
|
|
||||||
roles share the child's capacity. Preserve that check with inherited input
|
|
||||||
and its release/cancellation coverage; do not build another scheduler or
|
|
||||||
duplicate the provider retry/repair matrix. Use synchronization already in
|
|
||||||
the test, not sleeps to infer admission behavior.
|
|
||||||
3. Add one representative invalid relationship at the CLI boundary: a missing
|
|
||||||
sibling parent should yield configuration exit code `2` and no provider
|
|
||||||
dispatch. Use the existing subprocess fixture and semantic diagnostic
|
|
||||||
assertions; do not freeze full error text or invent early-failure reports.
|
|
||||||
4. Extend one representative subprocess success/inspection case to use inherited
|
|
||||||
backend input. With debug explicitly enabled, check that effective settings
|
|
||||||
and configuration-origin artifacts retain inherited settings and the new
|
|
||||||
explanation evidence without the resolved synthetic secret. Check the
|
|
||||||
explain view through the existing CLI route. Use existing coverage for
|
|
||||||
unchanged report placement, ordinary processing, and debug-disabled behavior.
|
|
||||||
Keep assertions on the affected fields rather than the entire artifact set.
|
|
||||||
|
|
||||||
**Verification and completion:** Run
|
|
||||||
`go test ./internal/framework/llm ./internal/cli ./cmd/audita` and
|
|
||||||
`git diff --check`. Review whether each added test covers a distinct integration
|
|
||||||
risk, then commit the runtime/CLI verification unit.
|
|
||||||
|
|
||||||
## Stage 5 — Document Native Inheritance and Close the Adoption Unit
|
|
||||||
|
|
||||||
**Completion:** Complete.
|
|
||||||
|
|
||||||
**Primary files:** `docs/config.md`, `examples/configkit-inheritance.yml`,
|
|
||||||
`docs/internal/cli-config.md`, and `docs/roadmap/configkit.md`. Update another
|
|
||||||
canonical document only where an implemented statement actually changes.
|
|
||||||
|
|
||||||
1. Add `examples/configkit-inheritance.yml` beside the existing examples, with
|
|
||||||
`version: 2`, a valid `local-base` backend, and a valid `local` backend that
|
|
||||||
extends it. Inherit a local endpoint and zero queue capacity; use a positive
|
|
||||||
parent concurrency and a child concurrency override. Select the existing
|
|
||||||
`local-proposal` and `local-validation` profiles under `profiles/` and the
|
|
||||||
grammar module. The example needs no credential or new profile format and
|
|
||||||
can be validated offline without a running local server.
|
|
||||||
2. Update the configuration contract to describe native sibling inheritance,
|
|
||||||
precedence before inheritance, inherited explicit presence, null credential
|
|
||||||
removal, and normal parent validation. Link the maintained example and the
|
|
||||||
version-pinned upstream generic grammar. Retain current file/overlay/override
|
|
||||||
behavior and main-file-relative path rules. Do not imply that ordinary
|
|
||||||
PromptKit v0.11.2 profile files now accept ConfigKit `extends` syntax.
|
|
||||||
3. Document that `extends` is reserved across input mappings. Explain the legacy
|
|
||||||
backend-name conflict and migration: rename the backend to a non-conflicting
|
|
||||||
ID and update every profile selecting it. Keep application `version: 2`;
|
|
||||||
do not claim all previously valid configurations are compatible. Record the
|
|
||||||
compatibility finding in the feature roadmap for later release preparation.
|
|
||||||
Release classification remains outside this implementation unit, governed by
|
|
||||||
the existing release policy; no policy exception is selected here.
|
|
||||||
4. Add the new example's offline validation command to the existing example
|
|
||||||
recipe. Validate it and the maintained minimal, production, and selected
|
|
||||||
testing-overlay examples, with a controlled synthetic service credential.
|
|
||||||
Inspect the new example's settings and explanation output. No live model
|
|
||||||
request is needed to check configuration or profiles.
|
|
||||||
5. Run `go build -o ./bin/audita ./cmd/audita`, `go test ./...`, affected-link
|
|
||||||
checks, and `git diff --check`. Review the final dependency graph and diff:
|
|
||||||
ConfigKit is the released v0.5.0, PromptKit/catalogs retain their selections,
|
|
||||||
source attribution is pinned, and no unrelated settings or limits were added.
|
|
||||||
Keep generated binaries out of the commit. Resolve actual failures rather
|
|
||||||
than adding gates unrelated to this feature.
|
|
||||||
6. Mark the feature roadmap and this plan complete only after all stage outcomes
|
|
||||||
pass. Record the tested source revision and checks accurately; if a final
|
|
||||||
documentation-only completion commit follows validation, distinguish it from
|
|
||||||
the tested implementation revision. Review and commit the final documentation
|
|
||||||
unit, leaving a clean workspace. Reuse successful checks for unchanged content.
|
|
||||||
|
|
||||||
**End state:** Native ConfigKit inheritance reaches typed settings, safe
|
|
||||||
inspection, selected runtime backends, and maintained operator examples;
|
|
||||||
PromptKit migration remains a separate unit. No implementation-blocking design
|
|
||||||
questions remain. The eventual release version and treatment of the known
|
|
||||||
compatibility impact remain release-preparation decisions, not prerequisites
|
|
||||||
for these stages.
|
|
||||||
|
|||||||
@@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
**Last updated:** 2026-10-03
|
**Last updated:** 2026-10-03
|
||||||
|
|
||||||
**Status:** Accepted target scope; ready for implementation planning. The
|
**Status:** Accepted target scope; implementation is defined in the
|
||||||
operator-directory scope decision has been resolved. Implementation has not
|
[implementation plan](implementation.md). Implementation has not begun.
|
||||||
begun.
|
|
||||||
|
|
||||||
## Purpose and Baseline
|
## Purpose and Baseline
|
||||||
|
|
||||||
@@ -263,4 +262,5 @@ No live provider calls, new release gates, or CI-success dependency are needed
|
|||||||
to establish adoption. Guided domain recovery and the other work recorded in
|
to establish adoption. Guided domain recovery and the other work recorded in
|
||||||
[future.md](future.md) remain separate features. Do not expand this upgrade into
|
[future.md](future.md) remain separate features. Do not expand this upgrade into
|
||||||
new report formats, pipeline scheduling, or general configuration-inspection
|
new report formats, pipeline scheduling, or general configuration-inspection
|
||||||
commands. A staged implementation plan can now be prepared.
|
commands. The [implementation plan](implementation.md) owns execution steps
|
||||||
|
and their verification.
|
||||||
|
|||||||
Reference in New Issue
Block a user