Files
ConfigKit/docs/roadmap/internal-boundaries.md

187 lines
11 KiB
Markdown

# Import Discovery And Facade Boundary Simplification
Status: target defined; execution is tracked in the [implementation plan](implementation.md).
Baseline: `80cf23e7102fca2c5d7c7621e75f930a1ef1ecad`.
This roadmap brings together the two refactors deferred until after the audit
remediation sprint: glob entry preparation (**C03**) and facade-to-engine
transport simplification (**F07**). Their original motivation is retained in the
[glob](future.md#1-separate-glob-entry-preparation-from-traversal) and
[transport](future.md#2-simplify-redundant-facade-to-engine-transport) future-work
entries and the [consolidated audit](audit.md).
The goal is clearer responsibility and ownership with fewer redundant internal
representations. Both changes preserve the public API and configuration model.
They are independent work areas within one maintenance effort, not a new loading
workflow. The [implementation plan](implementation.md) owns concrete edits,
stages, validation commands, and execution progress.
## Baseline And Targeted End State
The preceding sprint repaired directory-failure classification and shared link
dependency evaluation, clarified acquisition handoffs, and removed unused
placement bridges. Those changes provide the baseline; this work does not repeat
or redesign them.
| Area | Current baseline | Target |
| --- | --- | --- |
| Glob discovery | `selectGlobImportCandidates` interleaves traversal and set operations with substantial per-entry preparation. | The selector coordinates discovery; a cohesive private operation prepares a wildcard-discovered entry. |
| Facade transport | Import defaults pass through root conversion, an exported engine transport record, an equivalent private engine record, and repeated snapshots. Placement construction also uses setter-style bridges. | Root-owned public records convert explicitly to one engine defaults representation, with straightforward engine option/input construction and identifiable ownership copies. |
The [architecture policy](../policy/architecture.md), [configuration
contract](../config.md), and public declarations remain authoritative. [ADR
0006](../adr/0006-public-facade.md) continues to govern the facade boundary. These
refactors do not require a new architectural decision or changes to its accepted
decision. The [component overview](../internal/overview.md) and [import
internals](../internal/imports.md) own implemented structure.
## Glob Entry Preparation
### Target Responsibility Split
In [glob.go](../../internal/engine/glob.go), the selector continues to own pattern
validation, component advancement, literal-segment handling, directory
enumeration and its accounting, candidate union and sorting, final target
validation, exclusions, and requiredness.
A private glob-specific preparation operation owns the patterned branch's work
for one directory entry: matching and hidden-entry filtering, lexical/access path
construction, containment checks, target inspection and discovered-link policy,
intermediate-directory eligibility, host/native access-path selection, labels,
and candidate construction. Its result distinguishes a selected candidate, an
ordinary skip, and a diagnostic. It receives the facts needed for that entry
rather than mutating the selector's candidate set or surrounding traversal state.
Use the existing filesystem access and link-resolution helpers. Directory
selection already has `prepareImportDirectoryEntry`; it remains a separate owner
because its recursion, matching, absence handling, and traversal state differ.
Share a smaller operation only where it actually expresses the same semantics
and reduces duplication. No common visitor or discovery strategy is needed for
this extraction.
### Behavior To Preserve
Preserve the current distinctions and processing order documented by
[explicit imports](../config.md#explicit-imports) and exercised by the selection
tests:
- Literal components remain explicit selections; discovery filters apply at
their existing wildcard boundaries. Moving matching or hidden filtering after
filesystem inspection would change which errors are observable.
- Keep lexical candidate identity separate from resolved access identity.
Native source identity and relative imports retain namespace spelling; host
access retains its existing canonicalization and containment behavior.
- Keep discovered-link follow rules, intermediate-directory eligibility,
missing-target handling, and structured diagnostic sites/classifications.
Do not make glob and directory rules identical as a side effect of extraction.
- Preserve deterministic candidate and error order, union/deduplication,
directory-entry accounting, and the existing point of source admission.
Final selected-file validation remains before exclusions where it is today;
exclusions do not hide discovery or resource errors.
- Retain the preceding sprint's distinction between missing-on-open directories
and failures after opening, along with operation-local completed-link reuse.
The intended benefit is that a maintainer can understand traversal separately
from entry eligibility and identity preparation. This is a readability change;
it does not select a different search algorithm or claim a speedup.
## Facade-To-Engine Transport
### Target Representations
The root keeps its public `ImportDefaults`, `PlacementMode`, `Options`, `Input`,
and `LayeredOptions` types. Explicit conversions remain appropriate at this
boundary; consumers must not acquire engine type identity, fields, or methods.
Inside the engine, consolidate the equivalent `ImportDefaults` transport and
private `importDefaults` records into one presence-aware input-defaults
representation. Carry that representation through the ordinary and layered
options, normalized request, and acquisition policy instead of translating the
same five fields between equivalent engine records.
Keep `resolvedImportPolicy` distinct: it represents concrete per-declaration
choices, including selector-specific rules, rather than another copy of optional
load-wide input. Likewise, registration compilation and the normalized loading
request have real responsibilities and are not replacement targets.
Make placement and defaults straightforward to construct on the existing engine
option/input records. Remove decorator-style bridges made unnecessary by that
construction surface. Exporting fields or types within `internal/engine` where
needed by the root converter does not make them part of ConfigKit's supported
public API. Keep explicit enum conversion and preserve unknown values until the
existing option validation can report them; conversion must not silently choose
a default or move validation into facade setters.
### Ownership And Copying
Make the actual mutable ownership boundaries identifiable. Public load calls
continue to snapshot pointed-to default booleans and the pattern slice before
source acquisition, as specified by the [public
declaration](../../lifecycle.go). Preserve omitted, explicit false, nil pattern,
and non-nil empty pattern as distinct inputs where they are distinct today.
Review the entire handoff, not just the duplicate type definitions: root
conversion in [conversion.go](../../conversion.go), ordinary construction in
[lifecycle.go](../../lifecycle.go), layered construction in
[layered.go](../../layered.go), engine options and normalization, acquisition
policy construction, and declaration resolution in
[import_spec.go](../../internal/engine/import_spec.go).
Remove snapshots that merely recopy already-owned read-only defaults as they
cross those private representations. Keep copies needed when establishing
independent mutable ownership, including any independently owned resolved
policy. The target is explainable ownership and less redundant work, not an exact
copy count or removal of copying throughout the library. Shared defaults within
one load can be read-only by implementation discipline; this creates no new
caller immutability or concurrency requirement.
Preserve ordinary and layered option preflight before source reads and application
hooks, independent declaration overrides, transitive/underlay propagation,
selected-overlay behavior, destination normalization, and invalid-enum
diagnostics. Keep callback, source, path, secret, and returned-record conversions
whose ownership or domain meaning is not redundant transport.
The intended benefit is fewer concepts, field mappings, and construction paths
to maintain. Reduced copying is useful but does not establish an end-to-end
performance guarantee.
## Documentation Ownership
Internal documentation describes the resulting discovery and transport
boundaries once implemented. Public declarations continue to own the existing
snapshot and type contracts; this effort selects no new public behavior.
The corresponding C03/F07 future-work entries serve as navigation to this
roadmap rather than parallel target or progress inventories. Unrelated future
candidates remain separate. The implementation plan owns the documentation
updates and retirement of replaced private representations and helpers.
## Validation And Completion
Follow the [testing policy](../policy/testing.md) and [development
guide](../development.md#baseline-validation). Reuse the existing glob selection,
directory/link failure, import-default, placement, public facade, and dependency
boundary coverage. Add a focused behavioral case only where a concrete
extraction or ownership risk lacks protection.
For discovery, verify literal versus wildcard filters, host/native identity,
contained and escaping links, optional absence versus read/close failures,
ordering, exclusions, regular-file checks, and existing resource accounting. For
transport, verify nil/empty and explicit-false distinctions, mutation of caller
default storage after the load snapshot through a supported callback, invalid
options before input consumption, both loading APIs, and transitive/underlay
defaults. Existing conversion-focused tests may change with private construction;
preserve the useful ownership behavior rather than fossilizing a helper's shape.
Completion requires an easier-to-follow selector, one engine input-defaults
representation, fewer redundant mapping/construction sites, justified remaining
copies, and preserved public behavior under the relevant checks. Review source
and ownership flow as well as passing tests; moving complexity into a helper or
renaming a duplicate record alone is insufficient.
No benchmark campaign, complexity score, allocation threshold, exact filesystem
call trace, new resource limit, or additional release gate is required. This work
adds no dependencies, caches, background activity, or new consumer controls, and
does not reopen other audit findings or deferred performance experiments. Routine
helper signatures, names, and file placement belong to the implementation plan;
no significant product or architectural decision remains open for this scope.