Consolidate repository audit findings for review
This commit is contained in:
926
docs/roadmap/audit.md
Normal file
926
docs/roadmap/audit.md
Normal file
@@ -0,0 +1,926 @@
|
||||
# Consolidated Audit Review
|
||||
|
||||
Status: review pending; implementation scope has not been selected.
|
||||
Consolidated: 2026-10-25. Baseline: `ecd5d5d`.
|
||||
|
||||
This document consolidates nine sequential audits for maintainer review. It owns
|
||||
their open findings, supporting evidence, proposed remedies, and relationships.
|
||||
It is not an implementation plan, an acceptance of every recommendation, or a
|
||||
new set of release gates. The [configuration contract](../config.md), public Go
|
||||
declarations, and [architecture policy](../policy/architecture.md) continue to
|
||||
own behavior and guarantees.
|
||||
|
||||
There are nine distinct reported defects: four from correctness, three from
|
||||
resources, one from error handling, and one from security. Concurrency adds
|
||||
evidence for an existing callback-lifetime defect. Other entries are cleanup,
|
||||
efficiency, maintainability, or test improvements. Regression recommendations
|
||||
are attached to the defects they protect rather than counted as additional
|
||||
product fixes.
|
||||
|
||||
The 35 original numbered findings map to 31 review entries after deduplication
|
||||
and integration of related test work. All entries remain open and unselected.
|
||||
Their medium/low priorities retain the original assessments; those labels do not
|
||||
imply severity certification or implementation order. IDs remain stable as work
|
||||
is selected or completed.
|
||||
|
||||
## Evidence And Provenance
|
||||
|
||||
All nine audits were dated 2026-10-25. Their sequential commits changed only the
|
||||
audit documents, so their production baseline is the same. This consolidation
|
||||
does not independently reproduce the findings or claim new runtime evidence.
|
||||
|
||||
| Original report | Reviewed revision | Evidence contributed |
|
||||
| --- | --- | --- |
|
||||
| `correctness.md` | `47944d2` | Source review and standalone public-API reproductions of four defects. |
|
||||
| `efficiency.md` | `5098b56` | Source-derived scaling cases and proposed algorithm changes; no benchmarks. |
|
||||
| `complexity.md` | `320d0c5` | Responsibility/caller review, graph complexity estimates, and maintainability candidates. |
|
||||
| `concurrency.md` | `a802734` | Ownership review, race checks, and corroboration of callback lifetime after panic. |
|
||||
| `resources.md` | `0cca633` | Bounded allocation, retained-node, and host-handle diagnostics. |
|
||||
| `error-handling.md` | `5925066` | Directory read/close fault injection through the public API. |
|
||||
| `security.md` | `b30c9f1` | Trust-boundary review, bounded symlink operation counts, and a historical dependency spot-check. |
|
||||
| `testing.md` | `eb5a82f` | Aggregate statement coverage, assertion review, and regression/test-cleanup recommendations. |
|
||||
| `deadcode.md` | `b1c278b` | Type-aware reference inventory, graph/caller checks, and source review of private cleanup candidates. |
|
||||
|
||||
The full original reports, including exact probes, commands, source line
|
||||
references, and validation limitations, are preserved at `ecd5d5d`. For example:
|
||||
|
||||
```sh
|
||||
git show ecd5d5d:docs/roadmap/correctness.md
|
||||
git show ecd5d5d:docs/roadmap/security.md
|
||||
```
|
||||
|
||||
The [original-finding map](#original-finding-map) accounts for every numbered
|
||||
finding, including duplicates and test recommendations integrated elsewhere.
|
||||
Source links below identify implementation owners; historical line numbers are
|
||||
left in the originals because later edits will move them.
|
||||
|
||||
### Recorded Validation And Its Limits
|
||||
|
||||
The audits report successful development checks, ordinary tests, full race tests,
|
||||
`go vet`, and focused suites as specified in their individual records, using
|
||||
Go 1.26.10 on Linux amd64. Concurrency additionally repeated six relevant engine
|
||||
tests with race instrumentation, count 20, and CPUs 1, 4, and 8. Testing ran the
|
||||
suite with shuffle enabled three times. These results did not detect the newly
|
||||
reported defects and are not evidence that those defects have been fixed.
|
||||
|
||||
Testing recorded 771 ordinary test functions, three fuzz targets, and 29 executable
|
||||
examples. Aggregate cross-package coverage was 90.3%: root 81.3%, engine 91.0%,
|
||||
document 100%, YAML 89.9%, and maintained consumers 79.2%. Those figures locate
|
||||
gaps; they are not targets or a measure of assertion strength. Only checked-in
|
||||
fuzz seeds ran, not an extended campaign or mutation analysis.
|
||||
|
||||
Standalone diagnostics stayed outside the repository. Some potentially fatal
|
||||
cases used disposable processes, small limits, or operation ceilings; larger
|
||||
scaling examples were derived rather than executed. The dead-code inventory
|
||||
considered Linux, Darwin, and Windows build configurations, but no audit reports
|
||||
native macOS or Windows execution. Graph scores and reachability results were
|
||||
triage aids, not proof that a function is unnecessary or a numerical refactoring
|
||||
threshold. Cached analysis tooling was used outside the repository; no new
|
||||
project tools or dependencies were introduced.
|
||||
|
||||
The security report's module-path advisory spot-check and successful module
|
||||
integrity verification are historical evidence only. It recorded no listed
|
||||
advisories for the selected YAML v4, ReleaseKit, or Goldmark v2 module paths, and
|
||||
recorded the selected `x/mod` version as fixed for the two reports it found. It
|
||||
did not perform complete toolchain/transitive reachability analysis or supply-
|
||||
chain attestation; dedicated vulnerability, security, and secret scanners were
|
||||
unavailable. This consolidation neither refreshes nor broadens that conclusion.
|
||||
|
||||
## Review Priorities And Dependencies
|
||||
|
||||
Recommended review order is reported defects with their regression coverage,
|
||||
bounded cleanup, targeted efficiency changes, and then broader structural
|
||||
refactoring. Small prerequisite cleanups can accompany a defect fix. The order
|
||||
of the groups below is for navigation, not an execution sequence.
|
||||
|
||||
| Relationship | Consequence for scope selection |
|
||||
| --- | --- |
|
||||
| A02 and A05 | Make descriptor construction safe before reusing successful dynamic-type eligibility results. |
|
||||
| B01 and B02 | Panic cleanup must close callback state and the owned host root independently. Neither fix substitutes for the other. |
|
||||
| C01 and its filesystem tests | Strengthen error/handle assertions while adding failure-phase regressions, using one shared test owner. |
|
||||
| C02 and C03 | Link expansion correctness is independent of optional glob readability extraction. Do not make the latter a prerequisite. |
|
||||
| D01, D02, and D03 | Remove confirmed unused copies where selected, then account for the complete retained graph. Removing one unused tree does not fix the remaining omissions. |
|
||||
| E01, E02, and E03 | Consider policy-state costs and responsibility boundaries together, but preserve separate scaling and behavioral acceptance cases. |
|
||||
| F01 and F02 | Removing the test-only acquisition mode does not by itself simplify active lifecycle handoffs. |
|
||||
| F04, F09, and F12 | Replace useful facade ownership/query coverage before deleting disconnected or representation-coupled scaffolding. |
|
||||
| F05 and F07 | Removing unused placement bridges is a bounded cleanup independent of the wider transport refactor. |
|
||||
|
||||
## A. Schema And Typed Values
|
||||
|
||||
### A01. Terminate Pointer-Only Recursive Descriptor Traversal
|
||||
|
||||
Type: reported defect. Priority: medium. Source: correctness 1; testing 1.
|
||||
|
||||
**Problem and evidence.** In [schema.go](../../internal/engine/schema.go), a legal
|
||||
type such as `type Loop *Loop` produces a pointer descriptor whose element is
|
||||
itself. [decode.go](../../internal/engine/decode.go) unwraps that descriptor
|
||||
without consuming a non-null input node; `resolveSchemaPath` likewise assumes
|
||||
pointer traversal eventually reaches another kind. A public load with a `Loop`
|
||||
field and `value: {}` overflowed the stack in a process with a small stack limit.
|
||||
`value: null` succeeded, but resolving a normalization path for that field hung
|
||||
until the diagnostic process was stopped. The [schema
|
||||
contract](../config.md#application-schema-binding) permits recursive types with
|
||||
acyclic values; the inline-field restriction is not a blanket pointer restriction.
|
||||
|
||||
**Recommendation and acceptance.** Detect repeated descriptors while unwrapping
|
||||
pointer-only chains in decoding and schema-path resolution, and review analogous
|
||||
helpers. Incompatible non-null input must fail safely; path traversal must
|
||||
terminate and reject unaddressable descendants. Preserve supported nil/null
|
||||
values and ordinary recursive structs. Do not add a blanket schema rejection or
|
||||
arbitrary depth cap. Add bounded regression coverage for both decoding and helper
|
||||
path resolution, keeping fatal/hanging probes out of the default test process.
|
||||
|
||||
### A02. Make Failed Dynamic Descriptor Construction Transactional
|
||||
|
||||
Type: reported defect. Priority: medium. Source: correctness 2; testing 1.
|
||||
|
||||
**Problem and evidence.** `dynamicDescriptor` in
|
||||
[value_operation.go](../../internal/engine/value_operation.go) passes the load's
|
||||
descriptor cache to `schemaBuilder`. Failed construction leaves cached container
|
||||
placeholders. For a dynamic struct containing an unsupported channel field, two
|
||||
`Normalize` calls in one resolver, first with a typed nil pointer and then a
|
||||
non-nil pointer to that type, reproduced a nil-pointer panic on the second call.
|
||||
The first call reported a diagnostic but left a reusable partial descriptor.
|
||||
The application callback itself did not panic.
|
||||
|
||||
**Recommendation and acceptance.** Stage new descriptors and commit only on
|
||||
successful construction, or roll back all additions from a failed build. Include
|
||||
recursive references among newly built descriptors; clearing only the immediate
|
||||
failed container or adding a projection nil guard is insufficient. Preserve
|
||||
previously valid descriptors, load-local ownership, and safe path-specific
|
||||
diagnostics under [typed projection](../config.md#typed-projection-and-ownership)
|
||||
and [resolution](../config.md#recorded-application-resolution). Test repeated
|
||||
operations after a failed build in the same load. Coordinate A05 only after this
|
||||
failure-state boundary is sound.
|
||||
|
||||
### A03. Distinguish Acyclic Slice Views In Cycle Detection
|
||||
|
||||
Type: reported defect. Priority: medium. Source: correctness 3; testing 1.
|
||||
|
||||
**Problem and evidence.** `valueVisit` / `visitFor` in
|
||||
[value_operation.go](../../internal/engine/value_operation.go) identify slices by
|
||||
type, kind, and starting pointer, omitting length. The finite value built by
|
||||
`shared := []any{"leaf", nil}; shared[1] = shared[:1]` was rejected through mapping
|
||||
sources, typed defaults, and CLI overrides, while an equivalent independently
|
||||
allocated value succeeded. The nested view contains only the leaf, not its
|
||||
enclosing view. The same helper serves projection/cloning and
|
||||
[value.go](../../internal/engine/value.go).
|
||||
|
||||
**Recommendation and acceptance.** Include visible slice length in active-visit
|
||||
identity, or use an equivalent distinction. Preserve rejection of actual self
|
||||
and mutual cycles, nil/empty behavior, and detached output; preserving alias
|
||||
identity is not required. Regressions should cover the shared source, override,
|
||||
projection, and cloning paths under the existing supported-acyclic-value contract,
|
||||
alongside true-cycle rejection.
|
||||
|
||||
### A04. Enforce Existing Node Budgets Before Container Reservations
|
||||
|
||||
Type: reported defect. Priority: medium. Source: resources 1; testing 1.
|
||||
|
||||
**Problem and evidence.** `projectSequence` and `projectMap` in
|
||||
[projection.go](../../internal/engine/projection.go) reserve space for the full
|
||||
container, and maps collect all keys, before child charging in
|
||||
[value_operation.go](../../internal/engine/value_operation.go). Defaults containing
|
||||
a maximum-length slice of zero-sized structs caused a `makeslice: cap out of range`
|
||||
panic instead of `schema.projection_limit`; that diagnostic did not allocate a
|
||||
huge input backing array. Less extreme cases can allocate excessive temporary
|
||||
memory before rejection. Application resolution can reach these paths too.
|
||||
|
||||
**Recommendation and acceptance.** Check the known minimum node cost against the
|
||||
remaining existing allowance with overflow-safe arithmetic, or bound initial
|
||||
capacity and grow as charging succeeds. Review map reservation/key collection as
|
||||
well as sequences. Preserve node/depth semantics, inline handling, and useful
|
||||
diagnostic paths. Use bounded regressions, including small controlled allowances,
|
||||
without enormous allocations. This enforces an existing budget, not a new length
|
||||
cap or universal heap-size guarantee.
|
||||
|
||||
### A05. Reuse Successful Dynamic-Type Eligibility Checks Locally
|
||||
|
||||
Type: optimization candidate. Priority: low. Source: efficiency 6.
|
||||
|
||||
**Problem and evidence.** Each dynamic value in projection/cloning invokes
|
||||
`descriptorContainsSecret` with a new visited map, even when its descriptor is
|
||||
cached. N values of one concrete type with descriptor-graph size S therefore cost
|
||||
O(N × S) eligibility work. N interface values containing nil pointers to one wide
|
||||
supported struct can produce only N null values while repeating the full type
|
||||
walk. This is a source-derived bound, not measured runtime.
|
||||
|
||||
**Recommendation and acceptance.** After A02, consider remembering successfully
|
||||
approved concrete descriptors within `valueOperation`, reducing repeated-type
|
||||
eligibility work to O(S + N). Cache only completed successful eligibility checks,
|
||||
not traversal-local visits, partial descriptors, or path-bearing failures.
|
||||
Preserve rejection of dynamic secret-reference types, including nil pointers and
|
||||
recursive descriptor cases. This does not select cross-load schema caching or a
|
||||
clone traversal redesign.
|
||||
|
||||
## B. Callback And Filesystem Lifetime
|
||||
|
||||
### B01. Deactivate Callback Contexts During Panic Unwinding
|
||||
|
||||
Type: reported defect. Priority: low. Sources: correctness 4, concurrency 1;
|
||||
testing 1; corroborated by error-handling and security reviews.
|
||||
|
||||
**Problem and evidence.** `runResolution` in
|
||||
[resolution.go](../../internal/engine/resolution.go) and `runValidation` /
|
||||
`reportVersion` in [validation.go](../../internal/engine/validation.go) deactivate
|
||||
contexts only after normal callback return. Public probes retained the context,
|
||||
panicked, recovered outside `Load`, and then successfully queried resolution or
|
||||
wrote validation/version diagnostics. The concurrency audit reproduced this
|
||||
with race instrumentation without reporting a data race. The defect violates
|
||||
callback lifetime, not a newly supported concurrent-use scenario.
|
||||
|
||||
**Recommendation and acceptance.** Defer deactivation within each callback
|
||||
invocation, closing immediately at normal return and on unwinding, before later
|
||||
projection or metadata work. Preserve the original panic and prohibit retained
|
||||
context use through the established closed-context behavior. Test all three
|
||||
callback kinds with external recovery. No recovery service, lock, atomic flag,
|
||||
or broader callback thread-safety guarantee is needed. B02 separately owns root
|
||||
handle cleanup.
|
||||
|
||||
### B02. Close The Owned Import Root When A Version Callback Panics
|
||||
|
||||
Type: reported defect. Priority: medium. Source: resources 3; testing 1.
|
||||
|
||||
**Problem and evidence.** Host import acquisition in
|
||||
[import_acquisition.go](../../internal/engine/import_acquisition.go) opens an
|
||||
`os.Root` through [filesystem_access.go](../../internal/engine/filesystem_access.go)
|
||||
but relies on explicit ordinary-path closes. An imported version-check panic
|
||||
bypasses them. A disposable Linux probe disabled GC, recovered outside `Load`,
|
||||
and observed one remaining root descriptor through `/proc/self/fd`; the normal
|
||||
control returned to zero. The imported file's own deferred close still ran.
|
||||
|
||||
**Recommendation and acceptance.** Install deferred fallback cleanup at the
|
||||
owning boundary, preserving explicit normal close timing and diagnostics, as
|
||||
selected-overlay acquisition already does. Avoid double-close confusion, leave
|
||||
borrowed filesystems untouched, and propagate the original panic. A regression
|
||||
must observe the owned host root, not merely a native file-close counter, and
|
||||
document platform prerequisites. Context deactivation in B01 is a separate
|
||||
requirement. This restores load-scope cleanup without adding panic recovery.
|
||||
|
||||
## C. Import Selection And Link Resolution
|
||||
|
||||
### C01. Preserve Directory Failure Phase And Strengthen Its Tests
|
||||
|
||||
Type: reported defect with test improvements. Priority: medium.
|
||||
Sources: error-handling 1, testing 3.
|
||||
|
||||
**Problem and evidence.** `filesystemAccess.readDirectory` in
|
||||
[filesystem_access.go](../../internal/engine/filesystem_access.go) returns open,
|
||||
read, and close errors through one unqualified error channel.
|
||||
[import_selection.go](../../internal/engine/import_selection.go) and
|
||||
[glob.go](../../internal/engine/glob.go) treat any `fs.ErrNotExist` as absence.
|
||||
A borrowed filesystem probe selected a failing directory plus a good directory,
|
||||
using both `dir` and `glob` with `required: true`. Injecting `fs.ErrNotExist`
|
||||
alongside entries from `ReadDir`, or from `Close`, let loads succeed with the bad
|
||||
directory's contribution omitted. Permission-classified controls failed. All
|
||||
eight selector/phase/error cases ran. This violates the existing distinction
|
||||
between optional absence and failed acquisition.
|
||||
|
||||
**Recommendation and acceptance.** Preserve missing-on-open versus post-open
|
||||
failure, for example with a small private failure record analogous to regular
|
||||
file acquisition. Keep genuine missing-target rules, entry budgets, first-error
|
||||
precedence, borrowed filesystem ownership, and safe existing traversal diagnostics.
|
||||
Review both batched `fs.ReadDirFile` and standard fallback paths. A successful
|
||||
second directory must not hide enumeration/close failure; raw backing error text
|
||||
must not leak. No retries or filesystem transaction are proposed.
|
||||
|
||||
**Test improvements.** The shared fixture in
|
||||
[native_filesystem_test.go](../../internal/engine/native_filesystem_test.go) and
|
||||
[resource_context_test.go](../../internal/engine/resource_context_test.go) currently
|
||||
checks aggregate closes and often only non-nil errors. One leaked handle and
|
||||
one double-close can cancel out. Its canary check examines the terse error
|
||||
summary, not structured diagnostics. Track per-handle closure, assert nil result,
|
||||
diagnostic code and source, and inspect diagnostic messages/rendering for canaries.
|
||||
Add entries/data-plus-error and close-phase cases through narrow failure seams.
|
||||
Preserve intentionally ignored read-only regular-file close errors; this does
|
||||
not impose a universal close-error policy.
|
||||
|
||||
### C02. Avoid Reexpanding Completed Finite Symlink Dependencies
|
||||
|
||||
Type: reported availability defect. Priority: medium. Source: security 1;
|
||||
testing 1.
|
||||
|
||||
**Problem and evidence.** Host/native resolvers in
|
||||
[filesystem_links.go](../../internal/engine/filesystem_links.go) track active links
|
||||
but reuse no completed resolution. A finite contained graph `s00 -> .`,
|
||||
`s01 -> s00/s00`, `s02 -> s01/s01`, and so on repeats completed dependencies.
|
||||
Its work follows T(N) = 2T(N-1) + O(1), despite linear graph size. Directory
|
||||
selection resolves discovered links before deciding on recursive descent, so
|
||||
`recursive: false` does not avoid it. Existing source/entry/node/import-depth
|
||||
budgets do not account for the repeated expansion.
|
||||
|
||||
A real-link fixture exposed through a native `fs.ReadLinkFS` wrapper recorded
|
||||
32, 128, 512, 2,048, and 8,192 `Lstat` calls for 3, 5, 7, 9, and 11 entries;
|
||||
corresponding `ReadLink` counts were 11, 57, 247, 1,013, and 4,083. Thirteen
|
||||
entries reached a diagnostic ceiling of 12,000 `Lstat` calls. With following
|
||||
disabled, that fixture used 17 `Lstat` calls and no `ReadLink`. The host resolver's
|
||||
matching logic was reviewed, not separately operation-count tested.
|
||||
|
||||
**Recommendation and acceptance.** Reuse fully resolved targets within the
|
||||
resolution operation, keyed for the rooted namespace and full link path, or use
|
||||
equivalent dependency evaluation. Retain active-path cycle detection, containment,
|
||||
finite reuse, relative/absolute host semantics, and the stable-input assumption.
|
||||
A global visited-means-cycle rule would incorrectly reject valid inputs. Cover
|
||||
both resolvers and directory/glob entry points with small fixtures and bounded
|
||||
operation observation, not timing thresholds or exhaustion tests. No arbitrary
|
||||
link cap, public cache, or default-follow change is selected.
|
||||
|
||||
The availability risk requires influence over imported filesystem data; it is
|
||||
not an anonymous remote vulnerability by itself. No concurrent mutation or
|
||||
outside-root target is needed, and accidental graphs can cause the same work.
|
||||
|
||||
### C03. Separate Glob Entry Preparation From Traversal
|
||||
|
||||
Type: optional refactor. Priority: medium. Source: complexity 4.
|
||||
|
||||
**Problem and evidence.** The patterned branch of `selectGlobImportCandidates`
|
||||
in [glob.go](../../internal/engine/glob.go) interleaves component traversal and
|
||||
union/sorting with hidden/match rules, lexical/access paths, containment, links,
|
||||
directory eligibility, namespace differences, labels, and candidate construction.
|
||||
Directory selection already has a named entry-preparation operation.
|
||||
|
||||
**Recommendation and acceptance.** Consider a glob-specific preparation helper
|
||||
returning an admitted candidate, ordinary skip, or diagnostic. Keep literal
|
||||
segments, component advancement, union/sorting, exclusions, and requiredness in
|
||||
the selector. Preserve inspection/error order, budgets, native spelling, and
|
||||
selected-file validation. Share low-level facts only where semantics agree;
|
||||
no general visitor framework, discovery-algorithm change, or caching is implied.
|
||||
C01/C02 can be fixed independently of this readability change.
|
||||
|
||||
## D. Retained History And Unused Evidence
|
||||
|
||||
### D01. Account For The Complete Published History Graph
|
||||
|
||||
Type: reported defect. Priority: medium. Source: resources 2; testing 1.
|
||||
|
||||
**Problem and evidence.** The checkpoint in [load.go](../../internal/engine/load.go)
|
||||
and [history.go](../../internal/engine/history.go) counts a different root set
|
||||
from [load_result.go](../../internal/engine/load_result.go) publication. Separately
|
||||
cloned post-CLI input, `structuralInput`, `preCLI`, and later inheritance copies
|
||||
are not all represented. A read-only diagnostic of a small successful load with
|
||||
a no-op resolver counted 14 distinct nodes before including the two published
|
||||
replay roots and 22 with them. Source inspection found that the checkpoint uses
|
||||
a different, same-sized decoded-final instance and also counts 14 in this case.
|
||||
Generalized to N scalar items, the reported counts were 3N + 8 versus 5N + 12;
|
||||
800,000 items would pass the checkpoint yet exceed the existing 4,000,000-node
|
||||
history allowance. That large case was derived, not allocated or executed.
|
||||
|
||||
**Recommendation and acceptance.** Use pointer-aware accounting for every document
|
||||
root actually retained at publication, including replay and copied inheritance
|
||||
history, counting shared nodes once. Where practical, reserve/charge copies before
|
||||
allocation. Coordinate removal of unused trees under D03 and recalculate the
|
||||
retained set afterward; that removal alone does not establish complete accounting.
|
||||
Reuse already-owned immutable snapshots only where equivalence and ownership
|
||||
are demonstrated. This need not redesign public metadata copying.
|
||||
|
||||
Use a small controlled allowance to test publication integration and the existing
|
||||
`explain.limit_exceeded` outcome, as well as count-once sharing. Helper-only tests
|
||||
cannot detect roots omitted by callers. Preserve [historical
|
||||
inspection](../config.md#historical-value-explanation), detached ownership, and
|
||||
the existing quota; no smaller limit or universal heap-size bound is proposed.
|
||||
|
||||
### D02. Remove The Unconsumed Override-Result Pre-CLI Copy
|
||||
|
||||
Type: cleanup. Priority: medium. Source: deadcode 1.
|
||||
|
||||
**Problem and evidence.** `decodedOverrideResult.preCLI` in
|
||||
[override_decode.go](../../internal/engine/override_decode.go) clones the entire
|
||||
decoded final tree even without CLI assignments. Its readers are private tests;
|
||||
production independently clones `before.final` into the active context in
|
||||
[override_context.go](../../internal/engine/override_context.go).
|
||||
|
||||
**Recommendation and acceptance.** Remove that result member, its clone, and
|
||||
assertions solely about it. Preserve the independently owned pre-CLI context
|
||||
that actually feeds resolution, publication, and explanation. Retain behavioral
|
||||
CLI/history/ownership coverage. The change removes a redundant traversal, not
|
||||
the active replay snapshot or its detachment boundary.
|
||||
|
||||
### D03. Remove The Unqueried Published Structural-Input Copy
|
||||
|
||||
Type: cleanup. Priority: medium. Source: deadcode 2.
|
||||
|
||||
**Problem and evidence.** `Inspection.structuralInput` in
|
||||
[load.go](../../internal/engine/load.go) is cloned and indexed at publication,
|
||||
but has no production reader. [explain.go](../../internal/engine/explain.go)
|
||||
uses source/inheritance replay, `preCLI`, and `input`. The immutable lookup is
|
||||
addressed by supplied node pointers; indexing this otherwise unused root does
|
||||
not make it useful and keeps its mappings alive.
|
||||
|
||||
**Recommendation and acceptance.** Remove the inspection member, final clone,
|
||||
and its `retainedTrees` inclusion. Keep earlier `resolved.structuralInput` uses
|
||||
for path finalization and sensitivity. Check explanation, historical paths,
|
||||
redaction, and ownership through active outputs. Coordinate D01 for all remaining
|
||||
retained roots; do not infer that structural evidence is globally unused.
|
||||
|
||||
### D04. Stop Constructing Unconsumed Combination Evidence
|
||||
|
||||
Type: cleanup. Priority: medium. Source: deadcode 5.
|
||||
|
||||
**Problem and evidence.** `sequenceCombinationResult.discardedLower` in
|
||||
[sequence_combine.go](../../internal/engine/sequence_combine.go) allocates a list
|
||||
of all replaced lower indexes with no production reader. Three tests inspect it.
|
||||
`inheritanceReplacement.path`, `previous`, and `effective` in
|
||||
[inheritance.go](../../internal/engine/inheritance.go) are also unread, but their
|
||||
writers perform path/origin copies and displaced-subtree walks. Active inheritance
|
||||
history uses operations and projected changes elsewhere. Replacement `before`
|
||||
and `after` trees still feed node accounting.
|
||||
|
||||
**Recommendation and acceptance.** Remove only unread members and work solely
|
||||
feeding them. Keep replacement trees, item projections, replacement mappings,
|
||||
`appendedHigher`, active provenance/history, and node accounting. Keep
|
||||
`sequenceIndexes` for append and `displacedOrigins` for overlay callers. Replace
|
||||
private unused-evidence assertions with existing behavior-level replacement,
|
||||
removed-descendant, and history protection where necessary. Coordinate D01 and
|
||||
E03 without deleting active evidence merely because another representation exists.
|
||||
|
||||
## E. Collection Processing And Efficiency
|
||||
|
||||
All complexity estimates here describe identified internal work with bounded-
|
||||
depth examples and expected hash lookup costs. Actual path processing, copied
|
||||
payload, and expanded output remain costs; no end-to-end complexity or timing
|
||||
guarantee is proposed.
|
||||
|
||||
### E01. Avoid Scanning Every Policy For Each Replacement
|
||||
|
||||
Type: optimization candidate. Priority: medium. Source: efficiency 1.
|
||||
|
||||
**Problem and evidence.** `retireCollectionPoliciesAtOrBelow` in
|
||||
[collection_policy_state.go](../../internal/engine/collection_policy_state.go)
|
||||
scans all P policies for each of Q ordinary replacements in
|
||||
[overlay.go](../../internal/engine/overlay.go), even if the changed scalars are
|
||||
unrelated to every collection. P = Q = N gives O(N²) visits for linear-sized
|
||||
input and output within one tier.
|
||||
|
||||
**Recommendation and acceptance.** Consider an operation-local semantic-path
|
||||
index with descendant queries, maintained as policies change, or batch retirement
|
||||
where timing remains equivalent. The disjoint case can approach O(P + Q), with
|
||||
additional work charged to affected entries/path lengths. Preserve explicit-mode
|
||||
persistence, record ownership, and the moment old identity retires; delayed
|
||||
retirement must not clear newly established higher-tier policy. Evaluate existing
|
||||
inheritance indexing without requiring identical interfaces. Retain a distinct
|
||||
disjoint-replacement case even if implementation is coordinated with E02/E03.
|
||||
|
||||
### E02. Avoid Recopying Unrelated Policy Across Small Tiers
|
||||
|
||||
Type: optimization candidate. Priority: medium. Source: efficiency 2.
|
||||
|
||||
**Problem and evidence.** `lowerCollectionPoliciesForClaims` in
|
||||
[collection_retirement.go](../../internal/engine/collection_retirement.go) clones
|
||||
and scans lower policy, and `resolveStrictCollectionPolicies` in
|
||||
[compose.go](../../internal/engine/compose.go) clones it again. Overlay preparation
|
||||
repeats full-state work and checks retained destinations. P initial policies
|
||||
followed by T scalar-only tiers cost O(T × P) work/allocation although only O(P + T)
|
||||
material exists. Copies include record order and nested record policy; these
|
||||
are transient private copies, not independently published snapshots.
|
||||
|
||||
**Recommendation and acceptance.** Separate read-only lower-policy lookup from
|
||||
owned current-tier changes, localize work to incoming claims/declarations, and
|
||||
apply changes to the assembly owner. Keep copies at actual mutable ownership
|
||||
boundaries. Removing the immediate duplicate copy helps but does not alone fix
|
||||
O(T × P) growth. Preserve pending declarations, replacement eligibility, and
|
||||
independent nested record policies. This case remains distinct from E01 and the
|
||||
deferred public metadata-copy experiment.
|
||||
|
||||
### E03. Clarify Policy Preparation And Merge Evidence Application
|
||||
|
||||
Type: optional refactor. Priority: medium. Source: complexity 3.
|
||||
|
||||
**Problem and evidence.** [overlay.go](../../internal/engine/overlay.go) combines
|
||||
claim/declaration preparation, operation resolution, callbacks, diagnostics,
|
||||
origins/history, retirement, record policy rebuilding, and declaration-only
|
||||
finalization. Overlay and [inheritance](../../internal/engine/inheritance_collection.go)
|
||||
separately translate sequence results into history descriptors and reconstruct
|
||||
record order. `combineSequence` already owns shared value combination.
|
||||
|
||||
**Recommendation and acceptance.** Consider explicit preparation, application,
|
||||
and finalization operations with a small result/owner for evidence and diagnostics.
|
||||
Share straightforward history-descriptor construction; assess projected-record
|
||||
selection sharing while keeping precedence and inheritance policy ownership
|
||||
explicit. Do not unify distinct origin or mode-lifetime rules behind a generic
|
||||
strategy framework. Coordinate E01/E02 so extraction does not preserve avoidable
|
||||
full-table work. Preserve pending declarations, replacement ordering, retained
|
||||
versus incoming record owners, and stable history. D04 can remove unused evidence
|
||||
without requiring this broader refactor.
|
||||
|
||||
### E04. Index Tier-History Projection Lookups
|
||||
|
||||
Type: optimization candidate. Priority: medium. Source: efficiency 3.
|
||||
|
||||
**Problem and evidence.** `projectTierHistoryApplications` in
|
||||
[sequence_history_projection.go](../../internal/engine/sequence_history_projection.go)
|
||||
calls unindexed `documentAtPath` for each mapped sequence. N sibling collections
|
||||
selected by one wildcard identity registration incur O(N²) mapping comparisons
|
||||
while projecting linear-sized source/history material.
|
||||
|
||||
**Recommendation and acceptance.** Lazily prepare one read-only `documentLookup`
|
||||
per original application value with mapped contributions, or collect needed nodes
|
||||
in one traversal. With V nodes, S contributions, depth D, and I projected items,
|
||||
that portion can be O(V + S × D + I). Preserve authored coordinates, sparse item
|
||||
projections, replacement evidence, and independent output storage. This is load-
|
||||
time coordinate projection, not branch-local explanation replay.
|
||||
|
||||
### E05. Restore Compound Identity Without Repeated Mapping Scans
|
||||
|
||||
Type: optimization candidate. Priority: medium. Source: efficiency 4.
|
||||
|
||||
**Problem and evidence.** `preserveInheritanceIdentityFields` in
|
||||
[inheritance_scope.go](../../internal/engine/inheritance_scope.go) searches child
|
||||
and merged mappings for each identity field. K fields and C/M child/merged
|
||||
entries cost O(K × (C + M)) comparisons plus required clones. A wide compound
|
||||
identity can make this quadratic without expanding record output.
|
||||
|
||||
**Recommendation and acceptance.** Index merged positions and walk child entries
|
||||
against an identity-field set, or use equivalent local mapping indexes, for
|
||||
O(K + C + M) lookup work plus copies. Preserve child-owned identity values and
|
||||
locations, mapping order, and detached nodes. Do not change identity equality or
|
||||
parent selection. Removing the restoration step instead requires a separate
|
||||
equivalence review; apparent duplication alone is insufficient.
|
||||
|
||||
## F. Remaining Maintenance And Test Improvements
|
||||
|
||||
### F01. Remove The Test-Only Eager Acquisition Mode
|
||||
|
||||
Type: cleanup. Priority: medium. Sources: complexity 1, deadcode 8.
|
||||
|
||||
**Problem and evidence.** Both production constructors of the request declared in
|
||||
[acquisition.go](../../internal/engine/acquisition.go) set
|
||||
`inputAcquisitionRequest.deferAssembly` to true. Only private
|
||||
test helpers select the eager composition branch in
|
||||
[import_acquisition.go](../../internal/engine/import_acquisition.go). Acquisition
|
||||
maintains two return protocols and tests can bypass the production phase handoff.
|
||||
|
||||
**Recommendation and acceptance.** Return retained scopes consistently and remove
|
||||
the unused production mode. Tests needing composition should invoke the active
|
||||
composition phase through a small test-only helper; acquisition-only tests should
|
||||
remain acquisition-only. Preserve closure, pending-item reservation, accounting,
|
||||
diagnostics, and meaningful composition coverage. This does not retire public
|
||||
loading workflows or imply that every nil-state/directive context is unused.
|
||||
|
||||
### F02. Clarify Active Acquisition And Coordinator Handoffs
|
||||
|
||||
Type: optional refactor. Priority: medium. Source: complexity 2.
|
||||
|
||||
**Problem and evidence.** `acquireInput` in
|
||||
[acquisition.go](../../internal/engine/acquisition.go) combines discovery, parsing,
|
||||
directive/version branches, placement/accounting, dispatch, and passive contexts.
|
||||
Version branches repeat source-ID/failure/result handling, and layered processing
|
||||
extracts and restores directives. [load.go](../../internal/engine/load.go) contains
|
||||
a substantial ordinary-load context fallback; [load_request.go](../../internal/engine/load_request.go)
|
||||
repeats tier declaration/application/projection handoffs. Parsed, local, composed,
|
||||
inherited, and version-path representations are difficult to follow together.
|
||||
|
||||
**Recommendation and acceptance.** Consider cohesive parsed-input directive/version
|
||||
processing and standalone placement/registration operations, plus explicit context,
|
||||
structural-expansion, and repeated tier handoffs. Reuse existing state/results;
|
||||
helpers that merely share the same mutable surrounding locals do not resolve
|
||||
ownership. Preserve visible phase order, ordinary/layered overlay differences,
|
||||
default/enabled version timing, warnings, exactly-once callbacks, and load-wide
|
||||
versus tier-local state. F01 removes a different, inactive protocol; neither task
|
||||
requires a new context hierarchy or public request model.
|
||||
|
||||
### F03. Retire The Parallel Test-Only Import Directive Parser
|
||||
|
||||
Type: cleanup. Priority: low. Source: deadcode 7.
|
||||
|
||||
**Problem and evidence.** `parseImportSpecificationDirective` in
|
||||
[import_spec.go](../../internal/engine/import_spec.go) is called only by the
|
||||
`parseImportSpecsYAML` test fixture. It duplicates mapping/field dispatch already
|
||||
owned by `parseRootDirectiveBlock` in [directives.go](../../internal/engine/directives.go).
|
||||
|
||||
**Recommendation and acceptance.** Use the active parser with the appropriate
|
||||
context, or parse the declaration list directly when that is the tested boundary,
|
||||
then remove the obsolete implementation. Preserve malformed-declaration and
|
||||
selector coverage. Keep the active imports-only context used in layered version
|
||||
processing; thin test helpers delegating to production are not inherently dead.
|
||||
|
||||
### F04. Remove The Disconnected Root Record-Clone Family
|
||||
|
||||
Type: cleanup. Priority: low. Source: deadcode 3; related testing 6.
|
||||
|
||||
**Problem and evidence.** The private family in root [records.go](../../records.go)
|
||||
has no production facade entry: `cloneLocation`, `cloneLocations`, `cloneSourceInfo`,
|
||||
`cloneImportSelections`, `cloneSourceVersionCheck`, `cloneSourceInfos`, `cloneOrigin`,
|
||||
`cloneFieldInfo`, `cloneChange`, `cloneDiagnostic`, and `cloneDiagnostics`.
|
||||
Helpers refer to each other; only tests call `cloneSourceInfo`. Active root-owned
|
||||
records come through [conversion.go](../../conversion.go).
|
||||
|
||||
**Recommendation and acceptance.** Delete the disconnected family and tests solely
|
||||
protecting it. Keep conversion assertions and useful returned-record ownership
|
||||
coverage through repeated public queries and mutation of mutable nested results.
|
||||
Replacing an entire `Destination` field on a copied struct does not demonstrate
|
||||
nested detachment. Keep active engine clones and `Path.clone`; do not expose
|
||||
opaque path internals or invent a stronger copy guarantee. Coordinate F12.
|
||||
|
||||
### F05. Remove Uncalled Engine Helpers
|
||||
|
||||
Type: cleanup. Priority: low. Source: deadcode 4; placement subset also complexity 5.
|
||||
|
||||
The type-aware audit found no callers or function-value uses in the inspected
|
||||
production/test build configurations for the following helpers:
|
||||
|
||||
| Candidate | Active counterpart to preserve |
|
||||
| --- | --- |
|
||||
| `mergeDisjointMappings` in [compose.go](../../internal/engine/compose.go) | `mergeDisjointMappingsAtPath` and shared recursive merging; the old helper references only itself. |
|
||||
| `mergeHistoryDocument` in [history.go](../../internal/engine/history.go) | `mergeHistoryDocumentAtPath` with sequence evidence. |
|
||||
| `inheritanceDirectiveLocation` in [inheritance.go](../../internal/engine/inheritance.go) | Preparation's directive entry/location handling. |
|
||||
| `addSecretEvidencePath` in [secret.go](../../internal/engine/secret.go) | Projected version sensitivity evidence and the active path accumulator. |
|
||||
| `PlacementModeFromFacade`, `PlacementModeForFacade` in [destination.go](../../internal/engine/destination.go) | Input/options conversion and `SourceInfoPlacementModeForFacade`. |
|
||||
|
||||
**Recommendation and acceptance.** Remove these definitions and imports/comments
|
||||
solely supporting them after confirming references at implementation time. Preserve
|
||||
active counterparts and public root APIs. The placement pair can be removed
|
||||
without selecting the broader transport work in F07.
|
||||
|
||||
### F06. Trim Unread Private Result And Transport Members
|
||||
|
||||
Type: cleanup. Priority: low. Source: deadcode 6.
|
||||
|
||||
The audit identified the following populated members without production readers.
|
||||
Some private tests inspect them. Remove only these slots and computations solely
|
||||
feeding them, preserving validation and active outputs:
|
||||
|
||||
| Owner and candidate members | Boundary to preserve |
|
||||
| --- | --- |
|
||||
| `collectionPolicyResolution.declarations`, `declarationsPresent`, `identityDeclarationPresent`, `applicationIdentityFields` in [collection_policy.go](../../internal/engine/collection_policy.go) | Local declaration normalization, `modeDeclarationPresent`, and `applicationIdentityPresent`. |
|
||||
| `inputPresence.null` in [decode.go](../../internal/engine/decode.go) | Presence/location and effective-node null reporting. |
|
||||
| `rootDirectiveExtraction.importsPresent`, `sequencesPresent` in [directives.go](../../internal/engine/directives.go) | Parsed declarations, diagnostics, and directive validation. |
|
||||
| `importSelection.outcome` in [import_selection.go](../../internal/engine/import_selection.go) and glob selection | Candidate/admission behavior and the distinct, active public `importSelectionEvidence.outcome`. |
|
||||
| `importDeclarationSpec.excludeSet` in [import_spec.go](../../internal/engine/import_spec.go) | Active `exclude` policy. |
|
||||
| `schemaPath.field`, `dynamic` in [schema.go](../../internal/engine/schema.go) | Descriptor and success result used by path consumers; coordinate A01. |
|
||||
| `selectedOverlayRequest.filesystem` in [selected_overlay.go](../../internal/engine/selected_overlay.go) | Explicit filesystem-access argument and borrowed ownership. |
|
||||
| `sequenceDeclarationSpec.destinationLocation` in [sequence_declaration.go](../../internal/engine/sequence_declaration.go) | Other active declaration/field diagnostic locations. |
|
||||
| `sourceVersionEvidence.absence`, `checked`; `sourceVersionAncestor.kind` in [source_version.go](../../internal/engine/source_version.go) | Actual checks, version/presence/location evidence, ancestor paths, and sensitivity. |
|
||||
| `postDecodeOverrideContext.sources` in [override_context.go](../../internal/engine/override_context.go) | Local source list used to build callback resolution input. |
|
||||
|
||||
**Acceptance.** Preserve public presence, null, selection, version, diagnostic,
|
||||
and ownership behavior. Rework assertions on inactive annotations only where
|
||||
they protect a meaningful supported outcome. A lack of selector reads alone is
|
||||
not a general removal rule: map keys, embedded records, and interfaces require
|
||||
separate analysis.
|
||||
|
||||
### F07. Simplify Redundant Facade-To-Engine Transport
|
||||
|
||||
Type: optional refactor. Priority: low. Source: complexity 5, excluding F05's
|
||||
bounded placement-bridge removal.
|
||||
|
||||
**Problem and evidence.** Root conversion, engine facade-transport records, engine
|
||||
private defaults, decorators, and load normalization provide several mapping
|
||||
sites for the same import-default fields. Placement likewise uses a record plus
|
||||
a setter-style bridge. See [conversion.go](../../conversion.go),
|
||||
[lifecycle.go](../../lifecycle.go), [layered.go](../../layered.go),
|
||||
[import_spec.go](../../internal/engine/import_spec.go), and
|
||||
[destination.go](../../internal/engine/destination.go).
|
||||
|
||||
**Recommendation and acceptance.** Consider one engine representation for
|
||||
import-default input and straightforward construction on existing option/input
|
||||
records, only if this reduces total concepts and mapping sites. Keep domain-rule
|
||||
and ownership conversions and separate registration compilation. Preserve
|
||||
root-owned types/signatures, both loading APIs, invalid-enum validation,
|
||||
nil-versus-empty patterns, and pointer/slice snapshots. No universal request DTO,
|
||||
generated mapper, public internal aliases, or adapter framework is proposed.
|
||||
|
||||
### F08. Index Secret-Failure Location Queries Lazily
|
||||
|
||||
Type: optimization candidate. Priority: low. Source: efficiency 5.
|
||||
|
||||
**Problem and evidence.** `secretDiagnostic` in
|
||||
[secret_reference.go](../../internal/engine/secret_reference.go) calls unindexed
|
||||
nearest-location traversal for each failed reference. N missing references in a
|
||||
wide mapping incur O(N²) comparisons, even when they use one cached environment
|
||||
name. Normal deterministic traversal/sorting does not require these scans.
|
||||
|
||||
**Recommendation and acceptance.** Consider a lazy read-only `documentLookup`
|
||||
shared during secret resolution, or carry relevant location state through the
|
||||
walk. With V nodes, F failures, and depth D, attribution can be O(V + F × D),
|
||||
apart from sorting. Keep the successful path free of an unnecessary eager index.
|
||||
Preserve all diagnostics, ancestor fallback, source coordinates, and safe messages;
|
||||
failing fast would change behavior rather than optimize it.
|
||||
|
||||
### F09. Cover Public Historical-Path Enumeration
|
||||
|
||||
Type: test improvement. Priority: medium. Source: testing 2; related testing 6.
|
||||
|
||||
**Problem and evidence.** Root `Metadata.HistoricalPaths` in
|
||||
[metadata.go](../../metadata.go) had no executed statements in the aggregate
|
||||
profile. Engine tests cover it thoroughly, but not root path conversion. An empty
|
||||
or incorrectly converted public result could leave engine tests green.
|
||||
|
||||
**Recommendation and acceptance.** Add one external-package test enumerating
|
||||
effective and removed paths, using returned paths with `Lookup` and `History`,
|
||||
including a numeric-key/sequence shape change. Cover sorted unique pointer
|
||||
spelling, zero metadata, and replacement of a returned slice element without
|
||||
affecting later queries. Keep detailed path mutation/shape tests in the engine.
|
||||
This can replace F12's private segment-representation assertion without copying
|
||||
the complete internal matrix or exposing private segments.
|
||||
|
||||
### F10. Strengthen Fuzz Detachment Assertions
|
||||
|
||||
Type: test improvement. Priority: low. Source: testing 4.
|
||||
|
||||
**Problem and evidence.** `FuzzCompositionAndOverlay` in
|
||||
[composition_fuzz_test.go](../../internal/engine/composition_fuzz_test.go) appends
|
||||
to the result root then compares inputs. A shallow root copy sharing existing
|
||||
descendants can pass because append changes neither the input's slice header nor
|
||||
elements within its old length. Existing deterministic merge tests already
|
||||
exercise meaningful nested mutation.
|
||||
|
||||
**Recommendation and acceptance.** Mutate an existing result descendant or
|
||||
in-length element within the bounded fuzz target, then compare both inputs.
|
||||
Handle empty containers separately and retain input immutability/commutativity
|
||||
properties. Improve the existing assertion rather than adding another ownership
|
||||
matrix or claiming all ownership coverage is absent.
|
||||
|
||||
### F11. Replace Exact Stat-Call Choreography With Observable Ordering
|
||||
|
||||
Type: test cleanup. Priority: low. Source: testing 5.
|
||||
|
||||
**Problem and evidence.** `TestSelectNamedImportsChecksNormalizedPathsLexically`
|
||||
in [import_selection_test.go](../../internal/engine/import_selection_test.go)
|
||||
requires `a.yaml,a.yaml,z.yaml,z.yaml` stat calls but checks candidate count only.
|
||||
Lexical handling matters; exactly two stats per file is not an established contract.
|
||||
|
||||
**Recommendation and acceptance.** Assert ordered candidate paths and, where
|
||||
needed, the first diagnostic site using failing targets. Consolidate with existing
|
||||
selection tests and delete the standalone case if its protection is subsumed.
|
||||
Keep meaningful observations such as not opening excluded contents. Do not turn
|
||||
incidental helper call counts into an efficiency or behavior guarantee.
|
||||
|
||||
### F12. Consolidate Facade Scaffolding Around Public Behavior
|
||||
|
||||
Type: test cleanup. Priority: low. Source: testing 6; related deadcode 3.
|
||||
|
||||
**Evidence and recommendations.**
|
||||
|
||||
- Remove the duplicate six-type ownership loop in
|
||||
[facade_compatibility_test.go](../../facade_compatibility_test.go), retaining the
|
||||
comprehensive owner in [facade_candidate_test.go](../../facade_candidate_test.go),
|
||||
compile-time interfaces, public construction, and distinct lifecycle checks.
|
||||
A literal assignment equality assertion on a new `Result.Config` adds no
|
||||
protection beyond compilation and ordinary Go assignment.
|
||||
- Replace `TestWrappedPathsRetainEngineSegmentIntent` in
|
||||
[facade_internal_test.go](../../facade_internal_test.go), which compares private
|
||||
representations, with public contextual mapping/index behavior under F09.
|
||||
Keep engine segment-intent coverage.
|
||||
- Move `TestWrappedSourcesPreserveEngineOwnership` from direct `engine.Load`
|
||||
through `source.toEngine()` to public `Load` and root error assertions.
|
||||
Consolidate reader cases with [facade_equivalence_test.go](../../facade_equivalence_test.go)
|
||||
while preserving explicit copied-reader and byte-source mutation coverage.
|
||||
- F04 owns removal of the disconnected clone family and the ineffective whole-
|
||||
destination assignment assertion in [records_test.go](../../records_test.go).
|
||||
Keep useful conversion and returned-record ownership protection there or in
|
||||
existing public source-snapshot tests.
|
||||
|
||||
**Acceptance.** Remove scaffolding only after preserving its distinct behavioral
|
||||
risks. Root integration tests still protect conversion, error typing, callbacks,
|
||||
source identity, disclosure, and ownership; engine coverage does not substitute
|
||||
for them. Static public/dependency-boundary tests remain useful.
|
||||
|
||||
## Boundaries To Preserve
|
||||
|
||||
The audits found the architecture coherent and did not establish a need for new
|
||||
public features, a replacement loading API, package proliferation, or a general
|
||||
visitor/strategy framework. Root-owned conversions, synchronous load-local state,
|
||||
shared dependency scheduling, indexed combination, separated inheritance phases,
|
||||
and passive resource contexts remain useful owners. The clone traversal was
|
||||
already reviewed and retained at `34cbc0d:docs/roadmap/consolidation.md`; a high
|
||||
complexity estimate does not reopen it.
|
||||
|
||||
No additional supported-use data race, deadlock, background-work leak, credential
|
||||
disclosure, command injection, authority bypass, or host containment escape was
|
||||
established. These are limited audit observations, not absence guarantees.
|
||||
Caller-owned mutable objects, blocking operations, safe callback messages, and
|
||||
borrowed filesystem behavior retain their documented responsibilities. No new
|
||||
locking, cancellation, retry, authentication, permission, or environment-variable
|
||||
restriction follows from these findings.
|
||||
|
||||
Preserve raw-error suppression, structured safe diagnostics, original application
|
||||
panic propagation, intentional bootstrap partial writes, allowed partial writer
|
||||
output, and documented read-only regular-file close handling. Regression tests
|
||||
must enforce existing contracts rather than broaden them. Optional absence must
|
||||
remain distinct from acquisition failure, and genuine finite reuse from cycles.
|
||||
|
||||
Public APIs are not dead merely because repository examples omit them. Interface
|
||||
dispatch, reflection, build constraints, identity tokens, map-key equality, and
|
||||
uninstantiated generics require more than caller counts. In particular,
|
||||
`decodeInlineMapEntry` and import-cycle diagnostics remain active.
|
||||
`Inspection.resolution` retains recorded snapshots under the existing resolution
|
||||
contract even though replay uses a coalesced view; it is not a cleanup candidate.
|
||||
|
||||
Selected stable Kahn ordering, deterministic sorting, exact numeric identity,
|
||||
and the expressly selected registration-overlap check are not reconsidered here.
|
||||
Required detached copies and genuinely expanding output remain legitimate costs.
|
||||
The broader replay, metadata-handoff, cross-load schema-cache, and contributor-
|
||||
trace experiments stay in [future.md](future.md#3-performance-experiments).
|
||||
Local fixes and removal of proven unused work do not select those experiments.
|
||||
|
||||
## Validation Approach For Selected Work
|
||||
|
||||
Use the existing [development guide](../development.md#baseline-validation) and
|
||||
[testing policy](../policy/testing.md). Add meaningful regressions with the
|
||||
selected fixes, at the narrowest stable boundary that detects the reported
|
||||
failure. Extend existing owners rather than duplicating internal matrices at
|
||||
every layer. Assert nil results and safe structured failures where relevant,
|
||||
and verify retained state/handles independently when they have distinct owners.
|
||||
|
||||
Keep termination, allocation, and link-expansion probes bounded. Use small
|
||||
controlled budgets, disposable processes where necessary, and filesystem
|
||||
observation where it detects the specific defect. No wall-clock thresholds,
|
||||
coverage percentages, complexity-score limits, exact incidental syscall traces,
|
||||
new resource caps, or extra release gates are selected. Algorithmic evidence is
|
||||
not a measured speedup. Performance experiments need separate scope and suitable
|
||||
measurement conditions; no benchmarks were run for this consolidation.
|
||||
|
||||
Once selected work changes behavior or structure, update its canonical contract
|
||||
or internal owner as appropriate. This review document remains the finding/status
|
||||
owner until an implementation plan is prepared; completed records can retire
|
||||
to Git history under the normal documentation lifecycle.
|
||||
|
||||
## Original-Finding Map
|
||||
|
||||
Original files are retrieved from `ecd5d5d:docs/roadmap/<filename>`. Every numbered
|
||||
finding is mapped below; repeated citations are corroboration or shared coverage,
|
||||
not extra fixes.
|
||||
|
||||
| Original finding | Consolidated owner |
|
||||
| --- | --- |
|
||||
| correctness 1 | [A01](#a01-terminate-pointer-only-recursive-descriptor-traversal) |
|
||||
| correctness 2 | [A02](#a02-make-failed-dynamic-descriptor-construction-transactional) |
|
||||
| correctness 3 | [A03](#a03-distinguish-acyclic-slice-views-in-cycle-detection) |
|
||||
| correctness 4 | [B01](#b01-deactivate-callback-contexts-during-panic-unwinding) |
|
||||
| efficiency 1 | [E01](#e01-avoid-scanning-every-policy-for-each-replacement) |
|
||||
| efficiency 2 | [E02](#e02-avoid-recopying-unrelated-policy-across-small-tiers) |
|
||||
| efficiency 3 | [E04](#e04-index-tier-history-projection-lookups) |
|
||||
| efficiency 4 | [E05](#e05-restore-compound-identity-without-repeated-mapping-scans) |
|
||||
| efficiency 5 | [F08](#f08-index-secret-failure-location-queries-lazily) |
|
||||
| efficiency 6 | [A05](#a05-reuse-successful-dynamic-type-eligibility-checks-locally) |
|
||||
| complexity 1 | [F01](#f01-remove-the-test-only-eager-acquisition-mode) |
|
||||
| complexity 2 | [F02](#f02-clarify-active-acquisition-and-coordinator-handoffs) |
|
||||
| complexity 3 | [E03](#e03-clarify-policy-preparation-and-merge-evidence-application) |
|
||||
| complexity 4 | [C03](#c03-separate-glob-entry-preparation-from-traversal) |
|
||||
| complexity 5 | [F07](#f07-simplify-redundant-facade-to-engine-transport), with bounded bridge removal in [F05](#f05-remove-uncalled-engine-helpers) |
|
||||
| concurrency 1 | [B01](#b01-deactivate-callback-contexts-during-panic-unwinding), corroboration |
|
||||
| resources 1 | [A04](#a04-enforce-existing-node-budgets-before-container-reservations) |
|
||||
| resources 2 | [D01](#d01-account-for-the-complete-published-history-graph) |
|
||||
| resources 3 | [B02](#b02-close-the-owned-import-root-when-a-version-callback-panics) |
|
||||
| error-handling 1 | [C01](#c01-preserve-directory-failure-phase-and-strengthen-its-tests) |
|
||||
| security 1 | [C02](#c02-avoid-reexpanding-completed-finite-symlink-dependencies) |
|
||||
| testing 1 | Regression acceptance under A01–A04, B01–B02, C02, and D01 |
|
||||
| testing 2 | [F09](#f09-cover-public-historical-path-enumeration) |
|
||||
| testing 3 | [C01](#c01-preserve-directory-failure-phase-and-strengthen-its-tests), including shared fixture assertions |
|
||||
| testing 4 | [F10](#f10-strengthen-fuzz-detachment-assertions) |
|
||||
| testing 5 | [F11](#f11-replace-exact-stat-call-choreography-with-observable-ordering) |
|
||||
| testing 6 | [F12](#f12-consolidate-facade-scaffolding-around-public-behavior), with F04 and F09 |
|
||||
| deadcode 1 | [D02](#d02-remove-the-unconsumed-override-result-pre-cli-copy) |
|
||||
| deadcode 2 | [D03](#d03-remove-the-unqueried-published-structural-input-copy) |
|
||||
| deadcode 3 | [F04](#f04-remove-the-disconnected-root-record-clone-family) |
|
||||
| deadcode 4 | [F05](#f05-remove-uncalled-engine-helpers) |
|
||||
| deadcode 5 | [D04](#d04-stop-constructing-unconsumed-combination-evidence) |
|
||||
| deadcode 6 | [F06](#f06-trim-unread-private-result-and-transport-members) |
|
||||
| deadcode 7 | [F03](#f03-retire-the-parallel-test-only-import-directive-parser) |
|
||||
| deadcode 8 | [F01](#f01-remove-the-test-only-eager-acquisition-mode), duplicate of complexity 1 |
|
||||
|
||||
## Open Questions
|
||||
|
||||
### OQ-1. What Should The First Implementation Scope Include?
|
||||
|
||||
**Recommendation:** select all nine reported defects with their regression
|
||||
coverage, plus the bounded cleanup and test improvements where their evidence
|
||||
holds on the implementation baseline. The unused history copies deserve early
|
||||
coordination with D01, and callback context/root closure deserve independent
|
||||
acceptance within the same work area. Keep fixes reviewable and distinct even
|
||||
when delivered in one sprint.
|
||||
|
||||
**Alternative:** deliver defect fixes first, then handle cleanup and independent
|
||||
test improvements in a separate effort. This produces a smaller initial scope
|
||||
and simpler attribution, but retains known redundant work and can revisit the
|
||||
same files/tests. Cleanup should not delay a consequential fix merely to achieve
|
||||
a tidier overall structure.
|
||||
|
||||
### OQ-2. Which Efficiency Candidates Should Accompany Remediation?
|
||||
|
||||
**Recommendation:** consider E04/E05 as narrow local improvements, and A05/F08
|
||||
as lower-priority options after their correctness/diagnostic boundaries are sound.
|
||||
Evaluate E01/E02 together with E03 before committing to a policy-state redesign:
|
||||
their distinct scaling cases need preserved acceptance even if they share an
|
||||
implementation. These candidates have source-level evidence of avoidable work,
|
||||
but no new measured speedup claim.
|
||||
|
||||
**Alternative:** defer all six efficiency candidates until representative consumer
|
||||
profiling establishes their practical cost. This concentrates the first effort
|
||||
on correctness and cleanup, at the cost of retaining demonstrated growth patterns.
|
||||
It does not block C02's availability fix or A04/D01's enforcement of existing
|
||||
resource budgets. Broader experiments in `future.md` remain separately deferred.
|
||||
|
||||
### OQ-3. How Much Structural Refactoring Should Be Selected?
|
||||
|
||||
**Recommendation:** accept F01's removal of the test-only protocol as bounded
|
||||
cleanup; assess active acquisition handoffs (F02) and policy/evidence ownership
|
||||
(E03) with their affected fixes before selecting a wider extraction. Leave glob
|
||||
entry extraction (C03) and transport simplification (F07) optional unless a
|
||||
concrete design reduces concepts and clarifies ownership.
|
||||
|
||||
**Alternative:** include all four structural refactors in the same effort for a
|
||||
more uniform maintenance result. This offers broader readability improvements
|
||||
but increases review scope and the chance of moving complexity rather than
|
||||
removing it. Neither approach calls for a new public API, generic framework, or
|
||||
changes to the established configuration model.
|
||||
@@ -1,283 +0,0 @@
|
||||
# Maintainability And Complexity Audit
|
||||
|
||||
Reviewed revision: `320d0c5f439a059a7081cf7532c9b5d65891f5c7`.
|
||||
Audit date: 2026-10-25.
|
||||
|
||||
## Scope And Method
|
||||
|
||||
This audit examines readability, responsibility boundaries, state handoffs, and
|
||||
interface duplication. It covers the root facade, engine subsystems, document
|
||||
and YAML boundaries, and relevant tests, documentation, and prior refactoring
|
||||
decisions. It does not propose new feature behavior or performance guarantees.
|
||||
|
||||
The codebase-memory graph was refreshed and its function spans, cyclomatic and
|
||||
cognitive complexity estimates, parameter counts, and caller traces were used
|
||||
to select code for inspection. The graph contains 907 non-test functions/methods
|
||||
and 940 test-file functions/methods. Its index excludes examples, documentation,
|
||||
and scripts; tracked-file inventory and direct inspection supplemented it.
|
||||
Standalone `gocyclo`, `gocognit`, and `golangci-lint` were unavailable. No tool
|
||||
installation, benchmarks, or empirical performance testing was needed.
|
||||
|
||||
The tracked production inventory, excluding examples, contains 16 root Go files,
|
||||
97 engine files, one document file, and two YAML adapter files: approximately
|
||||
22,612 physical lines overall. The largest production files are `compose.go`
|
||||
(599 lines), `history.go` (568), `overlay.go` (564), and `discovery.go` (540).
|
||||
These measurements locate responsibilities; they are not refactoring thresholds.
|
||||
|
||||
Representative graph measurements:
|
||||
|
||||
| Function | File | Function span | Cognitive estimate |
|
||||
| --- | --- | ---: | ---: |
|
||||
| `valueOperation.clone` | `internal/engine/clone.go` | 130 | 104 |
|
||||
| `acquireInput` | `internal/engine/acquisition.go` | 202 | 99 |
|
||||
| `valueBuilder.build` | `internal/engine/value.go` | 104 | 93 |
|
||||
| `decodeValue` | `internal/engine/decode.go` | 115 | 85 |
|
||||
| `selectGlobImportCandidates` | `internal/engine/glob.go` | 112 | 73 |
|
||||
| `assembleLayeredInput` | `internal/engine/load_request.go` | 146 | 63 |
|
||||
| `executeLoadRequest` | `internal/engine/load.go` | 198 | 56 |
|
||||
| `mergeOverlayMappingsWithCollectionPolicy` | `internal/engine/overlay.go` | 163 | 46 |
|
||||
|
||||
Spans include comments and blank lines; scores are tool estimates for comparative
|
||||
triage, not standardized quality grades. Source review, rather than a numerical
|
||||
cutoff, determines the findings below.
|
||||
|
||||
## Architectural Assessment
|
||||
|
||||
The [implemented architecture](../internal/overview.md) remains coherent: the
|
||||
root owns the supported public types and explicit conversions; the engine owns
|
||||
loading and frozen inspection; the document package owns the ordered tree; and
|
||||
the YAML adapter isolates the upstream parser. Ordinary and layered loads share
|
||||
one normalized request and execution lifecycle. Imports and inheritance retain
|
||||
their separate scopes and use the common dependency scheduler.
|
||||
|
||||
The recent consolidation improved import ownership and file boundaries, separated
|
||||
inheritance preparation/combination/finalization, shared filesystem facts, and
|
||||
clarified schema and projection responsibilities. The findings concern remaining
|
||||
maintenance opportunities, not a recommendation to repeat that refactor or split
|
||||
the engine into a package per subsystem.
|
||||
|
||||
The existing [correctness](correctness.md) and [efficiency](efficiency.md) audits
|
||||
remain separate owners of their findings. No additional runtime defect was
|
||||
established in this pass. Related risks are referenced rather than duplicated.
|
||||
|
||||
## 1. Remove The Test-Only Eager Acquisition Mode
|
||||
|
||||
Status: open. Priority: medium. Scope: engine acquisition and its test helpers.
|
||||
|
||||
**Relevant code.** `inputAcquisitionRequest.deferAssembly` in
|
||||
[acquisition.go](../../internal/engine/acquisition.go), and the final branch of
|
||||
`acquireImportedWithAccess` in
|
||||
[import_acquisition.go](../../internal/engine/import_acquisition.go), lines
|
||||
206–224. Production construction sites in `executeLoadRequest`
|
||||
([load.go](../../internal/engine/load.go), lines 210–214) and
|
||||
`acquireUnderlayGroupScopes`
|
||||
([load_request.go](../../internal/engine/load_request.go), lines 243–246) both
|
||||
set this flag to true.
|
||||
|
||||
**Complexity.** Caller tracing found no production caller selecting eager
|
||||
composition. The false branch remains exercised by private test entry helpers,
|
||||
including `testImportRequest`, `testAcquireImport`, and `testAcquireInput` in
|
||||
[imports_test.go](../../internal/engine/imports_test.go). Acquisition therefore
|
||||
maintains two return protocols: an acquired scope with a nil composed root, or
|
||||
an already composed document. The eager branch reconstructs `assembledInput`
|
||||
and reenters composition from the acquisition function, while the published
|
||||
loading paths perform that phase later. Tests can consequently exercise a
|
||||
different handoff from the one consumers use.
|
||||
|
||||
**Potential refactoring.** Make acquisition return retained scopes consistently
|
||||
and remove the unused production mode. Tests needing composed values can invoke
|
||||
the real composition phase explicitly through a small test-only convenience
|
||||
helper. Keep acquisition-only tests acquisition-only. Preserve handle closure,
|
||||
pending-item placement reservation, accounting, diagnostics, and meaningful
|
||||
composition coverage. This removes a private alternative path, not support for
|
||||
any public loading workflow. Do not infer that other nil-state or directive
|
||||
contexts are unused without separately tracing their callers.
|
||||
|
||||
## 2. Clarify Acquisition And Load-Coordinator Phase Handoffs
|
||||
|
||||
Status: open. Priority: medium. Scope: engine, across acquisition, version,
|
||||
assembly, and lifecycle files.
|
||||
|
||||
**Relevant code.** `acquireInput` in
|
||||
[acquisition.go](../../internal/engine/acquisition.go), `executeLoadRequest` in
|
||||
[load.go](../../internal/engine/load.go), and `assembleLayeredInput` in
|
||||
[load_request.go](../../internal/engine/load_request.go).
|
||||
|
||||
**Complexity.** `acquireInput` still combines search outcome handling, parsing,
|
||||
disabled-directive checks, three directive/version-processing branches,
|
||||
import-versus-standalone dispatch, placement/accounting, and passive context
|
||||
construction. Its version-processing section repeats source-ID extraction,
|
||||
failure handling, and `mainProcessing` updates, while the layered branch must
|
||||
extract directives separately and restore them after version processing.
|
||||
|
||||
The coordinators also manipulate several intentionally distinct representations:
|
||||
parsed source, local payload, acquired scope, composed root, inherited root,
|
||||
local/protected version paths, and effective version evidence. For example,
|
||||
`executeLoadRequest` includes a substantial ordinary-load resource-context
|
||||
fallback between assembly and inheritance, while `assembleLayeredInput` repeats
|
||||
declaration gathering, tier application, and destination projection for underlays
|
||||
and main. Understanding a source-version or placement change requires tracing
|
||||
both those mechanics and the overall phase order through long functions.
|
||||
|
||||
**Potential refactoring.** Extract cohesive operations for processing one parsed
|
||||
input's directives/version evidence and for placing/registering a standalone
|
||||
contribution. Reuse the existing processing result and acquisition state rather
|
||||
than inventing another context hierarchy. Isolate the substantial context and
|
||||
structural-expansion operations from the top-level lifecycle, and consider one
|
||||
helper for the repeated tier application/projection handoff. Keep phase order,
|
||||
error exits, and source acquisition order readable in the coordinators.
|
||||
|
||||
Extraction is useful only when it gives one operation a clear owner and result;
|
||||
moving blocks into helpers that still share the same mutable surrounding locals
|
||||
would not solve the problem. Preserve the deliberate ordinary/layered overlay
|
||||
differences, default versus enabled version-check timing, warning accumulation,
|
||||
exactly-once callbacks, and load-wide versus tier-local state. This is separate
|
||||
from finding 1: removing the eager branch does not simplify these active paths.
|
||||
|
||||
## 3. Separate Collection-Policy Preparation From Merge Evidence Application
|
||||
|
||||
Status: open. Priority: medium. Scope: engine precedence and inheritance.
|
||||
|
||||
**Relevant code.** `mergeOverlayMappingsWithCollectionPolicy` and
|
||||
`applyOverlaySequenceEvidence` in
|
||||
[overlay.go](../../internal/engine/overlay.go);
|
||||
`resolveStrictCollectionPolicies` in
|
||||
[compose.go](../../internal/engine/compose.go);
|
||||
`combineInheritanceTemplate` in
|
||||
[inheritance_combine.go](../../internal/engine/inheritance_combine.go); and the
|
||||
policy/origin helpers in
|
||||
[inheritance_collection.go](../../internal/engine/inheritance_collection.go).
|
||||
|
||||
**Complexity.** The overlay coordinator prepares claims and declaration groups,
|
||||
discovers applicable destinations, resolves operations, configures recursive
|
||||
merge callbacks, accumulates diagnostics/history, reconciles declaration-only
|
||||
policies after mutation, and sorts the output. Its callbacks close over several
|
||||
maps and mutate the assembly while reporting failures through an outer slice.
|
||||
`applyOverlaySequenceEvidence` then mixes policy retirement, displaced origins,
|
||||
replacement records, copied incoming origins, and record-policy reconstruction.
|
||||
|
||||
There is also concrete duplicated bookkeeping: overlay and inheritance callbacks
|
||||
both translate a sequence result into replace-versus-mapped history descriptors;
|
||||
overlay evidence and `applyInheritanceSequencePolicy` both rebuild record policy
|
||||
order from lower/higher item projections. The shared `combineSequence` is already
|
||||
the correct value-combination owner, but maintainers must separately coordinate
|
||||
these sidecar translations when its result representation changes.
|
||||
|
||||
**Potential refactoring.** Give overlay preparation, value/evidence application,
|
||||
and declaration-only finalization explicit local boundaries. Let a small
|
||||
operation owner or result carry the diagnostic and evidence collections currently
|
||||
captured by the large callbacks. Share the straightforward history-descriptor
|
||||
construction; evaluate a common projected-record selection helper while retaining
|
||||
named precedence and inheritance ownership rules.
|
||||
|
||||
Do not merge the distinct origin semantics or hide mode-lifetime differences
|
||||
behind a generic strategy framework. Keep `combineSequence` and the recursive
|
||||
mapping merge shared, and consume their result rather than recomputing values.
|
||||
Coordinate this work with collection-policy findings 1–2 in the
|
||||
[efficiency audit](efficiency.md) so clearer preparation does not preserve or
|
||||
introduce repeated whole-table copying/scanning. Preserve replacement ordering,
|
||||
pending declarations, new versus retained record owners, and stable history.
|
||||
|
||||
## 4. Extract Patterned Glob Entry Preparation From Traversal Orchestration
|
||||
|
||||
Status: open. Priority: medium. Scope: engine import discovery.
|
||||
|
||||
**Relevant code.** `selectGlobImportCandidates` in
|
||||
[glob.go](../../internal/engine/glob.go), especially its patterned-entry branch.
|
||||
The corresponding directory-search entry operation already has a named owner,
|
||||
`prepareImportDirectoryEntry` in
|
||||
[import_selection.go](../../internal/engine/import_selection.go).
|
||||
|
||||
**Complexity.** The glob function nests pattern-segment traversal, parent
|
||||
candidates, and directory entries. Its innermost branch handles matching,
|
||||
hidden-entry policy, lexical and access paths, containment, link inspection,
|
||||
follow behavior, intermediate-directory eligibility, native/host identity
|
||||
differences, canonicalization, labels, and candidate creation. Set-union and
|
||||
component-advancement mechanics are interleaved with those admission decisions,
|
||||
making the important lexical-versus-canonical distinction difficult to follow.
|
||||
|
||||
**Potential refactoring.** Extract a glob-specific entry preparation operation
|
||||
returning an admitted candidate, an ordinary skip, or a diagnostic. Leave pattern
|
||||
component advancement, literal segments, per-component union/sorting, and final
|
||||
exclusion/requiredness visible in the selector. Reuse low-level filesystem facts
|
||||
where semantics coincide; directory and glob admission need not become one
|
||||
general visitor interface. Preserve inspection/error order, entry accounting,
|
||||
native namespace spelling, and selected-file validation. This is a readability
|
||||
change, not a proposal to change the selected discovery algorithm or add caching.
|
||||
|
||||
## 5. Simplify Redundant Facade-To-Engine Input Transport
|
||||
|
||||
Status: open. Priority: low. Scope: root facade and engine, across packages.
|
||||
|
||||
**Relevant code.** Root `toEngineImportDefaults` in
|
||||
[conversion.go](../../conversion.go), `toEngineOptions` in
|
||||
[lifecycle.go](../../lifecycle.go), and `toEngineLayeredOptions` in
|
||||
[layered.go](../../layered.go); engine transport/private defaults and option
|
||||
decorators in [import_spec.go](../../internal/engine/import_spec.go), lines
|
||||
46–87; and placement transport helpers in
|
||||
[destination.go](../../internal/engine/destination.go), lines 23–39.
|
||||
|
||||
**Complexity.** Import defaults have a root-owned public representation, an
|
||||
engine facade-transport representation, and a second engine-private representation
|
||||
with the same five fields. Conversion constructs the transport, an option
|
||||
decorator converts it to private defaults, and load normalization snapshots it
|
||||
again. Placement similarly requires constructing an engine record and then
|
||||
passing it through a separate setter-style helper. Even a simple control change
|
||||
has multiple mechanical mapping sites across the package boundary.
|
||||
|
||||
Caller and text-reference checks also found no uses of the standalone
|
||||
`PlacementModeFromFacade` and `PlacementModeForFacade` functions beyond their
|
||||
declarations. The similarly named `SourceInfoPlacementModeForFacade` is used by
|
||||
root source-record conversion and is not dead code. The unused pair adds a
|
||||
second apparent placement conversion route for maintainers to investigate.
|
||||
|
||||
Root type ownership and explicit conversion are deliberate and useful; the
|
||||
opportunity is the extra engine-internal representation/construction protocol,
|
||||
not eliminating the facade. The public wrappers do not need to change.
|
||||
|
||||
**Potential refactoring.** Remove the two unused enum bridges. Then consider one
|
||||
engine representation of import-default input values and a straightforward
|
||||
construction surface on the existing engine option/input records. Review inert
|
||||
placement decorators as part of the same bounded cleanup. Keep helpers that
|
||||
actually encode domain rules or ownership conversion, and keep
|
||||
definition/registration compilation separate from transport.
|
||||
Avoid adding another universal request DTO, code generator, reflective mapper,
|
||||
or adapter framework to remove a few mechanical functions.
|
||||
|
||||
Preserve root-owned named types and signatures, invalid-enum validation,
|
||||
nil-versus-empty patterns, pointer/slice snapshots, and the two public loading
|
||||
entry points. Exported declarations inside Go's `internal` boundary need not
|
||||
become public root aliases or bridge methods. Pursue this low-priority cleanup
|
||||
only if it reduces total concepts and mapping sites, rather than relocating them.
|
||||
|
||||
## Areas To Retain And Review Boundaries
|
||||
|
||||
- The clone traversal was explicitly reviewed and retained in the completed
|
||||
consolidation record at `34cbc0d:docs/roadmap/consolidation.md`. Its high score
|
||||
is not new evidence for reopening that work. `valueBuilder.build`, typed
|
||||
decoding, and the YAML translator also contain substantial but recognizable
|
||||
type dispatch; no repository-wide visitor framework is recommended.
|
||||
- The cohesive engine package and explicit root record conversions follow
|
||||
[ADR 0006](../adr/0006-public-facade.md). Function/file counts alone do not
|
||||
justify package extraction, public API consolidation, or generated conversions.
|
||||
- The shared scheduler, mapping/sequence primitives, recently separated
|
||||
inheritance phases, schema field assembly, and resolved filesystem facts remain
|
||||
useful common owners. Preserve those improvements.
|
||||
- `history.go` and the larger integration-test files have several substantial
|
||||
routines, but file size alone did not establish another prioritized refactor.
|
||||
The deferred replay, copy-handoff, caching, and contributor-index experiments
|
||||
remain in [future work](future.md#3-performance-experiments).
|
||||
|
||||
These are opportunities for further consideration, not a staged implementation
|
||||
plan or new release blockers. Favor the concrete unused-mode removal and active
|
||||
acquisition/collection boundaries before lower-value transport cleanup. A later
|
||||
implementation should preserve the established contracts and relevant behavioral
|
||||
coverage; complexity scores, helper counts, and private call sequences should
|
||||
not become test thresholds or repository guarantees.
|
||||
|
||||
## Validation
|
||||
|
||||
This audit changes only this findings document. No production code, tests,
|
||||
dependencies, policies, or public contracts are changed. Validation consists of
|
||||
the existing local documentation-link test and `git diff --check`; runtime and
|
||||
performance measurements are not part of this review.
|
||||
@@ -1,108 +0,0 @@
|
||||
# Concurrency And Lifetime Audit
|
||||
|
||||
Reviewed revision: `a80273433e87ca955e5a5d9e99b616d8da10f185`.
|
||||
Audit date: 2026-10-25.
|
||||
|
||||
## Scope And Assessment
|
||||
|
||||
This audit reviewed source reuse, concurrent independent loads, schema and
|
||||
acquisition state, callback lifetime, publication, frozen metadata/explanation/
|
||||
diff/rendering, resource contexts, and secrets bootstrap. Knowledge-graph searches
|
||||
and caller traces were supplemented by source inspection and existing tests.
|
||||
|
||||
No new data race, deadlock, unsafe synchronization, goroutine leak, channel
|
||||
management defect, or cancellation/shutdown defect was established under the
|
||||
documented usage contracts. One previously reported callback-lifetime defect
|
||||
remains reproducible and relevant to teardown; it is referenced below rather
|
||||
than assigned a second independent remediation task.
|
||||
|
||||
The [implemented architecture](../internal/overview.md) provides a straightforward
|
||||
ownership model for concurrency:
|
||||
|
||||
- Loading runs synchronously through one engine lifecycle. Production code
|
||||
launches no library-owned goroutines and has no channel, worker, timer, watcher,
|
||||
or background shutdown protocol to manage.
|
||||
- Acquisition, version evidence, schema caches, reflection traversal, composition,
|
||||
and callback records belong to a load or operation, rather than a shared global
|
||||
cache. The root facade delegates without introducing a second shared state owner.
|
||||
- Reader-source copies share a pointer to `readerSource`, whose atomic one-use
|
||||
claim precedes reading. Byte and mapping sources retain constructor snapshots.
|
||||
- Publication builds the retained inspection indexes before returning. Query,
|
||||
explanation, diff, and rendering paths read frozen state and allocate their
|
||||
own mutable results or replay trees. Typed configuration and returned metadata
|
||||
are detached from the retained inspection snapshot.
|
||||
- Returned resource contexts contain passive root information or a borrowed
|
||||
filesystem. Host resource opens acquire their own handles, with ownership
|
||||
transferred to the returned file, rather than sharing the acquisition handle.
|
||||
|
||||
These observations support the existing model; they are not new blanket
|
||||
thread-safety guarantees for application callbacks, borrowed objects, or I/O.
|
||||
|
||||
## 1. Callback Lifetime Guards Survive Panic Unwinding — Previously Reported
|
||||
|
||||
Status: open, tracked by
|
||||
[correctness finding 4](correctness.md#4-callback-contexts-remain-active-after-panic-unwinding).
|
||||
Priority: low. Category: callback teardown across the facade/engine boundary.
|
||||
|
||||
**Relevant code.** `runResolution` in
|
||||
[resolution.go](../../internal/engine/resolution.go), and `runValidation` /
|
||||
`reportVersion` in [validation.go](../../internal/engine/validation.go), deactivate
|
||||
the callback state only after a normal return. The root callback wrappers in
|
||||
[lifecycle.go](../../lifecycle.go) expose that same engine context.
|
||||
|
||||
**Circumstances and consequence.** If a callback retains its context and panics,
|
||||
and application code recovers outside the load, the retained context still
|
||||
accepts queries or diagnostic writes after callback exit. It should instead
|
||||
produce the established closed-context failure. The abandoned per-load state
|
||||
therefore remains accessible beyond its intended lifetime. Reusing the existing
|
||||
external diagnostic probe reproduced this for resolution, semantic validation,
|
||||
and version-check contexts at the reviewed revision.
|
||||
|
||||
**Potential remediation.** Use invocation-scoped deferred deactivation, as
|
||||
described in the linked correctness finding, preserving immediate closure on
|
||||
normal return and unchanged propagation of application panics. There is no need
|
||||
to add context locks, atomic lifecycle flags, panic recovery, or background-work
|
||||
management. Concurrent use of a live callback context is already outside its
|
||||
supported contract; this finding does not establish an additional supported-use
|
||||
race or justify broadening that contract.
|
||||
|
||||
## Validation
|
||||
|
||||
The following passed with Go 1.26.10 on Linux amd64:
|
||||
|
||||
```sh
|
||||
go test -race ./... -count=1
|
||||
go vet ./...
|
||||
```
|
||||
|
||||
The six existing engine concurrency tests for shared definitions, copied-reader
|
||||
claims, concurrent inspection, selected-overlay loads, and resolution-input
|
||||
isolation also passed with `-race -count=20 -cpu=1,4,8`. These tests live in
|
||||
[independence_test.go](../../internal/engine/independence_test.go),
|
||||
[source_test.go](../../internal/engine/source_test.go),
|
||||
[explain_test.go](../../internal/engine/explain_test.go), and
|
||||
[provenance_test.go](../../internal/engine/provenance_test.go).
|
||||
|
||||
The previously created standalone callback-panic probe was rerun outside the
|
||||
repository with race instrumentation. It confirmed the known lifetime defect
|
||||
without reporting a data race; that probe performs sequential post-panic calls,
|
||||
not unsupported concurrent callback-context use. No new tests or production
|
||||
changes were made. Race detection covers executed paths and is not a proof of
|
||||
all possible interleavings. No native macOS or Windows execution was performed.
|
||||
|
||||
## Contract Boundaries Preserved
|
||||
|
||||
- Read-only shared definitions and independent result ownership remain the
|
||||
existing model. Callers remain responsible for synchronization of their own
|
||||
mutable options, callback effects, readers, filesystems, and output writers.
|
||||
- Secrets bootstrap is explicitly a startup operation with no environment
|
||||
compare-and-set guarantee; its check-then-set behavior is not a new finding.
|
||||
See the [bootstrap contract](../config.md#explicit-secrets-directory-bootstrap).
|
||||
- Synchronous loading has no cancellation API or background refresh service.
|
||||
Caller-supplied blocking operations are not evidence of a leaked ConfigKit
|
||||
goroutine or a missing promised shutdown mechanism. See
|
||||
[completion and resource lifetime](../config.md#completion-and-resource-lifetime).
|
||||
|
||||
This report adds no synchronization requirements, new API, or release gates.
|
||||
The existing [correctness](correctness.md), [efficiency](efficiency.md), and
|
||||
[maintainability](complexity.md) findings retain their own scopes and status.
|
||||
@@ -1,191 +0,0 @@
|
||||
# Functional Correctness Audit
|
||||
|
||||
Reviewed revision: `47944d22d1ad45a7f537780effb3d05f998eef14`
|
||||
(Update ReleaseKit to v0.4.2).
|
||||
Audit date: 2026-10-25.
|
||||
|
||||
## Scope And Evidence
|
||||
|
||||
This audit reviewed the root facade and its engine handoffs, source/discovery
|
||||
and filesystem handling, composition and collection rules, inheritance, typed
|
||||
decoding and ownership, application callbacks, secrets, metadata, explanation,
|
||||
and effective-value comparison against the configuration contract and relevant
|
||||
implementation/tests. It was a source-level functional review with targeted
|
||||
diagnostics, not an exhaustive proof or a performance/security certification.
|
||||
|
||||
The existing development check (`./scripts/check.sh`) and full race-enabled
|
||||
suite (`go test -race ./...`) passed using Go 1.26.10 on Linux amd64. Standalone
|
||||
public-API probes outside the repository reproduced the findings below. No
|
||||
production code or repository tests were added or changed. No native macOS or
|
||||
Windows validation was performed, and no new release gates are proposed.
|
||||
|
||||
## 1. Pointer-Only Recursive Types Can Overflow The Stack Or Hang
|
||||
|
||||
Status: open. Priority: medium. Category: schema/decoder termination.
|
||||
|
||||
**Relevant code.** `schemaBuilder.describe` in
|
||||
[schema.go](../../internal/engine/schema.go), lines 119–140, caches a placeholder
|
||||
before describing pointer elements. A legal Go type such as `type Loop *Loop`
|
||||
therefore produces a pointer descriptor whose element is itself.
|
||||
`decodeValue` in [decode.go](../../internal/engine/decode.go), lines 93–106,
|
||||
recursively unwraps pointers without consuming the input node. The pointer
|
||||
unwrapping loops in `resolveSchemaPath` (`schema.go`, lines 347–350 and 387–390)
|
||||
also assume that a non-pointer descriptor will eventually be reached.
|
||||
|
||||
**Reproduction.** With the public package imported as `configkit`:
|
||||
|
||||
```go
|
||||
type Loop *Loop
|
||||
type Config struct {
|
||||
Value Loop `yaml:"value"`
|
||||
}
|
||||
|
||||
configkit.Load[Config](configkit.Bytes("input", []byte("value: {}\n")))
|
||||
```
|
||||
|
||||
This does not return a decode error. It repeatedly calls `decodeValue` with the
|
||||
same input and descriptor until the process reports a fatal stack overflow.
|
||||
A disposable probe using `debug.SetMaxStack(64 << 10)` demonstrated the failure
|
||||
without allowing the process to grow a large stack. Explicit `value: null`
|
||||
loads successfully. With that null input, adding a resolver that calls
|
||||
`Normalize` on `/value` with `Loop(nil)` instead hangs in `resolveSchemaPath`;
|
||||
the separate diagnostic process was stopped by a three-second timeout.
|
||||
|
||||
**Expected behavior.** Incompatible non-null input must fail with a safe
|
||||
diagnostic, and schema-path resolution must terminate. The
|
||||
[schema contract](../config.md#application-schema-binding) supports recursive
|
||||
types with acyclic values; the existing explicit pointer-only restriction is
|
||||
for inline fields, not all pointer fields. This is not a request to recover
|
||||
application panics or reject ordinary recursive structs.
|
||||
|
||||
**Potential remediation.** Detect repeated descriptors while unwrapping
|
||||
pointer-only chains in decoding and schema-path traversal. Preserve supported
|
||||
nil/null values and finite acyclic values, return an appropriate decode error
|
||||
for an incompatible non-null node, and reject descendants that cannot be
|
||||
addressed. Review analogous pointer-unwrapping helpers for the same assumption.
|
||||
A blanket schema rejection of pointer-only recursive types would instead be a
|
||||
contract decision, since it would also reject currently valid nil values; do
|
||||
not introduce it or an arbitrary pointer-depth cap merely to stop the loop.
|
||||
|
||||
## 2. Failed Dynamic Schema Construction Leaves A Reusable Partial Descriptor
|
||||
|
||||
Status: open. Priority: medium. Category: error handling and shared operation state.
|
||||
|
||||
**Relevant code.** `valueOperation.dynamicDescriptor` in
|
||||
[value_operation.go](../../internal/engine/value_operation.go), lines 36–48,
|
||||
passes the load's existing descriptor cache directly to a new schema builder.
|
||||
`schemaBuilder.describe` in [schema.go](../../internal/engine/schema.go), lines
|
||||
119–140 and 167–191, caches container placeholders but returns child errors
|
||||
without removing those placeholders. A subsequent lookup returns the partial
|
||||
descriptor as if construction had succeeded.
|
||||
|
||||
**Reproduction.** Use a configuration with `Value any` and this dynamic type:
|
||||
|
||||
```go
|
||||
type Invalid struct {
|
||||
Channel chan int `yaml:"channel"`
|
||||
}
|
||||
```
|
||||
|
||||
In one resolver, execute these two assignments in order:
|
||||
|
||||
```go
|
||||
configkit.Normalize(r, configkit.Keys("value"), &c.Value,
|
||||
any((*Invalid)(nil)), "first unsupported value")
|
||||
configkit.Normalize(r, configkit.Keys("value"), &c.Value,
|
||||
any(&Invalid{}), "second unsupported value")
|
||||
```
|
||||
|
||||
The first helper correctly records an invalid-value diagnostic because channels
|
||||
are unsupported. It nevertheless leaves the `*Invalid` descriptor cached with
|
||||
a nil element. The second helper reuses it, reaches projection with that nil
|
||||
element, and panics with a nil-pointer dereference instead of returning a
|
||||
`LoadError`. This was reproduced through ordinary public `Load` and `Normalize`;
|
||||
the application callback itself does not panic.
|
||||
|
||||
**Expected behavior.** Unsupported dynamic/helper values must produce safe
|
||||
schema/resolution diagnostics under the
|
||||
[typed projection](../config.md#typed-projection-and-ownership) and
|
||||
[resolution contracts](../config.md#recorded-application-resolution).
|
||||
One reported validation failure must not corrupt the descriptor cache used by
|
||||
later operations in the same callback.
|
||||
|
||||
**Potential remediation.** Make dynamic descriptor construction transactional:
|
||||
stage newly discovered descriptors and commit them only after a successful
|
||||
build, or track and roll back all cache additions belonging to a failed build.
|
||||
Account for recursive descriptors that refer to other partially built types,
|
||||
not just the immediate failed container. Preserve previously valid descriptors
|
||||
and the load-local cache ownership. A nil guard in projection alone would not
|
||||
repair invalid cache entries being treated as successful schema descriptions.
|
||||
|
||||
## 3. Cycle Detection Rejects Acyclic Slice Views Sharing A Starting Address
|
||||
|
||||
Status: open. Priority: medium. Category: supported-value correctness.
|
||||
|
||||
**Relevant code.** `valueVisit` and `visitFor` in
|
||||
[value_operation.go](../../internal/engine/value_operation.go), lines 20–24
|
||||
and 97–116, identify a slice by its type, kind, and starting pointer, but not its
|
||||
length. Both reflective projection/cloning and the parser-neutral value builder
|
||||
in [value.go](../../internal/engine/value.go) use that identity for active-path
|
||||
cycle detection.
|
||||
|
||||
**Reproduction.** This value is finite and acyclic: its nested one-element view
|
||||
contains only the string, not the enclosing two-element view.
|
||||
|
||||
```go
|
||||
shared := []any{"leaf", nil}
|
||||
shared[1] = shared[:1]
|
||||
```
|
||||
|
||||
Place it at `data` in a `Mapping` source, return it from typed defaults for
|
||||
`Data []any`, or supply it as a CLI override. Observed results at `/data/1` were,
|
||||
respectively, `source.invalid`, `schema.cycle`, and `override.invalid_value`.
|
||||
The equivalent independently allocated value
|
||||
`[]any{"leaf", []any{"leaf"}}` loads and renders successfully. A true
|
||||
self-referential slice was also checked and remains correctly rejected.
|
||||
|
||||
**Expected behavior.** The
|
||||
[mapping source](../config.md#sources),
|
||||
[projection/ownership](../config.md#typed-projection-and-ownership), and
|
||||
[override](../config.md#explicit-cli-overrides) contracts permit supported
|
||||
acyclic values. Shared backing storage alone is not a cycle, and detaching it
|
||||
does not require preserving alias identity in the returned configuration.
|
||||
|
||||
**Potential remediation.** Include the visible slice extent (its length) in the
|
||||
active-visit identity, or use an equivalent identity that distinguishes these
|
||||
views. Preserve detection of actual self/mutual cycles, empty/nil distinctions,
|
||||
and independent ownership of retained values. Cover the shared helper's source,
|
||||
override, projection, and cloning callers rather than fixing only one entry point.
|
||||
|
||||
## 4. Callback Contexts Remain Active After Panic Unwinding
|
||||
|
||||
Status: open. Priority: low. Category: callback-lifetime contract.
|
||||
|
||||
**Relevant code.** `runResolution` in
|
||||
[resolution.go](../../internal/engine/resolution.go), lines 283–291, and
|
||||
`runValidation`/`reportVersion` in
|
||||
[validation.go](../../internal/engine/validation.go), lines 99–106 and 250–257,
|
||||
set `state.active = false` only after the application callback returns normally.
|
||||
The root facade forwards the context without an additional lifetime guard.
|
||||
|
||||
**Reproduction.** Retain the supplied context in a resolver, semantic validator,
|
||||
or version checker, then panic in that callback. Recover the application panic
|
||||
outside `Load` and invoke the retained context. Public-API probes showed that
|
||||
`Resolution.IsExplicit` still returns a value and `Validation.Warning` still
|
||||
accepts a report for both validation and version contexts; none produces the
|
||||
documented closed-context panic.
|
||||
|
||||
**Expected behavior.** The
|
||||
[resolution](../config.md#recorded-application-resolution) and
|
||||
[validation](../config.md#semantic-validation) contracts make these contexts
|
||||
callback-scoped and require retained contexts to reject use after callback exit.
|
||||
Application panics remain programming failures and should propagate unchanged;
|
||||
closing the context during unwinding does not require ConfigKit to recover them
|
||||
or return a partial result. This finding concerns only the lifetime guard after
|
||||
an application chooses to recover its own panic.
|
||||
|
||||
**Potential remediation.** Deactivate the context with a defer scoped to each
|
||||
callback invocation, retaining immediate deactivation on normal return as well
|
||||
as on panic unwinding. Do not leave the context active through later projection
|
||||
or metadata work, and do not convert or suppress the callback panic. Apply the
|
||||
same lifetime handling to resolution, semantic validation, and version checks.
|
||||
@@ -1,307 +0,0 @@
|
||||
# Dead Code And Obsolete Functionality Audit
|
||||
|
||||
Reviewed revision: `b1c278b38bead1fceeb80b99d2f336b0cb6fe2fd`.
|
||||
Audit date: 2026-10-25.
|
||||
|
||||
## Scope And Method
|
||||
|
||||
This audit covers the public facade, engine, document and YAML packages,
|
||||
consumer examples, and development/release entry points. It identifies private
|
||||
implementation cleanup, not public features to retire or new release gates.
|
||||
All findings below are open opportunities for further consideration.
|
||||
|
||||
Knowledge-graph discovery and caller tracing were supplemented by a temporary,
|
||||
type-aware reference inventory built outside the repository with the locally
|
||||
cached `golang.org/x/tools` v0.49.0. It distinguishes declarations, production
|
||||
references, test references, and direct field writes. Static inventories were
|
||||
run for Linux, Darwin, and Windows; only Linux tests were executed. A separate
|
||||
SSA/Rapid Type Analysis pass over test executables supplied additional leads.
|
||||
Neither absent graph edges nor an unreachable result from the selected test
|
||||
programs was treated as proof of dead library code. In particular, uninstantiated
|
||||
generic declarations and unexercised public APIs require caller/source review.
|
||||
|
||||
The standalone `deadcode`, `unused`, and `staticcheck` commands were not installed.
|
||||
Building the cached standalone `deadcode` command offline encountered an uncached
|
||||
telemetry dependency; the temporary analysis instead used cached packages/SSA/RTA
|
||||
libraries directly. Repository dependencies and tooling were not changed.
|
||||
|
||||
Candidates were checked for interface dispatch, reflection, whole-record use,
|
||||
map-key equality, build constraints, public consumers, and documented retention.
|
||||
The existing Linux suite and `go vet ./...` pass with Go 1.26.10. No benchmarks,
|
||||
new tests, or production changes were made.
|
||||
|
||||
## Architectural Assessment
|
||||
|
||||
The [implemented architecture](../internal/overview.md) remains coherent. The
|
||||
root owns the supported API and explicit conversions; `internal/engine` owns
|
||||
synchronous acquisition, composition, inheritance, decoding, CLI application,
|
||||
resolution, validation, and frozen inspection. `internal/document` owns the
|
||||
ordered tree, and `internal/yaml` owns parser/dumper integration. Ordinary and
|
||||
layered loading share one lifecycle.
|
||||
|
||||
Most findings are remnants beside that shared lifecycle: unused snapshots,
|
||||
private clone families disconnected from the facade, obsolete helper entry
|
||||
points, and bookkeeping whose results no longer reach an active consumer.
|
||||
No supported public feature or deliberate compatibility mechanism was established
|
||||
as obsolete. Existing correctness and resource findings remain owned by their
|
||||
separate audit documents.
|
||||
|
||||
## 1. Remove The Unconsumed Override-Result Pre-CLI Snapshot
|
||||
|
||||
Priority: medium. Scope: engine loading and override handoff.
|
||||
|
||||
**Relevant code.** `decodedOverrideResult.preCLI` and `applyDecodedOverrides`
|
||||
in [override_decode.go](../../internal/engine/override_decode.go), lines 9–18,
|
||||
33, and 79; `preparePostDecodeOverrideContext` in
|
||||
[override_context.go](../../internal/engine/override_context.go), lines 20–84.
|
||||
|
||||
**Evidence.** `applyDecodedOverrides` clones the complete `decoded.final` tree
|
||||
and returns it in `preCLI`. Type-aware references identify no production read
|
||||
of that particular field. Its readers are assertions in `override_test.go` and
|
||||
`override_context_test.go`. The production recipient instead independently clones
|
||||
`before.final` into `postDecodeOverrideContext.preCLI`.
|
||||
|
||||
This performs an extra traversal and allocation proportional to the decoded
|
||||
tree on successful ordinary and layered loads, including loads without CLI
|
||||
assignments. It does not supply the pre-CLI snapshot used by explanation.
|
||||
|
||||
**Potential cleanup.** Remove the unused result member and its clone, and
|
||||
update assertions tied to that member. Keep the independently owned pre-CLI
|
||||
state that actually feeds resolution/publication and explanation. This is not a
|
||||
proposal to share mutable trees or redesign the remaining ownership handoffs.
|
||||
|
||||
## 2. Retire The Unqueried Published Structural-Input Clone
|
||||
|
||||
Priority: medium. Scope: engine publication and immutable lookup.
|
||||
|
||||
**Relevant code.** `Inspection.structuralInput` in
|
||||
[load.go](../../internal/engine/load.go), line 96, and `publishLoadResult` in
|
||||
[load_result.go](../../internal/engine/load_result.go), lines 112, 119, and 131.
|
||||
Lookup ownership is in
|
||||
[document_lookup.go](../../internal/engine/document_lookup.go); active replay is
|
||||
in [explain.go](../../internal/engine/explain.go).
|
||||
|
||||
**Evidence.** Publication clones `resolved.structuralInput`, stores the clone
|
||||
on `Inspection`, and indexes it as an additional immutable tree. No production
|
||||
reader accesses `Inspection.structuralInput`; one private test populates it.
|
||||
Explanation replays source applications and inheritance operations, then uses
|
||||
`preCLI` and `input`. It does not query this separately cloned structural root.
|
||||
The lookup is addressed by a supplied node pointer, not by searching all indexed
|
||||
roots, so indexing the otherwise unreachable clone does not make it useful.
|
||||
Its mapping-node keys also keep the tree alive.
|
||||
|
||||
**Potential cleanup.** Remove the final publication clone, unused inspection
|
||||
member, and that clone's inclusion in `retainedTrees`. Preserve
|
||||
`resolved.structuralInput` where it is still used for path finalization and
|
||||
sensitivity classification before publication. Do not indiscriminately remove
|
||||
earlier structural evidence or active source/application history.
|
||||
|
||||
Coordinate this bounded removal with finding 2 in the
|
||||
[resource audit](resources.md): removing an unused tree does not by itself fix
|
||||
accounting for the other retained replay trees.
|
||||
|
||||
## 3. Remove The Facade's Disconnected Record-Clone Family
|
||||
|
||||
Priority: low. Scope: root facade, across the root/engine conversion boundary.
|
||||
|
||||
**Relevant code.** The private helper block in
|
||||
[records.go](../../records.go), lines 317–430:
|
||||
`cloneLocation`, `cloneLocations`, `cloneSourceInfo`, `cloneImportSelections`,
|
||||
`cloneSourceVersionCheck`, `cloneSourceInfos`, `cloneOrigin`, `cloneFieldInfo`,
|
||||
`cloneChange`, `cloneDiagnostic`, and `cloneDiagnostics`.
|
||||
|
||||
**Evidence.** None is reachable from a production facade entry point.
|
||||
`cloneSourceInfos`, `cloneFieldInfo`, `cloneChange`, and `cloneDiagnostics`
|
||||
have no references at all. Their supporting helpers refer to one another;
|
||||
the only external callers of this family are private `records_test.go` calls
|
||||
to `cloneSourceInfo`. Public results already acquire root-owned records through
|
||||
`fromEngineSourceInfo`, `fromEngineOrigin`, `fromEngineFieldInfo`,
|
||||
`fromEngineChange`, and diagnostic conversions in
|
||||
[conversion.go](../../conversion.go). The engine's separate clone helpers are
|
||||
active and are not removal candidates.
|
||||
|
||||
**Potential cleanup.** Delete the disconnected root helper family. Keep relevant
|
||||
conversion checks, and express ownership checks through repeated public record
|
||||
queries and mutation of returned nested data rather than testing an unused
|
||||
clone API. This complements the facade-test observations in the
|
||||
[testing audit](testing.md); it does not eliminate explicit conversions,
|
||||
root-owned types, or active `Path.clone` callers.
|
||||
|
||||
## 4. Remove Uncalled Engine Helper Remnants
|
||||
|
||||
Priority: low. Scope: individual engine helpers and facade transport.
|
||||
|
||||
The following definitions have no callers or function-value references in
|
||||
production or tests, across the inspected build configurations:
|
||||
|
||||
| Definition | Relevant code | Evidence and active replacement |
|
||||
| --- | --- | --- |
|
||||
| `mergeDisjointMappings` | [compose.go](../../internal/engine/compose.go), line 486 | Its only reference is its own recursion. Strict composition uses `mergeDisjointMappingsAtPath` and the shared recursive merge machinery. |
|
||||
| `mergeHistoryDocument` | [history.go](../../internal/engine/history.go), line 240 | No caller remains. Replay calls `mergeHistoryDocumentAtPath` directly with sequence evidence. |
|
||||
| `inheritanceDirectiveLocation` | [inheritance.go](../../internal/engine/inheritance.go), line 176 | No caller remains. Active preparation uses the directive entry and its location directly. |
|
||||
| `addSecretEvidencePath` | [secret.go](../../internal/engine/secret.go), line 137 | No caller remains. Classification obtains projected sensitivity paths from version evidence and feeds the active path accumulator. |
|
||||
| `PlacementModeFromFacade`, `PlacementModeForFacade` | [destination.go](../../internal/engine/destination.go), lines 23 and 26 | Neither is used by the facade. Input/options decorators perform the incoming conversion; `SourceInfoPlacementModeForFacade` supplies outgoing evidence. |
|
||||
|
||||
**Potential cleanup.** Delete these definitions and any imports/comments left
|
||||
solely for them, keeping their active counterparts. These are private functions
|
||||
or internal-package exports, not supported root API. The unused placement pair
|
||||
was already identified in finding 5 of the [complexity audit](complexity.md);
|
||||
this audit confirms that bounded removal without expanding its broader transport
|
||||
refactor.
|
||||
|
||||
## 5. Stop Constructing Unconsumed Combination Evidence
|
||||
|
||||
Priority: medium. Scope: sequence combination and inheritance bookkeeping.
|
||||
|
||||
**Relevant code and evidence.**
|
||||
|
||||
- `sequenceCombinationResult.discardedLower` in
|
||||
[sequence_combine.go](../../internal/engine/sequence_combine.go), lines 26
|
||||
and 72, is populated with a newly allocated list of every lower sequence
|
||||
index during replacement. It has no production reader; three test assertions
|
||||
inspect it. Overlay and inheritance owners already handle whole replacement
|
||||
from the selected operation and lower value. The result therefore allocates
|
||||
an unused `O(n)` index slice for an `n`-item lower sequence.
|
||||
- `inheritanceReplacement.path`, `.previous`, and `.effective` in
|
||||
[inheritance.go](../../internal/engine/inheritance.go), lines 135–141, are
|
||||
written by [inheritance_combine.go](../../internal/engine/inheritance_combine.go)
|
||||
and [inheritance_collection.go](../../internal/engine/inheritance_collection.go)
|
||||
but never read by production. Populating them performs path/origin copies
|
||||
and `displacedOrigins` subtree walks whose results are discarded. The active
|
||||
history path uses `inheritanceOperation`, its origin maps, and
|
||||
`projectedInheritanceChanges` in
|
||||
[inheritance_history.go](../../internal/engine/inheritance_history.go).
|
||||
The replacement's `before` and `after` trees, however, are read by retained-node
|
||||
accounting in [inheritance_finalize.go](../../internal/engine/inheritance_finalize.go)
|
||||
and [history.go](../../internal/engine/history.go).
|
||||
|
||||
**Potential cleanup.** Remove the unread members and computations exclusively
|
||||
feeding them. Preserve higher/lower item projections, replacement mappings,
|
||||
`appendedHigher`, active provenance/history, and replacement node accounting.
|
||||
Keep `sequenceIndexes` where append still uses it, and keep `displacedOrigins`
|
||||
where overlay processing needs it. Adjust private evidence assertions while
|
||||
retaining behavior-level replacement, removed-descendant, and history tests.
|
||||
This consolidates duplicate evidence ownership rather than removing inspection
|
||||
functionality or changing collection semantics.
|
||||
|
||||
## 6. Trim Write-Only Private Result And Transport Metadata
|
||||
|
||||
Priority: low. Scope: engine phase handoffs and private result shapes.
|
||||
|
||||
The following members are populated but have no production reader. Some are
|
||||
inspected by private tests; none is exposed as a root record or callback field.
|
||||
They add apparent responsibilities to result shapes that active consumers do not
|
||||
actually use:
|
||||
|
||||
| Private record and members | Relevant code and evidence |
|
||||
| --- | --- |
|
||||
| `collectionPolicyResolution.declarations`, `declarationsPresent`, `identityDeclarationPresent`, `applicationIdentityFields` | [collection_policy.go](../../internal/engine/collection_policy.go), lines 14–24. The resolver uses local normalized declarations/fields to compute the active policy; these returned copies/flags are not consumed. Preserve `modeDeclarationPresent` and `applicationIdentityPresent`, which are consumed. |
|
||||
| `inputPresence.null` | [decode.go](../../internal/engine/decode.go), line 25. Presence collection writes it, but current metadata null reporting uses the effective node's kind. The presence entry and its location remain active. |
|
||||
| `rootDirectiveExtraction.importsPresent`, `sequencesPresent` | [directives.go](../../internal/engine/directives.go), lines 25–26. Parsing sets them, but callers use the parsed declaration slices and diagnostics. |
|
||||
| `importSelection.outcome` | [import_selection.go](../../internal/engine/import_selection.go), line 29, and [glob.go](../../internal/engine/glob.go). Selectors set it, but traversal uses candidate lists and admitted-source counts. The separate `importSelectionEvidence.outcome` is consumed by public source-record conversion and must remain. |
|
||||
| `importDeclarationSpec.excludeSet` | [import_spec.go](../../internal/engine/import_spec.go), line 38. Parsing sets it; active policy resolution consumes `exclude`, not this flag. |
|
||||
| `schemaPath.field`, `dynamic` | [schema.go](../../internal/engine/schema.go), lines 335–339. Path resolution tracks and returns them, but callers consume only the descriptor and success result. |
|
||||
| `selectedOverlayRequest.filesystem` | [selected_overlay.go](../../internal/engine/selected_overlay.go), line 33. Callers populate it, but the loader uses its explicit filesystem-access argument. |
|
||||
| `sequenceDeclarationSpec.destinationLocation` | [sequence_declaration.go](../../internal/engine/sequence_declaration.go), line 17. The parser stores it, but later diagnostics use other retained declaration/field locations. |
|
||||
| `sourceVersionEvidence.absence`, `checked`; `sourceVersionAncestor.kind` | [source_version.go](../../internal/engine/source_version.go), lines 27–43. These annotations have no production consumers. Actual checking, version/presence/location evidence, and ancestor paths are consumed separately. |
|
||||
| `postDecodeOverrideContext.sources` | [override_context.go](../../internal/engine/override_context.go), line 14. The local source list is used to build resolution input, but returning it again in this member serves only tests. |
|
||||
|
||||
**Potential cleanup.** Remove these unused result slots and any bookkeeping
|
||||
whose sole purpose is filling them. Keep computations that validate or produce
|
||||
the active result, and keep public presence, null, selection, version, ownership,
|
||||
and diagnostic behavior unchanged. In particular, do not remove the source list
|
||||
used for callback input, public empty-selection evidence, declaration validation,
|
||||
or filesystem access. Rework assertions on inactive annotations to check the
|
||||
actual supported outcome where they protect a meaningful risk.
|
||||
|
||||
This is a bounded handoff cleanup, not a requirement to remove every field with
|
||||
no explicit selector read: map keys, embedded records, and interface contracts
|
||||
need separate treatment.
|
||||
|
||||
## 7. Consolidate The Test-Only Import Directive Parser
|
||||
|
||||
Priority: low. Scope: engine import parsing and test fixtures.
|
||||
|
||||
**Relevant code.** `parseImportSpecificationDirective` in
|
||||
[import_spec.go](../../internal/engine/import_spec.go), lines 183–201;
|
||||
`parseImportSpecsYAML` in
|
||||
[import_spec_test.go](../../internal/engine/import_spec_test.go); and
|
||||
`parseRootDirectiveBlock` in [directives.go](../../internal/engine/directives.go).
|
||||
|
||||
**Evidence.** The older parser has exactly one direct caller, the test fixture
|
||||
helper. That helper feeds many selector/declaration tests, but no supported load
|
||||
uses this parser. The active root parser owns the same mapping/field dispatch
|
||||
and delegates import declarations to the same `parseImportDeclarations` function,
|
||||
while also supporting the appropriate sequence-declaration context. This is a
|
||||
parallel directive-validation implementation, not merely a thin test adapter.
|
||||
|
||||
**Potential cleanup.** Have the fixture helper use the active root-directive
|
||||
parser with the appropriate context, or parse the import declaration list
|
||||
directly when that is the test's actual boundary. Remove the obsolete production
|
||||
parser after preserving relevant malformed-declaration and selector coverage.
|
||||
Do not retire the active imports-only context wholesale: layered version
|
||||
processing still uses it after extracting the outer directives.
|
||||
|
||||
## 8. Remove The Test-Only Eager Acquisition Mode
|
||||
|
||||
Priority: medium. Scope: engine acquisition. Previously recorded in finding 1
|
||||
of the [complexity audit](complexity.md); not a second independent defect.
|
||||
|
||||
**Relevant code.** `inputAcquisitionRequest.deferAssembly` in
|
||||
[acquisition.go](../../internal/engine/acquisition.go), and the final branch of
|
||||
`acquireImportedWithAccess` in
|
||||
[import_acquisition.go](../../internal/engine/import_acquisition.go), lines 206–224.
|
||||
|
||||
**Evidence.** Both production request construction sites, `executeLoadRequest`
|
||||
in [load.go](../../internal/engine/load.go) and `acquireUnderlayGroupScopes`
|
||||
in [load_request.go](../../internal/engine/load_request.go), set the flag to
|
||||
true. Only private test entry helpers choose the eager path. Its assembly call
|
||||
and alternate return protocol are therefore disconnected from supported loading.
|
||||
|
||||
**Potential cleanup.** Make acquisition consistently return retained scopes.
|
||||
Tests needing composition can explicitly invoke the active composition phase
|
||||
through a test helper. Preserve pending-item reservation, resource closure,
|
||||
accounting, diagnostics, and composition coverage. Thin test conveniences that
|
||||
delegate to active implementations are not generally dead functionality; the
|
||||
problem here is the alternate production phase protocol maintained solely for
|
||||
tests.
|
||||
|
||||
## Retained Functionality And Review Limits
|
||||
|
||||
- Public exports remain supported even when current in-repository programs do
|
||||
not call them. Discovery presets, `Metadata.HistoricalPaths`, generic APIs,
|
||||
diagnostic codes, and optional controls are not removal recommendations.
|
||||
- Heap methods, filesystem adapters, error/string/format methods, writer
|
||||
methods, reflection descriptors, callback bindings, and platform-specific
|
||||
implementations may be live without direct calls. They were not classified
|
||||
as dead on reference counts alone. Nonzero-size identity tokens and
|
||||
whole-struct map keys also have meaningful behavior without field reads.
|
||||
- `decodeInlineMapEntry` and import cycle diagnostics have real production
|
||||
callers despite gaps in current execution coverage. They remain necessary.
|
||||
- `Inspection.resolution` has no production selector reader, but the
|
||||
[recorded-resolution contract](../config.md#recorded-application-resolution)
|
||||
documents retaining each recorded before/after snapshot. This audit does not
|
||||
propose dropping that retention merely because explanation uses a coalesced
|
||||
replay view. Any separate retention redesign must respect that contract.
|
||||
- The retained inclusion graph, historical paths, sensitivity evidence, and
|
||||
passive contexts serve supported behavior. Deferred experiments in
|
||||
[future work](future.md#3-performance-experiments) are not obsolete features
|
||||
to remove. Neither are deliberate overlay/default/version semantics.
|
||||
- This audit establishes cleanup candidates, not measured performance gains or
|
||||
an exhaustive proof that all unsupported input states are unreachable.
|
||||
|
||||
## Validation
|
||||
|
||||
The following checks passed against unchanged production code:
|
||||
|
||||
```sh
|
||||
env PATH=/snap/go/current/bin:$PATH GOTOOLCHAIN=local GOTELEMETRY=off \
|
||||
GOPROXY=off GOCACHE=/tmp/configkit-review-cache-shared \
|
||||
go test ./... -count=1
|
||||
env PATH=/snap/go/current/bin:$PATH GOTOOLCHAIN=local GOTELEMETRY=off \
|
||||
GOPROXY=off GOCACHE=/tmp/configkit-review-cache-shared go vet ./...
|
||||
```
|
||||
|
||||
The audit document is additionally checked by the existing local documentation
|
||||
link test and whitespace checks. No production code, tests, dependencies,
|
||||
policies, public contracts, or release machinery are changed by this audit.
|
||||
@@ -1,245 +0,0 @@
|
||||
# Algorithmic Efficiency Audit
|
||||
|
||||
Reviewed revision: `5098b56655bd383e22a57d6cf09d99db3e92090f`.
|
||||
Audit date: 2026-10-25.
|
||||
|
||||
## Scope And Assessment
|
||||
|
||||
This source-level audit reviewed the public facade, acquisition and discovery,
|
||||
strict composition, precedence assembly, collection policy, inheritance, schema
|
||||
and typed-value operations, callbacks, secrets, inspection, and comparison.
|
||||
Knowledge-graph searches and caller traces guided source inspection; the bounds
|
||||
below follow from the actual loops and handoffs, not timing measurements.
|
||||
|
||||
The implementation already uses indexed mapping merges, tuple-indexed sequence
|
||||
matching, sparse item projections, scoped import adjacency, inheritance policy
|
||||
localization, and worklist sensitivity propagation. The findings are remaining
|
||||
batch-processing costs, not a recommendation to replace those mechanisms.
|
||||
|
||||
The review excludes expressly selected algorithms, including deterministic
|
||||
sorting, stable Kahn scheduling, exact numeric identity normalization, and the
|
||||
pairwise registration-overlap check expressly selected in the completed sequence
|
||||
plan at `d0a605a:docs/roadmap/implementation.md`. It also leaves the
|
||||
[deferred performance experiments](future.md#3-performance-experiments) deferred.
|
||||
Required detached copies and genuinely expanding configuration/history output
|
||||
are not treated as avoidable overhead.
|
||||
|
||||
Complexities describe the identified internal work, not an end-to-end runtime
|
||||
bound or a new consumer guarantee. Examples use bounded-depth paths and
|
||||
constant-sized records unless noted; hash-index alternatives use expected lookup
|
||||
costs, with string processing and actual copied payload accounted for separately.
|
||||
Existing resource limits bound realizable inputs but do not remove these growth
|
||||
patterns. No new limits, public caches, dependencies, or release gates are proposed.
|
||||
|
||||
No additional functional defect was established during this pass. The four open
|
||||
findings in the separate [functional correctness audit](correctness.md) remain
|
||||
applicable and are not duplicated here.
|
||||
|
||||
## 1. Policy Retirement Scans Every Collection For Every Replacement
|
||||
|
||||
Status: open. Priority: medium.
|
||||
|
||||
**Relevant code.** `collectionPolicyScope.retireCollectionPoliciesAtOrBelow` in
|
||||
[collection_policy_state.go](../../internal/engine/collection_policy_state.go),
|
||||
lines 163–174, scans the complete policy table. The replacement hook in
|
||||
`mergeOverlayMappingsWithCollectionPolicy`
|
||||
([overlay.go](../../internal/engine/overlay.go), lines 182–185) calls it for each
|
||||
ordinary replaced value. `applyOverlaySequenceEvidence` also calls it for
|
||||
whole-collection replacement.
|
||||
|
||||
**Scaling case.** A lower tier has P independently declared collection policies
|
||||
and Q ordinary scalar settings elsewhere. A higher tier changes those Q scalar
|
||||
settings without touching a collection. Each scalar replacement scans all P
|
||||
policies even though none is affected: O(P × Q) policy visits. Taking P = Q = N
|
||||
gives quadratic work for linear-sized inputs, effective values, and policy state.
|
||||
This occurs within one precedence merge; it does not depend on many tiers,
|
||||
registration-overlap checking, or expanding inheritance output.
|
||||
|
||||
**Potential refactoring.** Prepare an operation-local semantic path index over
|
||||
the policy table and use descendant queries for retirement, maintaining it as
|
||||
policies change. Alternatively, batch retirement against the old policy state
|
||||
where its timing can be preserved. For the disjoint example, preparation plus
|
||||
queries can be O(P + Q); generally charge additional work to affected entries
|
||||
and path lengths. Preserve explicit-mode persistence, record ownership, and the
|
||||
point at which old identity is retired. A delayed blanket retirement must not
|
||||
clear newly established higher-tier policy. Existing inheritance policy indexing
|
||||
provides a related mechanism to evaluate, not a requirement to unify its interface.
|
||||
|
||||
## 2. Small Tiers Recopy Unrelated Accumulated Collection Policy
|
||||
|
||||
Status: open. Priority: medium.
|
||||
|
||||
**Relevant code.** `resolveStrictCollectionPolicies` in
|
||||
[compose.go](../../internal/engine/compose.go), lines 330–334, first obtains
|
||||
`effectiveLower` through `lowerCollectionPoliciesForClaims`, then clones the
|
||||
result. The latter helper
|
||||
([collection_retirement.go](../../internal/engine/collection_retirement.go),
|
||||
lines 65–71) already deep-clones and scans the entire lower scope.
|
||||
`cloneCollectionPolicyScope` / `cloneCollectionPolicy` in
|
||||
[collection_policy_state.go](../../internal/engine/collection_policy_state.go)
|
||||
also copy record-order and nested record-policy state.
|
||||
|
||||
`assembleLayeredInput` in [load_request.go](../../internal/engine/load_request.go)
|
||||
supplies the accumulated lower policy when composing each underlay group and
|
||||
when applying that group to the accumulator. The overlay resolver repeats this
|
||||
whole-table preparation and additionally checks all retained policy destinations
|
||||
against the incoming tree (`overlay.go`, lines 145–150).
|
||||
|
||||
**Scaling case.** An initial underlay establishes P constant-sized collection
|
||||
policies. Each of T later underlays contributes only one unrelated scalar, with
|
||||
no declarations or collection changes. Despite having no relevant collection
|
||||
work, each tier copies/scans all P policies: O(T × P) work and cumulative
|
||||
allocation. P = T = N yields quadratic bookkeeping for O(P + T) input and final
|
||||
policy/value sizes. These are transient copies of unchanged private policy, not
|
||||
T separately published snapshots required by the public ownership contract.
|
||||
|
||||
**Potential refactoring.** Separate read-only lower-policy lookup from the owned
|
||||
policy changes produced by the current tier. Resolve only policies intersecting
|
||||
incoming claims/declarations, and apply those changes to the owned assembly
|
||||
state. A path index or localized view can avoid scanning unrelated entries;
|
||||
retain copies where state actually crosses a mutable ownership boundary. At
|
||||
minimum, avoid the immediate duplicate deep copy, but removing only that copy
|
||||
does not change the O(T × P) growth. Aim for work proportional to initial state,
|
||||
incoming material, and affected policy rather than the complete accumulated
|
||||
table per tier. Preserve pending declarations, replacement eligibility, and
|
||||
independent nested record-policy ownership.
|
||||
|
||||
This is distinct from finding 1: one tier can avoid repeated retirement scans
|
||||
and still recopy the full table at every subsequent tier. It is also distinct
|
||||
from the deferred metadata-copy/public-record handoff experiment.
|
||||
|
||||
## 3. Tier-History Projection Repeatedly Searches Wide Mappings
|
||||
|
||||
Status: open. Priority: medium.
|
||||
|
||||
**Relevant code.** `projectTierHistoryApplications` in
|
||||
[sequence_history_projection.go](../../internal/engine/sequence_history_projection.go),
|
||||
lines 17–30, calls unindexed `documentAtPath` for each mapped sequence in a source
|
||||
application. That helper delegates to `documentAtPathWithLookup` with no lookup;
|
||||
[document_walk.go](../../internal/engine/document_walk.go), lines 51–58, then
|
||||
linearly searches each mapping on the path.
|
||||
|
||||
**Scaling case.** A source has N sibling collections under `collections`, each
|
||||
with a constant number of records. A single wildcard registration can identify
|
||||
all of them. When this tier upserts/appends over lower collections, the source
|
||||
application contains N sequence contributions requiring projection. Locating
|
||||
each `/collections/<key>` searches the same N-entry mapping, costing
|
||||
1 + 2 + ... + N entry comparisons: O(N²), despite linear-sized source material
|
||||
and projection output. This does not require N application registrations.
|
||||
|
||||
**Potential refactoring.** Lazily build one read-only `documentLookup` for each
|
||||
original application value with active mapped contributions and reuse it, or
|
||||
collect the relevant sequence nodes in one traversal. With V input nodes, S
|
||||
contributions, maximum depth D, and I projected items, the lookup/projection
|
||||
portion can be O(V + S × D + I), rather than repeated wide scans. Preserve
|
||||
authored coordinates, noncontiguous item projections, replacement evidence,
|
||||
and independent output storage. This concerns load-time coordinate projection,
|
||||
not the deferred branch-local explanation-replay experiment.
|
||||
|
||||
## 4. Compound Identity Restoration Rescans Both Records Per Field
|
||||
|
||||
Status: open. Priority: medium.
|
||||
|
||||
**Relevant code.** `preserveInheritanceIdentityFields` in
|
||||
[inheritance_scope.go](../../internal/engine/inheritance_scope.go), lines 143–161,
|
||||
searches the child's mapping for each identity field, then searches the merged
|
||||
mapping again. `combineInheritanceTemplate` invokes it after merging the parent
|
||||
payload with the child in
|
||||
[inheritance_combine.go](../../internal/engine/inheritance_combine.go), line 104.
|
||||
|
||||
**Scaling case.** For K identity fields, C child entries, and M merged entries,
|
||||
the searches cost O(K × (C + M)), plus the required identity-value clones.
|
||||
A single parent/child relationship with K = C = M = N direct scalar identity
|
||||
fields performs quadratic comparisons for linear-sized records and identity
|
||||
metadata. There is no declared small bound on compound-identity width. The
|
||||
shared identity validator and parent-identity exclusion already use mapping or
|
||||
membership indexes; this restoration step does not.
|
||||
|
||||
**Potential refactoring.** Index merged entry positions once and walk child
|
||||
entries against an identity-field set, or use equivalent operation-local mapping
|
||||
indexes. This can be O(K + C + M), plus required copies. Preserve child-owned
|
||||
identity values and locations, existing mapping order, and detached nodes; do
|
||||
not change parent lookup or identity equality. If the step proves redundant
|
||||
after the established merge, removal needs a separate equivalence review rather
|
||||
than an assumption that identity preservation is unnecessary.
|
||||
|
||||
## 5. Secret Failure Reporting Repeats Unindexed Location Searches
|
||||
|
||||
Status: open. Priority: low; affects batches of failures.
|
||||
|
||||
**Relevant code.** `resolveSecretValue` reports each failed reference through
|
||||
`secretDiagnostic` in
|
||||
[secret_reference.go](../../internal/engine/secret_reference.go), lines 53–78 and
|
||||
112–117. That helper calls unindexed `nearestDocumentLocation`; the mapping
|
||||
branch of `nearestDocumentLocationWithLookup` in
|
||||
[validation.go](../../internal/engine/validation.go), lines 144–155, falls back
|
||||
to a linear search when no lookup is supplied.
|
||||
|
||||
**Scaling case.** An N-entry mapping of secret references whose environment
|
||||
values are all absent produces N diagnostics. Each location lookup starts at
|
||||
the root and scans the mapping for its key, yielding O(N²) comparisons for
|
||||
O(N) references and diagnostics. Reusing the same environment name still
|
||||
reproduces the lookup pattern even though environment lookup itself is cached.
|
||||
Deterministic traversal and diagnostic sorting add their ordinary O(N log N)
|
||||
costs; they do not require the quadratic location work.
|
||||
|
||||
**Potential refactoring.** Share a lazily initialized read-only `documentLookup`
|
||||
for the duration of secret resolution, using `nearestDocumentLocationWithLookup`
|
||||
for failures, or carry matching document/location state through traversal. For
|
||||
V input nodes and F failed references at depth D, attribution can be
|
||||
O(V + F × D), before existing diagnostic sorting. Keep the success path free
|
||||
of an eager index if it is unnecessary. Preserve all diagnostics, nearest-known
|
||||
ancestor fallback, source coordinates, and safe messages; failing fast instead
|
||||
would change behavior rather than optimize it.
|
||||
|
||||
## 6. Dynamic Values Repeat A Type-Graph Eligibility Walk
|
||||
|
||||
Status: open. Priority: low; most relevant to repeated dynamic container types.
|
||||
|
||||
**Relevant code.** `valueOperation.dynamicDescriptor` in
|
||||
[value_operation.go](../../internal/engine/value_operation.go), lines 36–48,
|
||||
uses the schema descriptor cache but still calls `descriptorContainsSecret`
|
||||
with a fresh visited map on every value. That helper (lines 51–68) traverses
|
||||
the reachable descriptor graph. Dynamic branches in projection and cloning
|
||||
invoke it for every non-nil interface value, before handling the concrete value.
|
||||
|
||||
**Scaling case.** Let N dynamic values have the same concrete pointer type whose
|
||||
descriptor graph has size S (nodes plus member/element edges). Each call rechecks
|
||||
the same graph, costing O(N × S), even after descriptor construction is cached.
|
||||
For example, typed defaults can supply N interface entries holding nil pointers
|
||||
to one wide, supported, secret-free struct type. Actual values and projected
|
||||
output contain only N nulls, while the struct has S fields. Taking N = S makes
|
||||
the repeated eligibility walk quadratic in the combined type/value description,
|
||||
without requiring quadratic value expansion.
|
||||
|
||||
**Potential refactoring.** Remember successfully approved dynamic descriptors
|
||||
by concrete type within `valueOperation`, after complete construction and the
|
||||
secret-semantics check. The repeated-type case becomes O(S + N) eligibility
|
||||
work, with one entry per approved concrete type. Do not treat a traversal-local
|
||||
visited marker as a completed negative result for a cyclic descriptor graph.
|
||||
Do not cache partial descriptors or path-bearing failures; coordinate with
|
||||
finding 2 of the [correctness audit](correctness.md), which identifies failed
|
||||
construction cache poisoning. Preserve rejection of dynamic secret-reference
|
||||
types, including nil pointers to them. This is operation-local reuse, not the
|
||||
deferred cross-load schema cache or a redesign of typed cloning.
|
||||
|
||||
## Validation And Recommended Order
|
||||
|
||||
Existing focused tests passed on Go 1.26.10, Linux amd64:
|
||||
|
||||
```sh
|
||||
go test ./internal/engine -run 'Collection|Sequence|Inheritance|Secret|Dynamic' -count=1
|
||||
go test . -run '^TestLocalDocumentationLinks$' -count=1
|
||||
git diff --check
|
||||
```
|
||||
|
||||
No benchmarks, timing comparisons, or new tests were needed to establish the
|
||||
loop bounds. Passing tests do not establish efficient growth. Production code
|
||||
and existing correctness findings are unchanged by this audit.
|
||||
|
||||
Consider findings 1 and 2 together when selecting a policy-state refactoring,
|
||||
while keeping their acceptance cases distinct. Findings 3 and 4 are narrower
|
||||
independent changes; findings 5 and 6 are lower-priority follow-ups. These are
|
||||
opportunities for consideration, not an implementation sequence or new release
|
||||
blockers. Any later refactoring should preserve the existing contracts and use
|
||||
focused behavioral coverage without adding performance thresholds.
|
||||
@@ -1,158 +0,0 @@
|
||||
# Error-Handling Audit
|
||||
|
||||
Reviewed revision: `5925066d35795b2dc1d31d069a1fb23024a62ab8`.
|
||||
Audit date: 2026-10-25.
|
||||
|
||||
## Scope And Architecture
|
||||
|
||||
The audit traced source construction and discovery, host/native filesystem
|
||||
acquisition, import selection, grouped composition, inheritance, typed decoding
|
||||
and codecs, application callbacks, secrets bootstrap, diagnostics, inspection,
|
||||
and rendering/diff failure paths. It reviewed error classification, propagation,
|
||||
partial state, exceptional cleanup, and the root facade's conversions against
|
||||
the [configuration contract](../config.md) and existing tests.
|
||||
|
||||
The [implemented architecture](../internal/overview.md) separates public wrappers
|
||||
from one synchronous private engine lifecycle. The document package provides the
|
||||
owned tree; the YAML adapter isolates parser/dumper failures. Engine loading
|
||||
collects safe structured diagnostics and returns a nil result on failure; the
|
||||
facade translates engine load errors into root-owned `LoadError` values. Secrets
|
||||
bootstrap is a separate operation with its own partial report and error type.
|
||||
Published inspections read frozen state rather than reloading input.
|
||||
|
||||
One new finding warrants remediation. Previously recorded exceptional-path
|
||||
defects are cross-referenced below rather than duplicated as new work.
|
||||
|
||||
## 1. Directory Read And Close Failures Can Be Misclassified As Absence
|
||||
|
||||
Status: open. Priority: medium. Category: filesystem/selection error propagation.
|
||||
|
||||
**Relevant code.** `filesystemAccess.readDirectory` in
|
||||
[filesystem_access.go](../../internal/engine/filesystem_access.go), lines 144–184,
|
||||
returns errors from opening a directory, reading its entries, and closing it
|
||||
through the same unqualified error result. `visitBoundedImportDirectory` in
|
||||
[directory_walk.go](../../internal/engine/directory_walk.go) forwards that error.
|
||||
Both `importDirectoryEntries` in
|
||||
[import_selection.go](../../internal/engine/import_selection.go), lines 295–306,
|
||||
and `readGlobEntries` in [glob.go](../../internal/engine/glob.go), lines 187–198,
|
||||
interpret any resulting `fs.ErrNotExist` as an absent directory and discard its
|
||||
entries without a diagnostic.
|
||||
|
||||
**Failure condition.** A directory has been successfully inspected and opened,
|
||||
but its `ReadDir` fails with an error wrapping `fs.ErrNotExist`, possibly together
|
||||
with entries already read. The same issue occurs if enumeration succeeds but
|
||||
`Close` returns that classification. A caller-supplied `fs.FS` can legitimately
|
||||
encounter such failures during its backing operations. The helper loses the
|
||||
distinction between an absent target at lookup/open and a failure after opening.
|
||||
|
||||
**Expected behavior.** Preserve the existing
|
||||
[absence and requiredness rules](../config.md#explicit-imports) for genuinely
|
||||
missing targets, while reporting a safe load failure when enumeration fails
|
||||
after opening. A close failure that the directory helper elects to report must
|
||||
not become an empty successful selection just because of its error identity.
|
||||
This follows the existing distinction between absence and failed acquisition;
|
||||
the regular-file helper in
|
||||
[source_file.go](../../internal/engine/source_file.go) already restricts its
|
||||
`missingTarget` flag to preflight/open failures rather than subsequent reads.
|
||||
|
||||
**Actual behavior and consequence.** The failed directory is treated as though
|
||||
it contributed no files. Optional loading can succeed with an incomplete
|
||||
configuration. Required directory/glob selection can also succeed if another
|
||||
directory supplies a match, since requiredness is checked against the surviving
|
||||
combined selection. If it was the only directory, the outcome is either a
|
||||
successful optional empty selection or a misleading `import.missing` error,
|
||||
rather than the acquisition failure.
|
||||
|
||||
**Evidence.** A standalone public-API diagnostic used a borrowed filesystem
|
||||
backed by `fstest.MapFS` with these files:
|
||||
|
||||
```text
|
||||
main.yml
|
||||
bad/b.yml # b: 2
|
||||
good/a.yml # a: 1
|
||||
```
|
||||
|
||||
The main input selected either `dir: [bad, good]` or `glob: '*/*.yml'`, with
|
||||
`required: true`. The filesystem kept metadata and file opens working and
|
||||
wrapped only the opened `bad` directory. Its wrapper returned an injected error
|
||||
either alongside its `ReadDir` entries or from `Close` after enumeration.
|
||||
|
||||
For both selectors and both failure phases, `fs.ErrNotExist` produced a
|
||||
successful load with `a=1, b=0`. Replacing only the injected error with
|
||||
`fs.ErrPermission` failed loading (`import.invalid` for directory search and
|
||||
`import.permission` for glob search). All eight small cases were executed; no
|
||||
repository test or production code was changed. The filesystem still contained
|
||||
the omitted file, so this was not a missing-target fixture.
|
||||
|
||||
**Potential remediation.** Preserve failure phase across the shared directory
|
||||
boundary, for example with a small private result/failure record distinguishing
|
||||
missing-on-open from read/close failure, analogous to `sourceReadFailure`.
|
||||
Keep the existing preflight and open-time missing-directory behavior, entry
|
||||
budgets, first-error precedence, and caller-owned filesystem lifetime. Map later
|
||||
failures to the existing safe traversal diagnostics without exposing raw backing
|
||||
error text. Review the standard `fs.ReadDir` fallback as well as the batched
|
||||
`fs.ReadDirFile` path. No retry policy, filesystem transaction, rollback service,
|
||||
or new restriction on supported filesystems is needed.
|
||||
|
||||
## Existing Findings Relevant To Error Handling
|
||||
|
||||
These remain open in their original owners; this audit creates no duplicate
|
||||
remediation requirement:
|
||||
|
||||
- [Correctness finding 1](correctness.md#1-pointer-only-recursive-types-can-overflow-the-stack-or-hang):
|
||||
pointer-only recursive descriptors can turn incompatible input or a helper
|
||||
query into stack exhaustion/nontermination instead of a safe failure.
|
||||
- [Correctness finding 2](correctness.md#2-failed-dynamic-schema-construction-leaves-a-reusable-partial-descriptor):
|
||||
failed dynamic descriptor construction leaves partial cache state; a later
|
||||
helper in the same callback can panic instead of returning the recorded load
|
||||
diagnostics. Error-state rollback belongs to that finding.
|
||||
- [Correctness finding 4](correctness.md#4-callback-contexts-remain-active-after-panic-unwinding)
|
||||
and [resource finding 3](resources.md#3-an-imported-version-check-panic-leaves-the-host-root-open):
|
||||
panic unwinding bypasses callback deactivation and imported host-root cleanup.
|
||||
Application panics should still propagate; neither finding requests recovery
|
||||
or publication of partial results.
|
||||
- [Resource findings 1 and 2](resources.md): oversized typed-container allocation
|
||||
can panic before a quota diagnostic, and incomplete history accounting can
|
||||
omit an established limit failure.
|
||||
|
||||
## Deliberate Behaviors Preserved
|
||||
|
||||
- Raw parser, reader, codec, filesystem, and returned callback error text is
|
||||
intentionally suppressed at the loading boundary. Stable codes, safe messages,
|
||||
semantic paths, and available locations provide context; adding raw error
|
||||
chains would conflict with the [safe-failure contract](../config.md#safe-failures).
|
||||
- Version/resolution callbacks that return an error without reporting one receive
|
||||
a generic hook-failed diagnostic. Warnings alone do not suppress that failure.
|
||||
Application callback panics remain programming failures.
|
||||
- Read-only regular-file close errors are explicitly ignored by the shared
|
||||
helper. Cleanup failures during an existing primary failure do not need to
|
||||
replace that primary failure. These choices are not findings by themselves.
|
||||
- Secrets bootstrap stages reads before writes and documents that an apply
|
||||
failure leaves earlier writes in place, reports the failed entry, and leaves
|
||||
later entries unapplied. That partial-state reporting is intentional, not a
|
||||
missing rollback guarantee.
|
||||
- Effective rendering, diagnostic rendering, explanation output, and bootstrap
|
||||
reports propagate writer failures, including short writes; partial output is
|
||||
permitted. Internal snapshot/diff serialization uses safe errors or redacted
|
||||
fallback snapshots rather than exposing internal serialization details.
|
||||
- ConfigKit owns no background cancellation, timeout, retry, or shutdown service.
|
||||
Synchronous application readers/callbacks can block; this audit does not invent
|
||||
a cancellation guarantee or move their resource ownership into ConfigKit.
|
||||
|
||||
## Validation
|
||||
|
||||
The following passed with Go 1.26.10 on Linux amd64, using cached dependencies
|
||||
with network/toolchain acquisition disabled:
|
||||
|
||||
```sh
|
||||
go test ./... -count=1
|
||||
go vet ./...
|
||||
go test ./internal/engine -run 'Failure|Failures|Error|Errors|Preflight|Propagates|HookOrder' -count=1
|
||||
go test ./internal/yaml -run 'Safe|Writer|Malformed' -count=1
|
||||
```
|
||||
|
||||
The standalone fault-injection diagnostic ran outside the repository. No
|
||||
benchmarks, new repository tests, production changes, or native macOS/Windows
|
||||
validation were performed. Passing existing tests does not cover the newly
|
||||
identified phase-classification case. This report adds no public contract,
|
||||
security hardening requirement, or release gate.
|
||||
@@ -1,189 +0,0 @@
|
||||
# Resource Management Audit
|
||||
|
||||
Reviewed revision: `0cca633a67abd3d0fdcb7db6e83260dcaf1eaac8`.
|
||||
Audit date: 2026-10-25.
|
||||
|
||||
## Scope And Architecture
|
||||
|
||||
The audit covered input snapshots and readers, discovery, filesystem acquisition,
|
||||
imports and selected overlays, typed projection and cloning, composition and
|
||||
inheritance, callback teardown, retained inspection history, rendering/diff, and
|
||||
secrets bootstrap. Knowledge-graph discovery and caller tracing were supplemented
|
||||
by source inspection, existing tests, and small standalone diagnostics outside
|
||||
the repository. No benchmarks or large-memory stress tests were conducted.
|
||||
|
||||
The [implemented architecture](../internal/overview.md) has a mostly clear
|
||||
resource-ownership model:
|
||||
|
||||
- The public facade delegates to a synchronous engine lifecycle, with private
|
||||
document and YAML packages. Loading creates no library-owned background
|
||||
goroutines, timers, network connections, or shutdown service.
|
||||
- Ordinary file reads close owned handles, including read/stat failures. Host
|
||||
import and overlay acquisition own their root handles; caller-supplied readers
|
||||
and filesystems remain borrowed.
|
||||
- Published inspection retains immutable documents, history, indexes, and passive
|
||||
resource contexts. A later explicit resource open transfers ownership of that
|
||||
returned file to the caller; publication does not normally retain acquisition
|
||||
handles.
|
||||
- Retained history and detached query results are intentional ownership choices,
|
||||
not leaks by themselves. The findings below concern enforcing existing limits
|
||||
and closing owned resources, rather than removing that functionality.
|
||||
|
||||
Three new findings warrant remediation. All remain open.
|
||||
|
||||
## 1. Typed Containers Allocate Before Their Node Budget Is Enforced
|
||||
|
||||
Priority: medium. Category: peak memory and failure handling.
|
||||
|
||||
**Relevant code.** `projectSequence` and `projectMap` in
|
||||
[projection.go](../../internal/engine/projection.go), `valueOperation.charge` in
|
||||
[value_operation.go](../../internal/engine/value_operation.go), and the defaults
|
||||
projection in [decode.go](../../internal/engine/decode.go).
|
||||
|
||||
**Circumstances.** Sequence projection reserves `value.Len()` document pointers
|
||||
before visiting any children. Map projection similarly reserves the complete
|
||||
entry array and obtains all map keys before charging individual entries. The
|
||||
existing node limit therefore rejects an oversized typed value only after a
|
||||
potentially much larger allocation has already occurred. Defaults and values
|
||||
returned by application resolution can reach these paths.
|
||||
|
||||
**Evidence.** A standalone public-API diagnostic loaded `NoSource()` with defaults
|
||||
containing an `Items []struct{}` field initialized with
|
||||
`make([]struct{}, int(^uint(0)>>1))`. Zero-sized elements make the input slice
|
||||
inexpensive, but projection immediately panicked with
|
||||
`runtime error: makeslice: cap out of range`. It did not return the existing
|
||||
`schema.projection_limit` diagnostic. No enormous backing array was successfully
|
||||
allocated by this diagnostic.
|
||||
|
||||
**Consequence.** Less extreme oversized containers can cause excessive temporary
|
||||
memory allocation before rejection; sufficiently large lengths panic or exhaust
|
||||
memory instead of reaching the intended limit failure. This is a library-created
|
||||
allocation, distinct from memory an application has already allocated itself.
|
||||
|
||||
**Potential remediation.** Before bulk reservations, compare the known minimum
|
||||
node cost of the container against the operation's remaining existing allowance,
|
||||
using overflow-safe arithmetic. Alternatively, bound initial capacity and grow
|
||||
only as successfully charged elements are accepted. Review the analogous map
|
||||
reservation/key collection. Preserve current node/depth semantics, inline-field
|
||||
behavior, and useful diagnostic paths; do not introduce an unrelated container
|
||||
length cap or promise a universal heap-size bound.
|
||||
|
||||
## 2. Retained-History Accounting Omits Published Replay Trees
|
||||
|
||||
Priority: medium. Category: retained memory and lifecycle integration.
|
||||
|
||||
**Relevant code.** The history check in `executeLoadRequest` in
|
||||
[load.go](../../internal/engine/load.go), `historyNodesWithin` in
|
||||
[history.go](../../internal/engine/history.go), `preparePostDecodeOverrideContext`
|
||||
in [override_context.go](../../internal/engine/override_context.go), and
|
||||
`resolveLoadInput` / `publishLoadResult` in
|
||||
[load_result.go](../../internal/engine/load_result.go).
|
||||
|
||||
**Expected behavior.** The
|
||||
[retained-history contract](../config.md#historical-value-explanation) limits retained
|
||||
history to 4,000,000 distinct document nodes, counting shared nodes once and
|
||||
reporting `explain.limit_exceeded` when exceeded.
|
||||
|
||||
**Actual behavior.** The load check visits the original decoded baseline and
|
||||
pre-CLI final tree, the resolved final tree, application trees, resolution deltas,
|
||||
and the acquisition inheritance scope. Publication retains a different root set:
|
||||
it includes a separately cloned post-CLI decoded tree as inspection input, plus
|
||||
independent `structuralInput` and `preCLI` replay snapshots. The replay snapshots
|
||||
are cloned again during publication and included in its immutable lookup. They
|
||||
are not passed to the budget check. Inheritance operation copies are also made
|
||||
after that check. Counting the earlier root set does not bound the distinct
|
||||
nodes actually kept alive by the result.
|
||||
|
||||
**Evidence.** A successful public load of `items: [1, 2]`, decoded into
|
||||
`struct { Items []int }` with a no-op resolver, was inspected by a read-only
|
||||
standalone reflection diagnostic. Its baseline/input/final/application roots
|
||||
contained 14 distinct nodes; including the two published replay roots yielded
|
||||
22. The checkpoint uses a different decoded-final instance of the same size in
|
||||
this example. Source inspection establishes that its count is also 14.
|
||||
|
||||
For this fixture generalized to N scalar items, the checkpoint counts `3N + 8`
|
||||
nodes, while the published roots retain `5N + 12`. Thus 800,000 items would pass
|
||||
the history checkpoint with 2,400,008 nodes yet retain 4,000,012. Such a source
|
||||
also fits the existing per-source byte and node allowances. This larger case is
|
||||
a structural derivation, not an executed allocation test.
|
||||
|
||||
**Consequence.** Successful loads can exceed the established retained-history
|
||||
limit, with additional retained lookup/index overhead. The quota currently gives
|
||||
an incomplete account of the memory-owning snapshot graph.
|
||||
|
||||
**Potential remediation.** Apply one pointer-aware accounting operation to the
|
||||
complete set of document roots actually retained at publication, including replay
|
||||
snapshots and copied inheritance history. Preserve count-once semantics for
|
||||
shared nodes. Where practical, charge or reserve these copies before creating
|
||||
them so failure does not first incur avoidable peak allocation. Reusing an
|
||||
already-owned immutable snapshot can be considered where equivalent, but this
|
||||
finding does not require the broader metadata-copy redesign deferred in
|
||||
[future experiments](future.md#3-performance-experiments), weaker detachment, a
|
||||
smaller limit, or removal of historical inspection.
|
||||
|
||||
## 3. An Imported Version-Check Panic Leaves The Host Root Open
|
||||
|
||||
Priority: medium. Category: file-descriptor cleanup during unwinding.
|
||||
|
||||
**Relevant code.** `acquireImportedInput` / `acquireImportedWithAccess` and imported
|
||||
version processing in
|
||||
[import_acquisition.go](../../internal/engine/import_acquisition.go), together with
|
||||
`openHostAccess` / `filesystemAccess.close` in
|
||||
[filesystem_access.go](../../internal/engine/filesystem_access.go). Compare the
|
||||
deferred fallback cleanup in
|
||||
[selected_overlay.go](../../internal/engine/selected_overlay.go) and deferred file
|
||||
cleanup in [source_file.go](../../internal/engine/source_file.go).
|
||||
|
||||
**Circumstances.** Host import acquisition opens an `os.Root`, then closes it
|
||||
explicitly on ordinary failure paths and after import traversal. It has no
|
||||
deferred fallback closure. A user version-check callback runs for imported
|
||||
sources while that root is open. If it panics and the application recovers outside
|
||||
`Load`, unwinding bypasses all those explicit root closes. The imported file's
|
||||
own deferred close still runs; the outstanding resource is the directory/root
|
||||
handle.
|
||||
|
||||
**Evidence.** A standalone Linux diagnostic created a temporary main file and one
|
||||
import, both with a version, enabled source-version checks, and panicked only on
|
||||
the imported source's check. With automatic GC disabled only in that disposable
|
||||
diagnostic process, the number of `/proc/self/fd` entries targeting the temporary
|
||||
root went from zero to one after external recovery. The non-panicking control
|
||||
ran both checks and returned to zero. One outstanding root was sufficient to
|
||||
demonstrate the issue; no descriptor-exhaustion workload was run.
|
||||
|
||||
**Consequence.** Library-owned root cleanup depends on eventual runtime cleanup
|
||||
instead of load-scope unwinding. Repeated recovered callback failures can retain
|
||||
descriptors long enough to exhaust them. This does not imply that ConfigKit must
|
||||
recover application panics or successfully return a configuration after one.
|
||||
|
||||
**Potential remediation.** Install a deferred fallback close at the owning
|
||||
acquisition boundary, while preserving normal explicit close timing and close
|
||||
error diagnostics, as the selected-overlay path already does. Avoid double-close
|
||||
confusion and leave borrowed native filesystems untouched. Preserve panic
|
||||
propagation. This is separate from
|
||||
[correctness finding 4](correctness.md#4-callback-contexts-remain-active-after-panic-unwinding):
|
||||
deactivating a callback context alone does not close the root, and closing the
|
||||
root alone does not deactivate that context.
|
||||
|
||||
## Validation And Boundaries
|
||||
|
||||
The following passed with Go 1.26.10 on Linux amd64, using cached dependencies
|
||||
with automatic toolchain/network acquisition disabled:
|
||||
|
||||
```sh
|
||||
go test ./internal/engine -run 'Closes|Close|Budget|Limits|Limit|SecretsDir' -count=1
|
||||
go test ./... -count=1
|
||||
```
|
||||
|
||||
The three standalone diagnostics described above were run outside the repository;
|
||||
they added no production code or repository tests. The history diagnostic only
|
||||
read private fields to count pointers; it did not mutate inspection state. No
|
||||
native macOS or Windows checks were performed.
|
||||
|
||||
No additional network, timer, goroutine, buffer-pool, or ordinary-return handle
|
||||
leak was established. Borrowed blocking readers/callbacks do not create a new
|
||||
cancellation guarantee. Previously reported recursive-schema stack exhaustion
|
||||
and callback-state retention remain owned by the
|
||||
[correctness audit](correctness.md), rather than duplicated here. Existing
|
||||
algorithmic and maintainability findings remain owned by their respective
|
||||
audits. This report adds no API, release gate, new resource quota, or background
|
||||
management requirement.
|
||||
@@ -1,194 +0,0 @@
|
||||
# Security Audit
|
||||
|
||||
Reviewed revision: `b30c9f167dba16a9192d9bfde4aeb2b9c597ce0e`.
|
||||
Audit date: 2026-10-25.
|
||||
|
||||
## Scope And Trust Model
|
||||
|
||||
This review examined input validation and budgets, import/discovery containment,
|
||||
link resolution, collection authority, application callbacks, secret references
|
||||
and bootstrap, historical sensitivity, diagnostics, effective rendering and
|
||||
diffs, and the runtime/development dependency boundary. Knowledge-graph searches
|
||||
and caller traces were supplemented by source inspection, existing tests, a
|
||||
bounded standalone diagnostic, and an advisory-database spot-check.
|
||||
|
||||
The [architecture](../policy/architecture.md) and
|
||||
[configuration contract](../config.md) establish these boundaries:
|
||||
|
||||
- ConfigKit is a synchronous startup library, not a network service or an
|
||||
authentication/authorization framework. Applications select inputs, roots,
|
||||
filesystem implementations, callbacks, and credential use. Applications own
|
||||
remote acquisition and authentication of that data.
|
||||
- The public facade delegates to a private engine and private document/YAML
|
||||
packages. Input composition and inspection do not execute shell commands or
|
||||
launch a background service. Ordinary loading does not change the process
|
||||
environment; explicit secrets-directory bootstrap is the narrow exception.
|
||||
- Host imports use canonical containment checks and owned rooted access under
|
||||
the documented stable-input assumption. Borrowed native filesystems retain
|
||||
their own behavior and are explicitly not a general sandbox guarantee.
|
||||
- Secret references resolve after composition and application resolution. The
|
||||
trusted returned configuration can expose credentials through `Value()`;
|
||||
inspection retains names rather than credentials. Tags, a path predicate,
|
||||
inheritance, and recorded dependencies govern redaction of other values.
|
||||
Application-supplied messages and unrecorded secret transformations remain
|
||||
application responsibilities.
|
||||
|
||||
One new availability finding warrants remediation. No new credential disclosure,
|
||||
command injection, application-authority bypass, or host containment escape was
|
||||
established. This is a source-level audit with bounded checks, not a certification
|
||||
that every input, dependency, platform, or deployment is secure.
|
||||
|
||||
## 1. Finite Symlink Reuse Can Cause Exponential Import-Resolution Work
|
||||
|
||||
Status: open. Priority: medium. Category: availability / input amplification.
|
||||
|
||||
**Relevant code.** `resolveHostImportPath` and `resolveNativeImportPath` in
|
||||
[filesystem_links.go](../../internal/engine/filesystem_links.go), lines 129–242,
|
||||
expand link-target components with a frame stack and track only currently active
|
||||
links. Completion removes a link from that set; a later use resolves its entire
|
||||
target again. No completed-target result is reused.
|
||||
|
||||
`importEntryTarget` invokes these resolvers for discovered links. Both
|
||||
[directory selection](../../internal/engine/import_selection.go) and
|
||||
[glob selection](../../internal/engine/glob.go) reach it. Directory selection
|
||||
resolves the target before deciding whether recursive descent is enabled, so
|
||||
`recursive: false` does not avoid this work. Native resolution is used when the
|
||||
borrowed filesystem provides `fs.ReadLinkFS`; host resolution uses the analogous
|
||||
rooted implementation.
|
||||
|
||||
**Plausible scenario.** An application loads a configuration tree whose imported
|
||||
assets can be supplied by a less-trusted user or configuration provider. That
|
||||
provider controls link entries inside an allowed import directory. The
|
||||
application's own main file need only select that directory with link following
|
||||
enabled, which is the current default. No concurrent filesystem mutation,
|
||||
outside-root access, executable callback, or malicious filesystem implementation
|
||||
is required. This is conditional on influence over imported filesystem data;
|
||||
it is not an anonymous remote vulnerability in ConfigKit by itself.
|
||||
|
||||
Inside an ordinary `links` directory, create this finite graph:
|
||||
|
||||
```text
|
||||
s00 -> .
|
||||
s01 -> s00/s00
|
||||
s02 -> s01/s01
|
||||
s03 -> s02/s02
|
||||
...
|
||||
```
|
||||
|
||||
Each link resolves to the same contained directory. It has no active link cycle:
|
||||
the first reference to a lower link finishes before the second begins. Resolving
|
||||
level N nevertheless repeats the level N-1 expansion twice, giving a recurrence
|
||||
of `T(N) = 2T(N-1) + O(1)` component work for this fixed-name fixture. Directory
|
||||
enumeration contains only N+1 entries, and no imported configuration nodes or
|
||||
new import edges account for those repeated expansions. Consequently, source,
|
||||
entry, input-node, and active-import-depth budgets do not bound this work by the
|
||||
size of the selected graph. This is repeated resolution of a compact graph, not
|
||||
genuinely expanding configuration output or ordinary deterministic sorting.
|
||||
|
||||
**Evidence.** A standalone public-API diagnostic created real temporary symlinks
|
||||
and exposed them through `NewFilesystem` backed by `os.DirFS`. A thin
|
||||
`fs.ReadLinkFS` wrapper counted metadata/link operations and imposed a diagnostic
|
||||
ceiling of 12,000 `Lstat` calls. The main input selected `dir: links` with link
|
||||
following enabled and default nonrecursive discovery. Successful loads produced
|
||||
these counts:
|
||||
|
||||
| Link entries | `Lstat` calls | `ReadLink` calls |
|
||||
| --- | ---: | ---: |
|
||||
| 3 | 32 | 11 |
|
||||
| 5 | 128 | 57 |
|
||||
| 7 | 512 | 247 |
|
||||
| 9 | 2,048 | 1,013 |
|
||||
| 11 | 8,192 | 4,083 |
|
||||
|
||||
A 13-entry fixture reached the diagnostic ceiling and returned a safe load
|
||||
failure when the wrapper stopped it. The same fixture with `follow: false`
|
||||
completed with 17 `Lstat` calls and zero `ReadLink` calls. The operation counts
|
||||
substantiate amplification in the native resolver; the host resolver's matching
|
||||
frame-expansion logic was verified by source inspection and caller tracing,
|
||||
not a separate host operation-count test. No timings, large attack graph, or
|
||||
external-system exploitation were used.
|
||||
|
||||
**Impact.** A small imported asset tree can monopolize startup/load execution for
|
||||
an impractically long period. Applications that expose configuration validation
|
||||
or repeated loading to less-trusted providers can also tie up their own workers.
|
||||
The normal trusted-operator-only deployment reduces the adversarial exposure,
|
||||
but accidental alias graphs can cause the same availability failure.
|
||||
|
||||
**Potential remediation.** Reuse fully resolved link-target results within the
|
||||
resolution operation, keyed by the appropriate rooted namespace and full link
|
||||
path, while retaining active-path cycle detection and containment checks.
|
||||
Equivalent dependency-based evaluation is another option. Preserve legitimate
|
||||
finite reuse, relative/absolute host-link semantics, and the stable-input model;
|
||||
do not replace the active set with a global "already visited means cycle" rule.
|
||||
Review both resolvers and directory/glob entry points. The objective is to avoid
|
||||
re-expanding completed dependencies, not to introduce a public cache or reject
|
||||
valid graphs with an arbitrary link-count cap. Consumers can already opt out of
|
||||
following discovered links where appropriate; changing that default is not part
|
||||
of this recommendation.
|
||||
|
||||
## Previously Reported Risks
|
||||
|
||||
The [correctness audit](correctness.md) already records pointer-only recursive
|
||||
schema nontermination, failed dynamic-descriptor cache state, and callback guards
|
||||
left active during panic unwinding. The [resource audit](resources.md) owns
|
||||
pre-budget typed-container allocation, incomplete retained-history accounting,
|
||||
and an import-root cleanup gap after callback panic. These can affect availability
|
||||
when their documented preconditions hold; they are not newly discovered remote
|
||||
exploits or duplicate remediation tasks here.
|
||||
|
||||
The [error-handling audit](error-handling.md) separately owns silently omitted
|
||||
directory contributions after certain enumeration/close failures. The
|
||||
[efficiency audit](efficiency.md) owns previously identified avoidable batch costs.
|
||||
This review does not reclassify every expensive operation or application
|
||||
programming error as a security vulnerability.
|
||||
|
||||
## Dependency Spot-Check
|
||||
|
||||
The ordinary package's non-standard-library dependency graph contains only
|
||||
`go.yaml.in/yaml/v4 v4.0.0-rc.6`; ReleaseKit, Goldmark, and `x/mod` are maintainer
|
||||
tool dependencies rather than ConfigKit runtime imports. Cached module integrity
|
||||
verification passed.
|
||||
|
||||
The current [Go vulnerability database module index](https://vuln.go.dev/index/modules.json)
|
||||
contained no entries for the selected YAML v4, ReleaseKit, or Goldmark v2 module
|
||||
paths. Its two `golang.org/x/mod` reports,
|
||||
[GO-2026-6179](https://pkg.go.dev/vuln/GO-2026-6179) and
|
||||
[GO-2026-6180](https://pkg.go.dev/vuln/GO-2026-6180), identify v0.40.0 as fixed,
|
||||
which is the version selected here. The related toolchain fixes also precede the
|
||||
Go 1.26.10 toolchain used for this audit. The database metadata reported a modified
|
||||
time of `2026-10-21T00:27:29Z` when checked.
|
||||
|
||||
This was a module-path/advisory spot-check, not a complete standard-library,
|
||||
toolchain, transitive-reachability, or supply-chain attestation. `govulncheck`,
|
||||
`gosec`, and `gitleaks` were not installed; no scanners were added to the project.
|
||||
Absence of an advisory is not proof of absence of vulnerabilities, and
|
||||
`go mod verify` does not audit dependency behavior or establish that upstream
|
||||
content is safe.
|
||||
The [database API documentation](https://go.dev/doc/security/vuln/database)
|
||||
describes the advisory source used for this check.
|
||||
|
||||
## Validation And Preserved Boundaries
|
||||
|
||||
The following passed with Go 1.26.10 on Linux amd64 using cached dependencies and
|
||||
disabled automatic dependency/toolchain acquisition:
|
||||
|
||||
```sh
|
||||
go test -race ./... -count=1
|
||||
go test ./internal/engine -run 'Secret|Sensitive|Sensitivity|Contain|Escap|Outside|Symlink|Nonregular|Budget|Limit|Diagnostic' -count=1
|
||||
go vet ./...
|
||||
go mod verify
|
||||
```
|
||||
|
||||
These checks include existing canary-based non-disclosure, historical and
|
||||
bilateral diff sensitivity, safe diagnostic, parser-policy, containment, and
|
||||
nonregular-file cases. The bounded link diagnostic ran outside the repository.
|
||||
No production code or repository tests were added or changed; no native
|
||||
macOS/Windows run, active external exploitation, or exhaustive fuzzing was done.
|
||||
|
||||
This report does not propose authentication in the library, arbitrary environment
|
||||
name restrictions, secret-file permission requirements, retries, memory erasure,
|
||||
or protection against privileged concurrent filesystem mutation. Those would
|
||||
need their own concrete requirement and threat analysis. It preserves borrowed
|
||||
filesystem ownership, application-owned safe callback messages, public secret
|
||||
reference names, explicit partial bootstrap semantics, and the current release
|
||||
gates.
|
||||
@@ -1,281 +0,0 @@
|
||||
# Test Coverage And Effectiveness Audit
|
||||
|
||||
Reviewed revision: `eb5a82f1f3a3286506c2d527e7980db7ccae5398`.
|
||||
Audit date: 2026-10-25.
|
||||
|
||||
## Assessment And Architecture
|
||||
|
||||
The suite broadly follows the [testing policy](../policy/testing.md): real
|
||||
parsing, composition, decoding, and filesystem fixtures dominate; narrow doubles
|
||||
control I/O and environment failures. Engine tests own mechanisms and semantics,
|
||||
root tests protect public conversions and integration, and maintained consumers
|
||||
exercise representative workflows. The private document tree and YAML adapter
|
||||
support the synchronous engine behind the root-owned public facade; see the
|
||||
[component overview](../internal/overview.md).
|
||||
|
||||
Strengths include presence/default/zero distinctions, strict composition versus
|
||||
precedence, collection policy, inheritance/history agreement, safe rendering and
|
||||
bilateral diff sensitivity, independent loads, reader claims, callback ordering,
|
||||
bootstrap partial failures, and realistic source/containment behavior. Parser and
|
||||
path fuzz targets have deterministic seeds in the ordinary suite. Architecture,
|
||||
documentation, and development-check tests protect explicit repository contracts.
|
||||
|
||||
Six targeted findings follow: four coverage/assertion improvements and two areas
|
||||
for removal or consolidation. They do not justify a wholesale test purge, a
|
||||
percentage target, or another test for every private helper. No new production
|
||||
defect was established during this pass; the existing audits own their findings.
|
||||
|
||||
## Coverage Evidence
|
||||
|
||||
On Go 1.26.10, Linux amd64, the ordinary suite listed 771 `Test` functions, three
|
||||
fuzz targets, and 29 executable examples. These counts exclude Windows-only
|
||||
compiled tests and do not count table cases as separate test functions.
|
||||
|
||||
Cross-package coverage, aggregated by source block across all test binaries, was:
|
||||
|
||||
| Package | Covered statements | Coverage |
|
||||
| --- | ---: | ---: |
|
||||
| Root public package | 348 / 428 | 81.3% |
|
||||
| `internal/engine` | 9,089 / 9,987 | 91.0% |
|
||||
| `internal/document` | 13 / 13 | 100.0% |
|
||||
| `internal/yaml` | 151 / 168 | 89.9% |
|
||||
| Maintained consumer examples | 259 / 327 | 79.2% |
|
||||
| Total | 9,860 / 10,923 | 90.3% |
|
||||
|
||||
The document package has no standalone tests, but its code is covered through
|
||||
real collaborators. The per-test-binary percentages printed by `-coverpkg=./...`
|
||||
have a different denominator and must not be mistaken for these aggregate
|
||||
package percentages. Statement coverage measures execution, not assertion
|
||||
strength or state-space coverage: the current suite passes despite the defects
|
||||
already recorded in the correctness, resource, error-handling, and security audits.
|
||||
|
||||
Some zero-coverage private functions have no production caller; trivial public
|
||||
preset forwards are also unexecuted. Neither observation alone warrants adding
|
||||
tests. Prioritize the behavioral risks below over filling those percentages.
|
||||
|
||||
## 1. Confirmed Exceptional Cases Lack Durable Regression Coverage
|
||||
|
||||
Status: open. Priority: medium. Category: gaps in state transitions and boundaries.
|
||||
|
||||
The earlier audits reproduced defects outside the checked-in suite. Relevant
|
||||
tests exercise nearby ordinary cases but do not yet protect these transitions:
|
||||
|
||||
- **Schema and dynamic-value failure state.**
|
||||
[schema_test.go](../../internal/engine/schema_test.go) covers ordinary recursive
|
||||
structs; [projection_test.go](../../internal/engine/projection_test.go) checks
|
||||
independent invalid values and cycles. Neither covers pointer-only recursive
|
||||
descriptors, acyclic slice views sharing a starting pointer, or a second
|
||||
dynamic/helper operation after a failed descriptor build in the same load.
|
||||
Add the narrowly scoped regressions described by
|
||||
[correctness findings 1–3](correctness.md), retaining null/acyclic success cases
|
||||
and asserting safe classification and termination. Avoid an unbounded
|
||||
stack-overflow/hang fixture in the default test process.
|
||||
- **Exceptional callback exit.** The retained-context tests in
|
||||
[resolution_test.go](../../internal/engine/resolution_test.go) and
|
||||
[facade_context_test.go](../../facade_context_test.go) verify normal callback
|
||||
return. File-close tests cover ordinary load failures. They do not exercise
|
||||
external recovery after version/resolution/validation callback panic or an
|
||||
imported version check while a host root is owned. Extend the existing owners
|
||||
when fixing [correctness finding 4](correctness.md#4-callback-contexts-remain-active-after-panic-unwinding)
|
||||
and [resource finding 3](resources.md#3-an-imported-version-check-panic-leaves-the-host-root-open).
|
||||
Preserve propagation of the original panic and verify closure of the callback
|
||||
state and the actually owned root independently; a native file-close counter
|
||||
alone cannot verify an `os.Root` lifetime.
|
||||
- **Budgets before allocation and through publication.**
|
||||
`TestProjectionRejectsNonFiniteLimitsAndCodecFailuresSafely` checks a small
|
||||
scalar tree against supplied limits. `TestHistoryNodeBudgetCountsSharedTreesOnce`
|
||||
and the inheritance-history budget tests verify the accounting helper with
|
||||
explicitly supplied roots. They cannot detect a container reservation before
|
||||
charging, or roots omitted by the publication caller. Add bounded regressions
|
||||
with [resource findings 1–2](resources.md): oversized zero-sized-element input
|
||||
can avoid a huge input allocation, and a small controlled history allowance can
|
||||
test the complete retained-root boundary. Keep count-once sharing coverage;
|
||||
do not allocate millions of nodes just to cross the production default.
|
||||
- **Nested finite link expansion.**
|
||||
[filesystem_links_test.go](../../internal/engine/filesystem_links_test.go) and
|
||||
the public finite-reuse test cover simple reuse and actual cycles, but not the
|
||||
compact repeated-dependency graph in [security finding 1](security.md#1-finite-symlink-reuse-can-cause-exponential-import-resolution-work).
|
||||
When that remediation is selected, use a small real link fixture and a bounded
|
||||
operation observer at the filesystem boundary. Protect finite reuse and
|
||||
nonrecursive discovery without running an exhaustion workload or adding a
|
||||
wall-clock performance threshold.
|
||||
|
||||
These are test accompaniments to the original remediation owners, not duplicate
|
||||
product fixes or a request for a broad new cross-product matrix. The existing
|
||||
tests should remain where they protect distinct ordinary behavior.
|
||||
|
||||
## 2. Public Historical-Path Enumeration Is Not Exercised
|
||||
|
||||
Status: open. Priority: medium. Category: public facade integration.
|
||||
|
||||
**Relevant code/tests.** `Metadata.HistoricalPaths` in
|
||||
[metadata.go](../../metadata.go), lines 49–56, has zero executed statements in
|
||||
the aggregate profile. Every checked-in `HistoricalPaths` test call is in the
|
||||
engine package. `TestMetadataHistoricalPaths` in
|
||||
[metadata_test.go](../../internal/engine/metadata_test.go) thoroughly covers the
|
||||
engine method, including removed descendants, escapes, contextual numeric
|
||||
tokens, and detached results, but does not cross the public conversion.
|
||||
|
||||
**Risk.** Returning no paths or incorrectly converting the numeric segment intent
|
||||
at the root boundary could leave that engine suite green while breaking the
|
||||
documented consumer enumeration/query workflow. Coverage of `History` and
|
||||
`Lookup` separately does not exercise enumeration's result conversion.
|
||||
|
||||
**Improvement.** Add one small external-package public-API test that enumerates
|
||||
effective and removed paths, then uses the returned paths with `Lookup` and
|
||||
`History`, including a numeric-key/sequence shape change. Check sorted unique
|
||||
pointer spelling, zero metadata, and replacement of a returned slice element
|
||||
without affecting later queries. Keep detailed path mutation and engine shape
|
||||
cases with their existing owner; do not duplicate the complete internal matrix
|
||||
or expose private segments to test the facade.
|
||||
|
||||
## 3. Native-Filesystem Failure Tests Observe Too Little
|
||||
|
||||
Status: open. Priority: medium. Category: doubles and inadequate assertions.
|
||||
|
||||
**Relevant tests.** `TestNativeFilesystemClosesFilesOnSuccessAndFailure`,
|
||||
`observedFilesystem`, and `observedFile` in
|
||||
[native_filesystem_test.go](../../internal/engine/native_filesystem_test.go),
|
||||
especially lines 150–162 and 278–319. The fixture is also used by
|
||||
`TestLoadingClosesNativeFilesAcrossPipelineOutcomes` in
|
||||
[resource_context_test.go](../../internal/engine/resource_context_test.go).
|
||||
|
||||
**Deficiencies and plausible survivors.**
|
||||
|
||||
- Failure cases require only a non-nil error, not a nil result, the expected
|
||||
diagnostic classification, or evidence identifying the intended failed
|
||||
source. An unrelated early failure could satisfy the assertion.
|
||||
- The non-disclosure check searches only `err.Error()` for the fixture canary.
|
||||
`LoadError.Error` deliberately renders an error count, not diagnostic messages.
|
||||
Accidentally forwarding the raw filesystem error into `Diagnostics()` could
|
||||
therefore pass this check. The parser/callback canary tests cover different
|
||||
failure-producing boundaries.
|
||||
- `assertClosed` checks only total opens versus total `Close` calls. The counter
|
||||
increments even for a repeated close, so one leaked handle and one double-close
|
||||
can cancel out. It does not prove that each acquired handle was released.
|
||||
- The double supplies immediate generic read/directory errors and successful
|
||||
closes. It cannot model entries/data plus an error, or a close error whose
|
||||
identity resembles absence. This leaves the
|
||||
[directory failure-phase defect](error-handling.md#1-directory-read-and-close-failures-can-be-misclassified-as-absence)
|
||||
unprotected on both the batched and fallback paths.
|
||||
|
||||
**Improvement.** Keep the real in-memory filesystem backing and small controlled
|
||||
failure seams. Track each returned handle's close state, assert the relevant
|
||||
structured load error and nil result, and inspect diagnostics/rendered diagnostics
|
||||
for the canary. Add only the read/close phase cases needed by the existing
|
||||
error-handling remediation, including a second successful directory so required
|
||||
selection cannot mask the failed one. Preserve intentionally ignored read-only
|
||||
regular-file close errors; do not invent a universal close-error contract.
|
||||
|
||||
## 4. Fuzz Detachment Assertions Miss Shared Descendants
|
||||
|
||||
Status: open. Priority: low. Category: ineffective ownership assertion.
|
||||
|
||||
**Relevant target.** `FuzzCompositionAndOverlay` in
|
||||
[composition_fuzz_test.go](../../internal/engine/composition_fuzz_test.go),
|
||||
lines 46–49 and 63–66, appends a new root mapping entry and then compares inputs
|
||||
against their earlier copies to establish result detachment.
|
||||
|
||||
**Deficiency.** A shallow-copied root can still share existing entries, descendant
|
||||
nodes, or sequence backing storage. Appending through the copied root's slice
|
||||
header changes neither the input's header nor its existing elements; even reuse
|
||||
of the backing array writes beyond the input's old length. The comparison can
|
||||
pass while the result still shares mutable descendants. It primarily detects
|
||||
aliasing the root object itself, not the deeper ownership property in its error
|
||||
message.
|
||||
|
||||
**Improvement.** Within the existing bounded target, mutate an existing result
|
||||
descendant or an element inside the original slice length, then check both
|
||||
inputs. Keep empty-container cases separate and retain the existing input
|
||||
immutability and commutativity properties. Deterministic tests in
|
||||
[compose_test.go](../../internal/engine/compose_test.go),
|
||||
[overlay_test.go](../../internal/engine/overlay_test.go), and
|
||||
[recursive_merge_test.go](../../internal/engine/recursive_merge_test.go) already
|
||||
give meaningful nested-mutation protection; improve the fuzz assertion rather
|
||||
than adding a parallel matrix or claiming all ownership coverage is absent.
|
||||
|
||||
## 5. Remove Exact Stat-Call Choreography From The Ordering Test
|
||||
|
||||
Status: open. Priority: low. Category: removal/rewrite candidate.
|
||||
|
||||
`TestSelectNamedImportsChecksNormalizedPathsLexically` in
|
||||
[import_selection_test.go](../../internal/engine/import_selection_test.go),
|
||||
lines 151–166, asserts the exact trace `a.yaml,a.yaml,z.yaml,z.yaml`.
|
||||
|
||||
Lexically ordered target handling is meaningful. Performing exactly two `Stat`
|
||||
calls per target is not an established requirement: reusing successful preflight
|
||||
metadata or changing a filesystem helper could preserve selection, safe failure,
|
||||
and ordering while failing this test. The selected-candidate assertion meanwhile
|
||||
checks only the count, not the order or paths.
|
||||
|
||||
Remove the duplicated-stat trace expectation. Check ordered candidate paths and,
|
||||
if first-failure order needs separate protection, the selected diagnostic site
|
||||
using two failing targets. Consolidate that case into the existing selection
|
||||
tests and delete this standalone test if its distinct protection is then
|
||||
subsumed. Keep meaningful interaction assertions such as not opening excluded
|
||||
file contents; those protect an actual resource/selection behavior.
|
||||
|
||||
## 6. Consolidate Redundant And Representation-Coupled Facade Scaffolding
|
||||
|
||||
Status: open. Priority: low. Category: removal/consolidation candidates.
|
||||
|
||||
- In [facade_compatibility_test.go](../../facade_compatibility_test.go), the
|
||||
six-type package-ownership loop in `TestFacadeCompatibility` is a subset of
|
||||
the comprehensive `TestFacadeValuesRemainRootOwned` loop in
|
||||
[facade_candidate_test.go](../../facade_candidate_test.go). Remove the duplicate
|
||||
loop while retaining the compile-time interface checks, public construction,
|
||||
and any distinct lifecycle behavior. The runtime assertion that a freshly
|
||||
constructed `Result.Config` still equals its literal field value adds no
|
||||
protection beyond ordinary Go assignment and compilation.
|
||||
- `TestWrappedPathsRetainEngineSegmentIntent` in
|
||||
[facade_internal_test.go](../../facade_internal_test.go) compares private
|
||||
`.value` representations for inequality. Distinct representations are not the
|
||||
consumer contract; correct contextual mapping/index lookup is. Replace its
|
||||
protection with public query behavior, coordinated with finding 2, then remove
|
||||
the private-representation test. Keep the engine's own segment-intent tests.
|
||||
- In that same file, `TestWrappedSourcesPreserveEngineOwnership` invokes
|
||||
`engine.Load` directly through `source.toEngine()`. Its byte snapshot and
|
||||
copied-reader risks are legitimate, but the facade test should use public
|
||||
`Load` and root-owned errors. Consolidate overlapping reader behavior with
|
||||
`TestRepeatedImportsAcrossTiersAndReaderConsumption` in
|
||||
[facade_equivalence_test.go](../../facade_equivalence_test.go), preserving
|
||||
explicit copied-source and byte-mutation coverage before deleting scaffolding.
|
||||
- The clone portion of `TestSourceInfoDestinationConversionsAndCopies` in
|
||||
[records_test.go](../../records_test.go), lines 39–42, replaces the whole copied
|
||||
`Destination` field. A shallow struct copy passes this without proving nested
|
||||
detachment. Remove that non-protective assertion or consolidate the relevant
|
||||
returned-record ownership check into existing public source-snapshot tests;
|
||||
retain conversion checks that protect fields at the facade boundary. `Path`
|
||||
is opaque and immutable through its public builders, so exposing internals or
|
||||
adding a new deep-copy guarantee is not justified by this test.
|
||||
|
||||
This is a small cleanup, not a recommendation to remove root integration tests
|
||||
because the engine has tests. Public conversion, error typing, callback bridging,
|
||||
source namespace identity, disclosure, and returned-record ownership have real
|
||||
cross-package risks. The static public/dependency-boundary checks also protect
|
||||
the expressly selected architecture and should remain.
|
||||
|
||||
## Validation And Limits Of This Review
|
||||
|
||||
The following passed using cached dependencies with automatic network/toolchain
|
||||
acquisition disabled:
|
||||
|
||||
```sh
|
||||
go test ./... -coverpkg=./... -covermode=atomic -coverprofile=/tmp/configkit-testing-audit.ZNsVuW/coverage.out -count=1
|
||||
go tool cover -func=/tmp/configkit-testing-audit.ZNsVuW/coverage.out
|
||||
go test ./... -shuffle=on -count=3
|
||||
```
|
||||
|
||||
The profile stayed outside the repository. Coverage blocks were combined across
|
||||
test binaries before calculating package totals. A separate JSON test run found
|
||||
no individual skipped test/subtest on this Linux host; `internal/document` was
|
||||
reported as having no standalone tests. This is not native macOS/Windows evidence.
|
||||
Only the checked-in fuzz seeds were run; no extended fuzz campaign or mutation
|
||||
testing was performed. Assertion weaknesses above are grounded in source-level
|
||||
counterexamples, not a claimed measured mutation score.
|
||||
|
||||
No production code, tests, fixtures, dependencies, or release gates were changed.
|
||||
Recommended additions should accompany the relevant fixes and existing test
|
||||
owners. Use small controlled budgets and independent outcomes, retain selected
|
||||
stable formatting/code/path contracts, and avoid making implementation details
|
||||
or speculative guarantees into new policy through assertions.
|
||||
Reference in New Issue
Block a user