2026-11-05 19:24:09 +00:00
# Responsibility Simplification Implementation Plan
## Scope And Execution
Implement [responsibility-simplification.md ](responsibility-simplification.md )
from baseline `c69703b` , using the accepted decisions and evidence in
[A1-responsibility.md ](audit/A1-responsibility.md ). Production code is unchanged
from the audit baseline `1ff6d77` . Findings 1– 7 require changes; finding 8 requires
preserving current runtime behavior. All stages below are initially pending.
This replaces the completed 33-stage audit-remediation plan. Historical links
from the older audit/remediation documents refer to that earlier plan, available
with `git show c69703b:docs/roadmap/implementation.md` , not to the stages below.
Do not repeat the earlier sprint or treat its completion evidence as validation
of these changes.
Execute stages in order as one end-to-end sprint. Each stage is a focused Luna
prompt. Intermediate stages may leave callers/tests unmigrated or fail to
compile; record deferred checks and run them once their affected paths are
coherent. Do not add compatibility wrappers or duplicate implementations just
to keep an intermediate commit green. No human-review or external-publication
gate is needed between stages. Completion concerns the combined end state.
Read [development guidance ](../development.md ) and its applicable policies,
especially agents, architecture, testing, and documentation, plus
[ADR 0001 ](../adr/0001-configuration-boundary.md ). Use graph tools for discovery
and verify actual callers before deletion. Preserve unrelated work. Follow the
local commit policy and record completion/evidence for finished stages without
claiming temporarily deferred checks passed.
### Shared Rules
- Keep ConfigKit composition/history outside runtime validation. Validate final
configuration and genuinely new runtime inputs at their existing boundaries.
- Preserve the public facade and substantive API/wire behavior, except removal
of incidental schema-copy budgets selected in finding 7. The removed direct
output-validator workflow is private, not public `ValidateRequest` .
- Retain runtime supported values, concrete type/nil behavior, limits, number
handling, and errors. Do not narrow runtime values to ConfigKit mapping forms.
- Keep needed ownership copies, artifact defensive copying, prepared-handle
identity/lifecycle, admission versus active permits, HTTP evidence/deadlines,
and operation-owner errors. Do not expand this into another subsystem audit.
- Use existing trusted cloning for accepted values; keep validating copying for
actual acceptance. Do not add a reflection framework, schema budget, numeric
converter, raw-source validator, or public internal-type alias.
- Private names are implementation seams, not new public promises. Test selected
behavior, not allocation counts, helper choreography, or incidental wording.
- Include relevant GoDoc/internal documentation with the owning change. Stage 16
reconciles omissions, rather than authorizing stale documentation until then.
- Select the newest locally available Go installation as documented, with
`GOTOOLCHAIN=local` and `GOWORK=off` for isolated checks. The audit used Go
1.27.3. This sprint does not select a release, change dependency versions or
the consumer Go minimum, or authorize pushing/tagging/publication.
## Ownership Inventory For Stages 10– 15
Use these decisions, checking the affected callers as they are migrated. Record
any discovered mutation edge and account for it in the same boundary; do not
introduce a new ownership subsystem.
| Value/path | Acceptance and mutation | Selected ownership treatment |
| --- | --- | --- |
| Configured provider values | Final configuration validation and effective-target construction own acceptance; retained configuration/index state must not be mutated by runtime work. | Preserve acceptance/overlay semantics. Registry/profile lookup may continue returning detached values, but their copies use trusted cloning, not repeated acceptance checks. |
| Runtime provider override | `toDomainExecutionTargetOverride` , also used by smoke request conversion, validates/copies caller values. | Keep that boundary and its errors. Subsequent internal selection may transfer accepted private values without another deep validation pass. |
| Resolved target within one operation | Captured lookup returns detached values; runtime override conversion supplies owned values. Resolution changes scalar fields and selects whole provider maps, not nested content. | Transfer selected private maps through preparation/inspection; avoid repeated shallow/deep copying merely between private functions. Preserve current nil/empty projection behavior. |
| Loaded schema | The validator decodes/compiles a self-contained JSON document and retains immutable plan state. | Trusted-detach the provider-facing schema without provider-value depth/node validation. Keep the frozen compiled plan and existing acceptance checks. |
| Prepared metadata | Messages/input hashes are created during preparation; selected maps and schema belong to that operation. | Retain one immutable redacted snapshot for execution and details. Clear execution-only fields without modifying metadata. |
| Public prepared/details/result/inspection values | Root conversion crosses into caller-owned mutable state. | Keep one outward deep projection at that boundary. Never expose a borrowed internal map, schema, message pointer, or slice. |
| Injected generation and repair | The internal runner/repairer reads private settings; repair constructs a new message sequence. The root client adapter supplies a mutable public request. | Keep public request detachment for every dispatch, including repairs, and existing response copying. Do not add copies to compensate for removed internal copies. |
| Smoke reports | Selection and internal orchestration use accepted private targets; public report conversion creates caller-owned facts/settings. | Keep target redaction/endpoint sanitization and final projection. Remove validation-only copies and redundant private detachment, retaining any copy needed by an actual mutator. |
## Stage 1: Remove Client-Level Routing Fallbacks
2026-11-05 19:52:48 +00:00
**Completed:** Client routing now uses the resolved target; constructor fixtures
and integration guidance were migrated. With Go 1.27.3, `go test ./internal/llm
./internal/generation ./internal/configuration ./internal/usecase ./internal/engine`
passed, including loaded-target coverage.
2026-11-05 19:24:09 +00:00
**Finding:** 1. **Files: ** `internal/llm/openai_compatible_client.go` , client
fixtures/tests, `internal/engine/engine.go` caller verification, `docs/internal/llm.md` .
1. Delete `OpenAICompatibleConfig.BaseURL` /`Model` , stored `baseURL` /`defaultModel` ,
constructor endpoint normalization, and request fallback branches. Use the
selected target endpoint/model directly; retain final validity checks.
2. Remove the default-model parameter from the request builder and its caller.
Preserve HTTP-client cloning/timeouts and request authentication behavior.
3. Make the internal constructor infallible once its only failure path is gone;
update engine assembly and internal callers rather than retaining an always-nil
error return. Update constructor fixtures to put routing settings on request
targets. Delete tests solely asserting constructor-default precedence;
retain endpoint composition/rejection and supplied HTTP-client ownership cases.
4. Retire internal configured-base fallback prose. Do not add a new default
source or change backend/profile/request precedence.
**Check:** Relevant llm, generation, and loaded-target tests; defer compilation
where fixture migration remains. No production construction supplies the removed fields.
## Stage 2: Encode One Root Wire Representation
2026-11-05 19:53:41 +00:00
**Completed:** Requests now build the provider payload directly, with structured
dispatch evidence derived from that payload. Go 1.27.3 `go test ./internal/llm
./internal/generation` passed, including mapping, presence, payload freezing,
session, structured-output, and encoding-failure tests.
2026-11-05 19:24:09 +00:00
**Finding:** 2. **Files: ** `internal/llm/openai_compatible_client.go` and request-mapping tests.
1. Replace the root `domain request -> openAIChatRequest -> map` sequence with
one direct payload builder. Remove the intermediate root struct and obsolete
projection helper; retain useful nested typed wire structures.
2. Preserve explicit numeric zero versus omission, session normalization,
native schema envelopes, reserved/empty extension-key errors, and flattened
provider extensions. Derive structured-output evidence from the same selected
constraint, not a second independent mapping.
3. Keep successful payload encoding once and existing encoding-failure error
classification/privacy. Do not introduce JSON round trips or a custom serializer.
**Check:** Run `go test ./internal/llm ./internal/generation` ; reuse request-mapping,
presence, prepared-payload freezing, session, and structured-dispatch assertions.
## Stage 3: Require Captured Repository Operations
2026-11-05 19:55:10 +00:00
**Completed:** Repository interfaces require captured definitions, metadata,
requirements, and profile identity; the alternate lookups and hash wrapper
were removed. Go 1.27.3 `go build ./...` passed with the real configuration
snapshot. Use-case test fixture compilation is deferred to the next stage.
2026-11-05 19:24:09 +00:00
**Finding:** 3. **Files: ** `internal/promptdef/repository.go` , `internal/profile/repository.go` ,
`internal/usecase/{runner,prompt_inspection,profile_inspection,requirements_inspection}.go` ,
`internal/configuration/prompts.go` and `targets.go` .
1. Make the runner's prompt repository explicitly provide `GetPromptSnapshot` ,
`GetPromptInspection` , and `GetRequirementSnapshot` with their existing
signatures. Require `GetProfileIdentity` alongside `GetProfile` on its profile
repository. Reuse the existing domain/template values; no public interfaces change.
2. Call these captured operations directly. Remove capability assertions and
alternate full-definition/profile lookup/hash paths. Do not add new rejection
rules for hashes or introduce runtime hashing in another helper.
3. Preserve direct not-found versus load-error ownership, context checks, exact
IDs, and metadata-only inspection. Keep captured definition detachment.
4. Remove unused legacy repository methods and the use-case hash wrapper once
callers are migrated; retain the hash implementation used by configuration.
**Check:** Inspect the real configuration snapshot against the new interfaces.
Use-case tests may remain uncompilable until Stage 4; no transitional fallback is needed.
## Stage 4: Migrate Repository Fixtures And Inspection Tests
2026-11-05 19:57:13 +00:00
**Completed:** Private repositories now supply captured lookup operations and
inspection tests cover captured hashes, metadata, identities, and errors. Go
1.27.3 `go test ./internal/configuration ./internal/usecase` passed.
2026-11-05 19:24:09 +00:00
**Finding:** 3. **Scope: ** private repository fixtures in use-case tests and affected configuration tests.
1. Update small repository fixtures to supply captured hashes, metadata, and
requirement snapshots through Stage 3's operations. Prefer real in-memory
configuration where useful, rather than rebuilding configuration resolution.
2. Replace the missing-metadata-capability fallback case with captured-hash and
narrow-inspection behavior. Preserve useful tests for missing resources,
lookup errors, cancellation, independent returned metadata, and namespaces.
3. Remove fixture methods/helpers that solely support deleted alternatives.
Keep convenient no-repair runner construction and controlled external doubles.
**Check:** Focused configuration/use-case prompt, profile, and requirement
inspection tests. Renderer-related failures may be deferred through Stage 6.
## Stage 5: Keep Only Captured Rendering
2026-11-05 19:57:55 +00:00
**Completed:** Rendering now requires captured templates and no longer parses
messages or sessions per call. Go 1.27.3 `go build ./...` passed; renderer and
use-case test migrations and their checks are deferred to the next stage.
2026-11-05 19:24:09 +00:00
**Finding:** 3. **Files: ** `internal/prompt/go_renderer.go` , template helpers, engine assembly.
1. Remove `NewGoRenderer` and the nil-template lookup mode. Keep
`NewCompiledRenderer` consuming the existing `TemplateLookup` .
2. Remove per-call parsing branches and the uncompiled session-rendering helper.
Keep construction-time compilation, missing captured-template errors,
per-call template cloning/function binding, and direct-session suppression.
3. Preserve input requirements, roles/cache-control behavior, message order,
artifact text resolution, cancellation, and rendered/session hash inputs.
Do not expand recognized template syntax or add a template cache.
**Check:** Engine assembly already provides captured templates. Test callers
are deliberately migrated in Stage 6 rather than accommodated in production.
## Stage 6: Move Renderer Tests Onto Captured Templates
2026-11-05 19:59:34 +00:00
**Completed:** Renderer fixtures and benchmarks now compile captured templates
before rendering; invalid syntax, missing captures, cancellation, session, and
artifact behavior remain covered. Go 1.27.3 `go test ./internal/prompt
./internal/configuration ./internal/usecase` passed, resolving the deferred
repository and renderer checks.
2026-11-05 19:24:09 +00:00
**Finding:** 3. **Scope: ** prompt rendering tests/benchmarks and their use-case/configuration callers.
1. Use `CompileTemplate` and a small `TemplateLookup` fixture, or a loaded
configuration snapshot, to provide message/session parses. Keep parsing outside
benchmark timing where measuring execution rather than capture.
2. Preserve syntax-error protection at compilation/capture, runtime missing
variable/input cases, direct/rendered session behavior, artifact-text lifecycle,
cancellation, and independent requirement-versus-rendering comparisons.
3. Do not recreate the deleted parser mode inside a renderer fixture. Share only
simple fixture setup; avoid a general test configuration framework.
**Check:** Run `go test ./internal/prompt ./internal/configuration ./internal/usecase` .
Revisit deferred Stage 3– 5 checks; carry any still-blocked checks forward to
final validation without adding transitional code or an intermediate gate.
## Stage 7: Use Prepared Plans For Both Smoke Output Checks
2026-11-05 20:00:33 +00:00
**Completed:** Smoke inference prepares separate JSON and schema plans and
checks syntax before schema matching. Go 1.27.3 `go test ./internal/usecase
-run 'Smoke|Diagnostic'` passed, including malformed, scalar, matching,
nonmatching, cancellation, and dispatch cases.
2026-11-05 19:24:09 +00:00
**Finding:** 4. **Files: ** `internal/usecase/smoke_inference_case.go` and diagnostic tests.
1. Replace the smoke case's `jsonValidator validate.Validator` with a
`validate.PreparedValidation` JSON-only plan, prepared through the existing
validator. Keep the distinct compiled schema plan and provider schema.
2. Invoke JSON-only validation first and schema validation only after syntax
passes. Preserve nil/false/true facts, cancellation precedence, scalar JSON
syntax, construction errors, privacy, and current diagnostic completion rules.
3. Do not move `json.Valid` into orchestration or add a composite validation API.
JSON-only plan creation performs no schema loading/compilation.
**Check:** Focused smoke tests for malformed JSON, valid nonmatching schema,
matching schema, cancellation, and native schema dispatch. Reuse existing coverage.
## Stage 8: Remove Standalone Direct Output Validation
2026-11-05 20:01:28 +00:00
**Completed:** Output validation now executes only prepared plans, with direct
on-demand schema callbacks removed. Go 1.27.3 `go build ./...` passed. Tests
using the retired private API are deferred to the next stage.
2026-11-05 19:24:09 +00:00
**Finding:** 4. **Files: ** `internal/validate/validator.go` , `standard_validator.go` .
1. Remove the standalone `Validator` interface and concrete host/FS
`Validate(ctx, artifact, contract)` methods after Stage 7's migration.
2. Delete the direct on-demand schema callbacks. Keep `ValidationPreparer` ,
`PreparedValidation` , shared instance-mode validation, and prepared schema
execution. Simplify callback plumbing tied only to the removed workflow
without writing a new validation mechanism.
3. Preserve host and `fs.FS` root-source handling, eager plan compilation,
synchronous context boundaries, self-containment/portability checks, numeric
decoding, and frozen plans. Keep nil-validator/no-op behavior in the runner.
**Check:** Production no longer calls a direct validator. Old test calls may
temporarily fail to compile; migrate them in Stage 9, not through a wrapper.
## Stage 9: Migrate Validator Tests To Prepared Execution
**Finding:** 4. **Scope: ** `internal/validate` tests, particularly standard-validator and cancellation cases.
1. Express meaningful direct-validation cases as plan preparation followed by
plan validation. Keep malformed instance outcomes separate from preparation
failures, rather than retaining decode-before-schema-I/O as an expectation.
2. Retain independent host/FS path and containment coverage, source mutation/removal
freezing, references/unused declarations/portability, JSON precision, basic/JSON
modes, and cancellation around reading/compilation/execution where already selected.
3. Delete redundant direct/prepared duplicates and mocks of the retired interface.
In-progress synchronous dependency work is still not detached on cancellation.
**Check:** Run `go test ./internal/validate ./internal/usecase` and relevant root
schema/smoke tests. Resolve Stage 8's deferred checks.
## Stage 10: Remove Copier-Derived Schema Budgets
**Finding:** 7. **Files: ** `internal/usecase/runner.go` , `prepared_execution.go` , schema/preparation tests.
1. Replace schema-document validation/copying in
`structuredOutputFromValidationPlan` and prepared metadata cloning with trusted
detachment of the decoded schema. Preserve nil-plan/missing-document failures
and the existing frozen schema boundary.
2. Remove `cloneJSONValue` if no longer needed; do not substitute another limited
walker, JSON-number conversion, or new schema-resource check.
3. Replace the fake-plan excessive-depth rejection expectation with selected
acceptance/isolation behavior. Include a representative real loaded schema
exceeding the old copier depth or node budget in annotation data, which the
compiler accepts; verify preparation and outward detachment. Generate large
fixtures in test setup, not as bulky checked-in files.
4. Preserve invalid/external-schema rejection and runtime provider-value budgets.
Do not turn the regression into a promise of arbitrary depth or provider support.
**Check:** Focused prepared/schema-file tests plus `internal/validate` and
`internal/jsonvalue` tests establish that only schema-copy acceptance changed.
## Stage 11: Detach Captured Backend And Profile Values Without Revalidation
**Finding:** 5; preserve 8. **Files: ** `internal/domain/smoke_diagnostics.go` ,
`internal/backend/registry.go` , `internal/configuration/targets.go` , associated tests.
1. Apply the ownership inventory: final validation/effective construction remains
responsible for configured acceptance; later lookup does not repeat it.
2. Make `CloneBackend` an infallible trusted deep clone, retaining smoke metadata
detachment. Remove copy-only errors from effective registry construction and
update its callers; `GetBackend` still reports genuine not-found errors.
3. Keep `GetProfile` returning a detached target/map using trusted cloning,
retaining context/not-found failures and presence semantics. Keep required
construction ownership separation from the retained ConfigKit result.
4. Leave configured overlay/acceptance semantics intact in this stage; assembling
a new effective map is not the same as copying a captured lookup result.
Do not remove final `validateExtraParams` or runtime override validation.
**Check:** Backend/configuration tests cover mutation isolation, composed targets,
null/empty values, and construction errors without pinning deleted copy-error branches.
## Stage 12: Transfer Accepted Provider Maps Through Internal Resolution
**Finding:** 5; preserve 8. **Files: ** `internal/usecase/runner.go` ,
`profile_inspection.go` , `smoke_selection.go` , related ownership tests.
1. With detached lookup values from Stage 11, pass selected maps through private
target resolution rather than copying them again. Runtime replacement maps
already belong to the converted request; scalar overrides need not mutate them.
2. Remove the extra validating map copy in profile inspection. Retain credential
redaction and the root facade's independent public projection.
3. Remove redundant `copyExtraParams` uses in target/override/smoke selection and
the helper if unused. Preserve existing nil/empty outcomes, including inheritance
for an empty runtime map; do not let sharing alter public JSON shapes.
4. Keep the facade's `toDomainExecutionTargetOverride` validation/deep copy and
actual client/result detachment. Do not expose internal request sharing as a
new mutable consumer interface.
**Check:** Focused target precedence, profile inspection, runtime override, smoke
selection, and mutation-isolation tests. Retain typed/numeric runtime cases.
## Stage 13: Share One Immutable Prepared Metadata Snapshot
**Findings:** 5– 6. **Files: ** `internal/usecase/prepared_execution.go` ,
`prepared_execution.go` , `convert.go` , lifecycle/ownership tests.
1. Remove payload cleanup's write into prepared metadata. Keep clearing private
credential, observer, retry, validation, and execution payload references under
the existing lifecycle. Owner identity and claim/discard synchronization stay.
2. Retain the prepared operation's one redacted metadata snapshot for both
internal execution and details. Remove the extra provider-map clone and
separate deep details snapshot created by `PrepareExecution` .
3. Make the internal details accessor return that immutable private snapshot;
its root caller performs the sole outward `fromDomainPreparedRun` copy.
Update private comments/tests to distinguish borrowed internal metadata from
mutable public details. Do not expose an internal type in a public signature.
4. Delete `clonePreparedRun` and hidden copy-error-to-nil fallback once unused.
Preserve nil/zero public handle behavior, details after use/discard, source
freezing, and private direct-key lifetime. Execution and repair must not mutate
shared metadata, including nested maps, cache controls, or schema values.
**Check:** Race-enabled prepared lifecycle, concurrent claim/discard, engine/view
binding, independent details, mutation, credential, and repair tests. Public Run
results also remain detached from metadata retained by the handle.
## Stage 14: Simplify Smoke Target And Public Report Detachment
**Finding:** 5. **Files: ** `internal/usecase/smoke_tester.go` ,
`smoke_diagnostics.go` , smoke conversion/ownership tests.
1. Keep accepted targets private and read-only through diagnostic orchestration;
remove their validation-only provider-map copy in `smokeReportTarget` where
no mutable ownership handoff occurs. Keep endpoint sanitization, credential
redaction, and genuine endpoint errors.
2. Use the existing trusted public execution-target projection in
`fromDomainSmokeTestReport` , rather than another `CopyMap` . Make report
conversion infallible and update facade callers, removing only the impossible
report-copy error path. Other operational/configuration errors remain.
3. Retain detached report facts, attempts, pointer fields, and nested provider
values. Delete the internal invalid-provider-map conversion-error test that
sustains revalidation of fabricated unaccepted reports; retain its meaningful
public acceptance/ownership protection at the real boundary.
**Check:** Smoke conversion isolation, privacy, partial/canceled reports, and
configured-default/runtime-override diagnostics through the public facade.
## Stage 15: Verify Cross-Path Ownership And Runtime Compatibility
**Findings:** 5– 8. **Scope: ** focused existing public and package contract tests.
1. Reconcile the ownership inventory with the delivered call paths. Verify that
prepared details/results, profile inspection, smoke reports, and injected
initial/repair requests cannot mutate retained engine/handle state. Extend a
representative existing test only where these changes leave a meaningful gap.
2. Keep valid typed/named runtime containers, numbers, nil/empty forms, map
replacement, and current invalid/cyclic/over-budget rejection at acceptance.
Distinguish those provider budgets from removed schema budgets.
3. Exercise a mutating injected client across initial and repair calls and
concurrent details/claim/discard where existing coverage supplies the seam.
Keep the built-in HTTP payload freeze and existing artifact defensive copy.
4. Review remaining copy/validation callers for purpose. Remove overlooked
repeated acceptance work on the selected paths, not all copies indiscriminately.
Do not preserve private copy-failure tests as new public requirements.
**Check:** Run targeted race-enabled root/use-case/configuration/jsonvalue tests.
Record results and any reconciled ownership edge; no benchmark framework or exact
allocation threshold is needed.
## Stage 16: Reconcile Canonical Documentation And Retire Obsolete Descriptions
**Findings:** 1– 8. **Scope: ** GoDoc, `docs/internal/{overview,llm,runner,sources}.md` ,
relevant consumer/format guidance, feature roadmap completion status.
1. Remove descriptions of client routing defaults, uncaptured renderer/repository
fallbacks, standalone direct output validation, duplicate prepared metadata,
and prepared-schema copier limits. Describe the delivered ownership paths.
2. Record broadened schema acceptance only where consumer/format guidance needs
it. Keep the self-contained-schema rule, runtime provider budgets, and existing
number handling; add no resource/provider/performance promises.
3. Keep exact public contracts in GoDoc, formats/wire behavior with their owning
references, and private mechanics in internal docs. Update affected comments
throughout, not just the package inventory.
4. Update the feature roadmap with delivered outcomes and pending final checks;
do not mislabel the audit's original tests as replacement validation. Leave
unrelated completed-roadmap retirement and release notes to their own work.
**Check:** Documentation links and whitespace, plus searches for the retired
names/claims to separate historical audit evidence from stale current guidance.
## Stage 17: Validate And Close The Sprint
**Scope:** combined final state, all findings and deferred checks.
1. Resolve remaining deferred compilation/tests; format changed Go files. Run
`go test -race ./...` and `go vet ./...` using the selected local toolchain.
The suite includes maintained examples; separate ordinary/full build/example
runs are not additional required checks for the same unchanged candidate.
2. Check documentation links, `git diff --check` , full intended/staged diff,
and repository status. Exclude secrets, generated artifacts, local workspace
files/replacements, and unrelated changes. No release publication check is needed.
3. Confirm removal of client defaults, duplicate root wire representation,
optional lookup fallbacks, uncaptured rendering, direct-validator lifecycle,
redundant copy-validation paths, duplicate prepared metadata, and schema-copy
budgets. Verify that remaining copies implement real ownership boundaries.
4. Record final evidence and completion for findings 1– 7 and preservation of 8
in the feature roadmap/plan. A deferred check or unimplemented selected change
is not completion. Preserve actual scope if a new blocker appears and surface
it rather than substituting a compatibility layer or narrowing the feature.
5. Commit the completed work under repository policy and report the result and
any remaining unrelated workspace changes. Do not push, tag, or publish.
**End state:** The selected roadmap is implemented with fewer private workflows,
representations, and redundant traversals; public behavior and ownership remain
intact except for the explicitly removed incidental schema restriction.