feat(ttp): E.3.5 FilesystemRuleStore — inotify hot-reload + per-rule events
Implements the filesystem-backed rule store body left empty at contract phase: YAML parse + Pydantic validation, asyncinotify watch over ./rules/ttp/, in-process state cache with auto-revert on expires_at, and a subscribe_changes() async iterator yielding one RuleChange per per-rule edit. Bus topic builders ttp_rule_reloaded / ttp_rule_state ship alongside. Why: the rule plane needed a store before the engine (E.3.7) could consume RuleChange events and atomically swap compiled rules into its dispatch index. Notes: - Linux-only by construction (asyncinotify wheel gated by sys_platform marker; FilesystemRuleStore.__init__ raises on non-Linux). - Filename allowlist is the FIRST check on every inotify event. - Content-hash dedup so a single write firing IN_CREATE + IN_CLOSE_WRITE produces exactly one RuleChange. - All compile work serializes on a single asyncio.Lock. - Subscribers register their queue eagerly so events fired between subscribe_changes() and the first __anext__() are buffered. xfails flipped: per-save-style + filter-ordering + atomic-swap in test_filesystem.py; load_compiled / set_state isolation / round-trip / per-rule fan-out / expired-state revert / set_state failure semantics in test_conformance.py (FS side; DB side stays xfail until E.3.6); malformed-YAML compile-time check in test_rule_engine.py. Tests: 197 passed, 35 xfailed (gated on E.3.6 / E.3.7 / lifters). mypy + bandit: clean on all touched files. Wiki update for the per-rule reload + state-change topics lands in a matching wiki-checkout/Service-Bus.md edit (separate repo).
This commit is contained in:
@@ -2933,7 +2933,13 @@ Order:
|
||||
Pydantic validation, inotify watch, in-process state cache,
|
||||
`subscribe_changes()` async iterator yielding per-rule events.
|
||||
Test bus-event fan-out under a 5-file edit produces exactly 5
|
||||
events. `test_*.py` for the filesystem backend green.
|
||||
events. `test_*.py` for the filesystem backend green. ✅ done.
|
||||
`asyncinotify` added to runtime deps (Linux-only marker). Bus
|
||||
topic builders `ttp_rule_reloaded(rule_id)` and
|
||||
`ttp_rule_state(rule_id)` shipped alongside the store. Content-hash
|
||||
dedup in the inotify handler so a single write firing
|
||||
`IN_CREATE` + `IN_CLOSE_WRITE` produces exactly one
|
||||
`RuleChange`.
|
||||
6. **RuleStore — DatabaseRuleStore** — implement DB-backed
|
||||
variant. `ttp_rule` and `ttp_rule_state` tables created via
|
||||
SQLModel. Master-side filesystem→DB sync. Worker-side DB
|
||||
|
||||
Reference in New Issue
Block a user