You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tracking issue for the move described in docs/agents/architecture-migration.md. That document is the plan and the rules; this issue is the working state.
4 — derivations are content addressed. Verdict identity becomes (input_hash, recipe_id); model becomes provenance. Migrates the verdict cache; needs a person.
5 — files move to the shape. Last, not first. Includes untangling the api / api.tasks cycle.
Phase 1 inventory (measured 2026-09-10)
148 occurrences of a check-type literal: 87 in src, 61 in tests. Six values exist: closed, clearance, custom, content, plus extraction and comp, which are read or asserted but never written by src. The only place all six are enumerated is a test.
category
src
tests
READ-FILTER (SQL predicates)
58
25
WRITE (recording a verdict)
13
34
DISPATCH (branching on type)
9
0
DECLARATION (lists, enums, indexes)
7
2
The registry belongs in core/checks.py, which is already half of one: its docstring says the prompt and the response model are one pair per check, and it is the import target of both dispatch ladders.
Per-type behaviour varies on six axes, currently spread across seven files: instructions, result schema, verdict extraction lambda, model routing, staleness rule, and cache topology. A registry entry has to carry all six or the ladders come back.
Findings worth acting on regardless of the phase:
routers/jobs.py:518-540 and routers/admin.py:1142-1174 are the same ~30-line dispatch ladder, duplicated and drifted: admin has a hash: addressing mode and a with_reason schema switch that jobs does not.
custom keys its own cache by prompt hash while every other type shares _latest_cache, and its staleness is identity rather than age — which is the entanglement phase 4 removes.
orm.py:722,731 bake check-type literals into two partial indexes, repeated in alembic/versions/f3a4b5c6d7e8. They must move in lockstep with the registry.
Invariant
openapi.json is canon and tests/test_openapi_current.py fails the build when routes and schema disagree. No phase changes an operation's shape. A frontend repo and a browser extension read that contract.
Tracking issue for the move described in
docs/agents/architecture-migration.md. That document is the plan and the rules; this issue is the working state.Phases
import-linterholdscore does not depend on api;core/devseed.pymoved toapi/. Verified the contract can fail.jobs.relisted_at(feat: a posting its feed puts back is read again, so a closure stops being permanent #504) retires into an append-only log.(input_hash, recipe_id); model becomes provenance. Migrates the verdict cache; needs a person.api/api.taskscycle.Phase 1 inventory (measured 2026-09-10)
148 occurrences of a check-type literal: 87 in
src, 61 in tests. Six values exist:closed,clearance,custom,content, plusextractionandcomp, which are read or asserted but never written bysrc. The only place all six are enumerated is a test.The registry belongs in
core/checks.py, which is already half of one: its docstring says the prompt and the response model are one pair per check, and it is the import target of both dispatch ladders.Per-type behaviour varies on six axes, currently spread across seven files: instructions, result schema, verdict extraction lambda, model routing, staleness rule, and cache topology. A registry entry has to carry all six or the ladders come back.
Findings worth acting on regardless of the phase:
routers/jobs.py:518-540androuters/admin.py:1142-1174are the same ~30-line dispatch ladder, duplicated and drifted: admin has ahash:addressing mode and awith_reasonschema switch that jobs does not.clearancehas no staleness rule at all. It is only ever backfilled when missing, so a clearance verdict is never revisited. That is the same class of defect as the closed verdict being permanent, which feat: a posting its feed puts back is read again, so a closure stops being permanent #504 fixed.customkeys its own cache by prompt hash while every other type shares_latest_cache, and its staleness is identity rather than age — which is the entanglement phase 4 removes.orm.py:722,731bake check-type literals into two partial indexes, repeated inalembic/versions/f3a4b5c6d7e8. They must move in lockstep with the registry.Invariant
openapi.jsonis canon andtests/test_openapi_current.pyfails the build when routes and schema disagree. No phase changes an operation's shape. A frontend repo and a browser extension read that contract.