refactor(engine): ambiguity gate covers the full cluster — batches 1-3, 585 pairs burned to zero
Test / fmt (pull_request) Successful in 4s
Test / test (pull_request) Successful in 4m13s

Port the July 7 gate-extender branch onto current master (the You-hub,
touch action bar, glass tab bar, Phase L, and hint-ghost work all landed
since) and finish batch 3. cluster_app now includes the mode, replay,
input, radial, tooltip, cursor, touch-selection, and safe-area plugins on
top of batches 1-2; the 585 ambiguous pairs the expansion exposed are
annotated down to zero and the gate stays assert_eq!(count, 0).

New ordering machinery:
- ReplayPlayback: playback driver chain on the pre-mutation spine
  (PointerInput < ReplayPlayback < overlay chain < GameMutation)
- ModeStart: mode-start handlers between the stats abandon-recorder and
  GameMutation; ChallengeCompletion < DailyCompletion < WeeklyGoalsEval
  pinned inside ProgressUpdate so `.after(ProgressUpdate)` readers see
  settled progress
- PointerInput: public set wrapping the input chain; AbandonRecord on the
  stats abandon-recorder; PendingHint around the async hint pipeline;
  HintGhostFx for the ghost chain (after the full visual spine)
- Clubs: MoveRequestWriters, WarningToastWriters join the existing
  request/toast writer clubs; UiTextFx grows the overlay/tooltip/safe-area
  chrome painters; SettingsAccess grows the lag-tolerant settings readers

Gate: cargo test --workspace green (993 engine tests), clippy
--all-targets -D warnings clean, rustfmt applied.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-07-16 17:42:46 -07:00
parent 099b7a263f
commit 838342649c
37 changed files with 1155 additions and 174 deletions
+60 -14
View File
@@ -464,25 +464,71 @@ impl Plugin for ReplayOverlayPlugin {
Update,
(
react_to_state_change,
update_banner_label,
update_progress_text,
update_floating_progress_chip,
update_scrub_fill,
update_move_log_header,
update_move_log_active_row,
update_move_log_prev_rows,
update_move_log_next_rows,
update_mini_tableau_foundations,
update_mini_tableau_stock_waste,
update_pause_button_label,
// Marker-filtered Text/Node repaints — each owns one
// disjoint overlay marker, so they join the UiTextFx
// club alongside the HUD text painters (#143).
update_banner_label
.in_set(crate::ui_theme::UiTextFx)
.ambiguous_with(crate::ui_theme::UiTextFx),
update_progress_text
.in_set(crate::ui_theme::UiTextFx)
.ambiguous_with(crate::ui_theme::UiTextFx),
update_floating_progress_chip
.in_set(crate::ui_theme::UiTextFx)
.ambiguous_with(crate::ui_theme::UiTextFx),
update_scrub_fill
.in_set(crate::ui_theme::UiTextFx)
.ambiguous_with(crate::ui_theme::UiTextFx),
update_move_log_header
.in_set(crate::ui_theme::UiTextFx)
.ambiguous_with(crate::ui_theme::UiTextFx),
update_move_log_active_row
.in_set(crate::ui_theme::UiTextFx)
.ambiguous_with(crate::ui_theme::UiTextFx),
update_move_log_prev_rows
.in_set(crate::ui_theme::UiTextFx)
.ambiguous_with(crate::ui_theme::UiTextFx),
update_move_log_next_rows
.in_set(crate::ui_theme::UiTextFx)
.ambiguous_with(crate::ui_theme::UiTextFx),
update_mini_tableau_foundations
.in_set(crate::ui_theme::UiTextFx)
.ambiguous_with(crate::ui_theme::UiTextFx),
update_mini_tableau_stock_waste
.in_set(crate::ui_theme::UiTextFx)
.ambiguous_with(crate::ui_theme::UiTextFx),
update_pause_button_label
.in_set(crate::ui_theme::UiTextFx)
.ambiguous_with(crate::ui_theme::UiTextFx),
handle_pause_button,
handle_step_button,
// Step/scrub dispatch into the shared move/draw/undo
// request streams (drained wholesale at GameMutation),
// so they join the writer clubs (#143).
handle_step_button
.in_set(crate::game_plugin::MoveRequestWriters)
.ambiguous_with(crate::game_plugin::MoveRequestWriters)
.in_set(crate::game_plugin::DrawRequestWriters)
.ambiguous_with(crate::game_plugin::DrawRequestWriters),
handle_pause_keyboard,
handle_stop_keyboard,
handle_arrow_keyboard,
handle_arrow_keyboard
.in_set(crate::game_plugin::MoveRequestWriters)
.ambiguous_with(crate::game_plugin::MoveRequestWriters)
.in_set(crate::game_plugin::UndoRequestWriters)
.ambiguous_with(crate::game_plugin::UndoRequestWriters)
.in_set(crate::game_plugin::DrawRequestWriters)
.ambiguous_with(crate::game_plugin::DrawRequestWriters),
handle_stop_button,
)
.chain(),
.chain()
// After the playback driver so painters render the
// post-tick state; before GameMutation so the step /
// scrub events are consumed this frame. Click handlers
// writing ReplayPlaybackState stay at the end of the
// chain — a press is observed by react_to_state_change
// next frame (state-driven loop, see above) (#143).
.after(crate::replay_playback::ReplayPlayback)
.before(crate::game_plugin::GameMutation),
);
}
}