detail
Started Phase 3 (add new token as dual-valid alongside old). Verification immediately caught a real design flaw: most of the 91 files migrated earlier used cai_current_token() (returns only active[0]) at the actual incoming-auth-gate comparison site, instead of cai_check_token() (true array-membership check) -- meaning those gates could never accept more than the first token in the array regardless of what tokens.json contained. Old token still worked everywhere (array[0]), so nothing was live-broken, but the new token was rejected almost everywhere -- caught before any real damage, exactly by the verification step meant to catch it. Root cause: two different functions built for two different jobs (cai_check_token for incoming gates, cai_current_token for a script authenticating itself to ANOTHER endpoint) got mixed up during the original migration. Fixed across 79 files: 49 caught by an automated pattern-match pass, 30 requiring individual inspection due to real per-file variation (different constant names, hash_equals() style checks, and two files -- systems/community/comms/api.php and all 11 systems/*/data/api.php -- that have a SEPARATE, unrelated second credential called ISC_TOKEN for inter-system communication, which was correctly identified and left completely untouched, out of scope). 3 files (BACKUP.php, TASKGATE.php, CHECKPOINT.php) were already correct from the very first migration pass and needed no change. backend/info/domains/09-inner.php has no incoming gate at all by design (pure outbound proxy) -- confirmed correct as-is. Every one of the 79 changed files was backed up, deployed, and verified with THREE tests: old token works, new token works, bad token rejected -- not just swept for a literal string. SEPARATE, MORE SERIOUS FINDING during this verification pass: backend/tools/file-editor.php had NO token check at all gating its main editor view or its raw/download branch -- only the 'save' (write) action was ever actually checked. This is a pre-existing gap, not something tonight's token-rotation work introduced -- anyone who could reach the URL could read any server file's contents (blocked only by a '..' traversal check), no token needed. Fixed with a single top-level gate covering every branch (main view, raw, download, save). Verified: bad token now rejected on every path (main view returns 'Unauthorized.', raw/download/save all return a proper 401/error JSON), both old and new token work correctly on every path.