NetBox write-path hardening: the bugs that would have corrupted the apex at C2
Found by adversarial review during D-119; independent of the naming work. These
are what would have bitten during C2 (the production IPAM write Stage 2 needs).

1. roles-aggregates-import.py STILL died half-way through a production write. The
   preflight added on 2026-07-13 -- after this same script committed 4 roles, 400'd
   on the 5th and left the apex half-populated -- only covered role-NAME collisions.
   The ARIN RIR lookup and validate_ula_48() both still ran BELOW the first write,
   so an apex without ARIN, or a typo'd ORG_ULA_48, would commit 5 roles (and the
   RIRs) and THEN die, with no rollback. The exact failure the preflight was added
   to prevent, still armed one section lower. The RIR half of the preflight loop was
   a literal no-op. Both checks moved INTO the preflight.
   A preflight that does not cover every die() downstream of the first write is not
   a preflight.

2. sandbox-fidelity-check.py could return a FALSE GREEN -- and it is the script we
   have been citing as PROOF the sandbox is a faithful replica. It field-compared
   only SHARED objects; the planned delta was checked merely as a SUBSET of
   EXPECTED_NEW. With ZERO of the 36 DC prefixes created, extra={} -> unexpected={}
   -> it printed "Nothing lost, nothing stray" and exited 0. EXPECTED_NEW was an
   upper bound masquerading as an assertion. It is now BOTH bounds, and delta
   prefixes are checked for scope and role (the 17-prefix scope-drop bug relocated
   into the delta, where the old check was structurally blind).

3. dc-dc-prefixes-import.py died mid-loop on a missing role -- find_role() was
   resolved lazily INSIDE the write loop. Against upstream as it stands TODAY (no
   six-plane roles), a --commit creates the site + 4 prefixes then dies on the 5th:
   a half-written datacenter. Now a whole-plan preflight resolves every role first.

4. The test fake was KINDER THAN REALITY at the failure point: fake_pynetbox.get()
   returned matches[0] on a multi-match where real pynetbox RAISES. NetBox permits
   duplicate prefixes (the importer's own docstring anticipates them vs vr0-dc0), so
   this would blow up in production while the harness sailed through. It now raises.

TESTS: tests/sandbox-fidelity-check/ is NEW (10/10) -- the checker shipped with NO
harness at all, which is exactly why the false green survived; T3 reproduces it, and
T1 derives its expectation from the checker's own EXPECTED_NEW rather than re-typing
it. roles-aggregates-import 16->19, asserting BY POSITION that ARIN and the ULA are
validated before the first create (the old harness only checked the WORD "PREFLIGHT"
appeared -- green while the landmine was armed).

GAUNTLET ALL GREEN (58). repo-lint 0 fail. Zero NetBox writes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c79ad63 commit b945fd4c9960aec20146ac7270ecc376f4a94517
@JANeumatrix JANeumatrix authored 21 hours ago
Showing 7 changed files
View
docs/changelog-20260714-netbox-write-path-hardening.md 0 → 100644
View
netbox/dc-dc-prefixes-import.py
View
netbox/roles-aggregates-import.py
View
netbox/sandbox-fidelity-check.py
View
tests/dc-dc-prefixes-import/fake_pynetbox.py
View
tests/roles-aggregates-import/run-tests.sh
View
tests/sandbox-fidelity-check/run-tests.sh 0 → 100755