@massu/core 1.12.0 → 1.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,68 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
+ ## [1.12.2] - 2026-05-18
8
+
9
+ **Security MEDIUM sweep (`plan-2026-05-18-security-medium-sweep`)**. Closes the 5 MEDIUM findings from the post-1.12.0 `massu-security-reviewer` audit-loop with structural drift-guards for each. M-1 IP_HASH_PEPPER consistency (silent-fallback vs throw class), M-2 webhook POST schema symmetry, M-3 Lemon Squeezy webhook idempotency parity with Stripe, M-4 v1 audit UUID echo redaction, M-5 SSO IdP host allowlist (precondition for SSO re-enable). New CR-51 + VR-PEPPER-GUARD + pattern-scanner Check 27.
10
+
11
+ ### Added
12
+
13
+ - **M-1 / CR-51 / VR-PEPPER-GUARD** — `website/src/lib/ip/pepper-guard.ts` exporting `requireIpHashPepper()` + `hashIpWithPepper(ip, { length: 16 | 32 })` as the SOLE allowed reader of the IP hash pepper env var. Production fail-closed via `MissingPepperError`; documented test override via `MASSU_TEST_ALLOW_EMPTY_PEPPER=1`. Closes the structural drift class where `evidence/[id]/download/route.ts:21` silent-fallback diverged from `license/activate/route.ts:34-40` throw.
14
+ - **M-2 / VR-SCHEMA-SYMMETRY** — `webhookCreateSchema` in `src/lib/validations.ts`, symmetric to `webhookUpdateSchema`. `description` capped at 500 chars on BOTH schemas (CR-9 bypass-prevention). `route-schema-symmetry.test.ts` drift-guard scans every `app/api/v1/**/route.ts` POST/PATCH/PUT handler for `*Schema.safeParse` invocation.
15
+ - **M-3 / VR-LS-IDEMPOTENCY** — migration `042_lemon_squeezy_webhook_events.sql` + `lemon_squeezy_event_apply(p_event_id, p_event_type, p_payload, ...)` RPC returning TEXT `processing_status` (`processed_ok` | `duplicate_ignored` | `permanent_failure` | `transient_failure`). Route handler maps each status to HTTP 200/200/422/500 — 422 stops LS retries on permanent failures (Stripe's BOOLEAN return can't carry this contract). Down migration shipped alongside (`.down.sql`) per §6.5 Rollback Plan.
16
+ - **M-4 / VR-V1-NO-UUID-LEAK** — `v1-error-response-no-uuid-leak.test.ts` drift-guard scanning every `app/api/v1/**/route.ts` source for caller-controlled UUID interpolation in error/note response surfaces (`apiError`, `note =`, etc.). `${auth.orgId}` self-echo explicitly permitted (caller's auth context already binds them).
17
+ - **M-5 / VR-SSO-IDP-ALLOWLIST** — `website/src/lib/sso/idp-allowlist.ts` with `SSO_IDP_HOSTS_BY_PROVIDER` constant + `validateSsoUrlAgainstProvider(provider, ssoUrl)` + `inferSsoProviderFromUrl(ssoUrl)`. TLD-aware wildcard host match (`*.okta.com` does NOT match `evil-okta.com`); HTTPS-only scheme enforcement. Covers Okta, Auth0, Azure AD (microsoftonline.com + .us), Google Workspace. Generic OIDC deferred to `plan-B.3-followup` SSO re-enable.
18
+ - **`MASSU_SSO_ALLOWLIST_LOG_ONLY` env-flag** for the M-5 staged rollout — `isSsoAllowlistLogOnly()` in `sso-flag.ts`. Operator runs 24h log-only post-deploy to monitor false-positives before flipping to enforcing.
19
+ - **`scripts/massu-pattern-scanner.sh` Check 27** — bash drift-guard for security-sensitive env-var patterns. 27a flags raw `process.env.<NAME>_PEPPER` outside `lib/<purpose>/<purpose>-guard.ts`; 27b flags any `process.env.<NAME>_(PEPPER|SECRET|KEY) ?? <literal>` silent-fallback adjacent to such reads (framework-platform keys exempt).
20
+ - **CR-51** canonical rule in `.claude/CLAUDE.md`: security-sensitive env vars must use a dedicated guard helper. Three-layer enforcement: pattern-scanner Check 27 + vitest drift-guard + the guard helper is the ONLY allowed reader.
21
+ - 5 new vitest drift-guards: `ip-pepper-guard-usage.test.ts`, `route-schema-symmetry.test.ts`, `lemon-squeezy-event-atomic.test.ts`, `v1-error-response-no-uuid-leak.test.ts`, `sso-idp-allowlist.test.ts` (+23 happy/negative/integration cases for M-5 alone).
22
+
23
+ ### Changed
24
+
25
+ - **Lemon Squeezy webhook route (`src/app/api/lemon-squeezy/webhook/route.ts`)** — 4 handlers (`handleOrderCreated`, `handleLicenseKeyCreated`, `handleOrderRefunded`, `handleSubscriptionCancelled`) refactored to dispatch through `lemon_squeezy_event_apply` RPC. Direct `from('book_purchases').insert` / `from('organizations').update` calls REMOVED from the route. Pre-RPC test-mode mismatch rejection now returns `permanent_failure` (HTTP 422) instead of throwing.
26
+ - **`src/app/api/v1/audit/route.ts:66`** — `${actor}` UUID echo dropped from non-empty-org-no-rows note. New message: "No audit entries for the actor filter in this org. Verify the user is a member of org ${auth.orgId}." Eliminates the UUID-existence-probe side-channel for authenticated API-key holders.
27
+ - **`src/app/api/sso/route.ts`** — invokes `inferSsoProviderFromUrl(ssoConfig.sso_url)` before constructing `redirect_url`. Non-allowlisted host returns 502 with `X-SSO-Validation-Failure: idp-host-not-allowlisted` (or logs-only under `MASSU_SSO_ALLOWLIST_LOG_ONLY=1`).
28
+ - **`src/app/api/sso/callback/route.ts:exchangeOidcCode`** — same allowlist guard applied BEFORE any outbound `fetch()` to the IdP token endpoint. Closes the SSRF-to-IdP vector at the callback layer (P5-007).
29
+ - **`scripts/massu-security-scanner.sh` Check 6** — RLS coverage scanner now excludes `*.down.sql` rollback scripts (CR-46 structural fix; the literal "CREATE TABLE" only appears in their explanatory comments).
30
+ - **`website/src/data/stats.ts`** — Database Tables 44 → 45 (new `lemon_squeezy_webhook_events`), Canonical Rules 16 → 17 (new CR-51). Marketing count drift-guard covers both.
31
+ - **`website/src/__tests__/changelog-parse.test.ts:EXPECTED_COUNT`** bumped 40 → 41.
32
+ - **`website/src/__tests__/migration-grant-discipline.test.ts:SERVICE_ROLE_ONLY_TABLES`** adds `lemon_squeezy_webhook_events: '042_lemon_squeezy_webhook_events.sql'`.
33
+
34
+ ### Fixed
35
+
36
+ - Pre-existing `plan-token-changelog-coverage.test.ts` PTCC-03 failure surfaced during the loop — 3 post-tag chore-commit plan-tokens (`plan-stage-d-medium-sweep`, `plan-stage-e-low-info-sweep`, `plan-2026-05-16-prelaunch-audit`) added to the documented-divergence allowlist with the same rationale pattern as the existing `plan-stage-c-high-batch` entry.
37
+
38
+ ## [1.12.1] - 2026-05-18
39
+
40
+ **Pre-push ↔ CI parity (`plan-2026-05-18-pre-push-ci-parity`)**. Closes the structural drift class surfaced 2026-05-18 when SHA `b26fbb1` passed `pre-push-light` locally but failed CI on 4 distinct gates spread across 3 separate workflow YAMLs (`@massu/types/dist` missing → `ci.yml`, `eslint-rules/` missing from `PUBLIC_DIRS` → `sync-check.yml`, `diff-commands-vs-docs.sh` hardcoded path → `sync-check.yml`, Tarball E2E adapter list stale → `ci.yml`). The two operator-pushed fix attempts `8c6b843` + `d3164f7` fixed the specific instances but left the bug class wide open. This release closes the CLASS via three-layer enforcement.
41
+
42
+ ### Added
43
+
44
+ - **CR-50 / VR-CI-PARITY** — structural pre-push ↔ CI parity drift-guard. Every multi-line shell block (>5 lines) in ANY `.github/workflows/*.yml` (excluding `*.public.yml` mirrors + 6 INFRASTRUCTURE/SECURITY workflows in `WORKFLOW_FILE_EXCLUSIONS`) lives in `scripts/ci-<name>.sh`; every such script is called from `scripts/pre-push-light.sh` OR carries `# CI-ONLY:` opt-out + entry in `CI_ONLY_SCRIPTS` allowlist. Three-layer enforcement: vitest drift-guard `packages/core/src/__tests__/ci-prepush-parity.test.ts` (7 cases, including byte-equivalence mirror-enforcement between TS test sets and bash scanner arrays) + pattern-scanner Check 26 + workspace-build-freshness step `[12/15]`.
45
+ - **`scripts/ci-tarball-e2e.sh`** — extracted Tarball E2E adapter-pack verification. Adapter list filesystem-derived (`find packages/adapter-*`); supports `--quick` mode for pre-push-light.
46
+ - **`scripts/ci-sync-check.sh`** — extracted public-mirror sync verification with `mktemp -d` + `trap cleanup EXIT INT TERM` safety contract; called from both `sync-check.yml` and pre-push-light step `[13/15]`. Secrets scan extended to cover ALL file types (not just `.ts`+`.md`) AND added `rk_test_/rk_live_` restricted-key + `whsec_` webhook-secret regex variants.
47
+ - **`scripts/ci-fresh-install.sh`** (CI-ONLY) — `init --ci` fixture runner with `local` + `published` modes via `$2`. Fixture-name validated against `^[a-z][a-z0-9_-]*$` regex to prevent path traversal.
48
+ - **`scripts/ci-config-drift.sh`** (CI-ONLY) — workspace-shadow-avoiding scratch-dir setup for `massu config check-drift`.
49
+ - **`scripts/lib/mtime-helper.sh`** — cross-platform BSD/GNU `stat` shim with python3 fallback. Sourced by `pre-push-light.sh` step `[12/15]` Workspace Build Freshness.
50
+ - **`scripts/test-ci-parity-regression.sh`** — AC-PARITY-REGRESSION automated test (ephemeral `git clone --no-local` + `git revert 8c6b843 d3164f7` + `npm ci` + pre-push-light exit-code assertion). Cited markers: `PARITY-REGRESSION-TEST: PASS|FAIL|ABORT`.
51
+ - 5 new `pre-push-light.sh` steps: `[0/15]` Clean-state simulation (opt-in via `MASSU_PREPUSH_CLEAN=1`), `[12/15]` Workspace Build Freshness, `[13/15]` Sync Check (auto-gated on `packages/`+`scripts/`+`CHANGELOG.md`+...), `[14/15]` Tarball E2E quick, `[15/15]` Config Drift.
52
+ - 4 bypass env-vars threaded with audit-trail stderr markers mirroring CR-48 precedent: `MASSU_PREPUSH_CLEAN`, `MASSU_SKIP_NEW_STEPS`, `MASSU_PREPUSH_SYNC_CHECK`, `MASSU_SYNC_PUBLIC_CHECK_ONLY`.
53
+
54
+ ### Changed
55
+
56
+ - **`scripts/pre-push-light.sh`** renumbered from `N/11` to `N/15` label scheme (16 total labels — Plan-Token Changelog Currency REMOVED per P2-006 iter-5 resolution; absorbed by `changelog-parse.test.ts` EXPECTED_COUNT drift-guard running via `[6/15] Tests`). `[9/15] Deploy Staleness` parser fixed to scan for first `PASS:|SKIP:|WARN:` line rather than first log line (pre-existing minor bug masked by stderr/stdout merging — pre-push-light now correctly shows SKIP under `MASSU_SKIP_DEPLOY_STALENESS_CHECK=1`).
57
+ - **`scripts/sync-public.sh`** adds `check_public_dirs_completeness()` drift-guard catching future `PUBLIC_DIRS` omissions structurally (greps cross-package test imports). New `MASSU_SYNC_PUBLIC_CHECK_ONLY=1` env-var runs drift-guard then exits 0 with no filesystem side-effects (AC-12 contract).
58
+ - **`.github/workflows/{ci,sync-check,fresh-install-matrix,massu-config-drift}.yml`** — 4 in-scope workflows now delegate to `scripts/ci-*.sh` (thin orchestration); 7 excluded workflows remain inline with per-entry justification comments in `WORKFLOW_FILE_EXCLUSIONS`.
59
+ - **`scripts/massu-pattern-scanner.sh`** adds Check 26 (Pre-push ↔ CI parity). Awk regex covers all YAML block-scalar variants (`|`, `|-`, `|+`, `>`, `>-`, `>+`) — prior `|` only would silently bypass.
60
+ - **`.claude/CLAUDE.md`** adds CR-50 row + VR-CI-PARITY row + inline `### CR-50: Pre-Push Must Mirror CI` block.
61
+ - **`website/CHANGELOG.md`** synced to root CHANGELOG.md byte-equal (drift-guard `website-changelog-matches-root.test.ts`).
62
+ - **`website/src/__tests__/changelog-parse.test.ts:EXPECTED_COUNT`** bumped 39 → 40.
63
+
64
+ ### Fixed
65
+
66
+ - Closes the 2026-05-18 incident class (4 CI-only failure modes on SHAs `b26fbb1`, `8c6b843`, `d3164f7`).
67
+ - `scripts/pre-push-light.sh` step `[9/15]` deploy-staleness status parser pre-existing bug — first log line was the stderr audit-trail marker, not the stdout PASS/SKIP line (CR-9 fix surfaced during multi-perspective review).
68
+
7
69
  ## [1.12.0] - 2026-05-17
8
70
 
9
71
  **Stage E — LOW + INFO sweep (parent plan `plan-2026-05-16-prelaunch-audit`, sub-plan `plan-stage-e-low-info-sweep`)**. Closes the 14-agent pre-launch audit by addressing the residual 71 LOW + INFO items not handled in Stages A–D. Stage E ships ~25 actionable items + 2 mandatory CR-46 drift-guards + 5 deferred-idea/ADR docs for items intentionally not shipped here. Larger refactors (P-E-013 session-start lazy-load, P-E-019 hook spawn-chain consolidation, P-E-025 shared types package) are noted in the sub-plan as 1.12.x follow-up. All audit findings either SHIPPED, DEFERRED-with-doc, or OBSERVED-ONLY — pre-launch audit is closed.
package/dist/cli.js CHANGED
@@ -1173,7 +1173,7 @@ function enqueueSyncPayload(db, payload) {
1173
1173
  }
1174
1174
  function dequeuePendingSync(db, limit = 10) {
1175
1175
  const stale = db.prepare(
1176
- "SELECT id, retry_count, last_error FROM pending_sync WHERE retry_count >= 10"
1176
+ "SELECT id, retry_count, last_error FROM pending_sync WHERE retry_count >= 10 LIMIT 10000"
1177
1177
  ).all();
1178
1178
  if (stale.length > 0) {
1179
1179
  const ids = stale.map((s) => s.id);
@@ -1412,16 +1412,17 @@ function getSessionsByTask(db, taskId) {
1412
1412
  SELECT session_id, status, started_at, ended_at, plan_phase
1413
1413
  FROM sessions WHERE task_id = ?
1414
1414
  ORDER BY started_at_epoch DESC
1415
+ LIMIT 10000
1415
1416
  `).all(taskId);
1416
1417
  }
1417
1418
  function getCrossTaskProgress(db, taskId) {
1418
1419
  const sessions = db.prepare(`
1419
- SELECT session_id FROM sessions WHERE task_id = ?
1420
+ SELECT session_id FROM sessions WHERE task_id = ? LIMIT 10000
1420
1421
  `).all(taskId);
1421
1422
  const merged = {};
1422
1423
  for (const session of sessions) {
1423
1424
  const summaries = db.prepare(`
1424
- SELECT plan_progress FROM session_summaries WHERE session_id = ?
1425
+ SELECT plan_progress FROM session_summaries WHERE session_id = ? LIMIT 10000
1425
1426
  `).all(session.session_id);
1426
1427
  for (const summary of summaries) {
1427
1428
  try {
@@ -19667,7 +19668,7 @@ function traceImports(startFile, dataDb, visited, components, hooks, maxDepth =
19667
19668
  if (maxDepth <= 0 || visited.has(startFile)) return;
19668
19669
  visited.add(startFile);
19669
19670
  const imports = dataDb.prepare(
19670
- `SELECT target_file, imported_names FROM ${t("imports")} WHERE source_file = ?`
19671
+ `SELECT target_file, imported_names FROM ${t("imports")} WHERE source_file = ? LIMIT 10000`
19671
19672
  ).all(startFile);
19672
19673
  for (const imp of imports) {
19673
19674
  const target = imp.target_file;
@@ -19704,7 +19705,7 @@ function findTablesFromRouters(routerNames, dataDb) {
19704
19705
  const tables = /* @__PURE__ */ new Set();
19705
19706
  for (const routerName of routerNames) {
19706
19707
  const procs = dataDb.prepare(
19707
- `SELECT DISTINCT router_file FROM ${t("trpc_procedures")} WHERE router_name = ?`
19708
+ `SELECT DISTINCT router_file FROM ${t("trpc_procedures")} WHERE router_name = ? LIMIT 10000`
19708
19709
  ).all(routerName);
19709
19710
  for (const proc of procs) {
19710
19711
  const absPath = ensureWithinRoot(resolve27(getProjectRoot(), proc.router_file), getProjectRoot());
@@ -19727,7 +19728,7 @@ function findTablesFromRouters(routerNames, dataDb) {
19727
19728
  function buildPageDeps(dataDb, codegraphDb) {
19728
19729
  dataDb.exec(`DELETE FROM ${t("page_deps")}`);
19729
19730
  const pages = codegraphDb.prepare(
19730
- "SELECT path FROM files WHERE path LIKE 'src/app/%/page.tsx' OR path = 'src/app/page.tsx'"
19731
+ "SELECT path FROM files WHERE path LIKE 'src/app/%/page.tsx' OR path = 'src/app/page.tsx' LIMIT 10000"
19731
19732
  ).all();
19732
19733
  const insertStmt = dataDb.prepare(
19733
19734
  `INSERT INTO ${t("page_deps")} (page_file, route, portal, components, hooks, routers, tables_touched) VALUES (?, ?, ?, ?, ?, ?, ?)`
@@ -19776,7 +19777,7 @@ function findAffectedPages(dataDb, file) {
19776
19777
  const directPage = getPageChain(dataDb, file);
19777
19778
  if (directPage) return [directPage];
19778
19779
  const importers = dataDb.prepare(
19779
- `SELECT source_file FROM ${t("imports")} WHERE target_file = ?`
19780
+ `SELECT source_file FROM ${t("imports")} WHERE target_file = ? LIMIT 5000`
19780
19781
  ).all(file);
19781
19782
  const affectedFiles = /* @__PURE__ */ new Set([file, ...importers.map((i) => i.source_file)]);
19782
19783
  let frontier = [...importers.map((i) => i.source_file)];
@@ -19787,7 +19788,7 @@ function findAffectedPages(dataDb, file) {
19787
19788
  const next = [];
19788
19789
  for (const f2 of frontier) {
19789
19790
  const upstreamImporters = dataDb.prepare(
19790
- `SELECT source_file FROM ${t("imports")} WHERE target_file = ?`
19791
+ `SELECT source_file FROM ${t("imports")} WHERE target_file = ? LIMIT 5000`
19791
19792
  ).all(f2);
19792
19793
  for (const imp of upstreamImporters) {
19793
19794
  if (!visited.has(imp.source_file)) {
@@ -19838,7 +19839,7 @@ function buildMiddlewareTree(dataDb) {
19838
19839
  while (queue.length > 0) {
19839
19840
  const current = queue.shift();
19840
19841
  const imports = dataDb.prepare(
19841
- `SELECT target_file FROM ${t("imports")} WHERE source_file = ?`
19842
+ `SELECT target_file FROM ${t("imports")} WHERE source_file = ? LIMIT 10000`
19842
19843
  ).all(current);
19843
19844
  for (const imp of imports) {
19844
19845
  if (!visited.has(imp.target_file) && imp.target_file.startsWith("src/")) {
@@ -19926,7 +19927,7 @@ function findCrossDomainImports(dataDb) {
19926
19927
  const srcPrefix = config.paths.source;
19927
19928
  const srcPattern = srcPrefix + "/%";
19928
19929
  const imports = dataDb.prepare(
19929
- `SELECT source_file, target_file FROM ${t("imports")} WHERE source_file LIKE ? AND target_file LIKE ?`
19930
+ `SELECT source_file, target_file FROM ${t("imports")} WHERE source_file LIKE ? AND target_file LIKE ? LIMIT 10000`
19930
19931
  ).all(srcPattern, srcPattern);
19931
19932
  const crossings = [];
19932
19933
  for (const imp of imports) {
@@ -21491,7 +21492,7 @@ function handleDetail(args2, db) {
21491
21492
  if (!ids || ids.length === 0) return text("Error: ids array is required");
21492
21493
  const placeholders = ids.map(() => "?").join(",");
21493
21494
  const observations = db.prepare(
21494
- `SELECT * FROM observations WHERE id IN (${placeholders}) ORDER BY created_at_epoch ASC`
21495
+ `SELECT * FROM observations WHERE id IN (${placeholders}) ORDER BY created_at_epoch ASC LIMIT 10000`
21495
21496
  ).all(...ids);
21496
21497
  if (observations.length === 0) {
21497
21498
  return text("No observations found for the given IDs.");
@@ -22399,7 +22400,7 @@ function getFeatureImpact(db, filePaths) {
22399
22400
  const affectedFeatureIds = /* @__PURE__ */ new Set();
22400
22401
  for (const filePath of filePaths) {
22401
22402
  const links = db.prepare(
22402
- `SELECT feature_id FROM ${t("sentinel_components")} WHERE component_file = ?`
22403
+ `SELECT feature_id FROM ${t("sentinel_components")} WHERE component_file = ? LIMIT 10000`
22403
22404
  ).all(filePath);
22404
22405
  for (const link of links) {
22405
22406
  affectedFeatureIds.add(link.feature_id);
@@ -22412,7 +22413,7 @@ function getFeatureImpact(db, filePaths) {
22412
22413
  const feature = getFeatureById(db, featureId);
22413
22414
  if (!feature || feature.status !== "active") continue;
22414
22415
  const allComponents = db.prepare(
22415
- `SELECT component_file, is_primary FROM ${t("sentinel_components")} WHERE feature_id = ?`
22416
+ `SELECT component_file, is_primary FROM ${t("sentinel_components")} WHERE feature_id = ? LIMIT 10000`
22416
22417
  ).all(featureId);
22417
22418
  const affected = allComponents.filter((c2) => fileSet.has(c2.component_file));
22418
22419
  const remaining = allComponents.filter((c2) => !fileSet.has(c2.component_file));
@@ -23086,6 +23087,7 @@ function scanTrpcProcedures(dataDb) {
23086
23087
  SELECT router_name, procedure_name, procedure_type, router_file
23087
23088
  FROM ${t("trpc_procedures")}
23088
23089
  ORDER BY router_name, procedure_name
23090
+ LIMIT 100000
23089
23091
  `).all();
23090
23092
  for (const proc of procedures) {
23091
23093
  const subdomain = inferSubdomain(proc.router_name, proc.procedure_name);
@@ -23128,6 +23130,7 @@ function scanPageRoutes(dataDb) {
23128
23130
  SELECT page_file, route, portal, components, hooks, routers
23129
23131
  FROM ${t("page_deps")}
23130
23132
  ORDER BY route
23133
+ LIMIT 100000
23131
23134
  `).all();
23132
23135
  for (const page of pages) {
23133
23136
  const domain = inferDomain(page.route);
@@ -23315,7 +23318,7 @@ function calculateQualityScore(db, sessionId) {
23315
23318
  const weights = getWeights();
23316
23319
  const categories = getCategories();
23317
23320
  const observations = db.prepare(
23318
- "SELECT type, detail FROM observations WHERE session_id = ?"
23321
+ "SELECT type, detail FROM observations WHERE session_id = ? LIMIT 10000"
23319
23322
  ).all(sessionId);
23320
23323
  let score = 50;
23321
23324
  const breakdown = Object.fromEntries(
@@ -23357,6 +23360,7 @@ function backfillQualityScores(db) {
23357
23360
  FROM sessions s
23358
23361
  LEFT JOIN session_quality_scores q ON s.session_id = q.session_id
23359
23362
  WHERE q.session_id IS NULL
23363
+ LIMIT 100000
23360
23364
  `).all();
23361
23365
  let backfilled = 0;
23362
23366
  for (const session of sessions) {
@@ -23455,6 +23459,7 @@ function handleQualityTrend(args2, db, retried = false) {
23455
23459
  FROM session_quality_scores
23456
23460
  WHERE created_at >= datetime('now', ?)
23457
23461
  ORDER BY created_at ASC
23462
+ LIMIT 100000
23458
23463
  `).all(`-${days} days`);
23459
23464
  if (scores.length === 0) {
23460
23465
  if (!retried) {
@@ -23490,6 +23495,7 @@ function handleQualityReport(args2, db, retried = false) {
23490
23495
  SELECT score, security_score, architecture_score, coupling_score, test_score, rule_compliance_score
23491
23496
  FROM session_quality_scores
23492
23497
  WHERE created_at >= datetime('now', ?)
23498
+ LIMIT 10000
23493
23499
  `).all(`-${days} days`);
23494
23500
  if (scores.length === 0) {
23495
23501
  if (!retried) {
@@ -23976,7 +23982,7 @@ function queryAuditLog(db, options) {
23976
23982
  }
23977
23983
  function getFileChain(db, filePath) {
23978
23984
  return db.prepare(
23979
- "SELECT * FROM audit_log WHERE file_path = ? ORDER BY timestamp ASC"
23985
+ "SELECT * FROM audit_log WHERE file_path = ? ORDER BY timestamp ASC LIMIT 10000"
23980
23986
  ).all(filePath);
23981
23987
  }
23982
23988
  function getAuditToolDefinitions() {
@@ -24456,6 +24462,7 @@ function handleValidationReport(args2, db) {
24456
24462
  FROM validation_results
24457
24463
  WHERE created_at >= datetime('now', ?)
24458
24464
  ORDER BY created_at DESC
24465
+ LIMIT 100000
24459
24466
  `).all(`-${days} days`);
24460
24467
  if (results.length === 0) {
24461
24468
  return text9(`No validation results found in the last ${days} days. Run ${p10("validation_check")} { file: "src/path/to/file.ts" } on specific files to generate validation data, or try a longer time range with { days: 90 }.`);
@@ -24866,6 +24873,7 @@ function handleSecurityScore(args2, db) {
24866
24873
  SELECT file_path, risk_score, findings FROM security_scores
24867
24874
  WHERE session_id = ?
24868
24875
  ORDER BY risk_score DESC
24876
+ LIMIT 10000
24869
24877
  `).all(sessionId);
24870
24878
  if (scores.length === 0) {
24871
24879
  return text11(`No security scores for session ${sessionId.slice(0, 8)}... Security scores are generated when files are scanned. Try: ${p12("security_score")} { file_path: "src/server/api/routers/example.ts" } to scan a file, or ${p12("security_heatmap")} {} to see all scanned files.`);
@@ -25283,6 +25291,7 @@ function detectConflicts(db, daysBack = 7) {
25283
25291
  AND so1.created_at >= datetime('now', ?)
25284
25292
  AND so2.created_at >= datetime('now', ?)
25285
25293
  GROUP BY so1.file_path, so1.developer_id, so2.developer_id
25294
+ LIMIT 10000
25286
25295
  `).all(`-${daysBack} days`, `-${daysBack} days`);
25287
25296
  return conflicts.map((c2) => ({
25288
25297
  filePath: c2.file_path,
@@ -25432,6 +25441,7 @@ function handleTeamExpertise(args2, db) {
25432
25441
  FROM developer_expertise
25433
25442
  WHERE module = ?
25434
25443
  ORDER BY expertise_score DESC
25444
+ LIMIT 10000
25435
25445
  `).all(targetModule);
25436
25446
  if (experts.length === 0) {
25437
25447
  return text13(`No expertise data for module "${targetModule}". Expertise builds as developers work on files in this module across sessions. Try: ${p14("team_expertise")} {} to see all modules with tracked expertise.`);
@@ -25609,6 +25619,7 @@ function handleRegressionCheck(_args, db) {
25609
25619
  FROM feature_health
25610
25620
  WHERE modifications_since_test > 0
25611
25621
  ORDER BY modifications_since_test DESC
25622
+ LIMIT 10000
25612
25623
  `).all();
25613
25624
  if (recentlyModified.length === 0) {
25614
25625
  return text14(`No features have been modified since their last test run. Low regression risk. Use ${p15("feature_health")} {} to see the full feature health dashboard.`);
@@ -26516,7 +26527,7 @@ function handleRule(db, args2) {
26516
26527
  }
26517
26528
  if (withIncidents) {
26518
26529
  const edges = db.prepare(
26519
- "SELECT source_id FROM knowledge_edges WHERE target_type = 'cr' AND target_id = ? AND source_type = 'incident'"
26530
+ "SELECT source_id FROM knowledge_edges WHERE target_type = 'cr' AND target_id = ? AND source_type = 'incident' LIMIT 5000"
26520
26531
  ).all(ruleId);
26521
26532
  if (edges.length > 0) {
26522
26533
  lines.push("### Related Incidents");
@@ -26533,7 +26544,7 @@ function handleRule(db, args2) {
26533
26544
  }
26534
26545
  } else if (keyword) {
26535
26546
  const rules = db.prepare(
26536
- "SELECT * FROM knowledge_rules WHERE rule_text LIKE ? OR rule_id LIKE ? ORDER BY rule_id"
26547
+ "SELECT * FROM knowledge_rules WHERE rule_text LIKE ? OR rule_id LIKE ? ORDER BY rule_id LIMIT 1000"
26537
26548
  ).all(`%${keyword}%`, `%${keyword}%`);
26538
26549
  lines.push(`## Rules matching "${keyword}" (${rules.length} found)`);
26539
26550
  lines.push("");
@@ -26573,7 +26584,7 @@ function handleIncident(db, args2) {
26573
26584
  if (incident.user_quote) lines.push(`| **User Quote** | ${incident.user_quote.replace(/\|/g, "\\|")} |`);
26574
26585
  lines.push("");
26575
26586
  const edges = db.prepare(
26576
- "SELECT target_id FROM knowledge_edges WHERE source_type = 'incident' AND source_id = ? AND target_type = 'cr'"
26587
+ "SELECT target_id FROM knowledge_edges WHERE source_type = 'incident' AND source_id = ? AND target_type = 'cr' LIMIT 5000"
26577
26588
  ).all(String(incidentNum));
26578
26589
  if (edges.length > 0) {
26579
26590
  lines.push("### Linked Rules");
@@ -26618,7 +26629,7 @@ function handleSchemaCheck(db, args2) {
26618
26629
  const lines = [];
26619
26630
  if (table) {
26620
26631
  const mismatches = db.prepare(
26621
- "SELECT * FROM knowledge_schema_mismatches WHERE table_name = ?"
26632
+ "SELECT * FROM knowledge_schema_mismatches WHERE table_name = ? LIMIT 1000"
26622
26633
  ).all(table);
26623
26634
  if (mismatches.length > 0) {
26624
26635
  lines.push(`## Schema Mismatches for \`${table}\``);
@@ -26636,7 +26647,7 @@ function handleSchemaCheck(db, args2) {
26636
26647
  }
26637
26648
  if (column) {
26638
26649
  const mismatches = db.prepare(
26639
- "SELECT * FROM knowledge_schema_mismatches WHERE wrong_column = ?"
26650
+ "SELECT * FROM knowledge_schema_mismatches WHERE wrong_column = ? LIMIT 1000"
26640
26651
  ).all(column);
26641
26652
  if (mismatches.length > 0) {
26642
26653
  if (lines.length > 0) lines.push("");
@@ -26675,7 +26686,7 @@ function handlePattern(db, args2) {
26675
26686
  `patterns-quickref`
26676
26687
  ];
26677
26688
  const docs = db.prepare(
26678
- "SELECT id, file_path, title FROM knowledge_documents WHERE category = 'patterns' OR category = 'reference' OR category = 'root'"
26689
+ "SELECT id, file_path, title FROM knowledge_documents WHERE category = 'patterns' OR category = 'reference' OR category = 'root' LIMIT 1000"
26679
26690
  ).all();
26680
26691
  const relevantDocs = docs.filter(
26681
26692
  (d2) => domainPatterns.some((pat) => d2.file_path.toLowerCase().includes(pat.toLowerCase()))
@@ -26720,7 +26731,7 @@ function handlePattern(db, args2) {
26720
26731
  if (!topic && relevantDocs.length > 0) {
26721
26732
  for (const doc of relevantDocs.slice(0, 2)) {
26722
26733
  const chunks = db.prepare(
26723
- "SELECT heading, content, chunk_type FROM knowledge_chunks WHERE document_id = ? AND chunk_type = 'section' ORDER BY line_start"
26734
+ "SELECT heading, content, chunk_type FROM knowledge_chunks WHERE document_id = ? AND chunk_type = 'section' ORDER BY line_start LIMIT 5000"
26724
26735
  ).all(doc.id);
26725
26736
  lines.push(`### From: ${claudeDir}/${doc.file_path}`);
26726
26737
  lines.push("");
@@ -26776,7 +26787,7 @@ function handleVerification(db, args2) {
26776
26787
  if (vr.category) lines.push(`| **Category** | ${vr.category} |`);
26777
26788
  } else if (situation) {
26778
26789
  const results = db.prepare(
26779
- "SELECT * FROM knowledge_verifications WHERE use_when LIKE ? OR vr_type LIKE ? OR catches LIKE ? ORDER BY vr_type"
26790
+ "SELECT * FROM knowledge_verifications WHERE use_when LIKE ? OR vr_type LIKE ? OR catches LIKE ? ORDER BY vr_type LIMIT 1000"
26780
26791
  ).all(`%${situation}%`, `%${situation}%`, `%${situation}%`);
26781
26792
  lines.push(`## Verifications for "${situation}" (${results.length} found)`);
26782
26793
  lines.push("");
@@ -26814,10 +26825,10 @@ function handleGraph(db, args2) {
26814
26825
  lines.push("");
26815
26826
  for (const entity of currentLevel) {
26816
26827
  const outgoing = db.prepare(
26817
- "SELECT target_type, target_id, edge_type FROM knowledge_edges WHERE source_type = ? AND source_id = ?"
26828
+ "SELECT target_type, target_id, edge_type FROM knowledge_edges WHERE source_type = ? AND source_id = ? LIMIT 5000"
26818
26829
  ).all(entity.type, entity.id);
26819
26830
  const incoming = db.prepare(
26820
- "SELECT source_type, source_id, edge_type FROM knowledge_edges WHERE target_type = ? AND target_id = ?"
26831
+ "SELECT source_type, source_id, edge_type FROM knowledge_edges WHERE target_type = ? AND target_id = ? LIMIT 5000"
26821
26832
  ).all(entity.type, entity.id);
26822
26833
  for (const edge of outgoing) {
26823
26834
  const key = `${edge.target_type}:${edge.target_id}`;
@@ -26892,6 +26903,7 @@ function handleCommand(db, args2) {
26892
26903
  JOIN knowledge_documents kd ON kd.id = kc.document_id
26893
26904
  WHERE kc.chunk_type = 'command' AND (kc.content LIKE ? OR kc.heading LIKE ?)
26894
26905
  ORDER BY kc.heading
26906
+ LIMIT 1000
26895
26907
  `).all(`%${keyword}%`, `%${keyword}%`);
26896
26908
  lines.push(`## Commands matching "${keyword}" (${results.length} found)`);
26897
26909
  lines.push("");
@@ -26906,6 +26918,7 @@ function handleCommand(db, args2) {
26906
26918
  JOIN knowledge_documents kd ON kd.id = kc.document_id
26907
26919
  WHERE kc.chunk_type = 'command'
26908
26920
  ORDER BY kc.heading
26921
+ LIMIT 1000
26909
26922
  `).all();
26910
26923
  lines.push(`## All Commands (${commands.length} total)`);
26911
26924
  lines.push("");
@@ -27022,7 +27035,7 @@ function handlePlan(db, args2) {
27022
27035
  if (doc.description) lines.push(`**Description**: ${doc.description}`);
27023
27036
  lines.push("");
27024
27037
  const items = db.prepare(
27025
- "SELECT heading, content FROM knowledge_chunks WHERE document_id = ? AND metadata LIKE '%plan_item_id%' ORDER BY heading"
27038
+ "SELECT heading, content FROM knowledge_chunks WHERE document_id = ? AND metadata LIKE '%plan_item_id%' ORDER BY heading LIMIT 5000"
27026
27039
  ).all(doc.id);
27027
27040
  if (items.length > 0) {
27028
27041
  lines.push(`### Plan Items (${items.length})`);
@@ -27048,7 +27061,7 @@ function handlePlan(db, args2) {
27048
27061
  }
27049
27062
  } else if (status) {
27050
27063
  const docs = db.prepare(
27051
- "SELECT kd.file_path, kd.title, kc.content FROM knowledge_chunks kc JOIN knowledge_documents kd ON kd.id = kc.document_id WHERE kd.category = 'plan' AND kc.heading = 'IMPLEMENTATION STATUS' AND kc.content LIKE ? ORDER BY kd.file_path DESC"
27064
+ "SELECT kd.file_path, kd.title, kc.content FROM knowledge_chunks kc JOIN knowledge_documents kd ON kd.id = kc.document_id WHERE kd.category = 'plan' AND kc.heading = 'IMPLEMENTATION STATUS' AND kc.content LIKE ? ORDER BY kd.file_path DESC LIMIT 1000"
27052
27065
  ).all(`%${status}%`);
27053
27066
  lines.push(`## Plans with status "${status}" (${docs.length} found)`);
27054
27067
  lines.push("");
@@ -27134,7 +27147,7 @@ function handleGaps(db, args2) {
27134
27147
  }
27135
27148
  } else if (checkType === "patterns") {
27136
27149
  const patternDocs = db.prepare(
27137
- "SELECT file_path, title FROM knowledge_documents WHERE category = 'patterns'"
27150
+ "SELECT file_path, title FROM knowledge_documents WHERE category = 'patterns' LIMIT 10000"
27138
27151
  ).all();
27139
27152
  const documentedDomains = new Set(patternDocs.map((d2) => d2.title.replace("-patterns", "").replace(" Patterns", "").toLowerCase()));
27140
27153
  lines.push("### Pattern Coverage");
@@ -27144,7 +27157,7 @@ function handleGaps(db, args2) {
27144
27157
  try {
27145
27158
  dataDb = getDataDb();
27146
27159
  const domains = dataDb.prepare(
27147
- `SELECT DISTINCT domain FROM ${t("sentinel")} WHERE status = 'active' ORDER BY domain`
27160
+ `SELECT DISTINCT domain FROM ${t("sentinel")} WHERE status = 'active' ORDER BY domain LIMIT 10000`
27148
27161
  ).all();
27149
27162
  for (const d2 of domains) {
27150
27163
  const hasPattern = documentedDomains.has(d2.domain.toLowerCase());
@@ -27469,7 +27482,7 @@ function handlePyImports(args2, dataDb) {
27469
27482
  if (depth > maxDepth || visited.has(f2)) return;
27470
27483
  visited.add(f2);
27471
27484
  const imports = dataDb.prepare(
27472
- `SELECT target_file, imported_names FROM ${t("py_imports")} WHERE source_file = ?`
27485
+ `SELECT target_file, imported_names FROM ${t("py_imports")} WHERE source_file = ? LIMIT 10000`
27473
27486
  ).all(f2);
27474
27487
  for (const imp of imports) {
27475
27488
  const indent = " ".repeat(depth);
@@ -27484,7 +27497,7 @@ function handlePyImports(args2, dataDb) {
27484
27497
  traverse2(file, 0);
27485
27498
  } else {
27486
27499
  const imports = dataDb.prepare(
27487
- `SELECT target_file, import_type, imported_names, line FROM ${t("py_imports")} WHERE source_file = ? ORDER BY line`
27500
+ `SELECT target_file, import_type, imported_names, line FROM ${t("py_imports")} WHERE source_file = ? ORDER BY line LIMIT 10000`
27488
27501
  ).all(file);
27489
27502
  lines.push(`## Imports from ${file} (${imports.length} edges)`);
27490
27503
  for (const imp of imports) {
@@ -27494,7 +27507,7 @@ function handlePyImports(args2, dataDb) {
27494
27507
  }
27495
27508
  } else if (importedBy) {
27496
27509
  const importers = dataDb.prepare(
27497
- `SELECT source_file, imported_names, line FROM ${t("py_imports")} WHERE target_file = ? ORDER BY source_file`
27510
+ `SELECT source_file, imported_names, line FROM ${t("py_imports")} WHERE target_file = ? ORDER BY source_file LIMIT 10000`
27498
27511
  ).all(importedBy);
27499
27512
  lines.push(`## Files importing ${importedBy} (${importers.length} edges)`);
27500
27513
  for (const imp of importers) {
@@ -27741,14 +27754,14 @@ function handlePyImpact(args2, dataDb) {
27741
27754
  const file = args2.file;
27742
27755
  const lines = [`## Impact Analysis: ${file}`, ""];
27743
27756
  const importedBy = dataDb.prepare(
27744
- `SELECT source_file FROM ${t("py_imports")} WHERE target_file = ?`
27757
+ `SELECT source_file FROM ${t("py_imports")} WHERE target_file = ? LIMIT 10000`
27745
27758
  ).all(file);
27746
27759
  lines.push(`### Imported By (${importedBy.length} files)`);
27747
27760
  for (const imp of importedBy.slice(0, 20)) {
27748
27761
  lines.push(`- ${imp.source_file}`);
27749
27762
  }
27750
27763
  const routes = dataDb.prepare(
27751
- `SELECT method, path, function_name FROM ${t("py_routes")} WHERE file = ?`
27764
+ `SELECT method, path, function_name FROM ${t("py_routes")} WHERE file = ? LIMIT 10000`
27752
27765
  ).all(file);
27753
27766
  if (routes.length > 0) {
27754
27767
  lines.push(`
@@ -27758,7 +27771,7 @@ function handlePyImpact(args2, dataDb) {
27758
27771
  }
27759
27772
  }
27760
27773
  const models = dataDb.prepare(
27761
- `SELECT class_name, table_name FROM ${t("py_models")} WHERE file = ?`
27774
+ `SELECT class_name, table_name FROM ${t("py_models")} WHERE file = ? LIMIT 10000`
27762
27775
  ).all(file);
27763
27776
  if (models.length > 0) {
27764
27777
  lines.push(`
@@ -27771,7 +27784,7 @@ function handlePyImpact(args2, dataDb) {
27771
27784
  if (routeIds.length > 0) {
27772
27785
  const placeholders = routeIds.map(() => "?").join(",");
27773
27786
  const callers = dataDb.prepare(
27774
- `SELECT DISTINCT frontend_file FROM ${t("py_route_callers")} WHERE route_id IN (${placeholders})`
27787
+ `SELECT DISTINCT frontend_file FROM ${t("py_route_callers")} WHERE route_id IN (${placeholders}) LIMIT 100000`
27775
27788
  ).all(...routeIds.map((r2) => r2.id));
27776
27789
  if (callers.length > 0) {
27777
27790
  lines.push(`
@@ -27812,14 +27825,14 @@ function handlePyContext(args2, dataDb) {
27812
27825
  lines.push(`- ${imp.source_file}`);
27813
27826
  }
27814
27827
  }
27815
- const routes = dataDb.prepare(`SELECT method, path, function_name, line FROM ${t("py_routes")} WHERE file = ?`).all(file);
27828
+ const routes = dataDb.prepare(`SELECT method, path, function_name, line FROM ${t("py_routes")} WHERE file = ? LIMIT 10000`).all(file);
27816
27829
  if (routes.length > 0) {
27817
27830
  lines.push("\n### Routes");
27818
27831
  for (const r2 of routes) {
27819
27832
  lines.push(`- ${r2.method} ${r2.path} \u2192 ${r2.function_name} (L${r2.line})`);
27820
27833
  }
27821
27834
  }
27822
- const models = dataDb.prepare(`SELECT class_name, table_name, line FROM ${t("py_models")} WHERE file = ?`).all(file);
27835
+ const models = dataDb.prepare(`SELECT class_name, table_name, line FROM ${t("py_models")} WHERE file = ? LIMIT 10000`).all(file);
27823
27836
  if (models.length > 0) {
27824
27837
  lines.push("\n### Models");
27825
27838
  for (const m3 of models) {
@@ -28226,7 +28239,7 @@ Feature scan failed: ${error instanceof Error ? error.message : String(error)}`)
28226
28239
  function handleContext(file, dataDb, codegraphDb) {
28227
28240
  const lines = [];
28228
28241
  const nodes = codegraphDb.prepare(
28229
- "SELECT name, kind, start_line, end_line FROM nodes WHERE file_path = ? ORDER BY start_line"
28242
+ "SELECT name, kind, start_line, end_line FROM nodes WHERE file_path = ? ORDER BY start_line LIMIT 10000"
28230
28243
  ).all(file);
28231
28244
  if (nodes.length > 0) {
28232
28245
  lines.push("## CodeGraph Nodes");
@@ -28343,7 +28356,7 @@ function handleContext(file, dataDb, codegraphDb) {
28343
28356
  if (relevantCRs.length > 0) {
28344
28357
  const placeholders = relevantCRs.map(() => "?").join(",");
28345
28358
  const crRules = knowledgeDb.prepare(
28346
- `SELECT rule_id, rule_text, vr_type FROM knowledge_rules WHERE rule_id IN (${placeholders})`
28359
+ `SELECT rule_id, rule_text, vr_type FROM knowledge_rules WHERE rule_id IN (${placeholders}) LIMIT 10000`
28347
28360
  ).all(...relevantCRs);
28348
28361
  if (crRules.length > 0) {
28349
28362
  lines.push("## Relevant Canonical Rules");
@@ -28440,7 +28453,7 @@ function handleTrpcMap(args2, dataDb) {
28440
28453
  const lines = [];
28441
28454
  if (args2.uncoupled) {
28442
28455
  const uncoupled = dataDb.prepare(
28443
- `SELECT router_name, procedure_name, procedure_type, router_file FROM ${t("trpc_procedures")} WHERE has_ui_caller = 0 ORDER BY router_name, procedure_name`
28456
+ `SELECT router_name, procedure_name, procedure_type, router_file FROM ${t("trpc_procedures")} WHERE has_ui_caller = 0 ORDER BY router_name, procedure_name LIMIT 10000`
28444
28457
  ).all();
28445
28458
  lines.push(`## Uncoupled Procedures (${uncoupled.length} total)`);
28446
28459
  lines.push("These procedures have ZERO UI callers.");
@@ -28455,7 +28468,7 @@ function handleTrpcMap(args2, dataDb) {
28455
28468
  }
28456
28469
  } else if (args2.router) {
28457
28470
  const procs = dataDb.prepare(
28458
- `SELECT id, procedure_name, procedure_type, has_ui_caller FROM ${t("trpc_procedures")} WHERE router_name = ? ORDER BY procedure_name`
28471
+ `SELECT id, procedure_name, procedure_type, has_ui_caller FROM ${t("trpc_procedures")} WHERE router_name = ? ORDER BY procedure_name LIMIT 10000`
28459
28472
  ).all(args2.router);
28460
28473
  lines.push(`## Router: ${args2.router} (${procs.length} procedures)`);
28461
28474
  lines.push("");
@@ -28463,7 +28476,7 @@ function handleTrpcMap(args2, dataDb) {
28463
28476
  const status = proc.has_ui_caller ? "" : " [NO UI CALLERS]";
28464
28477
  lines.push(`### ${args2.router}.${proc.procedure_name} (${proc.procedure_type})${status}`);
28465
28478
  const callSites = dataDb.prepare(
28466
- `SELECT file, line, call_pattern FROM ${t("trpc_call_sites")} WHERE procedure_id = ?`
28479
+ `SELECT file, line, call_pattern FROM ${t("trpc_call_sites")} WHERE procedure_id = ? LIMIT 10000`
28467
28480
  ).all(proc.id);
28468
28481
  if (callSites.length > 0) {
28469
28482
  lines.push("UI Call Sites:");
@@ -28477,7 +28490,7 @@ function handleTrpcMap(args2, dataDb) {
28477
28490
  }
28478
28491
  } else if (args2.procedure) {
28479
28492
  const procs = dataDb.prepare(
28480
- `SELECT id, router_name, router_file, procedure_type, has_ui_caller FROM ${t("trpc_procedures")} WHERE procedure_name = ? ORDER BY router_name`
28493
+ `SELECT id, router_name, router_file, procedure_type, has_ui_caller FROM ${t("trpc_procedures")} WHERE procedure_name = ? ORDER BY router_name LIMIT 10000`
28481
28494
  ).all(args2.procedure);
28482
28495
  lines.push(`## Procedure "${args2.procedure}" found in ${procs.length} routers`);
28483
28496
  lines.push("");
@@ -28485,7 +28498,7 @@ function handleTrpcMap(args2, dataDb) {
28485
28498
  lines.push(`### ${proc.router_name}.${args2.procedure} (${proc.procedure_type})`);
28486
28499
  lines.push(`File: ${proc.router_file}`);
28487
28500
  const callSites = dataDb.prepare(
28488
- `SELECT file, line, call_pattern FROM ${t("trpc_call_sites")} WHERE procedure_id = ?`
28501
+ `SELECT file, line, call_pattern FROM ${t("trpc_call_sites")} WHERE procedure_id = ? LIMIT 10000`
28489
28502
  ).all(proc.id);
28490
28503
  if (callSites.length > 0) {
28491
28504
  lines.push("UI Call Sites:");
@@ -28530,11 +28543,11 @@ function handleCouplingCheck(args2, dataDb, codegraphDb) {
28530
28543
  let uncoupledProcs;
28531
28544
  if (stagedFiles) {
28532
28545
  uncoupledProcs = dataDb.prepare(
28533
- `SELECT router_name, procedure_name, procedure_type, router_file FROM ${t("trpc_procedures")} WHERE has_ui_caller = 0 AND router_file IN (${stagedFiles.map(() => "?").join(",")})`
28546
+ `SELECT router_name, procedure_name, procedure_type, router_file FROM ${t("trpc_procedures")} WHERE has_ui_caller = 0 AND router_file IN (${stagedFiles.map(() => "?").join(",")}) LIMIT 10000`
28534
28547
  ).all(...stagedFiles);
28535
28548
  } else {
28536
28549
  uncoupledProcs = dataDb.prepare(
28537
- `SELECT router_name, procedure_name, procedure_type, router_file FROM ${t("trpc_procedures")} WHERE has_ui_caller = 0`
28550
+ `SELECT router_name, procedure_name, procedure_type, router_file FROM ${t("trpc_procedures")} WHERE has_ui_caller = 0 LIMIT 10000`
28538
28551
  ).all();
28539
28552
  }
28540
28553
  lines.push("## Coupling Check Results");
@@ -28550,12 +28563,12 @@ function handleCouplingCheck(args2, dataDb, codegraphDb) {
28550
28563
  lines.push("");
28551
28564
  }
28552
28565
  const allPages = codegraphDb.prepare(
28553
- "SELECT path FROM files WHERE path LIKE 'src/app/%/page.tsx' OR path = 'src/app/page.tsx'"
28566
+ "SELECT path FROM files WHERE path LIKE 'src/app/%/page.tsx' OR path = 'src/app/page.tsx' LIMIT 10000"
28554
28567
  ).all();
28555
28568
  const pageImports = /* @__PURE__ */ new Set();
28556
28569
  for (const page of allPages) {
28557
28570
  const imports = dataDb.prepare(
28558
- `SELECT target_file FROM ${t("imports")} WHERE source_file = ?`
28571
+ `SELECT target_file FROM ${t("imports")} WHERE source_file = ? LIMIT 10000`
28559
28572
  ).all(page.path);
28560
28573
  for (const imp of imports) {
28561
28574
  pageImports.add(imp.target_file);
@@ -28565,7 +28578,7 @@ function handleCouplingCheck(args2, dataDb, codegraphDb) {
28565
28578
  if (stagedFiles) {
28566
28579
  const placeholders = stagedFiles.map(() => "?").join(",");
28567
28580
  componentFiles = codegraphDb.prepare(
28568
- `SELECT path FROM files WHERE path LIKE 'src/components/%' AND path IN (${placeholders})`
28581
+ `SELECT path FROM files WHERE path LIKE 'src/components/%' AND path IN (${placeholders}) LIMIT 10000`
28569
28582
  ).all(...stagedFiles);
28570
28583
  } else {
28571
28584
  componentFiles = [];
@@ -28627,7 +28640,7 @@ function handleImpact2(file, dataDb, codegraphDb) {
28627
28640
  const fileDomain = classifyFile(file);
28628
28641
  lines.push(`### Domain: ${fileDomain}`);
28629
28642
  const imports = dataDb.prepare(
28630
- `SELECT target_file FROM ${t("imports")} WHERE source_file = ?`
28643
+ `SELECT target_file FROM ${t("imports")} WHERE source_file = ? LIMIT 10000`
28631
28644
  ).all(file);
28632
28645
  const crossings = [];
28633
28646
  for (const imp of imports) {
@@ -2028,7 +2028,7 @@ async function main() {
2028
2028
  const counts = parseTestRunOutput(tool_response ?? "");
2029
2029
  if (counts) {
2030
2030
  const modifiedFeatures = db.prepare(
2031
- "SELECT feature_key FROM feature_health WHERE modifications_since_test > 0"
2031
+ "SELECT feature_key FROM feature_health WHERE modifications_since_test > 0 LIMIT 10000"
2032
2032
  ).all();
2033
2033
  for (const row of modifiedFeatures) {
2034
2034
  recordTestResult(db, row.feature_key, counts.passing, counts.failing);
@@ -1177,7 +1177,7 @@ async function main() {
1177
1177
  ).all(session_id);
1178
1178
  const observations = observationsDesc.reverse();
1179
1179
  const prompts = db.prepare(
1180
- "SELECT prompt_text FROM user_prompts WHERE session_id = ? ORDER BY prompt_number ASC"
1180
+ "SELECT prompt_text FROM user_prompts WHERE session_id = ? ORDER BY prompt_number ASC LIMIT 10000"
1181
1181
  ).all(session_id);
1182
1182
  const summary = buildSnapshotSummary(observations, prompts);
1183
1183
  addSummary(db, session_id, summary);