Reuse validated filesystem facts through acquisition

This commit is contained in:
2026-10-25 14:33:17 +00:00
parent 6440a500f7
commit e585decdb2
6 changed files with 41 additions and 65 deletions

View File

@@ -8,8 +8,9 @@ This note records implementation flow and private identities for maintainers.
Each source's root directive is parsed into presence-aware declarations and Each source's root directive is parsed into presence-aware declarations and
resolved against load-wide defaults. `acquisition.go` owns shared acquisition resolved against load-wide defaults. `acquisition.go` owns shared acquisition
policy, load accounting, and per-tier accounting; `import_acquisition.go` owns policy, load-wide accounting, and tier-scoped repetition/namespace state;
reading candidate bytes, declaration traversal, and import admission. Candidate `import_acquisition.go` owns reading candidate bytes, declaration traversal,
and import admission. Candidate
selection in `import_selection.go` preserves a normalized selection in `import_selection.go` preserves a normalized
namespace path separately from canonical access identity: overlapping roots namespace path separately from canonical access identity: overlapping roots
coalesce the same candidate spelling in that namespace, while aliases reached coalesce the same candidate spelling in that namespace, while aliases reached

View File

@@ -98,12 +98,14 @@ version, default-import, and override policy stays distinct from each input's
source, filesystem, destination, and import settings. source, filesystem, destination, and import settings.
[`acquisition.go`](../../internal/engine/acquisition.go) defines acquisition [`acquisition.go`](../../internal/engine/acquisition.go) defines acquisition
policy and load-wide and per-tier accounting state. Each input is acquired under policy, load-wide accounting, and tier-scoped repetition/namespace state. Each
that policy; grouped requests retain acquired underlay scopes until their tier is input is acquired under that policy; grouped requests retain acquired underlay
composed in [`load_request.go`](../../internal/engine/load_request.go). Live scopes until their tier is composed in
[`load_request.go`](../../internal/engine/load_request.go). Live
filesystem access handles are confined to acquisition and closed there. Resolved filesystem access handles are confined to acquisition and closed there. Resolved
filesystem facts used to authorize access are separate from passively retained filesystem facts used to authorize access are separate from passively retained
resource contexts: see resource contexts. Non-import validation retains those facts on `assembledInput`
for passive-context construction and ordinary-overlay handling: see
[`filesystem_context.go`](../../internal/engine/filesystem_context.go) and [`filesystem_context.go`](../../internal/engine/filesystem_context.go) and
[`source_context.go`](../../internal/engine/source_context.go). [`source_context.go`](../../internal/engine/source_context.go).

View File

@@ -12,7 +12,7 @@ and full race suite (`go test -race ./...`) passed with Go 1.26.10 on Linux.
## 1. Complete The Non-Import Resolved-Context Handoff ## 1. Complete The Non-Import Resolved-Context Handoff
Status: open. Priority: medium. Category: implementation gap and maintainability. Status: complete (2026-10-25). Priority: medium. Category: implementation gap and maintainability.
No user-facing correctness regression has been established for this finding. No user-facing correctness regression has been established for this finding.
**Target.** Roadmap internal target 2 and implementation Stages 7–9 select one **Target.** Roadmap internal target 2 and implementation Stages 7–9 select one
@@ -76,6 +76,17 @@ only for a consequential gap exposed by the change; do not assert incidental
canonicalization/stat call counts. Run the development check and applicable canonicalization/stat call counts. Run the development check and applicable
ownership race checks after remediation. ownership race checks after remediation.
**Completion.** Non-import validation now returns its resolved filesystem
description and acquisition retains it for passive contexts and ordinary
overlays, including absent inputs. Absent-host derivation uses the common
resolver; the duplicate validator was removed. Validation timing, directory and
root-open/close checks, and the existing absent-input containment diagnostic
are retained. Internal documentation now distinguishes load-wide accounting
from tier-scoped repetition/namespace state. Existing filesystem, discovery,
overlay, and resource tests, the development check, and `go test -race ./...`
passed with Go 1.26.10 on Linux. No new incidental call-count assertions were
added.
## Algorithmic Audit Scope ## Algorithmic Audit Scope
Audited worktree: `d898cb1`, with production code at the reviewed implementation Audited worktree: `d898cb1`, with production code at the reviewed implementation
@@ -88,7 +99,8 @@ schema construction.
Findings 2–3 are retained inefficiencies in paths carried through the refactor, Findings 2–3 are retained inefficiencies in paths carried through the refactor,
not algorithmic regressions introduced by the consolidation. They warrant not algorithmic regressions introduced by the consolidation. They warrant
focused follow-up without changing the selected configuration model. The audit focused follow-up without changing the selected configuration model. The audit
did not identify an additional correctness defect. Finding 1 remains open. did not identify an additional correctness defect. Finding 1 was open at the
time of that audit; completion is recorded with the finding above.
The selected stable Kahn scheduler, deterministic sorting, composition rules, The selected stable Kahn scheduler, deterministic sorting, composition rules,
scope boundaries, and required ownership copies are not reconsidered here. scope boundaries, and required ownership copies are not reconsidered here.

View File

@@ -178,9 +178,11 @@ func acquireInput(request inputAcquisitionRequest, policy acquisitionPolicy, sta
input.document = versionProcessing.payload input.document = versionProcessing.payload
} }
if request.input.filesystem != nil && (selectedSource.kind == sourceNone || !activeOverlay(request.ordinaryOverlay)) { if request.input.filesystem != nil && (selectedSource.kind == sourceNone || !activeOverlay(request.ordinaryOverlay)) {
if diagnostic := validateFilesystemContext(selectedSource, request.input.filesystem, parsed); diagnostic != nil { resolved, diagnostic := validateFilesystemContext(selectedSource, request.input.filesystem, parsed, tier.hostToken)
if diagnostic != nil {
return input, []Diagnostic{*diagnostic} return input, []Diagnostic{*diagnostic}
} }
input.resolvedFilesystem = &resolved
} }
} }
if !request.input.imports && input.document != nil { if !request.input.imports && input.document != nil {

View File

@@ -7,73 +7,33 @@ import (
"strings" "strings"
) )
func validateFilesystemContext(source Source, context *FilesystemContext, main parsedSource) *Diagnostic { func validateFilesystemContext(source Source, context *FilesystemContext, main parsedSource, hostToken *namespaceToken) (resolvedFilesystemContext, *Diagnostic) {
if source.kind == sourceNone && context.FS == nil { resolved, diagnostic := resolveFilesystemContext(source, context, main, hostToken)
return validateAbsentHostFilesystemContext(context)
}
if nativeContext(source, context) {
resolved, diagnostic := resolveNativeFilesystemContext(source, context)
if diagnostic != nil {
return diagnostic
}
return validateResolvedFilesystemDirectories(resolved)
}
resolved, diagnostic := resolveHostFilesystemContext(source, context, main, nil)
if diagnostic != nil { if diagnostic != nil {
return diagnostic // Keep absent-input validation's existing diagnostic while sharing
// root/base derivation with overlay and resource-context handling.
if source.kind == sourceNone && context.FS == nil && diagnostic.Code == CodeImportOutsideRoot {
diagnostic.Message = "import base must stay inside the configuration root"
}
return resolvedFilesystemContext{}, diagnostic
} }
if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil { if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil {
return diagnostic return resolvedFilesystemContext{}, diagnostic
}
if resolved.native != nil {
return resolved, nil
} }
root, err := os.OpenRoot(resolved.rootPath) root, err := os.OpenRoot(resolved.rootPath)
if err != nil { if err != nil {
value := globFilesystemDiagnostic(err, "configuration root could not be opened", Location{}) value := globFilesystemDiagnostic(err, "configuration root could not be opened", Location{})
value.Primary = nil value.Primary = nil
return &value return resolvedFilesystemContext{}, &value
} }
if err := root.Close(); err != nil { if err := root.Close(); err != nil {
value := importDiagnostic(CodeImportRead, "configuration root could not be closed", nil) value := importDiagnostic(CodeImportRead, "configuration root could not be closed", nil)
return &value return resolvedFilesystemContext{}, &value
} }
return nil return resolved, nil
}
func validateAbsentHostFilesystemContext(context *FilesystemContext) *Diagnostic {
rootPath, err := canonicalExistingPath(context.Root)
if err != nil {
value := importDiagnostic(CodeImportInvalid, "configuration root could not be canonicalized", nil)
return &value
}
basePath := rootPath
if context.BaseDir != "" {
basePath, err = canonicalExistingPath(context.BaseDir)
if err != nil {
value := importDiagnostic(CodeImportInvalid, "import base directory could not be canonicalized", nil)
return &value
}
}
if !containedPath(rootPath, basePath) {
value := importDiagnostic(CodeImportOutsideRoot, "import base must stay inside the configuration root", nil)
return &value
}
for _, candidate := range []string{rootPath, basePath} {
info, err := os.Stat(candidate)
if err != nil || !info.IsDir() {
value := importDiagnostic(CodeImportInvalid, "configuration root and import base must be directories", nil)
return &value
}
}
root, err := os.OpenRoot(rootPath)
if err != nil {
value := globFilesystemDiagnostic(err, "configuration root could not be opened", Location{})
value.Primary = nil
return &value
}
if err := root.Close(); err != nil {
value := importDiagnostic(CodeImportRead, "configuration root could not be closed", nil)
return &value
}
return nil
} }
func filesystemOptionDiagnostics(source Source, context *FilesystemContext) []Diagnostic { func filesystemOptionDiagnostics(source Source, context *FilesystemContext) []Diagnostic {

View File

@@ -43,7 +43,6 @@ func resolveOrdinaryOverlayFilesystem(source Source, context *FilesystemContext,
value := optionDiagnostic(CodeOptionsInvalid, "NoSource overlays require explicit filesystem context") value := optionDiagnostic(CodeOptionsInvalid, "NoSource overlays require explicit filesystem context")
return resolvedFilesystemContext{}, &value return resolvedFilesystemContext{}, &value
} }
return resolveAbsentFilesystemContext(context)
} }
if existing != nil { if existing != nil {
return *existing, nil return *existing, nil