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:
@@ -8,7 +8,7 @@ from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
from scribe.services.retrieval_telemetry import (
|
||||
from grimoire.services.retrieval_telemetry import (
|
||||
_build_payload,
|
||||
record_retrieval,
|
||||
)
|
||||
@@ -100,7 +100,7 @@ def test_the_count_of_hits_the_reader_already_held_is_carried():
|
||||
def test_the_readout_reports_unmeasured_suppression_as_none():
|
||||
"""`_bucket` renders the aggregate. No row reporting it → null, never a
|
||||
zeroed dict: a zeroed dict states a measurement nobody made."""
|
||||
from scribe.services.retrieval_telemetry import _bucket
|
||||
from grimoire.services.retrieval_telemetry import _bucket
|
||||
|
||||
# calls, zero, p10, p50, p90, min, max, avg_n, dur,
|
||||
# measured, supp_calls, supp_zero, miss_calls, miss_p50, miss_p90, miss_max
|
||||
@@ -138,9 +138,9 @@ def test_record_retrieval_without_event_loop_is_safe():
|
||||
async def test_insert_retrieval_log_roundtrip(_dispose_engine):
|
||||
from sqlalchemy import delete, select
|
||||
|
||||
from scribe.models import async_session
|
||||
from scribe.models.retrieval_log import RetrievalLog
|
||||
from scribe.services.retrieval_telemetry import _insert_retrieval_log
|
||||
from grimoire.models import async_session
|
||||
from grimoire.models.retrieval_log import RetrievalLog
|
||||
from grimoire.services.retrieval_telemetry import _insert_retrieval_log
|
||||
|
||||
payload = _build_payload(
|
||||
user_id=990001, source="mcp_search", query="pgvector tuning",
|
||||
@@ -179,10 +179,10 @@ async def test_insert_retrieval_log_roundtrip(_dispose_engine):
|
||||
async def test_retrieval_summary_reads_what_the_writer_wrote(_dispose_engine):
|
||||
from sqlalchemy import delete
|
||||
|
||||
from scribe.models import async_session
|
||||
from scribe.models.note_usage import NoteUsageEvent
|
||||
from scribe.models.retrieval_log import RetrievalLog
|
||||
from scribe.services.retrieval_telemetry import (
|
||||
from grimoire.models import async_session
|
||||
from grimoire.models.note_usage import NoteUsageEvent
|
||||
from grimoire.models.retrieval_log import RetrievalLog
|
||||
from grimoire.services.retrieval_telemetry import (
|
||||
_insert_retrieval_log, retrieval_summary,
|
||||
)
|
||||
|
||||
@@ -252,7 +252,7 @@ async def test_retrieval_summary_reads_what_the_writer_wrote(_dispose_engine):
|
||||
async def test_retrieval_summary_is_empty_not_broken_for_a_fresh_install(_dispose_engine):
|
||||
"""An install with no telemetry gets a coherent zero readout, and
|
||||
`read_failed` stays False — "no rows" is not "the read broke"."""
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
out = await retrieval_summary(990003, days=30)
|
||||
assert out["read_failed"] is False
|
||||
@@ -272,9 +272,9 @@ async def test_retrieval_summary_sees_only_its_own_users_telemetry(_dispose_engi
|
||||
included. The owner filter is the access rule, so it gets a test."""
|
||||
from sqlalchemy import delete
|
||||
|
||||
from scribe.models import async_session
|
||||
from scribe.models.retrieval_log import RetrievalLog
|
||||
from scribe.services.retrieval_telemetry import (
|
||||
from grimoire.models import async_session
|
||||
from grimoire.models.retrieval_log import RetrievalLog
|
||||
from grimoire.services.retrieval_telemetry import (
|
||||
_insert_retrieval_log, retrieval_summary,
|
||||
)
|
||||
|
||||
@@ -310,9 +310,9 @@ async def test_by_source_separates_a_surface_that_earns_its_noise_from_one_that_
|
||||
"""
|
||||
from sqlalchemy import delete
|
||||
|
||||
from scribe.models import async_session
|
||||
from scribe.models.note_usage import NoteUsageEvent
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.models import async_session
|
||||
from grimoire.models.note_usage import NoteUsageEvent
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
UID = 990010
|
||||
async with async_session() as s:
|
||||
@@ -367,9 +367,9 @@ async def test_an_ambient_surface_reports_its_counts_but_no_ratio(_dispose_engin
|
||||
counts stay visible and the ratio that would be misread is null."""
|
||||
from sqlalchemy import delete
|
||||
|
||||
from scribe.models import async_session
|
||||
from scribe.models.note_usage import NoteUsageEvent
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.models import async_session
|
||||
from grimoire.models.note_usage import NoteUsageEvent
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
UID = 990011
|
||||
async with async_session() as s:
|
||||
@@ -401,9 +401,9 @@ async def test_the_agent_pull_filter_does_not_treat_its_underscore_as_a_wildcard
|
||||
else in the payload would reveal the difference."""
|
||||
from sqlalchemy import delete
|
||||
|
||||
from scribe.models import async_session
|
||||
from scribe.models.note_usage import NoteUsageEvent
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.models import async_session
|
||||
from grimoire.models.note_usage import NoteUsageEvent
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
UID = 990012
|
||||
async with async_session() as s:
|
||||
@@ -434,8 +434,8 @@ async def _rule_events(uid, rows):
|
||||
"""Write (event, source) pairs for one rule and hand back a cleanup."""
|
||||
from sqlalchemy import delete
|
||||
|
||||
from scribe.models import async_session
|
||||
from scribe.models.rule_usage import RuleUsageEvent
|
||||
from grimoire.models import async_session
|
||||
from grimoire.models.rule_usage import RuleUsageEvent
|
||||
|
||||
async with async_session() as s:
|
||||
s.add_all([
|
||||
@@ -466,7 +466,7 @@ async def test_rule_usage_is_a_coherent_zero_on_a_fresh_install(_dispose_engine)
|
||||
zero asserts "rules were shown and none opened", which with an empty
|
||||
numerator AND denominator is a claim the data does not support.
|
||||
"""
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
out = await retrieval_summary(990010, days=30)
|
||||
assert out["read_failed"] is False
|
||||
@@ -482,7 +482,7 @@ async def test_rule_usage_is_a_coherent_zero_on_a_fresh_install(_dispose_engine)
|
||||
async def test_an_agent_reading_a_surfaced_rule_is_what_moves_the_ratio(_dispose_engine):
|
||||
"""The whole point of the milestone: the arm can now be told apart from a
|
||||
bar it cannot fail to clear."""
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
cleanup = await _rule_events(990011, [
|
||||
(5001, "surfaced", "write_path_rule"),
|
||||
@@ -512,7 +512,7 @@ async def test_a_person_browsing_the_rule_list_does_not_move_the_ratio(_dispose_
|
||||
list in the web UI says nothing about the hint. Both are still counted in
|
||||
`pulled`, so "is this rule dead weight?" stays answerable.
|
||||
"""
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
cleanup = await _rule_events(990012, [
|
||||
(5003, "surfaced", "write_path_rule"),
|
||||
@@ -539,7 +539,7 @@ async def test_rule_events_stay_out_of_the_note_block(_dispose_engine):
|
||||
was told about — and the rule arm would still be invisible, because a few
|
||||
dozen rules against thousands of notes is noise on the note ratio.
|
||||
"""
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
cleanup = await _rule_events(990013, [
|
||||
(5004, "surfaced", "write_path_rule"),
|
||||
@@ -561,7 +561,7 @@ async def test_rule_events_stay_out_of_the_note_block(_dispose_engine):
|
||||
async def test_rule_usage_sees_only_its_own_users_events(_dispose_engine):
|
||||
"""Same access rule as the rest of the readout — the owner filter IS the
|
||||
rule for telemetry, which is not a shared record kind."""
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
cleanup = await _rule_events(990014, [
|
||||
(5005, "surfaced", "write_path_rule"),
|
||||
@@ -586,7 +586,7 @@ async def test_the_preload_lands_in_ambient_and_never_in_the_ratio(_dispose_engi
|
||||
with the arm. So the resident deliveries are counted, reported, and kept
|
||||
out of the ratio.
|
||||
"""
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
cleanup = await _rule_events(990012, [
|
||||
# One rule the arm actually chose, and opened.
|
||||
@@ -624,7 +624,7 @@ async def test_ambient_alone_reports_no_ratio(_dispose_engine):
|
||||
"""A brand-new install loads rules every session and may never trigger the
|
||||
arm. That must read as "no ranked surfacings yet", not as a precision of
|
||||
zero — the reading that would make a working install look broken."""
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
cleanup = await _rule_events(990013, [
|
||||
(5201, "surfaced", "session_start"),
|
||||
@@ -652,7 +652,7 @@ async def test_the_outcome_counts_come_back_split(_dispose_engine):
|
||||
recorded", which is true of both and useful about neither: a departure is
|
||||
evidence about the rule, an application is evidence about the agent.
|
||||
"""
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
cleanup = await _rule_events(990016, [
|
||||
# Opened and followed.
|
||||
@@ -689,7 +689,7 @@ async def test_an_outcome_is_never_split_by_ambient(_dispose_engine):
|
||||
"""`source` on an outcome row names the door the outcome came through, not
|
||||
a ranker, so the surfaced/ambient split has nothing to say about it. An
|
||||
outcome recorded from an unranked source must still count."""
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
cleanup = await _rule_events(990017, [
|
||||
(5401, "surfaced", "session_start"),
|
||||
@@ -722,7 +722,7 @@ def test_coverage_says_nothing_rather_than_false_when_nothing_was_recorded():
|
||||
"""
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from scribe.services.retrieval_telemetry import _coverage
|
||||
from grimoire.services.retrieval_telemetry import _coverage
|
||||
|
||||
since = datetime(2026, 9, 1, tzinfo=timezone.utc)
|
||||
assert _coverage(None, since) == {
|
||||
@@ -733,7 +733,7 @@ def test_coverage_says_nothing_rather_than_false_when_nothing_was_recorded():
|
||||
def test_coverage_reads_a_start_before_the_window_as_covered():
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from scribe.services.retrieval_telemetry import _coverage
|
||||
from grimoire.services.retrieval_telemetry import _coverage
|
||||
|
||||
since = datetime(2026, 9, 1, tzinfo=timezone.utc)
|
||||
older = datetime(2026, 8, 1, tzinfo=timezone.utc)
|
||||
@@ -763,9 +763,9 @@ async def test_coverage_is_per_source_because_the_table_is_older_than_its_arms(
|
||||
|
||||
from sqlalchemy import delete
|
||||
|
||||
from scribe.models import async_session
|
||||
from scribe.models.retrieval_log import RetrievalLog
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.models import async_session
|
||||
from grimoire.models.retrieval_log import RetrievalLog
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
UID = 990077
|
||||
now = datetime.now(timezone.utc)
|
||||
@@ -821,9 +821,9 @@ async def test_a_surface_that_went_silent_is_not_the_same_as_one_that_never_ran(
|
||||
|
||||
from sqlalchemy import delete
|
||||
|
||||
from scribe.models import async_session
|
||||
from scribe.models.retrieval_log import RetrievalLog
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.models import async_session
|
||||
from grimoire.models.retrieval_log import RetrievalLog
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
UID = 990078
|
||||
now = datetime.now(timezone.utc)
|
||||
@@ -877,9 +877,9 @@ async def test_a_section_is_complete_only_from_its_latest_contributor(
|
||||
|
||||
from sqlalchemy import delete
|
||||
|
||||
from scribe.models import async_session
|
||||
from scribe.models.rule_usage import RuleUsageEvent
|
||||
from scribe.services.retrieval_telemetry import retrieval_summary
|
||||
from grimoire.models import async_session
|
||||
from grimoire.models.rule_usage import RuleUsageEvent
|
||||
from grimoire.services.retrieval_telemetry import retrieval_summary
|
||||
|
||||
UID = 990078
|
||||
now = datetime.now(timezone.utc)
|
||||
@@ -962,7 +962,7 @@ def test_the_readout_reports_unmeasured_near_misses_as_none():
|
||||
"""`_bucket`'s half of the same discipline, and the reason it is a block
|
||||
rather than three loose keys: old rows predate the column, so a window can
|
||||
legitimately contain declines nobody measured."""
|
||||
from scribe.services.retrieval_telemetry import _bucket
|
||||
from grimoire.services.retrieval_telemetry import _bucket
|
||||
|
||||
# calls, zero, p10, p50, p90, min, max, avg_n, dur,
|
||||
# measured, supp_calls, supp_zero, miss_calls, miss_p50, miss_p90, miss_max
|
||||
@@ -988,7 +988,7 @@ def test_the_readout_carries_no_field_derivable_from_its_neighbours():
|
||||
field reintroduces `calls - zero_result_calls` under a new name, the sum
|
||||
below is where it shows up.
|
||||
"""
|
||||
from scribe.services.retrieval_telemetry import _bucket
|
||||
from grimoire.services.retrieval_telemetry import _bucket
|
||||
|
||||
b = _bucket([326, 114, 0.6, 0.68, 0.77, 0.55, 0.85, 1.7, 130.9,
|
||||
0, 0, 0, 114, 0.61, 0.71, 0.72])
|
||||
@@ -1025,9 +1025,9 @@ async def test_the_near_miss_distribution_is_a_query_postgres_accepts(_dispose_e
|
||||
"""
|
||||
from sqlalchemy import delete
|
||||
|
||||
from scribe.models import async_session
|
||||
from scribe.models.retrieval_log import RetrievalLog
|
||||
from scribe.services.retrieval_telemetry import (
|
||||
from grimoire.models import async_session
|
||||
from grimoire.models.retrieval_log import RetrievalLog
|
||||
from grimoire.services.retrieval_telemetry import (
|
||||
_insert_retrieval_log, retrieval_summary,
|
||||
)
|
||||
|
||||
@@ -1122,7 +1122,7 @@ def test_a_search_that_never_ran_writes_no_row():
|
||||
"""
|
||||
from unittest.mock import patch
|
||||
|
||||
import scribe.services.retrieval_telemetry as rt
|
||||
import grimoire.services.retrieval_telemetry as rt
|
||||
|
||||
with patch.object(rt, "_build_payload") as build:
|
||||
rt.record_retrieval(
|
||||
@@ -1147,7 +1147,7 @@ def test_a_search_that_ran_and_found_nothing_still_writes_its_row():
|
||||
"""
|
||||
from unittest.mock import patch
|
||||
|
||||
import scribe.services.retrieval_telemetry as rt
|
||||
import grimoire.services.retrieval_telemetry as rt
|
||||
|
||||
with patch.object(rt, "_build_payload") as build:
|
||||
rt.record_retrieval(
|
||||
@@ -1168,7 +1168,7 @@ def test_a_caller_that_never_asked_is_assumed_to_have_searched():
|
||||
"""
|
||||
from unittest.mock import patch
|
||||
|
||||
import scribe.services.retrieval_telemetry as rt
|
||||
import grimoire.services.retrieval_telemetry as rt
|
||||
|
||||
with patch.object(rt, "_build_payload") as build:
|
||||
rt.record_retrieval(
|
||||
@@ -1233,9 +1233,9 @@ async def test_the_listing_names_the_highest_declines_per_source(_dispose_engine
|
||||
"""
|
||||
from sqlalchemy import delete
|
||||
|
||||
from scribe.models import async_session
|
||||
from scribe.models.retrieval_log import RetrievalLog
|
||||
from scribe.services.retrieval_telemetry import (
|
||||
from grimoire.models import async_session
|
||||
from grimoire.models.retrieval_log import RetrievalLog
|
||||
from grimoire.services.retrieval_telemetry import (
|
||||
_insert_retrieval_log, retrieval_summary,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user