Every ticket as the root of its provenance graph — goal, patch, approval, runs and (as the ticket-class build lands) mandate, manifestations, guarantees, journey, artifacts and children. Rendered through the <<<TicketGraphList>>> tag.
goal
STOP brake on the six "Port route <X> to Go" tickets: #235 agent.prompt, #237 agent.roster,
#238 agent.trail, #239 doc.list, #240 doc.read, #243 doc.repos. Authorized by the operator, on the
condition he set: brake IFF the routes exist in both Go and PHP, because there is no need to make two
sets. VERIFIED — there is exactly ONE set, and it is DATA.
WHY THESE WERE NEVER REAL WORK:
* A route is a ROW of the `api_routes` table (62 rows), not code. Its SQL is admin-authored.
* boot/rest.php: "Data-driven NAMED ROUTES (the stable contract) - endpoints are rows in api_routes".
* congruency-go/db.go: "a reimplementation of the data-driven api_routes engine that boot/rest.php
[has] ... an endpoint is a ROW of the api_routes table".
* BOTH engines read the SAME table. So porting a route was never per-route work - the ENGINE was
ported once, and every row came with it. These six were satisfied the moment the engine landed.
* All six are GET rows, e.g. agent.prompt -> "SELECT agent_id, parent, tools, status, ts...".
PROOF (re-runnable, read-only):
cd congruency-go && CONGRUENCY_STATE_DB=<state>/congruency.sqlite go test . -run TestRouteEquivalence
-> ok. Per-route subtests PASS byte-identical against live rest.php for exactly these six:
agent.prompt, agent.roster, agent.trail, doc.list, doc.read, doc.repos.
WHY BRAKE RATHER THAN CLOSE: there is NO close/resolve route. `ticket.*` offers only create/kind/
progress/assign/approve/lesson; DONE comes only via process_status, which the db refuses without a
registered pair. So a stale-but-satisfied ticket cannot be closed - braking is the available and
honest mechanism. Left ready, each of these invites a dispatcher (or a future least-privilege router)
to burn a worker rediscovering finished work - the same way "162 ready" overstated real work before
the #200 brake.
NOT BRAKED - #236 agent.register and #242 doc.record are WRITE (POST) routes. TestRouteEquivalence
SKIPS all 24 POST routes (verifying them would mutate state), so those two have NO equivalence proof.
They are unverifiable, not satisfied, and remain open deliberately. That blind spot covers the
governance spine - process_status, ticket.create, edge.record, ticket.assign - and is exactly the
class that produced #279, where an unverified write path (process_status ordering) broke every
dispatch. Extending the harness to POST against a throwaway scratch db is the outstanding work.
DO NOT re-dispatch #235/#237/#238/#239/#240/#243.