feat(moments): rules mount on moments, through every rule door (milestone 458 step 3, #4921)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 54s
CI & Build / integration (push) Successful in 1m0s
CI & Build / Python tests (push) Successful in 1m51s
CI & Build / Build & push image (push) Successful in 29s

rule_moments (migration 0117) records which moments a rule arrives at, by
catalog name, cascading with the rule. rule_detail, the one seam every
rule door already returns through, gains moments beside system_ids: None
leaves the mounts alone, a list replaces them. get_rule and both
list_rules doors read them back, batched per page.

All five MCP rule/preference writes and the three REST ones take moments
and validate them before their create or update. An unknown name is
refused with the catalog listed and leaves no half-made rule behind; a
parity test pins that ordering on every door.

Backup v22 carries the mounts as a join table remapped through the rule
map; a real-Postgres round trip checks they land on the restored rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-05 11:03:51 -04:00
co-authored by Claude Opus 5.5
parent cf3de5bae1
commit cc26054437
13 changed files with 560 additions and 26 deletions
+1 -1
View File
@@ -315,7 +315,7 @@ def plain_rule_detail():
stubbing the seam slightly differently is a test asserting something
slightly different than it appears to.
"""
async def _detail(_uid, rule, _system_ids=None):
async def _detail(_uid, rule, _system_ids=None, _moments=None):
return rule.to_dict()
return patch("scribe.mcp.tools.rulebooks.rulebooks_svc.rule_detail", _detail)