mirror of
https://github.com/ruvnet/RuView
synced 2026-07-29 18:31:44 +00:00
fix(homecore-automation): start engine + implement time/run-mode/choose/template (ADR-161 A3-A7)
A3 (HIGH): homecore-server constructed AutomationEngine then dropped it immediately while the doc claimed automation was active. Now .start()s the engine into a long-lived binding (event loop + timer task). A4 (HIGH): Trigger::Time was hard-coded false with no timer. Added a 1 Hz wall-clock timer task that fires time: automations when local HH:MM:SS matches 'at' (HH:MM or HH:MM:SS); matches_sync(Time)=false is now correct + documented. A5 (HIGH): RunMode was documented as AtomicBool-enforced but every trigger spawned unbounded parallel. Each automation now carries a running AtomicBool; Single/IgnoreFirst skip re-entrant triggers, Parallel fires every time. (Bounded Queued/Restart/max → ACCEPTED-FUTURE, honestly stated in the doc.) A6 (HIGH): Action::Choose discarded choices and always ran default. Now deserialises each branch's conditions, evaluates them, and runs the first matching branch; default only if none match. A7 (MEDIUM): template: conditions were always false in the engine path (EvalContext built with template_env: None). The engine now builds a TemplateEnvironment over the state machine and threads it into every EvalContext (event loop, timer, Choose). Tests (fail on old source): - engine_behaviors::time_trigger_fires_via_timer_path (A4) - engine_behaviors::single_mode_does_not_double_fire_on_rapid_triggers (A5; old fired 2x) - engine_behaviors::parallel_mode_does_fire_concurrently (A5) - action::choose_runs_matching_branch_not_default (A6; old ran default) - engine_behaviors::template_condition_evaluates_true_in_engine (A7; old always false) engine.rs kept <500 lines; behavioral tests moved to tests/engine_behaviors.rs. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -121,8 +121,21 @@ async fn main() -> Result<()> {
|
||||
let _ = plugin_registry; // wired-but-empty at boot; integrations register here
|
||||
|
||||
// ── 4. Automation engine ────────────────────────────────────────
|
||||
let _automation_engine = AutomationEngine::new(hc.clone());
|
||||
info!("Automation engine ready (no automations loaded yet)");
|
||||
// Construct AND start the engine (HC-WS-03, ADR-161). `start()`
|
||||
// spawns the state-change event loop + the 1 Hz wall-clock timer
|
||||
// task so state/numeric/event AND time triggers all fire. The
|
||||
// engine is kept alive for the process lifetime (it is moved into a
|
||||
// long-lived binding); its background tasks run until the HomeCore
|
||||
// broadcast channel closes at shutdown. No automations are loaded at
|
||||
// boot yet (YAML loader is P-next); integrations register via
|
||||
// `engine.register(..)`.
|
||||
let automation_engine = AutomationEngine::new(hc.clone());
|
||||
let _automation_task = automation_engine.start();
|
||||
info!(
|
||||
"Automation engine started ({} automations registered) — \
|
||||
state/numeric/event + time triggers active",
|
||||
automation_engine.len()
|
||||
);
|
||||
|
||||
// ── 5. Assist pipeline ──────────────────────────────────────────
|
||||
let recognizer = RegexIntentRecognizer::new();
|
||||
|
||||
Reference in New Issue
Block a user