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
+11 -11
View File
@@ -8,7 +8,7 @@ from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from scribe.services.db_maintenance import MAINTENANCE_TABLES, run_maintenance
from grimoire.services.db_maintenance import MAINTENANCE_TABLES, run_maintenance
from tests.helpers import make_mock_session
@@ -31,8 +31,8 @@ def _mock_engine(exec_side_effect=None):
@pytest.mark.asyncio
async def test_vacuums_each_allowlisted_table_once():
engine, autocommit = _mock_engine()
with patch("scribe.services.db_maintenance.engine", engine), \
patch("scribe.services.db_maintenance.set_admin_setting", AsyncMock()):
with patch("grimoire.services.db_maintenance.engine", engine), \
patch("grimoire.services.db_maintenance.set_admin_setting", AsyncMock()):
summary = await run_maintenance()
issued = [c.args[0] for c in autocommit.exec_driver_sql.await_args_list]
@@ -48,8 +48,8 @@ async def test_vacuums_each_allowlisted_table_once():
async def test_allowlist_is_closed():
"""A caller-supplied name not on the allowlist is silently ignored."""
engine, autocommit = _mock_engine()
with patch("scribe.services.db_maintenance.engine", engine), \
patch("scribe.services.db_maintenance.set_admin_setting", AsyncMock()):
with patch("grimoire.services.db_maintenance.engine", engine), \
patch("grimoire.services.db_maintenance.set_admin_setting", AsyncMock()):
summary = await run_maintenance(tables=["app_logs", "users; DROP TABLE notes"])
issued = [c.args[0] for c in autocommit.exec_driver_sql.await_args_list]
@@ -69,8 +69,8 @@ async def test_one_table_failure_does_not_abort_the_rest():
return MagicMock()
engine, autocommit = _mock_engine(exec_side_effect=flaky)
with patch("scribe.services.db_maintenance.engine", engine), \
patch("scribe.services.db_maintenance.set_admin_setting", AsyncMock()):
with patch("grimoire.services.db_maintenance.engine", engine), \
patch("grimoire.services.db_maintenance.set_admin_setting", AsyncMock()):
summary = await run_maintenance()
assert autocommit.exec_driver_sql.await_count == len(MAINTENANCE_TABLES)
@@ -93,14 +93,14 @@ def _health_session(db_bytes, rows):
async def test_table_health_shapes_rows_and_db_size():
from datetime import datetime, timezone
from scribe.services.db_maintenance import get_table_health
from grimoire.services.db_maintenance import get_table_health
vac = datetime(2026, 6, 14, 4, 0, tzinfo=timezone.utc)
rows = [
{"table_name": "notes", "live": 1000, "dead": 300, "dead_pct": 23.1,
"total_bytes": 5_000_000, "mod_since_analyze": 50,
"last_vacuum": vac, "last_analyze": None},
]
with patch("scribe.services.db_maintenance.async_session",
with patch("grimoire.services.db_maintenance.async_session",
return_value=_health_session(42_000_000, rows)):
health = await get_table_health()
@@ -116,8 +116,8 @@ async def test_table_health_shapes_rows_and_db_size():
async def test_summary_is_persisted_as_admin_setting():
engine, _ = _mock_engine()
setter = AsyncMock()
with patch("scribe.services.db_maintenance.engine", engine), \
patch("scribe.services.db_maintenance.set_admin_setting", setter):
with patch("grimoire.services.db_maintenance.engine", engine), \
patch("grimoire.services.db_maintenance.set_admin_setting", setter):
await run_maintenance()
setter.assert_awaited_once()
assert setter.await_args.args[0] == "db_maintenance_last_run"