Record main-relative scalability findings

This commit is contained in:
2026-11-09 21:01:36 +00:00
parent a05bb94a21
commit 9a08438769

View File

@@ -156,3 +156,73 @@ deterministic root-open failure or a permission fixture that verifies
the platform actually denies the open. The check concerns root access the platform actually denies the open. The check concerns root access
during loading. Later resource operations retain their existing filesystem during loading. Later resource operations retain their existing filesystem
semantics. [Layered loading contract](../config.md#layered-loading) semantics. [Layered loading contract](../config.md#layered-loading)
## Algorithm audit
The audit covers the implementation from `ae0c94d` through `18af2d2`.
It analyzes the work and storage implied by the code. The planning decisions
on precedence, selection, import traversal, and context ownership remain the
basis for the analysis.
| Stage | Work and storage reviewed |
| --- | --- |
| 1 | Facade conversion and binding preflight visit each input once, with work proportional to the option data copied or validated. The existing diagnostic sort orders failures after collection. |
| 2 | Binding and namespace anchor selection use a fixed number of linear passes. The temporary context table and per-input resolved copies are avoidable. See Finding 7. |
| 3 | Declaration preparation visits each declaration once, but resolving a shared pattern default copies its entries for each inheriting directory declaration. See Finding 6. |
| 4 | The no-base path prepares declarations and scans requiredness before assembling one payload. The pattern copies contribute a multiplicative cost even though no traversal runs. Root assembly duplication is already tracked in Finding 2. |
| 5 | Context selection considers at most three choices, and the shared overlay loader makes one linear pass over acquired sources for duplicate detection. The native path correctness issue remains in Finding 1. |
| 6 | The example uses one layered load and the existing declaration, import, and tier assembly paths. It adds no separate scan for companion files. |
| 7 | Source budgeting and evidence reuse the existing load state. The focused suite passed for the new loading paths and their import, overlay, and sequence-item dependencies. |
| 8 | The documented single discovery and deferred selection match the call path reviewed above. The identified improvements concern private storage and work, with no change to the selected algorithms or public behavior. |
## Finding 6 — Skipped directory imports copy shared patterns per declaration
**Priority P3.** With no base, `acquireContextlessInput` calls
`prepareImportDeclarations`, which holds one full resolved policy per
declaration. Each directory declaration that inherits the load-wide
`ImportDefaults.Pattern` allocates a separate copy of the pattern slice.
The no-base path reads the requiredness from those policies and never uses
the copied patterns.
[No-base preparation](../../internal/engine/contextless_imports.go#L22)
· [Policy slice](../../internal/engine/import_acquisition.go#L245)
· [Default pattern copy](../../internal/engine/import_spec.go#L122)
For **D** directory declarations that inherit **P** patterns, this adds
Θ(D × P) string-entry copies in time and peak temporary storage for a
single input. It becomes quadratic when both counts grow together. The
pattern text itself is shared. The work is separate from validating the
default patterns once and from matching filenames on the bound path.
Keep the load-owned default pattern snapshot and borrow its slice read-only
when resolving an inherited pattern. The selectors already read these
entries without modifying them. This reduces pattern storage and copying
to Θ(D + P) for the policy headers and shared entries. A separate option
is to share the context-independent validation and have the no-base path
retain only the policy fields it actually uses. Either approach should
preserve explicit empty pattern overrides, validation of skipped
declarations, and existing diagnostic sites.
[Default snapshot](../../internal/engine/import_spec.go#L72)
· [Filename filtering](../../internal/engine/import_selection.go#L230)
## Finding 7 — Each derived companion keeps a copy of the same tier context
**Priority P3.** `acquireUnderlayGroupScopes` allocates a context pointer
slot for every input, even in tiers with no bindings. Each derived input
then gets an addressable copy of the same main context with the same
cleared main path and receiving-tier host token. The separate copies
carry no input-specific values.
[Context preparation](../../internal/engine/load_request.go#L276)
For a tier with **U** inputs and **C** derived bindings, this adds Θ(U)
temporary pointer slots and Θ(C) context values. The passes themselves
are linear. Build at most one read-only derived context per tier and
select it during the existing ordered anchor and acquisition passes.
Use the private input's selected concrete context for fallbacks. This
reduces the extra context bookkeeping to O(1), excluding the existing
input list and native namespace map. Preserve per-input validation and
handle ownership, as well as first-input namespace anchors. Share the
context description without caching filesystem observations.
Complexity was derived from the loops and copies above. Focused Go 1.27.3
tests passed for the companion workflow, layered loading, overlays,
import policy and selection, and sequence-item placement.