Rules consolidation: Scribe-first check, project-scoped rules, enter_project handshake #53
Reference in New Issue
Block a user
Delete Branch "dev"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implements plan-task #508. Three commits, four slices, all aimed at making Scribe the source of truth for engineering rules while preserving the existing CLAUDE.md / auto-memory stores.
What changed and why
Problem. Rules in Scribe were "pull-only" — Claude only saw them when it explicitly called
get_projectorlist_rules. Memory files + CLAUDE.md, by contrast, are session-start auto-loaded, so they always won the "which rules did I read" contest. The MCP_INSTRUCTIONSalso never directed Claude to land NEW rules in Scribe, so they accumulated in~/.claude/.../memory/andCLAUDE.mdby default. Operator-confirmed direction: coexistence now, Scribe-first check, migrate later. No destructive consolidation.Slices
S1 + S2 —
always_onrulebook flag (commit658348f)rulebooks.always_onboolean. FabledSword family seededalways_on=trueat migrate-time.list_always_on_rules()returns the union of all rules from always-on rulebooks for the user — a single round-trip that doesn't require an active-project context._INSTRUCTIONSupdated: "At session start, calllist_always_on_rules; treat the result as binding." Also adds creation-routing: rules belong in Scribe viacreate_rule, not in CLAUDE.md or memory feedback files; those stores are now scoped to user-facts and codebase onboarding respectively.RulebookListPane; toggle inRulebookDetailPaneheader.S3 — Project-scoped rules (commit
43a860c)rules.project_id(nullable FK, CASCADE),rules.topic_idmade nullable, CHECK constraint enforces exactly-one of (topic_id,project_id), index onproject_id.create_project_rule(project_id, statement, title?, why?, how_to_apply?). No rulebook ceremony — bypasses the Rulebook → Topic → Rule chain when a rule only applies to one project.get_applicable_rulesadds aproject_rulesfield alongside the existingrules;get_project,get_task(for plan-tasks), andstart_planningall surface it.POST /api/projects/<id>/rulespowers the frontend fast path.ProjectRulesTab.vuegains a "Project rules" section with an inline create form (title optional, statement required, why/how_to_apply optional), per-rule expand-on-click, and a Delete control.get_rule/update_rule/delete_rulenow route through a shared_fetch_owned_rulehelper that handles both ownership paths (rulebook-via-topic OR project-via-project_id).S4 —
enter_projecthandshake (commitc546921)enter_project(project_id)composesget_project+get_applicable_rules+get_project_milestone_summary+ open-tasks + recent-notes into one round-trip. Intended to be called once at session start (or when the active project changes), in lieu of stitching those calls together separately._INSTRUCTIONSdirects Claude to call it before project-scoped work begins.Migrations
rulebooks.always_onboolean, default false. Seeds FabledSword family to true.rules.project_idadded (FK CASCADE),rules.topic_idmade nullable, CHECKck_rule_topic_xor_project. Both run automatically on first boot of the new image. Down-migrations exist but the 0059 down requires you to migrate or delete project-scoped rules first (it re-tightenstopic_id).Verification
c546921(typecheck / lint / Python tests / image build).list_always_on_rules,update_rulebook(always_on=...)pass-through,create_project_rulefield handling + title derivation,enter_projectcomposed shape + 404 handling,get_applicable_rulesreturningproject_rules, project-delete trash cascade now hitting 5 tables (was 4).project_rulesquery inget_applicable_rules) or where call counts changed (the project cascade in trash service).What this does NOT do
~/.claude/.../memory/feedback_*.mdandCLAUDE.mdstay where they are; the prompt change reroutes NEW rules to Scribe, but existing entries are not migrated. Cleanup pass is a separate exercise.list_trash/restore/purge. Same M1 carve-out as before.Deploy notes
_INSTRUCTIONS; Claude should calllist_always_on_rulesandenter_projecton session start. Eyeball the tool-call transcript on first use to confirm.enter_projectreturns the composed payload; create a project rule via the new tab; flip a rulebook'salways_onfrom the UI; verifylist_always_on_rulesincludes/excludes accordingly. After that's solid, cut the release tag.🤖 Generated with Claude Code