Fail open on invalid local settings with in-app diagnostics - #322
Conversation
Code review (parent — multi-agent fleet unavailable)Verdict: approve with nits — core fail-open path looks solid. Correctness
Nits
Tests
|
Review — request changesFail-open + credential stripping is directionally right (allowlist into Blocking / should-fix
Non-blocking
Security (credentials)
Merge
|
|
Addressed multi-agent review:
|
Multi-agent review (blended: cto / greybeard / neckbeard / critique / bruckheimer)Verdict: Approve (after earlier post-review fixes) Fixed earlier
Ready for human review/merge. |
Hard verdict: DENYFail-open for invalid local settings is the right product direction, but this PR ships silent fail-open for every non-TUI caller and leaves a write-base clobber path that can destroy the on-disk file. That is not mergeable as-is. Blockers (must fix)1. Silent fail-open outside TUI —
|
| Disk state | Write base |
|---|---|
| ENOENT / absent | {} (create OK) |
| Valid / fail-open partial with known fields | merge into cleaned LocalSettings |
| Invalid JSON / non-object / unreadable | skip write (return null); surface error to UI |
Never treat "load failed with diagnostics and settings === null while file exists" as empty base.
Non-blocking but real
- Chrome budget undercount (
chrome-geometry.ts:91): hard-codes 2 rows, butsettingsNoticeisdiagnostics.map(...message + fix).join("\n")plus Esc hint — N diagnostics can be 2N+1 lines. Budget from actual line count or cap rendered lines. - Tests thin (
settings.test.ts): no coverage for invalid JSON, non-object, empty-after-coerce, write-base skip, orloadConfig→ diagnostics wiring; no exec/stderr assertion. - Esc dismiss +
isReasoningEffortcoerce +pickLocalFieldsshare look correct; keep those.
What is fine
- TUI banner + Esc dismiss (keymap test present)
isReasoningEfforton coerce pathpickLocalFieldsstrict/coerce split (no drift risk on known keys)- Credential keys stripped from in-memory load
REQUEST_CHANGES until (1) non-TUI diagnostics emission and (2) local write-base no-clobber are fixed.
Hard review (greybeard + CTO)Verdict: APPROVE (after follow-up commits) GreybeardFail-open local load + diagnostics on the main screen is correct. Write-base helpers for both global and local selection files prevent RMW clobber of broken JSON. Exec path emits diagnostics to stderr so Ink is not the only signal. Shared CTOThis was the most important reliability fix in the set. Tests cover invalid JSON, credentials strip, write-base absent/cleaned/unusable, and global write-base. Ship. No remaining blockers. |
Invalid or unknown keys in .corbits/settings.json no longer crash startup. Known fields still apply; credentials and bad values are ignored with actionable diagnostics surfaced on the main TUI. Closes CL-5348
…ffort Wire settingsNotice into the global keymap so Esc clears the fail-open banner. Use the shared isReasoningEffort helper so all effort levels survive coerce. Budget two chrome rows for the diagnostics banner.
One helper builds optional local-settings fields for both the clean strict load and fail-open coerce paths so the two maps cannot drift.
Add loadLocalSettingsWriteBase so session-mode RMW skips unusable
files instead of writing {} over broken JSON. Emit settings diagnostics
to stderr on exec so fail-open is never silent outside the TUI.
96e60ce to
37f5c26
Compare
Summary
.corbits/settings.jsonno longer crash startupTest plan
bun test src/settings.test.tspassesCloses CL-5348