Confirmed TESTS.txt's own "@@@ we'll run out of junctors too!" note, and it's benign.
With only MAX_JUNCTORS (12) shared across up to 72 lines all going off-hook with no
intervening hangups, junctor allocation starts failing partway through the offhook phase
(Line::emit logs "could not allocate a junctor, ignoring event (congestion)" and leaves
that line's ccb NULL, though Line::state still correctly reaches OffHook -- the
state transition happens in Line::scan() before emit() is even called, unconditionally).
The interesting part: later hanging up one of these congestion-denied lines calls
Line::emit(LineEvent_Onhook) with ccb == NULL, and emit()'s ccb-bootstrap prologue
doesn't distinguish why ccb is NULL from what event triggered it -- it unconditionally
treats any event on a CCB-less line as a fresh origination attempt, so a bare Onhook can
momentarily allocate a brand new ccb + junctor + P_Line, exactly as if it were an Offhook.
This is harmless only because every processor (P_Line included) unconditionally
deactivates on CCBEvent_Onhook regardless of what state it's in, so the phantom ccb gets
torn down again in the very same event dispatch, before scan_cc()'s next pass -- confirmed
in the debug log: allocate, dispatch, immediately deactivate, teardown, free, all in one
Line[N]::emit Onhook block. Self-healing, not a leak, and the 12+-lines-congested scenario
this requires never arises outside a stress test like this one -- noted here rather than
"fixed," since there's no observable bug to fix (a guard limiting the ccb-bootstrap
prologue to LineEvent_Offhook specifically would be more obviously correct, but this
phase is about finishing the stress tests, not auditing Line::emit, and the current
behavior is already provably safe).
Verification: -t 9001 standalone clean (both counted above). make wipedb && make reg (110 tests now, -V9001 appended as the final reg line) matches the established
baseline exactly. Grand-total ASAN/UBSAN rebuild clean. Pico cross-build unaffected
(sim_tests.cc is simulator-only, not in CMakeLists.txt's source list) and confirmed to
still build clean.
With this, PLAN.md's Phase 3 step 5 (previously explicitly deferred as optional) is done, and every phase in the plan is now complete.