rename(547): the server is grimoire — package, image, DB defaults, backups
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 56s
CI & Build / integration (push) Successful in 1m4s
CI & Build / Python tests (push) Successful in 1m55s
CI & Build / Build & push image (push) Successful in 44s

Step 2 of the Scribe -> Grimoire rename.

- src/scribe -> src/grimoire, and every import, patch target, module path,
  hypercorn entry point and `python -m grimoire.restore` with it; pyproject,
  uv.lock and the frontend package are named grimoire.
- Image git.fabledsword.com/bvandeusen/fabledgrimoire; CI's Postgres service
  runs as grimoire / grimoire_test.
- Compose files default the DB user, database and (prod) volume to grimoire,
  each overridable from .env, so an install created as Scribe keeps its data
  by setting POSTGRES_USER, POSTGRES_DB and PGDATA_VOLUME.
- Backups are written as grimoire-<ts>.tar with format grimoire-backup-tar.
  Archives named scribe-* with the scribe-backup-tar manifest still restore
  and are still counted at the destination (folder and S3), with tests.
- Exports, the MCP auth realm, the ASGI scope key and the persistent logger
  carry the new name.

Kept on purpose: the secret-sealing key label stays "scribe.secrets.v1",
because every stored secret was derived under it.

Plugin identity (plugin name, hooks, env vars, .scribe marker, skills) is
step 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 10:50:45 -04:00
co-authored by Claude Opus 5.5
parent e99f1169f7
commit 0f5ef0be63
447 changed files with 3611 additions and 3558 deletions
+8 -8
View File
@@ -7,7 +7,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from scribe.services.embeddings import (
from grimoire.services.embeddings import (
_cosine_similarity, get_embedding,
)
@@ -54,7 +54,7 @@ async def test_get_embedding_returns_list_of_floats():
fake_embedder = MagicMock()
fake_embedder.embed = MagicMock(return_value=iter([fake_vec]))
with patch(
"scribe.services.embeddings._get_model",
"grimoire.services.embeddings._get_model",
AsyncMock(return_value=fake_embedder),
):
out = await get_embedding("hello world")
@@ -67,7 +67,7 @@ async def test_get_embedding_propagates_model_load_failures():
"""If fastembed can't initialize, the error propagates — callers catch
and degrade to keyword search."""
with patch(
"scribe.services.embeddings._get_model",
"grimoire.services.embeddings._get_model",
AsyncMock(side_effect=RuntimeError("model load failed")),
):
with pytest.raises(RuntimeError, match="model load failed"):
@@ -91,7 +91,7 @@ def _counting_embeddings():
@pytest.mark.asyncio
async def test_memo_embeds_a_repeated_query_once_per_scope():
from scribe.services import embeddings as emb
from grimoire.services import embeddings as emb
fake, calls = _counting_embeddings()
with patch.object(emb, "get_embeddings", fake):
@@ -108,7 +108,7 @@ async def test_memo_embeds_a_repeated_query_once_per_scope():
async def test_without_a_scope_every_call_reaches_the_model():
"""The default is None: outside a request scope nothing is remembered, so
every caller other than the plugin routes behaves exactly as before."""
from scribe.services import embeddings as emb
from grimoire.services import embeddings as emb
fake, calls = _counting_embeddings()
with patch.object(emb, "get_embeddings", fake):
@@ -119,7 +119,7 @@ async def test_without_a_scope_every_call_reaches_the_model():
@pytest.mark.asyncio
async def test_a_scope_does_not_leak_into_the_next_one():
from scribe.services import embeddings as emb
from grimoire.services import embeddings as emb
fake, calls = _counting_embeddings()
with patch.object(emb, "get_embeddings", fake):
@@ -136,7 +136,7 @@ async def test_a_scope_does_not_leak_into_the_next_one():
async def test_a_failed_embedding_is_not_remembered():
"""The next arm in the request must try again and degrade on its own,
not inherit a failure as if it were a vector."""
from scribe.services import embeddings as emb
from grimoire.services import embeddings as emb
attempts = {"n": 0}
@@ -156,7 +156,7 @@ async def test_a_failed_embedding_is_not_remembered():
@pytest.mark.asyncio
async def test_the_route_decorator_opens_one_scope_per_call():
from scribe.services import embeddings as emb
from grimoire.services import embeddings as emb
fake, calls = _counting_embeddings()