refactor(engine): collapse resolver host I/O onto the Session seam (deepen-engine-seams)#30
Merged
Conversation
factMatchesQuery moves beside its sole caller in projection.go; the delegate-driven tests retarget NewProjection(...).Select directly. detector.go had zero production callers (deletion test: concentrates). deepen-engine-seams group 1
…v seam - fakeHostOS grows additive knobs: per-path error maps, emptyRunDefault, fakeFileEntries (IsDir-skipping loops need file entries) - pure envValue (case-insensitive only on windows) + Session.getenv - ~30 runtime.GOOS reads across fips/selinux/timezone/uptime/ssh/identity/ dmi/os/core bind s.goos(); SystemRoot/programdata/PROCESSOR_ARCHITEW6432/ PATH read the Session host environ - ssh + fips gating-test skips deleted; fake-windows ssh/os assembly tests deepen-engine-seams groups 2-3
Linux ran the dmidecode/virt-what/vmware/lspci gather three times per discovery (virtual, hypervisors.*, uptime container gate); Windows ran the wmic/reg gather twice. One Session memo per platform (cachedDMI pattern, ADR-0005-compliant: per-discovery, never Engine-resident); classification stays pure so resolved values are unchanged. deepen-engine-seams group 4
…art 1) Groups 5.1-5.4, 5.6: core.go reader helpers take required readers; networking metadata/bonding/DHCP variant families collapse to host-taking functions (10 variants -> 4), closing raw os.ReadDir at networking.go:1099/1170; processors physical-count triple -> 1, closing os.ReadDir at processors.go:457; dmi five ForPlatform pairs + windows fold onto the Session. Resolver tests migrate to fakeHostOS under the same-assertions-relocated-fixtures rule. deepen-engine-seams group 5 (part 1)
…ze the seam Groups 5.5, 5.9-5.11: virtual/xen fold WithCommands/WithHost onto the Session (procVZEntryCount closes os.ReadDir at virtual.go:605); fips/identity/augeas/ec2 fileExecutable take the Session (closes os.Stat at ec2.go:106); delete dead filehelper.go. TestNoRawHostIOInResolvers AST-gates the collapsed state: no raw os.ReadDir/ReadFile/Stat/Lstat/ filepath.Glob/exec.Command outside session*.go/external.go/cache.go/ config.go/statfs*. deepen-engine-seams group 5 (part 2)
metadatahttp.go: newMetadataHTTPClient (proxy-less) + fetchMetadata
(200-required, 1MB-capped, fail-closed) replace four hand-rolled copies
in ec2/gce/az. Providers keep their own headers, token/flavor handling,
parse, gates, and per-provider timeouts. Delete dead gceFacts (retarget
its 6 tests to linuxGCEFacts with production {gce: nil} empty-case
expectations); metadatahttp_test.go adds the first transport-invariant
tests (proxy-less, non-200, request-build error, transport error, 1MB
body cap, header passthrough).
deepen-engine-seams group 6
…ession Groups 5.7-5.8: currentOSRelease/currentFilesystems/currentLinuxDistro and the macOS probe pairs (os.go); the currentUptime*/currentLoadAverages family (keeping the now func() time.Time param — the clock is not on the host seam) and currentWindowsMemory/currentDarwinSwapUsage (memory.go) take their readers/runner/goos from the Session. ~50 test closures migrate to fakeHostOS under the same-assertions-relocated-fixtures rule. deepen-engine-seams group 5 (part 3) — group 5 complete
The two near-identical loader arms in Engine.Discover become one construction + one load() call with a single mode-conditional branch: CLI mode returns newSnapshot(nil, logger), err byte-identically (partial facts + planFailures discarded, finish() skipped); library mode appends to failures and keeps partial facts. Discover-level pins lock both error policies. Delete the test-only LoadExternalFacts/WithBlocklist facade (zero production callers); external_test.go gets a field-for-field in-package helper, ~98 call sites retargeted. deepen-engine-seams group 7
Export one pure DisabledUnion (config + --disable + FACTS_DISABLE union, group-expanded); discovery planning and internal/app's fast path both derive their disabled set from it, so they can never disagree on whether facterversion is disabled. Delete the EnvironmentDisabledFacts / DisabledFactsForFiltering crutch exports. Route writeVersionQuery through engine.BuildFormatter (three format booleans only; --color/--force-dot stay ignored). Demote the four bare Format* functions to an in-package test helper — 102 formatter_test call sites + 3 benchmarks untouched, production build loses the exports. Byte pins + fall-through pins lock identity. deepen-engine-seams group 8
…010 follow-on CHANGELOG internal-refactor entry; ADR-0010's deferred commandRunner/ fileReader->Session collapse marked done (structurally enforced by TestNoRawHostIOInResolvers), resolving the archived 2026-06-17 LoadExternalFacts open question; design.md records the Lima real-Linux behavior-preservation result and the plan9/windows guest-smoke accepted risk (nlab unavailable; covered by cross-builds + fake-host tests). deepen-engine-seams group 9
Both guests reachable and validated: main vs branch binaries diff stable-subset byte-identical on Windows Server 2025 and Plan 9 (9front), only volatile uptime/memory/disk facts differ. Windows os.windows.system32 = C:\WINDOWS\system32 (s.getenv(SystemRoot) matches os.Getenv); Plan 9 path fact = [/bin, .] (non-empty, NUL-split).
Applies the change's spec deltas to the main specs (facts-library-api diagnostics drops OS-hierarchy detection; go-port-supported-platform-facts gains the Session-only-host-I/O-path enforcement and single-gather requirement; facts-cli-option-contract gains the version fast-path seam reuse) and moves the completed change to the archive.
Four fake-host tests passed on darwin/linux but failed on the Windows CI runner: fakeHostPath normalized lookups with filepath.ToSlash (a no-op off Windows), while fixtures keyed windows paths with backslashes and newLeaseDirHost keyed with filepath.Join — so keys and lookups diverged only on Windows, and the want-empty lease tests passed vacuously. Normalize fakeHostPath with an unconditional backslash->slash replace (sshCoreFacts forces backslash joins for the windows branch on every host, so a slash-keyed fixture must resolve on unix dev hosts too) and key the lease/ssh fixtures with forward slashes. Fixes the Windows Server 2022/2025 go-test failures on PR #30.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Behavior-preserving deepening of
internal/engine: the run-scoped Session host seam becomes the only path resolvers use to reach the host, structurally enforced by a new AST gate. This is the ADR-0010-deferredcommandRunner/fileReader→ Session collapse, extended by six adjacent deepenings found by the same deletion-test review. No public API, CLI flag, output, input-source precedence, diagnostic, or cache behavior changes.Implements the
deepen-engine-seamsOpenSpec change (archived in this PR; 47 tasks across 9 groups).What changed
FromRoot/WithHost/WithReader/ForPlatformvariant families (networking 10→4, processors triple→1, dmi's fiveForPlatformpairs, virtual/xen, os/uptime/memory) collapse onto the Session; rawos.ReadDir/os.Statleaks are closed.TestNoRawHostIOInResolvers(AST-based) freezes the boundary.s.goos()and environment vias.getenv(case-insensitive only on Windows), so windows/plan9 paths are exercisable with a fake host; the ssh/fips gating-test skips are gone.metadatahttp.goconsolidates four hand-rolled ec2/gce/az clients (proxy-less, 200-required, 1 MiB-capped, fail-closed) with the first transport-invariant tests.Engine.Discover's two near-identical external-loader arms collapse to one; the test-onlyLoadExternalFactsfacade is deleted.engine.DisabledUnionandengine.BuildFormatterinstead of aninternal/appmirror; the four bareFormat*become test-only.detector.go,query.goSelect delegates,filehelper.go, deadgceFacts, the fast-path crutch exports.Verification
go build ./...,go vet ./...,go test ./...(2326 tests),go test -raceon engine + app — all green.TestNoRawHostIOInResolversseam gate passes.main.main, stable fact subset byte-identical, only volatile uptime/memory/disk facts differ):os.windows.system32=C:\WINDOWS\system32,pathleads with it (provess.getenv("SystemRoot")matchesos.Getenv).path=["/bin", "."](non-empty, NUL-split).🤖 Generated with Claude Code