Files
sentryagent-idp/openspec/vv_audit/VV_ISSUE_003.md
SentryAgent.ai Developer 7441c9f298 fix(vv): resolve all 6 V&V issues — field trial unblocked
All findings from the inaugural LeadValidator audit resolved and
confirmed. Release gate: PASS.

VV_ISSUE_002 (BLOCKER): 15 OpenAPI specs verified present covering
all 20 route groups (46 endpoints documented in docs/openapi/)

VV_ISSUE_003 (MAJOR): Remove any types from src/db/pool.ts —
replaced pool.query shim with unknown[] + Object.defineProperty,
zero any types, eslint-disable suppressions removed

VV_ISSUE_004 (MAJOR): Remove raw Pool from ScaffoldController and
HealthDetailedController — injected AgentRepository/CredentialRepository
and DbProbe interface respectively; added CredentialRepository.findActiveClientId()

VV_ISSUE_005 (MAJOR): Add unit tests for 5 untested services —
ComplianceStatusStore, EventPublisher, MarketplaceService,
OIDCTrustPolicyService, UsageService

VV_ISSUE_006 (MAJOR): Add integration tests for 7 missing route
groups — analytics, billing, tiers, webhooks, marketplace,
oidc-trust-policies, oidc-token-exchange

VV_ISSUE_001 (MINOR): Create missing design.md and tasks.md in 4
OpenSpec archives — all archives now complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 04:52:47 +00:00

71 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# VV_ISSUE_003 — `any` type usage in src/db/pool.ts
**Status:** RESOLVED
**Severity:** MAJOR
**Category:** TYPE_VIOLATION
**Logged by:** LeadValidator
**Date:** 2026-04-07
**Audit phase:** Phase C — TypeScript Standards Audit
## Finding
The PRD (Sections 6.4 and 4.5) states: "No `any` types — ever." and "TypeScript strict mode:
zero `any` types." The `tsconfig.json` correctly enables `noImplicitAny: true` and all strict
flags.
Despite this, `src/db/pool.ts` contains explicit `any` type casts on two lines (lines 89 and
91), with ESLint suppression comments (`eslint-disable-next-line @typescript-eslint/no-explicit-any`)
added to bypass the linting rule. While the developer included a comment explaining the
technical reason (wrapping the pg query method in a shim that is difficult to type precisely),
the PRD standard is absolute: zero `any` types, with no exceptions granted.
The intent of the standard is to eliminate unsafe escape hatches that weaken TypeScript's
type safety guarantees. Using `any` in the database pool layer — a critical path component —
is particularly concerning since this wraps every database query in the application.
## Evidence
**File:** `src/db/pool.ts`, lines 8891:
```typescript
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const originalQuery = pool.query.bind(pool) as (...args: any[]) => Promise<any>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(pool as any).query = async (...args: any[]): Promise<any> => {
```
There are 5 `any` occurrences on these two lines:
- `(...args: any[]) => Promise<any>` — line 89
- `(pool as any)` — line 91
- `(...args: any[]): Promise<any>` — line 91
The surrounding comment (lines 8487) acknowledges the issue and explains the rationale, but
does not resolve it per PRD standards.
## Required Action
Replace the `any` types in `src/db/pool.ts` with properly typed alternatives. Options:
1. Use the `pg` library's exported `QueryConfig`, `QueryResultRow`, and overload signatures
to type the query wrapper correctly without resorting to `any`.
2. Use generic types: `<T extends QueryResultRow>(...args: Parameters<Pool['query']>) => Promise<QueryResult<T>>`
3. If the shim cannot be typed without `any` due to pg's type definitions, document the
specific technical constraint and seek CEO approval for a formal exemption. An exemption
does NOT mean leaving it as-is — it means a tracked, acknowledged deviation.
Remove the `eslint-disable-next-line` suppression comments once the `any` types are resolved.
## CTO Response
Agreed. The `any` types in pool.ts were a sanctioned workaround for pg's overloaded `Pool.query` signature. The correct solution is to use `unknown[]` rest parameters and `Object.defineProperty` to replace the method without widening the pool reference to `any`. The pool's typed interface is preserved at the type level for all callers; only the internal shim uses `unknown` as the safe alternative to `any`.
## Resolution
**Fixed in:** `src/db/pool.ts`
Replaced the two `any`-typed lines and two `eslint-disable-next-line` suppressions with a clean `Object.defineProperty` shim:
- `originalQuery` is typed via `pool.query.bind(pool)` — no cast needed
- The replacement function uses `unknown[]` rest params and `Promise<unknown>` — zero `any` types
- TypeScript compiles clean (`npx tsc --noEmit` — 0 errors)
- Pool's typed interface (`Pool['query']`) unchanged for all callers