Compare commits
4
Commits
40f603ba28
...
79655fd19f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79655fd19f | ||
|
|
79059ca1e7 | ||
|
|
8c9bb000fa | ||
|
|
9e1da4af3d |
@@ -1,13 +1,11 @@
|
||||
"""replace events.end_dt with duration_minutes (Fable #160)
|
||||
"""replace events.end_dt with duration_minutes
|
||||
|
||||
Revision ID: 0043
|
||||
Revises: 0042
|
||||
Create Date: 2026-04-29
|
||||
|
||||
Structural fix for the "end before start" bug class observed on prod
|
||||
2026-04-29: an event landed with end_dt 32 days before start_dt due
|
||||
to a tool-call mishap, then disappeared from upcoming-list filters.
|
||||
Storing duration instead of end_dt makes the invalid state
|
||||
Structural fix for the "end before start" bug class: an event whose end_dt
|
||||
precedes its start_dt disappears from upcoming-list filters. Storing duration instead of end_dt makes the invalid state
|
||||
inexpressible at the schema level (duration_minutes >= 0).
|
||||
|
||||
Backfill rules:
|
||||
|
||||
@@ -5,7 +5,7 @@ Revises: 0043
|
||||
Create Date: 2026-05-13
|
||||
|
||||
Adds two columns to the ``notes`` table to support the task-as-durable-record
|
||||
design (spec 2026-05-13):
|
||||
design:
|
||||
|
||||
- ``description``: user-stated goal / initial context. Meaningful when
|
||||
``is_task=true``; left NULL on knowledge notes.
|
||||
|
||||
@@ -4,7 +4,7 @@ Revision ID: 0048
|
||||
Revises: 0047
|
||||
Create Date: 2026-05-22
|
||||
|
||||
Phase 2 of the conversation+curator architecture (Fable #172). The
|
||||
Part of the conversation+curator architecture. The
|
||||
scheduler runs every 15 minutes and processes any journal conversation
|
||||
with messages newer than its `last_curator_run_at` timestamp. NULL
|
||||
means "never run; process all of today on first sweep."
|
||||
|
||||
@@ -4,7 +4,7 @@ Revision ID: 0049
|
||||
Revises: 0048
|
||||
Create Date: 2026-05-22
|
||||
|
||||
Phase 3 of the conversation+curator architecture (Fable #172). The
|
||||
Part of the conversation+curator architecture. The
|
||||
curator's final summary line (≤ 240 chars) is persisted here so the
|
||||
NEXT chat turn can include it in the system prompt. This is the
|
||||
feedback loop that closes the architecture — without it, the chat
|
||||
|
||||
@@ -4,13 +4,11 @@ Revision ID: 0053
|
||||
Revises: 0052
|
||||
Create Date: 2026-05-27
|
||||
|
||||
Phase 9 of the MCP-first pivot. The Python models for these tables were
|
||||
deleted in Phase 8 (commit 91bafb6); this migration drops the orphan
|
||||
Part of the MCP-first pivot. The Python models for these tables are gone;
|
||||
this migration drops the orphan
|
||||
SQL tables and cleans up dead per-user setting rows.
|
||||
|
||||
Hard-cutover: existing rows in these tables are discarded. The
|
||||
accompanying spec at docs/superpowers/specs/2026-05-26-mcp-first-pivot-design.md
|
||||
explicitly accepted this loss.
|
||||
Hard-cutover: existing rows in these tables are discarded, deliberately.
|
||||
"""
|
||||
from alembic import op
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Revision ID: 0054
|
||||
Revises: 0053
|
||||
Create Date: 2026-05-27
|
||||
|
||||
The image cache was wired into the LLM image-search tool (removed in Phase 8).
|
||||
The image cache was wired into the LLM image-search tool, which is gone.
|
||||
With no producer or consumer left, the table is dropped here.
|
||||
"""
|
||||
from alembic import op
|
||||
|
||||
@@ -6,8 +6,8 @@ Create Date: 2026-05-27
|
||||
|
||||
Adds the Scribe Rulebook hierarchy as a fourth top-level entity, sibling
|
||||
to Project. Rules carry a structural (statement, why, how_to_apply)
|
||||
triple. Projects subscribe to Rulebooks (many-to-many). See the design
|
||||
doc at docs/superpowers/specs/2026-05-27-scribe-rulebook-design.md.
|
||||
triple. Projects subscribe to Rulebooks (many-to-many; migration 0101
|
||||
later drops subscriptions).
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
@@ -4,7 +4,7 @@ Revision ID: 0066
|
||||
Revises: 0065
|
||||
Create Date: 2026-06-14
|
||||
|
||||
T3 of plan #819. The milestone becomes the plan container: its `body` holds
|
||||
The milestone becomes the plan container: its `body` holds
|
||||
the design/intent/purpose (markdown), `description` stays the one-liner, and
|
||||
individual steps live as first-class child tasks (milestone_id) instead of
|
||||
checkboxes crammed into a kind=plan task body. start_planning is reworked to
|
||||
|
||||
@@ -4,8 +4,7 @@ Revision ID: 0074
|
||||
Revises: 0073
|
||||
Create Date: 2026-07-31
|
||||
|
||||
The operator's shape for #254: prose doesn't live as one-offs, it lives centrally
|
||||
on the system. Two fields rather than one per category:
|
||||
Prose doesn't live as one-offs; it lives centrally on the system. Two fields rather than one per category:
|
||||
|
||||
design_systems.guidance the narrative a token table cannot hold — aesthetic,
|
||||
voice and tone, what is deliberately out of scope.
|
||||
@@ -17,7 +16,7 @@ on the system. Two fields rather than one per category:
|
||||
|
||||
Free-form rather than a column per category on purpose. A schema with `voice`,
|
||||
`aesthetic` and `scope` columns would bake one rulebook's table of contents into
|
||||
every install (rule #115), and the next install's design system would have three
|
||||
every install, and the next install's design system would have three
|
||||
empty columns and nowhere to put what it actually cares about.
|
||||
|
||||
Both nullable: a design system with no prose at all is complete, not a draft.
|
||||
|
||||
@@ -4,7 +4,7 @@ Revision ID: 0076
|
||||
Revises: 0075
|
||||
Create Date: 2026-08-07
|
||||
|
||||
Step 1 of milestone #278. Structure only — nothing reads or writes the new
|
||||
Structure only — nothing reads or writes the new
|
||||
table yet, and nothing behaves differently after this runs.
|
||||
|
||||
## What the table is for
|
||||
@@ -39,7 +39,7 @@ and not for notes, so the column looked like the notes-side half of that
|
||||
feature, modelled and abandoned.
|
||||
|
||||
It is dropped rather than repurposed for supersession, and the distinction is
|
||||
the point (#2483): consolidation folds several records into one survivor and
|
||||
the point: consolidation folds several records into one survivor and
|
||||
destroys the originals. Merging two snippets is lossless — one helper, several
|
||||
call sites. Folding two dev-logs means writing a summary and losing what each
|
||||
actually said. Supersession is the opposite act: both records survive, and the
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Chunked embeddings: one note_embeddings row per chunk (#280)
|
||||
"""Chunked embeddings: one note_embeddings row per chunk
|
||||
|
||||
Revision ID: 0077
|
||||
Revises: 0076
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Forge connections move to the user level (#2778)
|
||||
"""Forge connections move to the user level
|
||||
|
||||
Revision ID: 0078
|
||||
Revises: 0077
|
||||
@@ -12,7 +12,7 @@ keyring, with an optional per-project pin (projects.forge_connection_id).
|
||||
|
||||
The data move carries the existing admin config into a connection row for the
|
||||
first admin user (host parsed from the base URL), then deletes the old
|
||||
setting keys outright — no legacy dual-read (rule #22). The env-var channel
|
||||
setting keys outright — no legacy dual-read. The env-var channel
|
||||
(FORGE_KIND/FORGE_BASE_URL/FORGE_TOKEN) is untouched by this migration; it
|
||||
survives as an implicit keyring entry for admin users only.
|
||||
"""
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"""The shape ledger: code_shapes (#2787, milestone 294)
|
||||
"""The shape ledger: code_shapes
|
||||
|
||||
Revision ID: 0079
|
||||
Revises: 0078
|
||||
Create Date: 2026-08-19
|
||||
|
||||
The accounting half of the pattern system (governing note 2786): the snippet
|
||||
The accounting half of the pattern system: the snippet
|
||||
library records canon (small); this table accounts for EVERY shape the
|
||||
coverage extractor finds in a bound repo (total). Rows arrive `unclassified`
|
||||
from the coverage sync (step 2) and gain judgments — canonical / instance /
|
||||
from the coverage sync and gain judgments — canonical / instance /
|
||||
variant / exempt — from audits, hooks, and the mechanical proposer.
|
||||
Unclassified IS the todo list.
|
||||
"""
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Shape fingerprints + the mechanical proposer's columns (#2792, milestone 294)
|
||||
"""Shape fingerprints + the mechanical proposer's columns
|
||||
|
||||
Revision ID: 0080
|
||||
Revises: 0079
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Shape history, recheck, and the divergence flag (#2793, milestone 294)
|
||||
"""Shape history, recheck, and the divergence flag
|
||||
|
||||
Revision ID: 0081
|
||||
Revises: 0080
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"""Per-binding ref — the branch a project's ledger follows (#2873, milestone 294)
|
||||
"""Per-binding ref — the branch a project's ledger follows
|
||||
|
||||
Revision ID: 0082
|
||||
Revises: 0081
|
||||
Create Date: 2026-08-21
|
||||
|
||||
A repo binding used to imply the repo's default branch; the shape ledger
|
||||
therefore only saw work after a merge to main, while the operator's work
|
||||
lands on dev (rule 1). `ref` names the branch the coverage refresh reads —
|
||||
NULL keeps today's behaviour (the forge's default branch).
|
||||
Without a ref, a repo binding implies the repo's default branch, so the shape
|
||||
ledger only sees work after a merge — while a project may do its work on a
|
||||
dev branch. `ref` names the branch the coverage refresh reads; NULL means the
|
||||
forge's default branch.
|
||||
"""
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Exempt/variant reason codes — a small fixed catalogue beside the prose (#2874, milestone 294)
|
||||
"""Exempt/variant reason codes — a small fixed catalogue beside the prose
|
||||
|
||||
Revision ID: 0083
|
||||
Revises: 0082
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""code_shape_uses — consumption edges, separate from conformance (#2870, milestone 294)
|
||||
"""code_shape_uses — consumption edges, separate from conformance
|
||||
|
||||
Revision ID: 0084
|
||||
Revises: 0083
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Project inception: the decision record + always-on rulebook exclusions (milestone 297)
|
||||
"""Project inception: the decision record + always-on rulebook exclusions
|
||||
|
||||
Revision ID: 0085
|
||||
Revises: 0084
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""code_shape_consumers — the CSS consumer map (milestone 302, note 2917)
|
||||
"""code_shape_consumers — the CSS consumer map
|
||||
|
||||
Revision ID: 0086
|
||||
Revises: 0085
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
"""canonical_systems — the global area vocabulary, promoted from a constant
|
||||
to a table (milestone 307 step 1, decision note 3026)
|
||||
to a table
|
||||
|
||||
Revision ID: 0087
|
||||
Revises: 0086
|
||||
Create Date: 2026-08-26
|
||||
|
||||
The eight standard area names already existed as `STANDARD_SYSTEMS`, a tuple in
|
||||
services/systems.py that milestone 297 seeds into a project at inception. A
|
||||
services/systems.py that is seeded into a project at inception. A
|
||||
constant cannot be referenced: a rule that applies across projects has nothing
|
||||
to point at, because `systems.project_id` is NOT NULL and a family rule cannot
|
||||
be chained to one project's row. This makes the vocabulary a table so it can be
|
||||
@@ -35,7 +35,7 @@ depends_on = None
|
||||
# service computes (canonical_slug: lowercase, "&" -> "and", non-alphanumerics
|
||||
# collapsed to "-"). Charters stay generic on purpose: a project refines its
|
||||
# own System's description, never this one. Nothing here names an app, a repo,
|
||||
# a vendor or a house convention — the catalog ships to every install (rule 115).
|
||||
# a vendor or a house convention — the catalog ships to every install.
|
||||
_SEED = (
|
||||
("CI & Release", "ci-and-release",
|
||||
"How the project is verified and shipped: pipelines, runners, image/artifact builds, release tagging and rollback."),
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""rules gain a trigger, a tier, canon tags and typed edges (milestone 307
|
||||
step 3, decision note 3026)
|
||||
"""rules gain a trigger, a tier, canon tags and typed edges
|
||||
|
||||
Revision ID: 0088
|
||||
Revises: 0087
|
||||
@@ -31,8 +30,8 @@ down_revision = "0087"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
# Kept in one place so upgrade and the CHECK agree by construction (rule 36:
|
||||
# a whitelisted value means DROP + ADD CONSTRAINT in the same migration —
|
||||
# Kept in one place so upgrade and the CHECK agree by construction (a
|
||||
# whitelisted value means DROP + ADD CONSTRAINT in the same migration —
|
||||
# there is no prior constraint here, so the pair is created together).
|
||||
_TIERS = ("always_on", "conditional")
|
||||
_RELATION_KINDS = ("co_surfaces", "overrides", "elaborates")
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""rule_embeddings — rules become findable by meaning (milestone 307 step 4,
|
||||
decision note 3026)
|
||||
"""rule_embeddings — rules become findable by meaning
|
||||
|
||||
Revision ID: 0089
|
||||
Revises: 0088
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""a rule can carry its own check — verify_with, expires_when, verified_at
|
||||
(milestone 312 step 1)
|
||||
|
||||
Revision ID: 0090
|
||||
Revises: 0089
|
||||
@@ -11,10 +10,9 @@ know they did. A CONSTRAINT is a fact about someone else's software: a
|
||||
runner's shell, a bot's config, a tool that exists. Nobody is present when
|
||||
that goes false.
|
||||
|
||||
Milestone 307's rulebook audit found nine stale sites. Every one was a
|
||||
constraint; not one norm had rotted. One of them had been telling every
|
||||
session to skip database-backed tests for weeks while the integration lane
|
||||
sat green in the workflow.
|
||||
What goes stale in a rulebook is the constraints, not the norms — and a
|
||||
stale constraint keeps instructing every session that loads it, long after
|
||||
the world it described has moved.
|
||||
|
||||
Three nullable columns, so a rule can say how to check itself:
|
||||
|
||||
@@ -31,7 +29,7 @@ none of them. A null `verify_with` is not an omission — it is the honest
|
||||
marker of "this one is a decision, and there is nothing to go and check."
|
||||
That signal only works if the field stays empty wherever it belongs empty.
|
||||
|
||||
No CHECK constraint is involved, so rule 36 does not apply here. Nothing is
|
||||
No CHECK constraint is involved. Nothing is
|
||||
backfilled: a migration cannot invent a check any more than 0088 could
|
||||
invent a trigger.
|
||||
"""
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""task_kind gains 'spike' — the investigation, not the change
|
||||
(milestone 312 step 5)
|
||||
|
||||
Revision ID: 0091
|
||||
Revises: 0090
|
||||
@@ -12,12 +11,12 @@ end of it. "Find out whether the runner can be given a bash shell" is not
|
||||
work, and filing it as work makes a finished investigation look like an
|
||||
abandoned change.
|
||||
|
||||
It is the record a failed check asks for. Milestone 312 gave rules a
|
||||
It is the record a failed check asks for. Rules carry a
|
||||
`verify_with`; when one of those fails, the rule is wrong and the next move
|
||||
is often to go and find out what replaced it. `notes.arose_from_id` already
|
||||
exists (0065), so that constraint -> spike link needs no further schema.
|
||||
|
||||
Rule 36: `task_kind` is gated by a CHECK whitelist, so the value and the
|
||||
`task_kind` is gated by a CHECK whitelist, so the value and the
|
||||
widened constraint land in the SAME migration — DROP then ADD, exactly as
|
||||
0065 did when it introduced 'issue'. Adding the value and constraining it
|
||||
later leaves a window where the database accepts anything.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""a note can carry its own check — verify_with, expires_when, verified_at
|
||||
(milestone 317 step 1)
|
||||
|
||||
Revision ID: 0092
|
||||
Revises: 0091
|
||||
@@ -32,8 +31,7 @@ Three nullable columns:
|
||||
|
||||
WHICH ROWS THESE ARE FOR. `notes` is one table holding notes, tasks,
|
||||
snippets and processes, so these columns land on all of them. Only non-task,
|
||||
non-snippet records are OFFERED them (milestone 317 decisions 1 and 2, gated
|
||||
at the service in step 2): a task's decay is its status, and a snippet
|
||||
non-snippet records are OFFERED them (gated at the service): a task's decay is its status, and a snippet
|
||||
already carries a richer, location-aware verdict in `data.verification`. The
|
||||
columns exist on the other rows and stay null there; a gate that lives in
|
||||
the schema would have meant a partial index or a CHECK across three columns
|
||||
@@ -44,7 +42,7 @@ value of the sweep is that its output is short. A null `verify_with` is not
|
||||
an omission; it is the honest marker of "this one is a decision, and there
|
||||
is nothing to go and check."
|
||||
|
||||
No CHECK constraint is involved, so rule 36 does not apply. Nothing is
|
||||
No CHECK constraint is involved. Nothing is
|
||||
backfilled: a migration cannot invent a check.
|
||||
"""
|
||||
import sqlalchemy as sa
|
||||
@@ -69,9 +67,8 @@ def upgrade() -> None:
|
||||
#
|
||||
# Still a sequential scan's job at this size, and an index on
|
||||
# (verified_at) filtered to `verify_with IS NOT NULL` would be maintained
|
||||
# on every note write to serve one operator-initiated query. If step 3's
|
||||
# live acceptance measures otherwise, add it there against a real plan
|
||||
# rather than guessing here.
|
||||
# on every note write to serve one operator-initiated query. If a real
|
||||
# plan says otherwise, add it then rather than guessing here.
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""rules gain an edit history — rule_versions (milestone 323 step 1)
|
||||
"""rules gain an edit history — rule_versions
|
||||
|
||||
Revision ID: 0093
|
||||
Revises: 0092
|
||||
@@ -7,12 +7,9 @@ Create Date: 2026-08-29
|
||||
The sibling `note_versions` has had for a long time. A note's every meaningful
|
||||
edit is snapshotted, and the design-system note calls that history "the
|
||||
changelog". A RULE — which binds behaviour on every session that loads it —
|
||||
had nothing: an edit destroyed what it used to say, with no record anywhere.
|
||||
|
||||
Rescoping rule 79 on 2026-08-29 is what surfaced it. The superseded statement
|
||||
had to be hand-copied into a task log to survive the edit (#3237), which is
|
||||
not a process, it is a person remembering. The more consequential record had
|
||||
the weaker protection.
|
||||
had nothing: an edit destroyed what it used to say, with no record anywhere,
|
||||
and keeping a superseded statement meant a person remembering to copy it
|
||||
somewhere. The more consequential record had the weaker protection.
|
||||
|
||||
Three things are deliberately NOT copied from note_versions, and each is a
|
||||
guard that exists there for a reason that does not hold here:
|
||||
@@ -31,7 +28,7 @@ guard that exists there for a reason that does not hold here:
|
||||
CASCADE: deleting a user must not erase the history of the rules they edited.
|
||||
The edit still happened and the rule still binds because of it.
|
||||
|
||||
No CHECK constraint, so rule 36 does not apply. Nothing is backfilled — a
|
||||
No CHECK constraint is involved. Nothing is backfilled — a
|
||||
migration cannot invent the text a rule used to have, and inventing "the
|
||||
current text, as of now" would be worse than an empty history, because it
|
||||
would look like a record of an edit that never occurred.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""add rule_usage_events — was a surfaced rule ever read? (milestone 333 step 1)
|
||||
"""add rule_usage_events — was a surfaced rule ever read?
|
||||
|
||||
Revision ID: 0094
|
||||
Revises: 0093
|
||||
@@ -9,18 +9,15 @@ table to arrive after `rule_embeddings` and `rule_versions` — each one added
|
||||
because the rule side kept inheriting machinery built for notes and getting
|
||||
the weaker version of it.
|
||||
|
||||
WHAT IT MEASURES. The write-path standing-rule arm is the only retrieval
|
||||
surface in Scribe whose usefulness cannot be observed, and — not coincidentally
|
||||
— the only one that has never declined to fire. Over 30 days it took 296 calls,
|
||||
returned something on every one, and cleared its threshold 100% of the time,
|
||||
while every other surface declines most of the time (#3311). That is either a
|
||||
perfectly tuned surface or a bar it cannot fail to clear, and `retrieval_logs`
|
||||
WHAT IT MEASURES. A standing-rule arm that returns something on every call
|
||||
and clears its threshold every time is either a perfectly tuned surface or a
|
||||
bar it cannot fail to clear, and `retrieval_logs`
|
||||
cannot tell them apart: it records what the ranker scored, never whether the
|
||||
hint was any use.
|
||||
|
||||
WHY NOT A rule_id COLUMN ON note_usage_events. The row shares no note-specific
|
||||
fields and the aggregate readout is the same shape, which is the strongest case
|
||||
for sharing that note #3163 admits. What decides against it is identity at
|
||||
for sharing there is. What decides against it is identity at
|
||||
RESTORE: `note_usage_events`'s importer maps `note_id` through `note_id_map`
|
||||
and drops what does not resolve. A rule id parked in that column would come
|
||||
back from a backup silently reattached to whatever note took that number —
|
||||
@@ -34,8 +31,8 @@ and dies with it; telemetry outlives the row it describes. Deleting a rule must
|
||||
not erase the evidence that it was surfaced forty times and opened never, since
|
||||
that evidence is exactly the case for having deleted it.
|
||||
|
||||
No CHECK on `event`, matching the note twin. Rule 36 governs adding a value to
|
||||
a column that is already gated; it does not require gating one that never was,
|
||||
No CHECK on `event`, matching the note twin. DROP + ADD governs adding a value
|
||||
to a column that is already gated; it does not require gating one that never was,
|
||||
and a two-member enum whose members are written by two functions in one module
|
||||
is not where that discipline earns its cost.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""add retrieval_logs.suppressed_count — tell a ranker decline from a repeat (#3497)
|
||||
"""add retrieval_logs.suppressed_count — tell a ranker decline from a repeat
|
||||
|
||||
Revision ID: 0095
|
||||
Revises: 0094
|
||||
@@ -20,9 +20,8 @@ the dropped rows never come back and there is nothing to count.
|
||||
NULLABLE, AND THE NULL IS THE POINT. A surface that does not measure
|
||||
suppression stores NULL, not 0, and the readout renders it as "not measured"
|
||||
rather than "none". Defaulting to 0 would make an unmeasured surface look like
|
||||
a perfectly clean one — the exact substitution of an artifact for a
|
||||
measurement that #3311 made and that #3497 exists to correct. Doing it again,
|
||||
in the migration that fixes it, would be its own small joke.
|
||||
a perfectly clean one — the substitution of an artifact for a measurement
|
||||
that this column exists to prevent.
|
||||
|
||||
No backfill for the same reason: existing rows genuinely do not know, and
|
||||
saying so is the honest state. `retrieval_logs` is not restored from backup,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""add retrieval_logs.best_available_score — the score the bar rejected (#3670)
|
||||
"""add retrieval_logs.best_available_score — the score the bar rejected
|
||||
|
||||
Revision ID: 0096
|
||||
Revises: 0095
|
||||
@@ -34,7 +34,7 @@ NULLABLE, AND UNBACKFILLED, for the reason 0095 spells out: a row written
|
||||
before this shipped genuinely does not know what its best rejected candidate
|
||||
scored, and saying so is the honest state. A 0.0 default would read as "the
|
||||
corpus had nothing remotely relevant" — an artifact standing in for a
|
||||
measurement, which is the whole defect this milestone corrects.
|
||||
measurement, which is the defect this column corrects.
|
||||
|
||||
`retrieval_logs` is not restored from backup, so no importer changes.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""add retrieval_logs.best_available_id — WHICH record the bar refused (#3807)
|
||||
"""add retrieval_logs.best_available_id — WHICH record the bar refused
|
||||
|
||||
Revision ID: 0097
|
||||
Revises: 0096
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""rules gain a `kind` — a preference is a rule that does not bind (#3849)
|
||||
"""rules gain a `kind` — a preference is a rule that does not bind
|
||||
|
||||
Revision ID: 0098
|
||||
Revises: 0097
|
||||
@@ -37,7 +37,7 @@ install upgrades and every existing row keeps the force it had. That is the
|
||||
same reasoning 0088 used for `tier`, and it is the reason both are safe to
|
||||
apply without reading the data first.
|
||||
|
||||
The CHECK is created with the column (rule 36: there is no prior constraint,
|
||||
The CHECK is created with the column (there is no prior constraint,
|
||||
so the pair is created together — a value added to it LATER does DROP + ADD
|
||||
in one migration).
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ Create Date: 2026-09-11
|
||||
`pre_tool_rule` retrieves against the RAW COMMAND TEXT and `write_path_rule`
|
||||
against the code being written, so whatever was on the command line or in the
|
||||
buffer is what `record_retrieval` wrote into `retrieval_logs.query`. A command
|
||||
that exported a token stored the token (#3925).
|
||||
that exported a token stored the token.
|
||||
|
||||
`services/retrieval_telemetry.scrub_secrets` closes that going forward — the
|
||||
value never reaches the column. It cannot reach BACKWARDS, and this does: it
|
||||
|
||||
@@ -4,14 +4,14 @@ Revision ID: 0100
|
||||
Revises: 0099
|
||||
Create Date: 2026-09-11
|
||||
|
||||
Milestone 394. Every rule now reaches a session by retrieval — because
|
||||
Every rule reaches a session by retrieval — because
|
||||
something it is about to do made the rule relevant — and the machinery that
|
||||
delivered rules unconditionally goes with it.
|
||||
|
||||
WHAT GOES, AND WHERE IT CAME FROM
|
||||
|
||||
- ``rules.tier`` and its ``ck_rules_tier`` CHECK (migration 0088). Dropping
|
||||
the column takes the constraint with it. Rule 36 is about ADDING a value to
|
||||
the column takes the constraint with it. DROP + ADD is about ADDING a value to
|
||||
a live whitelist, which needs DROP + ADD in the same migration; it does not
|
||||
speak to removing the column outright, and saying so here is cheaper than
|
||||
the next reader wondering whether it was forgotten.
|
||||
|
||||
@@ -4,12 +4,12 @@ Revision ID: 0101
|
||||
Revises: 0100
|
||||
Create Date: 2026-09-15
|
||||
|
||||
Milestone 414. A rule lives in a rulebook topic, where it is GLOBAL, or on one
|
||||
project, and retrieval reads that home directly (step 1). Subscriptions were
|
||||
the last thing that pretended a rulebook reached some projects and not others,
|
||||
and after milestone 394 they changed nothing a session received — only what a
|
||||
project's rule LISTING showed. Operator, 2026-09-15: "we have global and
|
||||
project scoped rules, we don't need the subscriptions now."
|
||||
A rule lives in a rulebook topic, where it is GLOBAL, or on one project, and
|
||||
retrieval reads that home directly. Subscriptions were the last thing that
|
||||
pretended a rulebook reached some projects and not others, and with no
|
||||
always-on tier they changed nothing a session received — only what a
|
||||
project's rule LISTING showed. Global and project-scoped rules cover what
|
||||
subscriptions were for.
|
||||
|
||||
WHAT GOES
|
||||
|
||||
@@ -19,8 +19,8 @@ WHAT GOES
|
||||
there is nothing to mute; a project that departs from a global rule writes
|
||||
a project rule with an ``overrides`` relation, which says why.
|
||||
- The ``subscribe_rulebooks`` key inside ``projects.inception.choices``, and
|
||||
the ``exclude_always_on_rulebooks`` key milestone 394 left behind in the
|
||||
same place. Both describe decisions that can no longer be made; a stored
|
||||
the ``exclude_always_on_rulebooks`` key the retired always-on tier left
|
||||
in the same place. Both describe decisions that can no longer be made; a stored
|
||||
record carrying them would be read back as a choice the product offers.
|
||||
|
||||
IRREVERSIBLE, AND THE DOWNGRADE SAYS SO
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""milestone_embeddings — a plan becomes findable by meaning (milestone 415)
|
||||
"""milestone_embeddings — a plan becomes findable by meaning
|
||||
|
||||
Revision ID: 0102
|
||||
Revises: 0101
|
||||
@@ -9,8 +9,8 @@ lives in — could not be found at all. So "is there already a plan for this?"
|
||||
had no tool, and a project whose roadmap was written as milestones had every
|
||||
later plan opened as a new milestone beside the one that already described it.
|
||||
|
||||
The sibling of rule_embeddings (0089), for the reasons its model docstring and
|
||||
note 3163 give. The vectors are DERIVED: nothing is backfilled here, the startup
|
||||
The sibling of rule_embeddings (0089), for the reasons its model docstring
|
||||
gives. The vectors are DERIVED: nothing is backfilled here, the startup
|
||||
backfill writes them.
|
||||
"""
|
||||
import sqlalchemy as sa
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
"""retrieval_tuning_events — why a floor is where it is (#4102)
|
||||
"""retrieval_tuning_events — why a floor is where it is
|
||||
|
||||
Revision ID: 0103
|
||||
Revises: 0102
|
||||
Create Date: 2026-09-17
|
||||
|
||||
Milestone 416 stops shipping similarity thresholds as values somebody has to
|
||||
defend, and hands the adjustment to the model that reads the surface's own
|
||||
telemetry. The operator's decision:
|
||||
|
||||
"the floor should be chosen and adjusted by the model using it… the user
|
||||
should be able to touch it but the model should be the thing handling it 9
|
||||
times out of 10."
|
||||
Similarity thresholds are not values somebody has to defend: the model that
|
||||
reads the surface's own telemetry adjusts them, and the operator can still
|
||||
touch them.
|
||||
|
||||
The number itself already has a home — the generic settings table. What has no
|
||||
home is the ARGUMENT, and once the values move on their own the argument is the
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"""retrieval_tuning_events carries the space each number was measured in (#4104)
|
||||
"""retrieval_tuning_events carries the space each number was measured in
|
||||
|
||||
Revision ID: 0104
|
||||
Revises: 0103
|
||||
Create Date: 2026-09-17
|
||||
|
||||
Milestone 416 step 6. A retrieval floor is a cosine distance in ONE embedding
|
||||
A retrieval floor is a cosine distance in ONE embedding
|
||||
model's geometry, computed over documents cut one particular way. Change the
|
||||
model and every score moves at once; change the chunker and the same record
|
||||
embeds different text. Either way a number chosen before the change is a
|
||||
@@ -16,7 +16,7 @@ merely unknown.
|
||||
the startup backfill re-embeds precisely what is stale instead of wiping the
|
||||
table. These two columns are that idea applied to the tuned numbers.
|
||||
|
||||
TWO COLUMNS, NOT ONE (rule 149). A reader has to be able to say WHICH half
|
||||
TWO COLUMNS, NOT ONE. A reader has to be able to say WHICH half
|
||||
moved: a new embedding model and a re-cut document shape invalidate the same
|
||||
numbers for different reasons, and a fused `"<model>@<n>"` could only report
|
||||
that something changed.
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
"""note_usage_events records WHICH project the reader was in (#4196, #3735)
|
||||
"""note_usage_events records WHICH project the reader was in
|
||||
|
||||
Revision ID: 0105
|
||||
Revises: 0104
|
||||
Create Date: 2026-09-20
|
||||
|
||||
Milestone 385. `RetrievalLog` has carried `project_id` from the start, so
|
||||
`RetrievalLog` has carried `project_id` from the start, so
|
||||
"this record was SURFACED on project B" has always been answerable. The usage
|
||||
table never had one, so "this record was OPENED on project B" never was — and
|
||||
the two cannot be joined to recover it, because there is no session identity
|
||||
server-side (see the NoteUsageEvent docstring, which rules that out on
|
||||
purpose).
|
||||
|
||||
That gap sits exactly on the question milestone 385 exists to answer. A
|
||||
lesson's whole claim is that it reaches a session on a project it was not
|
||||
written on; step 8's acceptance is "retrieved on a different project, at the
|
||||
moment it applies, AND opened". Surfacing cross-project: answerable. Opening:
|
||||
That gap sits exactly on the question lessons exist to answer. A lesson's
|
||||
whole claim is that it reaches a session on a project it was not written on:
|
||||
"retrieved on a different project, at the moment it applies, AND opened". Surfacing cross-project: answerable. Opening:
|
||||
answerable. Both at once: not, until this column.
|
||||
|
||||
WHICH PROJECT THIS IS, because the name is ambiguous and the wrong reading
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"""rule_usage_events carry an outcome, not just a read (#4212, milestone 419)
|
||||
"""rule_usage_events carry an outcome, not just a read
|
||||
|
||||
Revision ID: 0106
|
||||
Revises: 0105
|
||||
Create Date: 2026-09-20
|
||||
|
||||
Milestone 419's first step. `rule_usage_events` can say a rule was SURFACED
|
||||
`rule_usage_events` can say a rule was SURFACED
|
||||
and that it was PULLED. It cannot say what happened next, so these two
|
||||
sessions leave identical telemetry:
|
||||
|
||||
@@ -12,16 +12,14 @@ sessions leave identical telemetry:
|
||||
- a rule surfaced, opened, and silently ignored.
|
||||
|
||||
The second is the more urgent by a distance, and it is the one the readout
|
||||
cannot name. That is the whole of what this milestone is about, measured on a
|
||||
session where three of seven misses were caught by the operator and none by
|
||||
the system.
|
||||
cannot name, and it is what an outcome column is for.
|
||||
|
||||
TWO NEW EVENT VALUES, AND NO CHECK MIGRATION. `event` was created in 0094 as
|
||||
plain `sa.Text()` with no constraint — checked in the migration itself, not
|
||||
assumed from the model — so `applied` and `departed` join `surfaced` and
|
||||
`pulled` without a DROP/ADD pair. Rule 36 governs CHECK-whitelisted columns
|
||||
`pulled` without a DROP/ADD pair. That pair is for CHECK-whitelisted columns
|
||||
and this is not one; noted explicitly because the next reader will reach for
|
||||
rule 36 here, and should be able to see in one place why it does not bite.
|
||||
it here, and should be able to see in one place why it does not apply.
|
||||
|
||||
THE THIRD STATE IS DERIVED, AND THAT IS NOT A SHORTCUT. Read-and-silently-
|
||||
unchanged is the absence of an outcome, and it has to be: an agent that knew
|
||||
@@ -29,8 +27,8 @@ it was ignoring a rule would not be ignoring it. There is no honest way to ask
|
||||
for that event, so nothing here tries. `applied` and `departed` are reported;
|
||||
the third state is what is left over when a rule was pulled and neither
|
||||
arrived. A schema that offered an `ignored` value would collect nothing and
|
||||
read as though it had measured something, which is the #3311 failure — a
|
||||
statistic that cannot vary being mistaken for a finding.
|
||||
read as though it had measured something — a statistic that cannot vary
|
||||
being mistaken for a finding.
|
||||
|
||||
`detail` CARRIES THE WHY OF A DEPARTURE, and is the reason this is a column
|
||||
rather than two more bare event strings. A departure without its reason is
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""system_embeddings — a charter becomes an ANSWER, not just a filter (#4251)
|
||||
"""system_embeddings — a charter becomes an ANSWER, not just a filter
|
||||
|
||||
Revision ID: 0107
|
||||
Revises: 0106
|
||||
@@ -13,8 +13,7 @@ to one, and an agent asking where a record belonged had to read every charter
|
||||
or guess.
|
||||
|
||||
The fourth sibling of note_embeddings (0067), rule_embeddings (0089) and
|
||||
milestone_embeddings (0102), and for the same reason note 3163 gives about the
|
||||
third: the row could be shared, the search cannot. "Where does this belong?"
|
||||
milestone_embeddings (0102), and for the same reason as the third: the row could be shared, the search cannot. "Where does this belong?"
|
||||
is a different question from "what prior art is there?", and no note or rule
|
||||
search can answer it, because a charter is not a note.
|
||||
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
"""trigger_leaves_the_stored_title — a snippet's and lesson's title is its name (milestone 427)
|
||||
"""trigger_leaves_the_stored_title — a snippet's and lesson's title is its name
|
||||
|
||||
Revision ID: 0108
|
||||
Revises: 0107
|
||||
Create Date: 2026-09-23
|
||||
|
||||
Snippets and lessons stored their title as `subject — trigger`, because the
|
||||
join is what makes these kinds rank on the situation they apply to (#2485) and
|
||||
join is what makes these kinds rank on the situation they apply to and
|
||||
the stored title WAS the embedded one. Every surface that shows a title then
|
||||
showed the trigger too: menu lines, lists and search rows ran to 1,500–3,000
|
||||
characters, and an injected repeat spent all of it again.
|
||||
|
||||
The trigger's home is `data` (decision #4157), and since this milestone the
|
||||
join happens at embed time (`embeddings.document_title`). This revision
|
||||
The trigger's home is `data`, and the join happens at embed time (`embeddings.document_title`). This revision
|
||||
rewrites the rows already stored.
|
||||
|
||||
EXACT-SUFFIX, READ FROM THE ROW'S OWN MIRROR. A title is only rewritten when
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""embeddings_record_their_model — a vector says whose space it lives in (#4132)
|
||||
"""embeddings_record_their_model — a vector says whose space it lives in
|
||||
|
||||
Revision ID: 0109
|
||||
Revises: 0108
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""task_claims — a task can say a session is working it (milestone 381 step 2)
|
||||
"""task_claims — a task can say a session is working it
|
||||
|
||||
Revision ID: 0110
|
||||
Revises: 0109
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""lesson_rule_links — a lesson points at the rule it is an instance of
|
||||
(milestone 440 step 1, #4196)
|
||||
|
||||
Revision ID: 0111
|
||||
Revises: 0110
|
||||
@@ -21,8 +20,8 @@ down_revision = "0110"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
# One place, so the CHECK and the model's LINK_STATES cannot drift (rule 36:
|
||||
# a new value later means DROP + ADD CONSTRAINT in the same migration).
|
||||
# One place, so the CHECK and the model's LINK_STATES cannot drift (a new
|
||||
# value later means DROP + ADD CONSTRAINT in the same migration).
|
||||
_STATES = ("suggested", "confirmed", "rejected")
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""lesson_no_rule — "no rule fits" is a recorded answer (milestone 440 step 2,
|
||||
#4631)
|
||||
"""lesson_no_rule — "no rule fits" is a recorded answer
|
||||
|
||||
Revision ID: 0112
|
||||
Revises: 0111
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""system_path_patterns — a System names the files that are its area
|
||||
(milestone 444 step 3, #4756)
|
||||
|
||||
Revision ID: 0113
|
||||
Revises: 0112
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""system_usage_events — were an area's rulings read once its files were
|
||||
touched? (milestone 444 step 4, #4757)
|
||||
touched?
|
||||
|
||||
Revision ID: 0114
|
||||
Revises: 0113
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""retrieval_judgments — a reviewer's verdict on each line of a logged menu
|
||||
(#4772)
|
||||
|
||||
Revision ID: 0115
|
||||
Revises: 0114
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""moment_mappings — an install's own corrections to which actions reach which
|
||||
moment (milestone 458 step 2)
|
||||
moment
|
||||
|
||||
Revision ID: 0116
|
||||
Revises: 0115
|
||||
@@ -8,7 +8,7 @@ Create Date: 2026-10-05
|
||||
The moments and their default actions are code; this table holds what an
|
||||
install adds ("make ship" is a deliver here) and the defaults it switches off.
|
||||
User-owned configuration, so it cascades with the user. No CHECK on `effect`,
|
||||
which the service validates (rule 36).
|
||||
which the service validates.
|
||||
"""
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""rule_moments — the moments of work a rule arrives at (milestone 458 step 3)
|
||||
"""rule_moments — the moments of work a rule arrives at
|
||||
|
||||
Revision ID: 0117
|
||||
Revises: 0116
|
||||
@@ -28,7 +28,7 @@ def upgrade() -> None:
|
||||
sa.Column("moment", sa.Text(), primary_key=True),
|
||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=True),
|
||||
)
|
||||
# The delivery read (step 4) asks "which rules are on this moment?", the
|
||||
# The delivery read asks "which rules are on this moment?", the
|
||||
# opposite direction from the primary key.
|
||||
op.create_index("ix_rule_moments_moment", "rule_moments", ["moment"])
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"""rule_moment_judgments — whether a rule belongs on a moment, and who said so
|
||||
(milestone 458 step 7, #4925)
|
||||
|
||||
Revision ID: 0118
|
||||
Revises: 0117
|
||||
@@ -23,8 +22,8 @@ branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
# One place each, so the CHECKs and the model's JUDGMENT_STATES / SOURCES
|
||||
# cannot drift (rule 36: a new value later means DROP + ADD CONSTRAINT in the
|
||||
# same migration).
|
||||
# cannot drift (a new value later means DROP + ADD CONSTRAINT in the same
|
||||
# migration).
|
||||
_STATES = ("suggested", "confirmed", "rejected")
|
||||
_SOURCES = ("pass", "signal", "edit")
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""rule_moment_judgments.misfire — a mount reported as arriving where it does
|
||||
not apply (milestone 458 step 7b, #4955)
|
||||
not apply
|
||||
|
||||
Revision ID: 0119
|
||||
Revises: 0118
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""family canon — platforms, family ideas, the adoption ledger and its decision
|
||||
log (milestone 463 step 1)
|
||||
log
|
||||
|
||||
Revision ID: 0120
|
||||
Revises: 0119
|
||||
@@ -13,7 +13,7 @@ reason), or owed. These tables hold that.
|
||||
- `platforms` — a GLOBAL catalog, the canonical_systems shape: no owner, slug
|
||||
is the match key. Seeded with generic technology names only. Nothing here
|
||||
names an app, a repo or a house convention: the catalog ships to every
|
||||
install (rule 115).
|
||||
install.
|
||||
- `project_platforms` — which platforms a project is (declared / detected /
|
||||
rejected). Membership is what makes "is this in family?" a lookup.
|
||||
- `family_ideas` — a NOTE's family state. No new record type: any notes row
|
||||
@@ -39,7 +39,7 @@ branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
# One place per whitelist, so each CHECK and the model's tuple cannot drift
|
||||
# (rule 36: a new value later means DROP + ADD CONSTRAINT in one migration).
|
||||
# (a new value later means DROP + ADD CONSTRAINT in one migration).
|
||||
_MEMBERSHIP = ("declared", "detected", "rejected")
|
||||
_IDEA_STATUSES = ("candidate", "canon", "retired")
|
||||
_ADOPTION_STATUSES = ("unassessed", "adopted", "variant", "exempt", "owed")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""retire the report_preference arm's rows (milestone 500 step 4)
|
||||
"""retire the report_preference arm's rows
|
||||
|
||||
Revision ID: 0121
|
||||
Revises: 0120
|
||||
@@ -6,8 +6,8 @@ Create Date: 2026-10-09
|
||||
|
||||
The fixed-question arm that searched for completion-report preferences when a
|
||||
task closed is gone: the reply shapes and the preferences mounted beside them
|
||||
now arrive on the moments (milestone 500 step 3). Its rows go with it (rule
|
||||
22 — no legacy to preserve), because each one would otherwise mean something
|
||||
now arrive on the moments. Its rows go with it (there is no legacy to
|
||||
preserve), because each one would otherwise mean something
|
||||
different once the arm is no longer registered:
|
||||
|
||||
- `retrieval_logs` / `retrieval_judgments` — a source missing from the
|
||||
@@ -21,11 +21,10 @@ different once the arm is no longer registered:
|
||||
- `settings` — the arm's floor and budget keys, which nothing reads.
|
||||
|
||||
COST IS BOUNDED BY AN INDEX, NOT BY THE TABLE. A migration runs at boot
|
||||
against the live tables, which CI never has (lesson #5221). `retrieval_logs`
|
||||
against the live tables, which CI never has. `retrieval_logs`
|
||||
and `retrieval_judgments` are indexed on `source`. `rule_usage_events` is not,
|
||||
so its delete is also bounded by `created_at` (indexed): the arm shipped with
|
||||
milestone 409 step 4, decided 2026-09-14, so no row of it predates
|
||||
`ARM_BORN`, and the scan covers weeks rather than the table's whole history.
|
||||
so its delete is also bounded by `created_at` (indexed): no row of the arm
|
||||
predates `ARM_BORN`, and the scan covers weeks rather than the table's whole history.
|
||||
|
||||
Not reversible: the arm is not coming back, so neither are its rows.
|
||||
"""
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""Seal forge-connection tokens at rest (milestone 523)
|
||||
"""Seal forge-connection tokens at rest
|
||||
|
||||
Revision ID: 0122
|
||||
Revises: 0121
|
||||
|
||||
Reference in New Issue
Block a user