CodeIssuesPull RequestsActionsSecurityInsights
✨ AI
More
Settings

fix: readiness wave 2 — repo_health honesty, durable rate limits, dashboard cold start, email truth, dead code indexes #5608

Merged⚡ AI-generatedXSccantynz wants to mergefix/readiness-wave-2mainopened 23h ago
ccantynzcommented 23h ago

Stacked on fix/explore-discovery-opt-in (#5607) — merge that first.

Five workstreams from the ranked open list, plus the GateTest session's findings, all independently reproduced before fixing.

1. repo_health certified a repo with committed credentials as "clean codebase"

Reproduced on ccantynz/esim: security: {score: 100, issues: []} and the insight "No security issues detected — clean codebase" for a tree containing, at lib/auth.ts:15-16, a committed default admin password and a committed HMAC signing key.

Three defects had to line up:

  1. No pattern matched. Both secret rules require the quote to follow = with only whitespace between; process.env.X ?? "literal" puts the env read in that gap. The scanner never considered those lines.
  2. The heuristic rejected them anyway. looksLikeRealSecret skipped all-lowercase slugs to suppress "application/json" — which is also the shape of a human-chosen password. Verified: it skipped "layova-admin" while flagging "application/json".
  3. Absence of evidence reported as a pass. The security breakdown now carries its own scan coverage, and the wording states scope. This is the rule Dependencies has followed since a Python repo scored 100 for having no manifest — "Unknown must never render as perfect". Security was the last category exempt.

Also FileMetric.lines carried bytes ("lines": 8339 for a 204-line file). health.tsx already worked around it by labelling the value "bytes", so humans read the truth and only the MCP surface lied — to the agents that are its main consumer.

2. Rate limiting survives a restart

Every counter lived in a process-local Map under a comment saying "replace with Redis", while rate_limit_buckets sat unread. The 10/min login bucket reset on every deploy, and deploys run on a 60-second timer.

Two tiers: durable write-through for auth/ai-search/reindex (low-frequency, high-consequence), write-behind snapshot for api/git/search (hot path untouched). Fails open throughout; the durable read is capped at 1500ms because the db layer's 8s budget is a page-render budget, not an acceptable wait in front of a login form.

3. Dashboard cold start: 6.8s → one SELECT

The only nav-audit failure. Warm it was already 0.75s; the LRU just died with the process. Stats change only on push and updatedAt tracks that, so the memo needed a home that outlives the container, not a shorter TTL. Streaming-after-paint was considered and rejected — two widgets derive from these numbers and a half-filled page would show a lying average.

4. Email: one live lie, and a predicate rotted both ways

Most flows were already honest. POST /status/subscribe was not — it said "Subscribed! Check your inbox" unconditionally, while the confirm token existed only in the unsent mail.

Bigger: emailProvider === "resend" && !!resendApiKey was hand-copied into seven places, none of which learned about the estate rail (EMAIL_PROVIDER=http). On a rail-wired host, mail leaves while the platform auto-verifies every account and shows health boards red — a false alarm teaches operators to scroll past red. Anti-enumeration preserved and pinned by a source-level test.

This does not unblock launch — sending mail still needs a credential. It stops the platform claiming otherwise.

5. The search tool queried the index nothing writes

find_symbol and semantic_search returned empty platform-wide — including for a function in this repo. Root cause: two unrelated indexes. code_embeddings is written on every push; code_chunks is written by one manual form and read by gluecron_semantic_search. That is also why chat returned 8 citations while semantic_search returned [] for the same repo.

indexRepositorySymbols had one caller platform-wide — the manual Reindex button. Not push, not import, not cron. Nothing was gated and nothing failing; the writer did not exist. Now dispatched from post-receive and from repo import.

Also: an AI outage returned a success-shaped payload with citations attached — citations computed before the stream, describing an answer never produced. Now throws with an explicit aiError and no citations. personal-chat.ts had the identical defect verbatim.

Adds gluecron_get_diff and files/stats on get_commit — an agent reviewing a change here previously could not see what changed.

Still required, not half-built

Existing repos stay unindexed until their next default-branch push. A backfill is needed — per repo via the two existing reindex endpoints, or a one-shot script over repositories. A truth-ledger claim now makes the empty-index condition detectable; its predicate is inverted (max: 0 failing repos, not min: 1 indexed) because a minimum would go green the moment one repo out of fifty was indexed.

Verification

  • bun run typecheck clean across the whole tree
  • 520 tests pass, 0 fail across 21 files, incl. green-ecosystem (82, covers the locked rate-limit headers) untouched
  • selfcheck 94/100, unchanged from before this wave — no quality regression; rate_limit_buckets has dropped off the dead-table list
  • rate-limit.ts is a BUILD_BIBLE §4.3 locked block; the change is additive, which §12-17's living-document rule permits explicitly

🤖 Generated with Claude Code

https://claude.ai/code/session_01TsbafFcgppHoe7tm56vnm3

ccantynzAI Reviewcommented 23h ago

AI Triage

(no summary)

Priority: medium Risk area: mixed

Suggested labels: (no label suggestions) Suggested reviewers: (no reviewer suggestions)

Suggestions only — nothing has been applied. The PR author stays in control.

gluecron[bot]🤖 botAI Reviewcommented 23h ago

AI review unavailable

The platform's AI balance is exhausted, so AI generation is temporarily unavailable. Nothing was lost. You can queue this as a repair for the internal agent from the repository's Health page, or try again once the balance is restored. The PR is otherwise unchanged.

Cross-repo impact

See what breaks downstream if this PR merges.

Analyze →
⮌ Merged

This pull request was merged into main.

c comment · e edit title · m merge · a approve · r request changes · ? shortcuts