rename(547): what people read says Grimoire
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 52s
CI & Build / integration (push) Successful in 1m1s
CI & Build / Python tests (push) Successful in 1m55s
CI & Build / Build & push image (push) Successful in 36s

Step 1 of the Scribe -> Grimoire rename: every capitalised "Scribe" in prose
becomes "Grimoire" ("Fabled Scribe" -> "Fabled Grimoire") across the UI,
the PWA manifest and page title, the MCP instructions and tool docstrings,
hook and skill text, docs and README, with the tests that assert on that
prose moving with it. Old migrations keep their wording.

Identifiers are untouched here: the package, plugin name, MCP server key,
hook file names, env vars, the .scribe marker and FabledScribe repo/image
names move in steps 2 and 3, along with prose that quotes them.

The sweep matched "Scribe" only as a whole word, so describe/subscribe and
friends are untouched. The longer name took the MCP instructions one
character over their 1,600 budget; two phrases are shortened to fit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 10:46:37 -04:00
co-authored by Claude Opus 5.5
parent 06be537a18
commit e99f1169f7
142 changed files with 460 additions and 460 deletions
+14 -14
View File
@@ -57,13 +57,13 @@ async def seeded():
data=compose_data(name=name, language="python", locations=locations),
)
nested = _snippet("nested", [loc(repo="Scribe", path="frontend/src/lib/x.ts", symbol="helper")])
sibling = _snippet("sibling", [loc(repo="Scribe", path="frontend/srcmap.ts", symbol="other")])
# Two locations, deliberately crossed: repo Scribe at src/a.py and repo
# Portal at src/b.py. repo=Scribe + path=src/b.py must NOT match it.
nested = _snippet("nested", [loc(repo="Grimoire", path="frontend/src/lib/x.ts", symbol="helper")])
sibling = _snippet("sibling", [loc(repo="Grimoire", path="frontend/srcmap.ts", symbol="other")])
# Two locations, deliberately crossed: repo Grimoire at src/a.py and repo
# Portal at src/b.py. repo=Grimoire + path=src/b.py must NOT match it.
multi = _snippet(
"multi",
[loc(repo="Scribe", path="src/a.py", symbol="alpha"), loc(repo="Portal", path="src/b.py", symbol="beta")],
[loc(repo="Grimoire", path="src/a.py", symbol="alpha"), loc(repo="Portal", path="src/b.py", symbol="beta")],
)
# No structured location at all — must never satisfy a location filter,
# and must not error the query either.
@@ -101,7 +101,7 @@ async def _ids_for(user_id: int, **parts) -> set[int]:
@pytest.mark.asyncio
async def test_repo_filter_finds_every_snippet_recorded_in_it(seeded):
user_id, ids = seeded
found = await _ids_for(user_id, repo="Scribe")
found = await _ids_for(user_id, repo="Grimoire")
assert found == {ids["nested"], ids["sibling"], ids["multi"]}
assert ids["placeless"] not in found
@@ -124,9 +124,9 @@ async def test_path_prefix_reaches_into_subdirectories(seeded):
@pytest.mark.asyncio
async def test_parts_must_match_within_one_location(seeded):
user_id, ids = seeded
assert await _ids_for(user_id, repo="Scribe", path="src/a.py") == {ids["multi"]}
assert await _ids_for(user_id, repo="Grimoire", path="src/a.py") == {ids["multi"]}
# Same snippet, but repo and path belong to two different entries.
assert await _ids_for(user_id, repo="Scribe", path="src/b.py") == set()
assert await _ids_for(user_id, repo="Grimoire", path="src/b.py") == set()
assert await _ids_for(user_id, repo="Portal", path="src/b.py") == {ids["multi"]}
@@ -155,7 +155,7 @@ async def test_keyword_arm_applies_the_location_filter(seeded):
"scribe.services.embeddings.semantic_search_notes",
AsyncMock(return_value=[]),
):
assert await _ids_for(user_id, q="nested", repo="Scribe") == {ids["nested"]}
assert await _ids_for(user_id, q="nested", repo="Grimoire") == {ids["nested"]}
# Matches the query but not the place.
assert await _ids_for(user_id, q="nested", repo="Portal") == set()
@@ -190,7 +190,7 @@ async def test_semantic_arm_applies_the_location_filter(seeded):
assert await _ids_for(user_id, q="zzzznomatch", path="frontend/src") == {
ids["nested"],
}
assert await _ids_for(user_id, q="zzzznomatch", repo="Scribe", path="src/b.py") == set()
assert await _ids_for(user_id, q="zzzznomatch", repo="Grimoire", path="src/b.py") == set()
@pytest.mark.asyncio
@@ -212,13 +212,13 @@ async def test_sql_and_python_dialects_agree_on_the_same_rows(seeded):
by_id = {n.id: n.data for n in rows}
cases = [
{"repo": "Scribe"},
{"repo": "Grimoire"},
{"path": "frontend/src"},
{"path": "frontend/src/lib/x.ts"},
{"repo": "Scribe", "path": "src/a.py"},
{"repo": "Scribe", "path": "src/b.py"},
{"repo": "Grimoire", "path": "src/a.py"},
{"repo": "Grimoire", "path": "src/b.py"},
{"symbol": "beta"},
{"repo": "Scribe", "path": "frontend", "symbol": "helper"},
{"repo": "Grimoire", "path": "frontend", "symbol": "helper"},
]
for case in cases:
sql_ids = await _ids_for(user_id, **case)