267 lines
13 KiB
Markdown
267 lines
13 KiB
Markdown
# Implementation Plan: Notarius Configuration Profile Selection
|
|
|
|
Status: Implementation in progress; Stages 1-3 complete.
|
|
|
|
## Scope and Working Instructions
|
|
|
|
Implement the [feature roadmap](notarius-config-profile.md), whose authority is
|
|
the [consumer request](feature-request-notarius-config-profile.yml). Complete
|
|
the numbered stages in order. Each stage is a bounded task for a gpt-5.6-terra
|
|
coding agent. Do not treat completion of an intermediate stage as completion of
|
|
the feature. Record completed stages and actual verification results here.
|
|
|
|
Before each stage, read `docs/development.md`, all documents under
|
|
`docs/policy/`, the feature roadmap, and that stage's preparation list. Follow
|
|
AGENTS.md discovery guidance. Use existing collaborators and fixtures; do not
|
|
build a new configuration, cache, or profile-management subsystem. Tests must
|
|
remain offline and independent of installed Notarius binaries and credentials.
|
|
Do not change dependencies, implement Ansible changes, tag, or release as part
|
|
of this plan.
|
|
|
|
## Implementation Decisions
|
|
|
|
These choices resolve implementation details without adding restrictions to
|
|
the feature request:
|
|
|
|
- Represent the authored field as `ConfigProfile *string` with YAML/JSON name
|
|
`config_profile` and `omitempty`, in both typed configuration and its safe
|
|
YAML projection. Nil means omitted/null. A non-nil pointer preserves an
|
|
explicitly supplied empty string as well as `default` and named selections.
|
|
- Carry the same optional value in the Notarius adapter request. Nil emits no
|
|
flag; non-nil emits `--config-profile` followed by the exact supplied string
|
|
as a separate argument, including an empty string. Do not trim, lowercase,
|
|
substitute Narratio's profile, impose a name regex, or inspect profile files.
|
|
Notarius owns validation and selector interpretation.
|
|
- For reuse evidence only, use one small stage-local helper that maps nil,
|
|
`""`, and exact `"default"` to the empty identity; other values remain
|
|
unchanged. Both extraction fingerprints use it. This does not mutate the
|
|
authored field or change CLI forwarding. Do not attempt to recreate the
|
|
downstream parser's complete normalization rules.
|
|
- Add `ConfigProfile string` with `json:"config_profile,omitempty"` to both
|
|
existing fingerprint payloads, populated only where extraction is enabled.
|
|
Preserve existing field ordering and the current semantic fingerprint version
|
|
(1). With no non-base selector the serialized payload remains unchanged;
|
|
a named selection adds evidence that old records cannot already possess.
|
|
No dual-reader, manifest migration, new durable metadata field, or broad
|
|
fingerprint-version bump is needed. This is a minimal additive encoding,
|
|
not a permanent promise to freeze fingerprint bytes across future releases.
|
|
- Profile changes trigger the existing non-resumable/invalidation paths, not
|
|
force mode. Preserve configured resume/cache controls, force precedence,
|
|
credentials, output contracts, and stage-range behavior. Do not run extraction
|
|
outside the operator's selected range or add a separate testing workspace.
|
|
- Preserve the existing division of ownership: private downstream file changes
|
|
behind an unchanged selector require operator-directed force when needed.
|
|
No downstream configuration validation subprocess or runtime version gate
|
|
is added.
|
|
|
|
## Stage 1: Add Configuration and Adapter Support
|
|
|
|
Status: Complete.
|
|
|
|
Completion marker (2026-09-21): Added composed optional configuration and safe
|
|
inspection support, adapter request/argument forwarding, copy auditing, and
|
|
focused configuration and subprocess coverage. Verified with
|
|
`go test ./internal/config ./internal/adapters/notarius`.
|
|
|
|
Preparation:
|
|
|
|
- `docs/config.md` (composition, profiles, Notarius, credentials).
|
|
- `docs/integrations/notarius.md` (invocation and failure behavior).
|
|
- `internal/config/config.go`, `credential_projection.go`,
|
|
`pipeline_configkit.go`, `pipeline_normalize.go`, and `notarius_test.go`.
|
|
- `internal/adapters/notarius/runner.go`, `subprocess.go`, `fake.go`, and
|
|
`subprocess_test.go`.
|
|
|
|
Work:
|
|
|
|
1. Add the optional field to `NotariusConfig` and the `safeNotarius` projection,
|
|
including its returned value. Let existing ConfigKit composition handle
|
|
overrides and null; do not add a default or resolve this name as a path.
|
|
2. Add the optional field to `notarius.RunRequest` and append the argument pair
|
|
when non-nil in `SubprocessRunner.Run`, before `--json`. Leave subprocess
|
|
environment construction and error propagation unchanged.
|
|
3. Audit any explicit Notarius configuration/request copies for the new field.
|
|
Update actual omissions without introducing a generic cloning framework.
|
|
4. Extend real configuration-load tests to cover a base selection, an overlay
|
|
replacing it with a differently named downstream selection, and an overlay
|
|
clearing it with null. Cover omitted, empty, and `default` values compactly.
|
|
Verify the safe effective-YAML output retains a supplied value, including
|
|
explicit empty, and round-trips without leaking credential values. Reuse
|
|
existing credential tests rather than duplicating their full matrix.
|
|
5. Extend adapter invocation tests for omitted and supplied selections,
|
|
including empty and `default`. Assert the argument/value boundary rather
|
|
than imposing new ordering requirements on unrelated arguments. Reuse the
|
|
existing nonzero-exit test with a selected profile to prove there is no
|
|
fallback or successful receipt processing after failure.
|
|
|
|
Verification:
|
|
|
|
```sh
|
|
go test ./internal/config ./internal/adapters/notarius
|
|
```
|
|
|
|
Completion: Configuration composition and safe inspection preserve the field,
|
|
and the adapter forwards it correctly. The executing stage is connected in
|
|
Stage 2 together with reuse tracking, so it cannot start using untracked profile
|
|
selections as an intermediate implementation.
|
|
|
|
## Stage 2: Wire Extraction and Profile-Sensitive Reuse
|
|
|
|
Status: Complete.
|
|
|
|
Completion marker (2026-09-21): Wired the selected profile into extraction,
|
|
added a shared base-selector reuse identity to both existing fingerprints, and
|
|
covered request forwarding, force precedence, semantic sensitivity, prior
|
|
no-profile encoding, and focused resume validation. Verified with
|
|
`go test ./internal/stage ./internal/adapters/notarius ./internal/config`.
|
|
|
|
Preparation:
|
|
|
|
- `docs/internal/stage-extract.md`.
|
|
- `internal/stage/extract.go`, `extract_resume.go`,
|
|
`semantic_contracts_delivery.go`, and their focused tests.
|
|
- In particular, `TestExtractStageResolvesManifestInputAndBuildsExactRequest`,
|
|
`TestExtractSemanticConfigSensitivityAndOperationalExclusions`, and
|
|
`TestExtractStageResumeValidationRequiresFreshEvidence`.
|
|
|
|
Work:
|
|
|
|
1. Pass `cfg.ConfigProfile` to the adapter request when extraction executes.
|
|
Keep the field independent of credential forwarding and force overrides.
|
|
2. Implement the reuse-identity helper and additive fingerprint fields described
|
|
above. Update both `extractSemanticConfig` and `fingerprintDocument`, using
|
|
the same identity in semantic comparison and `extractionFingerprint`.
|
|
Keep disabled extraction insensitive to unused downstream settings.
|
|
3. Extend the existing stage request test to prove the authored selection
|
|
reaches the adapter. Cover ordinary and forced execution sufficiently to
|
|
show that profile forwarding does not alter existing cache-control precedence.
|
|
4. Extend semantic-sensitivity coverage: base to named, named to different named,
|
|
and named to base change evidence; unchanged selection does not. Verify
|
|
nil/empty/`default` share base evidence and disabled settings remain inert.
|
|
5. Exercise the focused resume validator with an actual valid recorded bundle:
|
|
it remains reusable for the same selection and becomes non-resumable for a
|
|
changed selection. This guards the second fingerprint path independently
|
|
of the application's semantic comparison.
|
|
6. Check the additive encoding against the prior no-profile payload shape once
|
|
in focused coverage or a recorded development check. Avoid whole-manifest
|
|
snapshots and a permanent historical compatibility harness; retain existing
|
|
input/output/reference sorting and all unrelated fingerprint fields.
|
|
|
|
Verification:
|
|
|
|
```sh
|
|
go test ./internal/stage ./internal/adapters/notarius ./internal/config
|
|
```
|
|
|
|
Completion: Selected profiles reach actual extraction, and both existing reuse
|
|
checks account for the selection without forcing downstream cache refresh or
|
|
changing the manifest schema.
|
|
|
|
## Stage 3: Verify Application Lifecycle Behavior
|
|
|
|
Status: Complete.
|
|
|
|
Completion marker (2026-09-21): Extended the existing application lifecycle
|
|
fixtures to cover same-selection reuse, named and base selection changes,
|
|
dependent invalidation/rerun, sibling preservation, ordinary downstream
|
|
failure, and real ConfigKit profile-to-execution composition without implicit
|
|
name forwarding or digest-wide invalidation. Verified with
|
|
`go test ./internal/app ./internal/stage`.
|
|
|
|
Preparation:
|
|
|
|
- `internal/app/extract_lifecycle_test.go`, `runner_test.go`, and
|
|
`run_control_test.go`.
|
|
- Existing fixtures and tests for changed extraction outcomes, failure/retry,
|
|
and independent render/extract invalidation.
|
|
|
|
Work:
|
|
|
|
1. Extend the existing lifecycle fixtures rather than building another harness.
|
|
Run a successful extraction with a configured profile, then verify ordinary
|
|
reuse for that same profile. Change only the downstream selection and verify
|
|
that extraction executes again with the new value, upstream transcripts and
|
|
render remain current, and succeeded dependents are invalidated/rerun through
|
|
the existing runner policy. Include returning from a named selection to base.
|
|
2. Cover the changed-profile failure boundary with the existing fake runner:
|
|
return an ordinary downstream error and verify extraction is failed, the
|
|
previous result is not advertised as current success, and dependents are not
|
|
silently reused. Reuse existing retry coverage where it already proves the
|
|
recovery behavior. Do not assert Notarius-specific diagnostic wording.
|
|
3. Ensure one configuration-to-execution path proves explicit composition:
|
|
Narratio's testing overlay can select a differently named Notarius overlay;
|
|
without the field, selecting a Narratio profile does not populate the
|
|
downstream request. Use real configuration loading and the existing injected
|
|
runner, not a production provider or sibling repository dependency.
|
|
4. Review existing operational-exclusion and force tests for continued validity.
|
|
Do not broaden invalidation to the full effective configuration digest or
|
|
Narratio's profile label, and do not automatically change cache options.
|
|
|
|
Verification:
|
|
|
|
```sh
|
|
go test ./internal/app ./internal/stage
|
|
```
|
|
|
|
Completion: Tests demonstrate the requested workflow, including selection
|
|
changes and failure, across the real Narratio configuration/runner boundaries.
|
|
Notarius's own overlay loader and cache internals remain outside these tests.
|
|
|
|
## Stage 4: Document the Feature and Validate the Completed Change
|
|
|
|
Status: Pending.
|
|
|
|
Preparation: Canonical documentation owners listed in the feature roadmap,
|
|
`examples/README.md`, and the existing development-focused operations guidance.
|
|
|
|
Work:
|
|
|
|
1. Document the optional field in `docs/config.md`, including omitted/null,
|
|
explicit base selectors, and independence from Narratio's profile and
|
|
`notarius.llm_api_key`. Do not add profile-name restrictions.
|
|
2. Update the invocation in `docs/integrations/notarius.md` to include the
|
|
optional flag and identify Notarius v0.7.0 as a known supporting version,
|
|
not an unconditional version requirement. Preserve the distinction from
|
|
`--llm-profile` and ordinary downstream failure handling.
|
|
3. Update `docs/internal/stage-extract.md` to describe selection-sensitive reuse
|
|
and retain its distinction from private file content and operational settings.
|
|
Make clear this is an explicit downstream setting, not blanket invalidation
|
|
by Narratio's profile label or effective digest.
|
|
4. Add concise development workflow guidance in `docs/operations.md`: explicit
|
|
testing-overlay composition; different downstream names are allowed;
|
|
switching selection triggers extraction when that stage is in scope; edits
|
|
behind an unchanged selector may need force; testing is not a separate
|
|
workspace. Preserve the existing distinction between extract+analyze and
|
|
analyze-only regeneration.
|
|
5. Update the maintained annotated pipeline example to show the optional field
|
|
without requiring an externally installed testing overlay (use a commented
|
|
named-selection example). Do not make previously runnable examples depend
|
|
on new downstream files. Link to canonical owners instead of duplicating
|
|
full contracts or adding new top-level Narratio flags.
|
|
6. Review the final diff against every observable behavior and scope boundary
|
|
in the consumer request. Mark the implementation stages and roadmap status
|
|
accurately after verification; do not remove the original request or alter
|
|
historical release notes.
|
|
|
|
Run the repository checks with the maintained Go 1.26 toolchain:
|
|
|
|
```sh
|
|
go test ./...
|
|
go test -race ./...
|
|
go vet ./...
|
|
go build ./...
|
|
go test ./internal/doccheck
|
|
go test ./internal/config -run '^TestExamplesLoadAndValidate$'
|
|
git diff --check
|
|
```
|
|
|
|
Completion: The requested interface, failure and reuse behavior, examples, and
|
|
canonical documentation agree; all checks pass. No release is part of this
|
|
implementation sprint.
|
|
|
|
## Open Questions
|
|
|
|
None. The consumer request resolves the product behavior. The choices above
|
|
settle implementation details without adding new operator restrictions,
|
|
downstream configuration ownership, or cache guarantees.
|