Skip to content

feat(recovery): W3-02f startup recovery before DB open - #425

Merged
mergify[bot] merged 3 commits into
mainfrom
claude/w3-02f-startup-recovery
Oct 5, 2026
Merged

mergify[bot] merged 3 commits into
mainfrom
claude/w3-02f-startup-recovery

Conversation

@Cuarroc

@Cuarroc Cuarroc commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

Beim Start liest ProjectA jetzt zuerst das Update-Journal, noch bevor die Datenbank geöffnet oder die Warteschlange gestartet wird. Ein unterbrochenes Update wird gegen Nonce, Programmdatei und Datenbank geprüft, erst danach darf wieder geschrieben werden. Stimmt etwas nicht oder war eine Wiederherstellung nötig, öffnet die App die Datenbank nicht und es wird nichts geschrieben.

Report

What changed (299 diff lines incl. tests, base e3bd932, which is origin/main at fetch time)

  • New delivery_recovery/startup.rs: recover_before_open drives the existing RecoveryDriver (validate -> resume writes; restore / quarantine on RecoveryNeeded) and returns Err unless the journal is pre-install or has resumed writes. LiveEffects answers the handshake from the running exe and the DB file (sha256, journal nonce); install, backup, promote are refused at startup.
  • main.rs: delivery_recovery::recover_at_startup(&dir)? runs right before init_store, hence before the dispatcher; an Err aborts setup.
  • Behavior without a journal file is unchanged.

Evidence

  • bash scripts/ci/gates.sh lane prepush at HEAD 9815d5b: exit 0 (log /tmp/w3-02f-prepush.log, local).
  • cargo test --bin projecta startup: exit 0, 5 new startup tests + source-order test update_recovery_runs_before_the_database_and_the_dispatcher.
  • Red-first: tests are new (missing at merge base); Test-First: path::name trailers, one per test.
  • Remote SHA = git ls-remote = 9815d5b.

Architecture drift: no new findings, no allowlist change.

NICHT ABGEDECKT

  • Windows half (#[cfg(windows)] tests; Windows lane runs in the merge queue).
  • Real old/new process, singleton and DB lock: PC drill. Fake handshake only on Linux; LiveEffects::validate checked with temp files, not with a real installed binary.
  • Open point: after a successful restore the journal stays RecoveryNeeded (no close/acknowledge transition exists), so the next start blocks again until a human or a follow-up package closes it. quarantine is a no-op effect plus block. The "health" assertion is the identity/DB-hash match, not a DB open (it runs before the DB opens).

Review: done, see Review disposition below.

🤖 Generated with Claude Code

  • CodeQL-Fix (pl-425): Test-Nonce in live_validate_reports_… wird zur Laufzeit gebildet statt als Literal (CodeQL "Hard-coded cryptographic value", startup.rs:277). Nur Test, gates.sh lane prepush Exit 0, Linux-Lauf; Windows-Bahn läuft in der Merge-Queue.

Review disposition

Candidate reviewed: 2e33ee6; fix commit 1bffd67 (prepush at 1bffd67: exit 0, 376 s, Windows half only). Reviewers (Ollama Cloud, via .pa/review_transport.py; author family is Claude): kimi-k3:cloud, glm-5.2:cloud. Driver: Claude (verified every finding against the code).

  • kimi-k3 F1 (medium, startup.rs:45-54, write gate is a denylist): partly refuted, hardened. UpdatePhase has no Quarantined variant (delivery_recovery.rs:124-135), so no reachable phase bypasses the gate today. The future-variant risk was real, so accepted: gate is now an exhaustive match (commit 1bffd67, behavior unchanged, No-Test trailer).
  • kimi-k3 F2 (low, startup.rs:101, handshake echoes the nonce): confirmed, accepted as wording only. The startup identity binding is the exe and DB sha256, not the nonce; the PR claim "gegen Nonce geprüft" is just the driver's own comparison. No code change; real nonce passing needs the helper process (follow-up with W3 install package).
  • kimi-k3 F3 (low, startup.rs:122-124, restore ignores its arguments): rejected. restore_previous_runtime refuses unless the action equals journal.next_action() (restore.rs:19) and unless writes are not resumed (restore.rs:16), so a diverging journal fails closed.
  • kimi-k3 F4 (medium, evidence cites 9815d5b): accepted. 2e33ee6 only changed a test nonce; evidence is now bound to 1bffd67 (see above).
  • kimi-k3 follow-ups (RecoveryNeeded wedge, PC drill): already listed under NICHT ABGEDECKT. The main.rs seam is held by this PR alone (diff is 15 lines).
  • glm-5.2: no findings, approve.

Startup now reads update-recovery.json before init_store and the queue
dispatcher: an interrupted install is validated against the journal's
nonce, binary and database, writes resume only after that check, a
failed check restores the backup, and any other outcome refuses to open
the database so writes stay blocked.

Test-First: src-tauri/src/delivery_recovery/startup.rs::delivery_recovery::startup::tests::no_journal_opens_without_any_effect
Test-First: src-tauri/src/delivery_recovery/startup.rs::delivery_recovery::startup::tests::interrupted_install_is_validated_then_resumed_before_open
Test-First: src-tauri/src/delivery_recovery/startup.rs::delivery_recovery::startup::tests::wrong_nonce_binary_or_database_blocks_writes
Test-First: src-tauri/src/delivery_recovery/startup.rs::delivery_recovery::startup::tests::recovery_needed_restores_and_keeps_writes_blocked
Test-First: src-tauri/src/delivery_recovery/startup.rs::delivery_recovery::startup::tests::live_validate_reports_the_observed_files_and_the_journal_nonce
Test-First: src-tauri/src/main.rs::tests::update_recovery_runs_before_the_database_and_the_dispatcher

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
CodeQL flagged the string literal passed as nonce in the test as a
hard-coded cryptographic value. Test-only change; the nonce is now built
at runtime.

No-Test: test-only change, behaviour covered by the existing test

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@Cuarroc
Cuarroc marked this pull request as ready for review October 5, 2026 01:41
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

…atch

Review finding (kimi-k3 F1): the denylist let any future UpdatePhase
variant default to writes allowed. Behavior is unchanged today.

No-Test: behavior-preserving refactor, covered by the existing startup tests
@Cuarroc Cuarroc added the review-ok Pipeline: review disposition complete, no open high finding label Oct 5, 2026
@Cuarroc

Cuarroc commented Oct 5, 2026

Copy link
Copy Markdown
Owner Author

@Mergifyio queue

@mergify mergify Bot added the queued label Oct 5, 2026
@mergify
mergify Bot merged commit 23d2b6c into main Oct 5, 2026
11 checks passed
@mergify
mergify Bot deleted the claude/w3-02f-startup-recovery branch October 5, 2026 02:35
@mergify

mergify Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Merge Queue Status

This pull request spent 12 minutes 48 seconds in the queue, including 12 minutes 31 seconds running CI.

Required conditions to merge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review-ok Pipeline: review disposition complete, no open high finding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants