Mock mode faked assistant chat but left Patrol on the real provider
path. The public demo therefore ran real patrol cycles that failed with
"no patrol model configured", raised the Provider analysis error
finding, and rendered /patrol as an unconfigured setup surface with no
findings, which also cost the landing page its Patrol screenshot.
Demo mode now simulates the whole surface without ever contacting a
provider:
- runDemoPatrolCycle synthesizes findings from the live mock state
(offline Docker edge host, degraded PBS and PMG, unhealthy or
restart-looping containers, the fullest storage pool, the hungriest
guest), quoting each resource's actual observed values so the patrol
page stays consistent with the rest of the demo UI. Cycles refresh
findings as heartbeats, auto-resolve ones whose mock condition
cleared, and append matching run records plus a one-time backfilled
history.
- Readiness, the API readiness checks, and the model-check preflight
report a simulated pass under a "demo" provider identity, and the
stale provider-error finding is auto-resolved.
- Release demo ordering is handled: mock fixtures only enable after the
demo_fixtures license sync, so the patrol loop now starts for
demo-intended runtimes (PULSE_MOCK_MODE requested in env) and every
entry point re-checks IsDemoMode() live. Dev installs with the
background-AI guard get a warmup goroutine instead of the scheduler.
- Run-history evidence filtering is now symmetric (demo runtimes hide
real records, matching the existing inverse), scoped/targeted patrol
runs are skipped in demo mode, and demo findings are excluded from
ai_findings.json so fixtures never leak into a real install.