feat(lbm-agent): the reconciler — display changes and engine hooking as one state machine - #623
Merged
Merged
Conversation
…hine What the C# UI decided in DisplayChangeCoordinator, EngineController and MainService's daemon-event routing — when a display change rebuilds the layout, when the engine is hooked, how a wake is re-hooked — as one state machine without I/O: inputs in, effects out, timers as effects that come back as inputs, the layout read and rebuilt through a trait. One input is handled at a time and a Start carries no zones (the runtime computes them when it sends), so the stale Start of #607 cannot exist, and #609's request gate is not needed. #609's other half is kept: a fresh layout the user turned off sends Stop. One Start per event: a Start just sent is given one step before the resume watchdog re-asserts it (C# sends it twice). The C# tests of both classes are the specification: 29 ported one to one on a virtual clock, plus the hook routing and focus reports. docs/v6-agent.md records the design and the deviations. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Sep 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 3 of the v6 plan (
docs/v6-architecture-plan.mdonv6): the heart oflbm-agent, the reconciler — what the C# UI decided inDisplayChangeCoordinator,EngineControllerandMainService's daemon-event routing, as one state machine without I/O. The design and its deviations are written down indocs/v6-agent.md(French, like the plan).Shape
Inputin (a display change, a hook event, the user's Start/Stop/Refresh, a timer coming back),Effects out in order (Start, Stop, SaveEnabled, SaveLayout, a timer, a process seen). The layout is read and rebuilt through aWorldtrait.Effect::Startcarries no zones: the runtime computes them from the current layout when it sends. The stale Start of Cursor gets trapped at screen edges after disconnecting and waking from sleep #607 cannot exist, and fix: never hook a layout the desktop no longer matches (#607) #609'sLatestRequestGateis not needed here.Rules (from C#), and the deviations
The C# rules are kept: 300 ms debounce with generations, settle loop (100 ms, 8 steps), idempotence guard that re-hooks instead of rebuilding (#412), Refresh past the guard (#443), user Start/Stop recorded before (un)hooking, foreign layouts simulated never adopted, no re-hook while asleep / against the user / over a running engine / while the watchdog drives, the post-resume watchdog (500 ms steps, 3 stable, 6 restarts, 60 steps), and the "Stopped right after Connected" hand-over.
Deliberate deviations, documented:
Tests
lbm-agent/tests/reconcile.rs: the 10DisplayChangeCoordinatorTestsand 19EngineControllerTests, one Rust test per C# test, plus the hook routing. Where the C# test counted calls into its neighbour in isolation, the integrated Rust test checks what the call does, and says so.Not wired to anything yet: the runtime (hook connection with
--fake-hook, supervision per D5, Linux sources, persistence) comes next.🤖 Generated with Claude Code