Repository navigation
fix: classify Direct NAT preflight failures correctly - #50
Merged
Merged
Conversation
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
Slice 26 PR 3 only. The automatic installer previously treated any directly-addressed DNS-preflight failure as a reason to try a DNS-only NAT candidate. That could turn missing/failing/malformed interface inspection into a misleading NAT offer.
The installer now consumes one read-only Python classification from
direct-edge preflight HOST:direct: valid directly-addressed topology, including matching dual-stack DNS.nat-mismatch IPV4: successful interface inspection, nonlocal DNS, exactly one global IPv4 A and no AAAA.nat-no-public IPV4: successful empty/private-only inspection with the same NAT DNS restrictions.A narrow typed address-mismatch exception is raised only after successful inspection; unrelated command, JSON, address or DNS errors cannot be caught as topology mismatches. Classification uses one DNS snapshot. Bash branches only on machine tokens, never diagnostic text. The obsolete DNS-only
nat-candidateCLI operation is removed; explicitdns HOST --behind-natand provisioning behavior remain unchanged.Installer behavior
ip, malformed interface data and DNS failures stop with actual diagnostics and recovery guidance, without offering NAT.dns --behind-natbefore installer/public-edge mutation. A failed revalidation or decline leaves installation, service, credential and public-edge state unchanged.Regression coverage
install.shmatrix with injected system boundaries: eligible offers only, actual diagnostics, noninteractive refusal, default/explicit decline, fresh DNS revalidation failure/success, matching Direct, and unchanged Direct/NAT upgrade/provisioning/rollback paths. Whole matrix passed.Verification
uv run --directory services/relay pytest tests/test_direct_edge.py: 269 passed.scripts/test-installer-connections.py BUNDLE: passed.scripts/test-server-release.py ARCHIVE_BA/B acceptance: passed (275.5s), including frozen runtime, genuine A→B/legacy upgrades, failed-upgrade rollback, full installer acceptance and four native user-systemd flows.npm run check: passed, including relay Ruff formatting/lint/mypy, docs/version checks, all suites, e2e and production build. Existing 184 relay and one TinyFugue skip remain.git diff --check: passed.Scope / limitations
Seven files only: two production files, two existing test suites and three existing docs. Based on latest main/v0.4.3; no dependencies, release versions or CHANGELOG changed. Slice 25 remains Complete; Slice 26 remains In progress. PR 4 retained-edge recovery and PR 5 remaining messaging/docs remain outstanding.
All public-edge provisioning acceptance uses existing injected system boundaries, not live DNS/router/Caddy/certificate infrastructure. No live VPS, NAT VM, firewall, certificates or credentials touched. No remaining local acceptance blocker.