Plan Notarius configuration profile support
This commit is contained in:
248
docs/roadmap/implementation.md
Normal file
248
docs/roadmap/implementation.md
Normal file
@@ -0,0 +1,248 @@
|
||||
# Implementation Plan: Notarius Configuration Profile Selection
|
||||
|
||||
Status: Ready for implementation; all stages pending.
|
||||
|
||||
## 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: Pending.
|
||||
|
||||
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: Pending.
|
||||
|
||||
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: Pending.
|
||||
|
||||
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.
|
||||
Reference in New Issue
Block a user