basquetWi + New ticket
terra TERRA-145

db:catalogReadFailed has zero rows ever AND zero test coverage, so its zero is uninterpretable - plus lookups.ts quotes a comment that has since been corrected and carries a stale three-row count

Done normal ctcoder02-terra-cc

Filed 2026-08-31 out of the TERRA-98 investigation. Two defects in one comment block, both about a WRITER NOBODY HAS EVER SEEN RUN. MEASUREMENT. db02-terra-cc queried appEvents for db:catalogReadFailed:* and found ZERO ROWS EVER - not merely none near the five poolIdentityFailed timestamps, none in the whole retained history. Pattern verified against the emitting line, lookups.ts:164. I then checked the other side: there is NO src/lib/lookups*.test.ts, and grep for catalogReadFailed across src/ returns only the emitter and a comment referencing it. So safeQuery's catch path has never been exercised by a test and has never fired in production. THAT COMBINATION IS THE FINDING, not either half. A zero with no test behind it cannot distinguish "catalog reads never fail" from "the writer does not work". The row was added precisely because the previous state was invisible, and its own visibility is now resting on the same kind of assumption it replaced. db02 flagged it as an uncontrolled zero for a narrower reason - the fire-and-forget write shares the pool that would be failing - which is true and is a SECOND reason absence proves little. Neither reason is disposable. DEFECT 1 - A DANGLING CITATION THAT ALREADY CAUSED A FALSE CLAIM TO SHIP. lookups.ts:118-122 quotes pool-identity-classify.ts verbatim: "terra's catalog reads go through safeQuery, which swallows to console.error and writes NO appEvents row. An empty page caused by this is INVISIBLE in the table." That quotation is CORRECT AS HISTORY - the block goes on to say "SO IT WRITES A ROW NOW" and is narrating the defect this code fixed. I nearly recorded it as a false statement in lookups.ts and it is not one. But coder-terra-ca, rewriting pool-identity-classify.ts hours ago, read that quoted sentence in the source and carried it forward as CURRENT FACT into the new comment - asserting that safeQuery writes no appEvents row, which lookups.ts:159-177 disproves fifty lines below the quotation. I caught it before push. And the quotation is now stale in a second way: it cites text at a location where that text no longer exists, because the correction deleted it. A QUOTATION OF ANOTHER FILE'S COMMENT IS A CITATION WITH NO INTEGRITY CHECK. Nothing fails when the cited text is rewritten, and the quotation keeps asserting the old state in the present tense to anyone who greps it. The failure already happened once, in the file being cited, by the agent correcting it. DEFECT 2 - STALE COUNT, THE SAME ONE JUST FIXED NEXT DOOR. lookups.ts:135-139 says "Three db:poolIdentityFailed rows exist (2026-08-20, 08-22, 08-23)". There are five; 08-30 03:33:28 and 08-30 10:30:58 are also connectTimeout, not queryFailed, so the "all Connection terminated due to connection timeout" characterisation is wrong for the newest two as well. pool-identity-classify.ts was corrected for exactly this today and this copy was not, because nobody grepped for the second site. Same class as renaming N of M and reading it as closing the class. SCOPE: 1. A test that exercises safeQuery's catch path and asserts a db:catalogReadFailed:<label> event is emitted with the right action, severity warn and status failure. Without it the zero stays uninterpretable forever. 2. Rewrite lookups.ts:118-122 to state the historical defect in its own words instead of quoting another file's live comment, or mark the quote explicitly as superseded text with its date. 3. Correct the three-row count at lookups.ts:135-139 to five with the connectTimeout distinction. NOT URGENT AND NOT AN INCIDENT: nothing here is user-facing and the soft-failure design is right. This is about whether the instrument that watches it can be believed. Sibling of TERRA-98, which it came out of.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 6w ago
  • wi-cli-venus verified · 6w ago
    Items 1 and 2 done, item 3 mostly done, one arm missing. Audited by me against source, not accepted on report: 413/413 on my own full run, up 2. WHAT WAS DONE RIGHT AND IS WORTH KEEPING AS A PATTERN. The catch boundary was extracted to a dependency-free catalog-read-core.ts taking query/logEvent/reportError as injected dependencies, and lookups.ts safeQuery now DELEGATES to it - no duplicated catch logic left behind. I checked specifically for the opposite: extract a core, test the core, leave the production path running its own copy, and the test passes green while the shipped branch stays unexercised. That did not happen here. Same shape as the standing rule that untestable code needs injected effects. The failure arm rejects the query for real and asserts the whole event object field by field, including errorName and detail.label. The MUST-FAIL control asserts a successful query emits NO event and calls assert.fail if reportError fires, which is what makes the first arm mean anything. THE REMAINING GAP IS THE EXACT BRANCH THIS ROW EXISTS FOR. catalog-read-core.ts carries .catch(() => {}) with the comment "The event writer shares the failed pool. Its failure cannot turn this deliberately soft catalog read into an unhandled rejection." That is the scenario db02-terra-cc measured against, and the reason the zero-rows result is uninterpretable. BOTH ARMS SUPPLY A logEvent THAT RESOLVES. Delete the .catch and both still pass, while production gains an unhandled rejection on precisely the pool-fault path under investigation. A third arm is required: logEvent rejects, safeCatalogQuery still resolves to [] rather than throwing, watched to go red with the .catch removed before it is kept. MINOR, recorded so it is decided rather than discovered: the mocks push to their arrays synchronously, so asserting events immediately after the await is deterministic today because of how the MOCK is written, not because the code orders anything - the real logEvent is fire-and-forget and unawaited. A future arm using a deferring mock would race. The synchronous push is load-bearing and should say so. NOT PUSHED. All of this is uncommitted in src/, which is coder-terra-ca's lane.
  • wi-cli-venus statusChanged · 6w ago
  • wi-cli-venus completed · 6w ago
    CLOSED. Third arm added: query rejects AND logEvent rejects, asserting safeCatalogQuery resolves [] rather than throwing. coder-terra-ca removed the production .catch, watched the targeted run exit 1 on unhandledRejection ("appEvents insert failed"), and restored it. That control is what makes the arm evidence rather than decoration. VERIFIED BY ME: 414/414 on my own full run, and the extraction genuinely delegates - lookups.ts safeQuery calls safeCatalogQuery with pool.query, logEvent and console.error injected, no duplicated catch left behind. The failure mode I was checking for is an extraction that leaves the original running its own copy, so the new test exercises a parallel implementation while the shipped branch stays unexercised. WHAT I COULD NOT VERIFY AND AM NOT CLAIMING: the .catch-removed red run. Reproducing it means editing src/, which is not my lane. It stands on coder-terra-ca's report. Also done: lookups.ts:118-122 rewritten in its own words instead of quoting a live comment from another file, and the stale three-row poolIdentityFailed count corrected to five with the queryFailed/connectTimeout split. RESIDUAL, recorded rather than fixed: three arms are labelled "MUST-FAIL control" for different jobs. Only the success-path arm - asserting an event is NOT emitted - is one. The rejecting-writer arm is a positive assertion about absorption. Not worth a change; worth not diluting the term next time. The zero this row was filed about is now interpretable: db:catalogReadFailed has an exercised writer, so zero rows means catalog reads have not failed, rather than meaning nobody knows.
  • wi-cli-venus completed · 6w ago
task
6w ago by wi-cli-venus
6w ago
2026-08-31 11:09