Compare commits

...
2 Commits
Author SHA1 Message Date
bvandeusenandClaude Opus 5 8820551058 fix(394): unbreak collection, the TS typecheck and the plugin version
CI & Build / Plugin hooks (push) Successful in 7s
CI & Build / Python lint (push) Successful in 2s
CI & Build / integration (push) Failing after 39s
CI & Build / TypeScript typecheck (push) Successful in 52s
CI & Build / Python tests (push) Failing after 56s
CI & Build / Build & push image (push) Skipped
Five validators failed on 0e10f6b; these are the ones the logs named.

COLLECTION died first and hid everything else: test_inception.py still
imported project_rulebook_exclusions, so pytest aborted before running a
single test in either the unit or the integration lane. The migrations
therefore never ran, which means 0099 and 0100 are still unverified — this
push is what puts them in front of real Postgres.

The obsolete table test went with the import, and its module docstring now
says why rather than just describing one fewer thing.

TypeScript: RulebookDetailPane's currentRulebook computed existed only to
feed the always-on toggle, so removing the toggle left it unread; the vue
'computed' import went with it.

Plugin version minted — plugin content changed and the manifest gates the
executing cache (#2209), so the hook check fails until it moves.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cPyzNnegXHr5iRMzzy5KJ
2026-09-11 16:26:56 -04:00
bvandeusenandClaude Opus 5 4eebe271ed fix(rules): restore system_ids and clear the imports the deletions orphaned (#394)
Three defects from the sweep, all caught by ruff.

system_ids was REMOVED FROM create_rule AND create_project_rule — a real API
regression, not a lint nit. The parameter shared a signature line with tier,
so deleting the tier deleted it too, and the tools lost the ability to tag a
new rule to an area. Areas are what let a rule reach a project after this
milestone, so the one parameter that decides reach went missing from the two
tools that create reachable rules.

The other two are imports left holding nothing: services/rulebooks.py's
module-level datetime and its IntegrityError were used only by functions this
milestone deleted, and plugin_context lost four (select, async_session,
RulebookTopic, rulebooks_svc) with the preload and _topic_titles.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cPyzNnegXHr5iRMzzy5KJ
2026-09-11 16:24:38 -04:00
6 changed files with 11 additions and 26 deletions
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, computed, onMounted, watch } from "vue";
import { ref, onMounted, watch } from "vue";
import { useRulebooksStore } from "@/stores/rulebooks";
import { apiGet } from "@/api/client";
import {
@@ -18,9 +18,6 @@ const store = useRulebooksStore();
const isCreating = ref(false);
const newTitle = ref("");
const currentRulebook = computed(() =>
store.rulebooks.find((rb) => rb.id === props.rulebookId),
);
interface ProjectLite { id: number; title: string }
const projects = ref<ProjectLite[]>([]);
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "scribe",
"description": "Scribe system-of-record for Claude Code: MCP tools over your notes/tasks/projects/rules, a session-start push channel that surfaces your active-project context, process-skills (writing-plans, systematic-debugging, verification, brainstorming, reusing-code), and your saved Scribe Processes auto-surfaced as skills (/scribe:sync). Replaces superpowers + file-memory with one app-backed plugin.",
"version": "2026.09.11.1154",
"version": "2026.09.11.2026",
"author": {
"name": "Bryan Van Deusen"
},
+3 -3
View File
@@ -18,7 +18,7 @@ from scribe.mcp._context import current_user_id
from scribe.services import dedup as dedup_svc
from scribe.services import rulebooks as rulebooks_svc
from scribe.services import trash as trash_svc
from scribe.services.rule_usage import record_rule_pulled, record_rule_surfaced
from scribe.services.rule_usage import record_rule_pulled
# ── Rulebook CRUD ───────────────────────────────────────────────────────
@@ -249,7 +249,7 @@ async def create_rule(
topic_id: int, title: str, statement: str, when_to_apply: str = "",
why: str = "", how_to_apply: str = "", order_index: int = 0,
arose_from_id: int = 0, verify_with: str = "", expires_when: str = "",
force: bool = False,
system_ids: list[int] | None = None, force: bool = False,
) -> dict:
"""Create a new rule in a rulebook (a SHARED rule — keep it general).
@@ -415,7 +415,7 @@ async def create_project_rule(
project_id: int, statement: str, title: str = "", when_to_apply: str = "",
why: str = "", how_to_apply: str = "", order_index: int = 0,
arose_from_id: int = 0, verify_with: str = "", expires_when: str = "",
force: bool = False,
system_ids: list[int] | None = None, force: bool = False,
) -> dict:
"""Create a rule scoped to a single project (no rulebook needed).
-4
View File
@@ -18,15 +18,11 @@ import logging
import re
import time
from sqlalchemy import select
from scribe.models import async_session
from scribe.models.rulebook import RulebookTopic
from scribe.services import design_systems as design_systems_svc
from scribe.services import knowledge as knowledge_svc
from scribe.services import notes as notes_svc
from scribe.services import projects as projects_svc
from scribe.services import rulebooks as rulebooks_svc
from scribe.services import shape_ledger as shape_ledger_svc
from scribe.services import snippets as snippets_svc
from scribe.services.access import label_shared_items, owner_names_for
-4
View File
@@ -9,7 +9,6 @@ from __future__ import annotations
import logging
from collections.abc import Iterable
from datetime import datetime
from typing import Optional
from sqlalchemy import and_, delete as sql_delete, false as sa_false, insert, or_, select
@@ -933,9 +932,6 @@ async def delete_rule(rule_id: int, user_id: int) -> None:
# ── Subscriptions + get_applicable_rules ───────────────────────────────
from sqlalchemy.exc import IntegrityError
async def subscribe_project(
project_id: int, rulebook_id: int, user_id: int,
) -> None:
+6 -10
View File
@@ -1,12 +1,14 @@
"""Project inception (milestone 297) — step 1: the record's shape.
The WHY a project inherits what it does lives on projects.inception; the
opt-out of an always-on rulebook is its own association table. Pure
The WHY a project inherits what it does lives on projects.inception. Pure
validation is pinned here; the effects are step 3's integration tests.
The opt-out of an always-on rulebook had its own association table until
milestone 394. With no always-on tier there is nothing to opt out OF — a
rulebook binds a project only by subscription — so the table and the test
that pinned its shape both went with it.
"""
from scribe.models import Base
from scribe.models.project import Project
from scribe.models.rulebook import project_rulebook_exclusions
from scribe.services.inception import (
CHOICE_KEYS, INCEPTION_VIAS, is_decided, normalize_choices, validate_inception,
)
@@ -23,12 +25,6 @@ def test_project_carries_an_inception_record_and_to_dict_shows_it():
assert INCEPTION_VIAS == ("mcp", "ui", "legacy")
def test_exclusions_table_is_the_suppressions_sibling():
t = Base.metadata.tables["project_rulebook_exclusions"]
assert project_rulebook_exclusions is t
assert {c.name for c in t.primary_key.columns} == {"project_id", "rulebook_id"}
fks = {fk.column.table.name: fk.ondelete for c in t.columns for fk in c.foreign_keys}
assert fks == {"projects": "CASCADE", "rulebooks": "CASCADE"}
def test_validate_inception_pins_the_choice_vocabulary():