docs(6205): rule_moment_judgments, retrieval_migration, repo_bindings, moments, logging, design_systems comments drop citations

retrieval_migration states what it lets a tuned floor do without quoting
the operator, and its order-of-operations refusal is described as enforced
rather than as history. logging states why raw date filters fail rather
than citing the two issues that found it. The rest drop milestone, step and
record citations; step references now name the code that does the job.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-21 20:32:07 -04:00
co-authored by Claude Opus 5.5
parent cc5401b2d3
commit 172e784cb2
6 changed files with 25 additions and 28 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
"""Design system + token persistence, and the guard on the parent chain. """Design system + token persistence, and the guard on the parent chain.
Access goes through `services/access.py` (rule #78), where reaching a system via Access goes through `services/access.py`, where reaching a system via
a project you can see grants READ but never write — see a project you can see grants READ but never write — see
`get_design_system_permission` for why that asymmetry exists. `get_design_system_permission` for why that asymmetry exists.
@@ -92,7 +92,7 @@ async def create_design_system(
which, per the ACL, means one they do not own. which, per the ACL, means one they do not own.
`starter_role_groups` seeds the system with named, VALUELESS token roles `starter_role_groups` seeds the system with named, VALUELESS token roles
(#2349) — the moment a role is missing is the moment a literal gets written — the moment a role is missing is the moment a literal gets written
instead, so the cheapest time to name them is now. Pass a list of group instead, so the cheapest time to name them is now. Pass a list of group
names to choose, `[]` for none, or None for none. names to choose, `[]` for none, or None for none.
@@ -244,7 +244,7 @@ async def create_token(
async def list_tokens(user_id: int, design_system_id: int) -> list[DesignToken]: async def list_tokens(user_id: int, design_system_id: int) -> list[DesignToken]:
"""One system's OWN tokens — its override set, not its effective set. """One system's OWN tokens — its override set, not its effective set.
Resolving the chain is step 2's job; this deliberately answers the narrower Resolving the chain is `resolve_design_system`'s job; this deliberately answers the narrower
question ("what does this system change?") that the model exists to make question ("what does this system change?") that the model exists to make
free. free.
""" """
+4 -5
View File
@@ -92,11 +92,10 @@ async def log_error(
def parse_filter_datetime(value: str | None, *, end_of_day: bool = False) -> datetime | None: def parse_filter_datetime(value: str | None, *, end_of_day: bool = False) -> datetime | None:
"""An ISO date/datetime from a query string as an AWARE UTC datetime. """An ISO date/datetime from a query string as an AWARE UTC datetime.
The admin log filters arrive as raw `request.args` strings and used to be The admin log filters arrive as raw `request.args` strings. Compared
compared straight against `AppLog.created_at`. asyncpg binds a str as straight against `AppLog.created_at`, they fail: asyncpg binds a str as
VARCHAR and Postgres has no `timestamptz >= text` operator, so supplying VARCHAR and Postgres has no `timestamptz >= text` operator, so either date
either date filter raised — the same defect as #1727 in notifications, in a filter would raise.
second place (#2254).
Returns None for anything unparseable: a malformed filter should narrow Returns None for anything unparseable: a malformed filter should narrow
nothing rather than 500 the log viewer. nothing rather than 500 the log viewer.
+3 -3
View File
@@ -1,4 +1,4 @@
"""The moments of work that rules mount on (milestone 458). """The moments of work that rules mount on.
WHY THIS EXISTS WHY THIS EXISTS
@@ -19,12 +19,12 @@ the same mount points, or a rule written on one could not mean the same thing on
another, and the plugin's hooks, the skills that declare moments and the another, and the plugin's hooks, the skills that declare moments and the
instruction surfaces all name them. What varies per install is which ACTIONS instruction surfaces all name them. What varies per install is which ACTIONS
reach a moment — one operator delivers with a push, another with a deploy reach a moment — one operator delivers with a push, another with a deploy
script, a third by sending a document — and that mapping is data (step 2). The script, a third by sending a document — and that mapping is data (`moment_actions`). The
moment is generic; the action that reaches it is local. moment is generic; the action that reaches it is local.
HOW TO WRITE ONE HOW TO WRITE ONE
Domain-neutral (rule 115): Scribe's work may be software, configuration, Domain-neutral: Scribe's work may be software, configuration,
infrastructure or anything else a person drives through an agent, so a infrastructure or anything else a person drives through an agent, so a
definition names the moment in words every one of those recognises. The test definition names the moment in words every one of those recognises. The test
beside this module refuses software-only vocabulary in both fields. Concrete beside this module refuses software-only vocabulary in both fields. Concrete
+3 -3
View File
@@ -73,7 +73,7 @@ async def set_binding(
) -> RepoBinding: ) -> RepoBinding:
"""Create or update the binding for a repo. Idempotent on (user, repo_key). """Create or update the binding for a repo. Idempotent on (user, repo_key).
``ref`` (#2873) is the branch the coverage refresh reads for this ``ref`` is the branch the coverage refresh reads for this
binding: a name sets it, ``""`` clears it back to the forge's default binding: a name sets it, ``""`` clears it back to the forge's default
branch, ``None`` leaves whatever stands (a re-bind that only moves the branch, ``None`` leaves whatever stands (a re-bind that only moves the
project keeps the ref it had). project keeps the ref it had).
@@ -111,7 +111,7 @@ async def list_bindings(user_id: int) -> list[RepoBinding]:
async def bindings_for_project(user_id: int, project_id: int) -> list[RepoBinding]: async def bindings_for_project(user_id: int, project_id: int) -> list[RepoBinding]:
"""Every binding of a project — key AND the ref its ledger follows (#2873).""" """Every binding of a project — key AND the ref its ledger follows."""
async with async_session() as session: async with async_session() as session:
rows = await session.execute( rows = await session.execute(
select(RepoBinding).where( select(RepoBinding).where(
@@ -141,7 +141,7 @@ async def is_bound(project_id: int, raw_repo: str) -> str:
async def keys_for_project(user_id: int, project_id: int) -> list[str]: async def keys_for_project(user_id: int, project_id: int) -> list[str]:
"""Every repo key bound to a project — the snippet→forge join (#2691). """Every repo key bound to a project — the snippet→forge join.
Recorded snippet locations carry free-form repo names ("Scribe"), which Recorded snippet locations carry free-form repo names ("Scribe"), which
can't address a forge API. The project's binding is the identity that can: can't address a forge API. The project's binding is the identity that can:
+9 -11
View File
@@ -1,4 +1,4 @@
"""Carrying a tuned floor across an embedding-model change (#4104). """Carrying a tuned floor across an embedding-model change.
THE PROBLEM THE PROBLEM
@@ -9,10 +9,8 @@ in `settings` survive the swap unchanged and silently stop describing anything:
the bar keeps applying, the telemetry keeps filling, and nothing anywhere says the bar keeps applying, the telemetry keeps filling, and nothing anywhere says
the arm is now cutting in a different place. the arm is now cutting in a different place.
Re-deriving six floors by hand is the alternative, and it is the thing the Re-deriving every floor by hand is the alternative. This module lets a tuned
operator asked for a way out of — *"a path for thresholds to be inherited by threshold be inherited by the next model instead of recalibrated from scratch.
the next version or different model so that they don't have to recalibrate a
lot."*
WHAT TRANSFERS, AND WHY IT IS NOT THE NUMBER WHAT TRANSFERS, AND WHY IT IS NOT THE NUMBER
@@ -30,8 +28,8 @@ units.
WHY `best_available_score` IS THE FIGURE ON BOTH SIDES WHY `best_available_score` IS THE FIGURE ON BOTH SIDES
Because it is the one number that exists whether or not a call returned Because it is the one number that exists whether or not a call returned
anything — the highest score the corpus offered, before the bar was applied anything — the highest score the corpus offered, before the bar was applied.
(#3670). It is what `retrieval_logs` recorded under the old model, and it is It is what `retrieval_logs` recorded under the old model, and it is
what a re-score reproduces under the new one, so the two sides are the same what a re-score reproduces under the new one, so the two sides are the same
measurement rather than two things that resemble each other. measurement rather than two things that resemble each other.
@@ -46,7 +44,7 @@ WHAT THIS DOES NOT DO
It does not fire by itself, and `migrate_floor` will not write anything unless It does not fire by itself, and `migrate_floor` will not write anything unless
asked twice — `apply=True` on top of having read the dry run. A model change is asked twice — `apply=True` on top of having read the dry run. A model change is
exactly the moment when every number is uncertain at once, which is the worst exactly the moment when every number is uncertain at once, which is the worst
possible moment to let a statistic move six dials unattended. The percentile is possible moment to let a statistic move every dial unattended. The percentile is
a starting point on the new scale, in the same sense the shipped defaults are a a starting point on the new scale, in the same sense the shipped defaults are a
starting point: better than a stale number, not a substitute for reading what starting point: better than a stale number, not a substitute for reading what
the surface actually turned away. the surface actually turned away.
@@ -122,7 +120,7 @@ _RESCORERS = {
# The embedding table each surface's re-scorer reads. A migration from a corpus # The embedding table each surface's re-scorer reads. A migration from a corpus
# that is still part-way through a model change re-scores against a blend of # that is still part-way through a model change re-scores against a blend of
# two geometries and writes a floor computed from it, with a confident reason # two geometries and writes a floor computed from it, with a confident reason
# attached (#4132) — so the corpus has to be wholly in the live space first. # attached — so the corpus has to be wholly in the live space first.
_CORPUS = { _CORPUS = {
"auto_inject": NoteEmbedding, "auto_inject": NoteEmbedding,
"write_path": NoteEmbedding, "write_path": NoteEmbedding,
@@ -178,8 +176,8 @@ async def migrate_floor(
off_model = await rows_off_the_live_model(_CORPUS[surface]) off_model = await rows_off_the_live_model(_CORPUS[surface])
if off_model: if off_model:
# Refused before sampling anything. The order of operations — re-embed, # Refused before sampling anything, so the order of operations —
# THEN migrate — used to be held only in the operator's memory. # re-embed, THEN migrate — is enforced rather than remembered.
stamp = calibration_stamp() stamp = calibration_stamp()
return { return {
"surface": surface, "migrated": False, "surface": surface, "migrated": False,
+3 -3
View File
@@ -1,4 +1,4 @@
"""Which rules belong on which moments — proposals and judgments (milestone 458 step 7). """Which rules belong on which moments — proposals and judgments.
A rule written before moments existed is mounted on nothing, and reaches a A rule written before moments existed is mounted on nothing, and reaches a
session only when its words resemble the work. Mounting the corpus is a session only when its words resemble the work. Mounting the corpus is a
@@ -19,7 +19,7 @@ Neither source mounts anything by itself. A suggestion that delivered its rule
would manufacture the opens it counts, and the operator's corpus is theirs to would manufacture the opens it counts, and the operator's corpus is theirs to
mount. mount.
THE MISFIRE (step 7b) is the same machinery pointed the other way. A session THE MISFIRE is the same machinery pointed the other way. A session
that was handed a mounted rule at a moment where it did not apply says so that was handed a mounted rule at a moment where it did not apply says so
(`misfired`), with why and the action that reached the moment. Reports count (`misfired`), with why and the action that reached the moment. Reports count
per distinct DAY — the MCP door is stateless and no session id reaches it, and per distinct DAY — the MCP door is stateless and no session id reaches it, and
@@ -35,7 +35,7 @@ write path, `rulebooks.set_rule_moments`) confirms what was added and rejects
what was removed — a moment taken off a rule must not be proposed straight what was removed — a moment taken off a rule must not be proposed straight
back by the signal. back by the signal.
ACL (rule 78): rules are owner-scoped, and every read and write here goes ACL: rules are owner-scoped, and every read and write here goes
through `rulebooks._owned_rules_clause` / `_fetch_owned_rule`. through `rulebooks._owned_rules_clause` / `_fetch_owned_rule`.
""" """
from __future__ import annotations from __future__ import annotations