diff --git a/frontend/src/views/ProjectView.vue b/frontend/src/views/ProjectView.vue
index dcd222e..5a0261c 100644
--- a/frontend/src/views/ProjectView.vue
+++ b/frontend/src/views/ProjectView.vue
@@ -754,7 +754,7 @@ async function confirmDelete() {
diff --git a/plugin/.claude-plugin/plugin.json b/plugin/.claude-plugin/plugin.json
index b2ea759..1c468de 100644
--- a/plugin/.claude-plugin/plugin.json
+++ b/plugin/.claude-plugin/plugin.json
@@ -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 always-on rules + 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": "0.1.36",
+ "version": "0.1.37",
"author": { "name": "Bryan Van Deusen" },
"mcpServers": {
"scribe": {
diff --git a/plugin/skills/shape-accounting/SKILL.md b/plugin/skills/shape-accounting/SKILL.md
index 2fb419e..6105faf 100644
--- a/plugin/skills/shape-accounting/SKILL.md
+++ b/plugin/skills/shape-accounting/SKILL.md
@@ -17,6 +17,11 @@ row carries a status:
— the why IS the record.
- `exempt` — judged genuinely one-off. **Reason required.** A recorded
judgment, not silence — it stops the next pass re-litigating it.
+- `scoped` — one-off **by construction**, stamped by the coverage sync
+ (a Vue component's scoped `", re.IGNORECASE)
+
+
+def scoped_definitions(path: str, text: str, defs: list[Definition]) -> set[tuple[str, str]]:
+ """The (kind, name) pairs among ``defs`` that are one-offs by
+ construction in this file: every sym in a .vue, and every css rule
+ that starts inside a `\n"
+ "\n"
+ )
+ defs = extract_definitions(vue)
+ names = {(d.kind, d.name) for d in defs}
+ assert {("sym", "load"), ("sym", "save"), ("css", "card"), ("css", "title"), ("css", "global-toast")} <= names
+ scoped = scoped_definitions("frontend/src/views/A.vue", vue, defs)
+ assert scoped == {("sym", "load"), ("sym", "save"), ("css", "card"), ("css", "title")}
+ # Definitions know their line, which is what the scoped-style range uses.
+ assert next(d for d in defs if d.name == "card").line > next(d for d in defs if d.name == "save").line
+ # Not a .vue: nothing is scoped, whatever it contains.
+ assert scoped_definitions("frontend/src/assets/components.css", ".card {\n x: 1;\n}\n",
+ extract_definitions(".card {\n x: 1;\n}\n")) == set()
+ assert scoped_definitions("src/a.py", "def load():\n pass\n", extract_definitions("def load():\n pass\n")) == set()
+
diff --git a/tests/test_shape_ledger.py b/tests/test_shape_ledger.py
index a8b17fb..f63c86e 100644
--- a/tests/test_shape_ledger.py
+++ b/tests/test_shape_ledger.py
@@ -30,7 +30,7 @@ def test_the_todo_state_is_the_default():
assert CodeShape.__table__.c.status.default.arg == "unclassified"
assert "unclassified" in SHAPE_STATUSES
assert set(SHAPE_STATUSES) == {
- "canonical", "instance", "variant", "exempt", "unclassified",
+ "canonical", "instance", "variant", "exempt", "scoped", "unclassified",
}
assert set(SHAPE_CLASSIFIERS) == {
"agent", "audit", "hook", "mechanical", "import",