282 lines
19 KiB
Markdown
282 lines
19 KiB
Markdown
# Pre-v1 Public API Cleanup Roadmap
|
|
|
|
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 roadmap owns the targeted end state, required changes, and completion
|
|
criteria. The [implementation plan](implementation.md) owns concrete edits,
|
|
sequential stages, validation commands, and progress tracking. 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.
|
|
|
|
## 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 |
|
|
| --- | --- |
|
|
| D1 | Rename `Resolution.InputInfo` to `EntryInfo`, describing the fixed resolution-entry metadata view, including retained defaults and CLI assignments. Preserve its return type and lookup behavior. |
|
|
| D2 | Rename `Definition.Secret` to `Sensitive`. Preserve classification behavior, the `configkit:"secret"` tag, and typed `Secret` references. |
|
|
| D3 | Rename `SourceVersionModeDefault` to `SourceVersionModeMainOnly`, `SourceVersionCheck` to `SourceVersionEvidence`, and `SourceInfo.VersionCheck` to `VersionEvidence`. Retain `SourceVersionModeIfPresent` and `SourceVersionModeRequired`. |
|
|
| D4 | Rename `ImportSelection` to `EmptyImportSelection` and `SourceInfo.ImportSelections` to `EmptyImportSelections`. Retain path, location, and selector; remove `Outcome`, `ImportSelectionOutcome`, and `ImportSelectionNone`. |
|
|
| D5 | Rename `SourceInfo.DestinationUnresolved` to `DestinationIsFallback`, preserving its existing meaning and destination coordinates. |
|
|
| D6 (including N4) | Replace `Resolution.Record` with the two intent-specific methods below and remove `CodeResolveInvalidKind` once its public trigger is eliminated. Retain `ChangeKind` and its inspection constants. |
|
|
| D7 | Rename `LoadSecretsDir` to `LoadSecretsIntoEnvironment`, making process-environment mutation explicit. Preserve its signature apart from the name, report-plus-error behavior, and existing bootstrap semantics. |
|
|
| D8 | Remove `CodeOptionsUnavailable` after confirming there is no intentional supported role. Do not introduce a failure merely to give the code a producer; a concrete reason to retain it should be brought back for discussion. |
|
|
| A1 (including N5) | Add `Result.Source(id)` and `LoadError.Source(id)` for direct lookup of source evidence on successful and failed loads, alongside their existing `Sources()` enumeration. Keep source evidence distinct from passive resource access through `SourceContext(id)`. |
|
|
| N1 | Rename `Paths(paths ...string) Search` to `SearchPaths(paths ...string) Search`, replacing the old name outright. Preserve literal file candidates, ordering, deferred acquisition, and selection/failure behavior. Leave semantic `Path` APIs and `Searches` unchanged. |
|
|
| N2 | Replace `LayerBase = "base"` with `LayerMain = "main"`, without a compatibility alias. Update Go references and affected string comparisons, serialization, and rendered labels. Preserve the existing main-tier category, imported contributions' owning tiers, precedence, and acquisition order. |
|
|
| N3 | Replace `CodeExplainLimitExceeded = "explain.limit_exceeded"` with `CodeHistoryLimitExceeded = "history.limit_exceeded"`, without a compatibility alias. Update Go references and affected diagnostic-code consumers. Preserve the existing quota, retained-node accounting, failure conditions, diagnostic locations, and admission timing before effective secret lookup and application validation. |
|
|
| N6 | Rename `ImportDefaults.Follow` to `FollowSymlinks` and `ImportDefaults.Hidden` to `IncludeHidden`, replacing the old fields outright. Preserve `*bool` types, nil defaulting, explicit true/false, declaration overrides, traversal behavior, and search scope. Keep YAML keys `follow` and `hidden`, and Go fields `Required`, `Recursive`, and `Pattern`, unchanged. |
|
|
|
|
### Recording Methods (D6)
|
|
|
|
The selected signatures are:
|
|
|
|
```go
|
|
func (r *Resolution) RecordDerivedDefault(path Path, reason string, dependencies ...Path)
|
|
func (r *Resolution) RecordNormalization(path Path, reason string, dependencies ...Path)
|
|
```
|
|
|
|
Both record intent for work already performed by application code. They do not
|
|
assign values; `RecordDerivedDefault` does not check absence or suppress work on
|
|
explicit input. Keep `Default` and `Normalize` as the assignment-and-recording
|
|
helpers. Preserve path/reason/dependency validation, container coverage,
|
|
coalescing, net-change auditing, and callback lifetime. Replace the old `Record`
|
|
method outright rather than retain parallel public recording interfaces.
|
|
|
|
Include N4's diagnostic cleanup in this change: confirm that no supported public
|
|
input can still produce `resolve.invalid_kind`, then remove `CodeResolveInvalidKind`
|
|
without a replacement or compatibility alias. Preserve other recording diagnostics.
|
|
Internal defensive checks remain an implementation choice. If another legitimate
|
|
public trigger is found, bring it back for discussion rather than silently
|
|
reclassifying the failure.
|
|
|
|
### Version Policy And Evidence (D3)
|
|
|
|
`MainOnly` remains the zero mode and does not enable checking without a configured
|
|
version rule. The broader modes retain their requirement for a usable rule.
|
|
Document the modes together, preserving these distinctions:
|
|
|
|
- `MainOnly` retains the existing main-version check at its effective path.
|
|
Broader modes inspect each participating document in source-local coordinates
|
|
before placement and composition.
|
|
- `IfPresent` passes an absent main declaration to the application checker, while
|
|
absent non-main declarations skip the checker. `Required` rejects missing
|
|
declarations in participating documents. Existing `NoSource` behavior remains.
|
|
- Version evidence describes observed declarations or absence, not checker
|
|
invocation or acceptance. Preserve nil-versus-observed-absence meaning,
|
|
explicit null, locations, consumption, and redaction. No acceptance flag is added.
|
|
|
|
### Direct Source Lookup (A1)
|
|
|
|
```go
|
|
func (r *Result[T]) Source(id string) (SourceInfo, bool)
|
|
func (e *LoadError) Source(id string) (SourceInfo, bool)
|
|
```
|
|
|
|
Look up an acquired source by its load-local ID, returning the same information
|
|
represented in `Sources()` as a detached record. Empty or unknown IDs return
|
|
false. The query performs no source acquisition, filesystem access, or credential
|
|
lookup. Reuse existing source lookup and conversion machinery where practical;
|
|
no public registry, indexing strategy, or constant-time guarantee is required.
|
|
|
|
The failed-load lookup returns records from `LoadError.Sources()`'s partial
|
|
inventory and returns false for nil or zero-valued errors as well. Preserve
|
|
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.
|
|
|
|
## Work Required From The Baseline
|
|
|
|
### Public Declarations And Facade Conversions
|
|
|
|
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.
|
|
|
|
### Recording Entry Points And 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.
|
|
|
|
### Direct Lookup And 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.
|
|
|
|
### Observable Strings And 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.
|
|
|
|
### 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.
|
|
|
|
## 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 lookup mechanics are selected in the implementation plan.
|
|
Public path comparison (A2) remains deferred and outside this scope.
|