fix: fail-closed node egress, PG step-arounds 500, and the fences that were green against their own defects - #5
Merged
damonleelcx merged 1 commit intoAug 1, 2026
Conversation
`url.Parse("socks5://:::::")` succeeds and yields Host ":::::", and
x/net/proxy.SOCKS5 stores the address without validating it. So an unusable
chain BUILT cleanly and only failed later, at dial.
That difference is the difference between a config error and an outage. Built
cleanly, the console's Test-connectivity button reports a dial timeout and
points the operator at the exit node — the exit node is fine and the typo is in
the spec they are looking straight at.
Rejecting here is lossless: an address net.SplitHostPort cannot split is one
net.Dial could never have dialed. A named port is refused too, because
/etc/services differs per host and the same spec would work on one node and
fail on the next.
Found by a fence in aikey-proxy that had been failing on exactly this
(TestBuildTransportStrict_ParsePathErrorsIndependently) before this session.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Part of the P0a upstream-fallback acceptance work (openspec change
aliyun-aigw-p0-upstream-fallback). One branch of the same name in each repo.Why
The fallback chain had been proven on one path — a switch, with synthetic
upstreams, in a configuration staging was then reconfigured away from. This
verifies the parts that decide whether failover is safe rather than merely
working, against a real provider and the real mihomo egress: cooldown,
switch-back, terminal states, streaming and the first-byte gate, the 429/529/
timeout/reset taxonomy, entry-shape parity, the same-VK fence, and per-hop model
mapping. 51/51 on staging, plus a real-provider run (real Anthropic 401 →
real 200) and form-② on both lobsters.
Defects this found and fixes
MasterUpstreamStepArounds500 on every Postgres deploymentCOALESCE(timestamptz, integer)— valid on SQLite, so unit tests were green and every production console was broken. This is also why 6.1's L4 row sat unfilled: the endpoint it depends on had never returned 200. Fixed.NODE_EGRESS_ENGINE_UNAVAILABLE503. Fixed.fallback_attempt = NULLsocks5://:::::passed validation and failed only at dial, so Test-connectivity blamed the exit node. Fixed.pkg/fallbackpolicyrequire+replace;go.workmasked it (GOWORK=off fails) and the Makefile step was WARN-and-continue. Fixed.Fences added, each observed red then green
candidate_chain.go:44has always claimed exists — the file did not exist, so task 6.3d had zero coverage while the source asserted otherwise. A cross-VK borrow succeeds, so only a fence can find it.1,'primary'— its single row's expected value is the default. Rewritten with distinct values.tr.Proxy == nil, which is true of both a direct and a refusing transport.deny_unknown_fieldsbanned.Reported, deliberately not fixed here
Cooldown is per-node, so "we stop calling a dead upstream" holds per worker, not per cluster. Revoking a VK leaves its bindings active, so its credentials can never be revoked (62 rows on staging) — which also blocks the revoked-skip scenario from running at all. A 403 on delivery never prunes, so an agent loops. The master audit drill-down doesn't select the fallback columns. The Route Groups list renders every chain as
0 hops.db upgradere-groups ungrouped bindings, including revoked keys.aikey use --onlyhas no channel to the cluster. Each needs a decision, not a silent patch.Not verified
Trial and Production editions (route-group APIs are master-only, so Trial cannot configure a chain at all); Windows; a real 429/529/timeout from a vendor. Staging currently carries two hand-swapped binaries pending the next package build.
🤖 Generated with Claude Code