refactor(mcp): one rules_payload() for every surface that hands rules to an agent; drop the dead bearer resolver (#2828, milestone 296 area 4)
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Successful in 9s
CI & Build / integration (push) Successful in 24s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / Python tests (push) Successful in 56s
CI & Build / Build & push image (push) Successful in 26s

Reading the 16 tool modules against each other: the six-key applicable-rules
block (applicable_rules, applicable_rules_truncated, subscribed_rulebooks,
project_rules, suppressed_rules, suppressed_topics) was hand-built in five
places — enter_project, get_project, get_task (legacy plans), get_milestone
(three of the six) and services/planning.start_planning. rulebooks_svc.
rules_payload() is now the one place that names them; get_milestone gains the
three it lacked, so every rules-carrying payload reads the same. list_rules /
list_always_on_rules share _rule_summary. mcp/auth.resolve_bearer_to_user_id
duplicated resolve_bearer's parsing and had no product caller (only its own
tests) — removed; the tests now exercise resolve_bearer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 11:20:36 -04:00
co-authored by Claude Fable 5
parent b0eda32575
commit c211e12b61
8 changed files with 45 additions and 72 deletions
+2 -12
View File
@@ -192,12 +192,7 @@ async def enter_project(project_id: int) -> dict:
],
"design_system": design_system,
"milestone_summary": milestone_summary,
"applicable_rules": applicable["rules"],
"project_rules": applicable.get("project_rules", []),
"suppressed_rules": applicable.get("suppressed_rules", []),
"suppressed_topics": applicable.get("suppressed_topics", []),
"subscribed_rulebooks": applicable["subscribed_rulebooks"],
"applicable_rules_truncated": applicable["truncated"],
**rulebooks_svc.rules_payload(applicable),
"open_tasks": [
{
"id": t.id, "title": t.title, "status": t.status,
@@ -239,12 +234,7 @@ async def get_project(project_id: int) -> dict:
applicable = await rulebooks_svc.get_applicable_rules(
project_id=project_id, user_id=uid,
)
data["applicable_rules"] = applicable["rules"]
data["applicable_rules_truncated"] = applicable["truncated"]
data["subscribed_rulebooks"] = applicable["subscribed_rulebooks"]
data["project_rules"] = applicable.get("project_rules", [])
data["suppressed_rules"] = applicable.get("suppressed_rules", [])
data["suppressed_topics"] = applicable.get("suppressed_topics", [])
data.update(rulebooks_svc.rules_payload(applicable))
return data