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>
Module and test docstrings state what is pinned without the record number
or step that introduced it. Incident accounts become the failure shape in
the present tense: the pipefail head, the code_shapes import, the export
order, the facet dialects, the cross-kind repeat, the write-once kind.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Step 1 added family_ideas.topic_id but nothing could set it, so the note<->topic
link the milestone promised existed only as a column. set_family_topic links or
unlinks (0) a topic in a rulebook the caller owns, one idea per topic; the
version does not move. get_family_idea and get_family_adoption list the topic's
rules; list_family_ideas and the Family page name the topic. The model
docstrings no longer claim the topic's rules are platform-scoped in retrieval.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
assess_family_adoption took system_ids for the task it files, which made
the family tool module look like a System-tagging door and tripped the
parity registry. It is not one: the owed task is tagged to the project's
System matching the idea's canonical area, and update_task retags it.
The unit test for each conflict ground passed evidence/conditions twice.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- services/family_adoption.py: assess one project against one canon idea by
the four outcomes in order (exempt, variant, adopted, owed). Every outcome
needs a reason and adopted needs evidence. The engine records the precedents
itself: this idea's answers elsewhere, and this project's answers to the
nearest ideas. The same answer given twice records nothing.
- owed files a task in the OWING project, tagged to the System matching the
idea's canonical area, naming the gap and the reference for that project's
language. The task follows the answer: adopted closes it, exempt or variant
cancels it, owed again reopens it. Each move is logged on the task.
- the conflict order is enforced: every ground above the deciding one must
say why it did not decide. The losing side is folded into the idea's note as
a trap, an alternative or a condition branch, the version moves, and both
rows are answered against the revision.
- recheck is derived (row version != idea version). family.revise moves the
version when substance changes. undo covers a project's latest answer too.
- set_family_references names the reference implementations.
- MCP: get/list/assess adoption, resolve_family_conflict, revise_family_idea,
set_family_references. Web: GET /api/family/matrix.
- UI: an adoption matrix on /family (platform filter, cell detail with reason,
recheck and owed-task link) and the same matrix narrowed to one project on
its Family tab. The decision log now reads project-level decisions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>