diff --git a/docs/roadmap/api.md b/docs/roadmap/api.md index 726e2e7..f25150e 100644 --- a/docs/roadmap/api.md +++ b/docs/roadmap/api.md @@ -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.