You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Description
This PR delivers a full replay + telemetry feature set and hardens
docs/wiki synchronization.
It solves two core gaps:
1. No first-class way to record, serialize, and replay real P2P matches
for deterministic debugging and validation.
2. Wiki mirror generation and SYNC-header validation were easier to
drift or fail with less-actionable diagnostics.
### What changed
- Added replay domain types and serialization:
- `Replay<I>` and `ReplayMetadata`
- `Replay::to_bytes()`, `Replay::from_bytes()`, `Replay::validate()`,
`Replay::total_frames()`
- Added replay playback session:
- `ReplaySession<T>` implementing `Session<T>`
- `ReplaySession::new()` and `ReplaySession::new_with_validation()`
- Validation mode emits `SaveGameState` before `AdvanceFrame` and
compares checksums frame-by-frame
- Added replay recording support to P2P sessions:
- `SessionBuilder::with_recording(bool)`
- `P2PSession::is_recording()`, `P2PSession::into_replay()`,
`P2PSession::take_replay()`
- Recording now captures confirmed inputs and recorded checksums
- Added session telemetry API and built-in collector:
- `SessionTelemetry` trait
- `TelemetryEvent` enum (`Rollback`, `PredictionMiss`,
`NetworkStatsUpdate`, `FrameAdvance`)
- `CollectingTelemetry`
- `SessionBuilder::with_telemetry(...)`
- P2P telemetry emission integrated in rollback, prediction miss,
network stats polling, and frame advance paths
- Added sync-layer helper used for telemetry:
- `players_with_incorrect_predictions(...)`
- Expanded public exports and docs:
- Re-exports for replay/telemetry in `lib.rs` and prelude
- New docs: replay and telemetry guides
- Added MkDocs nav entries and wiki mirror pages/sidebar links
- Hardened docs/wiki synchronization pipeline:
- Added pre-commit `sync-wiki` hook before wiki consistency checks
- `sync-wiki.py` now:
- injects/normalizes reciprocal wiki SYNC headers
- validates sidebar coverage before writing files
- normalizes generated markdown EOF/newline format deterministically
- `check-sync-headers.py` now reports case-mismatch hints and
remediation guidance
- Added/expanded script tests for sync behavior and diagnostics
- Added `.gitignore` entries for local pre-commit/pre-push log artifacts
### Breaking change
- Added `FortressEvent::ReplayDesync { frame, expected_checksum,
actual_checksum }`.
- Because `FortressEvent` is not `#[non_exhaustive]`, downstream
exhaustive `match` statements must add a branch for `ReplayDesync`.
## Type of Change
- [x] 🐛 Bug fix (non-breaking change that fixes an issue)
- [x] ✨ New feature (non-breaking change that adds functionality)
- [x] 💥 Breaking change (fix or feature that would cause existing
functionality to change)
- [x] 📚 Documentation (changes to documentation only)
- [ ] ♻️ Refactor (code change that neither fixes a bug nor adds a
feature)
- [x] 🧪 Test (adding or updating tests)
- [x] 🔧 CI/Build (changes to CI configuration or build process)
## Checklist
### Required
- [ ] I have read the [CONTRIBUTING guide](../docs/contributing.md)
- [ ] I have followed the **zero-panic policy**:
- No `unwrap()` in production code
- No `expect()` in production code
- No `panic!()` or `todo!()`
- All fallible operations return `Result`
- [x] I have added tests that prove my fix is effective or my feature
works
- [ ] I have run `cargo fmt && cargo clippy --all-targets --features
tokio,json` with no warnings
- [ ] I have run `cargo nextest run` and all tests pass
### If Applicable
- [x] I have updated the documentation accordingly
- [x] I have added an entry to `CHANGELOG.md` for user-facing changes
- [ ] I have updated relevant examples in the `examples/` directory
- [ ] My changes generate no new compiler warnings
## Testing
**Tests added/modified:**
- Added replay model tests in `src/replay.rs` (serialization roundtrip,
validation invariants, metadata/display, recorder behavior)
- Added replay session tests in `src/sessions/replay_session.rs`
(playback flow, completion behavior, validation mode, checksum mismatch
event emission)
- Added event display coverage for `ReplayDesync` in `src/lib.rs`
- Added builder/session tests in `src/sessions/builder.rs` and
`src/sessions/p2p_session.rs` for replay-session creation and recording
API behavior
- Added new script tests in `scripts/tests/test_check_sync_headers.py`
- Expanded `scripts/tests/test_sync_wiki.py` coverage for SYNC header
generation, sidebar coverage validation, idempotent output
normalization, and fail-before-write behavior
**Manual testing performed:**
- Reviewed API docs and migration impact for new replay + telemetry APIs
- Verified docs navigation additions and wiki mirror wiring in this
branch
- Full local command status (`cargo fmt`, `cargo clippy`, `cargo
nextest`) intentionally left unchecked in checklist for final author
confirmation
## Related Issues
- N/A (no issue links provided in branch metadata)
---
<!-- Thank you for contributing to Fortress Rollback! -->
Copy file name to clipboardExpand all lines: .llm/context.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -216,18 +216,23 @@ For protocol tests that poll in loops (`poll_remote_clients()` / protocol `poll(
216
216
217
217
**Exclude:** internal refactoring, test improvements, doc-only changes, CI/tooling, lint fixes.
218
218
219
+
**Unreleased code rule:** Never add separate "Fixed" or "Changed" entries for code that has not yet been released. Fixes to unreleased features should be folded into the existing "Added" entry describing that feature. The changelog should describe the final shipped state, not intermediate development history.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+28Lines changed: 28 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,6 +14,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
14
14
15
15
## [Unreleased]
16
16
17
+
## [0.8.0]
18
+
19
+
### Changed
20
+
21
+
-**Breaking:**`FortressEvent::ReplayDesync` — new variant added. Since `FortressEvent` is not `#[non_exhaustive]`, exhaustive matches must now handle this variant.
22
+
-**Breaking:**`InvalidFrameReason::ReplayExhausted` — new variant added. Since `InvalidFrameReason` is not `#[non_exhaustive]`, exhaustive matches must now handle this variant.
23
+
-**Breaking:**`Config::Input` now requires `Eq` in addition to `PartialEq`. Types used as `Config::Input` must derive or implement `Eq`. This ensures reflexive equality, which is a correctness requirement for deterministic rollback — non-reflexive types (e.g., floats with `NaN`) would cause phantom prediction misses and unnecessary rollbacks. All integer and struct-of-integer types already implement `Eq`; add `#[derive(Eq)]` to any custom input types that are missing it.
24
+
25
+
### Added
26
+
27
+
-`ReplaySession::new_with_validation()` constructor that enables checksum validation mode, emitting `SaveGameState` requests, comparing checksums against the replay recording, and flushing final-frame validation when `events()` is drained after completion
28
+
-`ReplaySession::is_validating()` accessor to check if checksum validation mode is enabled
29
+
-`SessionBuilder::start_replay_session_with_validation()` builder method for creating a validation-enabled replay session
0 commit comments