Commit 9e9bd26
* Add issue 742 path merge analysis
* fix(#742): reject reservation of physically impossible switch routes
Trace capture from failing RuleBasedDispatcherDeterminismTest runs showed
the remaining ~40% failures were NOT the suspected mergePathInfo fork-overlap
corruption (all 250 observed merges were clean continuations). The real
defect: when a train's through-exit was momentarily blocked,
findNextReservationTarget offered the sibling parallel branch's semaphore
(e.g. doB1→doB2), reservePath reserved it, and configureSwitchesInPath
swallowed the FATAL PathSeparatorChangeException ("switch doesn't join this
segments") — returning Success for a route no configuration of switch vB can
join. The train committed to an untraversable route, isPathExtendedBeyond
then suppressed the corrective decision forever, and the network gridlocked
(trainsExited 1 instead of 5).
Fix (railway-conservative, service layer only):
- configureSwitchesInPath returns Boolean: a genuinely traversed switch
(both segments known) that no configuration joins now fails the candidate;
null-segment cases keep the historical lenient skip (Issue #300)
- configureAndRegisterSwitches orders configuration BEFORE registerSwitches
- rollbackUnconfigurableCandidate undoes only the candidate's blocks and
newly locked switches — the train's pre-existing path state survives, so
it simply waits and reserves the through route at a future simulation time
- registerPathInfo moved AFTER switch+signal configuration so no rollback
can leave a poisoned PathInfo
Circular-route merging is untouched: mergePathInfo/addElementWithCycleDetection
unchanged; Issue316RegressionTest and PathReservationRegistryMergingTest pass
unchanged.
New Issue742RegressionTest (@timeout): impossible diversion rejected without
leaking blocks/locks/PathInfo (failed pre-fix), wait-then-extend partial-path
semantics, legitimate parallel alternate zB→doA2 still succeeds.
Determinism evidence on the dev machine: pre-fix 55/100 failed repetitions
(0/10 suites green); post-fix 8/210 failed repetitions, all matching the
pre-existing headless driver-pacing race (trainsExited=0 occurred 22×/100
pre-fix too) — that residue is AgentLoopDriver pacing, tracked separately.
Closes #742
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(SP0.11): green-up clean build integrationTest — KMP break, dispatcher wiring, pacing tests
Four SP0.11 (thin ShuntingLoop shell, #733) regressions fixed; none were
covered by CI because this branch's workflow run was never approved
(goal-10's last green CI is SP0.10).
1. KMP metadata compile break: ShuntingLoop.startAction used JVM-only
Thread/runBlocking in commonMain. New expect/actual
platformStartDaemonThread (util/PlatformThread.kt): JVM = daemon Thread +
runBlocking; native (linuxX64) = CoroutineScope(newSingleThreadContext).
Local gemma4 review suggested kotlin.concurrent.thread(isDaemon=true) —
rejected: that API is JVM-only, does not exist on Kotlin/Native.
2. Zero-train runs everywhere the async :dispatcher-agent stack isn't wired:
SP0.11 removed inline admission/reservation policy but only desktop-ui's
ExampleRegistry got the replacement wiring. New
sim/SynchronousDispatcherWiring.wireSynchronousDispatcher(env, loop) —
production RuleBasedDispatcher + core ports, deciding and applying
synchronously on the sim thread each iteration (pre-SP0.11 semantics;
deterministic by construction, immune to the PR #740/#742 async races).
Used by :fast-sim production (Main, NativeExampleRegistry — fixes 7
native integration tests + JVM/native parity) and by the bare-ShuntingLoop
test suites (JvmParity, ShuntingLoopRegression, TrainReporter, Metrics,
TrainCoverage, KoinGoldenOutput, SimulationSpeedGolden). Golden baselines
pass unchanged — the synchronous wiring reproduces pre-SP0.11 outputs.
3. AgentLoopDriverTest pacing tests updated to the SP0.11 stagnant-snapshot
contract runCycle gained (skip decide/throttle on a re-read of the same
sim tick, pause still honoured): multi-cycle test now advances simTime per
cycle; zero-delta test replaced by stagnantSimTimeSkipsCycle pinning the
skip behaviour (no re-decide — that re-decide was the #740 race source).
4. RuleBasedDispatcherDeterminismTest flaked (~1 in 3 suite runs) because the
free-running driver thread races the unthrottled headless sim — admission
timing drifted with OS scheduling. The Goal 10 A3 gate asserts determinism
of the DISPATCHER, so executeRun now runs a lock-step handshake: the sim
thread grants the driver exactly one cycle per tick and drains its
decisions in the same tick, all on production components. 5 consecutive
suite runs green (50/50 repetitions).
Verified: ./gradlew clean build integrationTest --no-build-cache
(122 tasks, 120 executed) BUILD SUCCESSFUL — includes :core jvm+native
tests, :core purity gate, :desktop-ui, :dispatcher-agent, :fast-sim
linuxX64 tests, detekt, ktlint.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(docker): copy dispatcher-agent build script and sources into image
settings.gradle.kts includes :dispatcher-agent, but the Dockerfile's
layered COPY steps never picked it up alongside core/core-test/desktop-ui.
Gradle saw an included project with no build script or sources, giving it
zero variants and breaking desktop-ui's runtimeClasspath resolution
("Could not resolve project :dispatcher-agent ... No variants exist.").
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---------
Co-authored-by: Bedrich Hovorka <bedrich.hovorka@gmail.com>
1 parent ffeb40c commit 9e9bd26
20 files changed
Lines changed: 978 additions & 66 deletions
File tree
- core/src
- commonMain/kotlin/cz/vutbr/fit/interlockSim
- sim
- util
- jvmMain/kotlin/cz/vutbr/fit/interlockSim/util
- jvmTest/kotlin/cz/vutbr/fit/interlockSim
- sim
- metrics
- nativeMain/kotlin/cz/vutbr/fit/interlockSim/util
- desktop-ui/src/test/kotlin/cz/vutbr/fit/interlockSim
- di
- gui
- dispatcher-agent/src/test/kotlin/cz/vutbr/fit/interlockSim/dispatcher
- docs/analysis
- fast-sim/src/linuxX64Main/kotlin/cz/vutbr/fit/interlockSim/fastsim
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
| 73 | + | |
73 | 74 | | |
74 | 75 | | |
75 | 76 | | |
| |||
97 | 98 | | |
98 | 99 | | |
99 | 100 | | |
| 101 | + | |
100 | 102 | | |
101 | 103 | | |
102 | 104 | | |
| |||
Lines changed: 153 additions & 41 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
267 | 267 | | |
268 | 268 | | |
269 | 269 | | |
270 | | - | |
271 | | - | |
272 | | - | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | | - | |
279 | | - | |
280 | | - | |
281 | | - | |
282 | | - | |
283 | | - | |
284 | | - | |
285 | | - | |
286 | | - | |
287 | | - | |
288 | | - | |
289 | | - | |
290 | | - | |
291 | | - | |
292 | | - | |
293 | | - | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
294 | 275 | | |
295 | 276 | | |
296 | 277 | | |
| |||
363 | 344 | | |
364 | 345 | | |
365 | 346 | | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
366 | 358 | | |
367 | 359 | | |
368 | 360 | | |
| |||
1580 | 1572 | | |
1581 | 1573 | | |
1582 | 1574 | | |
1583 | | - | |
| 1575 | + | |
| 1576 | + | |
| 1577 | + | |
1584 | 1578 | | |
1585 | | - | |
1586 | | - | |
1587 | | - | |
1588 | | - | |
| 1579 | + | |
| 1580 | + | |
| 1581 | + | |
| 1582 | + | |
| 1583 | + | |
| 1584 | + | |
| 1585 | + | |
| 1586 | + | |
| 1587 | + | |
1589 | 1588 | | |
1590 | 1589 | | |
1591 | 1590 | | |
1592 | | - | |
| 1591 | + | |
| 1592 | + | |
1593 | 1593 | | |
1594 | 1594 | | |
1595 | 1595 | | |
1596 | 1596 | | |
1597 | 1597 | | |
1598 | | - | |
| 1598 | + | |
1599 | 1599 | | |
1600 | 1600 | | |
1601 | 1601 | | |
| |||
1648 | 1648 | | |
1649 | 1649 | | |
1650 | 1650 | | |
1651 | | - | |
1652 | | - | |
1653 | | - | |
| 1651 | + | |
| 1652 | + | |
| 1653 | + | |
| 1654 | + | |
| 1655 | + | |
| 1656 | + | |
| 1657 | + | |
| 1658 | + | |
| 1659 | + | |
| 1660 | + | |
| 1661 | + | |
1654 | 1662 | | |
1655 | 1663 | | |
1656 | 1664 | | |
| |||
1671 | 1679 | | |
1672 | 1680 | | |
1673 | 1681 | | |
1674 | | - | |
1675 | | - | |
1676 | | - | |
1677 | | - | |
1678 | | - | |
1679 | | - | |
| 1682 | + | |
| 1683 | + | |
| 1684 | + | |
| 1685 | + | |
| 1686 | + | |
| 1687 | + | |
| 1688 | + | |
| 1689 | + | |
| 1690 | + | |
1680 | 1691 | | |
1681 | 1692 | | |
| 1693 | + | |
1682 | 1694 | | |
1683 | 1695 | | |
1684 | 1696 | | |
1685 | 1697 | | |
1686 | | - | |
| 1698 | + | |
| 1699 | + | |
| 1700 | + | |
| 1701 | + | |
1687 | 1702 | | |
1688 | 1703 | | |
1689 | 1704 | | |
| |||
1848 | 1863 | | |
1849 | 1864 | | |
1850 | 1865 | | |
| 1866 | + | |
| 1867 | + | |
| 1868 | + | |
| 1869 | + | |
| 1870 | + | |
| 1871 | + | |
| 1872 | + | |
| 1873 | + | |
| 1874 | + | |
| 1875 | + | |
| 1876 | + | |
| 1877 | + | |
| 1878 | + | |
| 1879 | + | |
| 1880 | + | |
| 1881 | + | |
| 1882 | + | |
| 1883 | + | |
| 1884 | + | |
| 1885 | + | |
| 1886 | + | |
| 1887 | + | |
| 1888 | + | |
| 1889 | + | |
| 1890 | + | |
| 1891 | + | |
| 1892 | + | |
| 1893 | + | |
| 1894 | + | |
| 1895 | + | |
| 1896 | + | |
| 1897 | + | |
| 1898 | + | |
| 1899 | + | |
| 1900 | + | |
| 1901 | + | |
| 1902 | + | |
| 1903 | + | |
| 1904 | + | |
| 1905 | + | |
| 1906 | + | |
| 1907 | + | |
| 1908 | + | |
| 1909 | + | |
| 1910 | + | |
| 1911 | + | |
| 1912 | + | |
| 1913 | + | |
| 1914 | + | |
| 1915 | + | |
| 1916 | + | |
| 1917 | + | |
| 1918 | + | |
| 1919 | + | |
| 1920 | + | |
| 1921 | + | |
| 1922 | + | |
| 1923 | + | |
| 1924 | + | |
| 1925 | + | |
| 1926 | + | |
| 1927 | + | |
| 1928 | + | |
| 1929 | + | |
| 1930 | + | |
| 1931 | + | |
| 1932 | + | |
| 1933 | + | |
| 1934 | + | |
| 1935 | + | |
| 1936 | + | |
| 1937 | + | |
| 1938 | + | |
| 1939 | + | |
| 1940 | + | |
| 1941 | + | |
| 1942 | + | |
| 1943 | + | |
| 1944 | + | |
| 1945 | + | |
| 1946 | + | |
| 1947 | + | |
| 1948 | + | |
| 1949 | + | |
| 1950 | + | |
| 1951 | + | |
| 1952 | + | |
| 1953 | + | |
| 1954 | + | |
| 1955 | + | |
| 1956 | + | |
| 1957 | + | |
| 1958 | + | |
| 1959 | + | |
| 1960 | + | |
| 1961 | + | |
| 1962 | + | |
1851 | 1963 | | |
1852 | 1964 | | |
1853 | 1965 | | |
| |||
Lines changed: 3 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
| 31 | + | |
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| |||
304 | 304 | | |
305 | 305 | | |
306 | 306 | | |
| 307 | + | |
307 | 308 | | |
308 | | - | |
309 | | - | |
310 | | - | |
311 | | - | |
| 309 | + | |
312 | 310 | | |
313 | 311 | | |
314 | 312 | | |
| |||
0 commit comments