Skip to content

orb(testing): the 99% coverage gate cannot catch the defect classes that actually bite us — four missing test categories #9063

Description

@JSONbored

A full-day audit found ~30 real production defects that a 99%-patch-coverage suite never caught. The diagnosis matters more than any individual bug: none of them is a coverage gap. All sit on lines tests execute, and several sit on lines tests assert about.

The dispositive evidence

src/selfhost/pg-queue.ts and src/selfhost/sqlite-queue.ts contain the byte-identical unguarded while (await processOne()) shutdown bug (#9007). pg-queue is on the Codecov ignore list; sqlite-queue is fully graded at 99% patch with a 193 KB dedicated test file — and missed it too. Coverage was never the binding variable.

Four blind spots, none of which coverage can measure

Class Why coverage can not see it Defects
Time — TTL, restart, shutdown, quiescence Coverage is a statement about the forward path; these bugs are about state left behind after it completes #9007, #8998
Absence — a branch that emits nothing Every branch that does emit is asserted; nothing enumerates branches against events #9008, #9015
Reachability — a state enterable but not exitable No test asks "can every state be left?" #9009
Cross-path parity — two paths that must behave alike Each is unit-tested in its own file with its own vocabulary; nothing compares them #9015

Fixtures make the bugs unrepresentable

  • test/helpers/d1.ts ~188-214: the SELFHOST_TRANSIENT_CACHE used by essentially every test is a plain Map whose set/claim discard ttlSeconds entirely, and it is rebuilt fresh per createTestEnv(). So AI_REVIEW_LOCK_TTL_SECONDS — the only recovery mechanism for an orphaned lock — is a no-op in 100% of tests, and "restart" is unrepresentable by construction. (advanceTimersByTime appears 35x in the suite, never once against a lock TTL.)
  • test/unit/selfhost-redis-cache.test.ts ~15: fakeRedis() ignores EX, so no Redis-backed expiry is testable anywhere.

Tests that actively pin the bugs

Location Problem
test/unit/agent-actions.test.ts ~132 Asserts manual-review is never removed — pins #9009; must be rewritten, not extended
test/unit/selfhost-sqlite-queue.test.ts ~3320, ~3337 await q.stop(); expect(await q.size()).toBe(0) — pins "stop() drains everything"
test/unit/selfhost-sqlite-queue.test.ts ~3341 "stop() waits for an in-flight pump" — only assertion is expect(done).toBe(true) over a one-job queue; true with and without the bug
test/unit/ai-review-advisory.test.ts ~861 Claims the lock, never releases, asserts aiCalls === 0 — a permanently starved PR satisfies this
test/unit/queue.test.ts ~4857 Labeled INVARIANT, runs the real reputation-skip path in block mode — and asserts a D1 read count, not the safety property

Aggregate scan (20,961 test blocks, 54,970 assertions): ~95% assertion-bearing, zero snapshot tests. The suite is not coverage filler — the problem is the kind of assertion, not the quantity.

Highest-value additions, in order

  1. Make test/helpers/d1.ts's cache honor TTL and Date.now() (~20 lines). Single highest-leverage change in the report — converts orphaned-lock/starvation/expiry from unrepresentable to ordinary across all four lock namespaces.
  2. One shutdown test per queue backend (~30 lines). Enqueue 5, start, let one be claimed, await stop(), assert consumed.length === 1 and size() === 4. Fails on today's code in both backends.
  3. Three invariant tests (~150 lines total): audit-branch completeness (catches orb(review): forceAiReview does not bypass the AI-review lock — the re-run button is silently inert behind an orphaned lock (root cause of #9000) #9008), label-removal reachability (catches orb(disposition): manual-review label has no autonomous removal path — every transient hold becomes a permanent human-only stuck state #9009), required-review skip parity (catches orb(security): reputation burst-downgrade fails OPEN — suspected abusers get LESS review (LIVE in prod) #9015). Model on test/contract/pr-disposition-invariants.test.ts — 179 lines and the best-designed file in the repo.
  4. Put the real-Postgres integration suite back on the PR trigger with a service container (it is on: push: main only since 2026-07-24), and add Redis. This makes the pg-queue Codecov exemption honest rather than decorative.

Verdict

Keep the 99% bar exactly where it is — relaxing it buys nothing and costs discipline. It is a floor against carelessness and works as one. Spend the next increment entirely on the four missing categories, not on the number.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.orbGittensory Orb related - maintainer self-hosting analytics.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions