-
released this
2026-06-01 08:11:45 -04:00 | 109 commits to main since this releaseRules subsystem matures from "additive cross-project rulebooks only" into a full first-class system: always-on rulebooks, project-scoped rules, an active-project handshake, and per-project suppression of inherited rules. Two PRs since v26.06.01.1.
PR #53 — Rules consolidation (4 slices)
Problem. Rules in Scribe were pull-only; CLAUDE.md and
~/.claude/.../memory/feedback_*.mdwere session-start auto-loaded. The MCP prompt never insisted that Claude fetch Scribe rules eagerly or codify new rules in Scribe rather than the competing stores. Result: Scribe rules silently lost.-
S1 + S2 —
always_onrulebook flag (commit658348f)- Migration 0058:
rulebooks.always_onboolean. FabledSword family rulebook seededalways_on=trueat migrate-time. - New MCP tool
list_always_on_rules()returns the union of standing rules for the user in one round-trip, no active-project needed. _INSTRUCTIONSrewritten: at session start, calllist_always_on_rules; treat as binding. Rules codified in Scribe viacreate_rule, never in CLAUDE.md or feedback files. Those stores are now scoped to user-facts and codebase onboarding respectively.- Frontend: badge on always-on rulebooks in
RulebookListPane; toggle inRulebookDetailPaneheader.
- Migration 0058:
-
S3 — Project-scoped rules (commit
43a860c)- Migration 0059:
rules.project_id(nullable FK, CASCADE),rules.topic_idmade nullable, CHECKck_rule_topic_xor_projectenforces exactly-one. - New MCP tool
create_project_rule(project_id, statement, title?, why?, how_to_apply?)— no rulebook ceremony for project-only rules. get_applicable_rulesadds aproject_rulesfield surfaced throughget_project,get_task(plan),start_planning.- Trash cascade: deleting a project soft-deletes its project-scoped rules along with the rest.
- REST:
POST /api/projects/<id>/rules; frontend Rules-tab gains a "Project rules" section with inline create form.
- Migration 0059:
-
S4 —
enter_projecthandshake (commitc546921)- New MCP tool
enter_project(project_id)composesget_project+get_applicable_rules+ milestone-summary + open-tasks + recent-notes into one round-trip. Intended for once-per-session use when work is project-scoped. _INSTRUCTIONSdirects Claude to call it before any project-scoped mutation.- No schema change; pure composition over existing services.
- New MCP tool
PR #54 — Project rule + topic suppressions (commit
7861607)Lets a project mute individual rules or whole topics from rulebooks it subscribes to, without unsubscribing the rulebook. Use case: subscribe to a broad rulebook (e.g. a future "FabledSword design system") but opt out of one or two rules — or a whole topic — that doesn't apply to a non-frontend project.
- Schema (migration 0060): two new pure m2m association tables —
project_rule_suppressionsandproject_topic_suppressions. PKs on both columns; FKs CASCADE. Nodeleted_at— pure associations, hard-deleted on project trash. - MCP tools (4):
suppress_rule_for_project,unsuppress_rule_for_project,suppress_topic_for_project,unsuppress_topic_for_project. All idempotent; verify project + rule/topic ownership. Project-scoped rules (Rule.project_id) are deliberately not suppressible — delete them instead. - REST:
POST/DELETE /api/projects/<pid>/suppressions/{rules,topics}/<id>. - Service projection:
get_applicable_rulesruns two extra queries and emitssuppressed_rules+suppressed_topicsas detail objects (id + title + rulebook context, not bare IDs — so the UI doesn't need a follow-up lookup). The mainruleslist is filtered SQL-side sotruncatedreflects post-suppression count. Rules now carrytopic_id+rulebook_idcolumns for the UI affordance. - Propagation:
suppressed_rulesandsuppressed_topicssurface throughget_project,enter_project,get_task(plan), andstart_planning— Claude sees what's muted from any standard handshake. - Frontend: "× skip" affordance reveals on hover for each rule row and each topic header in
ProjectRulesTab.vue; collapsed "Suppressed (N)" section at the bottom with per-item "↻ re-enable" buttons.groupByRulebookAndTopicrefactored to id-bearing structs. - Trash cascade: project deletion hard-deletes the project's suppression rows so a later restore starts fresh.
Migrations
- 0058 —
rulebooks.always_onboolean, default false; seeds FabledSword family to true. - 0059 —
rules.project_id(FK CASCADE),rules.topic_idnullable, CHECKck_rule_topic_xor_project. Down-migration requires migrating/deleting project-scoped rules first. - 0060 —
project_rule_suppressionsandproject_topic_suppressionsassociation tables.
All three run automatically on first boot.
Verification
- CI green on
c546921(S4 — after rebuild; original run flaked on npm-cache action),43a860c(S3),658348f(S1+S2), and7861607(suppressions). - Migrations 0058/0059/0060 applied cleanly to the dev environment; operator confirmed the suppression UI and MCP tools work end-to-end on dev (
migration in dev worked, 2026-06-01). - Tests cover:
list_always_on_rules,update_rulebook(always_on=…),create_project_rule(required-fields + title-derivation + explicit-title),enter_projectcomposed shape + 404,get_applicable_ruleswith project_rules + suppressed_rules + suppressed_topics, project-cascade trash hitting 7 tables (was 4 before S3, 5 after S3, 7 with this release).
Deploy notes
- Three migrations run automatically on container start.
- After deploy, MCP reconnects pick up the new
_INSTRUCTIONS; on the next project-scoped turn Claude should calllist_always_on_rulesandenter_project. Eyeball the tool-call transcript on first use. - No content migration: rule-shaped entries in CLAUDE.md and feedback memory files stay where they are. The prompt reroutes NEW rules to Scribe going forward.
What this release does NOT do
- No supersede semantics — a project rule can't yet replace a rulebook rule for one project (only mute it). Pure suppression covers the stated use case; replacement can land later.
- No write-scope enforcement on bearer tokens — mutating tools still ignore the read/write scope on
api_keys. M1 work, tracked separately. - No share-aware filtering on
list_trash/restore/purge— same M1 carve-out.
Downloads
-