Skip to content

refactor: ponytail audit cuts 3,633 net lines and 7 dependencies - #61

Merged
Programcode merged 15 commits into
mainfrom
t3code/ponytail-audit
Sep 22, 2026
Merged

Programcode merged 15 commits into
mainfrom
t3code/ponytail-audit

Conversation

@Programcode

@Programcode Programcode commented Sep 22, 2026 •

Copy link
Copy Markdown
Owner

Completes the ponytail audit against current main. The current diff removes 3,633 net lines across 90 files and drops 7 dependencies while preserving the active workspace evidence and practice release.

What changed

  • Removed duplicate toast infrastructure and dead UI.
  • Replaced five dependencies with browser or platform features.
  • Unified CORS and entitlement checks across Edge Functions, including the gift-trial path that had diverged between ai and ai-stream.
  • Removed the unreachable direct-provider pricing table and its only tsx consumer.
  • Removed the in-browser mock AI provider. E2E now intercepts the Edge Function boundary, so tests keep the real request and response-validation path.
  • Removed the unused Deno test shim and single-use navigation measurement harness while retaining its captured evidence.
  • Consolidated duplicate store tests without reducing store coverage.
  • Removed 105 orphaned translation keys from each locale.
  • Kept the security, runtime, CSP, noindex, and entitlement regression checks that protect shipped behavior.
  • Kept the workspace conversion and review code required by the active collaboration milestone.
  • Synced the branch with current main and preserved workspace evidence and practice support in AI requests.
  • Hid workspace navigation and routes when VITE_COLLABORATION_URL is absent. Production no longer sends users into an editor that cannot connect. A later collaboration deployment can enable the routes by configuring a WSS endpoint and allowing its origin in CSP.

Verification on the current head

  • npm run docs:check
  • npm run lint
  • npm run typecheck
  • App tests: 1,027 passed across 105 files, with 90.84% statement coverage
  • Collaboration service: 30 passed
  • Edge Functions: 238 passed
  • Production build and bundle-boundary check passed
  • Desktop and mobile Chromium: 226 passed, 6 intentional workspace skips, 0 failed, retries disabled
  • Independent current-tree review: no confirmed Critical or Important findings

The latest local database replay gate could not start because another active workspace trial owns the repository-wide Supabase lock. The previous gate passed 262 pgTAP checks, concurrency checks, and both real collaboration journeys. The PR's isolated database-tests check is running on this head and remains required before merge.

The persistent collaboration service still has no Milestone 1 production deployment. This PR fails closed by hiding those routes unless a collaboration endpoint is configured; it does not invent or publish an unsupported WebSocket target.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Workspace navigation and routes are now hidden or unavailable when collaboration is not configured.
    • Toast notifications follow the app’s theme and include an accessible close button.
    • Exported files now download through the browser’s built-in download flow.
  • Updates

    • AI features now use OpenRouter for requests and model selection; local mock responses are no longer available.
    • AI cost reporting uses the charge reported by the provider, and shows cost as unknown when no charge is available.

Programcode and others added 10 commits September 21, 2026 08:25
The app mounted two complete toast stacks side by side: a hand-rolled
Radix reducer (toast.tsx + hooks/use-toast.ts + toaster.tsx + a
re-export shim, 326 lines, 20 call sites) and sonner (5 call sites).

Keep sonner. hooks/use-toast.ts becomes a 27-line adapter that preserves
the `{ title, description, variant }` call shape, so the 94 existing call
sites are untouched. AskPage's one ToastAction becomes a sonner action
object.

next-themes was imported only by ui/sonner.tsx, and its provider was
never mounted, so useTheme() always returned the "system" default.
Read the real theme from settings-store instead.

Also removed, all with zero importers:
- ui/form.tsx (133 lines); all four forms use react-hook-form directly
- src/App.css (42 lines of Vite template leftovers)
- components/landing/index.ts barrel (one consumer, blocked tree-shaking)
- 10 unused CSS classes and their keyframes in index.css (-97 lines)
- public/favicon copy.{ico,png,jpeg} (724 KB unreferenced)

-2 deps: next-themes, @radix-ui/react-toast

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Each of these was a dependency doing what the platform or an existing
module already does.

- date-fns: one formatDistanceToNow call. Added formatRelativeTime to
  lib/date-format.ts using Intl.RelativeTimeFormat, next to the existing
  Intl formatters.
- file-saver: five saveAs calls. Added a 10-line saveBlob helper using
  URL.createObjectURL and <a download>. Tests now capture downloads
  through the real DOM path instead of mocking the module.
- react-window: one <List> over a personal source library, with no
  measurement justifying virtualization. Plain overflow-y-auto map.
  SourceRow now takes a source instead of index/style/aria plumbing.
- async-mutex: per-document locks in the collaboration service. Replaced
  with an 18-line promise-chain acquireLock that keeps the same
  beforeSync-acquire / afterHandleMessage-release handoff. All 10
  collaboration tests pass, including crash and lock-loss cases.
- @jam.dev/sdk: the published SDK only assigns a callback to
  window.__jam__.exports.metadata. Inlined that; the recorder itself
  already loads via script tags in jam-loader.ts.

Also collapsed the AIProvider interface and DEFAULT_PROVIDERS array,
which held exactly one provider whose isAvailable() returned true, into
AVAILABLE_MODELS plus a PROVIDER_ID constant. ModelSelector computed a
providerName it never rendered. Its test mocked the entire 10-model
catalog by hand; it now uses the real one.

New tests: formatRelativeTime units and fallback, jam metadata global.

-6 deps: date-fns, file-saver, @types/file-saver, react-window,
async-mutex, @jam.dev/sdk

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ALLOWED_ORIGINS + getCorsHeaders were copy-pasted into 11 edge functions and
had already drifted. ai-stream/ carried a reworded copy of ai/'s entitlement
gating, and the two had diverged on the gift-trial fallback.

- _shared/cors.ts: one origin list, opt-in dev origins, per-function methods
- _shared/entitlements.ts: ai/'s (stricter, gift-trial-aware) implementation
- demo-code-login: guard sanitizeRedirectTo against the non-http capacitor
  scheme the shared list now carries
- native-cors.test.ts replaced with behavioural cors.test.ts + entitlements.test.ts

190 edge tests pass; all 11 functions typecheck under deno.
Every request routes through OpenRouter, which reports the authoritative
account charge per response. calculateRequestCost returned on the openrouter
branch before any pricing lookup, so the transcribed per-model rate table, its
long-context/cache-TTL math, the three direct-provider usage normalizers, and
the refresh script were all dead.

- delete _shared/model-pricing.ts and scripts/update-model-pricing.ts
- collapse calculateRequestCost to the reachable OpenRouter path
- drop normalizeOpenAI/Anthropic/Google usage and their dead-branch tests
- drop the tsx dev dependency, which existed only for the refresh script
- keep docs/pricing-snapshots/ as historical evidence; note the supersession
  in plans/model-cost-accounting.md

184 edge tests pass, docs:check/lint/typecheck clean.
The mock provider let the app answer AI calls without leaving the browser,
which meant the tests exercising it skipped the request path and the schema
validation that ship to users. e2e now intercepts the edge-function call
instead, so the real client code runs against canned payloads.

The Deno compat shim existed so Vitest could re-run edge-function tests under
jsdom. `npm run test:edge` already runs them under the runtime they ship on.

Meta-tests trimmed to the assertions that guard something: the Vercel file
keeps the CSP/security headers and noindex rules and drops the restatement of
build config and cache rules; runtime-contracts keeps the Sentry capability
probe and the staging-capture policy and drops the deploy-workflow greps.
security-hardening.test.ts is repointed at _shared/entitlements.ts rather than
deleted, since it guards the entitlement-bypass fix.
806 lines of Playwright matrix driver that ran twice, in September 2026, to
produce docs/performance/smooth-navigation-baseline/. Nothing calls it: no
script entry, no workflow, only the README that documents its output. The
evidence it captured stays; the README now points at the commit to recover the
harness from if the matrix is ever re-run.

Its only test greped the source for a variable assignment, so it goes too.
settings-store had four files (819 lines, 56 tests) and session-store had three
(1,309 lines, 51 tests), all mocking the same Supabase client and re-asserting
the same setters from different angles. Each is now one file: 26 settings tests
and 34 session tests.

Coverage of both stores is unchanged or better, verified per file:
settings-store 94.21% stmts / 91.52% branch with the same uncovered lines;
session-store 87.88% stmts / 86.23% funcs / 90.88% lines, branches 75.31% (was
74.89%), no newly-uncovered function or branch. The handful of assertions that
only the deleted files reached (folder rename/delete, setFolderActive,
removeSource, the loading setters, getFeatureConfig hit, system-prompt
persistence) were carried over rather than dropped.
Keys no key lookup can reach: not a literal `t('...')`, not the prefix of any
template-literal key the app builds (`nav.${item.key}` and friends), not a
plural sibling of a used base, and not a `labelKey`/`nameKey` string anywhere
in src or e2e. Mostly leftovers from renamed keys (`generate.title` after
`generate.saveCase`, `login.email` after `login.emailLabel`) and two removed
screens' worth of crossfire and sparring.setup copy.

Three locale files shrink by 112 lines each. i18n.test.ts still passes: the
three files stay key-for-key identical with no empty values.
formatSparringDuration and the five sparring label getters were byte-identical
in export-utils.ts and pdf-export-utils.ts. One module now, imported by both.

The audit also proposed collapsing all three exporters behind a single
sections(result) model with thin emitters. Measured, that premise does not
hold: outside these helpers and the import block, DOCX and PDF share 6
identical lines, and each shares under 10 with the Google Docs function. The
three emit genuinely different document models — jsPDF draws 7 tables plus
accent bars and manual page-break arithmetic, docx builds Paragraph/TextRun
trees with no tables at all, and export-gdoc emits index-ranged Google Docs API
requests from Deno, where it cannot import from src/ anyway. A shared section
IR would be a fourth representation to translate three ways, not a deletion.
…e AI fixture

The deleted mock provider delayed 1-2s per feature and sized its contention
list from the requested length. Fulfilling instantly meant loading states never
rendered, and a fixed 2 contentions failed the client's expectedContentionCount
check for standard/comprehensive runs. All 4 animation-polish tests pass.
Copilot AI lite review requested due to automatic review settings September 22, 2026 17:11
@vercel

vercel Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
debate-navigator Ready Ready Preview Sep 22, 2026 10:11pm UTC

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: e95fde9e-2cdc-4156-a10a-c8050c3b9568

📥 Commits

Reviewing files that changed from the base of the PR and between 833d112 and af9347e.

📒 Files selected for processing (1)
  • e2e/navigation-performance.spec.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The changes consolidate AI routing on OpenRouter and centralize Edge Function CORS and entitlement logic. They update browser toast and download handling, gate collaboration routes, remove selected client utilities, and revise tests and measurement tooling.

Changes

AI Requests and Usage

Layer / File(s) Summary
OpenRouter model catalog and configuration
src/lib/ai/providers/types.ts, src/components/ModelSelector.tsx, src/lib/stores/settings-store.ts, src/lib/observability.ts, src/test/components/ModelSelector.test.tsx, src/test/providers.test.ts, src/test/stores/settings-store*.test.ts
The model contract now uses PROVIDER_ID and AVAILABLE_MODELS. Feature configuration normalization no longer preserves local mock settings. Tests cover the model catalog and persisted configuration migration.
OpenRouter request routing and e2e stubs
src/lib/ai/client.ts, src/lib/ai/streaming.ts, src/lib/ai/providers/mock-provider.ts, e2e/fixtures/ai-responses.ts, e2e/animation-polish.spec.ts, src/test/ai/*, src/test/sparring-ai.test.ts
AI feature calls and streaming now use provider openrouter. The local mock provider was removed, and end-to-end tests now stub AI Edge Function responses.
Shared entitlements and reported-cost accounting
supabase/functions/_shared/entitlements.ts, supabase/functions/_shared/entitlements.test.ts, supabase/functions/_shared/cost.ts, supabase/functions/_shared/cost.test.ts, supabase/functions/_shared/model-pricing.ts, supabase/functions/ai/index.ts, supabase/functions/ai-stream/index.ts, plans/model-cost-accounting.md, scripts/update-model-pricing.ts, supabase/README.md, src/test/security-hardening.test.ts
Shared entitlement helpers now provide rate-limit checks and usage logging for AI Edge Functions. Cost calculation uses reported OpenRouter charges. The model-pricing module and refresh script were removed, and related tests now check shared behavior.

Shared Edge Function CORS

Layer / File(s) Summary
Shared CORS policy and tests
supabase/functions/_shared/cors.ts, supabase/functions/_shared/cors.test.ts, supabase/functions/_shared/native-cors.test.ts
The shared CORS module defines allowed origins, development-origin validation, fallback behavior, and method headers. Tests cover the shared policy; the native CORS test file was removed.
Edge Function CORS adoption
supabase/functions/admin/index.ts, supabase/functions/announcements/index.ts, supabase/functions/create-checkout/index.ts, supabase/functions/create-portal/index.ts, supabase/functions/demo-code-login/index.ts, supabase/functions/export-gdoc/index.ts, supabase/functions/import-source/index.ts, supabase/functions/redeem-promo/index.ts, supabase/functions/share/index.ts
These Edge Functions now use the shared CORS helper instead of local implementations. demo-code-login rejects redirect URLs outside HTTP or HTTPS before checking the origin.

Browser UI and Utilities

Layer / File(s) Summary
Collaboration route and navigation gating
src/App.tsx, src/components/layout/AppLayout.tsx, e2e/navigation-performance.spec.ts
Workspace routes and the workspaces navigation item are added only when COLLABORATION_URL is set. End-to-end coverage checks that the link is absent and /app/workspaces displays a 404 when collaboration is unavailable.
Sonner toast adapter and app integration
src/components/ui/sonner.tsx, src/hooks/use-toast.ts, src/App.tsx, src/pages/AskPage.tsx, src/components/ui/toast.tsx, src/components/ui/toaster.tsx, src/components/ui/use-toast.ts, src/test/hooks/use-toast.test.ts, e2e/hungarian-parity.spec.ts, src/test/components/StreamingIndicator.test.tsx, package.json
The app renders Sonner directly, and the toast hook routes messages through Sonner. The local toast wrapper files were removed, retry actions use Sonner’s action shape, and related tests use the updated close-button selector and adapter behavior.
Browser downloads and export helpers
src/lib/export-sparring-labels.ts, src/lib/export-utils.ts, src/lib/pdf-export-utils.ts, src/test/helpers/downloads.ts, src/test/setup.ts, src/test/export-utils*.test.ts, src/test/export-telemetry.test.ts, src/test/sparring/exports.test.ts, package.json
DOCX exports now use object URLs and anchor clicks instead of file-saver. Shared sparring label helpers serve both exporters, and tests capture downloads through the DOM.
Source library list rendering
src/pages/LibraryPage.tsx, package.json
The source list no longer uses react-window. It renders visible sources in a fixed-height scrolling container.
Client integrations, styles, and content
src/lib/jam-metadata.ts, src/pages/LandingPage.tsx, src/components/landing/index.ts, src/components/ui/form.tsx, src/index.css, src/App.css, src/locales/*.json, package.json
Jam metadata registration now assigns a callback on window.__jam__. Landing components are imported directly, and unused UI components, styles, dependencies, and locale entries were removed.

Test and Measurement Cleanup

Layer / File(s) Summary
Navigation measurement retirement
scripts/measure-navigation-performance.mjs, src/test/performance-measurement-script.test.ts, docs/performance/smooth-navigation-baseline/README.md
The navigation measurement script and its test were removed. The baseline README records the harness removal, recovery commit, and captured run commands.
Browser navigation and timing tests
e2e/home-navigation.spec.ts, e2e/navigation-performance.spec.ts
Navigation-intent checks now poll for requests. The onboarding test records the timer delay and asserts it is 0; the cold-route test uses a 60-second timeout.
Test harness and runtime-scope changes
vitest.config.ts, src/test/deno-compat.ts, src/test/deno-assert-shim.ts, src/test/runtime-contracts.test.ts
Vitest no longer loads Deno compatibility helpers or includes Supabase tests. The Deno shim files were removed, and the runtime-contract test retains a smaller set of checks.
Session and settings store test consolidation
src/test/stores/session-store.test.ts, src/test/session-store.test.ts, src/test/stores/session-store-coverage.test.ts, src/test/stores/session-store-extended.test.ts, src/test/stores/settings-store.test.ts, src/test/stores/settings-store-additional.test.ts, src/test/stores/settings-store-branches.test.ts, src/test/stores/settings-store-extended.test.ts
Session-store and settings-store coverage is consolidated into the main suites. Older split suites were removed, and the remaining tests cover persistence, hydration, reset, and migration behavior.

Estimated code review effort: 5 (Critical) | ~110 minutes


Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Essentials by visiting https://app.coderabbit.ai/settings/billing.

Comment @coderabbitai help to get the list of available commands.

@Programcode

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Preserve the Ponytail deletions while retaining current model routing, localization, date formatting, and collaboration test requirements from main.\n\nCo-Authored-By: Claude Code <noreply@anthropic.com>
@Programcode

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Programcode

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Programcode

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Programcode

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Programcode and others added 2 commits September 22, 2026 21:00
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
@Programcode

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Head commit changed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@Programcode Programcode changed the title refactor: ponytail audit — cut 4,285 net lines and 7 dependencies refactor: ponytail audit cuts 3,633 net lines and 7 dependencies Sep 22, 2026
Co-Authored-By: Claude Code <noreply@anthropic.com>
@Programcode

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Programcode

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Programcode

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Programcode
Programcode merged commit 68c53f5 into main Sep 22, 2026
7 checks passed
@Programcode
Programcode deleted the t3code/ponytail-audit branch September 23, 2026 00:02

This branch was successfully deployed

1 active deployment
Preview — af9347e5 Deployed Sep 22, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants