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
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:
@@ -116,9 +116,9 @@ async def test_a_title_change_reaches_the_mirror_too():
|
||||
def test_every_kind_with_a_derived_mirror_is_registered():
|
||||
"""The load-bearing one. A single `if` naming one kind leaves the next
|
||||
kind uncovered."""
|
||||
from scribe.services.lessons import LESSON_NOTE_TYPE
|
||||
from scribe.services.notes import _mirror_recomposers
|
||||
from scribe.services.snippets import SNIPPET_NOTE_TYPE
|
||||
from grimoire.services.lessons import LESSON_NOTE_TYPE
|
||||
from grimoire.services.notes import _mirror_recomposers
|
||||
from grimoire.services.snippets import SNIPPET_NOTE_TYPE
|
||||
|
||||
table = _mirror_recomposers()
|
||||
assert SNIPPET_NOTE_TYPE in table, "snippets lost their mirror recomposer"
|
||||
@@ -132,7 +132,7 @@ def test_every_kind_with_a_derived_mirror_is_registered():
|
||||
def test_the_dispatch_is_a_lookup_not_a_named_kind():
|
||||
"""Asserted on structure. A lookup extends in one line in one
|
||||
place; naming a kind inline is the shape that left lessons uncovered."""
|
||||
from scribe.services import notes as notes_module
|
||||
from grimoire.services import notes as notes_module
|
||||
|
||||
src = inspect.getsource(notes_module.update_note)
|
||||
assert "_mirror_recomposers()" in src
|
||||
@@ -144,7 +144,7 @@ def test_the_dispatch_is_a_lookup_not_a_named_kind():
|
||||
def test_each_recomposer_takes_the_note_and_nothing_else():
|
||||
"""A registry entry with the wrong signature fails inside a generic PATCH,
|
||||
which is the one moment nobody is watching."""
|
||||
from scribe.services.notes import _mirror_recomposers
|
||||
from grimoire.services.notes import _mirror_recomposers
|
||||
|
||||
for kind, fn in _mirror_recomposers().items():
|
||||
assert callable(fn), f"{kind} maps to something not callable"
|
||||
@@ -158,13 +158,13 @@ NEW_TRIGGER = "a CI run has sat in_progress far longer than its suite takes"
|
||||
|
||||
|
||||
def _lesson_body(trigger, insight="Read the job log.", sources=None):
|
||||
from scribe.services.lessons import compose_body
|
||||
from grimoire.services.lessons import compose_body
|
||||
return compose_body(insight, trigger, sources)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_a_body_write_moves_a_lessons_trigger_with_it():
|
||||
from scribe.services.lessons import TRIGGER_KEY
|
||||
from grimoire.services.lessons import TRIGGER_KEY
|
||||
|
||||
what = "Read the job log before waiting longer"
|
||||
note = fake_lesson(
|
||||
@@ -186,8 +186,8 @@ async def test_a_subject_containing_an_em_dash_still_splits():
|
||||
separator: a subject may legitimately contain one. The title here is an
|
||||
UN-MIGRATED one, still carrying its trigger, because that
|
||||
is the row the inverse still has to read correctly."""
|
||||
from scribe.services.embeddings import trigger_title
|
||||
from scribe.services.lessons import TRIGGER_KEY
|
||||
from grimoire.services.embeddings import trigger_title
|
||||
from grimoire.services.lessons import TRIGGER_KEY
|
||||
|
||||
what = "A wait with no deadline — the shape, not the symptom"
|
||||
trigger = "you are about to await something crossing a process boundary"
|
||||
@@ -205,7 +205,7 @@ async def test_dropping_the_provenance_line_drops_it_from_the_mirror():
|
||||
the failure this recompose exists to prevent, not a courtesy — the
|
||||
opposite call from a snippet's `verification`, which is carried because it
|
||||
was never in the body to delete."""
|
||||
from scribe.services.lessons import SOURCES_KEY
|
||||
from grimoire.services.lessons import SOURCES_KEY
|
||||
|
||||
note = fake_lesson(
|
||||
title="Something learned",
|
||||
@@ -220,7 +220,7 @@ async def test_dropping_the_provenance_line_drops_it_from_the_mirror():
|
||||
async def test_an_explicit_data_wins_for_a_lesson_too():
|
||||
"""`update_lesson` composes the mirror from the merged field set and passes
|
||||
it here; that caller knows things a re-read of the body cannot recover."""
|
||||
from scribe.services.lessons import TRIGGER_KEY
|
||||
from grimoire.services.lessons import TRIGGER_KEY
|
||||
|
||||
note = fake_lesson(data={TRIGGER_KEY: "old"}, project_id=None)
|
||||
authoritative = {TRIGGER_KEY: "from the service", "what": "x"}
|
||||
@@ -232,7 +232,7 @@ async def test_an_explicit_data_wins_for_a_lesson_too():
|
||||
async def test_a_lesson_title_change_reaches_the_mirror():
|
||||
"""A lesson's subject lives in its title, so a title edit is a trigger for
|
||||
recomposition exactly as it is for a snippet's name."""
|
||||
from scribe.services.lessons import TRIGGER_KEY
|
||||
from grimoire.services.lessons import TRIGGER_KEY
|
||||
|
||||
trigger = "two absolute siblings overlap"
|
||||
note = fake_lesson(
|
||||
@@ -261,7 +261,7 @@ async def test_a_lesson_title_change_reaches_the_mirror():
|
||||
def test_untrigger_title_inverts_trigger_title(subject, trigger):
|
||||
"""The join's inverse lives beside it rather than in whichever caller
|
||||
wanted it."""
|
||||
from scribe.services.embeddings import trigger_title, untrigger_title
|
||||
from grimoire.services.embeddings import trigger_title, untrigger_title
|
||||
|
||||
title = trigger_title(subject, trigger)
|
||||
assert untrigger_title(title, trigger) == (subject or trigger).strip()
|
||||
@@ -270,7 +270,7 @@ def test_untrigger_title_inverts_trigger_title(subject, trigger):
|
||||
def test_untrigger_title_degrades_to_the_whole_title():
|
||||
"""A record written before the join existed still answers with something a
|
||||
human recognises rather than with ""."""
|
||||
from scribe.services.embeddings import untrigger_title
|
||||
from grimoire.services.embeddings import untrigger_title
|
||||
|
||||
assert untrigger_title("a plain old title", "") == "a plain old title"
|
||||
assert untrigger_title("a plain old title", "a trigger it lacks") == (
|
||||
@@ -282,7 +282,7 @@ def test_the_trigger_separator_is_spelled_in_exactly_one_place():
|
||||
"""Two literals that must match are one edit away from not matching."""
|
||||
import pathlib
|
||||
|
||||
root = pathlib.Path(__file__).resolve().parents[1] / "src" / "scribe"
|
||||
root = pathlib.Path(__file__).resolve().parents[1] / "src" / "grimoire"
|
||||
offenders = [
|
||||
str(p.relative_to(root)) for p in root.rglob("*.py")
|
||||
if '" \u2014 "' in p.read_text() and p.name != "embeddings.py"
|
||||
@@ -295,7 +295,7 @@ def test_the_trigger_separator_is_spelled_in_exactly_one_place():
|
||||
|
||||
def test_the_mirror_guards_can_fail():
|
||||
"""Shown turning red once."""
|
||||
from scribe.services.lessons import TRIGGER_KEY, recompose_data
|
||||
from grimoire.services.lessons import TRIGGER_KEY, recompose_data
|
||||
|
||||
bare = fake_lesson(title="just a title", body="no composed lines", data=None)
|
||||
assert TRIGGER_KEY not in recompose_data(bare)
|
||||
|
||||
Reference in New Issue
Block a user