Three of Ark0N's four "will take at merge" items, applied instead since
they were straightforward to do properly:
1. test/frontend-cli-no-id-branching.test.ts's ALLOWED_BRANCHES keyed on
<file>::<expression> (fixed last round) closed the line-shift problem
but opened a new one: every stock id was already allowlisted for
session-ui.js in the `mode === '<id>'` form, so a BRAND NEW branch
reusing that exact expression anywhere in the file passed unnoticed.
Reproduced live (`if (this.mode === 'codex')` injected into
runOpenCode()) — stayed green under the old version. Each allowlist
entry now carries the exact count of approved call sites, and a new
test asserts actual-vs-declared count for every key; a mismatch in
either direction is real (higher = new unreviewed branch riding in on
an existing approval, lower = a reviewed site was removed and the
entry is now stale). Reproduced again against the fix: same injection
now fails with an exact diagnostic (expected 2, found 3).
2. Added test/run-mode-launch-table-drift.test.ts. RUN_MODE_LAUNCH
restates four things stock.ts already owns (label, install command,
supportsCustomModel, the external-mode key set), and they agree today
with nothing enforcing it. supportsCustomModel is the dangerous one:
the Run-menu picker's rows come from the server-injected
window.__codemanCustomModelClis (built from
capabilities.customModelInjection.kind), so a CLI gaining a real
injection recipe later would be OFFERED in the picker while
_runCliMode silently drops the customModel field for it — the session
launches on the vendor's cloud while the UI claims the local endpoint.
Drives the real session-ui.js via JSDOM and compares RUN_MODE_LAUNCH
against STOCK_CLIS on all four axes.
3. Inlined the "Open Question 7 in PR-B2.md" references in the allowlist
reasons — PR-B2.md is a local planning doc, never part of the
committed tree, so the reference was dead on arrival for anyone
reading the repo. Points at the PR #458 review thread instead.
4. Added a sentence to docs/cli-registry.md naming the new frontend guard
alongside the backend one it mirrors.
Full gate: 406 files / 7721 tests / 0 failures, typecheck/lint/format/
check:frontend-syntax all clean.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GuHtuPiHXdykq9T6rKQJ9n