111 - Quality gates and PIT debt register - 2026-05-25
Summary
This audit converts the repository quality-gate findings into tracked engineering work.
The app build and TypeScript pass, but merge readiness must be defined by the full gate set:
- Copy lint: no em dash and no disallowed emoji in user-facing copy.
- ESLint on source files, excluding generated vendor bundles.
- Unit tests via Vitest.
- Next.js production build.
- Public smoke e2e against the deployed app until preview smoke is wired.
Operational changes
- CI now uses the repository Node version from
.nvmrcto avoid local Node 22 vs CI Node 20 drift. - CI runs copy lints, ESLint, unit tests, typecheck, build, and public smoke e2e.
- Vendored Swagger UI browser bundles are ignored by ESLint because they are generated assets served by
/docs/, not maintained source. - The HTTP migration endpoint has been removed from the app runtime. Schema changes should run through Prisma migrations and deploy-time jobs.
- Stripe webhooks fail closed while billing remains dormant. The route must not return 200 until signature verification and fulfillment are implemented.
PIT debt classification
The point-in-time issues in src/lib/signals.ts and src/lib/winning-strategy.ts are credibility debt, not cosmetic cleanup.
They can affect reported historical performance because some historical scoring paths still use current snapshots:
- Current
Company.marketCapfor historicalpctOfMarketCap, size bucket and mid-cap inclusion. - Current Yahoo composite inputs for historical momentum, analyst and fundamentals components.
- Current analyst and fundamentals snapshots for older declarations.
Ship rule
Any future strategy change that changes score weights, universe filters, role multipliers, family multipliers, market filters or performance claims must either:
- Implement point-in-time snapshots for the affected feature, or
- Explicitly disable that feature for historical rows where no PIT value exists, or
- Include an audit note quantifying why the remaining leakage is acceptable.
Without one of those three conditions, the change should not be described as a clean backtest improvement.
Implementation backlog
- Add
CompanyMarketCapSnapshotor equivalent PIT market-cap table and use it for historical scoring and strategy filters. - Add PIT analyst/fundamental snapshots, or clamp those components to neutral for historical declarations older than the live enrichment window.
- Split live scoring from historical scoring so current snapshot features remain allowed for live recommendations but do not contaminate OOS claims.
- Re-run the V14e EU_strict OOS proof after PIT fixes and update
STRATEGY_PROOF.