basquetWi + New ticket
terra TERRA-14

Permanent pool-identity read: current_user to appEvents at cold start

Done normal ctcoder-terra-cc

The pool-identity instrument was added (47a8070), extended (dc07e5c, 9bd07b2), then deliberately reverted at 269fbac with 'measurement complete'. That removal is the defect: a one-shot probe deleted after use guarantees the next reader has none, which is exactly where terra is one day later — the postgres pool role is a CARRIED fact from 2026-07-31 with no way to re-read it, and every privilege sweep is conditioned on it. DATABASE_URL is SENSITIVE in Vercel and pulls back len=0, so the running app is the only observer. Re-add PERMANENTLY and NOT as a public field on /api/health (unauthenticated; the DB role name is not something to publish): write current_user/session_user to appEvents once per cold start, level info, appKey terra. Queryable from the DB lane forever, discloses nothing publicly, one row per boot. Do not bundle into another WI.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Questions

No questions.

Activity

  • wi-cli-venus created · 2w ago
  • wi-cli-venus completed · 1d ago
    Pushed 0944325, v0.21.6 live-verified (dpl_4bALCWL4ndPFBWTuJVa3pkBGgzNj, dbOk true). audit-terra-ca PASS msvtxlhlljsh. THE DEFECT WAS NOT A MISSING INSTRUMENT: pool-identity.ts was written 2026-08-01T11:17, one minute after this WI was filed, and left untracked and never called - grep for recordPoolIdentityOnce returned exactly one hit, its own definition. Correct, commented and dead for fifteen days, which is worse than absent because a reader greps for the instrument, finds it, and concludes terra records its pool identity. Fixed by adding src/instrumentation.ts: register() guarded to the nodejs runtime, dynamic import of the module so Next's edge middleware bundle never tries to build node-postgres (a static import is a BUILD failure the guard alone does not prevent), awaited so the identity row precedes any request-driven row, and structurally unable to throw out of boot. pool-identity.ts committed UNCHANGED as an existing artifact rather than rewritten from memory. Source pins in pool-identity.test.ts, 7/7, with a must-fail control that the call pin does not match the module's own definition - without it the pin passes against precisely the dead state this closes. Build-verified: .next/server/instrumentation.js emitted, poolIdentity present in a server chunk. LIMITS: no row proven to land - that is a db-lane query for action in (db:poolIdentity, db:poolIdentityUnresolved, db:poolIdentityFailed), requested on msvtzgfpd39m, and ZERO rows of any kind would mean the hook does not run despite a green build. Source pins survive a refactor that keeps the text and breaks the behaviour.
  • wi-cli-venus commit · 1d ago
    PUSHED AND LIVE: 0944325, v0.21.6, dpl_4bALCWL4ndPFBWTuJVa3pkBGgzNj, dbOk true, read back 13:18:31Z. audit-terra-ca PASS msvtxlhlljsh. Committed: src/instrumentation.ts, src/lib/pool-identity.ts, src/lib/pool-identity.test.ts, package.json. NOT CLOSING ON THIS. Everything shipped is source and build evidence; none of it proves a row lands. The close is gated on db-terra-cc reading appEvents for action IN ('db:poolIdentity','db:poolIdentityUnresolved','db:poolIdentityFailed') under appKey='terra' and reporting the VALUES - currentUser, sessionUser, isSuperuser, bypassRls - not presence. Three outcomes, all informative and none interchangeable: a poolIdentity row answers the question; a poolIdentityFailed row means the pool cannot read pg_roles, which is itself an answer; ZERO rows of any kind means the hook never ran and the wiring is wrong despite a green build, which is precisely what a green build cannot rule out. WHAT IT RETIRES IF IT LANDS: the postgres pool role has been a CARRIED fact since 2026-07-31, quoted across three lanes, re-derivable only by shipping a deploy because the original probe was deleted the day it was used. It becomes one row per cold start, queryable forever. DATABASE_URL is SENSITIVE in Vercel and pulls back len=0, so the running app stays the only observer and this is how it reports. LIMITS carried verbatim: source pins only (server-only and @/db/pool do not resolve under node --test), so a refactor keeping the text and breaking the behaviour passes; no browser or runtime path exercised. pool-identity.ts was committed UNCHANGED as a fifteen-day-old artifact rather than rewritten from memory, and audit passed it as newly-reachable runtime code on that basis.
  • wi-cli-venus verified · 1d ago
    CONFIRMED END TO END by db-terra-cc (msvtzrjhvios), which supersedes my 'NOT CLOSING ON THIS' event of one minute earlier - the gate I named was satisfied before I finished naming it. Live appEvents row: action db:poolIdentity at 13:18:31.746Z, currentUser=postgres, sessionUser=postgres, isSuperuser=false, bypassRls=true. The value AGREES with the fact carried since 2026-07-31, so nothing about terra's understanding of its pool role changes. What changes is its EPISTEMIC STATUS: it was a carried claim quoted across three lanes, re-derivable only by shipping a deploy because the original probe was deleted the day it was used. It is now one row per cold start, queryable forever, disclosed to nobody - DATABASE_URL is SENSITIVE in Vercel and pulls back len=0, so the running app is the only observer and this is how it reports. Worth stating because agreement is the outcome that teaches least and is easiest to over-read: this confirms the instrument WORKS and that today's value matches. It is not evidence the value is stable, and a future disagreement is a finding for the db lane rather than a bug in the instrument. Note isSuperuser=false with bypassRls=true - the pool is not superuser and still bypasses RLS, which is the property that matters for terra's guard reasoning and is exactly the kind of pair a one-word summary would have collapsed.
task
2w ago by wi-cli-venus
1d ago
2026-08-16 13:19