Commit 4236724
fix(capstone): post-GA hardening - recovery-repair, OAuth cred validation, restore fail-closed
Resolves the whole-system codex CAPSTONE findings (1 promoted-P1 data-safety + 2 P2).
v0.1.0 is shipped; the upgrade repair runs on a v0.1.0 -> v0.1.1 boot, so the fleet benefits.
CAP-P1 (DATA-SAFETY) recovery-repair normalizes EVERY account with encrypted sources and
unacked recovery state, not only zero-ack-row accounts. The pre-fix repair skipped any account
that already had an ack row, so a partially-gated account (one pending ack + a sibling encrypted
source still ENABLED) escaped the gate and could keep producing encrypted backups before the
recovery phrase was acked (potentially unrecoverable). The repair now disables every still-enabled
encrypted source per account, seeds a pending ack for every encrypted source missing one
(idempotent), and writes the backfill marker only after normalization. The ack path
(enable_source_and_clear_recovery_ack) re-enables the whole gate-disabled set (resolve account from
the source's ack row -> re-enable all that account's pending-ack sources -> clear all its acks in one
transaction), so a single per-account ack fully restores a multi-source account. New regression test
upgrade_repair_normalizes_partially_gated_multi_source_account. (Subsumes the R9-P1-1 residual.)
CAP-P2a (commands/accounts.rs) reject control characters and newlines in BOTH OAuth client_id AND
client_secret at the input boundary. The keychain record is newline-delimited, so a newline in either
field corrupted decode_record on restart and stranded the account in reauth/refresh failure; only
non-empty client_id was validated before. New test
reject_control_chars_rejects_newlines_and_controls_but_accepts_clean_creds.
CAP-P2b (commands/restore.rs) restore fails-closed on the DB SourceRow.encryption_enabled flag
(apply_encryption_policy), mirroring the executor: DB encrypted -> only a Suite provider acceptable
(Plaintext/Unavailable -> Unavailable/error); DB unencrypted -> force plaintext, ignore any provider
suite. Previously resolve_suite trusted the live crypto provider, so a stale provider snapshot could
route an encrypted source through the plaintext path. New tests
encrypted_source_with_provider_{plaintext,unavailable}_fails_closed,
encrypted_source_with_provider_suite_uses_the_suite,
unencrypted_source_with_provider_{suite,unavailable}_forces_plaintext.
Gates green: cargo build/clippy/test --workspace (SQLX_OFFLINE), deny check, fmt --all --check,
git diff --check, sqlx 0-drift (5 query files replaced). Anti-fake-green stub sweep over the touched
surface: zero non-test todo!/unimplemented!/unreachable!.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CyiRqk2DVwmJjEu5gcD1m1 parent 3de2cf7 commit 4236724
14 files changed
Lines changed: 496 additions & 150 deletions
File tree
- .sqlx
- crates/driven-core/src/state
- design
- src-tauri/src/commands
Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 0 additions & 12 deletions
This file was deleted.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
0 commit comments