# Changelog 2026-07-10 -- DOCFIX-181: carve_gua subnet-enumeration hang + harness watchdog

**Context.** After the Stage-1 commit, the full `scripts/run-tests-all.sh`
gauntlet was seen to HANG on `tests/dc-dc-prefixes-import/`. Investigated per
operator request ("check into this now so it's not a problem later"). Root cause
is a real bug in the target script, not an environment quirk -- and the harness's
own claimed "40/40 PASS" was never actually reached (it was hanging).

## Root cause

`netbox/dc-dc-prefixes-import.py::carve_gua()` built
`list(dc_gua_prefix.subnets(new_prefix=64))` -- materializing EVERY /64 in the
GUA prefix, then returning only the first. D-101's own GUA example is a `/40`
(`2602:f3e2:1000::/40`), which has `2**(64-40) = 16,777,216` /64 subnets, so the
`list()` allocates ~16.7M `IPv6Network` objects -> effective hang / OOM. This is
NOT test-only: a real import run with a realistic GUA prefix would hang
identically. (`carve_ula` is safe -- it carves /48->/56->/64, bounded at 256.)

Diagnosed with `faulthandler.dump_traceback_later`, which pointed straight at
`carve_gua` line 306 inside `ipaddress.subnets()`.

## Fix

- **`netbox/dc-dc-prefixes-import.py::carve_gua`** -- take the first /64 LAZILY
  with `next(dc_gua_prefix.subnets(new_prefix=64))` (O(1)) instead of
  `list(...)[0]`. Same result, no enumeration.
- **`tests/dc-dc-prefixes-import/test_logic.py`** -- added a
  `faulthandler.dump_traceback_later(30, exit=True)` watchdog at import time, so
  any FUTURE blocking regression in this Python test self-aborts after 30s with a
  stack trace (non-zero exit) rather than hanging the whole gauntlet silently.

## Verification
- `bash tests/dc-dc-prefixes-import/run-tests.sh` -> `ALL PASS (40 checks)` in
  ~0.05s (previously: hung indefinitely, never completing).
- `bash scripts/repo-lint.sh` -> 0 fail.
- Full `scripts/run-tests-all.sh` gauntlet now runs to completion.

## Revert
- `git checkout netbox/dc-dc-prefixes-import.py tests/dc-dc-prefixes-import/test_logic.py`
  to the pre-DOCFIX-181 revision, plus
  `git rm docs/changelog-20260710-carve-gua-hang-fix.md`.
  (Reverting reinstates the hang -- do not, without replacing the fix.)

## Note
- The pre-existing ledger claim of "dc-dc-prefixes-import 40/40" was optimistic:
  the end-to-end path had been hanging, so those checks never actually ran to a
  green count until this fix. The watchdog prevents that class of false-green
  (a hang read as "still running") from recurring.
