What's shipped in LGTM, newest first. Pre-launch entries start 15 May 2026; the public launch date appears at the top once we go GA.
Launching soonPre-launch
LGTM is in pre-launch
The product is feature-complete and currently in private testing. Connect your GitHub account and try it — we're stress-testing the agent pipeline, polishing the UX, and finalising compliance before opening the doors. The public launch date will appear here when we're ready.
Ran the consent + delete-account flow past six adversarial review agents. They came back with seven real bugs and a handful of UX gaps. This entry is the fixes — none of them user-visible if everything worked already, but each one was an unexploited foot-gun.
CSRF guard on DELETE /auth/account — requires an X-Confirm-Delete: yes custom header, which browsers can't send cross-origin without triggering a CORS preflight (our allowlist rejects non-LGTM origins). Defence-in-depth on top of Bearer auth
Rate limits added: consent writes 20/min/user, account deletion 3/hour/user — bounds the blast radius of a stolen JWT
Dodo subscription auto-cancel on account deletion. Previously deleting your account left an active subscription on Dodo's side — you'd keep being charged. We now call Dodo's cancel API before anonymising, and return 502 to the user if Dodo rejects so they retry rather than ending up deleted-but-still-paid
Dodo webhook handlers now ignore soft-deleted users so a late renewal event can't update the billing fields on an anonymised record
POST /auth/refresh rejects soft-deleted accounts so a stale refresh token can't keep issuing fresh JWTs for the remainder of the 7-day refresh expiry
Reactivation: Mongoose $set: {} doesn't actually clear nested subdoc fields — it merges. Switched to $unset per-field so /consent properly re-shows after a delete-and-resignup
Reactivation billing fix: if the user's last subscription state was anything other than "active", we now reset billing.plan to "free" — fixes a UI/state mismatch where a deleted Pro account would reactivate showing Pro but the quota check still treated them as Free
Auth middleware now async — checks deletedAt on every authenticated request so a JWT issued before deletion can't survive the 24-hour access-token expiry
Settings → Privacy & Consents now has a real "Delete my account" button instead of an email-only fallback. Withdrawal is genuinely as easy as the one-click GitHub sign-in (DPDP §6(4) requires that).
Type-DELETE confirmation modal with role="dialog", aria-modal, ESC handler, focus trap on the input. No accidental deletes
Anti-abuse reactivation: deletion keeps githubId on the record so when the same GitHub identity OAuths back in, we reactivate the same _id rather than creating a fresh user. billing.reviewsUsedThisMonth carries over — you cannot delete-and-resignup to reset the Free 20/month quota
On reactivation, consents are cleared so the user must re-accept ToS + Privacy on the /consent screen before doing anything
Server-side consent enforcement — new requireConsent middleware on /repos/* /ai/* /api/prs/:id/review /security/* returns 412 consent_required when the user's recorded consents don't match the current policy versions. The SPA axios interceptor catches the 412 and routes to /consent
Email fallback preserved for users who can't sign in (account lockout, lost access)
Replaced the implicit single-checkbox model with the granular separate-purposes pattern that DPDP §6 actually requires.
New /consent screen after first OAuth — three unchecked-by-default checkboxes: Terms of Service (required), Privacy Policy (required), Marketing communications (optional)
Server records each consent as a full audit entry: { version, acceptedAt, IP, userAgent } so we can prove what was accepted, when, and from where if it ever matters
Settings → Privacy & Consents panel: view your recorded consent versions and dates, toggle marketing on/off with a proper switch (role="switch", loading spinner in the thumb during the in-flight save, 44px tap target per Apple HIG)
OAuthCallback redirects to /consent automatically when the recorded versions don't match the current ones — covers both first-time signups AND existing users on the next material policy bump
Backfill: 11 existing testers were marked accepted at v1.0 with marketing opted-out. We never auto opt-in
Withdrawal: standalone PATCH /auth/consents/marketing endpoint lets users flip marketing without re-accepting the legal docs — same effort as opt-in
Both the legal contract for using LGTM and the security-research contract for breaking it. Both based on real research into Indian law and the RFC 9116 / IT Act §43 / CERT-In trio that India-aware VDPs need.
Terms of Service v1.0
Indian-law-grounded: Indian Contract Act 1872 (§11 18+ eligibility), IT Act 2000 §79 (intermediary safe-harbour) + IT Rules 2021 Rule 3(2) (grievance officer), Consumer Protection Act 2019 (refund-clarity requirement), DPDP Act 2023 (privacy interplay), GST on OIDAR for the Pro tier
20 sections including a prominent AI-output disclaimer ("reviews can be wrong, you remain responsible for every merge"), explicit sole-proprietor liability disclosure, BYOK responsibility clauses, refund-policy clarity (no pro-rated refund for partial months — disclosed up front), Bangalore civil-court jurisdiction
TermsOfService JSON-LD schema and sticky sidebar TOC with IntersectionObserver active-section highlight
Responsible Disclosure v1.0
/security page covering scope (every LGTM-controlled surface listed by name), out-of-scope (third-party platforms with their own VDPs), rules of engagement, safe-harbour commitment under IT Act §43, severity-tiered SLA (Critical 14d / High 30d / Medium 60d / Low best-effort), 90-day coordinated-disclosure window
Honest no-bounty disclosure: no cash today (we're a single-founder operation, would rather under-promise than over-commit), but 1 year of Pro + swag + recognition for any valid Medium-or-higher report
CERT-In (incident@cert-in.org.in) listed as the final escalation if we ever fail to respond
Replaced the generic SaaS template with a Privacy Policy mapped to actual code behaviour and to India's Digital Personal Data Protection Act 2023. Every claim cross-checked against the field it describes — if the policy says "AES-256-GCM", the code uses AES-256-GCM.
16 sections covering all 9 DPDP §5 mandatory notice elements: data categories, processing purposes, retention, Data Principal rights, Grievance Officer contact, complaint route to the Data Protection Board, processing methods, third-party sharing, cross-border transfers
Sub-processor table: GitHub (US), OpenAI / Anthropic / Gemini (US, BYOK), Dodo Payments (India), MongoDB Atlas, Fly.io (Singapore — we wanted Mumbai but capacity is blocked), Sentry (US), SMTP, npm — each with what data goes to them, why, and where they're based
Retention table — per-field, with the 7-year Indian tax-compliance window flagged for billing invoices
Grievance Officer published: Tarin Agarwal, 48-hour ack + 30-day resolve windows, escalation path to the DPB once it's accepting complaints
Cookie inventory: lgtm_session / lgtm_refresh (HttpOnly, Secure, SameSite=Lax, Domain=.looksgoodtomeow.in, 24h / 7d), plus the localStorage entries for legacy Bearer flow
Honest cross-border map: India users → Atlas → Fly Singapore → US (for GitHub API, BYOK LLM calls, Sentry, SMTP). "If you require all your data to stay in India, you cannot meaningfully use LGTM today"
PrivacyPolicy JSON-LD schema; sticky sidebar TOC with IntersectionObserver-driven active highlight; lives on every subdomain
The collapsed sidebars were visibly janky: labels snap-disappeared during the width transition, the active row's full pressed background dominated a 72px rail, and the brand logo at full size overflowed the narrow rail.
Labels now fade via synchronised max-width + opacity transitions instead of conditional render — the text width shrinks in lockstep with the rail
Compact left-accent indicator for the active row when collapsed (3px primary bar flush against the rail's edge) instead of the heavy full-row pressed background
Hover state strengthened slightly when collapsed (icon needs visible feedback since the label isn't there to indicate)
Logo resized to 32px when collapsed so it lives in the same visual rhythm as the 16px nav icons and the 28px user avatar — fixed the proportional mismatch on the 68px rail
Same pattern applied to the Beta pill, Notifications counter, Collapse toggle, and Go-to-Dashboard CTA so the whole rail moves together
Documentation is where users decide whether the product is real. Rewrote it as content-dense reference material with structured data so search engines can render it as a developer tool.
TechArticle JSON-LD schema covering 11 article sections — search engines can surface the docs as a structured developer reference
16-detector security table verified line-by-line against the rule library (no more loose paraphrasing — rule IDs, default actions, severities all match code)
First-impression page rewritten to be content-heavy and to actually match what the code does. Several timing claims were softened, several model names corrected, several feature descriptions rewritten with concrete examples.
SEO foundation: new title under 60 chars + comprehensive description, OpenGraph tags for cross-platform link previews, canonical URL, robots directive with max-snippet, SoftwareApplication JSON-LD schema with INR pricing and the full feature list
12-question FAQ section grounded in code reality (correct timeouts, file caps, real model strings, BYOK encryption details, GitHub App permissions) + FAQPage JSON-LD for rich results
Honest timing claims — replaced "<3 min" with "Minutes, not hours". The 30-second figure was an aspirational best case; production diffs realistically land in 1-3 min for typical PRs
Real model names — agent registry now shows the actual gpt-5.4 / gpt-5.4-pro / gpt-5.4-mini / gpt-5.3-codex strings the code uses, not marketing placeholders
Specialist agent cards expanded with concrete finding examples per agent (Security catches "SQL injection, hardcoded secrets, IDOR" instead of generic "OWASP Top 10")
Footer: SEO-rich tagline + India-built credit + Free 20/mo · Pro ₹399/mo · BYOK · No code stored summary
Big bump from the v1.x line. URL handling rewritten for the api./app. subdomain split, command surface fully inventoried, doctor + completion added.
@tarin/lgtm-cli v2.0.1 live on npm — install with npm i -g @tarin/lgtm-cli
Default API URL points at api.looksgoodtomeow.in; localhost override (--api-url or LGTM_API_URL env) still works for dev
Command surface now ~50 commands grouped into 8 categories: Auth & diagnostics, Repo management, Reviews, Configuration (BYOK), LGTM Security, Notifications & analytics, Open shortcuts, Shell completion
New: lgtm doctor (Node + git + auth + API reachability + AI provider checks), lgtm completion (bash/zsh/fish completion script)
api. → app. URL heuristic — when the CLI tells you where to view a review, the link points at the dashboard subdomain instead of stripping the subdomain entirely (which would have landed on the marketing apex)
91 unit tests now pass; new tests cover the URL-rewrite heuristic specifically
Moved off *.fly.dev to a proper four-subdomain layout. Cross-subdomain auth via a shared cookie scope so a session created on the product subdomain is recognised by the marketing apex.
Four custom domains live: looksgoodtomeow.in (marketing apex), app.looksgoodtomeow.in (dashboard), docs.looksgoodtomeow.in (docs), api.looksgoodtomeow.in (API). Let's Encrypt certs issued and verified
DNS records (A + AAAA + an apex ACME-challenge CNAME for Fly's DNS-01 path) plus the apex ownership TXT — the apex cert was the tricky one
Multi-origin CORS — the API now accepts requests from all three LGTM origins and explicitly rejects everything else
Cross-subdomain session cookies: Domain=.looksgoodtomeow.in, HttpOnly, Secure, SameSite=Lax. Sign in on app.* and a fetch from apex carries the session automatically — so the apex Landing nav can show "Dashboard" instead of "Sign in" without a re-auth round trip
SubdomainGuard component locks docs.* to just /docs, /privacy, /terms, /security, /changelog, /review/:id — anything else hard-redirects to apex or app
Hostname-aware SPA routing: apex serves Landing on /, app.* redirects / to /dashboard, docs.* redirects / to /docs
Production bundle no longer references *.fly.dev anywhere — VITE_API_URL baked in at build time
External integrations updated: GitHub App webhook + OAuth callback now point at api.looksgoodtomeow.in, Dodo Payments webhook updated, Sentry DSN unchanged
Moved from a single-process consolidated server to five independent process groups so the API can't be starved by a long-running index-backfill, and so each pool scales independently.
lgtm-server now runs five process groups: api · review-worker · security-worker · index-incremental · index-backfill. Each scales independently via flyctl scale count <process>=N
index-backfill gets 2GB / shared-cpu-2x because tree-sitter parsing + dependency graph + PageRank on a 5000-file monorepo is memory-heavy; the rest run on 1GB / shared-cpu-1x
Operational hardening on LGTM Security after a couple of weeks of real-traffic learnings. Tightened job locking, made every failure surface to the UI, and laid the groundwork for scaling out workers.
Job locking to prevent concurrent security scans on the same monitor — double-fires under load were occasionally creating duplicate audit-log entries
Failure notifications + retry queuing — failed scans now emit a Notification, get reported to Sentry, and retry with exponential backoff instead of silently dying
Startup cleanup — orphaned PRs, RepoContexts, and SecurityScans left in mid-state by a previous container's hard kill are reset to a clean state on boot
Rate-limit hardening across security routes — separate limiters for write operations (enroll/unenroll/pause/policy edits) vs read operations
Socket.IO config overhaul — Redis adapter wired so progress events fan out across multiple API instances instead of being trapped on one Fly Machine
Global failure-toast UI — every worker error now surfaces a user-friendly toast in the dashboard instead of failing silently
Synthesizer threshold + BullMQ lockDuration grace tuned for stability under load
We started formally tracking changes from this date. Earlier work — the 6-specialist review agent pipeline, BYOK provider support, tree-sitter + PageRank context indexing, the 16-rule LGTM Security detector library, the runtime watchdog GitHub Action, and the LGTM Security launch on 7 May — is part of the v1.0 baseline and not enumerated here. From this entry forward every meaningful change gets a line.