Ctrl K
ComunidadGuías…

run-all-tests.log

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
Logs directory: /tmp/vpn-switch-test-results-20260203-153644

==> Running tests on FreeBSD (local)
==>   vpn-switch-unit-test.sh (minimal profile)
==>   vpn-switch-unit-test.sh (all profile)
==>   vpn-switch-integration-test.sh (minimal profile)
==>   vpn-switch-integration-test.sh (all profile)
==>   vpn-switch-architecture-test.sh (minimal profile)
==>   vpn-switch-architecture-test.sh (all profile)

================================================================================
Test Results Summary - Tue Feb  3 19:44:51 CET 2026
================================================================================

Status | Platform | Test Suite                          | Profile | Tests | Assert | Passed | Failed
-------|----------|-------------------------------------|---------|-------|--------|--------|-------
PASS   | FreeBSD  | vpn-switch-unit-test.sh             | minimal |   146 |    371 |    371 |      0
PASS   | FreeBSD  | vpn-switch-unit-test.sh             | all     |   146 |    371 |    371 |      0
PASS   | FreeBSD  | vpn-switch-integration-test.sh      | minimal |    12 |    296 |    296 |      0
PASS   | FreeBSD  | vpn-switch-integration-test.sh      | all     |    12 |    296 |    296 |      0
PASS   | FreeBSD  | vpn-switch-architecture-test.sh     | minimal |   238 |    412 |    412 |      0
PASS   | FreeBSD  | vpn-switch-architecture-test.sh     | all     |   238 |    408 |    408 |      0
================================================================================

ALL TESTS PASSED

Total: 792 tests, 2154 assertions (2154 passed, 0 failed)

Detailed logs saved to: /tmp/vpn-switch-test-results-20260203-153644

Logs directory: /tmp/vpn-switch-test-results-20260203-153649

==> Running tests on Debian (brj@calabria.local)
==>   Syncing code to remote...
==>   Setting platform symlink...
==>   vpn-switch-unit-test.sh (minimal profile)
==>   vpn-switch-unit-test.sh (all profile)
==>   vpn-switch-integration-test.sh (minimal profile)
==>   vpn-switch-integration-test.sh (all profile)
==>   vpn-switch-architecture-test.sh (minimal profile)
==>   vpn-switch-architecture-test.sh (all profile)

================================================================================
Test Results Summary - Tue Feb  3 20:48:02 CET 2026
================================================================================

Status | Platform | Test Suite                          | Profile | Tests | Assert | Passed | Failed
-------|----------|-------------------------------------|---------|-------|--------|--------|-------
PASS   | Debian   | vpn-switch-unit-test.sh             | minimal |   146 |    371 |    371 |      0
PASS   | Debian   | vpn-switch-unit-test.sh             | all     |   146 |    371 |    371 |      0
PASS   | Debian   | vpn-switch-integration-test.sh      | minimal |    12 |    296 |    296 |      0
PASS   | Debian   | vpn-switch-integration-test.sh      | all     |    12 |    296 |    296 |      0
PASS   | Debian   | vpn-switch-architecture-test.sh     | minimal |   238 |    410 |    410 |      0
PASS   | Debian   | vpn-switch-architecture-test.sh     | all     |   238 |    410 |    410 |      0
================================================================================

ALL TESTS PASSED

Total: 792 tests, 2154 assertions (2154 passed, 0 failed)

Detailed logs saved to: /tmp/vpn-switch-test-results-20260203-153649

========================================
vpn-switch Architecture Test Suite
========================================

Testing architectural rules for combinator functions
Profile: all

Running Combinator Tests
========================================

Found 28 combinator functions


TEST 1: Combinator: __session_exists1 - validate syntax with variations
✓ __session_exists1: Valid combinator syntax (all variations)

TEST 2: Combinator: __session_conflicts2 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-1]
✓ __session_conflicts2: Valid combinator syntax (all variations)

TEST 3: Combinator: __interface_check1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-2]
✓ __interface_check1: Valid combinator syntax (all variations)

TEST 4: Combinator: __stop1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-3]
✓ __stop1: Valid combinator syntax (all variations)

TEST 5: Combinator: __import1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-4]
✓ __import1: Valid combinator syntax (all variations)

TEST 6: Combinator: __start1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-5]
✓ __start1: Valid combinator syntax (all variations)

TEST 7: Combinator: __start0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-6]
✓ __start0: Valid combinator syntax (all variations)

TEST 8: Combinator: __bootstrap1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-7]
✓ __bootstrap1: Valid combinator syntax (all variations)

TEST 9: Combinator: __environment_cache0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-8]
✓ __environment_cache0: Valid combinator syntax (all variations)

TEST 10: Combinator: __phases_lift1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-9]
✓ __phases_lift1: Valid combinator syntax (all variations)

TEST 11: Combinator: __init0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-10]
✓ __init0: Valid combinator syntax (all variations)

TEST 12: Combinator: __batch1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-11]
✓ __batch1: Valid combinator syntax (all variations)

TEST 13: Combinator: __restore1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-12]
✓ __restore1: Valid combinator syntax (all variations)

TEST 14: Combinator: __openvpn_start0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-13]
✓ __openvpn_start0: Valid combinator syntax (all variations)

TEST 15: Combinator: __openvpn_start1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-14]
✓ __openvpn_start1: Valid combinator syntax (all variations)

TEST 16: Combinator: __openvpn_stop1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-15]
✓ __openvpn_stop1: Valid combinator syntax (all variations)

TEST 17: Combinator: __openvpn_add2 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-16]
✓ __openvpn_add2: Valid combinator syntax (all variations)

TEST 18: Combinator: __openvpn_help0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-17]
✓ __openvpn_help0: Valid combinator syntax (all variations)

TEST 19: Combinator: __session_disconnect1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-18]
✓ __session_disconnect1: Valid combinator syntax (all variations)

TEST 20: Combinator: __session_show0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-19]
✓ __session_show0: Valid combinator syntax (all variations)

TEST 21: Combinator: __session_start0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-20]
✓ __session_start0: Valid combinator syntax (all variations)

TEST 22: Combinator: __session_start1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-21]
✓ __session_start1: Valid combinator syntax (all variations)

TEST 23: Combinator: __session_help0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-22]
✓ __session_help0: Valid combinator syntax (all variations)

TEST 24: Combinator: __wireguard_start0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-23]
✓ __wireguard_start0: Valid combinator syntax (all variations)

TEST 25: Combinator: __wireguard_start1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-24]
✓ __wireguard_start1: Valid combinator syntax (all variations)

TEST 26: Combinator: __wireguard_stop1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-25]
✓ __wireguard_stop1: Valid combinator syntax (all variations)

TEST 27: Combinator: __wireguard_add2 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-26]
✓ __wireguard_add2: Valid combinator syntax (all variations)

TEST 28: Combinator: __wireguard_help0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-27]
✓ __wireguard_help0: Valid combinator syntax (all variations)

Running Batch Combinator Tests
========================================

Found 26 batch combinator functions


TEST 29: Batch Combinator: ___session_prepare3 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-28]
✓ ___session_prepare3: Valid batch combinator syntax (all variations)

TEST 30: Batch Combinator: ___stop0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-29]
✓ ___stop0: Valid batch combinator syntax (all variations)

TEST 31: Batch Combinator: ___phases_sync1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-30]
✓ ___phases_sync1: Valid batch combinator syntax (all variations)

TEST 32: Batch Combinator: ___phases_sync0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-31]
✓ ___phases_sync0: Valid batch combinator syntax (all variations)

TEST 33: Batch Combinator: ___list0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-32]
✓ ___list0: Valid batch combinator syntax (all variations)

TEST 34: Batch Combinator: ___bootstrap2 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-33]
✓ ___bootstrap2: Valid batch combinator syntax (all variations)

TEST 35: Batch Combinator: ___init1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-34]
✓ ___init1: Valid batch combinator syntax (all variations)

TEST 36: Batch Combinator: ___dumpenv1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-35]
✓ ___dumpenv1: Valid batch combinator syntax (all variations)

TEST 37: Batch Combinator: ___dump0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-36]
✓ ___dump0: Valid batch combinator syntax (all variations)

TEST 38: Batch Combinator: ___batch0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-37]
✓ ___batch0: Valid batch combinator syntax (all variations)

TEST 39: Batch Combinator: ___environment_inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-38]
✓ ___environment_inspect0: Valid batch combinator syntax (all variations)

TEST 40: Batch Combinator: ___inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-39]
✓ ___inspect0: Valid batch combinator syntax (all variations)

TEST 41: Batch Combinator: ___openvpn_create1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-40]
✓ ___openvpn_create1: Valid batch combinator syntax (all variations)

TEST 42: Batch Combinator: ___openvpn_stop0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-41]
✓ ___openvpn_stop0: Valid batch combinator syntax (all variations)

TEST 43: Batch Combinator: ___openvpn_inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-42]
✓ ___openvpn_inspect0: Valid batch combinator syntax (all variations)

TEST 44: Batch Combinator: ___openvpn_clean0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-43]
✓ ___openvpn_clean0: Valid batch combinator syntax (all variations)

TEST 45: Batch Combinator: ___openvpn_dump0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-44]
✓ ___openvpn_dump0: Valid batch combinator syntax (all variations)

TEST 46: Batch Combinator: ___session_dump0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-45]
✓ ___session_dump0: Valid batch combinator syntax (all variations)

TEST 47: Batch Combinator: ___session_inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-46]
✓ ___session_inspect0: Valid batch combinator syntax (all variations)

TEST 48: Batch Combinator: ___validate0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-47]
✓ ___validate0: Valid batch combinator syntax (all variations)

TEST 49: Batch Combinator: ___wireguard_create1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-48]
✓ ___wireguard_create1: Valid batch combinator syntax (all variations)

TEST 50: Batch Combinator: ___wireguard_inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-49]
✓ ___wireguard_inspect0: Valid batch combinator syntax (all variations)

TEST 51: Batch Combinator: ___wireguard_stop0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-50]
✓ ___wireguard_stop0: Valid batch combinator syntax (all variations)

TEST 52: Batch Combinator: ___wireguard_clean0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-51]
✓ ___wireguard_clean0: Valid batch combinator syntax (all variations)

TEST 53: Batch Combinator: ___wireguard_clean1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-52]
✓ ___wireguard_clean1: Valid batch combinator syntax (all variations)

TEST 54: Batch Combinator: ___wireguard_dump0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.40159/test-53]
✓ ___wireguard_dump0: Valid batch combinator syntax (all variations)

Running Terminal Function Tests
========================================

Found 83 terminal functions


TEST 55: Terminal: _session_create1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-54]
✓ _session_create1: Valid terminal function output (all variations)

TEST 56: Terminal: _interface_destroy1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-55]
✓ _interface_destroy1: Valid terminal function output (all variations)

TEST 57: Terminal: _session_populate3 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-56]
✓ _session_populate3: Valid terminal function output (all variations)

TEST 58: Terminal: _phases_copy0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-57]
✓ _phases_copy0: Valid terminal function output (all variations)

TEST 59: Terminal: _link2 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-58]
✓ _link2: Valid terminal function output (all variations)

TEST 60: Terminal: _remove1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-59]
✓ _remove1: Valid terminal function output (all variations)

TEST 61: Terminal: _error1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-60]
✓ _error1: Valid terminal function output (all variations)

TEST 62: Terminal: _error2 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-61]
✓ _error2: Valid terminal function output (all variations)

TEST 63: Terminal: _error3 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-62]
✓ _error3: Valid terminal function output (all variations)

TEST 64: Terminal: _fail2 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-63]
✓ _fail2: Valid terminal function output (all variations)

TEST 65: Terminal: _log1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-64]
✓ _log1: Valid terminal function output (all variations)

TEST 66: Terminal: _log2 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-65]
✓ _log2: Valid terminal function output (all variations)

TEST 67: Terminal: _log3 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-66]
✓ _log3: Valid terminal function output (all variations)

TEST 68: Terminal: _lift1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-67]
✓ _lift1: Valid terminal function output (all variations)

TEST 69: Terminal: _database_init0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-68]
✓ _database_init0: Valid terminal function output (all variations)

TEST 70: Terminal: _environment_init1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-69]
✓ _environment_init1: Valid terminal function output (all variations)

TEST 71: Terminal: _environment_cache1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-70]
✓ _environment_cache1: Valid terminal function output (all variations)

TEST 72: Terminal: _lift3 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-71]
✓ _lift3: Valid terminal function output (all variations)

TEST 73: Terminal: _setenv2 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-72]
✓ _setenv2: Valid terminal function output (all variations)

TEST 74: Terminal: _getenv1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-73]
✓ _getenv1: Valid terminal function output (all variations)

TEST 75: Terminal: _unsetenv1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-74]
✓ _unsetenv1: Valid terminal function output (all variations)
  Skipped: _cat1 (requires special setup)

TEST 76: Terminal: _batch2 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-75]
✓ _batch2: Valid terminal function output (all variations)

TEST 77: Terminal: _printenv0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-76]
✓ _printenv0: Valid terminal function output (all variations)

TEST 78: Terminal: _status0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-77]
✓ _status0: Valid terminal function output (all variations)

TEST 79: Terminal: _help0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-78]
✓ _help0: Valid terminal function output (all variations)

TEST 80: Terminal: _help1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-79]
✓ _help1: Valid terminal function output (all variations)

TEST 81: Terminal: _database_enumerate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-80]
✓ _database_enumerate0: Valid terminal function output (all variations)

TEST 82: Terminal: _system_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-81]
✓ _system_inspect0: Valid terminal function output (all variations)

TEST 83: Terminal: _logs_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-82]
✓ _logs_inspect0: Valid terminal function output (all variations)

TEST 84: Terminal: _phases_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-83]
✓ _phases_inspect0: Valid terminal function output (all variations)

TEST 85: Terminal: _summary_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-84]
✓ _summary_inspect0: Valid terminal function output (all variations)

TEST 86: Terminal: _prologue_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-85]
✓ _prologue_inspect0: Valid terminal function output (all variations)

TEST 87: Terminal: _openvpn_patch2 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-86]
✓ _openvpn_patch2: Valid terminal function output (all variations)

TEST 88: Terminal: _openvpn_configure1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-87]
✓ _openvpn_configure1: Valid terminal function output (all variations)

TEST 89: Terminal: _openvpn_connect1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-88]
✓ _openvpn_connect1: Valid terminal function output (all variations)

TEST 90: Terminal: _openvpn_disconnect1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-89]
✓ _openvpn_disconnect1: Valid terminal function output (all variations)

TEST 91: Terminal: _openvpn_patch1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-90]
✓ _openvpn_patch1: Valid terminal function output (all variations)

TEST 92: Terminal: _openvpn_enumerate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-91]
✓ _openvpn_enumerate0: Valid terminal function output (all variations)

TEST 93: Terminal: _openvpn_import1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-92]
✓ _openvpn_import1: Valid terminal function output (all variations)

TEST 94: Terminal: _openvpn_list0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-93]
✓ _openvpn_list0: Valid terminal function output (all variations)

TEST 95: Terminal: _openvpn_list1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-94]
✓ _openvpn_list1: Valid terminal function output (all variations)

TEST 96: Terminal: _openvpn_add1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-95]
✓ _openvpn_add1: Valid terminal function output (all variations)

TEST 97: Terminal: _openvpn_add3 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-96]
✓ _openvpn_add3: Valid terminal function output (all variations)

TEST 98: Terminal: _openvpn_link2 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-97]
✓ _openvpn_link2: Valid terminal function output (all variations)

TEST 99: Terminal: _openvpn_remove1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-98]
✓ _openvpn_remove1: Valid terminal function output (all variations)

TEST 100: Terminal: _openvpn_remove2 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-99]
✓ _openvpn_remove2: Valid terminal function output (all variations)

TEST 101: Terminal: _openvpn_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-100]
✓ _openvpn_validate0: Valid terminal function output (all variations)

TEST 102: Terminal: _openvpn_info1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-101]
✓ _openvpn_info1: Valid terminal function output (all variations)

TEST 103: Terminal: _session_list0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-102]
✓ _session_list0: Valid terminal function output (all variations)

TEST 104: Terminal: _session_show1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-103]
✓ _session_show1: Valid terminal function output (all variations)

TEST 105: Terminal: _session_remove1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-104]
✓ _session_remove1: Valid terminal function output (all variations)

TEST 106: Terminal: _session_connect1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-105]
✓ _session_connect1: Valid terminal function output (all variations)

TEST 107: Terminal: _session_save0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-106]
✓ _session_save0: Valid terminal function output (all variations)

TEST 108: Terminal: _session_save1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-107]
✓ _session_save1: Valid terminal function output (all variations)

TEST 109: Terminal: _session_clean0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-108]
✓ _session_clean0: Valid terminal function output (all variations)

TEST 110: Terminal: _session_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-109]
✓ _session_validate0: Valid terminal function output (all variations)

TEST 111: Terminal: _session_enumerate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-110]
✓ _session_enumerate0: Valid terminal function output (all variations)

TEST 112: Terminal: _session_describe0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-111]
✓ _session_describe0: Valid terminal function output (all variations)

TEST 113: Terminal: _logs_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-112]
✓ _logs_validate0: Valid terminal function output (all variations)

TEST 114: Terminal: _logs_clean0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-113]
✓ _logs_clean0: Valid terminal function output (all variations)

TEST 115: Terminal: _phases_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-114]
✓ _phases_validate0: Valid terminal function output (all variations)

TEST 116: Terminal: _database_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-115]
✓ _database_validate0: Valid terminal function output (all variations)

TEST 117: Terminal: _binaries_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-116]
✓ _binaries_validate0: Valid terminal function output (all variations)

TEST 118: Terminal: _network_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-117]
✓ _network_validate0: Valid terminal function output (all variations)

TEST 119: Terminal: _permissions_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-118]
✓ _permissions_validate0: Valid terminal function output (all variations)

TEST 120: Terminal: _environment_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-119]
✓ _environment_validate0: Valid terminal function output (all variations)

TEST 121: Terminal: _wireguard_patch2 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-120]
✓ _wireguard_patch2: Valid terminal function output (all variations)

TEST 122: Terminal: _wireguard_configure1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-121]
✓ _wireguard_configure1: Valid terminal function output (all variations)

TEST 123: Terminal: _wireguard_connect1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-122]
✓ _wireguard_connect1: Valid terminal function output (all variations)

TEST 124: Terminal: _wireguard_disconnect1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-123]
✓ _wireguard_disconnect1: Valid terminal function output (all variations)

TEST 125: Terminal: _wireguard_enumerate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-124]
✓ _wireguard_enumerate0: Valid terminal function output (all variations)

TEST 126: Terminal: _wireguard_import1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-125]
✓ _wireguard_import1: Valid terminal function output (all variations)

TEST 127: Terminal: _wireguard_list0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-126]
✓ _wireguard_list0: Valid terminal function output (all variations)

TEST 128: Terminal: _wireguard_list1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-127]
✓ _wireguard_list1: Valid terminal function output (all variations)

TEST 129: Terminal: _wireguard_add1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-128]
✓ _wireguard_add1: Valid terminal function output (all variations)

TEST 130: Terminal: _wireguard_add3 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-129]
✓ _wireguard_add3: Valid terminal function output (all variations)

TEST 131: Terminal: _wireguard_link2 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-130]
✓ _wireguard_link2: Valid terminal function output (all variations)

TEST 132: Terminal: _wireguard_remove1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-131]
✓ _wireguard_remove1: Valid terminal function output (all variations)

TEST 133: Terminal: _wireguard_remove2 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-132]
✓ _wireguard_remove2: Valid terminal function output (all variations)

TEST 134: Terminal: _wireguard_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-133]
✓ _wireguard_validate0: Valid terminal function output (all variations)

TEST 135: Terminal: _wireguard_patch1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-134]
✓ _wireguard_patch1: Valid terminal function output (all variations)

TEST 136: Terminal: _wireguard_info1 - validate output rules [db: /tmp/vpn-switch-arch-test.40159/test-135]
✓ _wireguard_info1: Valid terminal function output (all variations)

Running Error Propagation Tests (KEEP_GOING)
========================================


TEST 137: Batch Error Propagation - test _batch2 with failing commands [db: /tmp/vpn-switch-arch-test.40159/test-136]

TEST 138:   Sub-test: KEEP_GOING=0 (fail-fast mode) [db: /tmp/vpn-switch-arch-test.40159/test-137]
✓ KEEP_GOING=0: Batch execution stopped on first error

TEST 139:   Sub-test: KEEP_GOING=1 (continue mode) [db: /tmp/vpn-switch-arch-test.40159/test-137]
✓ KEEP_GOING=1: Batch execution completed despite errors
✓ KEEP_GOING=1: All commands were executed (count=3)

TEST 140: Recursive Batch Error Propagation - test chained _batch2 calls [db: /tmp/vpn-switch-arch-test.40159/test-137]
✓ Recursive fail-fast: Command 3 in batch 3 was not executed
✓ Recursive fail-fast: Batch 2 stopped after error in batch 3
✓ Recursive fail-fast: Batch 1 stopped after error in nested batch
✓ Recursive continue: Batch 2 continued after error in batch 3
✓ Recursive continue: Batch 1 continued after error in nested batch

TEST 141: Batch KEEP_GOING with Realistic Dump File [db: /tmp/vpn-switch-arch-test.40159/test-140]
✓ Created realistic batch file with 8 commands
✓ Selected command at position 6/8 for failure injection

TEST 142:   Sub-test: KEEP_GOING=0 at position 6/8 [db: /tmp/vpn-switch-arch-test.40159/test-141]
✓ KEEP_GOING=0: Stopped at or before position 6 (executed 6 commands)
✓ KEEP_GOING=0: Error stop message present

TEST 143:   Sub-test: KEEP_GOING=1 at position 6/8 [db: /tmp/vpn-switch-arch-test.40159/test-141]
✓ KEEP_GOING=1: All commands executed (8/8)
✓ KEEP_GOING=1: Completion message present
✓ KEEP_GOING=1: Failure markers present in output

Running Batch Combinator Error Propagation Tests
========================================

Testing ALL batch combinators with error injection and KEEP_GOING validation
Found 26 batch combinator functions


TEST 144: Batch Transitive Hull: ___session_prepare3 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-141]

TEST 145:   Sub-test: Walk command tree for '___session_prepare3' (command: session_prepare) [db: /tmp/vpn-switch-arch-test.40159/test-144]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 8 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 146: Batch Transitive Hull: ___stop0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-144]

TEST 147:   Sub-test: Walk command tree for '___stop0' (command: stop) [db: /tmp/vpn-switch-arch-test.40159/test-146]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 148:   Sub-test: Inject failure at node '___stop0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-146]
✓ KEEP_GOING affects output: fail-fast=       4 lines, continue=       4 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 149: Batch Transitive Hull: ___phases_sync1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-146]

TEST 150:   Sub-test: Walk command tree for '___phases_sync1' (command: phases_sync) [db: /tmp/vpn-switch-arch-test.40159/test-149]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 151:   Sub-test: Inject failure at node '___phases_sync0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-149]
✓ KEEP_GOING affects output: fail-fast=       4 lines, continue=       4 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 152: Batch Transitive Hull: ___phases_sync0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-149]

TEST 153:   Sub-test: Walk command tree for '___phases_sync0' (command: phases_sync) [db: /tmp/vpn-switch-arch-test.40159/test-152]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 154:   Sub-test: Inject failure at node '___phases_sync0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-152]
✓ KEEP_GOING affects output: fail-fast=       4 lines, continue=       4 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 155: Batch Transitive Hull: ___list0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-152]

TEST 156:   Sub-test: Walk command tree for '___list0' (command: list) [db: /tmp/vpn-switch-arch-test.40159/test-155]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 157:   Sub-test: Inject failure at node '___list0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-155]
✓ KEEP_GOING affects output: fail-fast=       2 lines, continue=       2 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 158: Batch Transitive Hull: ___bootstrap2 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-155]

TEST 159:   Sub-test: Walk command tree for '___bootstrap2' (command: bootstrap) [db: /tmp/vpn-switch-arch-test.40159/test-158]
✓ Command tree collected: 2 nodes in transitive hull
✓ Found 6 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 160: Batch Transitive Hull: ___init1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-158]

TEST 161:   Sub-test: Walk command tree for '___init1' (command: init) [db: /tmp/vpn-switch-arch-test.40159/test-160]
✓ Command tree collected: 2 nodes in transitive hull
✓ Found 1 injectable nodes (combinators/batches) in tree

TEST 162:   Sub-test: Inject failure at node '__init0' (node 1/1) [db: /tmp/vpn-switch-arch-test.40159/test-160]
✓ KEEP_GOING affects output: fail-fast=       1 lines, continue=       1 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 163: Batch Transitive Hull: ___dumpenv1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-160]

TEST 164:   Sub-test: Walk command tree for '___dumpenv1' (command: dumpenv) [db: /tmp/vpn-switch-arch-test.40159/test-163]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 8 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 165: Batch Transitive Hull: ___dump0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-163]

TEST 166:   Sub-test: Walk command tree for '___dump0' (command: dump) [db: /tmp/vpn-switch-arch-test.40159/test-165]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 167:   Sub-test: Inject failure at node '___dump0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-165]
✓ KEEP_GOING affects output: fail-fast=      17 lines, continue=      17 lines
    Note: No clear error stop indicator in fail-fast mode
✓ KEEP_GOING=1: Execution completed despite injected failure

TEST 168: Batch Transitive Hull: ___batch0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-165]

TEST 169:   Sub-test: Walk command tree for '___batch0' (command: batch) [db: /tmp/vpn-switch-arch-test.40159/test-168]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 170:   Sub-test: Inject failure at node '___batch0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-168]
✓ KEEP_GOING affects output: fail-fast=       2 lines, continue=       2 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 171: Batch Transitive Hull: ___environment_inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-168]

TEST 172:   Sub-test: Walk command tree for '___environment_inspect0' (command: environment_inspect) [db: /tmp/vpn-switch-arch-test.40159/test-171]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 173:   Sub-test: Inject failure at node '___environment_inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-171]
✓ KEEP_GOING affects output: fail-fast=       3 lines, continue=       3 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 174: Batch Transitive Hull: ___inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-171]

TEST 175:   Sub-test: Walk command tree for '___inspect0' (command: inspect) [db: /tmp/vpn-switch-arch-test.40159/test-174]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 176:   Sub-test: Inject failure at node '___inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-174]
✓ KEEP_GOING affects output: fail-fast=      12 lines, continue=      12 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 177: Batch Transitive Hull: ___openvpn_create1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-174]

TEST 178:   Sub-test: Walk command tree for '___openvpn_create1' (command: openvpn_create) [db: /tmp/vpn-switch-arch-test.40159/test-177]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 8 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 179: Batch Transitive Hull: ___openvpn_stop0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-177]

TEST 180:   Sub-test: Walk command tree for '___openvpn_stop0' (command: openvpn_stop) [db: /tmp/vpn-switch-arch-test.40159/test-179]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 1 injectable nodes (combinators/batches) in tree

TEST 181:   Sub-test: Inject failure at node '___openvpn_stop0' (node 1/1) [db: /tmp/vpn-switch-arch-test.40159/test-179]
✓ KEEP_GOING affects output: fail-fast=       1 lines, continue=       1 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 182: Batch Transitive Hull: ___openvpn_inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-179]

TEST 183:   Sub-test: Walk command tree for '___openvpn_inspect0' (command: openvpn_inspect) [db: /tmp/vpn-switch-arch-test.40159/test-182]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 184:   Sub-test: Inject failure at node '___openvpn_inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-182]
✓ KEEP_GOING affects output: fail-fast=       7 lines, continue=       7 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 185: Batch Transitive Hull: ___openvpn_clean0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-182]

TEST 186:   Sub-test: Walk command tree for '___openvpn_clean0' (command: openvpn_clean) [db: /tmp/vpn-switch-arch-test.40159/test-185]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 3 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 187: Batch Transitive Hull: ___openvpn_dump0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-185]

TEST 188:   Sub-test: Walk command tree for '___openvpn_dump0' (command: openvpn_dump) [db: /tmp/vpn-switch-arch-test.40159/test-187]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 189:   Sub-test: Inject failure at node '___openvpn_dump0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-187]
✓ KEEP_GOING affects output: fail-fast=      20 lines, continue=      20 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 190: Batch Transitive Hull: ___session_dump0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-187]

TEST 191:   Sub-test: Walk command tree for '___session_dump0' (command: session_dump) [db: /tmp/vpn-switch-arch-test.40159/test-190]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 192:   Sub-test: Inject failure at node '___session_dump0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-190]
✓ KEEP_GOING affects output: fail-fast=      41 lines, continue=      41 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 193: Batch Transitive Hull: ___session_inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-190]

TEST 194:   Sub-test: Walk command tree for '___session_inspect0' (command: session_inspect) [db: /tmp/vpn-switch-arch-test.40159/test-193]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 195:   Sub-test: Inject failure at node '___session_inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-193]
✓ KEEP_GOING affects output: fail-fast=       5 lines, continue=       5 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 196: Batch Transitive Hull: ___validate0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-193]

TEST 197:   Sub-test: Walk command tree for '___validate0' (command: validate) [db: /tmp/vpn-switch-arch-test.40159/test-196]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 198:   Sub-test: Inject failure at node '___validate0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-196]
✓ KEEP_GOING affects output: fail-fast=      10 lines, continue=      10 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 199: Batch Transitive Hull: ___wireguard_create1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-196]

TEST 200:   Sub-test: Walk command tree for '___wireguard_create1' (command: wireguard_create) [db: /tmp/vpn-switch-arch-test.40159/test-199]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 8 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 201: Batch Transitive Hull: ___wireguard_inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-199]

TEST 202:   Sub-test: Walk command tree for '___wireguard_inspect0' (command: wireguard_inspect) [db: /tmp/vpn-switch-arch-test.40159/test-201]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 203:   Sub-test: Inject failure at node '___wireguard_inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-201]
✓ KEEP_GOING affects output: fail-fast=       7 lines, continue=       7 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 204: Batch Transitive Hull: ___wireguard_stop0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-201]

TEST 205:   Sub-test: Walk command tree for '___wireguard_stop0' (command: wireguard_stop) [db: /tmp/vpn-switch-arch-test.40159/test-204]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 1 injectable nodes (combinators/batches) in tree

TEST 206:   Sub-test: Inject failure at node '___wireguard_stop0' (node 1/1) [db: /tmp/vpn-switch-arch-test.40159/test-204]
✓ KEEP_GOING affects output: fail-fast=       1 lines, continue=       1 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 207: Batch Transitive Hull: ___wireguard_clean0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-204]

TEST 208:   Sub-test: Walk command tree for '___wireguard_clean0' (command: wireguard_clean) [db: /tmp/vpn-switch-arch-test.40159/test-207]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 3 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 209: Batch Transitive Hull: ___wireguard_clean1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-207]

TEST 210:   Sub-test: Walk command tree for '___wireguard_clean1' (command: wireguard_clean) [db: /tmp/vpn-switch-arch-test.40159/test-209]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 3 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 211: Batch Transitive Hull: ___wireguard_dump0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.40159/test-209]

TEST 212:   Sub-test: Walk command tree for '___wireguard_dump0' (command: wireguard_dump) [db: /tmp/vpn-switch-arch-test.40159/test-211]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 213:   Sub-test: Inject failure at node '___wireguard_dump0' (node 1/2) [db: /tmp/vpn-switch-arch-test.40159/test-211]
✓ KEEP_GOING affects output: fail-fast=      42 lines, continue=      42 lines
    Note: No clear error stop indicator in fail-fast mode
✓ KEEP_GOING=1: Execution completed despite injected failure

Running Batch Combinator KEEP_GOING Precise Tests
========================================

Testing ALL batch combinators with precise architectural KEEP_GOING validation
Found 26 batch combinator functions


TEST 214: Batch KEEP_GOING Precise: ___session_prepare3 [db: /tmp/vpn-switch-arch-test.40159/test-211]
✓ Captured 175 command lines from ___session_prepare3
✓ Selected 95 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 215: Batch KEEP_GOING Precise: ___stop0 [db: /tmp/vpn-switch-arch-test.40159/test-214]
✓ Captured 2 command lines from ___stop0
✓ Selected 1 random line(s) for failure injection
✓ Injected failures into 1 function(s)
  Note: Not all commands attempted (0/2)
  Note: This may indicate KEEP_GOING=0 or execution stopped early
  Skipped: ___phases_sync1 (requires phase template setup)
  Skipped: ___phases_sync0 (requires phase template setup)

TEST 216: Batch KEEP_GOING Precise: ___list0 [db: /tmp/vpn-switch-arch-test.40159/test-215]
✓ Captured 2 command lines from ___list0
✓ Selected 1 random line(s) for failure injection
✓ Injected failures into 1 function(s)
✓ KEEP_GOING=1: All commands attempted (2/2)

TEST 217: Batch KEEP_GOING Precise: ___bootstrap2 [db: /tmp/vpn-switch-arch-test.40159/test-216]
✓ Captured 73 command lines from ___bootstrap2
✓ Selected 67 random line(s) for failure injection
  Skipped: No functions were injected with failures
  Skipped: ___init1 (complex initialization logic)

TEST 218: Batch KEEP_GOING Precise: ___dumpenv1 [db: /tmp/vpn-switch-arch-test.40159/test-217]
✓ Captured 175 command lines from ___dumpenv1
✓ Selected 62 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 219: Batch KEEP_GOING Precise: ___dump0 [db: /tmp/vpn-switch-arch-test.40159/test-218]
✓ Captured 5 command lines from ___dump0
✓ Selected 4 random line(s) for failure injection
✓ Injected failures into 3 function(s)
  Note: Not all commands attempted (3/5)
  Note: This may indicate KEEP_GOING=0 or execution stopped early

TEST 220: Batch KEEP_GOING Precise: ___batch0 [db: /tmp/vpn-switch-arch-test.40159/test-219]
✓ Captured 2 command lines from ___batch0
✓ Selected 1 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 221: Batch KEEP_GOING Precise: ___environment_inspect0 [db: /tmp/vpn-switch-arch-test.40159/test-220]
✓ Captured 2 command lines from ___environment_inspect0
✓ Selected 2 random line(s) for failure injection
✓ Injected failures into 2 function(s)
  Note: Not all commands attempted (2/3)
  Note: This may indicate KEEP_GOING=0 or execution stopped early

TEST 222: Batch KEEP_GOING Precise: ___inspect0 [db: /tmp/vpn-switch-arch-test.40159/test-221]
✓ Captured 12 command lines from ___inspect0
✓ Selected 1 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 223: Batch KEEP_GOING Precise: ___openvpn_create1 [db: /tmp/vpn-switch-arch-test.40159/test-222]
✓ Captured 175 command lines from ___openvpn_create1
✓ Selected 52 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 224: Batch KEEP_GOING Precise: ___openvpn_stop0 [db: /tmp/vpn-switch-arch-test.40159/test-223]
✓ Captured 1 command lines from ___openvpn_stop0
✓ Selected 1 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 225: Batch KEEP_GOING Precise: ___openvpn_inspect0 [db: /tmp/vpn-switch-arch-test.40159/test-224]
✓ Captured 3 command lines from ___openvpn_inspect0
✓ Selected 2 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 226: Batch KEEP_GOING Precise: ___openvpn_clean0 [db: /tmp/vpn-switch-arch-test.40159/test-225]
✓ Captured 3 command lines from ___openvpn_clean0
✓ Selected 3 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 227: Batch KEEP_GOING Precise: ___openvpn_dump0 [db: /tmp/vpn-switch-arch-test.40159/test-226]
✓ Captured 13 command lines from ___openvpn_dump0
✓ Selected 13 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 228: Batch KEEP_GOING Precise: ___session_dump0 [db: /tmp/vpn-switch-arch-test.40159/test-227]
✓ Captured 40 command lines from ___session_dump0
✓ Selected 10 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 229: Batch KEEP_GOING Precise: ___session_inspect0 [db: /tmp/vpn-switch-arch-test.40159/test-228]
✓ Captured 4 command lines from ___session_inspect0
✓ Selected 3 random line(s) for failure injection
✓ Injected failures into 3 function(s)
  Note: Not all commands attempted (3/4)
  Note: This may indicate KEEP_GOING=0 or execution stopped early

TEST 230: Batch KEEP_GOING Precise: ___validate0 [db: /tmp/vpn-switch-arch-test.40159/test-229]
✓ Captured 10 command lines from ___validate0
✓ Selected 10 random line(s) for failure injection
✓ Injected failures into 10 function(s)
  Note: Not all commands attempted (10/11)
  Note: This may indicate KEEP_GOING=0 or execution stopped early

TEST 231: Batch KEEP_GOING Precise: ___wireguard_create1 [db: /tmp/vpn-switch-arch-test.40159/test-230]
✓ Captured 175 command lines from ___wireguard_create1
✓ Selected 8 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 232: Batch KEEP_GOING Precise: ___wireguard_inspect0 [db: /tmp/vpn-switch-arch-test.40159/test-231]
✓ Captured 3 command lines from ___wireguard_inspect0
✓ Selected 3 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 233: Batch KEEP_GOING Precise: ___wireguard_stop0 [db: /tmp/vpn-switch-arch-test.40159/test-232]
✓ Captured 1 command lines from ___wireguard_stop0
✓ Selected 1 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 234: Batch KEEP_GOING Precise: ___wireguard_clean0 [db: /tmp/vpn-switch-arch-test.40159/test-233]
✓ Captured 9 command lines from ___wireguard_clean0
✓ Selected 9 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 235: Batch KEEP_GOING Precise: ___wireguard_clean1 [db: /tmp/vpn-switch-arch-test.40159/test-234]
✓ Captured 9 command lines from ___wireguard_clean1
✓ Selected 7 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 236: Batch KEEP_GOING Precise: ___wireguard_dump0 [db: /tmp/vpn-switch-arch-test.40159/test-235]
✓ Captured 34 command lines from ___wireguard_dump0
✓ Selected 11 random line(s) for failure injection
  Skipped: No functions were injected with failures

Running Static Analysis Tests
========================================

Testing architecture violation scanner


TEST 237: Architecture Violation Scanner [db: /tmp/vpn-switch-arch-test.40159/test-236]
✓ Scanner executed successfully (exit code: 0)
  Found: \033[0;31m1\033[0m total violations
✓ Scanner detection working (violations found as expected)
✓ Scanner detects MODIFY_* variable usage

Running Read-Only Database Tests
========================================

Testing that functions don't modify database at generation time


TEST 238: Read-Only Database: All functions [db: /tmp/vpn-switch-arch-test.40159/test-236]
  Testing terminal functions...
✓ _session_create1: No permission errors on read-only database
✓ _interface_destroy1: No permission errors on read-only database
✓ _session_populate3: No permission errors on read-only database
✓ _link2: No permission errors on read-only database
✓ _remove1: No permission errors on read-only database
✓ _error1: No permission errors on read-only database
✓ _error2: No permission errors on read-only database
✓ _error3: No permission errors on read-only database
✓ _fail2: No permission errors on read-only database
✓ _log1: No permission errors on read-only database
✓ _log2: No permission errors on read-only database
✓ _log3: No permission errors on read-only database
✓ _lift1: No permission errors on read-only database
✓ _lift3: No permission errors on read-only database
    Warning: setenv2: output differs between writable/readonly (but compliant)
✓ _setenv2: No permission errors on read-only database
✓ _getenv1: No permission errors on read-only database
✓ _unsetenv1: No permission errors on read-only database
✓ _printenv0: No permission errors on read-only database
    Warning: status0: output differs between writable/readonly (but compliant)
✓ _status0: No permission errors on read-only database
✓ _help0: No permission errors on read-only database
✓ _help1: No permission errors on read-only database
    Warning: database_enumerate0: output differs between writable/readonly (but compliant)
✓ _database_enumerate0: No permission errors on read-only database
✓ _system_inspect0: No permission errors on read-only database
    Warning: logs_inspect0: output differs between writable/readonly (but compliant)
✓ _logs_inspect0: No permission errors on read-only database
✓ _phases_inspect0: No permission errors on read-only database
✓ _summary_inspect0: No permission errors on read-only database
✓ _prologue_inspect0: No permission errors on read-only database
✓ _openvpn_patch2: No permission errors on read-only database
✓ _openvpn_configure1: No permission errors on read-only database
✓ _openvpn_connect1: No permission errors on read-only database
✓ _openvpn_disconnect1: No permission errors on read-only database
✓ _openvpn_patch1: No permission errors on read-only database
    Warning: openvpn_enumerate0: output differs between writable/readonly (but compliant)
✓ _openvpn_enumerate0: No permission errors on read-only database
✓ _openvpn_import1: No permission errors on read-only database
✓ _openvpn_list0: No permission errors on read-only database
✓ _openvpn_list1: No permission errors on read-only database
✓ _openvpn_add1: No permission errors on read-only database
✓ _openvpn_add3: No permission errors on read-only database
✓ _openvpn_link2: No permission errors on read-only database
✓ _openvpn_remove1: No permission errors on read-only database
✓ _openvpn_remove2: No permission errors on read-only database
✓ _openvpn_validate0: No permission errors on read-only database
✓ _openvpn_info1: No permission errors on read-only database
✓ _session_list0: No permission errors on read-only database
✓ _session_show1: No permission errors on read-only database
✓ _session_remove1: No permission errors on read-only database
✓ _session_connect1: No permission errors on read-only database
✓ _session_save0: No permission errors on read-only database
✓ _session_save1: No permission errors on read-only database
✓ _session_clean0: No permission errors on read-only database
✓ _session_validate0: No permission errors on read-only database
✓ _session_enumerate0: No permission errors on read-only database
✓ _session_describe0: No permission errors on read-only database
✓ _logs_validate0: No permission errors on read-only database
✓ _logs_clean0: No permission errors on read-only database
✓ _phases_validate0: No permission errors on read-only database
✓ _database_validate0: No permission errors on read-only database
✓ _binaries_validate0: No permission errors on read-only database
✓ _network_validate0: No permission errors on read-only database
✓ _permissions_validate0: No permission errors on read-only database
✓ _environment_validate0: No permission errors on read-only database
✓ _wireguard_patch2: No permission errors on read-only database
✓ _wireguard_configure1: No permission errors on read-only database
✓ _wireguard_connect1: No permission errors on read-only database
✓ _wireguard_disconnect1: No permission errors on read-only database
    Warning: wireguard_enumerate0: output differs between writable/readonly (but compliant)
✓ _wireguard_enumerate0: No permission errors on read-only database
✓ _wireguard_import1: No permission errors on read-only database
✓ _wireguard_list0: No permission errors on read-only database
✓ _wireguard_list1: No permission errors on read-only database
✓ _wireguard_add1: No permission errors on read-only database
✓ _wireguard_add3: No permission errors on read-only database
✓ _wireguard_link2: No permission errors on read-only database
✓ _wireguard_remove1: No permission errors on read-only database
✓ _wireguard_remove2: No permission errors on read-only database
✓ _wireguard_validate0: No permission errors on read-only database
✓ _wireguard_patch1: No permission errors on read-only database
✓ _wireguard_info1: No permission errors on read-only database

  Testing combinator functions...
✓ __session_exists1: No permission errors on read-only database
✓ __session_conflicts2: No permission errors on read-only database
✓ __interface_check1: No permission errors on read-only database
✓ __stop1: No permission errors on read-only database
✓ __import1: No permission errors on read-only database
✓ __start1: No permission errors on read-only database
✓ __start0: No permission errors on read-only database
✓ __bootstrap1: No permission errors on read-only database
✓ __environment_cache0: No permission errors on read-only database
✓ __phases_lift1: No permission errors on read-only database
✓ __init0: No permission errors on read-only database
✓ __batch1: No permission errors on read-only database
✓ __restore1: No permission errors on read-only database
    Warning: openvpn_start0: output differs between writable/readonly (but compliant)
✓ __openvpn_start0: No permission errors on read-only database
✓ __openvpn_start1: No permission errors on read-only database
✓ __openvpn_stop1: No permission errors on read-only database
✓ __openvpn_add2: No permission errors on read-only database
✓ __openvpn_help0: No permission errors on read-only database
✓ __session_disconnect1: No permission errors on read-only database
✓ __session_show0: No permission errors on read-only database
✓ __session_start0: No permission errors on read-only database
✓ __session_start1: No permission errors on read-only database
✓ __session_help0: No permission errors on read-only database
    Warning: wireguard_start0: output differs between writable/readonly (but compliant)
✓ __wireguard_start0: No permission errors on read-only database
✓ __wireguard_start1: No permission errors on read-only database
✓ __wireguard_stop1: No permission errors on read-only database
✓ __wireguard_add2: No permission errors on read-only database
✓ __wireguard_help0: No permission errors on read-only database

  Testing batch combinator functions...
✓ ___session_prepare3: No permission errors on read-only database
✓ ___stop0: No permission errors on read-only database
✓ ___phases_sync1: No permission errors on read-only database
✓ ___phases_sync0: No permission errors on read-only database
✓ ___list0: No permission errors on read-only database
✓ ___dumpenv1: No permission errors on read-only database
    Warning: dump0: output differs between writable/readonly (but compliant)
✓ ___dump0: No permission errors on read-only database
    Warning: batch0: output differs between writable/readonly (but compliant)
✓ ___batch0: No permission errors on read-only database
✓ ___environment_inspect0: No permission errors on read-only database
✓ ___inspect0: No permission errors on read-only database
    Warning: openvpn_create1: output differs between writable/readonly (but compliant)
✓ ___openvpn_create1: No permission errors on read-only database
✓ ___openvpn_stop0: No permission errors on read-only database
✓ ___openvpn_inspect0: No permission errors on read-only database
✓ ___openvpn_clean0: No permission errors on read-only database
✓ ___openvpn_dump0: No permission errors on read-only database
✓ ___session_dump0: No permission errors on read-only database
✓ ___session_inspect0: No permission errors on read-only database
✓ ___validate0: No permission errors on read-only database
    Warning: wireguard_create1: output differs between writable/readonly (but compliant)
✓ ___wireguard_create1: No permission errors on read-only database
✓ ___wireguard_inspect0: No permission errors on read-only database
✓ ___wireguard_stop0: No permission errors on read-only database
✓ ___wireguard_clean0: No permission errors on read-only database
✓ ___wireguard_clean1: No permission errors on read-only database
✓ ___wireguard_dump0: No permission errors on read-only database

  Summary: Tested 129 functions, skipped 8

========================================
Architecture Test Summary
========================================
Test Functions:     238
Total Assertions:   408
Passed Assertions:  408
Failed Assertions:  0

ALL TESTS PASSED

Cleaning up test databases...
Done.
========================================
vpn-switch Architecture Test Suite
========================================

Testing architectural rules for combinator functions
Profile: minimal

Running Combinator Tests
========================================

Found 28 combinator functions


TEST 1: Combinator: __session_exists1 - validate syntax with variations
✓ __session_exists1: Valid combinator syntax (all variations)

TEST 2: Combinator: __session_conflicts2 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-1]
✓ __session_conflicts2: Valid combinator syntax (all variations)

TEST 3: Combinator: __interface_check1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-2]
✓ __interface_check1: Valid combinator syntax (all variations)

TEST 4: Combinator: __stop1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-3]
✓ __stop1: Valid combinator syntax (all variations)

TEST 5: Combinator: __import1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-4]
✓ __import1: Valid combinator syntax (all variations)

TEST 6: Combinator: __start1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-5]
✓ __start1: Valid combinator syntax (all variations)

TEST 7: Combinator: __start0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-6]
✓ __start0: Valid combinator syntax (all variations)

TEST 8: Combinator: __bootstrap1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-7]
✓ __bootstrap1: Valid combinator syntax (all variations)

TEST 9: Combinator: __environment_cache0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-8]
✓ __environment_cache0: Valid combinator syntax (all variations)

TEST 10: Combinator: __phases_lift1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-9]
✓ __phases_lift1: Valid combinator syntax (all variations)

TEST 11: Combinator: __init0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-10]
✓ __init0: Valid combinator syntax (all variations)

TEST 12: Combinator: __batch1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-11]
✓ __batch1: Valid combinator syntax (all variations)

TEST 13: Combinator: __restore1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-12]
✓ __restore1: Valid combinator syntax (all variations)

TEST 14: Combinator: __openvpn_start0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-13]
✓ __openvpn_start0: Valid combinator syntax (all variations)

TEST 15: Combinator: __openvpn_start1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-14]
✓ __openvpn_start1: Valid combinator syntax (all variations)

TEST 16: Combinator: __openvpn_stop1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-15]
✓ __openvpn_stop1: Valid combinator syntax (all variations)

TEST 17: Combinator: __openvpn_add2 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-16]
✓ __openvpn_add2: Valid combinator syntax (all variations)

TEST 18: Combinator: __openvpn_help0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-17]
✓ __openvpn_help0: Valid combinator syntax (all variations)

TEST 19: Combinator: __session_disconnect1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-18]
✓ __session_disconnect1: Valid combinator syntax (all variations)

TEST 20: Combinator: __session_show0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-19]
✓ __session_show0: Valid combinator syntax (all variations)

TEST 21: Combinator: __session_start0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-20]
✓ __session_start0: Valid combinator syntax (all variations)

TEST 22: Combinator: __session_start1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-21]
✓ __session_start1: Valid combinator syntax (all variations)

TEST 23: Combinator: __session_help0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-22]
✓ __session_help0: Valid combinator syntax (all variations)

TEST 24: Combinator: __wireguard_start0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-23]
✓ __wireguard_start0: Valid combinator syntax (all variations)

TEST 25: Combinator: __wireguard_start1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-24]
✓ __wireguard_start1: Valid combinator syntax (all variations)

TEST 26: Combinator: __wireguard_stop1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-25]
✓ __wireguard_stop1: Valid combinator syntax (all variations)

TEST 27: Combinator: __wireguard_add2 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-26]
✓ __wireguard_add2: Valid combinator syntax (all variations)

TEST 28: Combinator: __wireguard_help0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-27]
✓ __wireguard_help0: Valid combinator syntax (all variations)

Running Batch Combinator Tests
========================================

Found 26 batch combinator functions


TEST 29: Batch Combinator: ___session_prepare3 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-28]
✓ ___session_prepare3: Valid batch combinator syntax (all variations)

TEST 30: Batch Combinator: ___stop0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-29]
✓ ___stop0: Valid batch combinator syntax (all variations)

TEST 31: Batch Combinator: ___phases_sync1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-30]
✓ ___phases_sync1: Valid batch combinator syntax (all variations)

TEST 32: Batch Combinator: ___phases_sync0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-31]
✓ ___phases_sync0: Valid batch combinator syntax (all variations)

TEST 33: Batch Combinator: ___list0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-32]
✓ ___list0: Valid batch combinator syntax (all variations)

TEST 34: Batch Combinator: ___bootstrap2 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-33]
✓ ___bootstrap2: Valid batch combinator syntax (all variations)

TEST 35: Batch Combinator: ___init1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-34]
✓ ___init1: Valid batch combinator syntax (all variations)

TEST 36: Batch Combinator: ___dumpenv1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-35]
✓ ___dumpenv1: Valid batch combinator syntax (all variations)

TEST 37: Batch Combinator: ___dump0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-36]
✓ ___dump0: Valid batch combinator syntax (all variations)

TEST 38: Batch Combinator: ___batch0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-37]
✓ ___batch0: Valid batch combinator syntax (all variations)

TEST 39: Batch Combinator: ___environment_inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-38]
✓ ___environment_inspect0: Valid batch combinator syntax (all variations)

TEST 40: Batch Combinator: ___inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-39]
✓ ___inspect0: Valid batch combinator syntax (all variations)

TEST 41: Batch Combinator: ___openvpn_create1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-40]
✓ ___openvpn_create1: Valid batch combinator syntax (all variations)

TEST 42: Batch Combinator: ___openvpn_stop0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-41]
✓ ___openvpn_stop0: Valid batch combinator syntax (all variations)

TEST 43: Batch Combinator: ___openvpn_inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-42]
✓ ___openvpn_inspect0: Valid batch combinator syntax (all variations)

TEST 44: Batch Combinator: ___openvpn_clean0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-43]
✓ ___openvpn_clean0: Valid batch combinator syntax (all variations)

TEST 45: Batch Combinator: ___openvpn_dump0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-44]
✓ ___openvpn_dump0: Valid batch combinator syntax (all variations)

TEST 46: Batch Combinator: ___session_dump0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-45]
✓ ___session_dump0: Valid batch combinator syntax (all variations)

TEST 47: Batch Combinator: ___session_inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-46]
✓ ___session_inspect0: Valid batch combinator syntax (all variations)

TEST 48: Batch Combinator: ___validate0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-47]
✓ ___validate0: Valid batch combinator syntax (all variations)

TEST 49: Batch Combinator: ___wireguard_create1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-48]
✓ ___wireguard_create1: Valid batch combinator syntax (all variations)

TEST 50: Batch Combinator: ___wireguard_inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-49]
✓ ___wireguard_inspect0: Valid batch combinator syntax (all variations)

TEST 51: Batch Combinator: ___wireguard_stop0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-50]
✓ ___wireguard_stop0: Valid batch combinator syntax (all variations)

TEST 52: Batch Combinator: ___wireguard_clean0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-51]
✓ ___wireguard_clean0: Valid batch combinator syntax (all variations)

TEST 53: Batch Combinator: ___wireguard_clean1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-52]
✓ ___wireguard_clean1: Valid batch combinator syntax (all variations)

TEST 54: Batch Combinator: ___wireguard_dump0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.18197/test-53]
✓ ___wireguard_dump0: Valid batch combinator syntax (all variations)

Running Terminal Function Tests
========================================

Found 83 terminal functions


TEST 55: Terminal: _session_create1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-54]
✓ _session_create1: Valid terminal function output (all variations)

TEST 56: Terminal: _interface_destroy1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-55]
✓ _interface_destroy1: Valid terminal function output (all variations)

TEST 57: Terminal: _session_populate3 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-56]
✓ _session_populate3: Valid terminal function output (all variations)

TEST 58: Terminal: _phases_copy0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-57]
✓ _phases_copy0: Valid terminal function output (all variations)

TEST 59: Terminal: _link2 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-58]
✓ _link2: Valid terminal function output (all variations)

TEST 60: Terminal: _remove1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-59]
✓ _remove1: Valid terminal function output (all variations)

TEST 61: Terminal: _error1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-60]
✓ _error1: Valid terminal function output (all variations)

TEST 62: Terminal: _error2 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-61]
✓ _error2: Valid terminal function output (all variations)

TEST 63: Terminal: _error3 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-62]
✓ _error3: Valid terminal function output (all variations)

TEST 64: Terminal: _fail2 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-63]
✓ _fail2: Valid terminal function output (all variations)

TEST 65: Terminal: _log1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-64]
✓ _log1: Valid terminal function output (all variations)

TEST 66: Terminal: _log2 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-65]
✓ _log2: Valid terminal function output (all variations)

TEST 67: Terminal: _log3 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-66]
✓ _log3: Valid terminal function output (all variations)

TEST 68: Terminal: _lift1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-67]
✓ _lift1: Valid terminal function output (all variations)

TEST 69: Terminal: _database_init0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-68]
✓ _database_init0: Valid terminal function output (all variations)

TEST 70: Terminal: _environment_init1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-69]
✓ _environment_init1: Valid terminal function output (all variations)

TEST 71: Terminal: _environment_cache1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-70]
✓ _environment_cache1: Valid terminal function output (all variations)

TEST 72: Terminal: _lift3 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-71]
✓ _lift3: Valid terminal function output (all variations)

TEST 73: Terminal: _setenv2 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-72]
✓ _setenv2: Valid terminal function output (all variations)

TEST 74: Terminal: _getenv1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-73]
✓ _getenv1: Valid terminal function output (all variations)

TEST 75: Terminal: _unsetenv1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-74]
✓ _unsetenv1: Valid terminal function output (all variations)
  Skipped: _cat1 (requires special setup)

TEST 76: Terminal: _batch2 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-75]
✓ _batch2: Valid terminal function output (all variations)

TEST 77: Terminal: _printenv0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-76]
✓ _printenv0: Valid terminal function output (all variations)

TEST 78: Terminal: _status0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-77]
✓ _status0: Valid terminal function output (all variations)

TEST 79: Terminal: _help0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-78]
✓ _help0: Valid terminal function output (all variations)

TEST 80: Terminal: _help1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-79]
✓ _help1: Valid terminal function output (all variations)

TEST 81: Terminal: _database_enumerate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-80]
✓ _database_enumerate0: Valid terminal function output (all variations)

TEST 82: Terminal: _system_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-81]
✓ _system_inspect0: Valid terminal function output (all variations)

TEST 83: Terminal: _logs_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-82]
✓ _logs_inspect0: Valid terminal function output (all variations)

TEST 84: Terminal: _phases_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-83]
✓ _phases_inspect0: Valid terminal function output (all variations)

TEST 85: Terminal: _summary_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-84]
✓ _summary_inspect0: Valid terminal function output (all variations)

TEST 86: Terminal: _prologue_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-85]
✓ _prologue_inspect0: Valid terminal function output (all variations)

TEST 87: Terminal: _openvpn_patch2 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-86]
✓ _openvpn_patch2: Valid terminal function output (all variations)

TEST 88: Terminal: _openvpn_configure1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-87]
✓ _openvpn_configure1: Valid terminal function output (all variations)

TEST 89: Terminal: _openvpn_connect1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-88]
✓ _openvpn_connect1: Valid terminal function output (all variations)

TEST 90: Terminal: _openvpn_disconnect1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-89]
✓ _openvpn_disconnect1: Valid terminal function output (all variations)

TEST 91: Terminal: _openvpn_patch1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-90]
✓ _openvpn_patch1: Valid terminal function output (all variations)

TEST 92: Terminal: _openvpn_enumerate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-91]
✓ _openvpn_enumerate0: Valid terminal function output (all variations)

TEST 93: Terminal: _openvpn_import1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-92]
✓ _openvpn_import1: Valid terminal function output (all variations)

TEST 94: Terminal: _openvpn_list0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-93]
✓ _openvpn_list0: Valid terminal function output (all variations)

TEST 95: Terminal: _openvpn_list1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-94]
✓ _openvpn_list1: Valid terminal function output (all variations)

TEST 96: Terminal: _openvpn_add1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-95]
✓ _openvpn_add1: Valid terminal function output (all variations)

TEST 97: Terminal: _openvpn_add3 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-96]
✓ _openvpn_add3: Valid terminal function output (all variations)

TEST 98: Terminal: _openvpn_link2 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-97]
✓ _openvpn_link2: Valid terminal function output (all variations)

TEST 99: Terminal: _openvpn_remove1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-98]
✓ _openvpn_remove1: Valid terminal function output (all variations)

TEST 100: Terminal: _openvpn_remove2 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-99]
✓ _openvpn_remove2: Valid terminal function output (all variations)

TEST 101: Terminal: _openvpn_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-100]
✓ _openvpn_validate0: Valid terminal function output (all variations)

TEST 102: Terminal: _openvpn_info1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-101]
✓ _openvpn_info1: Valid terminal function output (all variations)

TEST 103: Terminal: _session_list0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-102]
✓ _session_list0: Valid terminal function output (all variations)

TEST 104: Terminal: _session_show1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-103]
✓ _session_show1: Valid terminal function output (all variations)

TEST 105: Terminal: _session_remove1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-104]
✓ _session_remove1: Valid terminal function output (all variations)

TEST 106: Terminal: _session_connect1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-105]
✓ _session_connect1: Valid terminal function output (all variations)

TEST 107: Terminal: _session_save0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-106]
✓ _session_save0: Valid terminal function output (all variations)

TEST 108: Terminal: _session_save1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-107]
✓ _session_save1: Valid terminal function output (all variations)

TEST 109: Terminal: _session_clean0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-108]
✓ _session_clean0: Valid terminal function output (all variations)

TEST 110: Terminal: _session_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-109]
✓ _session_validate0: Valid terminal function output (all variations)

TEST 111: Terminal: _session_enumerate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-110]
✓ _session_enumerate0: Valid terminal function output (all variations)

TEST 112: Terminal: _session_describe0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-111]
✓ _session_describe0: Valid terminal function output (all variations)

TEST 113: Terminal: _logs_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-112]
✓ _logs_validate0: Valid terminal function output (all variations)

TEST 114: Terminal: _logs_clean0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-113]
✓ _logs_clean0: Valid terminal function output (all variations)

TEST 115: Terminal: _phases_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-114]
✓ _phases_validate0: Valid terminal function output (all variations)

TEST 116: Terminal: _database_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-115]
✓ _database_validate0: Valid terminal function output (all variations)

TEST 117: Terminal: _binaries_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-116]
✓ _binaries_validate0: Valid terminal function output (all variations)

TEST 118: Terminal: _network_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-117]
✓ _network_validate0: Valid terminal function output (all variations)

TEST 119: Terminal: _permissions_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-118]
✓ _permissions_validate0: Valid terminal function output (all variations)

TEST 120: Terminal: _environment_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-119]
✓ _environment_validate0: Valid terminal function output (all variations)

TEST 121: Terminal: _wireguard_patch2 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-120]
✓ _wireguard_patch2: Valid terminal function output (all variations)

TEST 122: Terminal: _wireguard_configure1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-121]
✓ _wireguard_configure1: Valid terminal function output (all variations)

TEST 123: Terminal: _wireguard_connect1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-122]
✓ _wireguard_connect1: Valid terminal function output (all variations)

TEST 124: Terminal: _wireguard_disconnect1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-123]
✓ _wireguard_disconnect1: Valid terminal function output (all variations)

TEST 125: Terminal: _wireguard_enumerate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-124]
✓ _wireguard_enumerate0: Valid terminal function output (all variations)

TEST 126: Terminal: _wireguard_import1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-125]
✓ _wireguard_import1: Valid terminal function output (all variations)

TEST 127: Terminal: _wireguard_list0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-126]
✓ _wireguard_list0: Valid terminal function output (all variations)

TEST 128: Terminal: _wireguard_list1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-127]
✓ _wireguard_list1: Valid terminal function output (all variations)

TEST 129: Terminal: _wireguard_add1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-128]
✓ _wireguard_add1: Valid terminal function output (all variations)

TEST 130: Terminal: _wireguard_add3 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-129]
✓ _wireguard_add3: Valid terminal function output (all variations)

TEST 131: Terminal: _wireguard_link2 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-130]
✓ _wireguard_link2: Valid terminal function output (all variations)

TEST 132: Terminal: _wireguard_remove1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-131]
✓ _wireguard_remove1: Valid terminal function output (all variations)

TEST 133: Terminal: _wireguard_remove2 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-132]
✓ _wireguard_remove2: Valid terminal function output (all variations)

TEST 134: Terminal: _wireguard_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-133]
✓ _wireguard_validate0: Valid terminal function output (all variations)

TEST 135: Terminal: _wireguard_patch1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-134]
✓ _wireguard_patch1: Valid terminal function output (all variations)

TEST 136: Terminal: _wireguard_info1 - validate output rules [db: /tmp/vpn-switch-arch-test.18197/test-135]
✓ _wireguard_info1: Valid terminal function output (all variations)

Running Error Propagation Tests (KEEP_GOING)
========================================


TEST 137: Batch Error Propagation - test _batch2 with failing commands [db: /tmp/vpn-switch-arch-test.18197/test-136]

TEST 138:   Sub-test: KEEP_GOING=0 (fail-fast mode) [db: /tmp/vpn-switch-arch-test.18197/test-137]
✓ KEEP_GOING=0: Batch execution stopped on first error

TEST 139:   Sub-test: KEEP_GOING=1 (continue mode) [db: /tmp/vpn-switch-arch-test.18197/test-137]
✓ KEEP_GOING=1: Batch execution completed despite errors
✓ KEEP_GOING=1: All commands were executed (count=3)

TEST 140: Recursive Batch Error Propagation - test chained _batch2 calls [db: /tmp/vpn-switch-arch-test.18197/test-137]
✓ Recursive fail-fast: Command 3 in batch 3 was not executed
✓ Recursive fail-fast: Batch 2 stopped after error in batch 3
✓ Recursive fail-fast: Batch 1 stopped after error in nested batch
✓ Recursive continue: Batch 2 continued after error in batch 3
✓ Recursive continue: Batch 1 continued after error in nested batch

TEST 141: Batch KEEP_GOING with Realistic Dump File [db: /tmp/vpn-switch-arch-test.18197/test-140]
✓ Created realistic batch file with 8 commands
✓ Selected command at position 5/8 for failure injection

TEST 142:   Sub-test: KEEP_GOING=0 at position 5/8 [db: /tmp/vpn-switch-arch-test.18197/test-141]
✓ KEEP_GOING=0: Stopped at or before position 5 (executed 5 commands)
✓ KEEP_GOING=0: Error stop message present

TEST 143:   Sub-test: KEEP_GOING=1 at position 5/8 [db: /tmp/vpn-switch-arch-test.18197/test-141]
✓ KEEP_GOING=1: All commands executed (8/8)
✓ KEEP_GOING=1: Completion message present
✓ KEEP_GOING=1: Failure markers present in output

Running Batch Combinator Error Propagation Tests
========================================

Testing ALL batch combinators with error injection and KEEP_GOING validation
Found 26 batch combinator functions


TEST 144: Batch Transitive Hull: ___session_prepare3 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-141]

TEST 145:   Sub-test: Walk command tree for '___session_prepare3' (command: session_prepare) [db: /tmp/vpn-switch-arch-test.18197/test-144]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 8 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 146: Batch Transitive Hull: ___stop0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-144]

TEST 147:   Sub-test: Walk command tree for '___stop0' (command: stop) [db: /tmp/vpn-switch-arch-test.18197/test-146]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 148:   Sub-test: Inject failure at node '___stop0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-146]
✓ KEEP_GOING affects output: fail-fast=       4 lines, continue=       4 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 149: Batch Transitive Hull: ___phases_sync1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-146]

TEST 150:   Sub-test: Walk command tree for '___phases_sync1' (command: phases_sync) [db: /tmp/vpn-switch-arch-test.18197/test-149]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 151:   Sub-test: Inject failure at node '___phases_sync0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-149]
✓ KEEP_GOING affects output: fail-fast=       4 lines, continue=       4 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 152: Batch Transitive Hull: ___phases_sync0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-149]

TEST 153:   Sub-test: Walk command tree for '___phases_sync0' (command: phases_sync) [db: /tmp/vpn-switch-arch-test.18197/test-152]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 154:   Sub-test: Inject failure at node '___phases_sync0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-152]
✓ KEEP_GOING affects output: fail-fast=       4 lines, continue=       4 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 155: Batch Transitive Hull: ___list0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-152]

TEST 156:   Sub-test: Walk command tree for '___list0' (command: list) [db: /tmp/vpn-switch-arch-test.18197/test-155]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 157:   Sub-test: Inject failure at node '___list0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-155]
✓ KEEP_GOING affects output: fail-fast=       2 lines, continue=       2 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 158: Batch Transitive Hull: ___bootstrap2 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-155]

TEST 159:   Sub-test: Walk command tree for '___bootstrap2' (command: bootstrap) [db: /tmp/vpn-switch-arch-test.18197/test-158]
✓ Command tree collected: 2 nodes in transitive hull
✓ Found 6 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 160: Batch Transitive Hull: ___init1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-158]

TEST 161:   Sub-test: Walk command tree for '___init1' (command: init) [db: /tmp/vpn-switch-arch-test.18197/test-160]
✓ Command tree collected: 2 nodes in transitive hull
✓ Found 1 injectable nodes (combinators/batches) in tree

TEST 162:   Sub-test: Inject failure at node '__init0' (node 1/1) [db: /tmp/vpn-switch-arch-test.18197/test-160]
✓ KEEP_GOING affects output: fail-fast=       1 lines, continue=       1 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 163: Batch Transitive Hull: ___dumpenv1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-160]

TEST 164:   Sub-test: Walk command tree for '___dumpenv1' (command: dumpenv) [db: /tmp/vpn-switch-arch-test.18197/test-163]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 8 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 165: Batch Transitive Hull: ___dump0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-163]

TEST 166:   Sub-test: Walk command tree for '___dump0' (command: dump) [db: /tmp/vpn-switch-arch-test.18197/test-165]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 167:   Sub-test: Inject failure at node '___dump0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-165]
✓ KEEP_GOING affects output: fail-fast=      17 lines, continue=      17 lines
    Note: No clear error stop indicator in fail-fast mode
✓ KEEP_GOING=1: Execution completed despite injected failure

TEST 168: Batch Transitive Hull: ___batch0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-165]

TEST 169:   Sub-test: Walk command tree for '___batch0' (command: batch) [db: /tmp/vpn-switch-arch-test.18197/test-168]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 170:   Sub-test: Inject failure at node '___batch0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-168]
✓ KEEP_GOING affects output: fail-fast=       2 lines, continue=       2 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 171: Batch Transitive Hull: ___environment_inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-168]

TEST 172:   Sub-test: Walk command tree for '___environment_inspect0' (command: environment_inspect) [db: /tmp/vpn-switch-arch-test.18197/test-171]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 173:   Sub-test: Inject failure at node '___environment_inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-171]
✓ KEEP_GOING affects output: fail-fast=       3 lines, continue=       3 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 174: Batch Transitive Hull: ___inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-171]

TEST 175:   Sub-test: Walk command tree for '___inspect0' (command: inspect) [db: /tmp/vpn-switch-arch-test.18197/test-174]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 176:   Sub-test: Inject failure at node '___inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-174]
✓ KEEP_GOING affects output: fail-fast=      12 lines, continue=      12 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 177: Batch Transitive Hull: ___openvpn_create1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-174]

TEST 178:   Sub-test: Walk command tree for '___openvpn_create1' (command: openvpn_create) [db: /tmp/vpn-switch-arch-test.18197/test-177]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 8 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 179: Batch Transitive Hull: ___openvpn_stop0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-177]

TEST 180:   Sub-test: Walk command tree for '___openvpn_stop0' (command: openvpn_stop) [db: /tmp/vpn-switch-arch-test.18197/test-179]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 1 injectable nodes (combinators/batches) in tree

TEST 181:   Sub-test: Inject failure at node '___openvpn_stop0' (node 1/1) [db: /tmp/vpn-switch-arch-test.18197/test-179]
✓ KEEP_GOING affects output: fail-fast=       1 lines, continue=       1 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 182: Batch Transitive Hull: ___openvpn_inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-179]

TEST 183:   Sub-test: Walk command tree for '___openvpn_inspect0' (command: openvpn_inspect) [db: /tmp/vpn-switch-arch-test.18197/test-182]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 184:   Sub-test: Inject failure at node '___openvpn_inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-182]
✓ KEEP_GOING affects output: fail-fast=       7 lines, continue=       7 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 185: Batch Transitive Hull: ___openvpn_clean0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-182]

TEST 186:   Sub-test: Walk command tree for '___openvpn_clean0' (command: openvpn_clean) [db: /tmp/vpn-switch-arch-test.18197/test-185]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 3 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 187: Batch Transitive Hull: ___openvpn_dump0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-185]

TEST 188:   Sub-test: Walk command tree for '___openvpn_dump0' (command: openvpn_dump) [db: /tmp/vpn-switch-arch-test.18197/test-187]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 189:   Sub-test: Inject failure at node '___openvpn_dump0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-187]
✓ KEEP_GOING affects output: fail-fast=      20 lines, continue=      20 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 190: Batch Transitive Hull: ___session_dump0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-187]

TEST 191:   Sub-test: Walk command tree for '___session_dump0' (command: session_dump) [db: /tmp/vpn-switch-arch-test.18197/test-190]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 192:   Sub-test: Inject failure at node '___session_dump0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-190]
✓ KEEP_GOING affects output: fail-fast=      41 lines, continue=      41 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 193: Batch Transitive Hull: ___session_inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-190]

TEST 194:   Sub-test: Walk command tree for '___session_inspect0' (command: session_inspect) [db: /tmp/vpn-switch-arch-test.18197/test-193]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 195:   Sub-test: Inject failure at node '___session_inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-193]
✓ KEEP_GOING affects output: fail-fast=       5 lines, continue=       5 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 196: Batch Transitive Hull: ___validate0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-193]

TEST 197:   Sub-test: Walk command tree for '___validate0' (command: validate) [db: /tmp/vpn-switch-arch-test.18197/test-196]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 198:   Sub-test: Inject failure at node '___validate0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-196]
✓ KEEP_GOING affects output: fail-fast=      10 lines, continue=      10 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 199: Batch Transitive Hull: ___wireguard_create1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-196]

TEST 200:   Sub-test: Walk command tree for '___wireguard_create1' (command: wireguard_create) [db: /tmp/vpn-switch-arch-test.18197/test-199]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 8 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 201: Batch Transitive Hull: ___wireguard_inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-199]

TEST 202:   Sub-test: Walk command tree for '___wireguard_inspect0' (command: wireguard_inspect) [db: /tmp/vpn-switch-arch-test.18197/test-201]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 203:   Sub-test: Inject failure at node '___wireguard_inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-201]
✓ KEEP_GOING affects output: fail-fast=       7 lines, continue=       7 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 204: Batch Transitive Hull: ___wireguard_stop0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-201]

TEST 205:   Sub-test: Walk command tree for '___wireguard_stop0' (command: wireguard_stop) [db: /tmp/vpn-switch-arch-test.18197/test-204]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 1 injectable nodes (combinators/batches) in tree

TEST 206:   Sub-test: Inject failure at node '___wireguard_stop0' (node 1/1) [db: /tmp/vpn-switch-arch-test.18197/test-204]
✓ KEEP_GOING affects output: fail-fast=       1 lines, continue=       1 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 207: Batch Transitive Hull: ___wireguard_clean0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-204]

TEST 208:   Sub-test: Walk command tree for '___wireguard_clean0' (command: wireguard_clean) [db: /tmp/vpn-switch-arch-test.18197/test-207]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 3 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 209: Batch Transitive Hull: ___wireguard_clean1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-207]

TEST 210:   Sub-test: Walk command tree for '___wireguard_clean1' (command: wireguard_clean) [db: /tmp/vpn-switch-arch-test.18197/test-209]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 3 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 211: Batch Transitive Hull: ___wireguard_dump0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.18197/test-209]

TEST 212:   Sub-test: Walk command tree for '___wireguard_dump0' (command: wireguard_dump) [db: /tmp/vpn-switch-arch-test.18197/test-211]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 213:   Sub-test: Inject failure at node '___wireguard_dump0' (node 1/2) [db: /tmp/vpn-switch-arch-test.18197/test-211]
✓ KEEP_GOING affects output: fail-fast=      42 lines, continue=      42 lines
    Note: No clear error stop indicator in fail-fast mode
✓ KEEP_GOING=1: Execution completed despite injected failure

Running Batch Combinator KEEP_GOING Precise Tests
========================================

Testing ALL batch combinators with precise architectural KEEP_GOING validation
Found 26 batch combinator functions


TEST 214: Batch KEEP_GOING Precise: ___session_prepare3 [db: /tmp/vpn-switch-arch-test.18197/test-211]
✓ Captured 143 command lines from ___session_prepare3
✓ Selected 112 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 215: Batch KEEP_GOING Precise: ___stop0 [db: /tmp/vpn-switch-arch-test.18197/test-214]
✓ Captured 2 command lines from ___stop0
✓ Selected 1 random line(s) for failure injection
✓ Injected failures into 1 function(s)
✓ KEEP_GOING=1: All commands attempted (2/2)
  Skipped: ___phases_sync1 (requires phase template setup)
  Skipped: ___phases_sync0 (requires phase template setup)

TEST 216: Batch KEEP_GOING Precise: ___list0 [db: /tmp/vpn-switch-arch-test.18197/test-215]
✓ Captured 2 command lines from ___list0
✓ Selected 1 random line(s) for failure injection
✓ Injected failures into 1 function(s)
✓ KEEP_GOING=1: All commands attempted (2/2)

TEST 217: Batch KEEP_GOING Precise: ___bootstrap2 [db: /tmp/vpn-switch-arch-test.18197/test-216]
✓ Captured 73 command lines from ___bootstrap2
✓ Selected 45 random line(s) for failure injection
  Skipped: No functions were injected with failures
  Skipped: ___init1 (complex initialization logic)

TEST 218: Batch KEEP_GOING Precise: ___dumpenv1 [db: /tmp/vpn-switch-arch-test.18197/test-217]
✓ Captured 143 command lines from ___dumpenv1
✓ Selected 139 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 219: Batch KEEP_GOING Precise: ___dump0 [db: /tmp/vpn-switch-arch-test.18197/test-218]
✓ Captured 5 command lines from ___dump0
✓ Selected 3 random line(s) for failure injection
✓ Injected failures into 1 function(s)
  Note: Not all commands attempted (3/5)
  Note: This may indicate KEEP_GOING=0 or execution stopped early

TEST 220: Batch KEEP_GOING Precise: ___batch0 [db: /tmp/vpn-switch-arch-test.18197/test-219]
✓ Captured 2 command lines from ___batch0
✓ Selected 1 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 221: Batch KEEP_GOING Precise: ___environment_inspect0 [db: /tmp/vpn-switch-arch-test.18197/test-220]
✓ Captured 2 command lines from ___environment_inspect0
✓ Selected 1 random line(s) for failure injection
✓ Injected failures into 1 function(s)
✓ KEEP_GOING=1: All commands attempted (2/2)

TEST 222: Batch KEEP_GOING Precise: ___inspect0 [db: /tmp/vpn-switch-arch-test.18197/test-221]
✓ Captured 12 command lines from ___inspect0
✓ Selected 5 random line(s) for failure injection
✓ Injected failures into 5 function(s)
  Note: Not all commands attempted (10/12)
  Note: This may indicate KEEP_GOING=0 or execution stopped early

TEST 223: Batch KEEP_GOING Precise: ___openvpn_create1 [db: /tmp/vpn-switch-arch-test.18197/test-222]
✓ Captured 143 command lines from ___openvpn_create1
✓ Selected 140 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 224: Batch KEEP_GOING Precise: ___openvpn_stop0 [db: /tmp/vpn-switch-arch-test.18197/test-223]
✓ Captured 1 command lines from ___openvpn_stop0
✓ Selected 1 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 225: Batch KEEP_GOING Precise: ___openvpn_inspect0 [db: /tmp/vpn-switch-arch-test.18197/test-224]
✓ Captured 3 command lines from ___openvpn_inspect0
✓ Selected 2 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 226: Batch KEEP_GOING Precise: ___openvpn_clean0 [db: /tmp/vpn-switch-arch-test.18197/test-225]
✓ Captured 3 command lines from ___openvpn_clean0
✓ Selected 1 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 227: Batch KEEP_GOING Precise: ___openvpn_dump0 [db: /tmp/vpn-switch-arch-test.18197/test-226]
✓ Captured 13 command lines from ___openvpn_dump0
✓ Selected 4 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 228: Batch KEEP_GOING Precise: ___session_dump0 [db: /tmp/vpn-switch-arch-test.18197/test-227]
✓ Captured 40 command lines from ___session_dump0
✓ Selected 30 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 229: Batch KEEP_GOING Precise: ___session_inspect0 [db: /tmp/vpn-switch-arch-test.18197/test-228]
✓ Captured 4 command lines from ___session_inspect0
✓ Selected 1 random line(s) for failure injection
✓ Injected failures into 1 function(s)
  Note: Not all commands attempted (3/4)
  Note: This may indicate KEEP_GOING=0 or execution stopped early

TEST 230: Batch KEEP_GOING Precise: ___validate0 [db: /tmp/vpn-switch-arch-test.18197/test-229]
✓ Captured 10 command lines from ___validate0
✓ Selected 2 random line(s) for failure injection
✓ Injected failures into 2 function(s)
✓ KEEP_GOING=1: All commands attempted (10/10)

TEST 231: Batch KEEP_GOING Precise: ___wireguard_create1 [db: /tmp/vpn-switch-arch-test.18197/test-230]
✓ Captured 143 command lines from ___wireguard_create1
✓ Selected 125 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 232: Batch KEEP_GOING Precise: ___wireguard_inspect0 [db: /tmp/vpn-switch-arch-test.18197/test-231]
✓ Captured 3 command lines from ___wireguard_inspect0
✓ Selected 3 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 233: Batch KEEP_GOING Precise: ___wireguard_stop0 [db: /tmp/vpn-switch-arch-test.18197/test-232]
✓ Captured 1 command lines from ___wireguard_stop0
✓ Selected 1 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 234: Batch KEEP_GOING Precise: ___wireguard_clean0 [db: /tmp/vpn-switch-arch-test.18197/test-233]
✓ Captured 9 command lines from ___wireguard_clean0
✓ Selected 6 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 235: Batch KEEP_GOING Precise: ___wireguard_clean1 [db: /tmp/vpn-switch-arch-test.18197/test-234]
✓ Captured 9 command lines from ___wireguard_clean1
✓ Selected 6 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 236: Batch KEEP_GOING Precise: ___wireguard_dump0 [db: /tmp/vpn-switch-arch-test.18197/test-235]
✓ Captured 34 command lines from ___wireguard_dump0
✓ Selected 22 random line(s) for failure injection
  Skipped: No functions were injected with failures

Running Static Analysis Tests
========================================

Testing architecture violation scanner


TEST 237: Architecture Violation Scanner [db: /tmp/vpn-switch-arch-test.18197/test-236]
✓ Scanner executed successfully (exit code: 0)
  Found: \033[0;31m1\033[0m total violations
✓ Scanner detection working (violations found as expected)
✓ Scanner detects MODIFY_* variable usage

Running Read-Only Database Tests
========================================

Testing that functions don't modify database at generation time


TEST 238: Read-Only Database: All functions [db: /tmp/vpn-switch-arch-test.18197/test-236]
  Testing terminal functions...
✓ _session_create1: No permission errors on read-only database
✓ _interface_destroy1: No permission errors on read-only database
✓ _session_populate3: No permission errors on read-only database
✓ _link2: No permission errors on read-only database
✓ _remove1: No permission errors on read-only database
✓ _error1: No permission errors on read-only database
✓ _error2: No permission errors on read-only database
✓ _error3: No permission errors on read-only database
✓ _fail2: No permission errors on read-only database
✓ _log1: No permission errors on read-only database
✓ _log2: No permission errors on read-only database
✓ _log3: No permission errors on read-only database
✓ _lift1: No permission errors on read-only database
✓ _lift3: No permission errors on read-only database
    Warning: setenv2: output differs between writable/readonly (but compliant)
✓ _setenv2: No permission errors on read-only database
✓ _getenv1: No permission errors on read-only database
✓ _unsetenv1: No permission errors on read-only database
✓ _printenv0: No permission errors on read-only database
    Warning: status0: output differs between writable/readonly (but compliant)
✓ _status0: No permission errors on read-only database
✓ _help0: No permission errors on read-only database
✓ _help1: No permission errors on read-only database
    Warning: database_enumerate0: output differs between writable/readonly (but compliant)
✓ _database_enumerate0: No permission errors on read-only database
✓ _system_inspect0: No permission errors on read-only database
    Warning: logs_inspect0: output differs between writable/readonly (but compliant)
✓ _logs_inspect0: No permission errors on read-only database
✓ _phases_inspect0: No permission errors on read-only database
✓ _summary_inspect0: No permission errors on read-only database
✓ _prologue_inspect0: No permission errors on read-only database
✓ _openvpn_patch2: No permission errors on read-only database
✓ _openvpn_configure1: No permission errors on read-only database
✓ _openvpn_connect1: No permission errors on read-only database
✓ _openvpn_disconnect1: No permission errors on read-only database
✓ _openvpn_patch1: No permission errors on read-only database
    Warning: openvpn_enumerate0: output differs between writable/readonly (but compliant)
✓ _openvpn_enumerate0: No permission errors on read-only database
✓ _openvpn_import1: No permission errors on read-only database
✓ _openvpn_list0: No permission errors on read-only database
✓ _openvpn_list1: No permission errors on read-only database
✓ _openvpn_add1: No permission errors on read-only database
✓ _openvpn_add3: No permission errors on read-only database
✓ _openvpn_link2: No permission errors on read-only database
✓ _openvpn_remove1: No permission errors on read-only database
✓ _openvpn_remove2: No permission errors on read-only database
✓ _openvpn_validate0: No permission errors on read-only database
✓ _openvpn_info1: No permission errors on read-only database
✓ _session_list0: No permission errors on read-only database
✓ _session_show1: No permission errors on read-only database
✓ _session_remove1: No permission errors on read-only database
✓ _session_connect1: No permission errors on read-only database
✓ _session_save0: No permission errors on read-only database
✓ _session_save1: No permission errors on read-only database
✓ _session_clean0: No permission errors on read-only database
✓ _session_validate0: No permission errors on read-only database
✓ _session_enumerate0: No permission errors on read-only database
✓ _session_describe0: No permission errors on read-only database
✓ _logs_validate0: No permission errors on read-only database
✓ _logs_clean0: No permission errors on read-only database
✓ _phases_validate0: No permission errors on read-only database
✓ _database_validate0: No permission errors on read-only database
✓ _binaries_validate0: No permission errors on read-only database
✓ _network_validate0: No permission errors on read-only database
✓ _permissions_validate0: No permission errors on read-only database
✓ _environment_validate0: No permission errors on read-only database
✓ _wireguard_patch2: No permission errors on read-only database
✓ _wireguard_configure1: No permission errors on read-only database
✓ _wireguard_connect1: No permission errors on read-only database
✓ _wireguard_disconnect1: No permission errors on read-only database
    Warning: wireguard_enumerate0: output differs between writable/readonly (but compliant)
✓ _wireguard_enumerate0: No permission errors on read-only database
✓ _wireguard_import1: No permission errors on read-only database
✓ _wireguard_list0: No permission errors on read-only database
✓ _wireguard_list1: No permission errors on read-only database
✓ _wireguard_add1: No permission errors on read-only database
✓ _wireguard_add3: No permission errors on read-only database
✓ _wireguard_link2: No permission errors on read-only database
✓ _wireguard_remove1: No permission errors on read-only database
✓ _wireguard_remove2: No permission errors on read-only database
✓ _wireguard_validate0: No permission errors on read-only database
✓ _wireguard_patch1: No permission errors on read-only database
✓ _wireguard_info1: No permission errors on read-only database

  Testing combinator functions...
✓ __session_exists1: No permission errors on read-only database
✓ __session_conflicts2: No permission errors on read-only database
✓ __interface_check1: No permission errors on read-only database
✓ __stop1: No permission errors on read-only database
✓ __import1: No permission errors on read-only database
✓ __start1: No permission errors on read-only database
✓ __start0: No permission errors on read-only database
✓ __bootstrap1: No permission errors on read-only database
✓ __environment_cache0: No permission errors on read-only database
✓ __phases_lift1: No permission errors on read-only database
✓ __init0: No permission errors on read-only database
✓ __batch1: No permission errors on read-only database
✓ __restore1: No permission errors on read-only database
    Warning: openvpn_start0: output differs between writable/readonly (but compliant)
✓ __openvpn_start0: No permission errors on read-only database
✓ __openvpn_start1: No permission errors on read-only database
✓ __openvpn_stop1: No permission errors on read-only database
✓ __openvpn_add2: No permission errors on read-only database
✓ __openvpn_help0: No permission errors on read-only database
✓ __session_disconnect1: No permission errors on read-only database
✓ __session_show0: No permission errors on read-only database
✓ __session_start0: No permission errors on read-only database
✓ __session_start1: No permission errors on read-only database
✓ __session_help0: No permission errors on read-only database
    Warning: wireguard_start0: output differs between writable/readonly (but compliant)
✓ __wireguard_start0: No permission errors on read-only database
✓ __wireguard_start1: No permission errors on read-only database
✓ __wireguard_stop1: No permission errors on read-only database
✓ __wireguard_add2: No permission errors on read-only database
✓ __wireguard_help0: No permission errors on read-only database

  Testing batch combinator functions...
✓ ___session_prepare3: No permission errors on read-only database
✓ ___stop0: No permission errors on read-only database
✓ ___phases_sync1: No permission errors on read-only database
✓ ___phases_sync0: No permission errors on read-only database
✓ ___list0: No permission errors on read-only database
✓ ___dumpenv1: No permission errors on read-only database
✓ ___dump0: No permission errors on read-only database
    Warning: batch0: output differs between writable/readonly (but compliant)
✓ ___batch0: No permission errors on read-only database
✓ ___environment_inspect0: No permission errors on read-only database
✓ ___inspect0: No permission errors on read-only database
    Warning: openvpn_create1: output differs between writable/readonly (but compliant)
✓ ___openvpn_create1: No permission errors on read-only database
✓ ___openvpn_stop0: No permission errors on read-only database
✓ ___openvpn_inspect0: No permission errors on read-only database
✓ ___openvpn_clean0: No permission errors on read-only database
✓ ___openvpn_dump0: No permission errors on read-only database
✓ ___session_dump0: No permission errors on read-only database
✓ ___session_inspect0: No permission errors on read-only database
✓ ___validate0: No permission errors on read-only database
    Warning: wireguard_create1: output differs between writable/readonly (but compliant)
✓ ___wireguard_create1: No permission errors on read-only database
✓ ___wireguard_inspect0: No permission errors on read-only database
✓ ___wireguard_stop0: No permission errors on read-only database
✓ ___wireguard_clean0: No permission errors on read-only database
✓ ___wireguard_clean1: No permission errors on read-only database
✓ ___wireguard_dump0: No permission errors on read-only database

  Summary: Tested 129 functions, skipped 8

========================================
Architecture Test Summary
========================================
Test Functions:     238
Total Assertions:   412
Passed Assertions:  412
Failed Assertions:  0

ALL TESTS PASSED

Cleaning up test databases...
Done.
=== vpn-switch Integration Tests ===
Profile: all


▶ User Story 1: Import → Organize → Dump → Restore → Idempotency (Multi-Protocol)
  Database: /tmp/vpn-integration-old.ahtbZ2
  ✓ WG: Imported config 1
  ✓ WG: Imported config 2
  ✓ WG: Imported config 3
  ✓ OVPN: Imported config 1
  ✓ OVPN: Imported config 2
  ✓ WG: Created category: privacy
  ✓ WG: Created category: streaming
  ✓ OVPN: Created group: work
  ✓ WG: Protocol-level link: quick
  ✓ WG: Category link: privacy/fast
  ✓ WG: Category link: privacy/secure
  ✓ WG: Category link: streaming/hd
  ✓ OVPN: Protocol-level link: office
  ✓ OVPN: Group link: work/primary
  ✓ Dump stderr is clean
# ================================
# db: /tmp/vpn-integration-old.ahtbZ2
# ================================
  ✓ Dump file created
  ✓ Dump contains WG import
  ✓ Dump contains OVPN import
  ✓ Dump contains WG category
  ✓ Dump contains OVPN group
  ✓ Dump contains WG link
  ✓ Dump contains OVPN link
  Database: /tmp/vpn-integration-new.KkjL9r
  ✓ NEW WG: Config 1 imported
  ✓ NEW WG: Config 2 imported
  ✓ NEW WG: Config 3 imported
  ✓ NEW WG: Category privacy created
  ✓ NEW WG: Category streaming created
  ✓ NEW WG: Protocol-level link
  ✓ NEW WG: Category link privacy/fast
  ✓ NEW WG: Category link privacy/secure
  ✓ NEW WG: Category link streaming/hd
  ✓ NEW OVPN: Config 1 imported
  ✓ NEW OVPN: Config 2 imported
  ✓ NEW OVPN: Group work created
  ✓ NEW OVPN: Protocol-level link
  ✓ NEW OVPN: Group link work/primary
  ✓ Idempotency dump stderr is clean
  ✓ Idempotency: dump(restore(dump(OLD))) == dump(OLD) [multi-protocol]
✓ Story 1 completed successfully

▶ User Story 2: Session Management: Save → Dump → Restore → Verify (Multi-Protocol)
  Database: /tmp/vpn-integration-old.0xPnuc
  ✓ WG: Named session created: work -> ../.session/15671
  ✓ OVPN: Named session created: home -> ../.session/47619
  ✓ Dump stderr is clean
  ✓ Dump contains WG session patch
  ✓ Dump contains OVPN session patch
  ✓ Dump contains WG save command
  ✓ Dump contains OVPN save command
  Database: /tmp/vpn-integration-new.ZzeT48
  ✓ NEW: WG config imported
  ✓ NEW: OVPN config imported
  ✓ NEW: WG session dump contains patch + save commands
  ✓ NEW: OVPN session dump contains patch + save commands
✓ Story 2 completed successfully

▶ User Story 3: Config Expiry: Import → Organize → Check Status
  Database: /tmp/vpn-integration-test.h1cUj6
  ✓ Info output contains fresh config
  ✓ Info output contains old config
  ✓ Validate command found no issues (acceptable)
✓ Story 3 completed successfully

▶ User Story 4: Multi-Category Organization: Complex Structure (Multi-Protocol)
  Database: /tmp/vpn-integration-test.y57Eps
  ✓ WG: Category: usa
  ✓ WG: Category: europe
  ✓ WG: Category: asia
  ✓ WG: Category: work
  ✓ WG: Category: personal
  ✓ OVPN: Group: corporate
  ✓ OVPN: Group: remote
  ✓ WG: usa/ny → wg-us-ny.conf
  ✓ WG: europe/uk → wg-eu-uk.conf
  ✓ WG: asia/jp → wg-asia-jp.conf
  ✓ WG: work/office → wg-us-ny.conf
  ✓ WG: personal/home → wg-us-sf.conf
  ✓ OVPN: corporate/us → us-office.ovpn
  ✓ OVPN: corporate/eu → eu-office.ovpn
  ✓ OVPN: remote/home → home-server.ovpn
  ✓ WG: default → wg-us-ny.conf
  ✓ WG: fast → wg-us-sf.conf
  ✓ OVPN: quick → us-office.ovpn
  ✓ WG: List shows usa category
  ✓ WG: List shows europe category
  ✓ WG: List shows work category
  ✓ OVPN: List shows corporate group
  ✓ OVPN: List shows remote group
✓ Story 4 completed successfully

▶ User Story 5: Completeness & Deletion Proof: Comprehensive State Tracking (Multi-Protocol)
  Database: /tmp/vpn-integration-test.wGKKcC
  ✓ Dump stderr is clean
  ✓ Completeness: All 26 operations present in dump (WG: 15, OVPN: 11)
  ✓ Deletion phase 1 dump stderr is clean
  ✓ Deletion: WG protocol link 'quick' removed from dump
  ✓ Deletion: OVPN protocol link 'office' removed from dump
  ✓ Deletion: WG protocol link 'default' still present
  ✓ Deletion: WG category 'privacy' still present
  ✓ Deletion: WG category 'work' still present
  ✓ Deletion: OVPN group 'corporate' still present
  ✓ Deletion phase 2 dump stderr is clean
  ✓ Deletion: WG category link 'privacy/fast' removed from dump
  ✓ Deletion: WG category link 'work/office' removed from dump
  ✓ Deletion: OVPN group link 'corporate/primary' removed from dump
  ✓ Deletion: WG category link 'privacy/secure' still present
  ✓ Deletion: WG category link 'streaming/hd' still present
  ✓ Deletion: OVPN group link 'corporate/secondary' still present
  ✓ Deletion: WG config wg-us-101.conf still present
  ✓ Deletion: WG config wg-de-303.conf still present
  ✓ Deletion: OVPN config us-server.ovpn still present
  ✓ Deletion phase 3 dump stderr is clean
  ✓ Deletion: WG config wg-jp-404.conf removed from dump
  ✓ Deletion: WG config wg-au-505.conf removed from dump
  ✓ Deletion: OVPN config asia-server.ovpn removed from dump
  ✓ Deletion: WG config wg-us-101.conf still present after removals
  ✓ Deletion: WG config wg-uk-202.conf still present after removals
  ✓ Deletion: WG config wg-de-303.conf still present after removals
  ✓ Deletion: OVPN config us-server.ovpn still present after removals
  ✓ Deletion: OVPN config eu-server.ovpn still present after removals
  ✓ Deletion: Empty WG category 'privacy' still present
  ✓ Deletion: Empty WG category 'work' still present
  ✓ Deletion: Empty WG category 'streaming' still present
  ✓ Deletion: OVPN group 'corporate' still present (has link)
  ✓ Deletion: Empty OVPN group 'remote' still present
✓ Story 5 completed successfully

▶ User Story 6: Dump Quality: Cleanliness, Pipeability, Executability, Transcript Reproducibility
  Database: /tmp/vpn-quality-test.bDuluq
  ✓ Property 1: Dump stderr is completely empty
  ✓ Property 2: Dump output is syntactically valid shell script
  ✓ Property 3: Direct pipe works (exit code 0)
  ✓ Property 3: Direct pipe produces identical output
  ✓ Property 4: All informational output is properly commented
  ✓ Property 5: All transcript commands present in dump (reproducibility)
  Database: /tmp/vpn-quality-restore.jHtK1Z
  ✓ Property 6: Dump is restorable (executable)
  ✓ Property 6: WG config restored
  ✓ Property 6: OVPN config restored
  ✓ Property 6: WG category restored
  ✓ Property 6: OVPN group restored
  ✓ Property 6: WG link restored
  ✓ Property 6: OVPN link restored
  ✓ Property 7: Normalized idempotency verified (dump(restore(dump)) == dump)
  ✓ Property 8: No duplicate protocol commands in dump (6 unique)
✓ Story 6 completed successfully

▶ User Story 7: Phase-Based Script Generation (WireGuard and OpenVPN)
  Database: /tmp/vpn-phase-gen.GmzJ8U
  ✓ WG: Extract session ID from start output
  ✓ WG: connect.sh exists
  ✓ WG: disconnect.sh exists
  ✓ WG: connect.sh has correct permissions (0750)
  ✓ WG: disconnect.sh has correct permissions (0750)
  ✓ WG: connect.sh is executable
  ✓ WG: disconnect.sh is executable
  ✓ WG: connect.sh has shebang
  ✓ WG: disconnect.sh has shebang
  ✓ OVPN: Extract session ID from start output
  ✓ OVPN: connect.sh exists
  ✓ OVPN: disconnect.sh exists
  ✓ OVPN: connect.sh has correct permissions (0750)
  ✓ OVPN: disconnect.sh has correct permissions (0750)
  ✓ OVPN: connect.sh is executable
  ✓ OVPN: disconnect.sh is executable
  ✓ OVPN: connect.sh has shebang
  ✓ OVPN: disconnect.sh has shebang
  ✓ WG: Session metadata exists (protocol)
  ✓ WG: Session metadata exists (interface)
  ✓ OVPN: Session metadata exists (protocol)
  ✓ OVPN: Session metadata exists (interface)
  ✓ WG and OVPN sessions are independent (different PIDs)
✓ Story 7 completed successfully

▶ User Story 8: Phase Script Content Verification (Structure and Commands)
  Database: /tmp/vpn-phase-content.vJCsJu
  ✓ WG connect: Has title
  ✓ WG connect: Has generation timestamp
  ✓ WG connect: Has session ID
  ✓ WG connect: Has context documentation
  ✓ WG connect: Has session_dir variable
  ✓ WG connect: Has protocol variable
  ✓ WG connect: Has interface variable
  ✓ WG connect: Has config_path variable
  ✓ WG connect: Has dns_server variable
  ✓ WG connect: Has remote_ips variable
  ✓ WG connect: Has firewall verify function
  ✓ WG connect: Has vpn verify function
  ✓ WG connect: Has dns verify function
  ✓ WG connect: Firewall prepare phase
  ✓ WG connect: Firewall execute phase
  ✓ WG connect: VPN prepare phase
  ✓ WG connect: VPN execute phase
  ✓ WG connect: DNS prepare phase
  ✓ WG connect: DNS execute phase
  ✓ WG connect: Has wg-quick up command
  ✓ WG connect: Correct phase order
  ✓ WG disconnect: Has title
  ✓ WG disconnect: Has session_dir variable
  ✓ WG disconnect: Has dns verify function
  ✓ WG disconnect: Has vpn verify function
  ✓ WG disconnect: Has firewall verify function
  ✓ WG disconnect: Has wg-quick down command
  ✓ WG disconnect: Correct reversed phase order
  ✓ OVPN connect: Has title
  ✓ OVPN connect: Has generation timestamp
  ✓ OVPN connect: Has session_dir variable
  ✓ OVPN connect: Has protocol variable
  ✓ OVPN connect: Has interface variable
  ✓ OVPN connect: Has config_path variable
  ✓ OVPN connect: Has firewall verify function
  ✓ OVPN connect: Has vpn verify function
  ✓ OVPN connect: Has dns verify function
  ✓ OVPN connect: Has openvpn command
  ✓ OVPN connect: Has daemon flag
  ✓ OVPN connect: Correct phase order
  ✓ OVPN disconnect: Has title
  ✓ OVPN disconnect: Has session_dir variable
  ✓ OVPN disconnect: Has process kill command
  ✓ OVPN disconnect: Correct reversed phase order
  ✓ WG connect: No OpenVPN commands
  ✓ WG connect: No OpenVPN daemon flag
  ✓ OVPN connect: No WireGuard commands
✓ Story 8 completed successfully

▶ User Story 9: Phase Customization (Reorder, Add, Skip)
  Database: /tmp/vpn-phase-custom.b4Z842
  ✓ Baseline: Default phase order
  ✓ Reordered: Custom phase order
  ✓ Custom phase: Has verify function
  ✓ Custom phase: Has prepare section
  ✓ Custom phase: Has execute section
  ✓ Custom phase: Correct order with routing
  ✓ Minimal: Has vpn verify function
  ✓ Minimal: No firewall phase
  ✓ Minimal: No dns phase
  ✓ Minimal: Only VPN phase
  ✓ Custom disconnect: Has dns phase
  ✓ Custom disconnect: Has vpn phase
  ✓ Custom disconnect: No firewall phase
  ✓ Custom disconnect: Only dns and vpn
  ✓ Multi-custom: Has logging phase
  ✓ Multi-custom: Has monitoring phase
  ✓ Multi-custom: Correct custom order
✓ Story 9 completed successfully

▶ User Story 10: Multi-Protocol Phase Support (Isolation and Simultaneous Operation)
  Database: /tmp/vpn-phase-multi.bM8ARj
  ✓ WG: Default phase order
  ✓ OVPN: Default phase order
  ✓ WG: Has WireGuard command
  ✓ WG: No OpenVPN commands
  ✓ OVPN: Has OpenVPN command
  ✓ OVPN: No WireGuard commands
  ✓ WG: Correct protocol variable
  ✓ WG: WireGuard interface naming
  ✓ WG: Has dns_server context
  ✓ WG: Has remote_ips context
  ✓ OVPN: Correct protocol variable
  ✓ OVPN: OpenVPN interface naming
  ✓ WG custom: Has custom phase
  ✓ WG custom: Has custom phase in order
  ✓ OVPN: No WireGuard custom phase
  ✓ OVPN: Default phases only
  ✓ WG: No OpenVPN custom phase
  ✓ WG: Default phases only
  ✓ OVPN: Protocol-specific phase config not yet supported
  ✓ OVPN: Uses default phases (protocol-specific config not implemented)
  ✓ Simultaneous: WG session exists
  ✓ Simultaneous: OVPN session exists
  ✓ Simultaneous: Different session IDs
  ✓ Simultaneous: WG has correct protocol
  ✓ Simultaneous: OVPN has correct protocol
✓ Story 10 completed successfully

▶ User Story 11: Multi-Protocol Edge Cases (Stress, Switching, Robustness)
  Database: /tmp/vpn-edge-cases.CmjeiZ
  ✓ Scenario 1.1: Duplicate WG import correctly rejected
  ✓ Scenario 1.1: Duplicate OVPN import correctly rejected
  ✓ Scenario 1.1: WG includes wg_custom phase
  ✓ Scenario 1.1: WG excludes ovpn_custom phase
  ✓ Scenario 1.1: OVPN includes ovpn_custom phase
  ✓ Scenario 1.1: OVPN excludes wg_custom phase
  ✓ Scenario 1.1: Phase order differs between protocols
  ✓ Scenario 1.2: WireGuard test interface configured
  ✓ Scenario 1.2: OpenVPN test interface configured
  ✓ Scenario 1.2: Two sessions active simultaneously
  ✓ Scenario 1.2: WG session uses wg_test* interface
  ✓ Scenario 1.2: OVPN session uses tun_test* interface
  ✓ Scenario 1.2: Unreferenced sessions cleaned, 'latest' preserved
  ✓ Scenario 1.3: WG session has DNS config
  ✓ Scenario 1.3: Connect scripts differ despite same DNS
  ✓ Scenario 2.1: WG session created
  ✓ Scenario 2.1: WG session stopped, 'latest' preserved
  ✓ Scenario 2.1: OVPN session created after WG stop
  ✓ Scenario 2.1: New session is OpenVPN protocol
  ✓ Scenario 2.2: Both sessions coexist
  ✓ Scenario 2.2: Both protocols running simultaneously
  ✓ Scenario 2.3: Cycle 1 - WG started
  ✓ Scenario 2.3: Cycle 1 - WG stopped, 'latest' preserved
  ✓ Scenario 2.3: Cycle 2 - OVPN started (old session + new)
  ✓ Scenario 2.3: Cycle 2 - OVPN stopped, unreferenced cleaned
  ✓ Scenario 2.3: Cycle 3 - WG started (old session + new)
  ✓ Scenario 2.3: Both sessions present (unreferenced + latest)
  ✓ Scenario 3.1: WG session saved as wg_work
  ✓ Scenario 3.1: Both sessions active after resume
  ✓ Scenario 3.1: Correct protocols after resume
  ✓ Scenario 3.2: Session 'work' points to WG session
  ✓ Scenario 3.2: Session 'work' now points to OVPN (overwrite)
  ✓ Scenario 3.2: Only one 'work' session exists (no duplicates)
  ✓ Scenario 4.1: Two active sessions before dump
  ✓ Scenario 4.1: Dump file created with active sessions
  ✓ Scenario 4.1: Dump excludes .session directory (transient)
  ✓ Scenario 4.1: Dump includes WG configs
  ✓ Scenario 4.1: Dump includes OVPN configs
  Database: /tmp/vpn-restore-a.tEN2Xn
  Database: /tmp/vpn-restore-b.dylO8z
  ✓ Scenario 4.2: Restored database has WG config
  ✓ Scenario 4.2: Restored database has no active sessions
  ✓ Scenario 5.1: Only 'latest' WG session after 10 cycles
  ✓ Scenario 5.1: Only 'latest' OVPN session after 10 cycles
  ✓ Scenario 5.1: Only latest session directory remains
✓ Story 11 completed successfully

▶ User Story 12: Phase Backend Selection (Strategy 7 - Automatic Template Lifting)
  Database: /tmp/vpn-backend-selection.ZMgQgp
  ✓ Backend template lifted: firewall/pf.sh
  ✓ Backend template lifted: firewall/ipfw.sh
  ✓ Backend template lifted: dns/resolvconf.sh
  ✓ Backend template lifted: dns/unbound.sh
  ✓ Scenario 1: Connect script generated
  ✓ Scenario 1: PF firewall backend used (contains pfctl)
  ✓ Scenario 1: Resolvconf DNS backend used
  ✓ Scenario 2: IPFW firewall backend used (contains ipfw)
  ✓ Scenario 2: Unbound DNS backend used
  ✓ Scenario 2: PF firewall phase not used (backend isolated)
  ✓ Scenario 3: Backward compat - connect script generated
  ✓ Scenario 3: Backward compat - script not empty
  ✓ Scenario 3: Uses protocol-specific phases (wireguard/)
  ✓ Scenario 4: Both backends from @base profile used
  ✓ Scenario 5: Variant-only syntax works (uses default profile)
  ✓ Scenario 6: Mixed syntax - ipfw backend used
  ✓ Scenario 6: Mixed syntax - vpn phase executed
  ✓ Scenario 6: Mixed syntax - traditional dns phase used
✓ Story 12 completed successfully

========================================
Test Summary
========================================
User Stories:  12
  Passed:      12
  Failed:      0

Assertions:    296
  Passed:      296
  Failed:      0

ALL STORIES PASSED
=== vpn-switch Integration Tests ===
Profile: minimal


▶ User Story 1: Import → Organize → Dump → Restore → Idempotency (Multi-Protocol)
  Database: /tmp/vpn-integration-old.cbW8p1
  ✓ WG: Imported config 1
  ✓ WG: Imported config 2
  ✓ WG: Imported config 3
  ✓ OVPN: Imported config 1
  ✓ OVPN: Imported config 2
  ✓ WG: Created category: privacy
  ✓ WG: Created category: streaming
  ✓ OVPN: Created group: work
  ✓ WG: Protocol-level link: quick
  ✓ WG: Category link: privacy/fast
  ✓ WG: Category link: privacy/secure
  ✓ WG: Category link: streaming/hd
  ✓ OVPN: Protocol-level link: office
  ✓ OVPN: Group link: work/primary
  ✓ Dump stderr is clean
# ================================
# db: /tmp/vpn-integration-old.cbW8p1
# ================================
  ✓ Dump file created
  ✓ Dump contains WG import
  ✓ Dump contains OVPN import
  ✓ Dump contains WG category
  ✓ Dump contains OVPN group
  ✓ Dump contains WG link
  ✓ Dump contains OVPN link
  Database: /tmp/vpn-integration-new.O0PzTg
  ✓ NEW WG: Config 1 imported
  ✓ NEW WG: Config 2 imported
  ✓ NEW WG: Config 3 imported
  ✓ NEW WG: Category privacy created
  ✓ NEW WG: Category streaming created
  ✓ NEW WG: Protocol-level link
  ✓ NEW WG: Category link privacy/fast
  ✓ NEW WG: Category link privacy/secure
  ✓ NEW WG: Category link streaming/hd
  ✓ NEW OVPN: Config 1 imported
  ✓ NEW OVPN: Config 2 imported
  ✓ NEW OVPN: Group work created
  ✓ NEW OVPN: Protocol-level link
  ✓ NEW OVPN: Group link work/primary
  ✓ Idempotency dump stderr is clean
  ✓ Idempotency: dump(restore(dump(OLD))) == dump(OLD) [multi-protocol]
✓ Story 1 completed successfully

▶ User Story 2: Session Management: Save → Dump → Restore → Verify (Multi-Protocol)
  Database: /tmp/vpn-integration-old.cBtc1V
  ✓ WG: Named session created: work -> ../.session/9607
  ✓ OVPN: Named session created: home -> ../.session/24852
  ✓ Dump stderr is clean
  ✓ Dump contains WG session patch
  ✓ Dump contains OVPN session patch
  ✓ Dump contains WG save command
  ✓ Dump contains OVPN save command
  Database: /tmp/vpn-integration-new.eYaBz3
  ✓ NEW: WG config imported
  ✓ NEW: OVPN config imported
  ✓ NEW: WG session dump contains patch + save commands
  ✓ NEW: OVPN session dump contains patch + save commands
✓ Story 2 completed successfully

▶ User Story 3: Config Expiry: Import → Organize → Check Status
  Database: /tmp/vpn-integration-test.bfqw9c
  ✓ Info output contains fresh config
  ✓ Info output contains old config
  ✓ Validate command found no issues (acceptable)
✓ Story 3 completed successfully

▶ User Story 4: Multi-Category Organization: Complex Structure (Multi-Protocol)
  Database: /tmp/vpn-integration-test.fT3u1i
  ✓ WG: Category: usa
  ✓ WG: Category: europe
  ✓ WG: Category: asia
  ✓ WG: Category: work
  ✓ WG: Category: personal
  ✓ OVPN: Group: corporate
  ✓ OVPN: Group: remote
  ✓ WG: usa/ny → wg-us-ny.conf
  ✓ WG: europe/uk → wg-eu-uk.conf
  ✓ WG: asia/jp → wg-asia-jp.conf
  ✓ WG: work/office → wg-us-ny.conf
  ✓ WG: personal/home → wg-us-sf.conf
  ✓ OVPN: corporate/us → us-office.ovpn
  ✓ OVPN: corporate/eu → eu-office.ovpn
  ✓ OVPN: remote/home → home-server.ovpn
  ✓ WG: default → wg-us-ny.conf
  ✓ WG: fast → wg-us-sf.conf
  ✓ OVPN: quick → us-office.ovpn
  ✓ WG: List shows usa category
  ✓ WG: List shows europe category
  ✓ WG: List shows work category
  ✓ OVPN: List shows corporate group
  ✓ OVPN: List shows remote group
✓ Story 4 completed successfully

▶ User Story 5: Completeness & Deletion Proof: Comprehensive State Tracking (Multi-Protocol)
  Database: /tmp/vpn-integration-test.ycvIt0
  ✓ Dump stderr is clean
  ✓ Completeness: All 26 operations present in dump (WG: 15, OVPN: 11)
  ✓ Deletion phase 1 dump stderr is clean
  ✓ Deletion: WG protocol link 'quick' removed from dump
  ✓ Deletion: OVPN protocol link 'office' removed from dump
  ✓ Deletion: WG protocol link 'default' still present
  ✓ Deletion: WG category 'privacy' still present
  ✓ Deletion: WG category 'work' still present
  ✓ Deletion: OVPN group 'corporate' still present
  ✓ Deletion phase 2 dump stderr is clean
  ✓ Deletion: WG category link 'privacy/fast' removed from dump
  ✓ Deletion: WG category link 'work/office' removed from dump
  ✓ Deletion: OVPN group link 'corporate/primary' removed from dump
  ✓ Deletion: WG category link 'privacy/secure' still present
  ✓ Deletion: WG category link 'streaming/hd' still present
  ✓ Deletion: OVPN group link 'corporate/secondary' still present
  ✓ Deletion: WG config wg-us-101.conf still present
  ✓ Deletion: WG config wg-de-303.conf still present
  ✓ Deletion: OVPN config us-server.ovpn still present
  ✓ Deletion phase 3 dump stderr is clean
  ✓ Deletion: WG config wg-jp-404.conf removed from dump
  ✓ Deletion: WG config wg-au-505.conf removed from dump
  ✓ Deletion: OVPN config asia-server.ovpn removed from dump
  ✓ Deletion: WG config wg-us-101.conf still present after removals
  ✓ Deletion: WG config wg-uk-202.conf still present after removals
  ✓ Deletion: WG config wg-de-303.conf still present after removals
  ✓ Deletion: OVPN config us-server.ovpn still present after removals
  ✓ Deletion: OVPN config eu-server.ovpn still present after removals
  ✓ Deletion: Empty WG category 'privacy' still present
  ✓ Deletion: Empty WG category 'work' still present
  ✓ Deletion: Empty WG category 'streaming' still present
  ✓ Deletion: OVPN group 'corporate' still present (has link)
  ✓ Deletion: Empty OVPN group 'remote' still present
✓ Story 5 completed successfully

▶ User Story 6: Dump Quality: Cleanliness, Pipeability, Executability, Transcript Reproducibility
  Database: /tmp/vpn-quality-test.byNNK6
  ✓ Property 1: Dump stderr is completely empty
  ✓ Property 2: Dump output is syntactically valid shell script
  ✓ Property 3: Direct pipe works (exit code 0)
  ✓ Property 3: Direct pipe produces identical output
  ✓ Property 4: All informational output is properly commented
  ✓ Property 5: All transcript commands present in dump (reproducibility)
  Database: /tmp/vpn-quality-restore.yvzHDW
  ✓ Property 6: Dump is restorable (executable)
  ✓ Property 6: WG config restored
  ✓ Property 6: OVPN config restored
  ✓ Property 6: WG category restored
  ✓ Property 6: OVPN group restored
  ✓ Property 6: WG link restored
  ✓ Property 6: OVPN link restored
  ✓ Property 7: Normalized idempotency verified (dump(restore(dump)) == dump)
  ✓ Property 8: No duplicate protocol commands in dump (6 unique)
✓ Story 6 completed successfully

▶ User Story 7: Phase-Based Script Generation (WireGuard and OpenVPN)
  Database: /tmp/vpn-phase-gen.M7IRB6
  ✓ WG: Extract session ID from start output
  ✓ WG: connect.sh exists
  ✓ WG: disconnect.sh exists
  ✓ WG: connect.sh has correct permissions (0750)
  ✓ WG: disconnect.sh has correct permissions (0750)
  ✓ WG: connect.sh is executable
  ✓ WG: disconnect.sh is executable
  ✓ WG: connect.sh has shebang
  ✓ WG: disconnect.sh has shebang
  ✓ OVPN: Extract session ID from start output
  ✓ OVPN: connect.sh exists
  ✓ OVPN: disconnect.sh exists
  ✓ OVPN: connect.sh has correct permissions (0750)
  ✓ OVPN: disconnect.sh has correct permissions (0750)
  ✓ OVPN: connect.sh is executable
  ✓ OVPN: disconnect.sh is executable
  ✓ OVPN: connect.sh has shebang
  ✓ OVPN: disconnect.sh has shebang
  ✓ WG: Session metadata exists (protocol)
  ✓ WG: Session metadata exists (interface)
  ✓ OVPN: Session metadata exists (protocol)
  ✓ OVPN: Session metadata exists (interface)
  ✓ WG and OVPN sessions are independent (different PIDs)
✓ Story 7 completed successfully

▶ User Story 8: Phase Script Content Verification (Structure and Commands)
  Database: /tmp/vpn-phase-content.DzfpTE
  ✓ WG connect: Has title
  ✓ WG connect: Has generation timestamp
  ✓ WG connect: Has session ID
  ✓ WG connect: Has context documentation
  ✓ WG connect: Has session_dir variable
  ✓ WG connect: Has protocol variable
  ✓ WG connect: Has interface variable
  ✓ WG connect: Has config_path variable
  ✓ WG connect: Has dns_server variable
  ✓ WG connect: Has remote_ips variable
  ✓ WG connect: Has firewall verify function
  ✓ WG connect: Has vpn verify function
  ✓ WG connect: Has dns verify function
  ✓ WG connect: Firewall prepare phase
  ✓ WG connect: Firewall execute phase
  ✓ WG connect: VPN prepare phase
  ✓ WG connect: VPN execute phase
  ✓ WG connect: DNS prepare phase
  ✓ WG connect: DNS execute phase
  ✓ WG connect: Has wg-quick up command
  ✓ WG connect: Correct phase order
  ✓ WG disconnect: Has title
  ✓ WG disconnect: Has session_dir variable
  ✓ WG disconnect: Has dns verify function
  ✓ WG disconnect: Has vpn verify function
  ✓ WG disconnect: Has firewall verify function
  ✓ WG disconnect: Has wg-quick down command
  ✓ WG disconnect: Correct reversed phase order
  ✓ OVPN connect: Has title
  ✓ OVPN connect: Has generation timestamp
  ✓ OVPN connect: Has session_dir variable
  ✓ OVPN connect: Has protocol variable
  ✓ OVPN connect: Has interface variable
  ✓ OVPN connect: Has config_path variable
  ✓ OVPN connect: Has firewall verify function
  ✓ OVPN connect: Has vpn verify function
  ✓ OVPN connect: Has dns verify function
  ✓ OVPN connect: Has openvpn command
  ✓ OVPN connect: Has daemon flag
  ✓ OVPN connect: Correct phase order
  ✓ OVPN disconnect: Has title
  ✓ OVPN disconnect: Has session_dir variable
  ✓ OVPN disconnect: Has process kill command
  ✓ OVPN disconnect: Correct reversed phase order
  ✓ WG connect: No OpenVPN commands
  ✓ WG connect: No OpenVPN daemon flag
  ✓ OVPN connect: No WireGuard commands
✓ Story 8 completed successfully

▶ User Story 9: Phase Customization (Reorder, Add, Skip)
  Database: /tmp/vpn-phase-custom.U8XhYA
  ✓ Baseline: Default phase order
  ✓ Reordered: Custom phase order
  ✓ Custom phase: Has verify function
  ✓ Custom phase: Has prepare section
  ✓ Custom phase: Has execute section
  ✓ Custom phase: Correct order with routing
  ✓ Minimal: Has vpn verify function
  ✓ Minimal: No firewall phase
  ✓ Minimal: No dns phase
  ✓ Minimal: Only VPN phase
  ✓ Custom disconnect: Has dns phase
  ✓ Custom disconnect: Has vpn phase
  ✓ Custom disconnect: No firewall phase
  ✓ Custom disconnect: Only dns and vpn
  ✓ Multi-custom: Has logging phase
  ✓ Multi-custom: Has monitoring phase
  ✓ Multi-custom: Correct custom order
✓ Story 9 completed successfully

▶ User Story 10: Multi-Protocol Phase Support (Isolation and Simultaneous Operation)
  Database: /tmp/vpn-phase-multi.RkI3Mk
  ✓ WG: Default phase order
  ✓ OVPN: Default phase order
  ✓ WG: Has WireGuard command
  ✓ WG: No OpenVPN commands
  ✓ OVPN: Has OpenVPN command
  ✓ OVPN: No WireGuard commands
  ✓ WG: Correct protocol variable
  ✓ WG: WireGuard interface naming
  ✓ WG: Has dns_server context
  ✓ WG: Has remote_ips context
  ✓ OVPN: Correct protocol variable
  ✓ OVPN: OpenVPN interface naming
  ✓ WG custom: Has custom phase
  ✓ WG custom: Has custom phase in order
  ✓ OVPN: No WireGuard custom phase
  ✓ OVPN: Default phases only
  ✓ WG: No OpenVPN custom phase
  ✓ WG: Default phases only
  ✓ OVPN: Protocol-specific phase config not yet supported
  ✓ OVPN: Uses default phases (protocol-specific config not implemented)
  ✓ Simultaneous: WG session exists
  ✓ Simultaneous: OVPN session exists
  ✓ Simultaneous: Different session IDs
  ✓ Simultaneous: WG has correct protocol
  ✓ Simultaneous: OVPN has correct protocol
✓ Story 10 completed successfully

▶ User Story 11: Multi-Protocol Edge Cases (Stress, Switching, Robustness)
  Database: /tmp/vpn-edge-cases.Bp7waY
  ✓ Scenario 1.1: Duplicate WG import correctly rejected
  ✓ Scenario 1.1: Duplicate OVPN import correctly rejected
  ✓ Scenario 1.1: WG includes wg_custom phase
  ✓ Scenario 1.1: WG excludes ovpn_custom phase
  ✓ Scenario 1.1: OVPN includes ovpn_custom phase
  ✓ Scenario 1.1: OVPN excludes wg_custom phase
  ✓ Scenario 1.1: Phase order differs between protocols
  ✓ Scenario 1.2: WireGuard test interface configured
  ✓ Scenario 1.2: OpenVPN test interface configured
  ✓ Scenario 1.2: Two sessions active simultaneously
  ✓ Scenario 1.2: WG session uses wg_test* interface
  ✓ Scenario 1.2: OVPN session uses tun_test* interface
  ✓ Scenario 1.2: Unreferenced sessions cleaned, 'latest' preserved
  ✓ Scenario 1.3: WG session has DNS config
  ✓ Scenario 1.3: Connect scripts differ despite same DNS
  ✓ Scenario 2.1: WG session created
  ✓ Scenario 2.1: WG session stopped, 'latest' preserved
  ✓ Scenario 2.1: OVPN session created after WG stop
  ✓ Scenario 2.1: New session is OpenVPN protocol
  ✓ Scenario 2.2: Both sessions coexist
  ✓ Scenario 2.2: Both protocols running simultaneously
  ✓ Scenario 2.3: Cycle 1 - WG started
  ✓ Scenario 2.3: Cycle 1 - WG stopped, 'latest' preserved
  ✓ Scenario 2.3: Cycle 2 - OVPN started (old session + new)
  ✓ Scenario 2.3: Cycle 2 - OVPN stopped, unreferenced cleaned
  ✓ Scenario 2.3: Cycle 3 - WG started (old session + new)
  ✓ Scenario 2.3: Both sessions present (unreferenced + latest)
  ✓ Scenario 3.1: WG session saved as wg_work
  ✓ Scenario 3.1: Both sessions active after resume
  ✓ Scenario 3.1: Correct protocols after resume
  ✓ Scenario 3.2: Session 'work' points to WG session
  ✓ Scenario 3.2: Session 'work' now points to OVPN (overwrite)
  ✓ Scenario 3.2: Only one 'work' session exists (no duplicates)
  ✓ Scenario 4.1: Two active sessions before dump
  ✓ Scenario 4.1: Dump file created with active sessions
  ✓ Scenario 4.1: Dump excludes .session directory (transient)
  ✓ Scenario 4.1: Dump includes WG configs
  ✓ Scenario 4.1: Dump includes OVPN configs
  Database: /tmp/vpn-restore-a.krjTed
  Database: /tmp/vpn-restore-b.VdLbBh
  ✓ Scenario 4.2: Restored database has WG config
  ✓ Scenario 4.2: Restored database has no active sessions
  ✓ Scenario 5.1: Only 'latest' WG session after 10 cycles
  ✓ Scenario 5.1: Only 'latest' OVPN session after 10 cycles
  ✓ Scenario 5.1: Only latest session directory remains
✓ Story 11 completed successfully

▶ User Story 12: Phase Backend Selection (Strategy 7 - Automatic Template Lifting)
  Database: /tmp/vpn-backend-selection.DWCW3o
  ✓ Backend template lifted: firewall/pf.sh
  ✓ Backend template lifted: firewall/ipfw.sh
  ✓ Backend template lifted: dns/resolvconf.sh
  ✓ Backend template lifted: dns/unbound.sh
  ✓ Scenario 1: Connect script generated
  ✓ Scenario 1: PF firewall backend used (contains pfctl)
  ✓ Scenario 1: Resolvconf DNS backend used
  ✓ Scenario 2: IPFW firewall backend used (contains ipfw)
  ✓ Scenario 2: Unbound DNS backend used
  ✓ Scenario 2: PF firewall phase not used (backend isolated)
  ✓ Scenario 3: Backward compat - connect script generated
  ✓ Scenario 3: Backward compat - script not empty
  ✓ Scenario 3: Uses protocol-specific phases (wireguard/)
  ✓ Scenario 4: Both backends from @base profile used
  ✓ Scenario 5: Variant-only syntax works (uses default profile)
  ✓ Scenario 6: Mixed syntax - ipfw backend used
  ✓ Scenario 6: Mixed syntax - vpn phase executed
  ✓ Scenario 6: Mixed syntax - traditional dns phase used
✓ Story 12 completed successfully

========================================
Test Summary
========================================
User Stories:  12
  Passed:      12
  Failed:      0

Assertions:    296
  Passed:      296
  Failed:      0

ALL STORIES PASSED
========================================
vpn-switch Unit Test Suite (Formalized)
========================================


Running Tests
========================================
Filter active - running only:test_header test_summary test_setup test_printenv_command test_status_command test_wireguard_import_valid test_wireguard_add_category test_wireguard_link_create test_wireguard_list test_wireguard_validate test_wireguard_info test_wireguard_start_basic test_wireguard_connect_resume test_wireguard_stop_basic test_session_list test_session_show test_session_remove test_session_save_default test_session_save_named test_session_start_default test_session_start_named test_session_start_bypid test_session_stop_named test_session_stop_bypid test_session_stop_inactive test_wireguard_remove_config_in_use test_wireguard_remove_config_with_refs test_wireguard_remove_symlink test_wireguard_remove_category_link test_wireguard_clean_no_broken test_wireguard_clean_broken_protocol_link test_wireguard_clean_broken_category_link test_wireguard_clean_category_no_broken test_wireguard_clean_category_with_broken test_wireguard_validate_broken_symlink test_wireguard_validate_broken_category_symlink test_wireguard_validate_naming_conflict test_wireguard_validate_invalid_config test_stop_no_sessions test_stop_specific_interface test_wireguard_disconnect_interface test_stop_nonexistent_interface test_disconnect_without_session test_stop_twice_idempotent test_wireguard_import_nonexistent test_wireguard_import_duplicate test_wireguard_add_category_conflict test_wireguard_add_link_conflict test_wireguard_link_conflict test_error_invalid_category test_error_broken_symlink test_error_invalid_command test_edge_duplicate_instance_prevention test_edge_stale_session_cleanup test_wireguard_patch_valid test_wireguard_patch_nonexistent test_wireguard_patch_absolute test_wireguard_info_category test_session_save_default test_session_save_named test_session_start_default test_session_start_named test_session_start_by_pid test_protocol_agnostic_import_wireguard test_protocol_agnostic_list test_protocol_agnostic_link test_protocol_agnostic_remove test_protocol_agnostic_validate test_network_validate test_permissions_validate test_environment_validate test_batch_validate_includes_system test_interpreter_single_underscore test_interpreter_double_underscore test_interpreter_triple_underscore test_interpreter_resolution_priority test_start_wireguard_only test_start_openvpn_only test_start_not_found test_start_no_default test_start_with_default_wireguard test_start_with_default_openvpn test_start_default_invalid_target test_init_extension_links test_database_init test_environment_init test_phases_copy test_phases_lift test_phases_sync_single test_phases_sync_all test_init_batch_combinator test_init_combinator test_start_extension_link_fast_path test_start_multiple_matches test_openvpn_import_valid test_openvpn_list test_openvpn_add_group test_openvpn_link test_openvpn_remove test_openvpn_validate test_openvpn_info test_openvpn_dump test_openvpn_patch_valid test_openvpn_patch_nonexistent test_openvpn_patch_absolute test_openvpn_patch_credentials_bare test_openvpn_patch_credentials_existing test_openvpn_patch_credentials_missing test_openvpn_start_basic test_openvpn_stop_basic test_openvpn_disconnect_interface test_openvpn_clean test_setenv_basic test_setenv_invalid_name test_getenv_local_override test_getenv_fallback_chain test_unsetenv_existing test_unsetenv_not_set test_dumpenv_prologue test_dumpenv_epilogue test_dumpenv_profile_filtering test_environment_cache_on test_environment_cache_off test_environment_cache_status test_environment_cache_no_args test_cache_invalidation_setenv test_cache_invalidation_unsetenv test_cache_invalidation_environment_init test_dumpenv_cache_preservation test_dumpenv_cache_not_included_when_disabled test_cache_no_recursion test_inspect_batch_complete test_environment_inspect test_system_inspect test_batch_syntax_wireguard_clean test_combinators_literal_variable test_function_classification_correct test_no_terminal_output_vpnswitch_commands test_metadata_function_lists test_combinator_syntax_validation test_error_command_single_line test_error_command_two_lines test_error_command_three_lines test_error_command_ansi_colors test_batch_id_sequential test_store_batch_exits_basic test_store_batch_exits_references test_free_batch_id test_batch_infrastructure_lifecycle 


TEST 1 (test_batch_id_sequential): get_batch_id - sequential allocation
  Database: /tmp/vpn-switch-test.88851/test_1
✓ First batch ID is 0
✓ Second batch ID is 1
✓ Third batch ID is 2
✓ Counter file has correct value (3)

TEST 2 (test_store_batch_exits_basic): store_batch_exits - stores exit codes to file
  Database: /tmp/vpn-switch-test.88851/test_2
✓ Batch file created
✓ Batch file has correct content

TEST 3 (test_store_batch_exits_references): store_batch_exits - stores exit codes with batch references
  Database: /tmp/vpn-switch-test.88851/test_3
✓ Batch file stores references correctly

TEST 4 (test_free_batch_id): free_batch_id - deletes batch file
  Database: /tmp/vpn-switch-test.88851/test_4
✓ Batch file exists before cleanup
✓ Batch file deleted after cleanup

TEST 5 (test_batch_infrastructure_lifecycle): Batch infrastructure - full allocation/store/free lifecycle
  Database: /tmp/vpn-switch-test.88851/test_5
✓ Allocated batch ID: 0
✓ Batch results stored
✓ Batch results readable
✓ Batch cleaned up successfully

TEST 6 (test_printenv_command): printenv - basic environment display
  Database: /tmp/vpn-switch-test.88851/test_6
✓ Printenv command executed and shows header
✓ Printenv shows VPN_SWITCH_BASE variable

TEST 7 (test_status_command): status - VPN status display
  Database: /tmp/vpn-switch-test.88851/test_7
✓ Status command shows header
✓ Status shows disconnected state
✓ Status checks network interfaces

TEST 8 (test_error_command_single_line): error command - single line message
  Database: /tmp/vpn-switch-test.88851/test_8
✓ error command outputs printf with 'Error:' prefix
✓ error command outputs exit 1
✓ error command redirects to stderr

TEST 9 (test_error_command_two_lines): error command - two line message
  Database: /tmp/vpn-switch-test.88851/test_9
✓ error command first line has 'Error:' prefix
✓ error command second line is indented without 'Error:' prefix
✓ error command outputs exit 1

TEST 10 (test_error_command_three_lines): error command - three line message
  Database: /tmp/vpn-switch-test.88851/test_10
✓ error command first line has 'Error:' prefix
✓ error command has properly indented continuation lines
✓ error command includes all three message lines
✓ error command outputs exit 1

TEST 11 (test_error_command_ansi_colors): error command - ANSI color support
  Database: /tmp/vpn-switch-test.88851/test_11
✓ error command includes ANSI escape codes when enabled
✓ error command includes ANSI reset code

TEST 12 (test_wireguard_list): wireguard list - display configurations
  Database: /tmp/vpn-switch-test.88851/test_12
✓ Configuration section header displayed
✓ Config files section displayed
✓ Imported config file listed

TEST 13 (test_wireguard_validate): wireguard validate - validate clean configuration
  Database: /tmp/vpn-switch-test.88851/test_13
✓ Validation header displayed
✓ No issues found in clean configuration

TEST 14 (test_wireguard_info): wireguard info - display category information
  Database: /tmp/vpn-switch-test.88851/test_14
✓ Category header displayed
✓ Category path displayed
✓ Contents section displayed
✓ Category contents listed with symlink arrows

TEST 15 (test_wireguard_import_valid): wireguard import - import valid config
  Database: /tmp/vpn-switch-test.88851/test_15
✓ Config file imported to database
✓ Permissions set to 0400 (read-only)

TEST 16 (test_wireguard_add_category): wireguard add - create category with permissions
  Database: /tmp/vpn-switch-test.88851/test_16
✓ Category directory created
✓ Permissions set to 0755

TEST 17 (test_wireguard_link_create): wireguard link - create symlink in protocol directory
  Database: /tmp/vpn-switch-test.88851/test_17
✓ Symlink created
✓ Symlink points to correct relative path (./wg-TEST-RS-1.conf)

TEST 18 (test_wireguard_start_basic): wireguard start - create session and connect to VPN
  Database: /tmp/vpn-switch-test.88851/test_18
✓ Session creation logged
✓ wg-quick command in connect.sh
✓ Session directory created in .session/
✓ Session metadata files created
✓ connect.sh script generated
✓ connect.sh is executable
✓ connect.sh documents original config with relative path
✓ Patched config (wg_test13.conf) created
✓ Patched config correctly strips PostUp hook (phase-based DNS)
✓ Patched config correctly strips PostDown hook (phase-based DNS)

TEST 19 (test_wireguard_connect_resume): wireguard connect - resume existing session by ID
  Database: /tmp/vpn-switch-test.88851/test_19
✓ wireguard connect generated wg-quick command in connect.sh
✓ wireguard connect generated pfctl command in connect.sh
✓ wireguard connect used session configuration
✓ connect.sh preserved after connect

TEST 20 (test_wireguard_stop_basic): stop - disconnect active VPN session
  Database: /tmp/vpn-switch-test.88851/test_20
✓ Session exists before stop
✓ disconnect.sh contains wg-quick down command
✓ Stop command executed
✓ Session preserved after stop (has 'latest' link)

TEST 21 (test_session_list): session list - display active and stale sessions
  Database: /tmp/vpn-switch-test.88851/test_21
✓ Session list header displayed
✓ Active session (PID 27440) listed
✓ Stale session (PID 99997) listed
✓ Stale session (dead process) marked as stopped

TEST 22 (test_session_show): session show - display connect script
  Database: /tmp/vpn-switch-test.88851/test_22
✓ Extracted session ID (89236) from start command output
✓ Session ID displayed in header
✓ Session protocol displayed
✓ Connect script contents displayed

TEST 23 (test_session_remove): session remove - remove stale, refuse active
  Database: /tmp/vpn-switch-test.88851/test_23
✓ Stale session created for removal test
✓ Removal operation logged for stale session
✓ Active session (PID 88851) created for refusal test
✓ Refuses to remove active session (PID 88851)

TEST 24 (test_session_save_default): session save - save current session as default
  Database: /tmp/vpn-switch-test.88851/test_24
✓ Default session symlink created
✓ Default symlink points to correct session

TEST 25 (test_session_save_named): session save work - save with custom name
  Database: /tmp/vpn-switch-test.88851/test_25
✓ Named session symlink created
✓ Named symlink points to correct session

TEST 26 (test_session_start_default): session start - resume default session
  Database: /tmp/vpn-switch-test.88851/test_26
✓ Connect script created before stopping
✓ Session directory kept for resumption (referenced)
✓ Default symlink persists after stop
✓ Session start executed successfully

TEST 27 (test_session_start_named): session start work - resume named session
  Database: /tmp/vpn-switch-test.88851/test_27
✓ Named symlink persists after stop
✓ Named session start executed successfully

TEST 28 (test_session_start_bypid): session start <PID> - resume session by PID
  Database: /tmp/vpn-switch-test.88851/test_28
✓ Mock session (PID 11111) created for PID resume test
✓ Session start resumes by explicit PID (11111)

TEST 29 (test_session_stop_named): session stop work - stop active named session
  Database: /tmp/vpn-switch-test.88851/test_29
✓ Session stop resolves named session 'work'

TEST 30 (test_session_stop_bypid): session stop <PID> - stop active session by PID
  Database: /tmp/vpn-switch-test.88851/test_30
✓ Session stop handles PID (88888)

TEST 31 (test_session_stop_inactive): session stop <PID> - inactive session should log (not error)
  Database: /tmp/vpn-switch-test.88851/test_31
✓ Session stop handles inactive session gracefully

TEST 32 (test_wireguard_remove_config_in_use): wireguard remove - refuse removal when config in use
  Database: /tmp/vpn-switch-test.88851/test_32
✓ Active session (PID 88851) created using config
✓ Error message when config in use by session
✓ Error suggests removing session first

TEST 33 (test_wireguard_remove_config_with_refs): wireguard remove - refuse removal when config has symlink refs
  Database: /tmp/vpn-switch-test.88851/test_33
✓ Category symlink created (privacy/rm2)
✓ Error message when config has symlink references
✓ Error lists symlink references

TEST 34 (test_wireguard_remove_symlink): wireguard remove - remove symlink (no safety checks)
  Database: /tmp/vpn-switch-test.88851/test_34
✓ Test symlink created
✓ Symlink removal operation logged
✓ Symlink was removed

TEST 35 (test_wireguard_remove_category_link): wireguard remove - remove link from category
  Database: /tmp/vpn-switch-test.88851/test_35
✓ Category link (privacy/rm4) created
✓ Category link removal operation logged
✓ Category link was removed

TEST 36 (test_wireguard_clean_no_broken): wireguard clean - no broken links found
  Database: /tmp/vpn-switch-test.88851/test_36
✓ Clean header displayed
✓ No broken symlinks message displayed
✓ Usage hint displayed

TEST 37 (test_wireguard_clean_broken_protocol_link): wireguard clean - detect and generate remove for broken protocol link
  Database: /tmp/vpn-switch-test.88851/test_37
✓ Broken protocol symlink created for testing
✓ Remove command generated for broken protocol link
✓ Command includes link name

TEST 38 (test_wireguard_clean_broken_category_link): wireguard clean - detect and generate remove for broken category link
  Database: /tmp/vpn-switch-test.88851/test_38
✓ Broken category symlink created for testing
✓ Remove command generated for broken category link
✓ Command includes category name

TEST 39 (test_wireguard_clean_category_no_broken): wireguard clean privacy - category with no broken links
  Database: /tmp/vpn-switch-test.88851/test_39
✓ Category-specific header displayed
✓ No broken symlinks message for category

TEST 40 (test_wireguard_clean_category_with_broken): wireguard clean privacy - category with broken links
  Database: /tmp/vpn-switch-test.88851/test_40
✓ Broken symlink created in privacy category
✓ Remove command generated for category link
✓ Category-specific clean (not global)

TEST 41 (test_wireguard_validate_broken_symlink): wireguard validate - detect broken symlinks
  Database: /tmp/vpn-switch-test.88851/test_41
✓ Broken symlink created for validation test
✓ Broken symlink detected in protocol directory
✓ Error status reported

TEST 42 (test_wireguard_validate_broken_category_symlink): wireguard validate - detect broken symlinks in categories
  Database: /tmp/vpn-switch-test.88851/test_42
✓ Broken category symlink created for validation test
✓ Broken symlink detected in category

TEST 43 (test_wireguard_validate_naming_conflict): wireguard validate - detect naming conflicts
  Database: /tmp/vpn-switch-test.88851/test_43
✓ Naming conflict created (file + directory)
✓ Naming conflict detected

TEST 44 (test_wireguard_validate_invalid_config): wireguard validate - detect invalid config files
  Database: /tmp/vpn-switch-test.88851/test_44
✓ Empty config file created for validation test
✓ Empty config file detected
✓ Missing [Interface] section detected

TEST 45 (test_stop_no_sessions): stop - no sessions exist (empty output)
  Database: /tmp/vpn-switch-test.88851/test_45
✓ No output or log message when no sessions exist

TEST 46 (test_stop_specific_interface): stop wg_test_safe - stop specific interface by name
  Database: /tmp/vpn-switch-test.88851/test_46
✓ Active session (PID 88851, interface wg_test_safe) created
✓ Stopped specific interface wg_test_safe
✓ Interface wg_test_safe disconnect command generated

TEST 47 (test_wireguard_disconnect_interface): wireguard disconnect wg_test_safe - direct disconnect command
  Database: /tmp/vpn-switch-test.88851/test_47
✓ Active session (PID 88851) created for disconnect test
✓ Disconnect command executed for wg_test_safe
✓ Session PID displayed correctly

TEST 48 (test_stop_nonexistent_interface): stop wg_test_other - error when interface not found
  Database: /tmp/vpn-switch-test.88851/test_48
✓ Active session with wg_test_safe interface created
✓ Error message for nonexistent interface

TEST 49 (test_disconnect_without_session): disconnect without session - error handling
  Database: /tmp/vpn-switch-test.88851/test_49
✓ Error message when no session exists

TEST 50 (test_stop_twice_idempotent): stop twice - idempotent (safe to call multiple times)
  Database: /tmp/vpn-switch-test.88851/test_50
✓ First stop: handles no sessions gracefully
✓ Second stop: still handles no sessions (idempotent)

TEST 51 (test_wireguard_import_nonexistent): wireguard import - error when file doesn't exist
  Database: /tmp/vpn-switch-test.88851/test_51
✓ Error message for non-existent file

TEST 52 (test_wireguard_import_duplicate): wireguard import - error when config already exists
  Database: /tmp/vpn-switch-test.88851/test_52
✓ First import succeeded
✓ Error message when config already exists

TEST 53 (test_wireguard_add_category_conflict): wireguard add - error when category already exists
  Database: /tmp/vpn-switch-test.88851/test_53
✓ First add succeeded (privacy category created)
✓ Error message when category already exists

TEST 54 (test_wireguard_add_link_conflict): wireguard add - error when link already exists
  Database: /tmp/vpn-switch-test.88851/test_54
✓ First link created successfully
✓ Error message when link already exists

TEST 55 (test_wireguard_link_conflict): wireguard link - error when alias already exists
  Database: /tmp/vpn-switch-test.88851/test_55
✓ Config imported successfully
✓ Error message when alias already exists

TEST 56 (test_error_invalid_category): error handling - invalid category shows error
  Database: /tmp/vpn-switch-test.88851/test_56
✓ Error message for invalid category

TEST 57 (test_error_broken_symlink): error handling - broken symlink handled gracefully
  Database: /tmp/vpn-switch-test.88851/test_57
✓ Broken symlink created for testing
✓ Handled broken symlink (error or skipped)

TEST 58 (test_error_invalid_command): error handling - invalid command shows usage
  Database: /tmp/vpn-switch-test.88851/test_58
✓ Usage/help shown for invalid command

TEST 59 (test_edge_duplicate_instance_prevention): edge case - prevent duplicate VPN instances
  Database: /tmp/vpn-switch-test.88851/test_59
✓ First VPN session created (PID 88851)
✓ Detected existing VPN instance
✓ No duplicate session created

TEST 60 (test_edge_stale_session_cleanup): edge case - stale sessions don't block new sessions
  Database: /tmp/vpn-switch-test.88851/test_60
✓ Stale session created for testing
✓ Proceeded with new session (stale session didn't block)
✓ Stale session preserved (manual cleanup via 'session clean' required)

TEST 61 (test_wireguard_patch_valid): wireguard patch - displays patched configuration
  Database: /tmp/vpn-switch-test.88851/test_61
✓ Patch output correctly strips PostUp hook (phase-based DNS)
✓ Patch output correctly strips PostDown hook (phase-based DNS)
✓ Patch output preserves [Interface] section
✓ Patch output preserves [Peer] section

TEST 62 (test_wireguard_patch_nonexistent): wireguard patch - handles nonexistent config
  Database: /tmp/vpn-switch-test.88851/test_62
✓ Patch rejects nonexistent config with error

TEST 63 (test_wireguard_patch_absolute): wireguard patch - handles absolute path
  Database: /tmp/vpn-switch-test.88851/test_63
✓ Patch works with absolute path (strips DNS hooks)

TEST 64 (test_wireguard_info_category): wireguard info - displays category information
  Database: /tmp/vpn-switch-test.88851/test_64
✓ Category header displayed
✓ Config count displayed
✓ Link count displayed
✓ Category path displayed
✓ Contents section header displayed
✓ Category contents listed with symlink arrows

TEST 65 (test_session_save_default): session save - save current session as default
  Database: /tmp/vpn-switch-test.88851/test_65
✓ Default session symlink created
✓ Default symlink points to correct session

TEST 66 (test_session_save_named): session save work - save with custom name
  Database: /tmp/vpn-switch-test.88851/test_66
✓ Named session symlink created
✓ Named symlink points to correct session

TEST 67 (test_session_start_default): session start - resume default session
  Database: /tmp/vpn-switch-test.88851/test_67
✓ Connect script created before stopping
✓ Session directory kept for resumption (referenced)
✓ Default symlink persists after stop
✓ Session start executed successfully

TEST 68 (test_session_start_named): session start work - resume named session
  Database: /tmp/vpn-switch-test.88851/test_68
✓ Named symlink persists after stop
✓ Named session start executed successfully

TEST 69 (test_session_start_by_pid): session start <PID> - resume by PID
  Database: /tmp/vpn-switch-test.88851/test_69
✓ Session start by PID executed successfully

TEST 70 (test_openvpn_import_valid): openvpn import - import valid .ovpn config
  Database: /tmp/vpn-switch-test.88851/test_70
✓ Config imported to openvpn/
✓ Permissions set to 0400

TEST 71 (test_openvpn_list): openvpn list - list configs and groups
  Database: /tmp/vpn-switch-test.88851/test_71
✓ Lists config: us-server.ovpn
✓ Lists group: work/
✓ Lists group link with arity-1: work/office

TEST 72 (test_openvpn_add_group): openvpn add - create group
  Database: /tmp/vpn-switch-test.88851/test_72
✓ Group directory created
✓ Group permissions correct (0700)

TEST 73 (test_openvpn_link): openvpn link - create protocol-level link
  Database: /tmp/vpn-switch-test.88851/test_73
✓ Protocol-level link created
✓ Link target correct

TEST 74 (test_openvpn_remove): openvpn remove - remove config safely
  Database: /tmp/vpn-switch-test.88851/test_74
✓ Config removed
✓ Other config preserved

TEST 75 (test_openvpn_validate): openvpn validate - detect broken links
  Database: /tmp/vpn-switch-test.88851/test_75
✓ Broken symlink detected
✓ Valid database passes validation

TEST 76 (test_openvpn_info): openvpn info - show group information
  Database: /tmp/vpn-switch-test.88851/test_76
✓ Shows group name
✓ Shows correct link count
✓ Shows link: office

TEST 77 (test_openvpn_dump): openvpn dump - export database
  Database: /tmp/vpn-switch-test.88851/test_77
✓ Dump includes import command
✓ Dump includes group creation
✓ Dump includes protocol link
✓ Dump includes group link

TEST 78 (test_openvpn_patch_valid): openvpn patch - displays patched configuration
  Database: /tmp/vpn-switch-test.88851/test_78
✓ Patch output correctly strips up script (phase-based DNS)
✓ Patch output correctly strips down script (phase-based DNS)
✓ Patch output contains daemon mode
✓ Patch output contains device interface
✓ Patch output contains writepid directive
✓ Patch output preserves client directive
✓ Patch output preserves remote server

TEST 79 (test_openvpn_patch_nonexistent): openvpn patch - handles nonexistent config
  Database: /tmp/vpn-switch-test.88851/test_79
✓ Error message for nonexistent config

TEST 80 (test_openvpn_patch_absolute): openvpn patch - handles absolute path
  Database: /tmp/vpn-switch-test.88851/test_80
✓ Absolute path patch works

TEST 81 (test_openvpn_patch_credentials_bare): openvpn patch - patches bare auth-user-pass with credentials
  Database: /tmp/vpn-switch-test.88851/test_81
✓ Bare auth-user-pass patched with credentials path
✓ Bare auth-user-pass preserved when no credentials set

TEST 82 (test_openvpn_patch_credentials_existing): openvpn patch - preserves existing auth-user-pass path
  Database: /tmp/vpn-switch-test.88851/test_82
✓ Existing auth-user-pass path preserved (not overridden)

TEST 83 (test_openvpn_patch_credentials_missing): openvpn patch - handles config without auth-user-pass
  Database: /tmp/vpn-switch-test.88851/test_83
✓ Config without auth-user-pass remains unchanged

TEST 84 (test_openvpn_start_basic): openvpn start - create session and connect to VPN
  Database: /tmp/vpn-switch-test.88851/test_84
✓ Session creation logged
✓ openvpn command in connect.sh
✓ Session directory created in .session/
✓ Session metadata files created
✓ connect.sh script generated
✓ connect.sh is executable
✓ Patched config (tun_test80.ovpn) created
✓ Patched config contains daemon mode
✓ Patched config correctly strips up script (phase-based DNS)
✓ Patched config correctly strips down script (phase-based DNS)

TEST 85 (test_openvpn_stop_basic): openvpn stop - cleanup commands for session
  Database: /tmp/vpn-switch-test.88851/test_85
✓ Session created via user interface
✓ Disconnect commands reference correct interface (tun_test85)
✓ Disconnect generates process kill commands

TEST 86 (test_openvpn_disconnect_interface): openvpn disconnect - tear down OpenVPN interface
  Database: /tmp/vpn-switch-test.88851/test_86
✓ Disconnect generates process termination commands

TEST 87 (test_openvpn_clean): openvpn clean - generate cleanup commands for broken links
  Database: /tmp/vpn-switch-test.88851/test_87
✓ Clean generates remove commands
✓ Clean detected broken symlink

TEST 88 (test_protocol_agnostic_import_wireguard): import (protocol-agnostic) - detects WireGuard .conf file
  Database: /tmp/vpn-switch-test.88851/test_88
✓ Protocol-agnostic import detected .conf and delegated to wireguard import
✓ Protocol-agnostic import generates correct cp command

TEST 89 (test_protocol_agnostic_list): list (protocol-agnostic) - delegates to all protocols
  Database: /tmp/vpn-switch-test.88851/test_89
✓ Protocol-agnostic list delegated to wireguard list
✓ Protocol-agnostic list shows wireguard config sections
✓ Protocol-agnostic list has no duplicate lines (3 unique)

TEST 90 (test_protocol_agnostic_link): link (protocol-agnostic) - creates protocol-level alias
  Database: /tmp/vpn-switch-test.88851/test_90
✓ Protocol-agnostic link generates ln command
✓ Protocol-agnostic link uses correct relative path (./wireguard)
✓ Protocol-agnostic link includes correct alias name

TEST 91 (test_protocol_agnostic_remove): remove (protocol-agnostic) - removes protocol-level link
  Database: /tmp/vpn-switch-test.88851/test_91
✓ Protocol-agnostic remove generates rm command
✓ Protocol-agnostic remove includes descriptive comment
✓ Protocol-agnostic remove errors on non-existent link

TEST 92 (test_protocol_agnostic_validate): validate (protocol-agnostic) - delegates to all protocols
  Database: /tmp/vpn-switch-test.88851/test_92
✓ Protocol-agnostic validate delegated to wireguard validate
✓ Protocol-agnostic validate shows validation output

TEST 93 (test_network_validate): network validate - check network prerequisites
  Database: /tmp/vpn-switch-test.88851/test_93
✓ Network validation header displayed
✓ Network validate passed on clean configuration

TEST 94 (test_permissions_validate): permissions validate - check filesystem permissions
  Database: /tmp/vpn-switch-test.88851/test_94
✓ Permissions validation header displayed
✓ Permissions validate passed on clean configuration

TEST 95 (test_environment_validate): environment validate - check environment variables
  Database: /tmp/vpn-switch-test.88851/test_95
✓ Environment validation header displayed
✓ Environment validate passed on clean configuration

TEST 96 (test_batch_validate_includes_system): validate (batch) - includes system validators
  Database: /tmp/vpn-switch-test.88851/test_96
✓ Batch validate includes database validator
✓ Batch validate includes binaries validator
✓ Batch validate includes phases validator
✓ Batch validate includes network validator
✓ Batch validate includes permissions validator
✓ Batch validate includes environment validator

TEST 97 (test_start_wireguard_only): start - auto-detect WireGuard config
  Database: /tmp/vpn-switch-test.88851/test_97
✓ Delegates to wireguard commands for WireGuard-only config

TEST 98 (test_start_openvpn_only): start - auto-detect OpenVPN config
  Database: /tmp/vpn-switch-test.88851/test_98
✓ Delegates to openvpn commands for OpenVPN-only config

TEST 99 (test_start_not_found): start - error on nonexistent config
  Database: /tmp/vpn-switch-test.88851/test_99
✓ Error message for nonexistent config
✓ Error shows both search locations

TEST 100 (test_start_no_default): start - error when no configs exist (Phase 3.4.1)
  Database: /tmp/vpn-switch-test.88851/test_100
✓ Error message when no configs available
✓ Error provides hint to import configs

TEST 101 (test_start_with_default_wireguard): start - use default link (WireGuard) via API
  Database: /tmp/vpn-switch-test.88851/test_101
✓ Default session link created via API
✓ Start with no args resolves to default session

TEST 102 (test_start_with_default_openvpn): start - use default link (OpenVPN) via API
  Database: /tmp/vpn-switch-test.88851/test_102
✓ Default session link created via API
✓ Start with no args resolves to default session

TEST 103 (test_start_default_invalid_target): start - error on invalid default link target
  Database: /tmp/vpn-switch-test.88851/test_103
✓ Error detected for invalid default session target

TEST 104 (test_init_extension_links): init - creates protocol extension links (Phase 3.4.1)
  Database: /tmp/vpn-switch-test.88851/test_104
✓ conf link created
✓ ovpn link created
✓ conf → wireguard
✓ ovpn → openvpn

TEST 105 (test_start_extension_link_fast_path): start - uses extension link for protocol resolution (Phase 3.4.1)
  Database: /tmp/vpn-switch-test.88851/test_105
✓ Extension link used for fast protocol resolution (wireguard commands found)

TEST 106 (test_start_multiple_matches): start - error on multiple protocol matches (Phase 3.4.1)
  Database: /tmp/vpn-switch-test.88851/test_106
✓ Multiple matches error shown
✓ Both matches listed

TEST 107 (test_database_init): database init - creates directory structure (Phase 4.4)
  Database: /tmp/vpn-switch-test.88851/test_107
✓ wireguard/ created
✓ openvpn/ created
✓ .session/ created
✓ session/ created
✓ .env/default/ created
✓ .env/local/ created
✓ .include/phase/ created

TEST 108 (test_environment_init): environment init - copies profile templates (Phase 4.4)
  Database: /tmp/vpn-switch-test.88851/test_108
✓ minimal profile copied
✓ profile has correct permissions (0600)

TEST 109 (test_phases_copy): phases copy - copies phase templates (Phase 4.4)
  Database: /tmp/vpn-switch-test.88851/test_109
✓ wireguard phases copied
✓ openvpn phases copied
✓ wireguard phase subdirs exist

TEST 110 (test_phases_lift): phases lift - lifts phase:backend templates (Phase 4.4)
  Database: /tmp/vpn-switch-test.88851/test_110
✓ generates lift command
✓ output file is executable

TEST 111 (test_phases_sync_single): phases sync <phase> - discovers and lifts backends (Phase 4.4)
  Database: /tmp/vpn-switch-test.88851/test_111
✓ delegates to phases lift

TEST 112 (test_phases_sync_all): phases sync - syncs all phases (Phase 4.4)
  Database: /tmp/vpn-switch-test.88851/test_112
✓ delegates to single-phase sync

TEST 113 (test_init_batch_combinator): init - orchestrates full initialization (Phase 4.4)
  Database: /tmp/vpn-switch-test.88851/test_113
✓ database init executed
✓ environment init executed
✓ phases copy executed

TEST 114 (test_init_combinator): init combinator - delegates to batch combinator (Phase 4.4)
  Database: /tmp/vpn-switch-test.88851/test_114
✓ database created
✓ profile installed

TEST 115 (test_setenv_basic): setenv - basic variable setting
  Database: /tmp/vpn-switch-test.88851/test_115
✓ .env/local directory created
✓ Variable file created
✓ Variable has correct value
✓ File has correct permissions (0600 or 0640 for cross-user support)
✓ Shows confirmation message

TEST 116 (test_setenv_invalid_name): setenv - invalid variable name
  Database: /tmp/vpn-switch-test.88851/test_116
✓ Rejects invalid variable name
✓ No file created for invalid name

TEST 117 (test_getenv_local_override): getenv - shows local override
  Database: /tmp/vpn-switch-test.88851/test_117
✓ Shows local override source
✓ Outputs correct value from local

TEST 118 (test_getenv_fallback_chain): getenv - fallback chain (local > default > template)
  Database: /tmp/vpn-switch-test.88851/test_118
✓ Shows error if variable not found
✓ Falls back to .env/default
✓ Falls back to template/environment

TEST 119 (test_unsetenv_existing): unsetenv - remove existing variable
  Database: /tmp/vpn-switch-test.88851/test_119
✓ Variable file was removed
✓ Shows confirmation message

TEST 120 (test_unsetenv_not_set): unsetenv - variable not set in local
  Database: /tmp/vpn-switch-test.88851/test_120
✓ Shows informative message when not set

TEST 121 (test_dumpenv_prologue): dumpenv prologue - outputs safe minimal set
  Database: /tmp/vpn-switch-test.88851/test_121
✓ Prologue includes VPN_SWITCH_TERMINAL_INTERPRETER
✓ Prologue includes VPN_SWITCH_DISPLAY_ANSI
✓ Prologue excludes VPN_SWITCH_INTERPRETER_wireguard_list (epilogue-only)
✓ Prologue excludes VPN_SWITCH_INTERPRETER_wireguard_import1 (epilogue-only)

TEST 122 (test_dumpenv_epilogue): dumpenv epilogue - outputs complete set
  Database: /tmp/vpn-switch-test.88851/test_122
✓ Epilogue includes VPN_SWITCH_TERMINAL_INTERPRETER
✓ Epilogue includes VPN_SWITCH_DISPLAY_ANSI
✓ Epilogue includes VPN_SWITCH_INTERPRETER_wireguard_list
✓ Epilogue includes VPN_SWITCH_INTERPRETER_wireguard_import1

TEST 123 (test_dumpenv_profile_filtering): dumpenv - profile filtering prevents restore breakage
  Database: /tmp/vpn-switch-test.88851/test_123
✓ Prologue correctly excludes function-specific interpreter
✓ Epilogue correctly includes function-specific interpreter

TEST 124 (test_environment_cache_on): environment cache on - creates cache file with correct permissions
  Database: /tmp/vpn-switch-test.88851/test_124
✓ Cache file created
✓ Cache file has correct permissions (0600)
✓ Shows cache enabled message
✓ Cache file has content

TEST 125 (test_environment_cache_off): environment cache off - removes cache file
  Database: /tmp/vpn-switch-test.88851/test_125
✓ Cache file removed
✓ Shows cache disabled message

TEST 126 (test_environment_cache_status): environment cache status - shows correct status
  Database: /tmp/vpn-switch-test.88851/test_126
✓ Shows DISABLED status when cache off
✓ Shows ENABLED status when cache on
✓ Shows cached variable count

TEST 127 (test_environment_cache_no_args): environment cache (no args) - defaults to status
  Database: /tmp/vpn-switch-test.88851/test_127
✓ Shows status with no arguments

TEST 128 (test_cache_invalidation_setenv): setenv - rebuilds cache automatically
  Database: /tmp/vpn-switch-test.88851/test_128
✓ Cache rebuilt automatically after setenv
✓ Rebuilt cache contains new variable TEST_VAR

TEST 129 (test_cache_invalidation_unsetenv): unsetenv - rebuilds cache automatically
  Database: /tmp/vpn-switch-test.88851/test_129
✓ Cache rebuilt automatically after unsetenv
✓ Rebuilt cache no longer contains TEST_VAR

TEST 130 (test_cache_invalidation_environment_init): environment init - invalidates cache automatically
  Database: /tmp/vpn-switch-test.88851/test_130
✓ Cache file removed after environment init
✓ Shows cache invalidation warning

TEST 131 (test_dumpenv_cache_preservation): dumpenv epilogue - includes cache if enabled
  Database: /tmp/vpn-switch-test.88851/test_131
✓ Epilogue includes cache content
✓ Epilogue includes cache restore comment

TEST 132 (test_dumpenv_cache_not_included_when_disabled): dumpenv epilogue - excludes cache when disabled
  Database: /tmp/vpn-switch-test.88851/test_132
✓ Epilogue correctly excludes cache when disabled

TEST 133 (test_cache_no_recursion): environment cache on - excludes cache file from scan
  Database: /tmp/vpn-switch-test.88851/test_133
✓ Cache correctly excludes itself

TEST 134 (test_interpreter_single_underscore): interpreter resolution - single underscore uses TERMINAL_INTERPRETER
  Database: /tmp/vpn-switch-test.88851/test_134
# Set VPN_SWITCH_TERMINAL_INTERPRETER (effective next command)
✓ Single underscore function used TERMINAL_INTERPRETER

TEST 135 (test_interpreter_double_underscore): interpreter resolution - double underscore uses COMBINATOR_INTERPRETER
  Database: /tmp/vpn-switch-test.88851/test_135
# Set VPN_SWITCH_COMBINATOR_INTERPRETER (effective next command)
✓ Double underscore function used COMBINATOR_INTERPRETER

TEST 136 (test_interpreter_triple_underscore): interpreter resolution - triple underscore uses BATCH_COMBINATOR_INTERPRETER
  Database: /tmp/vpn-switch-test.88851/test_136
# Set VPN_SWITCH_BATCH_COMBINATOR_INTERPRETER (effective next command)
✓ Triple underscore function used BATCH_COMBINATOR_INTERPRETER

TEST 137 (test_interpreter_resolution_priority): interpreter resolution - function-specific override beats intrinsic classification
  Database: /tmp/vpn-switch-test.88851/test_137
# Set VPN_SWITCH_TERMINAL_INTERPRETER (effective next command)
✓ Function-specific override takes priority over intrinsic classification
✓ Intrinsic classification was correctly bypassed

TEST 138 (test_inspect_batch_complete): inspect (batch) - includes all inspection sections
  Database: /tmp/vpn-switch-test.88851/test_138
✓ Batch inspect includes environment section
✓ Batch inspect includes system section
✓ Batch inspect includes WireGuard section
✓ Batch inspect includes OpenVPN section
✓ Batch inspect includes session section
✓ Batch inspect includes phases section

TEST 139 (test_environment_inspect): environment inspect - displays environment variables
  Database: /tmp/vpn-switch-test.88851/test_139
✓ Environment inspect shows header
✓ Environment inspect shows VPN_SWITCH_BASE
✓ Environment inspect shows database structure

TEST 140 (test_system_inspect): system inspect - displays system configuration
  Database: /tmp/vpn-switch-test.88851/test_140
✓ System inspect shows header
✓ System inspect shows system info section
✓ System inspect shows network interfaces section

TEST 141 (test_batch_syntax_wireguard_clean): wireguard clean - validates batch syntax
  Database: /tmp/vpn-switch-test.88851/test_141
✓ wireguard clean outputs valid batch syntax
✓ wireguard clean uses literal $VPN_SWITCH_CONTEXT_SCRIPT

TEST 142 (test_combinators_literal_variable): combinators - use literal $VPN_SWITCH_CONTEXT_SCRIPT
  Database: /tmp/vpn-switch-test.88851/test_142
✓ wireguard start uses literal variable
✓ wireguard start variable not expanded

TEST 143 (test_combinator_syntax_validation): combinators - validate single-command output syntax
  Database: /tmp/vpn-switch-test.88851/test_143
✓ wireguard start outputs exactly one command
✓ wireguard start uses literal variable
✓ wireguard start variable not expanded
✓ openvpn start outputs exactly one command
✓ start (protocol-agnostic) outputs exactly one command

TEST 144 (test_function_classification_correct): function classification - naming matches behavior
✓ wireguard add2 correctly classified as combinator (__)
✓ wireguard clean0 correctly classified as batch (___)
✓ openvpn clean0 correctly classified as batch (___)

TEST 145 (test_no_terminal_output_vpnswitch_commands): terminal functions - must not output vpn-switch commands
✓ No terminal functions output vpn-switch commands

TEST 146 (test_metadata_function_lists): metadata - function lists accurate after renames
✓ Metadata includes __wireguard_add2 in combinators
✓ Metadata includes ___wireguard_clean0 in batch combinators
✓ Metadata includes ___openvpn_clean0 in batch combinators

========================================
Test Summary
========================================
Test Functions:     146
Total Assertions:   371
Passed Assertions:  371
Failed Assertions:  0

ALL TESTS PASSED
========================================
vpn-switch Unit Test Suite (Formalized)
========================================


Running Tests
========================================
Filter active - running only:test_header test_summary test_setup test_printenv_command test_status_command test_wireguard_import_valid test_wireguard_add_category test_wireguard_link_create test_wireguard_list test_wireguard_validate test_wireguard_info test_wireguard_start_basic test_wireguard_connect_resume test_wireguard_stop_basic test_session_list test_session_show test_session_remove test_session_save_default test_session_save_named test_session_start_default test_session_start_named test_session_start_bypid test_session_stop_named test_session_stop_bypid test_session_stop_inactive test_wireguard_remove_config_in_use test_wireguard_remove_config_with_refs test_wireguard_remove_symlink test_wireguard_remove_category_link test_wireguard_clean_no_broken test_wireguard_clean_broken_protocol_link test_wireguard_clean_broken_category_link test_wireguard_clean_category_no_broken test_wireguard_clean_category_with_broken test_wireguard_validate_broken_symlink test_wireguard_validate_broken_category_symlink test_wireguard_validate_naming_conflict test_wireguard_validate_invalid_config test_stop_no_sessions test_stop_specific_interface test_wireguard_disconnect_interface test_stop_nonexistent_interface test_disconnect_without_session test_stop_twice_idempotent test_wireguard_import_nonexistent test_wireguard_import_duplicate test_wireguard_add_category_conflict test_wireguard_add_link_conflict test_wireguard_link_conflict test_error_invalid_category test_error_broken_symlink test_error_invalid_command test_edge_duplicate_instance_prevention test_edge_stale_session_cleanup test_wireguard_patch_valid test_wireguard_patch_nonexistent test_wireguard_patch_absolute test_wireguard_info_category test_session_save_default test_session_save_named test_session_start_default test_session_start_named test_session_start_by_pid test_protocol_agnostic_import_wireguard test_protocol_agnostic_list test_protocol_agnostic_link test_protocol_agnostic_remove test_protocol_agnostic_validate test_network_validate test_permissions_validate test_environment_validate test_batch_validate_includes_system test_interpreter_single_underscore test_interpreter_double_underscore test_interpreter_triple_underscore test_interpreter_resolution_priority test_start_wireguard_only test_start_openvpn_only test_start_not_found test_start_no_default test_start_with_default_wireguard test_start_with_default_openvpn test_start_default_invalid_target test_init_extension_links test_database_init test_environment_init test_phases_copy test_phases_lift test_phases_sync_single test_phases_sync_all test_init_batch_combinator test_init_combinator test_start_extension_link_fast_path test_start_multiple_matches test_openvpn_import_valid test_openvpn_list test_openvpn_add_group test_openvpn_link test_openvpn_remove test_openvpn_validate test_openvpn_info test_openvpn_dump test_openvpn_patch_valid test_openvpn_patch_nonexistent test_openvpn_patch_absolute test_openvpn_patch_credentials_bare test_openvpn_patch_credentials_existing test_openvpn_patch_credentials_missing test_openvpn_start_basic test_openvpn_stop_basic test_openvpn_disconnect_interface test_openvpn_clean test_setenv_basic test_setenv_invalid_name test_getenv_local_override test_getenv_fallback_chain test_unsetenv_existing test_unsetenv_not_set test_dumpenv_prologue test_dumpenv_epilogue test_dumpenv_profile_filtering test_environment_cache_on test_environment_cache_off test_environment_cache_status test_environment_cache_no_args test_cache_invalidation_setenv test_cache_invalidation_unsetenv test_cache_invalidation_environment_init test_dumpenv_cache_preservation test_dumpenv_cache_not_included_when_disabled test_cache_no_recursion test_inspect_batch_complete test_environment_inspect test_system_inspect test_batch_syntax_wireguard_clean test_combinators_literal_variable test_function_classification_correct test_no_terminal_output_vpnswitch_commands test_metadata_function_lists test_combinator_syntax_validation test_error_command_single_line test_error_command_two_lines test_error_command_three_lines test_error_command_ansi_colors test_batch_id_sequential test_store_batch_exits_basic test_store_batch_exits_references test_free_batch_id test_batch_infrastructure_lifecycle 


TEST 1 (test_batch_id_sequential): get_batch_id - sequential allocation
  Database: /tmp/vpn-switch-test.12000/test_1
✓ First batch ID is 0
✓ Second batch ID is 1
✓ Third batch ID is 2
✓ Counter file has correct value (3)

TEST 2 (test_store_batch_exits_basic): store_batch_exits - stores exit codes to file
  Database: /tmp/vpn-switch-test.12000/test_2
✓ Batch file created
✓ Batch file has correct content

TEST 3 (test_store_batch_exits_references): store_batch_exits - stores exit codes with batch references
  Database: /tmp/vpn-switch-test.12000/test_3
✓ Batch file stores references correctly

TEST 4 (test_free_batch_id): free_batch_id - deletes batch file
  Database: /tmp/vpn-switch-test.12000/test_4
✓ Batch file exists before cleanup
✓ Batch file deleted after cleanup

TEST 5 (test_batch_infrastructure_lifecycle): Batch infrastructure - full allocation/store/free lifecycle
  Database: /tmp/vpn-switch-test.12000/test_5
✓ Allocated batch ID: 0
✓ Batch results stored
✓ Batch results readable
✓ Batch cleaned up successfully

TEST 6 (test_printenv_command): printenv - basic environment display
  Database: /tmp/vpn-switch-test.12000/test_6
✓ Printenv command executed and shows header
✓ Printenv shows VPN_SWITCH_BASE variable

TEST 7 (test_status_command): status - VPN status display
  Database: /tmp/vpn-switch-test.12000/test_7
✓ Status command shows header
✓ Status shows disconnected state
✓ Status checks network interfaces

TEST 8 (test_error_command_single_line): error command - single line message
  Database: /tmp/vpn-switch-test.12000/test_8
✓ error command outputs printf with 'Error:' prefix
✓ error command outputs exit 1
✓ error command redirects to stderr

TEST 9 (test_error_command_two_lines): error command - two line message
  Database: /tmp/vpn-switch-test.12000/test_9
✓ error command first line has 'Error:' prefix
✓ error command second line is indented without 'Error:' prefix
✓ error command outputs exit 1

TEST 10 (test_error_command_three_lines): error command - three line message
  Database: /tmp/vpn-switch-test.12000/test_10
✓ error command first line has 'Error:' prefix
✓ error command has properly indented continuation lines
✓ error command includes all three message lines
✓ error command outputs exit 1

TEST 11 (test_error_command_ansi_colors): error command - ANSI color support
  Database: /tmp/vpn-switch-test.12000/test_11
✓ error command includes ANSI escape codes when enabled
✓ error command includes ANSI reset code

TEST 12 (test_wireguard_list): wireguard list - display configurations
  Database: /tmp/vpn-switch-test.12000/test_12
✓ Configuration section header displayed
✓ Config files section displayed
✓ Imported config file listed

TEST 13 (test_wireguard_validate): wireguard validate - validate clean configuration
  Database: /tmp/vpn-switch-test.12000/test_13
✓ Validation header displayed
✓ No issues found in clean configuration

TEST 14 (test_wireguard_info): wireguard info - display category information
  Database: /tmp/vpn-switch-test.12000/test_14
✓ Category header displayed
✓ Category path displayed
✓ Contents section displayed
✓ Category contents listed with symlink arrows

TEST 15 (test_wireguard_import_valid): wireguard import - import valid config
  Database: /tmp/vpn-switch-test.12000/test_15
✓ Config file imported to database
✓ Permissions set to 0400 (read-only)

TEST 16 (test_wireguard_add_category): wireguard add - create category with permissions
  Database: /tmp/vpn-switch-test.12000/test_16
✓ Category directory created
✓ Permissions set to 0755

TEST 17 (test_wireguard_link_create): wireguard link - create symlink in protocol directory
  Database: /tmp/vpn-switch-test.12000/test_17
✓ Symlink created
✓ Symlink points to correct relative path (./wg-TEST-RS-1.conf)

TEST 18 (test_wireguard_start_basic): wireguard start - create session and connect to VPN
  Database: /tmp/vpn-switch-test.12000/test_18
✓ Session creation logged
✓ wg-quick command in connect.sh
✓ Session directory created in .session/
✓ Session metadata files created
✓ connect.sh script generated
✓ connect.sh is executable
✓ connect.sh documents original config with relative path
✓ Patched config (wg_test13.conf) created
✓ Patched config correctly strips PostUp hook (phase-based DNS)
✓ Patched config correctly strips PostDown hook (phase-based DNS)

TEST 19 (test_wireguard_connect_resume): wireguard connect - resume existing session by ID
  Database: /tmp/vpn-switch-test.12000/test_19
✓ wireguard connect generated wg-quick command in connect.sh
✓ wireguard connect generated pfctl command in connect.sh
✓ wireguard connect used session configuration
✓ connect.sh preserved after connect

TEST 20 (test_wireguard_stop_basic): stop - disconnect active VPN session
  Database: /tmp/vpn-switch-test.12000/test_20
✓ Session exists before stop
✓ disconnect.sh contains wg-quick down command
✓ Stop command executed
✓ Session preserved after stop (has 'latest' link)

TEST 21 (test_session_list): session list - display active and stale sessions
  Database: /tmp/vpn-switch-test.12000/test_21
✓ Session list header displayed
✓ Active session (PID 91555) listed
✓ Stale session (PID 99997) listed
✓ Stale session (dead process) marked as stopped

TEST 22 (test_session_show): session show - display connect script
  Database: /tmp/vpn-switch-test.12000/test_22
✓ Extracted session ID (78522) from start command output
✓ Session ID displayed in header
✓ Session protocol displayed
✓ Connect script contents displayed

TEST 23 (test_session_remove): session remove - remove stale, refuse active
  Database: /tmp/vpn-switch-test.12000/test_23
✓ Stale session created for removal test
✓ Removal operation logged for stale session
✓ Active session (PID 12000) created for refusal test
✓ Refuses to remove active session (PID 12000)

TEST 24 (test_session_save_default): session save - save current session as default
  Database: /tmp/vpn-switch-test.12000/test_24
✓ Default session symlink created
✓ Default symlink points to correct session

TEST 25 (test_session_save_named): session save work - save with custom name
  Database: /tmp/vpn-switch-test.12000/test_25
✓ Named session symlink created
✓ Named symlink points to correct session

TEST 26 (test_session_start_default): session start - resume default session
  Database: /tmp/vpn-switch-test.12000/test_26
✓ Connect script created before stopping
✓ Session directory kept for resumption (referenced)
✓ Default symlink persists after stop
✓ Session start executed successfully

TEST 27 (test_session_start_named): session start work - resume named session
  Database: /tmp/vpn-switch-test.12000/test_27
✓ Named symlink persists after stop
✓ Named session start executed successfully

TEST 28 (test_session_start_bypid): session start <PID> - resume session by PID
  Database: /tmp/vpn-switch-test.12000/test_28
✓ Mock session (PID 11111) created for PID resume test
✓ Session start resumes by explicit PID (11111)

TEST 29 (test_session_stop_named): session stop work - stop active named session
  Database: /tmp/vpn-switch-test.12000/test_29
✓ Session stop resolves named session 'work'

TEST 30 (test_session_stop_bypid): session stop <PID> - stop active session by PID
  Database: /tmp/vpn-switch-test.12000/test_30
✓ Session stop handles PID (88888)

TEST 31 (test_session_stop_inactive): session stop <PID> - inactive session should log (not error)
  Database: /tmp/vpn-switch-test.12000/test_31
✓ Session stop handles inactive session gracefully

TEST 32 (test_wireguard_remove_config_in_use): wireguard remove - refuse removal when config in use
  Database: /tmp/vpn-switch-test.12000/test_32
✓ Active session (PID 12000) created using config
✓ Error message when config in use by session
✓ Error suggests removing session first

TEST 33 (test_wireguard_remove_config_with_refs): wireguard remove - refuse removal when config has symlink refs
  Database: /tmp/vpn-switch-test.12000/test_33
✓ Category symlink created (privacy/rm2)
✓ Error message when config has symlink references
✓ Error lists symlink references

TEST 34 (test_wireguard_remove_symlink): wireguard remove - remove symlink (no safety checks)
  Database: /tmp/vpn-switch-test.12000/test_34
✓ Test symlink created
✓ Symlink removal operation logged
✓ Symlink was removed

TEST 35 (test_wireguard_remove_category_link): wireguard remove - remove link from category
  Database: /tmp/vpn-switch-test.12000/test_35
✓ Category link (privacy/rm4) created
✓ Category link removal operation logged
✓ Category link was removed

TEST 36 (test_wireguard_clean_no_broken): wireguard clean - no broken links found
  Database: /tmp/vpn-switch-test.12000/test_36
✓ Clean header displayed
✓ No broken symlinks message displayed
✓ Usage hint displayed

TEST 37 (test_wireguard_clean_broken_protocol_link): wireguard clean - detect and generate remove for broken protocol link
  Database: /tmp/vpn-switch-test.12000/test_37
✓ Broken protocol symlink created for testing
✓ Remove command generated for broken protocol link
✓ Command includes link name

TEST 38 (test_wireguard_clean_broken_category_link): wireguard clean - detect and generate remove for broken category link
  Database: /tmp/vpn-switch-test.12000/test_38
✓ Broken category symlink created for testing
✓ Remove command generated for broken category link
✓ Command includes category name

TEST 39 (test_wireguard_clean_category_no_broken): wireguard clean privacy - category with no broken links
  Database: /tmp/vpn-switch-test.12000/test_39
✓ Category-specific header displayed
✓ No broken symlinks message for category

TEST 40 (test_wireguard_clean_category_with_broken): wireguard clean privacy - category with broken links
  Database: /tmp/vpn-switch-test.12000/test_40
✓ Broken symlink created in privacy category
✓ Remove command generated for category link
✓ Category-specific clean (not global)

TEST 41 (test_wireguard_validate_broken_symlink): wireguard validate - detect broken symlinks
  Database: /tmp/vpn-switch-test.12000/test_41
✓ Broken symlink created for validation test
✓ Broken symlink detected in protocol directory
✓ Error status reported

TEST 42 (test_wireguard_validate_broken_category_symlink): wireguard validate - detect broken symlinks in categories
  Database: /tmp/vpn-switch-test.12000/test_42
✓ Broken category symlink created for validation test
✓ Broken symlink detected in category

TEST 43 (test_wireguard_validate_naming_conflict): wireguard validate - detect naming conflicts
  Database: /tmp/vpn-switch-test.12000/test_43
✓ Naming conflict created (file + directory)
✓ Naming conflict detected

TEST 44 (test_wireguard_validate_invalid_config): wireguard validate - detect invalid config files
  Database: /tmp/vpn-switch-test.12000/test_44
✓ Empty config file created for validation test
✓ Empty config file detected
✓ Missing [Interface] section detected

TEST 45 (test_stop_no_sessions): stop - no sessions exist (empty output)
  Database: /tmp/vpn-switch-test.12000/test_45
✓ No output or log message when no sessions exist

TEST 46 (test_stop_specific_interface): stop wg_test_safe - stop specific interface by name
  Database: /tmp/vpn-switch-test.12000/test_46
✓ Active session (PID 12000, interface wg_test_safe) created
✓ Stopped specific interface wg_test_safe
✓ Interface wg_test_safe disconnect command generated

TEST 47 (test_wireguard_disconnect_interface): wireguard disconnect wg_test_safe - direct disconnect command
  Database: /tmp/vpn-switch-test.12000/test_47
✓ Active session (PID 12000) created for disconnect test
✓ Disconnect command executed for wg_test_safe
✓ Session PID displayed correctly

TEST 48 (test_stop_nonexistent_interface): stop wg_test_other - error when interface not found
  Database: /tmp/vpn-switch-test.12000/test_48
✓ Active session with wg_test_safe interface created
✓ Error message for nonexistent interface

TEST 49 (test_disconnect_without_session): disconnect without session - error handling
  Database: /tmp/vpn-switch-test.12000/test_49
✓ Error message when no session exists

TEST 50 (test_stop_twice_idempotent): stop twice - idempotent (safe to call multiple times)
  Database: /tmp/vpn-switch-test.12000/test_50
✓ First stop: handles no sessions gracefully
✓ Second stop: still handles no sessions (idempotent)

TEST 51 (test_wireguard_import_nonexistent): wireguard import - error when file doesn't exist
  Database: /tmp/vpn-switch-test.12000/test_51
✓ Error message for non-existent file

TEST 52 (test_wireguard_import_duplicate): wireguard import - error when config already exists
  Database: /tmp/vpn-switch-test.12000/test_52
✓ First import succeeded
✓ Error message when config already exists

TEST 53 (test_wireguard_add_category_conflict): wireguard add - error when category already exists
  Database: /tmp/vpn-switch-test.12000/test_53
✓ First add succeeded (privacy category created)
✓ Error message when category already exists

TEST 54 (test_wireguard_add_link_conflict): wireguard add - error when link already exists
  Database: /tmp/vpn-switch-test.12000/test_54
✓ First link created successfully
✓ Error message when link already exists

TEST 55 (test_wireguard_link_conflict): wireguard link - error when alias already exists
  Database: /tmp/vpn-switch-test.12000/test_55
✓ Config imported successfully
✓ Error message when alias already exists

TEST 56 (test_error_invalid_category): error handling - invalid category shows error
  Database: /tmp/vpn-switch-test.12000/test_56
✓ Error message for invalid category

TEST 57 (test_error_broken_symlink): error handling - broken symlink handled gracefully
  Database: /tmp/vpn-switch-test.12000/test_57
✓ Broken symlink created for testing
✓ Handled broken symlink (error or skipped)

TEST 58 (test_error_invalid_command): error handling - invalid command shows usage
  Database: /tmp/vpn-switch-test.12000/test_58
✓ Usage/help shown for invalid command

TEST 59 (test_edge_duplicate_instance_prevention): edge case - prevent duplicate VPN instances
  Database: /tmp/vpn-switch-test.12000/test_59
✓ First VPN session created (PID 12000)
✓ Detected existing VPN instance
✓ No duplicate session created

TEST 60 (test_edge_stale_session_cleanup): edge case - stale sessions don't block new sessions
  Database: /tmp/vpn-switch-test.12000/test_60
✓ Stale session created for testing
✓ Proceeded with new session (stale session didn't block)
✓ Stale session preserved (manual cleanup via 'session clean' required)

TEST 61 (test_wireguard_patch_valid): wireguard patch - displays patched configuration
  Database: /tmp/vpn-switch-test.12000/test_61
✓ Patch output correctly strips PostUp hook (phase-based DNS)
✓ Patch output correctly strips PostDown hook (phase-based DNS)
✓ Patch output preserves [Interface] section
✓ Patch output preserves [Peer] section

TEST 62 (test_wireguard_patch_nonexistent): wireguard patch - handles nonexistent config
  Database: /tmp/vpn-switch-test.12000/test_62
✓ Patch rejects nonexistent config with error

TEST 63 (test_wireguard_patch_absolute): wireguard patch - handles absolute path
  Database: /tmp/vpn-switch-test.12000/test_63
✓ Patch works with absolute path (strips DNS hooks)

TEST 64 (test_wireguard_info_category): wireguard info - displays category information
  Database: /tmp/vpn-switch-test.12000/test_64
✓ Category header displayed
✓ Config count displayed
✓ Link count displayed
✓ Category path displayed
✓ Contents section header displayed
✓ Category contents listed with symlink arrows

TEST 65 (test_session_save_default): session save - save current session as default
  Database: /tmp/vpn-switch-test.12000/test_65
✓ Default session symlink created
✓ Default symlink points to correct session

TEST 66 (test_session_save_named): session save work - save with custom name
  Database: /tmp/vpn-switch-test.12000/test_66
✓ Named session symlink created
✓ Named symlink points to correct session

TEST 67 (test_session_start_default): session start - resume default session
  Database: /tmp/vpn-switch-test.12000/test_67
✓ Connect script created before stopping
✓ Session directory kept for resumption (referenced)
✓ Default symlink persists after stop
✓ Session start executed successfully

TEST 68 (test_session_start_named): session start work - resume named session
  Database: /tmp/vpn-switch-test.12000/test_68
✓ Named symlink persists after stop
✓ Named session start executed successfully

TEST 69 (test_session_start_by_pid): session start <PID> - resume by PID
  Database: /tmp/vpn-switch-test.12000/test_69
✓ Session start by PID executed successfully

TEST 70 (test_openvpn_import_valid): openvpn import - import valid .ovpn config
  Database: /tmp/vpn-switch-test.12000/test_70
✓ Config imported to openvpn/
✓ Permissions set to 0400

TEST 71 (test_openvpn_list): openvpn list - list configs and groups
  Database: /tmp/vpn-switch-test.12000/test_71
✓ Lists config: us-server.ovpn
✓ Lists group: work/
✓ Lists group link with arity-1: work/office

TEST 72 (test_openvpn_add_group): openvpn add - create group
  Database: /tmp/vpn-switch-test.12000/test_72
✓ Group directory created
✓ Group permissions correct (0700)

TEST 73 (test_openvpn_link): openvpn link - create protocol-level link
  Database: /tmp/vpn-switch-test.12000/test_73
✓ Protocol-level link created
✓ Link target correct

TEST 74 (test_openvpn_remove): openvpn remove - remove config safely
  Database: /tmp/vpn-switch-test.12000/test_74
✓ Config removed
✓ Other config preserved

TEST 75 (test_openvpn_validate): openvpn validate - detect broken links
  Database: /tmp/vpn-switch-test.12000/test_75
✓ Broken symlink detected
✓ Valid database passes validation

TEST 76 (test_openvpn_info): openvpn info - show group information
  Database: /tmp/vpn-switch-test.12000/test_76
✓ Shows group name
✓ Shows correct link count
✓ Shows link: office

TEST 77 (test_openvpn_dump): openvpn dump - export database
  Database: /tmp/vpn-switch-test.12000/test_77
✓ Dump includes import command
✓ Dump includes group creation
✓ Dump includes protocol link
✓ Dump includes group link

TEST 78 (test_openvpn_patch_valid): openvpn patch - displays patched configuration
  Database: /tmp/vpn-switch-test.12000/test_78
✓ Patch output correctly strips up script (phase-based DNS)
✓ Patch output correctly strips down script (phase-based DNS)
✓ Patch output contains daemon mode
✓ Patch output contains device interface
✓ Patch output contains writepid directive
✓ Patch output preserves client directive
✓ Patch output preserves remote server

TEST 79 (test_openvpn_patch_nonexistent): openvpn patch - handles nonexistent config
  Database: /tmp/vpn-switch-test.12000/test_79
✓ Error message for nonexistent config

TEST 80 (test_openvpn_patch_absolute): openvpn patch - handles absolute path
  Database: /tmp/vpn-switch-test.12000/test_80
✓ Absolute path patch works

TEST 81 (test_openvpn_patch_credentials_bare): openvpn patch - patches bare auth-user-pass with credentials
  Database: /tmp/vpn-switch-test.12000/test_81
✓ Bare auth-user-pass patched with credentials path
✓ Bare auth-user-pass preserved when no credentials set

TEST 82 (test_openvpn_patch_credentials_existing): openvpn patch - preserves existing auth-user-pass path
  Database: /tmp/vpn-switch-test.12000/test_82
✓ Existing auth-user-pass path preserved (not overridden)

TEST 83 (test_openvpn_patch_credentials_missing): openvpn patch - handles config without auth-user-pass
  Database: /tmp/vpn-switch-test.12000/test_83
✓ Config without auth-user-pass remains unchanged

TEST 84 (test_openvpn_start_basic): openvpn start - create session and connect to VPN
  Database: /tmp/vpn-switch-test.12000/test_84
✓ Session creation logged
✓ openvpn command in connect.sh
✓ Session directory created in .session/
✓ Session metadata files created
✓ connect.sh script generated
✓ connect.sh is executable
✓ Patched config (tun_test80.ovpn) created
✓ Patched config contains daemon mode
✓ Patched config correctly strips up script (phase-based DNS)
✓ Patched config correctly strips down script (phase-based DNS)

TEST 85 (test_openvpn_stop_basic): openvpn stop - cleanup commands for session
  Database: /tmp/vpn-switch-test.12000/test_85
✓ Session created via user interface
✓ Disconnect commands reference correct interface (tun_test85)
✓ Disconnect generates process kill commands

TEST 86 (test_openvpn_disconnect_interface): openvpn disconnect - tear down OpenVPN interface
  Database: /tmp/vpn-switch-test.12000/test_86
✓ Disconnect generates process termination commands

TEST 87 (test_openvpn_clean): openvpn clean - generate cleanup commands for broken links
  Database: /tmp/vpn-switch-test.12000/test_87
✓ Clean generates remove commands
✓ Clean detected broken symlink

TEST 88 (test_protocol_agnostic_import_wireguard): import (protocol-agnostic) - detects WireGuard .conf file
  Database: /tmp/vpn-switch-test.12000/test_88
✓ Protocol-agnostic import detected .conf and delegated to wireguard import
✓ Protocol-agnostic import generates correct cp command

TEST 89 (test_protocol_agnostic_list): list (protocol-agnostic) - delegates to all protocols
  Database: /tmp/vpn-switch-test.12000/test_89
✓ Protocol-agnostic list delegated to wireguard list
✓ Protocol-agnostic list shows wireguard config sections
✓ Protocol-agnostic list has no duplicate lines (3 unique)

TEST 90 (test_protocol_agnostic_link): link (protocol-agnostic) - creates protocol-level alias
  Database: /tmp/vpn-switch-test.12000/test_90
✓ Protocol-agnostic link generates ln command
✓ Protocol-agnostic link uses correct relative path (./wireguard)
✓ Protocol-agnostic link includes correct alias name

TEST 91 (test_protocol_agnostic_remove): remove (protocol-agnostic) - removes protocol-level link
  Database: /tmp/vpn-switch-test.12000/test_91
✓ Protocol-agnostic remove generates rm command
✓ Protocol-agnostic remove includes descriptive comment
✓ Protocol-agnostic remove errors on non-existent link

TEST 92 (test_protocol_agnostic_validate): validate (protocol-agnostic) - delegates to all protocols
  Database: /tmp/vpn-switch-test.12000/test_92
✓ Protocol-agnostic validate delegated to wireguard validate
✓ Protocol-agnostic validate shows validation output

TEST 93 (test_network_validate): network validate - check network prerequisites
  Database: /tmp/vpn-switch-test.12000/test_93
✓ Network validation header displayed
✓ Network validate passed on clean configuration

TEST 94 (test_permissions_validate): permissions validate - check filesystem permissions
  Database: /tmp/vpn-switch-test.12000/test_94
✓ Permissions validation header displayed
✓ Permissions validate passed on clean configuration

TEST 95 (test_environment_validate): environment validate - check environment variables
  Database: /tmp/vpn-switch-test.12000/test_95
✓ Environment validation header displayed
✓ Environment validate passed on clean configuration

TEST 96 (test_batch_validate_includes_system): validate (batch) - includes system validators
  Database: /tmp/vpn-switch-test.12000/test_96
✓ Batch validate includes database validator
✓ Batch validate includes binaries validator
✓ Batch validate includes phases validator
✓ Batch validate includes network validator
✓ Batch validate includes permissions validator
✓ Batch validate includes environment validator

TEST 97 (test_start_wireguard_only): start - auto-detect WireGuard config
  Database: /tmp/vpn-switch-test.12000/test_97
✓ Delegates to wireguard commands for WireGuard-only config

TEST 98 (test_start_openvpn_only): start - auto-detect OpenVPN config
  Database: /tmp/vpn-switch-test.12000/test_98
✓ Delegates to openvpn commands for OpenVPN-only config

TEST 99 (test_start_not_found): start - error on nonexistent config
  Database: /tmp/vpn-switch-test.12000/test_99
✓ Error message for nonexistent config
✓ Error shows both search locations

TEST 100 (test_start_no_default): start - error when no configs exist (Phase 3.4.1)
  Database: /tmp/vpn-switch-test.12000/test_100
✓ Error message when no configs available
✓ Error provides hint to import configs

TEST 101 (test_start_with_default_wireguard): start - use default link (WireGuard) via API
  Database: /tmp/vpn-switch-test.12000/test_101
✓ Default session link created via API
✓ Start with no args resolves to default session

TEST 102 (test_start_with_default_openvpn): start - use default link (OpenVPN) via API
  Database: /tmp/vpn-switch-test.12000/test_102
✓ Default session link created via API
✓ Start with no args resolves to default session

TEST 103 (test_start_default_invalid_target): start - error on invalid default link target
  Database: /tmp/vpn-switch-test.12000/test_103
✓ Error detected for invalid default session target

TEST 104 (test_init_extension_links): init - creates protocol extension links (Phase 3.4.1)
  Database: /tmp/vpn-switch-test.12000/test_104
✓ conf link created
✓ ovpn link created
✓ conf → wireguard
✓ ovpn → openvpn

TEST 105 (test_start_extension_link_fast_path): start - uses extension link for protocol resolution (Phase 3.4.1)
  Database: /tmp/vpn-switch-test.12000/test_105
✓ Extension link used for fast protocol resolution (wireguard commands found)

TEST 106 (test_start_multiple_matches): start - error on multiple protocol matches (Phase 3.4.1)
  Database: /tmp/vpn-switch-test.12000/test_106
✓ Multiple matches error shown
✓ Both matches listed

TEST 107 (test_database_init): database init - creates directory structure (Phase 4.4)
  Database: /tmp/vpn-switch-test.12000/test_107
✓ wireguard/ created
✓ openvpn/ created
✓ .session/ created
✓ session/ created
✓ .env/default/ created
✓ .env/local/ created
✓ .include/phase/ created

TEST 108 (test_environment_init): environment init - copies profile templates (Phase 4.4)
  Database: /tmp/vpn-switch-test.12000/test_108
✓ minimal profile copied
✓ profile has correct permissions (0600)

TEST 109 (test_phases_copy): phases copy - copies phase templates (Phase 4.4)
  Database: /tmp/vpn-switch-test.12000/test_109
✓ wireguard phases copied
✓ openvpn phases copied
✓ wireguard phase subdirs exist

TEST 110 (test_phases_lift): phases lift - lifts phase:backend templates (Phase 4.4)
  Database: /tmp/vpn-switch-test.12000/test_110
✓ generates lift command
✓ output file is executable

TEST 111 (test_phases_sync_single): phases sync <phase> - discovers and lifts backends (Phase 4.4)
  Database: /tmp/vpn-switch-test.12000/test_111
✓ delegates to phases lift

TEST 112 (test_phases_sync_all): phases sync - syncs all phases (Phase 4.4)
  Database: /tmp/vpn-switch-test.12000/test_112
✓ delegates to single-phase sync

TEST 113 (test_init_batch_combinator): init - orchestrates full initialization (Phase 4.4)
  Database: /tmp/vpn-switch-test.12000/test_113
✓ database init executed
✓ environment init executed
✓ phases copy executed

TEST 114 (test_init_combinator): init combinator - delegates to batch combinator (Phase 4.4)
  Database: /tmp/vpn-switch-test.12000/test_114
✓ database created
✓ profile installed

TEST 115 (test_setenv_basic): setenv - basic variable setting
  Database: /tmp/vpn-switch-test.12000/test_115
✓ .env/local directory created
✓ Variable file created
✓ Variable has correct value
✓ File has correct permissions (0600 or 0640 for cross-user support)
✓ Shows confirmation message

TEST 116 (test_setenv_invalid_name): setenv - invalid variable name
  Database: /tmp/vpn-switch-test.12000/test_116
✓ Rejects invalid variable name
✓ No file created for invalid name

TEST 117 (test_getenv_local_override): getenv - shows local override
  Database: /tmp/vpn-switch-test.12000/test_117
✓ Shows local override source
✓ Outputs correct value from local

TEST 118 (test_getenv_fallback_chain): getenv - fallback chain (local > default > template)
  Database: /tmp/vpn-switch-test.12000/test_118
✓ Shows error if variable not found
✓ Falls back to .env/default
✓ Falls back to template/environment

TEST 119 (test_unsetenv_existing): unsetenv - remove existing variable
  Database: /tmp/vpn-switch-test.12000/test_119
✓ Variable file was removed
✓ Shows confirmation message

TEST 120 (test_unsetenv_not_set): unsetenv - variable not set in local
  Database: /tmp/vpn-switch-test.12000/test_120
✓ Shows informative message when not set

TEST 121 (test_dumpenv_prologue): dumpenv prologue - outputs safe minimal set
  Database: /tmp/vpn-switch-test.12000/test_121
✓ Prologue includes VPN_SWITCH_TERMINAL_INTERPRETER
✓ Prologue includes VPN_SWITCH_DISPLAY_ANSI
✓ Prologue excludes VPN_SWITCH_INTERPRETER_wireguard_list (epilogue-only)
✓ Prologue excludes VPN_SWITCH_INTERPRETER_wireguard_import1 (epilogue-only)

TEST 122 (test_dumpenv_epilogue): dumpenv epilogue - outputs complete set
  Database: /tmp/vpn-switch-test.12000/test_122
✓ Epilogue includes VPN_SWITCH_TERMINAL_INTERPRETER
✓ Epilogue includes VPN_SWITCH_DISPLAY_ANSI
✓ Epilogue includes VPN_SWITCH_INTERPRETER_wireguard_list
✓ Epilogue includes VPN_SWITCH_INTERPRETER_wireguard_import1

TEST 123 (test_dumpenv_profile_filtering): dumpenv - profile filtering prevents restore breakage
  Database: /tmp/vpn-switch-test.12000/test_123
✓ Prologue correctly excludes function-specific interpreter
✓ Epilogue correctly includes function-specific interpreter

TEST 124 (test_environment_cache_on): environment cache on - creates cache file with correct permissions
  Database: /tmp/vpn-switch-test.12000/test_124
✓ Cache file created
✓ Cache file has correct permissions (0600)
✓ Shows cache enabled message
✓ Cache file has content

TEST 125 (test_environment_cache_off): environment cache off - removes cache file
  Database: /tmp/vpn-switch-test.12000/test_125
✓ Cache file removed
✓ Shows cache disabled message

TEST 126 (test_environment_cache_status): environment cache status - shows correct status
  Database: /tmp/vpn-switch-test.12000/test_126
✓ Shows DISABLED status when cache off
✓ Shows ENABLED status when cache on
✓ Shows cached variable count

TEST 127 (test_environment_cache_no_args): environment cache (no args) - defaults to status
  Database: /tmp/vpn-switch-test.12000/test_127
✓ Shows status with no arguments

TEST 128 (test_cache_invalidation_setenv): setenv - rebuilds cache automatically
  Database: /tmp/vpn-switch-test.12000/test_128
✓ Cache rebuilt automatically after setenv
✓ Rebuilt cache contains new variable TEST_VAR

TEST 129 (test_cache_invalidation_unsetenv): unsetenv - rebuilds cache automatically
  Database: /tmp/vpn-switch-test.12000/test_129
✓ Cache rebuilt automatically after unsetenv
✓ Rebuilt cache no longer contains TEST_VAR

TEST 130 (test_cache_invalidation_environment_init): environment init - invalidates cache automatically
  Database: /tmp/vpn-switch-test.12000/test_130
✓ Cache file removed after environment init
✓ Shows cache invalidation warning

TEST 131 (test_dumpenv_cache_preservation): dumpenv epilogue - includes cache if enabled
  Database: /tmp/vpn-switch-test.12000/test_131
✓ Epilogue includes cache content
✓ Epilogue includes cache restore comment

TEST 132 (test_dumpenv_cache_not_included_when_disabled): dumpenv epilogue - excludes cache when disabled
  Database: /tmp/vpn-switch-test.12000/test_132
✓ Epilogue correctly excludes cache when disabled

TEST 133 (test_cache_no_recursion): environment cache on - excludes cache file from scan
  Database: /tmp/vpn-switch-test.12000/test_133
✓ Cache correctly excludes itself

TEST 134 (test_interpreter_single_underscore): interpreter resolution - single underscore uses TERMINAL_INTERPRETER
  Database: /tmp/vpn-switch-test.12000/test_134
# Set VPN_SWITCH_TERMINAL_INTERPRETER (effective next command)
✓ Single underscore function used TERMINAL_INTERPRETER

TEST 135 (test_interpreter_double_underscore): interpreter resolution - double underscore uses COMBINATOR_INTERPRETER
  Database: /tmp/vpn-switch-test.12000/test_135
# Set VPN_SWITCH_COMBINATOR_INTERPRETER (effective next command)
✓ Double underscore function used COMBINATOR_INTERPRETER

TEST 136 (test_interpreter_triple_underscore): interpreter resolution - triple underscore uses BATCH_COMBINATOR_INTERPRETER
  Database: /tmp/vpn-switch-test.12000/test_136
# Set VPN_SWITCH_BATCH_COMBINATOR_INTERPRETER (effective next command)
✓ Triple underscore function used BATCH_COMBINATOR_INTERPRETER

TEST 137 (test_interpreter_resolution_priority): interpreter resolution - function-specific override beats intrinsic classification
  Database: /tmp/vpn-switch-test.12000/test_137
# Set VPN_SWITCH_TERMINAL_INTERPRETER (effective next command)
✓ Function-specific override takes priority over intrinsic classification
✓ Intrinsic classification was correctly bypassed

TEST 138 (test_inspect_batch_complete): inspect (batch) - includes all inspection sections
  Database: /tmp/vpn-switch-test.12000/test_138
✓ Batch inspect includes environment section
✓ Batch inspect includes system section
✓ Batch inspect includes WireGuard section
✓ Batch inspect includes OpenVPN section
✓ Batch inspect includes session section
✓ Batch inspect includes phases section

TEST 139 (test_environment_inspect): environment inspect - displays environment variables
  Database: /tmp/vpn-switch-test.12000/test_139
✓ Environment inspect shows header
✓ Environment inspect shows VPN_SWITCH_BASE
✓ Environment inspect shows database structure

TEST 140 (test_system_inspect): system inspect - displays system configuration
  Database: /tmp/vpn-switch-test.12000/test_140
✓ System inspect shows header
✓ System inspect shows system info section
✓ System inspect shows network interfaces section

TEST 141 (test_batch_syntax_wireguard_clean): wireguard clean - validates batch syntax
  Database: /tmp/vpn-switch-test.12000/test_141
✓ wireguard clean outputs valid batch syntax
✓ wireguard clean uses literal $VPN_SWITCH_CONTEXT_SCRIPT

TEST 142 (test_combinators_literal_variable): combinators - use literal $VPN_SWITCH_CONTEXT_SCRIPT
  Database: /tmp/vpn-switch-test.12000/test_142
✓ wireguard start uses literal variable
✓ wireguard start variable not expanded

TEST 143 (test_combinator_syntax_validation): combinators - validate single-command output syntax
  Database: /tmp/vpn-switch-test.12000/test_143
✓ wireguard start outputs exactly one command
✓ wireguard start uses literal variable
✓ wireguard start variable not expanded
✓ openvpn start outputs exactly one command
✓ start (protocol-agnostic) outputs exactly one command

TEST 144 (test_function_classification_correct): function classification - naming matches behavior
✓ wireguard add2 correctly classified as combinator (__)
✓ wireguard clean0 correctly classified as batch (___)
✓ openvpn clean0 correctly classified as batch (___)

TEST 145 (test_no_terminal_output_vpnswitch_commands): terminal functions - must not output vpn-switch commands
✓ No terminal functions output vpn-switch commands

TEST 146 (test_metadata_function_lists): metadata - function lists accurate after renames
✓ Metadata includes __wireguard_add2 in combinators
✓ Metadata includes ___wireguard_clean0 in batch combinators
✓ Metadata includes ___openvpn_clean0 in batch combinators

========================================
Test Summary
========================================
Test Functions:     146
Total Assertions:   371
Passed Assertions:  371
Failed Assertions:  0

ALL TESTS PASSED
========================================
vpn-switch Architecture Test Suite
========================================

Testing architectural rules for combinator functions
Profile: all

Running Combinator Tests
========================================

Found 28 combinator functions


TEST 1: Combinator: __session_exists1 - validate syntax with variations
✓ __session_exists1: Valid combinator syntax (all variations)

TEST 2: Combinator: __session_conflicts2 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-1]
✓ __session_conflicts2: Valid combinator syntax (all variations)

TEST 3: Combinator: __interface_check1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-2]
✓ __interface_check1: Valid combinator syntax (all variations)

TEST 4: Combinator: __stop1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-3]
✓ __stop1: Valid combinator syntax (all variations)

TEST 5: Combinator: __import1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-4]
✓ __import1: Valid combinator syntax (all variations)

TEST 6: Combinator: __start1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-5]
✓ __start1: Valid combinator syntax (all variations)

TEST 7: Combinator: __start0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-6]
✓ __start0: Valid combinator syntax (all variations)

TEST 8: Combinator: __bootstrap1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-7]
✓ __bootstrap1: Valid combinator syntax (all variations)

TEST 9: Combinator: __environment_cache0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-8]
✓ __environment_cache0: Valid combinator syntax (all variations)

TEST 10: Combinator: __phases_lift1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-9]
✓ __phases_lift1: Valid combinator syntax (all variations)

TEST 11: Combinator: __init0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-10]
✓ __init0: Valid combinator syntax (all variations)

TEST 12: Combinator: __batch1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-11]
✓ __batch1: Valid combinator syntax (all variations)

TEST 13: Combinator: __restore1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-12]
✓ __restore1: Valid combinator syntax (all variations)

TEST 14: Combinator: __openvpn_start0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-13]
✓ __openvpn_start0: Valid combinator syntax (all variations)

TEST 15: Combinator: __openvpn_start1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-14]
✓ __openvpn_start1: Valid combinator syntax (all variations)

TEST 16: Combinator: __openvpn_stop1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-15]
✓ __openvpn_stop1: Valid combinator syntax (all variations)

TEST 17: Combinator: __openvpn_add2 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-16]
✓ __openvpn_add2: Valid combinator syntax (all variations)

TEST 18: Combinator: __openvpn_help0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-17]
✓ __openvpn_help0: Valid combinator syntax (all variations)

TEST 19: Combinator: __session_disconnect1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-18]
✓ __session_disconnect1: Valid combinator syntax (all variations)

TEST 20: Combinator: __session_show0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-19]
✓ __session_show0: Valid combinator syntax (all variations)

TEST 21: Combinator: __session_start0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-20]
✓ __session_start0: Valid combinator syntax (all variations)

TEST 22: Combinator: __session_start1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-21]
✓ __session_start1: Valid combinator syntax (all variations)

TEST 23: Combinator: __session_help0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-22]
✓ __session_help0: Valid combinator syntax (all variations)

TEST 24: Combinator: __wireguard_start0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-23]
✓ __wireguard_start0: Valid combinator syntax (all variations)

TEST 25: Combinator: __wireguard_start1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-24]
✓ __wireguard_start1: Valid combinator syntax (all variations)

TEST 26: Combinator: __wireguard_stop1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-25]
✓ __wireguard_stop1: Valid combinator syntax (all variations)

TEST 27: Combinator: __wireguard_add2 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-26]
✓ __wireguard_add2: Valid combinator syntax (all variations)

TEST 28: Combinator: __wireguard_help0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-27]
✓ __wireguard_help0: Valid combinator syntax (all variations)

Running Batch Combinator Tests
========================================

Found 26 batch combinator functions


TEST 29: Batch Combinator: ___session_prepare3 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-28]
✓ ___session_prepare3: Valid batch combinator syntax (all variations)

TEST 30: Batch Combinator: ___stop0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-29]
✓ ___stop0: Valid batch combinator syntax (all variations)

TEST 31: Batch Combinator: ___phases_sync1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-30]
✓ ___phases_sync1: Valid batch combinator syntax (all variations)

TEST 32: Batch Combinator: ___phases_sync0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-31]
✓ ___phases_sync0: Valid batch combinator syntax (all variations)

TEST 33: Batch Combinator: ___list0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-32]
✓ ___list0: Valid batch combinator syntax (all variations)

TEST 34: Batch Combinator: ___bootstrap2 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-33]
✓ ___bootstrap2: Valid batch combinator syntax (all variations)

TEST 35: Batch Combinator: ___init1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-34]
✓ ___init1: Valid batch combinator syntax (all variations)

TEST 36: Batch Combinator: ___dumpenv1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-35]
✓ ___dumpenv1: Valid batch combinator syntax (all variations)

TEST 37: Batch Combinator: ___dump0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-36]
✓ ___dump0: Valid batch combinator syntax (all variations)

TEST 38: Batch Combinator: ___batch0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-37]
✓ ___batch0: Valid batch combinator syntax (all variations)

TEST 39: Batch Combinator: ___environment_inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-38]
✓ ___environment_inspect0: Valid batch combinator syntax (all variations)

TEST 40: Batch Combinator: ___inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-39]
✓ ___inspect0: Valid batch combinator syntax (all variations)

TEST 41: Batch Combinator: ___openvpn_create1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-40]
✓ ___openvpn_create1: Valid batch combinator syntax (all variations)

TEST 42: Batch Combinator: ___openvpn_stop0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-41]
✓ ___openvpn_stop0: Valid batch combinator syntax (all variations)

TEST 43: Batch Combinator: ___openvpn_inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-42]
✓ ___openvpn_inspect0: Valid batch combinator syntax (all variations)

TEST 44: Batch Combinator: ___openvpn_clean0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-43]
✓ ___openvpn_clean0: Valid batch combinator syntax (all variations)

TEST 45: Batch Combinator: ___openvpn_dump0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-44]
✓ ___openvpn_dump0: Valid batch combinator syntax (all variations)

TEST 46: Batch Combinator: ___session_dump0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-45]
✓ ___session_dump0: Valid batch combinator syntax (all variations)

TEST 47: Batch Combinator: ___session_inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-46]
✓ ___session_inspect0: Valid batch combinator syntax (all variations)

TEST 48: Batch Combinator: ___validate0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-47]
✓ ___validate0: Valid batch combinator syntax (all variations)

TEST 49: Batch Combinator: ___wireguard_create1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-48]
✓ ___wireguard_create1: Valid batch combinator syntax (all variations)

TEST 50: Batch Combinator: ___wireguard_inspect0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-49]
✓ ___wireguard_inspect0: Valid batch combinator syntax (all variations)

TEST 51: Batch Combinator: ___wireguard_stop0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-50]
✓ ___wireguard_stop0: Valid batch combinator syntax (all variations)

TEST 52: Batch Combinator: ___wireguard_clean0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-51]
✓ ___wireguard_clean0: Valid batch combinator syntax (all variations)

TEST 53: Batch Combinator: ___wireguard_clean1 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-52]
✓ ___wireguard_clean1: Valid batch combinator syntax (all variations)

TEST 54: Batch Combinator: ___wireguard_dump0 - validate syntax with variations [db: /tmp/vpn-switch-arch-test.483595/test-53]
✓ ___wireguard_dump0: Valid batch combinator syntax (all variations)

Running Terminal Function Tests
========================================

Found 83 terminal functions


TEST 55: Terminal: _session_create1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-54]
✓ _session_create1: Valid terminal function output (all variations)

TEST 56: Terminal: _interface_destroy1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-55]
✓ _interface_destroy1: Valid terminal function output (all variations)

TEST 57: Terminal: _session_populate3 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-56]
✓ _session_populate3: Valid terminal function output (all variations)

TEST 58: Terminal: _phases_copy0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-57]
✓ _phases_copy0: Valid terminal function output (all variations)

TEST 59: Terminal: _link2 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-58]
✓ _link2: Valid terminal function output (all variations)

TEST 60: Terminal: _remove1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-59]
✓ _remove1: Valid terminal function output (all variations)

TEST 61: Terminal: _error1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-60]
✓ _error1: Valid terminal function output (all variations)

TEST 62: Terminal: _error2 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-61]
✓ _error2: Valid terminal function output (all variations)

TEST 63: Terminal: _error3 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-62]
✓ _error3: Valid terminal function output (all variations)

TEST 64: Terminal: _fail2 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-63]
✓ _fail2: Valid terminal function output (all variations)

TEST 65: Terminal: _log1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-64]
✓ _log1: Valid terminal function output (all variations)

TEST 66: Terminal: _log2 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-65]
✓ _log2: Valid terminal function output (all variations)

TEST 67: Terminal: _log3 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-66]
✓ _log3: Valid terminal function output (all variations)

TEST 68: Terminal: _lift1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-67]
✓ _lift1: Valid terminal function output (all variations)

TEST 69: Terminal: _database_init0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-68]
✓ _database_init0: Valid terminal function output (all variations)

TEST 70: Terminal: _environment_init1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-69]
✓ _environment_init1: Valid terminal function output (all variations)

TEST 71: Terminal: _environment_cache1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-70]
✓ _environment_cache1: Valid terminal function output (all variations)

TEST 72: Terminal: _lift3 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-71]
✓ _lift3: Valid terminal function output (all variations)

TEST 73: Terminal: _setenv2 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-72]
✓ _setenv2: Valid terminal function output (all variations)

TEST 74: Terminal: _getenv1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-73]
✓ _getenv1: Valid terminal function output (all variations)

TEST 75: Terminal: _unsetenv1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-74]
✓ _unsetenv1: Valid terminal function output (all variations)
  Skipped: _cat1 (requires special setup)

TEST 76: Terminal: _batch2 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-75]
✓ _batch2: Valid terminal function output (all variations)

TEST 77: Terminal: _printenv0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-76]
✓ _printenv0: Valid terminal function output (all variations)

TEST 78: Terminal: _status0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-77]
✓ _status0: Valid terminal function output (all variations)

TEST 79: Terminal: _help0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-78]
✓ _help0: Valid terminal function output (all variations)

TEST 80: Terminal: _help1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-79]
✓ _help1: Valid terminal function output (all variations)

TEST 81: Terminal: _database_enumerate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-80]
✓ _database_enumerate0: Valid terminal function output (all variations)

TEST 82: Terminal: _system_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-81]
✓ _system_inspect0: Valid terminal function output (all variations)

TEST 83: Terminal: _logs_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-82]
✓ _logs_inspect0: Valid terminal function output (all variations)

TEST 84: Terminal: _phases_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-83]
✓ _phases_inspect0: Valid terminal function output (all variations)

TEST 85: Terminal: _summary_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-84]
✓ _summary_inspect0: Valid terminal function output (all variations)

TEST 86: Terminal: _prologue_inspect0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-85]
✓ _prologue_inspect0: Valid terminal function output (all variations)

TEST 87: Terminal: _openvpn_patch2 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-86]
✓ _openvpn_patch2: Valid terminal function output (all variations)

TEST 88: Terminal: _openvpn_configure1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-87]
✓ _openvpn_configure1: Valid terminal function output (all variations)

TEST 89: Terminal: _openvpn_connect1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-88]
✓ _openvpn_connect1: Valid terminal function output (all variations)

TEST 90: Terminal: _openvpn_disconnect1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-89]
✓ _openvpn_disconnect1: Valid terminal function output (all variations)

TEST 91: Terminal: _openvpn_patch1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-90]
✓ _openvpn_patch1: Valid terminal function output (all variations)

TEST 92: Terminal: _openvpn_enumerate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-91]
✓ _openvpn_enumerate0: Valid terminal function output (all variations)

TEST 93: Terminal: _openvpn_import1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-92]
✓ _openvpn_import1: Valid terminal function output (all variations)

TEST 94: Terminal: _openvpn_list0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-93]
✓ _openvpn_list0: Valid terminal function output (all variations)

TEST 95: Terminal: _openvpn_list1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-94]
✓ _openvpn_list1: Valid terminal function output (all variations)

TEST 96: Terminal: _openvpn_add1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-95]
✓ _openvpn_add1: Valid terminal function output (all variations)

TEST 97: Terminal: _openvpn_add3 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-96]
✓ _openvpn_add3: Valid terminal function output (all variations)

TEST 98: Terminal: _openvpn_link2 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-97]
✓ _openvpn_link2: Valid terminal function output (all variations)

TEST 99: Terminal: _openvpn_remove1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-98]
✓ _openvpn_remove1: Valid terminal function output (all variations)

TEST 100: Terminal: _openvpn_remove2 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-99]
✓ _openvpn_remove2: Valid terminal function output (all variations)

TEST 101: Terminal: _openvpn_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-100]
✓ _openvpn_validate0: Valid terminal function output (all variations)

TEST 102: Terminal: _openvpn_info1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-101]
✓ _openvpn_info1: Valid terminal function output (all variations)

TEST 103: Terminal: _session_list0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-102]
✓ _session_list0: Valid terminal function output (all variations)

TEST 104: Terminal: _session_show1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-103]
✓ _session_show1: Valid terminal function output (all variations)

TEST 105: Terminal: _session_remove1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-104]
✓ _session_remove1: Valid terminal function output (all variations)

TEST 106: Terminal: _session_connect1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-105]
✓ _session_connect1: Valid terminal function output (all variations)

TEST 107: Terminal: _session_save0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-106]
✓ _session_save0: Valid terminal function output (all variations)

TEST 108: Terminal: _session_save1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-107]
✓ _session_save1: Valid terminal function output (all variations)

TEST 109: Terminal: _session_clean0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-108]
✓ _session_clean0: Valid terminal function output (all variations)

TEST 110: Terminal: _session_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-109]
✓ _session_validate0: Valid terminal function output (all variations)

TEST 111: Terminal: _session_enumerate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-110]
✓ _session_enumerate0: Valid terminal function output (all variations)

TEST 112: Terminal: _session_describe0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-111]
✓ _session_describe0: Valid terminal function output (all variations)

TEST 113: Terminal: _logs_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-112]
✓ _logs_validate0: Valid terminal function output (all variations)

TEST 114: Terminal: _logs_clean0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-113]
✓ _logs_clean0: Valid terminal function output (all variations)

TEST 115: Terminal: _phases_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-114]
✓ _phases_validate0: Valid terminal function output (all variations)

TEST 116: Terminal: _database_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-115]
✓ _database_validate0: Valid terminal function output (all variations)

TEST 117: Terminal: _binaries_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-116]
✓ _binaries_validate0: Valid terminal function output (all variations)

TEST 118: Terminal: _network_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-117]
✓ _network_validate0: Valid terminal function output (all variations)

TEST 119: Terminal: _permissions_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-118]
✓ _permissions_validate0: Valid terminal function output (all variations)

TEST 120: Terminal: _environment_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-119]
✓ _environment_validate0: Valid terminal function output (all variations)

TEST 121: Terminal: _wireguard_patch2 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-120]
✓ _wireguard_patch2: Valid terminal function output (all variations)

TEST 122: Terminal: _wireguard_configure1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-121]
✓ _wireguard_configure1: Valid terminal function output (all variations)

TEST 123: Terminal: _wireguard_connect1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-122]
✓ _wireguard_connect1: Valid terminal function output (all variations)

TEST 124: Terminal: _wireguard_disconnect1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-123]
✓ _wireguard_disconnect1: Valid terminal function output (all variations)

TEST 125: Terminal: _wireguard_enumerate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-124]
✓ _wireguard_enumerate0: Valid terminal function output (all variations)

TEST 126: Terminal: _wireguard_import1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-125]
✓ _wireguard_import1: Valid terminal function output (all variations)

TEST 127: Terminal: _wireguard_list0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-126]
✓ _wireguard_list0: Valid terminal function output (all variations)

TEST 128: Terminal: _wireguard_list1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-127]
✓ _wireguard_list1: Valid terminal function output (all variations)

TEST 129: Terminal: _wireguard_add1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-128]
✓ _wireguard_add1: Valid terminal function output (all variations)

TEST 130: Terminal: _wireguard_add3 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-129]
✓ _wireguard_add3: Valid terminal function output (all variations)

TEST 131: Terminal: _wireguard_link2 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-130]
✓ _wireguard_link2: Valid terminal function output (all variations)

TEST 132: Terminal: _wireguard_remove1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-131]
✓ _wireguard_remove1: Valid terminal function output (all variations)

TEST 133: Terminal: _wireguard_remove2 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-132]
✓ _wireguard_remove2: Valid terminal function output (all variations)

TEST 134: Terminal: _wireguard_validate0 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-133]
✓ _wireguard_validate0: Valid terminal function output (all variations)

TEST 135: Terminal: _wireguard_patch1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-134]
✓ _wireguard_patch1: Valid terminal function output (all variations)

TEST 136: Terminal: _wireguard_info1 - validate output rules [db: /tmp/vpn-switch-arch-test.483595/test-135]
✓ _wireguard_info1: Valid terminal function output (all variations)

Running Error Propagation Tests (KEEP_GOING)
========================================


TEST 137: Batch Error Propagation - test _batch2 with failing commands [db: /tmp/vpn-switch-arch-test.483595/test-136]

TEST 138:   Sub-test: KEEP_GOING=0 (fail-fast mode) [db: /tmp/vpn-switch-arch-test.483595/test-137]
✓ KEEP_GOING=0: Batch execution stopped on first error

TEST 139:   Sub-test: KEEP_GOING=1 (continue mode) [db: /tmp/vpn-switch-arch-test.483595/test-137]
✓ KEEP_GOING=1: Batch execution completed despite errors
✓ KEEP_GOING=1: All commands were executed (count=3)

TEST 140: Recursive Batch Error Propagation - test chained _batch2 calls [db: /tmp/vpn-switch-arch-test.483595/test-137]
✓ Recursive fail-fast: Command 3 in batch 3 was not executed
✓ Recursive fail-fast: Batch 2 stopped after error in batch 3
✓ Recursive fail-fast: Batch 1 stopped after error in nested batch
✓ Recursive continue: Batch 2 continued after error in batch 3
✓ Recursive continue: Batch 1 continued after error in nested batch

TEST 141: Batch KEEP_GOING with Realistic Dump File [db: /tmp/vpn-switch-arch-test.483595/test-140]
✓ Created realistic batch file with 8 commands
✓ Selected command at position 4/8 for failure injection

TEST 142:   Sub-test: KEEP_GOING=0 at position 4/8 [db: /tmp/vpn-switch-arch-test.483595/test-141]
✓ KEEP_GOING=0: Stopped at or before position 4 (executed 4 commands)
✓ KEEP_GOING=0: Error stop message present

TEST 143:   Sub-test: KEEP_GOING=1 at position 4/8 [db: /tmp/vpn-switch-arch-test.483595/test-141]
✓ KEEP_GOING=1: All commands executed (8/8)
✓ KEEP_GOING=1: Completion message present
✓ KEEP_GOING=1: Failure markers present in output

Running Batch Combinator Error Propagation Tests
========================================

Testing ALL batch combinators with error injection and KEEP_GOING validation
Found 26 batch combinator functions


TEST 144: Batch Transitive Hull: ___session_prepare3 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-141]

TEST 145:   Sub-test: Walk command tree for '___session_prepare3' (command: session_prepare) [db: /tmp/vpn-switch-arch-test.483595/test-144]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 8 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 146: Batch Transitive Hull: ___stop0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-144]

TEST 147:   Sub-test: Walk command tree for '___stop0' (command: stop) [db: /tmp/vpn-switch-arch-test.483595/test-146]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 148:   Sub-test: Inject failure at node '___stop0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-146]
✓ KEEP_GOING affects output: fail-fast=4 lines, continue=4 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 149: Batch Transitive Hull: ___phases_sync1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-146]

TEST 150:   Sub-test: Walk command tree for '___phases_sync1' (command: phases_sync) [db: /tmp/vpn-switch-arch-test.483595/test-149]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 151:   Sub-test: Inject failure at node '___phases_sync0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-149]
✓ KEEP_GOING affects output: fail-fast=3 lines, continue=3 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 152: Batch Transitive Hull: ___phases_sync0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-149]

TEST 153:   Sub-test: Walk command tree for '___phases_sync0' (command: phases_sync) [db: /tmp/vpn-switch-arch-test.483595/test-152]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 154:   Sub-test: Inject failure at node '___phases_sync0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-152]
✓ KEEP_GOING affects output: fail-fast=3 lines, continue=3 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 155: Batch Transitive Hull: ___list0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-152]

TEST 156:   Sub-test: Walk command tree for '___list0' (command: list) [db: /tmp/vpn-switch-arch-test.483595/test-155]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 157:   Sub-test: Inject failure at node '___list0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-155]
✓ KEEP_GOING affects output: fail-fast=2 lines, continue=2 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 158: Batch Transitive Hull: ___bootstrap2 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-155]

TEST 159:   Sub-test: Walk command tree for '___bootstrap2' (command: bootstrap) [db: /tmp/vpn-switch-arch-test.483595/test-158]
✓ Command tree collected: 2 nodes in transitive hull
✓ Found 6 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 160: Batch Transitive Hull: ___init1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-158]

TEST 161:   Sub-test: Walk command tree for '___init1' (command: init) [db: /tmp/vpn-switch-arch-test.483595/test-160]
✓ Command tree collected: 2 nodes in transitive hull
✓ Found 1 injectable nodes (combinators/batches) in tree

TEST 162:   Sub-test: Inject failure at node '__init0' (node 1/1) [db: /tmp/vpn-switch-arch-test.483595/test-160]
✓ KEEP_GOING affects output: fail-fast=1 lines, continue=1 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 163: Batch Transitive Hull: ___dumpenv1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-160]

TEST 164:   Sub-test: Walk command tree for '___dumpenv1' (command: dumpenv) [db: /tmp/vpn-switch-arch-test.483595/test-163]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 8 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 165: Batch Transitive Hull: ___dump0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-163]

TEST 166:   Sub-test: Walk command tree for '___dump0' (command: dump) [db: /tmp/vpn-switch-arch-test.483595/test-165]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 167:   Sub-test: Inject failure at node '___dump0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-165]
✓ KEEP_GOING affects output: fail-fast=17 lines, continue=17 lines
    Note: No clear error stop indicator in fail-fast mode
✓ KEEP_GOING=1: Execution completed despite injected failure

TEST 168: Batch Transitive Hull: ___batch0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-165]

TEST 169:   Sub-test: Walk command tree for '___batch0' (command: batch) [db: /tmp/vpn-switch-arch-test.483595/test-168]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 170:   Sub-test: Inject failure at node '___batch0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-168]
✓ KEEP_GOING affects output: fail-fast=2 lines, continue=2 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 171: Batch Transitive Hull: ___environment_inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-168]

TEST 172:   Sub-test: Walk command tree for '___environment_inspect0' (command: environment_inspect) [db: /tmp/vpn-switch-arch-test.483595/test-171]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 173:   Sub-test: Inject failure at node '___environment_inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-171]
✓ KEEP_GOING affects output: fail-fast=3 lines, continue=3 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 174: Batch Transitive Hull: ___inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-171]

TEST 175:   Sub-test: Walk command tree for '___inspect0' (command: inspect) [db: /tmp/vpn-switch-arch-test.483595/test-174]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 176:   Sub-test: Inject failure at node '___inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-174]
✓ KEEP_GOING affects output: fail-fast=12 lines, continue=12 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 177: Batch Transitive Hull: ___openvpn_create1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-174]

TEST 178:   Sub-test: Walk command tree for '___openvpn_create1' (command: openvpn_create) [db: /tmp/vpn-switch-arch-test.483595/test-177]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 8 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 179: Batch Transitive Hull: ___openvpn_stop0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-177]

TEST 180:   Sub-test: Walk command tree for '___openvpn_stop0' (command: openvpn_stop) [db: /tmp/vpn-switch-arch-test.483595/test-179]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 1 injectable nodes (combinators/batches) in tree

TEST 181:   Sub-test: Inject failure at node '___openvpn_stop0' (node 1/1) [db: /tmp/vpn-switch-arch-test.483595/test-179]
✓ KEEP_GOING affects output: fail-fast=1 lines, continue=1 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 182: Batch Transitive Hull: ___openvpn_inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-179]

TEST 183:   Sub-test: Walk command tree for '___openvpn_inspect0' (command: openvpn_inspect) [db: /tmp/vpn-switch-arch-test.483595/test-182]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 184:   Sub-test: Inject failure at node '___openvpn_inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-182]
✓ KEEP_GOING affects output: fail-fast=7 lines, continue=7 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 185: Batch Transitive Hull: ___openvpn_clean0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-182]

TEST 186:   Sub-test: Walk command tree for '___openvpn_clean0' (command: openvpn_clean) [db: /tmp/vpn-switch-arch-test.483595/test-185]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 3 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 187: Batch Transitive Hull: ___openvpn_dump0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-185]

TEST 188:   Sub-test: Walk command tree for '___openvpn_dump0' (command: openvpn_dump) [db: /tmp/vpn-switch-arch-test.483595/test-187]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 189:   Sub-test: Inject failure at node '___openvpn_dump0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-187]
✓ KEEP_GOING affects output: fail-fast=20 lines, continue=20 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 190: Batch Transitive Hull: ___session_dump0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-187]

TEST 191:   Sub-test: Walk command tree for '___session_dump0' (command: session_dump) [db: /tmp/vpn-switch-arch-test.483595/test-190]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 192:   Sub-test: Inject failure at node '___session_dump0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-190]
✓ KEEP_GOING affects output: fail-fast=41 lines, continue=41 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 193: Batch Transitive Hull: ___session_inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-190]

TEST 194:   Sub-test: Walk command tree for '___session_inspect0' (command: session_inspect) [db: /tmp/vpn-switch-arch-test.483595/test-193]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 195:   Sub-test: Inject failure at node '___session_inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-193]
✓ KEEP_GOING affects output: fail-fast=5 lines, continue=5 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 196: Batch Transitive Hull: ___validate0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-193]

TEST 197:   Sub-test: Walk command tree for '___validate0' (command: validate) [db: /tmp/vpn-switch-arch-test.483595/test-196]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 198:   Sub-test: Inject failure at node '___validate0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-196]
✓ KEEP_GOING affects output: fail-fast=10 lines, continue=10 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 199: Batch Transitive Hull: ___wireguard_create1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-196]

TEST 200:   Sub-test: Walk command tree for '___wireguard_create1' (command: wireguard_create) [db: /tmp/vpn-switch-arch-test.483595/test-199]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 8 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 201: Batch Transitive Hull: ___wireguard_inspect0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-199]

TEST 202:   Sub-test: Walk command tree for '___wireguard_inspect0' (command: wireguard_inspect) [db: /tmp/vpn-switch-arch-test.483595/test-201]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 203:   Sub-test: Inject failure at node '___wireguard_inspect0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-201]
✓ KEEP_GOING affects output: fail-fast=7 lines, continue=7 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 204: Batch Transitive Hull: ___wireguard_stop0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-201]

TEST 205:   Sub-test: Walk command tree for '___wireguard_stop0' (command: wireguard_stop) [db: /tmp/vpn-switch-arch-test.483595/test-204]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 1 injectable nodes (combinators/batches) in tree

TEST 206:   Sub-test: Inject failure at node '___wireguard_stop0' (node 1/1) [db: /tmp/vpn-switch-arch-test.483595/test-204]
✓ KEEP_GOING affects output: fail-fast=1 lines, continue=1 lines
    Note: No clear error stop indicator in fail-fast mode
    Note: No clear completion indicator in continue mode

TEST 207: Batch Transitive Hull: ___wireguard_clean0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-204]

TEST 208:   Sub-test: Walk command tree for '___wireguard_clean0' (command: wireguard_clean) [db: /tmp/vpn-switch-arch-test.483595/test-207]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 3 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 209: Batch Transitive Hull: ___wireguard_clean1 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-207]

TEST 210:   Sub-test: Walk command tree for '___wireguard_clean1' (command: wireguard_clean) [db: /tmp/vpn-switch-arch-test.483595/test-209]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 3 injectable nodes (combinators/batches) in tree
    Skipped: Could not select target node for injection

TEST 211: Batch Transitive Hull: ___wireguard_dump0 - walkthrough-based error injection [db: /tmp/vpn-switch-arch-test.483595/test-209]

TEST 212:   Sub-test: Walk command tree for '___wireguard_dump0' (command: wireguard_dump) [db: /tmp/vpn-switch-arch-test.483595/test-211]
✓ Command tree collected: 1 nodes in transitive hull
✓ Found 2 injectable nodes (combinators/batches) in tree

TEST 213:   Sub-test: Inject failure at node '___wireguard_dump0' (node 1/2) [db: /tmp/vpn-switch-arch-test.483595/test-211]
✓ KEEP_GOING affects output: fail-fast=42 lines, continue=42 lines
    Note: No clear error stop indicator in fail-fast mode
✓ KEEP_GOING=1: Execution completed despite injected failure

Running Batch Combinator KEEP_GOING Precise Tests
========================================

Testing ALL batch combinators with precise architectural KEEP_GOING validation
Found 26 batch combinator functions


TEST 214: Batch KEEP_GOING Precise: ___session_prepare3 [db: /tmp/vpn-switch-arch-test.483595/test-211]
✓ Captured 175 command lines from ___session_prepare3
✓ Selected 65 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 215: Batch KEEP_GOING Precise: ___stop0 [db: /tmp/vpn-switch-arch-test.483595/test-214]
✓ Captured 2 command lines from ___stop0
✓ Selected 2 random line(s) for failure injection
✓ Injected failures into 2 function(s)
  Note: Not all commands attempted (0/3)
  Note: This may indicate KEEP_GOING=0 or execution stopped early
  Skipped: ___phases_sync1 (requires phase template setup)
  Skipped: ___phases_sync0 (requires phase template setup)

TEST 216: Batch KEEP_GOING Precise: ___list0 [db: /tmp/vpn-switch-arch-test.483595/test-215]
✓ Captured 2 command lines from ___list0
✓ Selected 1 random line(s) for failure injection
✓ Injected failures into 1 function(s)
✓ KEEP_GOING=1: All commands attempted (2/2)

TEST 217: Batch KEEP_GOING Precise: ___bootstrap2 [db: /tmp/vpn-switch-arch-test.483595/test-216]
✓ Captured 73 command lines from ___bootstrap2
✓ Selected 36 random line(s) for failure injection
  Skipped: No functions were injected with failures
  Skipped: ___init1 (complex initialization logic)

TEST 218: Batch KEEP_GOING Precise: ___dumpenv1 [db: /tmp/vpn-switch-arch-test.483595/test-217]
✓ Captured 175 command lines from ___dumpenv1
✓ Selected 133 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 219: Batch KEEP_GOING Precise: ___dump0 [db: /tmp/vpn-switch-arch-test.483595/test-218]
✓ Captured 5 command lines from ___dump0
✓ Selected 3 random line(s) for failure injection
✓ Injected failures into 1 function(s)
  Note: Not all commands attempted (3/5)
  Note: This may indicate KEEP_GOING=0 or execution stopped early

TEST 220: Batch KEEP_GOING Precise: ___batch0 [db: /tmp/vpn-switch-arch-test.483595/test-219]
✓ Captured 2 command lines from ___batch0
✓ Selected 2 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 221: Batch KEEP_GOING Precise: ___environment_inspect0 [db: /tmp/vpn-switch-arch-test.483595/test-220]
✓ Captured 2 command lines from ___environment_inspect0
✓ Selected 2 random line(s) for failure injection
✓ Injected failures into 2 function(s)
  Note: Not all commands attempted (2/3)
  Note: This may indicate KEEP_GOING=0 or execution stopped early

TEST 222: Batch KEEP_GOING Precise: ___inspect0 [db: /tmp/vpn-switch-arch-test.483595/test-221]
✓ Captured 12 command lines from ___inspect0
✓ Selected 6 random line(s) for failure injection
✓ Injected failures into 4 function(s)
  Note: Not all commands attempted (10/12)
  Note: This may indicate KEEP_GOING=0 or execution stopped early

TEST 223: Batch KEEP_GOING Precise: ___openvpn_create1 [db: /tmp/vpn-switch-arch-test.483595/test-222]
✓ Captured 175 command lines from ___openvpn_create1
✓ Selected 29 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 224: Batch KEEP_GOING Precise: ___openvpn_stop0 [db: /tmp/vpn-switch-arch-test.483595/test-223]
✓ Captured 1 command lines from ___openvpn_stop0
✓ Selected 1 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 225: Batch KEEP_GOING Precise: ___openvpn_inspect0 [db: /tmp/vpn-switch-arch-test.483595/test-224]
✓ Captured 3 command lines from ___openvpn_inspect0
✓ Selected 3 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 226: Batch KEEP_GOING Precise: ___openvpn_clean0 [db: /tmp/vpn-switch-arch-test.483595/test-225]
✓ Captured 3 command lines from ___openvpn_clean0
✓ Selected 1 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 227: Batch KEEP_GOING Precise: ___openvpn_dump0 [db: /tmp/vpn-switch-arch-test.483595/test-226]
✓ Captured 13 command lines from ___openvpn_dump0
✓ Selected 3 random line(s) for failure injection
  Skipped: No functions were injected with failures

TEST 228: Batch KEEP_GOING Precise: ___session_dump0 [db: /tmp/vpn-switch-arch-test.483595/test-227]
✓ Captured 40 command lines from ___session_dump0
✓ Selected 23 random line(s) for failure inject