Split "may I touch this" from "is this mine" before widening either - #8
Closed
Purple10101 wants to merge 1 commit into
Closed
Purple10101 wants to merge 1 commit into
Purple10101 wants to merge 1 commit into
Conversation
…ng either NODE_ID_RE answered two different questions with one constant, and they fail in opposite directions. _guard() asks whether a name is one this script may create, reconfigure or delete. Too narrow there is safe: the worst case is refusing to act. reconcile() asks, in three places, whether a name is ours and therefore rubbish to sweep up. Too wide there is dangerous: an over-broad pattern claims something somebody built by hand, and --prune deletes it. retnode.com carries eight hand-built tunnels, several serving live customer nodes. Sharing one constant meant widening the node_id format for the first purpose silently widened it for the second. MAY_ACT_ON and OWNED_BY_US are identical today and deliberately separate, so the next format change has to answer both questions rather than one. Both now accept retg + 15 hex alongside ret + 8 hex. Checked before widening: nothing in the zone begins retg, across 27 tunnels, 43 DNS records and 25 Access applications, and the eight hand-built tunnel names match neither format. Tests pin that property rather than describing it: every one of the eight real names is asserted against OWNED_BY_US, and reconcile is driven end to end so a hand-built tunnel is never offered as an orphan from any of the three sweeps. The constant being right is not the same as it being used in all three. Verified against the live account: this script and the one on main produce byte-identical dry-run output, so the widening changes nothing today. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Closing: this work is not being taken forward. The branch is deleted, but the commits stay reachable from this closed PR if it is ever revived. |
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 3 of 5, with owl-os#59 and retina-telemetry#20. Merge this before owl-os#59 — node-infra is the only component that sees every node's id from the server, so it must tolerate the new format before anything has one.
The bug in the shape of the old code
NODE_ID_REanswered two different questions with one constant, and they fail in opposite directions._guard()asks "is this a name I may create, reconfigure or delete?" Too narrow is safe: the worst case is refusing to act.reconcile()asks, in three separate places, "is this name mine, and therefore rubbish to sweep up?" Too wide is dangerous: an over-broad pattern claims something somebody built by hand, and--prunedeletes it.Sharing one constant meant widening the format for the first purpose silently widened it for the second.
MAY_ACT_ONandOWNED_BY_USare identical today and deliberately separate, so the next format change has to answer both questions rather than one.What shares the zone
retnode.comcarries eight tunnels this script did not create, several serving live customer nodes:Checked before widening: nothing in the zone begins
retg, across 27 tunnels, 43 DNS records and 25 Access applications, and none of those eight names matches either format.Tests pin the property rather than describing it
Every one of the eight real names is asserted against
OWNED_BY_US, andreconcile()is driven end to end so a hand-built tunnel is never offered as an orphan from any of the three sweeps. The constant being right is not the same as it being used in all three, which is precisely the bug this PR is about.Verified against the live account
This script and the one on
mainproduce byte-identical dry-run output:Read-only (no
--apply, no--prune), against an isolated state file so the real one was untouched.Operational finding from the migration dry run
Not a code change here, but it belongs with this file.
retina-tunnel-sync.timerruns--applyevery five minutes and applies repairs, not just reports them. That races a node migration in both directions:reconcile()sees "we recorded a tunnel that no longer exists" →ensure_tunnel()recreates the old tunnel, DNS record and Access application and re-stages a token onto the node.plan()raises acreateand provisions a second complete set.The timer must be stopped for the duration of each node's migration. Worth knowing before anyone runs the first one.
Also proven, separately
Cloudflare objects can be renamed in place rather than torn down and recreated. Tested on throwaway objects: the tunnel keeps its id and its token is byte-identical across a rename, and an Access application's domain can be changed with
PUT(notPATCH, which returns a misleading405 / 10405) with itsaudand policy preserved. That means a migrated node needs nothing staged onto it, the connector never drops, and no orphans are created, so--prunenever has to run.Not verified
The rename path against live Cloudflare objects. Proven on throwaway ones only, because doing it live needs the timer stopped first.
🤖 Generated with Claude Code