Skip to content

Validate C++ disaster recovery traces with Lean - #8282

Draft
Amaury Chamayou (achamayou) wants to merge 34 commits into
mainfrom
achamayou-fluffy-parakeet
Draft

Validate C++ disaster recovery traces with Lean#8282
Amaury Chamayou (achamayou) wants to merge 34 commits into
mainfrom
achamayou-fluffy-parakeet

Conversation

@achamayou

@achamayou Amaury Chamayou (achamayou) commented Sep 4, 2026

Copy link
Copy Markdown
Member

Summary

Part 4/4 of the replacement stack for #8241. This PR validates real C++ recovery-decision-protocol executions against the permanent Lean model introduced below it.

Stack:

This PR depends on draft deletion PR #8280 and must remain gated until the lower layers are ready.

Approach

  • Defers the production host restart until the JOINING state transaction globally commits in both default and trace-enabled builds. In trace-enabled builds, the committed join_restart observation is emitted before restart is requested. This is a commit-before-restart guarantee, not an exactly-once guarantee.
  • Adds the OFF-by-default CCF_RECOVERY_TRACE option, a commit-aware trace table, versioned RDP_TRACE records, per-node sequences, message IDs, causal IDs, exact ordered retry-send batches, accepted receives, committed timeouts, and one-shot effects.
  • Adds an isolated Lean 4.33.1 package at lean/disaster-recovery-trace/. It depends locally on ../disaster-recovery and imports only DisasterRecovery.Protocol.Model; no trace modules or targets are added to the canonical package.
  • Defines and documents the strict ccf.recovery_decision_protocol.trace/1 NDJSON contract. The validator rejects the shortest incompatible prefix and checks parser/replay behavior without treating synthetic tests as implementation evidence.
  • Extracts records from each node, validates identity, sequence, message IDs, and causal edges, deterministically topologically orders them, writes *.recovery.ndjson, and invokes the isolated validator.
  • Wires quorum, failover, and repeated-timeout recovery scenarios into the Milan and Genoa SNP jobs. Those jobs build with tracing enabled and upload captured NDJSON even on failure.
  • Adds the trace validator as a job in the shared .github/workflows/lean.yml; there is no separate Lean workflow. The job uses mk_all --check, warnings-as-errors, and the same standard axiom audit as the canonical package.

Evidence and isolation

Real captured C++ SNP traces are the implementation conformance evidence. Small in-memory Lean and Python tests cover rejection, extraction, and ordering only.

lean/disaster-recovery/ remains byte-for-byte unchanged. This PR does not recreate lean/disaster-recovery-migration/ or tla/disaster-recovery/, and contains no migration, Rust, or Stateright code.

Validation

  • Built node_frontend_test with CCF_RECOVERY_TRACE both OFF and ON.
  • Ran node_frontend_test through each build's tests.sh wrapper.
  • Ran the focused Python extraction/ordering suite (8 tests).
  • Ran lake exe cache get, lake exe mk_all --check --lib DisasterRecoveryTrace, lake build --wfail, lake lint, and lake exe trace-checks for the isolated package under Lean 4.33.1. The axiom audit checked 317 trace declarations, all within the propext, Classical.choice, and Quot.sound allowlist.
  • Ran scripts/ci-checks.sh -f successfully on the original trace layer; the rebased workflow and package metadata pass Prettier and stale-reference checks.

Gates

Keep this PR in draft while #8280 remains gated. Native stack #8283 preserves the order #8277 -> #8279 -> #8280 -> #8282.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep protocol definitions and explicit system properties on the human-review surface. Move proof implementations to checked helper lemmas and use standard Lake build, axiom lint, and import coverage checks.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: ed9f1e31-297c-4592-a089-2d37c49c2434
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: ed9f1e31-297c-4592-a089-2d37c49c2434
Use file-aligned Protocol and Proofs namespaces, expose the reviewed theorems under DisasterRecovery.Properties, and update dependent names and documentation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove temporal and liveness definitions and proofs, retain local transition safety under Proofs.Model, and rename TxID.PrefixOf to TxID.EarlierThan.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: ed9f1e31-297c-4592-a089-2d37c49c2434
Request host restart only from the committed JOINING state hook so aborted recovery transactions cannot trigger a restart.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Gate versioned RDP_TRACE records behind CCF_RECOVERY_TRACE and publish receive, timeout, effect, and retry-send events only at their required commit boundaries.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replay strict version 1 recovery traces against the canonical model through a local package dependency, with focused rejection tests, no-sorry checks, documentation, and a shallow workflow.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Validate trace identity, per-node sequences, message IDs, and causal edges before producing a deterministic NDJSON linearization for the isolated Lean validator.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Build the isolated validator in Milan and Genoa trace-enabled jobs, validate quorum, failover, and repeated-timeout recoveries, and retain generated NDJSON artifacts on failure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Exercise the focused Python extraction and causal-ordering suite in the dedicated trace workflow.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Consolidate the trace checks into the shared Lean workflow and replace the handwritten sorry scan with the standard axiom audit.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: ed9f1e31-297c-4592-a089-2d37c49c2434
Update trace parsing, replay, and tests for the canonical model namespace introduced lower in the stack.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread CHANGELOG.md Outdated
- Corrected the OpenAPI schema name for `ccf::ds::SizeString` from `TimeString` to `SizeString` (#8261).
- A transaction in a JavaScript application endpoint which conflicts with compaction is now re-executed, rather than returning `500 Internal Server Error` (#8289).
- A `Range` header requesting a suffix longer than the file is now clamped to the whole file, per RFC 9110. Ranges which select no bytes, such as `bytes=-0`, are now rejected with `400 Bad Request` (#8299).
- Recovery-decision-protocol nodes now request host restart only after the `JOINING` state transaction commits, preventing restart for an aborted transaction. (#8282)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Umm,... this PR shouldn't make meaningful changes to the behavior of CCF, just add DR tracing

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss with cjen1-msft, we can split it, but the currently implementation is otherwise dangerous, and the TV does not match the model with this bug that allows rollback. If this feature was stable and used, I would feel differently, but here I think we ought to fix before we TV (I am happy to split).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to do as little trace manipulation in python as possible. We did this before due to the constraints of TLA+ but Lean is more flexible

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, let me try.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm just sloppy but I don't think we need unit tests for our test infra, the test is the trace validation in the CI. The only testing for trace validation I'm concerned about is ensuring the trace validation isn't too relaxed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think versioning traces in unnecessary

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So long as they're a CI concern, agreed, certainly. Eventually though, we'd like to get traces from production deployments, and then versioning will be quite useful if we ever decide to make changes.

Base automatically changed from achamayou-solid-tribble to main September 11, 2026 13:42
Keep Ubuntu 26.04 runners and pull-request-only Lean validation while retaining the trace-validator job and recovery path filters. Move the recovery restart fix to the upcoming 7.0.16 release notes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Include the JavaScript wrapped-value ownership fix merged while recovery-trace validation was running.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lean Verification using Lean

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants