From aa93aeda3fb8f4baa859b9f8b09ee25ec9081407 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Mon, 19 Oct 2026 14:33:01 +0000 Subject: [PATCH] Plan import discovery and shared dependency ordering --- docs/roadmap/implementation.md | 566 +++++++++++++++++++++++++++++++++ docs/roadmap/imports.md | 5 +- 2 files changed, 569 insertions(+), 2 deletions(-) create mode 100644 docs/roadmap/implementation.md diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md new file mode 100644 index 0000000..8aeae19 --- /dev/null +++ b/docs/roadmap/implementation.md @@ -0,0 +1,566 @@ +# Implementation Plan: Import Discovery and Dependency-Ready Ordering + +Status: planned; no implementation stages completed. + +## Authority, baseline, and execution + +Implement the accepted [import roadmap](imports.md), +[ADR 0015](../adr/0015-shared-dependency-ready-ordering.md), and +[ADR 0016](../adr/0016-independent-import-controls.md), starting at +`94381a67fd39635f448a5225e38adb2a7f43cc9f`. The roadmap owns target behavior and +scope; this plan settles delivery order and the remaining implementation choices. +The accepted ADRs already exist; do not draft replacements or rewrite their +decision text. + +The implementer is a Luna coding agent. Execute one numbered stage per focused +prompt, in order. Each stage should end with a validated, nonempty commit and a +completion entry here identifying the commit, checks, and any remaining work. +Do not mark a stage complete while its acceptance conditions remain unmet. +Preserve unrelated work. This planning pass changes documentation only. + +Start with [development](../development.md) and read the applicable +[agent](../policy/agents.md), [architecture](../policy/architecture.md), +[testing](../policy/testing.md), and [documentation](../policy/documentation.md) +policies. Prefer the code graph for discovery, then inspect current source and +tests; indexed snippets can have stale line ranges. Use the actual working tree +when an indexed snippet is incomplete or mismatched. + +Keep each stage's public documentation accurate to its implemented boundary. +Private groundwork may precede wiring, but do not expose options that silently +do nothing. The final syntax cutover is Stage 14; there is no consumer-facing +compatibility mode, alias, or alternate scheduler. Intermediate private helpers +are scaffolding, not a second supported interface. Release publication and +consumer dependency updates are outside this plan. + +## Settled implementation choices + +### Public defaults + +Add a root-owned `ImportDefaults` struct and an `ImportDefaults ImportDefaults` +field to both `Options[T]` and `LayeredOptions[T]`: + +```go +type ImportDefaults struct { + Required *bool + Follow *bool + Hidden *bool + Recursive *bool + Pattern []string +} +``` + +Nil boolean pointers mean unspecified. Copy pointed-to values when loading +begins. Nil `Pattern` means unspecified; non-nil empty means select nothing for +directory searches. Snapshot the slice without collapsing this distinction. +No new defaults field belongs on `Input`, `Underlay`, or `Definition`: one +load-level selection applies to main and all underlay/transitive import +declarations. Existing per-input `Imports` booleans still enable imports. + +Resolve each applicable declaration field independently: explicit declaration, +then application default, then library default. Library defaults are required +false, recursive false, follow true, hidden true, and unrestricted filenames. +No parent-declaration inheritance, enforced application override, default +exclusion list, or application depth setting is added. `pattern` replaces rather +than augments the default. Validate supplied default patterns once at option +selection, reporting `options.invalid` before source reads or callbacks. +Defaults do not make unsupported fields applicable to a selector. + +Use a private presence-aware declaration representation, distinct from its +resolved discovery policy. Normalize scalar/list selectors and filters once. +Keep existing import path validity rules, with `.` accepted for literal directory +roots. Match basenames with case-sensitive `path.Match`; path globs retain their +existing grammar, including rejection of recursive `**`. A filename filter has +no directory-recursion interpretation. Validate all expressions even in empty +or otherwise inactive selections. Follow the roadmap's option applicability, +empty-list, null, and depth rules exactly. + +`depth` has no arbitrary machine-integer maximum. Accept nonnegative YAML +integers under the existing scalar rules, including bounds larger than can be +reached under the visit budget; an implementation may saturate its internal +bound at the largest representable traversal depth without rejecting that input. +Numeric `-0` denotes zero. Do not accept fractional/exponent numbers as integer +depth or coerce strings. + +### No-selection inspection + +Extend root-owned `SourceInfo` with `ImportSelections []ImportSelection`. Add +root-owned string types and constants: + +- `ImportSelector`: `ImportSelectorPath = "path"`, `ImportSelectorDirectory = + "dir"`, and `ImportSelectorGlob = "glob"`. +- `ImportSelectionOutcome`: `ImportSelectionNone = "none"`. +- `ImportSelection` fields: `Path Path`, `Location Location`, + `Selector ImportSelector`, and `Outcome ImportSelectionOutcome`. + +`Path` is the source-local declaration path, such as +`/configkit/imports/0`; `Location` identifies the declaring mapping and carries +its actual SourceID. Attach one record to that declaring source for each +effectively optional declaration whose entire selected set is empty. Keep +records in declaration order. Do not record partial omissions, candidate lists, +raw selector values, inferred missing-file reasons, warnings, or fake sources. +Required empty `path: []` succeeds but gets no optional-declaration record. + +Reuse `Result.Sources`, `LoadError.Sources`, and callback source snapshots rather +than adding another query surface. Snapshots contain only outcomes established +by that point; no complete discovery record is promised after an earlier error. +Records remain source-local through mounting and item placement. Deep-copy paths +and slices through engine cloning and facade conversion. Existing version-text +redaction remains independent and unchanged. + +### Scheduling and identities + +Keep the shared scheduler private to `internal/engine`, in a focused +`dependency_order.go` owner; no new public scheduling API or dependency is needed. +It accepts immutable node keys and dependency edges and returns a complete order +or an actual closed cycle. Use Kahn's algorithm and `container/heap`; deduplicate +edges before counting dependencies. Compute keys once. Compare key tuples by Go +bytewise string order component by component, shorter tuple first on a prefix. + +Use these key constructions in both integrations: + +- Import nodes: `(namespace-kind, namespace-anchor, resource-kind, resource-path)`. + Kind is `host` or `native`; resource kind is `file` or `synthetic`. Host paths + are canonical absolute paths rendered with slash separators; native paths use + their existing namespace-relative identity. Synthetic roots use their explicit + input anchor, not a label or allocated token address. +- Derive namespace anchors from explicit request positions, never discovery. + Positions are main `(0,0)` and underlay/input `(group+1,input+1)`. Encode each + numeric component in fixed-width decimal sufficient for a Go index. All host + accesses within one scheduled tier share its host anchor; each native token + uses the smallest explicit input position selecting that namespace in that + tier. Same-label, separately constructed filesystems remain distinct. Use + tokens to identify equality, not to order nodes. +- Inheritance nodes: `("definition", scope-pointer, definition-pointer)` using + canonical escaped semantic pointers. Within a sibling scope these distinguish + exact names, including empty or escaped keys. No source ID participates. + +The tuple comparator is shared; resolver-specific key construction is not a +second ordering algorithm. Unique keys are an internal construction requirement, +not a new user configuration restriction. Imports already reject repeated +canonical inclusion; separate synthetic roots have distinct explicit anchors. + +For a stalled graph, deterministically traverse residual dependencies using +explicit DFS state, visiting nodes and neighbors in key order. Return an actual +stack cycle, rotated to begin at its smallest key, with the start repeated at +the end. Exclude blocked non-cycle dependents. Both resolvers translate these +node/edge identities to existing domain diagnostic codes and authored sites; +do not expose inheritance names or payload values in messages. Preserve import +cycle-site evidence. Build deterministic adjacency from precomputed node ranks +in linear edge work, rather than repeatedly sorting the ready set or scanning +all nodes for each completion. Scheduling costs O(E + V log V), O(V + E) memory, +apart from key construction/comparison and domain operations. + +### Discovery, scopes, and assembly + +Keep acquisition deterministic and separate from application. Enumerate +declarations in authored order; normalize/deduplicate a declaration's selected +candidate paths and visit them in namespace-path lexical order. Keep main-first +acquisition records, IDs, source-local version checking, and physical import +resolution. This discovery order does not determine sequence assembly order. +There is no new first-error or no-read-before-error guarantee. + +Represent dependencies while acquiring files. Ordinary source-body nodes depend +on their imported contributions; importing bodies therefore assemble after +their dependencies. Record source roles explicitly: the main body must not be +identified as contribution index zero after scheduling. Keep all source IDs and +authored locations attached to contributions when reordering them. + +Each main tier or underlay group has one outer strict-scope graph, including all +its independent input roots and ordinary imports. An item contribution is one +outer node keyed by its owning source. It owns a nested strict mapping-scope +graph containing that source body, ordinary helper contributions, and further +item nodes. Prevalidate the available scope schedules before applying their +operations. When the outer schedule selects an item node, execute its validated +local schedule, compose the item mapping, then place the completed item into +the outer scope. Do not globally flatten helper bodies into the collection. +Resolve local paths and project final indexes using that actual scheduled +contribution order. Main-item and underlay-item roots use the same model. + +Retain the acquisition/inclusion graph independently of these composition scope +boundaries so cycles crossing item boundaries remain detectable. On an active +canonical repeat, retain the closing edge without rereading the source and use +the shared cycle logic on the available inclusion graph. Non-active repeated +inclusion still fails as `import.repeated`; no successful diamond import or +global source deduplication is introduced. + +Within inheritance, construct the graph of direct mapping siblings and their +string parent edges, validate it, then produce templates in scheduled order. +Null cancels a relationship without an edge. Keep enclosing-before-nested +destination-local traversal and unresolved nested templates, as in ADR 0009. +Do not reorder output mappings merely to mirror scheduling. + +Directory discovery keeps candidate spellings separate from canonical access. +One normalized candidate path per namespace is selected once per declaration; +aliases retain separate candidates and existing admission rules. Directory +filters run on discovered names. Exclusions never read content, but do not hide +discovery, containment, or resource failures. For required named paths, verify +every listed target exists even if excluded, without parsing excluded content. + +Use existing bounded directory reads. For distinct roots, traverse each search +with its applicable depth once and test the union of filename patterns per +file; do not walk once per root/pattern pair. Overlapping roots may revisit +entries under the existing visit accounting, but selected candidates deduplicate. +Do not use global canonical-directory visitation to silently suppress aliases. +Charge selected-source allowance after exclusions and local deduplication; +discovery entries still count throughout, and excluded content costs no bytes. + +Use host `Lstat`/root-relative operations for discovery controls and the standard +native `fs.ReadLinkFS` capability where available. Follow the supplied filesystem's +capabilities; do not require every `fs.FS` to implement link inspection or turn +opaque native behavior into a universal sandbox guarantee. Host directory cycle +keys are canonical paths; link-aware native traversal uses the corresponding +resolved namespace directory identity. This traversal identity must not silently +change the existing native source-admission identity. Track canonical directories +on the active traversal path, not all previously visited directories. Distinguish +directory traversal cycles from import dependency cycles; use `import.cycle` +with the declaring site and a safe directory-cycle message for the former. + +## Stage 1 — Build the shared scheduler + +Create the private scheduler, tuple comparator, min-heap, and deterministic +cycle finder specified above. Keep it independent of documents, filesystem +handles, diagnostics, and callbacks. Document Kahn's algorithm, actual-cycle +identification, and complexity beside its owner. + +Tests own observable schedules: independent branches, unequal chains, multiple +dependencies, shared dependencies at equal/unequal depths, a newly ready small +key preceding an older large key, duplicate edges, self/multi-node cycles, and +blocked non-cycle dependents. Permute insertion order while retaining keys and +assert equal schedules/cycles. Do not assert heap internals. + +Acceptance: focused scheduler tests pass; no loading behavior changes. + +## Stage 2 — Separate inheritance graph analysis from application + +In `inheritance.go`, extract direct-sibling relationship analysis from the +existing stack-driven application loop. Build keyed mapping nodes and edges; +retain null controls, missing/non-mapping parent diagnostics, exact directive +sites, and non-mapping siblings. Add a scheduled template-application helper +reusing current merge hooks, origins, retained-node accounting, and unresolved +nested template behavior. Keep the currently wired resolver unchanged until +Stage 3; do not expose an alternate public path. + +Acceptance: private scope tests demonstrate the shared schedule, ordinary/null +relationships, real cycle sites, and preserved template values/ownership. + +## Stage 3 — Integrate scheduled inheritance + +Replace the old sibling-frame resolution in the loading path with Stage 2's +analysis and application. Remove superseded stack/state machinery. Retain +`inheritance_walk.go`'s enclosing-before-nested scope discovery, sequence +traversal, final projection budgets, and immutable retained evidence. + +Review inheritance history/control/transfer ordering against the selected +schedule, not the old DFS order. Add one unequal-branch integration case and +reuse existing nested destination, cancellation, sensitivity, version ownership, +and budget tests. Update the owning inheritance contract and internal overview +to describe implemented scheduling, linking ADR 0015. + +Acceptance: inheritance and facade inheritance suites pass; final values, +presence, origins, and explanation agree; no alternate resolver remains. + +## Stage 4 — Retain the import inclusion graph during acquisition + +Refactor `imports.go` and `load_input.go` so acquired contributions carry stable +source identity, role, inclusion edges, and explicit scope ownership, rather +than treating their slice position as both acquisition and application order. +Separate item discovery from immediate item composition. Preserve parsed +payloads and source-version processing results without rereading sources. + +Keep existing wired application order for this extraction stage. Introduce the +stable import keys and include-cycle integration with the shared cycle finder; +keep non-active repeats invalid, including aliases and different inclusion +routes. Do not expand successful shared dependency support for imports. + +Acceptance: current ordinary/item import behavior tests pass, including a cycle +through a nested item scope, repeated imports, source IDs, and handle closure. + +## Stage 5 — Schedule ordinary main-tier contributions + +Use the shared scheduler for ordinary mapping contributions in the main tier. +Plan before composing. The main body follows its import dependencies; independent +ready branches follow stable keys. Reuse `composeDocumentsWithPolicy` and the +existing merge primitives. Update the corresponding order tests deliberately. + +Replace assumptions that main is document/contribution zero in +`importedVersionClaim`, source-root ownership, contexts, and history. Carry an +explicit main source ID/role and locate its scheduled contribution. Keep source +enumeration and version callbacks in acquisition order. Default-mode effective +version checking still happens after main-tier assembly. + +Acceptance: ordinary import values, registered sequence order, conflict sites, +main-version protection, source records, and authored resource contexts agree. +Document this implemented ordering boundary in the import contract. + +## Stage 6 — Assemble item-local scopes under the scheduler + +Integrate item nodes and local schedules for imported and selected main items. +Complete helpers before local item assembly and outer placement. Reuse existing +`projectNestedEvidence`, destination projection, sequence ranges, and diagnostic +projection, correcting any assumptions about contribution order or index zero. +Do not register application collection policies inside helper mapping scopes. + +Keep local version checking/consumption before assembly and project retained +source evidence through the actual assigned indexes. Failed-load source paths +retain the existing unresolved-container semantics until indexes are known; +do not invent an exact index to simplify a failure. + +Acceptance: nested items, helper-supplied IDs, main items, multiple unequal +branches, physical coordinates, sensitivity, history chronology, and item +conflict paths pass engine and public tests. Run the focused race suite. + +## Stage 7 — Schedule underlay forests and preserve tier boundaries + +In `load_request.go`, acquire all roots in a strict underlay group before +scheduled group assembly. Combine their retained scope graphs rather than +concatenating already composed per-input orders. Assign namespace anchors from +explicit input positions. Include inputs without imports and item roots. + +Keep per-tier repeated-source state, accounting, main acquisition timing, and +underlay precedence unchanged. Independent groups never enter one scheduler; +overlays/CLI remain later precedence operations. Maintain source layers, +underlay indexes, global source IDs, and group-wide item path projections. + +Acceptance: a group with interleaving dependency branches across input roots +uses the expected schedule; separate tiers still replace sequences wholesale. +Test same-label distinct native namespaces and copies of one namespace. NoSource +still contributes no source or explicit empty root. + +## Stage 8 — Define private defaults and the final declaration parser + +Add the private defaults snapshot/validation and resolved-policy helpers. Add +the final declaration parser as an unwired private helper until Stage 14; retain +the current wired parser only until that cutover. Store declaration paths and +field locations for exact diagnostics and later no-selection evidence. + +Cover the roadmap's selector/option matrix: scalar/list normalization, exactly +one selector, unknown fields including removed `optional`, null/wrong-type +members, empty lists, duplicates, wildcard validation, literal destinations, +placement, and effective-recursion/depth applicability. Parse all declarations +before selecting candidates; invalid inactive fields still fail. + +Acceptance: parser/policy tests cover omitted, explicit false, explicit empty, +application defaults, and invalid default patterns without source access. No +new YAML syntax is accepted by public loading yet. + +## Stage 9 — Implement named-file selection and exclusions + +Build a private selector result containing normalized lexical candidates and +selection outcome. Implement string/list `path`, local candidate deduplication, +basename exclusions, and optional/required presence semantics. Check excluded +required target existence without opening content. Do not treat permission, +containment, regular-file admission, or parser failures as optional absence. + +Keep selector results distinct from source-admission identities; no source IDs +or read counts are assigned merely by selection. Preserve current validity rules +for explicit paths and existing source-access behavior for named symlinks and +hidden targets. Do not apply search-only controls to this selector. + +Acceptance: temporary-file tests cover partial missing lists, required/excluded +missing targets, explicit empty lists, alias candidates, and unread excluded +content. No fake source records are created for absence. + +## Stage 10 — Implement shallow directory selection + +Add literal directory string/list search, scalar/list basename patterns, and +exclusions through the same candidate-selection result. Start with nonrecursive +selection. Missing roots contribute nothing; an inaccessible or invalid supplied +root is not absence. Directories are traversal containers, not documents. + +Implement set union and difference, normalized candidate-path deduplication, +and requiredness across the complete selected union. Preserve nil/unrestricted +versus explicit-empty patterns and alias spelling during filtering. Test multiple +roots, overlapping roots/patterns, extensionless and hidden filenames, and a +missing root alongside one that supplies the required match. + +Acceptance: shallow directory tests pass with actual host files and a native +filesystem; no per-root/per-pattern requiredness is introduced. + +## Stage 11 — Add recursive directory traversal and depth accounting + +Extend the walker with explicit traversal frames, effective recursion, and the +settled depth convention. Apply filename patterns only to files, never to prune +directories. Share bounded directory-reading and entry accounting with glob +discovery. Do not rescan a root per pattern or use the import-edge depth limit +as a directory-recursion limit. + +Acceptance: direct files are depth 1, depth 2 includes one descendant level, +zero/omission are unlimited subject to existing budgets, and depth requires +effective recursion. Cover application-enabled recursion, explicit false, +large depth integers, empty searches, and limits using test-controlled budgets. + +## Stage 12 — Add discovery symlink and hidden controls + +Implement `follow`/`hidden` for directory discovery using capability-aware +filesystem helpers. Explicit roots keep existing access semantics; discovered +hidden directories prune when hidden is false, discovered symlink directories +do not descend when follow is false, and analogous files are not selected. + +When following links, track active-path directory identities and fail actual +loops without treating earlier completed branches as cycles. Preserve namespace +containment and candidate spellings. Cover contained links, escapes, filename +filtering on aliases, self/ancestor loops, and separate noncyclic aliases that +later retain ordinary repeated-source admission behavior. + +Acceptance: host filesystem behavior and a focused link-aware native fixture +pass; plain native filesystems still load without new capability requirements. +All success/failure paths close library-owned directory and root handles. + +## Stage 13 — Integrate glob filtering and final candidate accounting + +Adapt `glob.go` to the common selection pipeline. Keep path wildcards and +literal components distinct so follow/hidden filters affect only wildcard- +discovered entries, not explicitly named components. Apply basename exclusions +to final candidates. Preserve regular-file/source validity behavior rather than +silently accepting invalid glob-selected sources. + +Move source-allowance checking after exclusions and declaration-local +deduplication. Intermediate traversal candidates are bounded by entry visits, +not by the final source allowance. Charge bytes only when selected content is +read; never read excluded content. A tiny private source limit with many excluded +positive matches must succeed when its final selected set fits. + +Acceptance: existing glob syntax, containment, alias, and visit-budget tests +pass alongside discovery-control and post-filter source-limit regressions. + +## Stage 14 — Wire final syntax and load-wide defaults through the engine + +Add the private defaults value to ordinary/grouped requests, snapshot/validate +it before acquisition, and pass it to every enabled main/underlay/import +declaration. Wire Stage 8's parser and Stages 9–13's selection pipeline into +graph acquisition. Remove the old declaration parser and `optional` field; +there is one final parser and one absence policy. + +Include `source_version.go`'s stored import declarations in this wiring: syntax +parsing stays independent of source-version interpretation, and every stored +declaration receives the same effective policy before discovery. Do not bypass +validation when a consumed header or empty payload leaves no application fields. + +Keep imports disabled unless already enabled by the consumer. Selected overlays +still cannot enable their own imports; defaults do not change that boundary. +Validate effective placement/depth and declaration values before relying on a +missing target or empty selection to skip work. Declarations do not inherit +parent control values. + +Migrate existing tests and maintained fixture declarations from `optional` to +the intended `required` behavior. Tests expecting a missing import to fail must +request requiredness, not weaken their checks. Update the owning configuration +contract to describe the now-implemented final YAML interface and breaking +absence/order changes. Keep exact public Go defaults documentation for Stage 16. + +Acceptance: all engine imports, glob, destinations, source-version, and layered +tests pass under final syntax. An explicit regression rejects `optional`; +another proves missing imports are optional without setup. Run everyday checks. + +## Stage 15 — Retain no-selection evidence across load outcomes + +Add the private records from the settled inspection design to declaring source +records and their clone functions. Record only completed, optional, whole- +declaration empty outcomes. Preserve evidence for main and imported declarations +and underlay inputs through composition, nested item placement, overlays, +resolution entry state, final publication, and failed-load accumulation. + +Use source IDs to attach outcomes, not scheduled positions. Reuse source-record +transport; do not add synthetic imported sources or warnings. Keep evidence +source-local and detached even when its source destination remains unresolved. + +Acceptance: tests cover no matches, missing paths, empty lists, exclusions, +partial path-list omission (no record), and required empty paths (no record). +An error after a prior empty optional declaration retains that established +evidence, but does not fabricate later outcomes. Mutating query results cannot +alter subsequent snapshots or another load. + +## Stage 16 — Expose defaults and inspection through the public facade + +Add root-owned declarations from this plan, `ImportDefaults` fields on ordinary +and layered options, and `SourceInfo.ImportSelections`. Add explicit converters +and engine transport types/helpers as needed, following existing root-wrapper +ownership. Snapshot pointers/slices and preserve nil versus non-nil empty +patterns. Do not add defaults on individual inputs or a new result query API. + +Exercise final behavior through `Load` and `LoadLayered`, including defaults +applied to transitive and underlay imports, explicit declaration exceptions, +invalid default preflight without reader consumption, and result/error/resolver +source inspection ownership. Update declaration comments and the owning Go API +guidance when the surface becomes available. + +Acceptance: public facade/import-boundary tests and representative engine/public +equivalence cases pass; no internal type leaks through exported signatures. + +## Stage 17 — Audit cross-feature lifecycle and ownership + +Review and fill meaningful gaps rather than adding a full Cartesian-product +suite. Reuse existing regressions for version protection, consumed-header +sensitivity, scope diagnostics, NoSource, and historical removed descendants. + +Add representative combined cases for scheduled discovered items with helper- +supplied IDs; nested destinations and actual assigned indexes; required versus +if-present source versions; main-version ownership after main moves later in a +schedule; inherited relative resources; superseded relationships; and final +configuration/metadata/explanation agreement. Ensure consumed headers cannot +silently supply record IDs and secret values remain absent from diagnostics +and inspection. Preserve callback phases and source-local callback ordering. + +Compare an equivalent keyed graph through import and inheritance integrations: +both use the scheduler's eligible-node rule despite different domain operations. +Keep acquisition-source records stable when only graph construction order is +permuted in private scheduler/integration fixtures; do not promise unchanged IDs +when authored discovery order itself changes. + +Acceptance: run `go test -race ./internal/engine`, focused root facade tests, +and everyday checks. Record any genuine unresolved gap before marking complete. + +## Stage 18 — Maintain simple and complex consumer examples + +Update the prompt-catalog example for directory search, multiple patterns, +exclusions, and helper-supplied IDs while retaining explicit registration and +application final validation. Include application import defaults and a +declaration exception, plus inspection of a deliberately empty optional search. +Keep a short simple single-file/required-file example so adoption does not +require understanding all discovery controls. + +Update fixture expectations for scheduled sequence positions. Verify mounted +resource origins, whole-sequence precedence, and quiet absence through executable +examples. Do not add a consumer-side discovery, merge, scheduling, or provenance +reconstruction pass. All fixtures remain local, deterministic, and secret-free. + +Acceptance: consumer tests and executable public examples pass; the consumer +guide links complete copyable examples rather than duplicating them. + +## Stage 19 — Finalize documentation and validate the completed unit + +Align README orientation, `docs/config.md`, public declaration comments, +`docs/internal/overview.md`, relevant focused internal docs, and the development +reading/test map. Document Kahn's algorithm, set union/difference, and active-path +cycle detection beside their owners. State acquisition versus resolution order, +explicit defaults precedence, no-selection evidence, and source namespace/key +construction without duplicating canonical contracts. + +Update architecture policy to recognize implemented explicit directory discovery +and shared scheduling while retaining the boundary against unrequested implicit +application-path discovery. Update only ADR status/navigation as needed to link +implemented contracts; accepted decision text stays unchanged. Leave release +notes/version choice and roadmap retirement for separately authorized release +preparation. Do not introduce release gates, CI waiting, consumer validation +requirements, dependencies, or unrelated defaults/security changes. + +Run the everyday `./scripts/check.sh`, `go test -race ./...`, consumer/examples +tests, local documentation links, and `git diff --check`; reuse checks already +covering unchanged final content instead of repeating them gratuitously. Review +the baseline-to-final public and YAML diff for removed `optional`, changed +requiredness and sequence ordering, and accurately documented native filesystem +capability limits. Inspect source and history indexes for accidental quadratic +rescanning; no timing thresholds or busy-host benchmark evidence are required. + +Acceptance: all stages are complete, the final implemented behavior matches the +roadmap and ADRs, validations are recorded here, and the implementation workspace +is committed and clean. No release is published by this plan. + +## Open Questions + +None required to begin implementation. The API, evidence shape, ordering keys, +scope boundaries, and cycle treatment are selected above. Private helper names +and file splits may be adjusted for clarity without changing those decisions. +If implementation reveals a genuine conflict between an accepted requirement +and existing contracts, report it rather than silently strengthening or weakening +either one. diff --git a/docs/roadmap/imports.md b/docs/roadmap/imports.md index 62bba02..3d9355c 100644 --- a/docs/roadmap/imports.md +++ b/docs/roadmap/imports.md @@ -1,11 +1,12 @@ # Import Ergonomics And Permissive Defaults Status: accepted design; implementation pending. This document captures planned -behavior and requirements. Implementation sequencing remains to be prepared. +behavior and requirements. The [implementation plan](implementation.md) owns +delivery sequencing and the concrete API and integration choices. The selected direction separates directory searches, filename matching, recursion, and absence handling. Optional-by-default imports are the intended direction. The consumer-directed and Ansible-aligned decisions below are settled; -API spelling and implementation details remain for implementation planning. +API spelling and implementation details are specified by the implementation plan. All new syntax below is illustrative and unimplemented. The durable architectural decisions are recorded in