Expand accepted API decisions into an implementation roadmap

This commit is contained in:
2026-10-27 14:43:08 +00:00
parent 7548fa101a
commit 07e4ae5d92

View File

@@ -1,16 +1,58 @@
# Pre-v1 Public API Cleanup
# Pre-v1 Public API Cleanup Roadmap
Status: decisions accepted; implementation has not begun.
Baseline: `a050986` and the revision-pinned [API review](review.md).
Status: target settled; implementation has not begun.
Planning baseline: `7548fa1` (accepted decisions, with the v0.10.2 implementation
and subsequent interface/history remediation already present).
This document records the accepted cleanup from that review. The goal is clearer
public vocabulary, recording methods, and direct source lookup before v1.0.0,
preserving existing behavior. The review remains the catalog and analysis; its
other assessments are not automatically adopted by these decisions.
Accepted findings from the [additional API review](audit.md) are recorded here
as well.
This roadmap owns the targeted end state, required changes, general dependency
order, and completion criteria. The [preliminary review](review.md) retains the
API catalog and original proposals; the [additional review](audit.md) retains
its evidence and alternatives. Proposal IDs below provide traceability. A later
implementation plan should select concrete edits, stages, validation commands,
and progress tracking.
## Accepted Changes
## Purpose And Scope
Make the public API clearer before v1.0.0 through the accepted renames, narrower
recording methods, redundant-state removal, and direct source lookups. Preserve
existing configuration behavior except for the selected public replacements,
removals, and observable string changes. The root package remains the supported
facade; private engine structure can evolve within that boundary.
This is a breaking pre-v1 cleanup, not a compatibility-shim rollout. The renamed
or replaced public declarations give way to their selected forms. Existing Go
declaration comments and the [configuration contract](../config.md) continue to
own behavior that this roadmap does not change. No redesign of loading,
composition, history ownership, or YAML syntax is selected.
## Current Baseline
- [lifecycle.go](../../lifecycle.go), [records.go](../../records.go),
[discovery.go](../../discovery.go), and [secrets.go](../../secrets.go) expose
the old declarations listed below. There are corresponding engine declarations
and facade conversions, including [conversion.go](../../conversion.go).
- `Resolution.Record` accepts the inspection `ChangeKind` type, then rejects
kinds other than derived-default and normalization during loading. The generic
assignment helpers already select their own supported intent.
- `ImportSelection` represents only empty selections, but still carries a
single-valued outcome. Source records expose version and destination evidence
through names that do not fully describe that evidence.
- `Resolution.Source(id)` already performs passive, detached lookup during a
callback. `Result` and `LoadError` expose ordered `Sources()` lists but no
direct lookup. Failure records contain only the evidence available at failure.
- The shared history implementation and its admission boundary are already in
place. Provenance still uses `"base"`, and retained-history failures still use
`"explain.limit_exceeded"`.
- Current production-reference checks find only declarations for
`CodeOptionsUnavailable`, and the kind guard in `resolutionState.addRecord`
produces `CodeResolveInvalidKind`. Their removal requires the checks described
below, rather than inventing a new supported use for either code.
## Targeted Public API
The following table is the complete accepted change set. Unless stated otherwise,
renames retain the existing signature/type and behavior. Internal names are not
part of this public replacement list.
| Review item | Decision |
| --- | --- |
@@ -86,15 +128,177 @@ existing failed-load redaction and the evidence available at failure, including
incomplete placement information. Lookup neither completes acquisition nor
promises a record for every attempted source. This incorporates N5 into A1.
## Scope And Follow-Up
## Work Required From The Baseline
Implement the selected changes with corresponding declaration comments, owning
documentation, examples, tests, and affected consumer call sites. Preserve the
existing loading, composition, presence, inspection, ownership, and diagnostic
contracts except for the expressly selected API replacements/removals and addition
above.
This record does not authorize release publication or a broader API redesign.
### 1. Migrate Public Declarations And Facade Conversions
A2 (public path comparison) is deferred. It can be considered separately as a
compatible addition once a concrete use case and an explicit equality definition
are established.
Update the public declarations, comments, wrappers, and conversions as a coherent
surface. Useful existing owners are:
| Area | Baseline owners and required work |
| --- | --- |
| Entry metadata, sensitivity, version mode, and import defaults | [lifecycle.go](../../lifecycle.go), [layered.go](../../layered.go), and [conversion.go](../../conversion.go): update both ordinary and layered loading paths, callback wrappers, and definition/default conversions. |
| Source evidence | [records.go](../../records.go) and [conversion.go](../../conversion.go): rename records/fields and remove the empty-selection outcome. Cover source records returned through results, callbacks, and load errors. |
| Recording intents | [lifecycle.go](../../lifecycle.go) and [engine resolution](../../internal/engine/resolution.go): provide the two methods, route them to the existing recording/auditing machinery, and remove the public kind-selecting method. |
| Discovery and bootstrap | [discovery.go](../../discovery.go) and [secrets.go](../../secrets.go): replace constructor/function names and migrate their callers without changing acquisition or environment mutation behavior. |
| Provenance and diagnostic values | [records.go](../../records.go), [engine records](../../internal/engine/records.go), producers, conversions, and renderers: apply the selected labels and codes consistently. |
| Direct lookup | [lifecycle.go](../../lifecycle.go), [diagnostic.go](../../diagnostic.go), and their engine collaborators: expose the existing retained source evidence through the new result/error methods. |
Use explicit root/engine conversion as needed; no public aliases or engine types
are needed to implement these replacements. Private naming and helper placement
belong to implementation planning. Avoid unrelated internal renames merely to
make every private identifier match the facade.
Preserve distinctions that the new names clarify:
- `EntryInfo` remains a fixed, detached entry-state lookup with its current
unknown/invalid/shape-mismatch behavior. `IsExplicit` retains its own existing
validation behavior; the rename does not unify those two query contracts.
- `Sensitive` remains the classification predicate, separate from typed secret
references. Existing tag/predicate/dependency classification and redaction
still apply.
- `DestinationIsFallback` still describes the nearest resolved enclosing
container when the full destination is unavailable. It does not promise an
item's exact coordinates or upgrade evidence retained at an earlier stage.
- Empty-selection records keep their existing scope, order, and declaration-local
coordinates. Removing `Outcome` does not create a complete import ledger.
- `FollowSymlinks` and `IncludeHidden` retain pointer defaulting and load-preflight
snapshot behavior. Do not mechanically rename YAML `follow` or `hidden` keys.
### 2. Replace Recording Entry Points And Retire Obsolete Diagnostics
Implement the two recording methods over the existing resolution lifecycle.
Migrate manual-record callers according to the intent they currently supply;
keep assignment helper calls as helpers. Tests of container coverage, overlapping
records, dependencies, equal-valued intent, and net-change auditing continue to
protect the same behavior through the new entry points.
Complete the N4 check after replacing `Record`: trace supported recording routes,
then remove the obsolete exported invalid-kind code if its public trigger is
gone. Update tests of the removed input mechanism without weakening unrelated
record validation. Do not introduce a different public diagnostic solely to
represent an unreachable kind.
For D8, confirm both producer references and any documented intentional role for
`CodeOptionsUnavailable`, then remove the unused declaration and associated
active documentation. A concrete supported role discovered during this check
should be brought back for discussion. These are verification tasks for accepted
removals, not permission to delete other diagnostics that happen to be uncommon.
### 3. Add Direct Lookup Without Changing Source Evidence
Implement the result and error methods against each receiver's retained source
inventory. Reuse source-copying and facade-conversion helpers where practical so
lookup and enumeration agree, including nested locations, version evidence,
empty-selection evidence, and detached paths. Follow existing result-query
nil/zero conventions; failed-load nil/zero behavior is specified above.
Keep `Sources()` enumeration and `SourceContext(id)` responsibilities intact.
Lookup must not repeat acquisition, finalize failure evidence, or change source
IDs. A slice search or a suitable existing index can satisfy the contract; no
new lookup complexity promise or shared lazy cache is selected.
### 4. Carry The Two String Changes Through Their Producers And Readers
Replace the main-tier category's `"base"` spelling with `"main"` wherever that
category crosses the public boundary or is rendered. Imported contributions keep
their owning tier and ordinary source-location attribution. Other uses of the
word "base", such as filesystem base directories, are unrelated.
Change every retained-history-limit diagnostic producer and relevant reader to
`"history.limit_exceeded"`, including inheritance and final load admission.
Preserve the quota, accounting, and failure timing. This rename does not make
history optional or add a new limit control.
Review Go constant references and literal comparisons/expected output separately:
compilation catches old symbols but not stale diagnostic or provenance strings.
Other codes and layer values retain their existing meaning and spelling.
### 5. Update Consumer Guidance And Migration Information
Update declaration comments, applicable sections of [config.md](../config.md),
the [consumer guide](../consumers/README.md), README examples, and maintained
consumer code/fixtures under `examples/`. Use the new recording methods and source
lookups in relevant existing examples without expanding unrelated workflows.
Update internal documentation only where implemented ownership or terminology
changes. Accepted ADR decisions do not need revision for this cleanup.
Record the old-to-new Go names, removed outcome fields/codes, recording-call
replacements, and the two observable string changes as migration information.
Downstream applications may need to update literal comparisons and serialized
expectations as well as Go references. Version-specific release notes and
publication remain part of the normal [release process](../release.md); this
roadmap does not select a release version or authorize publication.
Keep revision-pinned review evidence and historical release records accurate for
their original revisions. Old names in those records are not stale active API
usage. Do not rewrite history or require external consumer migrations to claim
the repository implementation is complete.
## General Implementation Order
1. Map the accepted public changes to declarations, conversions, producers,
existing tests, and maintained consumer call sites. Confirm D8's intended-use
evidence and identify the D6/N4 dependency.
2. Apply the declaration and source-record changes across the facade and engine
boundary, preserving the existing semantics described above. Implement D6
with its associated N4 cleanup. Ordinary and layered paths must converge on
the same selected public vocabulary.
3. Add both source-lookup methods using the renamed source-evidence representation.
Complete the provenance and diagnostic string migration across production
sites and their readers.
4. Migrate maintained examples, documentation, and affected tests alongside the
relevant changes; finish consumer migration guidance after the public surface
is coherent.
5. Review the integrated public API and behavior, run applicable development
checks, and record completion evidence.
This is dependency ordering, not a prescribed commit count or a requirement for
intermediate releases. Independent renames can proceed together. The later
implementation plan should choose concrete work units without adding temporary
public compatibility machinery.
## Validation And Completion
Follow the [testing policy](../policy/testing.md) and
[development guide](../development.md#baseline-validation). Reuse existing
behavioral tests for mechanical renames; new tests should protect the changed
entry points and added lookups, rather than duplicate implementation details.
- Check the root API exposes every selected replacement/addition and no obsolete
public declarations from the accepted removals. Preserve root-owned type
identity and the existing public/dependency boundary checks. Historical
references and useful private implementation names do not invalidate this check.
- Exercise both recording intents through the new public methods. Preserve
helper assignment behavior, validation, recorded origins, and history under
the existing resolution tests; update the old invalid-kind case when its input
mechanism is removed.
- Cover successful and failed source lookup against each receiver's enumeration,
missing IDs, applicable nil/zero cases, detachment of nested evidence, and
unchanged records after caller mutation. Reuse existing source/version/resource
fixtures for redaction, partial failure evidence, and passive access behavior.
Do not add source-completeness, performance, or concurrency guarantees.
- Retain the existing entry-shape, sensitivity, version-mode, empty-selection,
placement, import-default snapshot, discovery, and secrets-bootstrap coverage.
In particular, Go field renames must leave YAML declarations and tri-state
defaulting behavior intact.
- Update relevant provenance and diagnostic assertions for the selected strings.
Existing history-budget cases should continue to check rejection before secret
lookup and application validation, using the new code and unchanged accounting.
- Run the applicable focused checks during development and the everyday check
for the integrated code changes. Apply existing race-check guidance if the
implementation changes ownership/concurrency behavior. Validate documentation
links and maintained examples. No benchmark campaign or additional release
gate is introduced.
Completion means all accepted proposals are implemented, the diagnostic-removal
checks are resolved, maintained consumers and current documentation use the new
surface, and applicable checks pass with behavior preserved except for the
expressly selected changes. Update roadmap/review status with the actual evidence;
passing the current baseline suite is not evidence of future implementation.
No significant open design decision remains. D8's role check and D6/N4's public
reachability check are implementation verification tasks; unexpected evidence of
a legitimate public use should be discussed before changing that use. Private
helper choices and indexing belong to the implementation plan. Public path
comparison (A2) remains deferred and outside this scope.