Plan the PromptKit configuration upgrade
This commit is contained in:
331
docs/roadmap/promptkit.md
Normal file
331
docs/roadmap/promptkit.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# PromptKit 0.12 Configuration Migration
|
||||
|
||||
## Purpose
|
||||
|
||||
Adopt PromptKit v0.12.0 after the completed ConfigKit upgrade, replacing the
|
||||
removed configuration APIs and asset formats with PromptKit's ConfigKit-backed
|
||||
configuration boundary. Make the new composition, inheritance, presence, and
|
||||
captured-configuration capabilities useful without introducing a second loader
|
||||
or changing Notarius's domain extraction and pipeline acceptance policies.
|
||||
|
||||
This is a feature roadmap, not an execution sequence. A separate implementation
|
||||
plan should be prepared after the open decisions below are settled. Release
|
||||
preparation and publication are separate work.
|
||||
|
||||
## Reviewed Baseline
|
||||
|
||||
Reviewed on 2026-10-04 against Notarius commit
|
||||
`af62b3b`, with ConfigKit v0.5.0 and PromptKit v0.11.2 selected in `go.mod`.
|
||||
The remote PromptKit v0.12.0 tag resolves to full source commit
|
||||
`4b8169da286917fde7875425bb32b799b12c6af3`, matching the sibling checkout.
|
||||
Primary upstream references are the
|
||||
[release guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.12.0/docs/releases/v0.12.0.md),
|
||||
[consumer migration guide](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.12.0/docs/consumers/pkg-promptkit.md#migrate-from-the-previous-configuration-api),
|
||||
and [format reference](https://gitea.maximumdirect.net/eric/promptkit/src/tag/v0.12.0/docs/formats.md).
|
||||
These were reviewed in the local checkout; the remote tag was verified directly.
|
||||
|
||||
The current integration has these migration-sensitive boundaries:
|
||||
|
||||
- `internal/framework/llm/asset_registry.go` flattens module-owned prompt,
|
||||
schema, and fallback-profile filesystems and constructs `WithPromptFS`,
|
||||
`WithSchemaFS`, and `WithFallbackProfileFS` options.
|
||||
- `promptkit_profiles.go` shares profile-source construction between the
|
||||
execution client and credential-free explicit-profile inspection. It uses
|
||||
`Config.ProfileDir`, `WithProfileFile`, and the backend registration option.
|
||||
The inspection engine supplies `PromptDir: "."` without preparing a prompt.
|
||||
- `promptkit_client.go` constructs the engine and uses prepared execution,
|
||||
semantic correction messages, structural repair overrides, observations,
|
||||
direct sessions, reasoning overrides, and provider-neutral error adaptation.
|
||||
- `promptkit_profile_fingerprint.go` combines a pinned catalog marker with
|
||||
reread operator profile files and fallback asset bytes. The optional local
|
||||
endpoint contributes a separate identity; local concurrency is excluded.
|
||||
- Embedded prompt definitions throughout `assets/dnd/` and
|
||||
`assets/generic/normalize/deduplication/` use top-level `id` and `version`.
|
||||
`assets/dnd/profiles/dnd-extraction.yaml` and the maintained deployment file
|
||||
`examples/llm-profiles/dnd-extraction.yml` use top-level `id`.
|
||||
- The public profile contract says a matching operator profile completely
|
||||
replaces a fallback or catalog profile. It documents `base_profile`
|
||||
inheritance. These claims do not match v0.12.0's native semantics.
|
||||
|
||||
The current focused LLM, CLI, and module-integration tests pass with
|
||||
`GOWORK=off`. This establishes the baseline only: no trial dependency upgrade,
|
||||
live inference, or production model-quality evaluation has been performed.
|
||||
|
||||
## Upstream Changes Relevant To Notarius
|
||||
|
||||
PromptKit v0.12.0 is an incompatible configuration/API release:
|
||||
|
||||
- `Config.Sources` accepts ordered ConfigKit underlays and an optional main
|
||||
input. Legacy prompt/profile directory fields and configuration-source
|
||||
options are removed. Schema and injected-runtime options remain available.
|
||||
- Documents use keyed `backends`, `profiles`, and `prompts` mappings, with a
|
||||
second version mapping beneath each prompt ID. Embedded `id`, `version`, and
|
||||
`base_profile` fields are invalid; profile inheritance uses `extends`.
|
||||
- Files within one source group compose strictly, not by filename precedence.
|
||||
Later groups overlay earlier groups recursively. Explicit null, zero,
|
||||
false, and empty values can differ from omission; `{}` does not clear a map.
|
||||
- Engine construction validates every final effective definition, including
|
||||
unused definitions, and captures message content and static templates.
|
||||
Ordinary execution and inspection do not reload them. Schemas, request
|
||||
artifacts, credentials, and provider operations retain their runtime timing.
|
||||
- `InspectConfiguration` exposes captured presence, sources, diagnostics,
|
||||
explanations, and redacted effective output. These reports are not
|
||||
automatically safe to publish: ordinary prompt/provider content remains data.
|
||||
- Maintained catalogs move to `/v3`, both at `v3.20260930.0`.
|
||||
PromptKit and Notarius already share the required ConfigKit v0.5.0 and Go
|
||||
1.25.5 baseline; no additional Go-version upgrade is required by this release.
|
||||
|
||||
## Target End State
|
||||
|
||||
### One Native Configuration Boundary
|
||||
|
||||
PromptKit owns the effective backend/profile/prompt configuration and all
|
||||
upstream composition and inheritance. Notarius selects its sources and adapts
|
||||
the resulting engine to the existing provider-neutral completion contract.
|
||||
ConfigKit and PromptKit types remain inside the LLM adapter's explicit
|
||||
integration boundary, not in domain modules or pipeline contracts.
|
||||
|
||||
Retain Notarius configuration `version: 5`, `promptkit.profile_file`,
|
||||
`promptkit.profile_dir`, their mutual exclusion and declaring-file-relative
|
||||
path handling, `transient_retries`, and the optional conventional local backend.
|
||||
Do not add replacement Notarius configuration fields merely because the
|
||||
upstream constructor has changed. Document the changed external file format.
|
||||
|
||||
Use one shared source-construction path for execution and profile preflight.
|
||||
The proposed precedence, subject to the decisions below, is:
|
||||
|
||||
1. PromptKit's maintained catalog layer, supplied by PromptKit itself.
|
||||
2. Registered application prompt and fallback-profile assets.
|
||||
3. The explicitly selected operator file or directory.
|
||||
4. A programmatic `local` backend contribution when Notarius's
|
||||
`promptkit.local_backend` is configured, so those explicit Notarius values
|
||||
win over conflicting file declarations of those fields.
|
||||
|
||||
Inputs within each group use native strict composition. Directory discovery is
|
||||
recursive over YAML files and has no hidden per-file priority. No unselected
|
||||
directory is scanned. Construct filesystem-backed inputs with usable resource
|
||||
contexts so referenced message files retain their declaring-source base.
|
||||
Do not combine host profile files with embedded content under a fabricated
|
||||
common filesystem root.
|
||||
|
||||
Use `FilesystemInputs` for the existing flattened embedded views,
|
||||
`DirectoryInputs` or an individual ConfigKit file input for the operator
|
||||
source, and `BackendSource` with the presence-aware local-backend helper for
|
||||
programmatic backend configuration. Keep schemas on the existing schema
|
||||
filesystem boundary. There is no need to deserialize catalog assets, register
|
||||
catalog backends individually, or recreate PromptKit inheritance.
|
||||
|
||||
The profile-only preflight engine does not need dummy prompt directories or
|
||||
synthetic prompts. It can construct an engine from catalog, fallback, operator,
|
||||
and local-backend sources, then call `InspectProfile`. If an operator source
|
||||
also supplies prompts under the selected source policy, native construction
|
||||
validation applies to them as well. Preflight does not resolve credential
|
||||
values, prepare request artifacts, or contact providers.
|
||||
|
||||
### Keyed Assets Without Prompt Behavior Changes
|
||||
|
||||
Every maintained prompt declaration becomes a keyed document of this shape:
|
||||
|
||||
```yaml
|
||||
prompts:
|
||||
dnd.spells:
|
||||
v1:
|
||||
# Existing definition body, without embedded id/version fields.
|
||||
```
|
||||
|
||||
Profiles become keyed entries beneath `profiles`. Preserve literal prompt IDs,
|
||||
the `v1` version, logical profile IDs, selected response schemas, content paths,
|
||||
message order, roles, shared fragment bytes, cache-control metadata, and
|
||||
configured structural repair budgets. Do not conflate this migration with
|
||||
prompt rewriting, schema changes, or durable artifact version changes.
|
||||
|
||||
The application-owned `dnd-extraction` fallback continues to explicitly select
|
||||
`openrouter`, `openai/gpt-5.6-luna`, timeout 240, and service tier `flex`, with
|
||||
reasoning effort unset. Do not replace that choice with an upstream catalog
|
||||
alias or adopt unrelated model defaults. Migrate the maintained operator
|
||||
example and relevant inline Go/YAML test fixtures as well as production assets.
|
||||
|
||||
Module ownership, ordered asset manifests, scoped mounting, and selected-asset
|
||||
hashing remain intact. Check virtual filenames and source-relative
|
||||
`content_file` resolution after wrapping definitions; do not move business
|
||||
logic into the root `assets` package.
|
||||
|
||||
### Presence, Inheritance, And Operator Migration
|
||||
|
||||
The recommended policy is native recursive overlay, not a compatibility shim
|
||||
for complete-definition replacement. Operators can override only the fields
|
||||
they want. Omitted fields retain lower-layer values, and `extends` uses native
|
||||
literal sibling-key lookup. Changing a backend or model does not erase
|
||||
explicit inherited settings; backend-derived defaults are applied to the
|
||||
final backend after inheritance.
|
||||
|
||||
Document intentional clearing with `null`, including reasoning/service tier,
|
||||
sampling controls, credential lookup, and provider maps where supported.
|
||||
Distinguish null from zero/false/blank and from an empty mapping. For example,
|
||||
switching an operator's `dnd-extraction` overlay to a local model may also need
|
||||
`service_tier: null` to remove the fallback's explicit `flex` setting. Do not
|
||||
automatically scrub settings based on model-name heuristics.
|
||||
|
||||
Translate `base_profile` to `extends` in maintained examples and explain that
|
||||
operators must migrate their external files. Do not retain legacy aliases or
|
||||
an alternate parser. Preserve exact PromptKit keys; do not introduce a new
|
||||
identifier normalization pass. Update tests that assumed whole replacement
|
||||
or selection-time validation deliberately, rather than treating those
|
||||
intentional upstream changes as regressions.
|
||||
|
||||
Native eager validation applies to final effective values, not independently
|
||||
to each superseded contribution. Do not add a source-history audit or raw-layer
|
||||
validation that prevents legitimate overrides from repairing lower layers.
|
||||
|
||||
### Captured Execution And Checkpoint Identity
|
||||
|
||||
One engine represents one captured configuration for its lifetime. Editing
|
||||
operator definitions or message files requires constructing a new engine;
|
||||
there is no watcher or automatic hot reload in this scope. Preserve the normal
|
||||
CLI lifecycle without promising that independently constructed preflight and
|
||||
execution engines are one transactional filesystem snapshot.
|
||||
|
||||
Compute and retain checkpoint identity from the configuration actually
|
||||
captured by the execution engine. Do not identify an old captured engine by
|
||||
files reread after it was constructed. Identity must account for effective
|
||||
profile/backend semantics and the pinned PromptKit/catalog revisions; if
|
||||
operator prompt definitions are admitted, it must also account for their
|
||||
captured prompt content, not just `content_file` path strings.
|
||||
|
||||
Use public captured inspection and prompt-definition equality values where
|
||||
appropriate; do not reach into PromptKit internals. `InspectPrompt.PromptHash`
|
||||
includes captured content and is an opaque equality value. Inspection reports
|
||||
alone do not embed referenced message-file bodies. Preserve application
|
||||
module/schema fingerprints, actual-used profile provenance, and the existing
|
||||
exclusion of concurrency-only local settings from semantic checkpoint identity.
|
||||
A conservative identity across effective profiles is acceptable; per-selected-
|
||||
profile optimization is not a prerequisite for this upgrade.
|
||||
|
||||
Raw sources, configuration history, prompt bodies, endpoints, and credential
|
||||
values must not be added to ordinary manifests or checkpoint metadata. The
|
||||
new inspection API is useful privately for the migration and captured identity;
|
||||
it does not require a new public CLI report or automatic dump into output or
|
||||
debug bundles. Hash-only identity is distinct from publishing an inspection
|
||||
report, and redaction is not a substitute for covering execution semantics.
|
||||
|
||||
### Existing Execution Policies Remain Unchanged
|
||||
|
||||
Preserve prepared execution, the exact latest-response semantic correction
|
||||
pair, prompt-prefix caching, direct sessions, reasoning overrides, cancellation,
|
||||
the shared scheduler, local/backend admission, observer accounting, error
|
||||
classification, and credential redaction. Structural repairs, transient HTTP
|
||||
retries, outer producer attempts, and validator execution budgets remain
|
||||
separate. The existing one-repair maintained prompt default remains unchanged.
|
||||
|
||||
The migration does not change extraction/normalization semantics, warning
|
||||
classification, artifact contracts, subprocess receipts, or reusable-state
|
||||
eligibility. Construction errors may occur earlier under native eager
|
||||
validation; adapt them through the existing safe adapter/CLI error boundary,
|
||||
not by exposing arbitrary upstream configuration content.
|
||||
|
||||
## Required Work
|
||||
|
||||
- Update `go.mod` and `go.sum` to PromptKit v0.12.0 and its selected `/v3`
|
||||
catalogs. Keep ConfigKit v0.5.0 and unrelated dependencies unless module
|
||||
resolution requires a change. Remove obsolete `/v2` requirements after tidy.
|
||||
- Replace removed constructor/source/backend APIs in the LLM adapter and
|
||||
shared profile-preflight construction; retain schema and injected-client
|
||||
options. Remove obsolete adapter helpers rather than layering a parallel
|
||||
configuration system beside them.
|
||||
- Migrate every registered prompt and fallback profile, the maintained
|
||||
deployment profile, and affected test fixtures to keyed definitions.
|
||||
- Adopt the agreed source policy, presence/null behavior, and captured
|
||||
lifetime; replace live-file checkpoint fingerprinting with captured identity.
|
||||
- Update behavioral tests at the adapter, CLI preflight, asset registry, and
|
||||
representative assembled-module boundaries. Reuse real ConfigKit/PromptKit
|
||||
loading and offline injected clients or local HTTP fixtures.
|
||||
- Update canonical documentation when implementation lands:
|
||||
`docs/config.md` owns selected sources, precedence, profile syntax and
|
||||
migration; `docs/operations.md` owns deployment and reload guidance;
|
||||
`docs/internal/llm.md` owns construction, capture, and checkpoint mechanics;
|
||||
`docs/integrations/pkg-promptkit.md` owns the supported upstream boundary and
|
||||
pinned links. Revise consumer/CLI examples only where actually affected.
|
||||
- Update `docs/oss/attribution.md` for PromptKit and the two `/v3` catalogs,
|
||||
checking their actual notices and exact source commits. PromptKit remains
|
||||
LGPL-3.0-or-later; the catalogs remain MIT at the reviewed revisions. Reuse
|
||||
unchanged standard texts and preserve the project's own license grant.
|
||||
|
||||
Native layered overrides change an existing documented operator contract.
|
||||
A concise Notarius ADR is appropriate if that recommendation is accepted,
|
||||
recording the ownership/compatibility decision rather than duplicating the
|
||||
upstream manual. Existing historical ADRs need not be rewritten.
|
||||
|
||||
## Verification And Acceptance
|
||||
|
||||
Acceptance is behavioral, not an inventory of private helper names:
|
||||
|
||||
- All registered D&D and generic prompts construct and prepare with migrated
|
||||
assets, resolving shared/module content in the correct source context.
|
||||
Request identities, message content/order, schemas, and cache controls retain
|
||||
their intended behavior. Do not add exact shared-prefix-length detector tests.
|
||||
- Operator overrides, inheritance, explicit zero/null, duplicate definitions
|
||||
within a group, local backend precedence, endpoint-only profiles, and invalid
|
||||
unused final definitions follow the agreed native configuration policy.
|
||||
Credential-free preflight and execution resolve the same source ordering.
|
||||
- Engine/file mutation tests demonstrate captured settings and content;
|
||||
fingerprints stay tied to that engine and change when a new engine captures
|
||||
different execution-relevant settings or admitted prompt content.
|
||||
- Structural repair, semantic feedback, sessions/reasoning, capacity failure,
|
||||
transient errors, safe diagnostics, and observations retain existing
|
||||
provider-neutral behavior using deterministic boundary tests.
|
||||
- Maintained minimal, complete, and inherited development pipelines validate
|
||||
without credentials or provider calls. External legacy profile files receive
|
||||
clear migration guidance, not silent reinterpretation.
|
||||
|
||||
Use focused LLM, CLI, and module-integration tests during implementation, then
|
||||
`GOWORK=off go test ./...`, `GOWORK=off go vet ./...`, a temporary native build,
|
||||
and `GOWORK=off go mod tidy -diff` for this shared-boundary migration. Verify
|
||||
selected module versions, attribution links, maintained examples, and stale
|
||||
API/format claims. These are migration checks, not new permanent release gates.
|
||||
Live provider testing is optional follow-up evidence, not required acceptance.
|
||||
|
||||
This work warrants a minor Notarius release because the accepted external
|
||||
profile format and override behavior change. Keep Notarius configuration at
|
||||
version 5; select the actual release number during separate release preparation.
|
||||
|
||||
## Open Decisions
|
||||
|
||||
### 1. Native Overlay Or Preserve Complete Profile Replacement?
|
||||
|
||||
**Recommendation:** adopt PromptKit's recursive field overlay and native
|
||||
`extends`/null semantics. It removes bespoke configuration machinery, makes
|
||||
small deployment overrides useful, and keeps Notarius aligned with upstream.
|
||||
The tradeoff is explicit operator migration: omitted fields no longer erase
|
||||
fallback settings, so local/model switches may require null clears.
|
||||
|
||||
**Alternative:** preserve whole-profile replacement by explicitly clearing
|
||||
lower definitions before applying operator definitions. This protects the old
|
||||
replacement expectation, but requires Notarius to inspect/transform selected
|
||||
sources and account for inheritance and origins. It undermines the simple
|
||||
native handoff and is harder to maintain. Merely placing files in a later
|
||||
underlay does not implement whole replacement.
|
||||
|
||||
### 2. Scope Of Operator PromptKit Documents
|
||||
|
||||
**Recommendation:** allow native combined `profiles`, `backends`, and `prompts`
|
||||
documents through the existing selected file/directory settings, and enable
|
||||
explicit ConfigKit imports on those operator inputs. Keep the familiar fields
|
||||
and describe them as PromptKit configuration sources whose principal workflow
|
||||
is profile selection. Do not invent a Notarius section whitelist or custom
|
||||
merge language. Custom backends and deployment prompt edits become useful
|
||||
native capabilities; source-relative content capture and checkpoint identity
|
||||
must cover them. Module response decoding and artifact validation still define
|
||||
what a supplied prompt can successfully produce.
|
||||
|
||||
Directory selection discovers all YAML beneath its root. Imported fragments
|
||||
that would also be discovered must not accidentally become duplicate inputs;
|
||||
document a file-root import layout or keep fragments outside the discovered
|
||||
directory, using upstream resource/import rules. Do not promise filename
|
||||
override order or unrestricted host resource access beyond upstream behavior.
|
||||
|
||||
**Alternative:** retain profile-only operator inputs and leave imports disabled
|
||||
for this upgrade, introducing broader source selection later. This narrows
|
||||
the initial migration and leaves module prompts exclusively embedded, but
|
||||
requires an explicit locally chosen restriction on the unified upstream format
|
||||
and postpones custom backend/configuration composition. It should be a
|
||||
deliberate product decision, not an accidental consequence of old helper names.
|
||||
Reference in New Issue
Block a user