diff --git a/src/scribe/mcp/tools/rulebooks.py b/src/scribe/mcp/tools/rulebooks.py index 43bd216..ee5da8e 100644 --- a/src/scribe/mcp/tools/rulebooks.py +++ b/src/scribe/mcp/tools/rulebooks.py @@ -297,6 +297,13 @@ async def create_rule( rulebook+topic ceremony). If it's a standard a CATEGORY of projects shares, put it in a themed subscribed rulebook, not the always-on one. + Write it general WITHOUT hedging for the exceptions. A project that needs + to strengthen, narrow or replace this rule writes its own and links it + with relate_rules(kind="overrides"), and one that adds local specifics + uses "elaborates" — so the general form does not have to anticipate every + project it will ever reach. A rulebook rule padded with "unless…" clauses + for two projects is two project rules that were never written. + Before writing a rule at all, check whether another entity already models the thing. A rule is prose an agent must remember and apply; the others are structure a tool can resolve, render and check. Visual standards are a @@ -412,12 +419,36 @@ async def create_project_rule( title: Short imperative title. If empty, derived from the first ~50 characters of statement. when_to_apply: WHEN this rule fires — the trigger, not the - instruction. See create_rule; it decides the tier and it is how - the rule is found at the moment it matters. - tier: "always_on" (default) or "conditional" — see create_rule. + instruction, and the rule's retrieval surface: name the SYMPTOM, + the words someone would type while stuck. See create_rule for the + full argument. It informs the tier below rather than deciding it, + since a project rule's tier turns on area-scope, not on whether + the trigger can be named. + tier: "always_on" (default) or "conditional". The SAME two values as + create_rule, judged against a different cost — do not import that + tool's test wholesale. There, always_on means every session in + every project, so the bar is high: the trigger must be nameless + ("whenever you are working"). Here the rule is already scoped to + one project by construction, so always_on costs only that + project's sessions and the bar is correspondingly lower. A + project rule that names something specific is still ordinarily + always_on — being specific is what project rules are FOR. + Reach for conditional when the rule is about one AREA of a large + project — a CI quirk, a migration gotcha, one subsystem's + convention — so it arrives with that area instead of resident in + every session. The failure to avoid is local: forty always-on + rules on one project reproduces, inside that project, exactly the + preload bloat that made every rule compete for the same budget. system_ids: Ids from list_canonical_systems — the global AREAS this - rule is about. - arose_from_id: The note or task that CAUSED this rule. + rule is about. Worth setting even on a project rule: it is what + lets a conditional one surface when the project is working in + that area. + arose_from_id: The note or task that CAUSED this rule. Reach for it + harder here than on a rulebook rule — a project rule usually + comes from one traceable incident in this repo, where a family + rule is more often a standing preference with no single origin. + The link is what lets a later reader judge whether the incident + still describes the project. why: Optional rationale — the reason the rule exists. how_to_apply: Optional operationalization — when / where it kicks in. verify_with: How to check this rule is still true — see create_rule.