A changed --cidr-pool is ignored without a word #104

Closed
opened 2026-08-23 10:13:28 +00:00 by a73x · 1 comment
a73x commented 2026-08-23 10:13:28 +00:00 (Migrated from git.a73x.sh)

[claude 2026-08-23] Found while writing TestCidrPoolFirstOpenWins for 25dd592e (item 8b). The test pins the current behaviour; this issue is about the silence around it.

store.Open seeds cidr_pool with ON CONFLICT DO NOTHING, so the first Open wins and every later --cidr-pool is discarded. That is the right behaviour — hosts hold their guest subnet for life, and honoring a changed flag would re-plan subnets under a fleet already routing on the old ones. It is now pinned by a test.

What is wrong is that the operator gets no signal. Someone who restarts the server with a deliberately different pool sees a clean startup, no warning in the log, and a control plane that quietly kept the old value. They then discover the flag did nothing only when a newly-enrolled host lands on a subnet they did not expect — or never, if they simply assume it took.

Proposed: at Open, compare the passed pool against the stored one and say something when they differ. Warning-vs-refusal is the open question:

  • warn keeps every existing deployment starting (including any that pass a stale flag today) and costs one log line
  • refuse is more in this repo's grain — the sshgate wildcard-bind refusal and the no-CA 409 both decline to run rather than run misleadingly — but it would brick a restart for anyone whose unit file carries a pool that has already drifted from the DB

Recommend warn for this cycle: nobody's fleet breaks, and the operator learns the flag is inert. Refusal deserves its own decision if the warning turns out to be ignored.

Also unpinned, same idiom: epoch and next_cidr_index at store.go:314-315 use the same ON CONFLICT DO NOTHING. Those take no operator input, so they need no signal — noted only so a fix here does not get applied to them by pattern-matching.


Migrated from git-collab issue c2ca921e7016083e67837756124e6ffb8fec2203.

Original author: a73x dev@a73x.sh.

Close reason: [claude 2026-08-23] Merged to main in d0c032f (pushed to both remotes). Every test proven by the mutant it kills; Fable's checkpoint review passed it merge-as-is. make ci green, boot gate PASS (full smoke incl. UDP, cold_start=20s).

[claude 2026-08-23] Found while writing `TestCidrPoolFirstOpenWins` for 25dd592e (item 8b). The test pins the current behaviour; this issue is about the silence around it. `store.Open` seeds `cidr_pool` with `ON CONFLICT DO NOTHING`, so the first Open wins and every later `--cidr-pool` is discarded. That is the **right** behaviour — hosts hold their guest subnet for life, and honoring a changed flag would re-plan subnets under a fleet already routing on the old ones. It is now pinned by a test. What is wrong is that the operator gets no signal. Someone who restarts the server with a deliberately different pool sees a clean startup, no warning in the log, and a control plane that quietly kept the old value. They then discover the flag did nothing only when a newly-enrolled host lands on a subnet they did not expect — or never, if they simply assume it took. **Proposed:** at Open, compare the passed pool against the stored one and say something when they differ. Warning-vs-refusal is the open question: - **warn** keeps every existing deployment starting (including any that pass a stale flag today) and costs one log line - **refuse** is more in this repo's grain — the sshgate wildcard-bind refusal and the no-CA 409 both decline to run rather than run misleadingly — but it would brick a restart for anyone whose unit file carries a pool that has already drifted from the DB Recommend **warn** for this cycle: nobody's fleet breaks, and the operator learns the flag is inert. Refusal deserves its own decision if the warning turns out to be ignored. **Also unpinned, same idiom:** `epoch` and `next_cidr_index` at `store.go:314-315` use the same `ON CONFLICT DO NOTHING`. Those take no operator input, so they need no signal — noted only so a fix here does not get applied to them by pattern-matching. --- Migrated from git-collab issue `c2ca921e7016083e67837756124e6ffb8fec2203`. Original author: a73x <dev@a73x.sh>. Close reason: [claude 2026-08-23] Merged to main in d0c032f (pushed to both remotes). Every test proven by the mutant it kills; Fable's checkpoint review passed it merge-as-is. make ci green, boot gate PASS (full smoke incl. UDP, cold_start=20s).
a73x commented 2026-08-23 10:38:26 +00:00 (Migrated from git.a73x.sh)

[claude 2026-08-23] Done on branch loud-misconfiguration. Took the recommendation: warn, do not refuse. store.Open reads back the stored cidr_pool after the ON CONFLICT DO NOTHING seed and, when it differs from the passed one, logs a WARN naming both values and saying the stored pool still governs every future allocation. Behaviour unchanged: TestCidrPoolFirstOpenWins still passes untouched (only its 'silently ignored' comment updated, since it is no longer silent). New TestChangedCidrPoolWarns proven by two mutants: guard disabled -> the changed-pool restart logs nothing and the test fails on 'does not contain --cidr-pool was ignored'; guard forced always-on -> the same-pool restart warns and the test fails on 'Should be empty'. epoch and next_cidr_index left alone as noted.

[claude 2026-08-23] Done on branch loud-misconfiguration. Took the recommendation: warn, do not refuse. store.Open reads back the stored cidr_pool after the ON CONFLICT DO NOTHING seed and, when it differs from the passed one, logs a WARN naming both values and saying the stored pool still governs every future allocation. Behaviour unchanged: TestCidrPoolFirstOpenWins still passes untouched (only its 'silently ignored' comment updated, since it is no longer silent). New TestChangedCidrPoolWarns proven by two mutants: guard disabled -> the changed-pool restart logs nothing and the test fails on 'does not contain --cidr-pool was ignored'; guard forced always-on -> the same-pool restart warns and the test fails on 'Should be empty'. epoch and next_cidr_index left alone as noted.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
a73x/eitri#104
No description provided.