Changelog

PulseLight is the launch and scale readiness platform for AI-built apps. This is the public log of what shipped, when, and what changed for founders using the product.

2026-05-04 — Growth track autonomous batch (M13–M16 partial)

Shipped in one focused session, ordered by impact-per-LOC:

  • M14.7 — Win-back coupon embedded in Day-30/60 drip email when

STRIPE_PROMOTION_CODE_WIN_BACK env var is set.

  • M15.6 — "What's new" pill in workspace header; localStorage

read-state, self-suppresses when current.

  • M15.7 — "Almost there" verdict variant for 1-2 blockers.

Re-frames remaining work as proximity to launch ("1 blocker from launch-ready" vs "1 thing should be fixed"). Small pill above subline; pure copy + UI emphasis.

  • M14.4 — Pause subscription. Stripe pause_collection.behavior=void

for 1/2/3 months; auto-resumes at end. New API endpoints + Pause dropdown next to Manage subscription.

  • M16.2 — Co-founder invite link on every Project Overview.

Reuses existing workspace-invite system; quiet always-present CTA.

  • M13.2 — Pricing CTA copy: "Start Studio free for 14 days · drops

to {tier} at trial end" — makes the reverse-trial mechanic visible.

  • M15.2 — Weekly digest reframed as a "report card." New

"Pick this week:" closing sentence pointing at a single highest-leverage next action.

  • M16.6marketing/OFFICE-HOURS.md playbook (operational).
  • M16.8marketing/CO-MARKETING-PITCH.md — four ≤200-word

pitch templates (Anthropic / Cursor / Vercel / Stripe).

  • M16.1marketing/DATA-REPORT-Q1-EDITION.md — first quarterly

edition working draft; depends on M13.5 for live aggregates.

  • M16.3/stories page (markdown-driven, mirrors /changelog)

+ harvest-discipline editor notes.

  • M16.5/wrapped private cumulative recap. Composes existing

trajectory + prompt-outcomes data; no new endpoints. Self-suppresses when scansRun < 3.

  • M14.3 — Compliance Pack foundation: migration 059 +

compliancePackPriceId() helpers. Checkout / webhook / email / download page deferred (mirrors Investor Report Pack when wired).

Removed by founder principle ("PulseLight is a confidence-building product, not a public-judgment product"):

  • M13.3 (public verdict page), M13.4 (badge re-promote), M16.7

(built-with-Cursor chip on public verdict).

Deferred to focused future sessions:

  • M14.2 per-seat, M14.5 Studio Agency tier, M14.6/M13.6 Free tier,

M15.3 pillar-greened toast, M15.5 onboarding rework, M13.1 OG card, M13.5 peer benchmark band, M16.4 referral primitive.

2026-05-04 — M15.1: "Since you started" trajectory strip on dashboard

  • New calm dashboard strip showing three cumulative numbers:

days here · scans run · projects launched.

  • Sits below the soft-cap meter, above the weekly hero — visual

hierarchy goes attention → cumulative → this-week → portfolio.

  • Self-suppresses on fresh workspaces (scansRun < 3); auto-collapses

the "projects launched" stat when it's zero.

  • Day count formats adaptively: 5 days in3 weeks in → `4 months

in` so it stays one short phrase regardless of tenure.

  • New endpoint GET /workspaces/:id/trajectory. Single grouped query.

2026-05-04 — M14.1: Annual prepay lift to 20% off + prominent savings labels

  • Yearly discount bumped 17% → 20% across all three tiers. New

yearly prices: Pro $278, Growth $566, Studio $948 (was $290 / $590 / $990).

  • New helpers yearlySavingsAmount(tier) + yearlySavingsPercent(tier)

in shared-utils — every label that quotes the discount is now computed from the price constants, not hardcoded. Future pricing changes won't drift the marketing copy out of sync.

  • Pricing-page yearly line now renders a green "Save $X (Y% off) with

yearly" badge directly under the monthly price, replacing the parenthetical "(17% off)" footnote treatment.

  • Trial-ending banner + upgrade-modal toggle + Day-7 trial recap email

all updated to derive the percent from the helper.

  • Operator follow-up required: create new Stripe Price objects at

the new amounts and rotate the STRIPE_PRICE_*_YEARLY env vars before deploying — the displayed price now diverges from the charged price until the env-var rotation lands.

2026-05-04 — M11.x.6b: Fix progress card (prompt outcome telemetry)

  • New Fix progress card on the Reports tab. Aggregates Fix-with-AI

prompt consumption against the latest scan's findings to answer "of the prompts I've consumed, how many actually cleared?" - Three top-line stats: Prompts consumed, Cleared, Still open. - Per-pillar breakdown table (only pillars with non-zero consumption render). - Counts unique by fingerprint, not by raw event — re-consuming a prompt for the same finding doesn't double-count. - Self-suppresses when no prompts have been consumed yet, so fresh projects don't see an empty placeholder.

  • New endpoint: GET /workspaces/:wid/projects/:pid/prompt-outcomes

returning PromptOutcomeSummaryDto. Resilient to the prompt_consumption_events table being absent (returns empty summary, no 500).

2026-05-04 — M11.x.5: Canny Connected Check (Usable pillar)

  • canny joins the Connected Check roster as feedback / feature-

request live evidence for the Usable pillar. Same founder question as the static feedback-path rules ("Can users tell me what's missing?"), different evidence shape: - CONN-CANNY-BOARDS-001 — Canny is connected but no public boards exist (users have nowhere to submit feedback). - CONN-CANNY-STALE-001 — boards exist with posts, but the most recent is > 60 days old (channel has gone cold; usually because users were never told it existed).

  • API key auth via Canny's older REST surface (apiKey passed in

request body, not header).

2026-05-04 — M11.x.4: Clerk Connected Check (Secure pillar)

  • clerk joins the Connected Check roster as auth-platform live

evidence for the Secure pillar. Closes the static ACCESS-* rules' weakness — the scanner can detect Clerk is imported, but only the live API tells the founder which Clerk instance the prod env-var resolves to and whether MFA enrolment is happening: - CONN-CLERK-INSTANCE-001 — instance environment is not production (catches sk_test_... keys pasted into prod env-vars). Defensive on null/unknown values — only flags an explicit non-production string. - CONN-CLERK-USERS-001 — production instance has ≥5 registered users and zero of the first 100 sampled have MFA enrolled.

  • API key auth via Clerk's Backend API (api.clerk.com/v1).

2026-05-04 — M11.x.3: Better Stack Connected Check (Stable pillar)

  • betterstack joins the Connected Check roster as the external

uptime / incident-management complement to Sentry. Different evidence shape (external pings vs in-app exceptions), same Stable pillar — both answer "will I find out before users?": - CONN-BETTERSTACK-MONITORS-001 — workspace has zero active uptime monitors (paused / pending ones don't count). - CONN-BETTERSTACK-DOWN-001 — at least one active monitor reports down right now. Lists up to 3 names in the title; suffix "+ N more" beyond.

  • API token auth via the uptime.betterstack.com/api/v2 surface.

2026-05-04 — M11.x.2: Lemon Squeezy Connected Check (Billable pillar)

  • lemonsqueezy joins the Connected Check roster as the merchant-

of-record alternative to Stripe. Same Billable pillar, three rules mirror the Stripe set: - CONN-LMSQ-WEBHOOK-001 — store has no live-mode webhook (test-mode webhooks don't count as production coverage). - CONN-LMSQ-EVENTS-001 — webhook(s) exist but skip critical events (subscription_cancelled / subscription_updated / subscription_payment_failed / order_created). Coverage is aggregated across multiple webhooks. - CONN-LMSQ-MODE-001 — store still in test mode (real customer cards can't be charged).

  • API key auth via Lemon Squeezy's JSON:API surface.

2026-05-04 — M11.x.1: Plausible Connected Check (Measurable pillar)

  • plausible joins the Connected Check roster as a privacy-first

PostHog alternative. Same Measurable pillar, different evidence shape: Plausible models analytics as pageviews + named "goals" rather than arbitrary event definitions, so the rule pack is narrower. - CONN-PLAUSIBLE-INGEST-001 — site has 0 pageviews + 0 visitors over 30 days (script tag missing, domain mismatch, ad-blocker). - CONN-PLAUSIBLE-SIGNUP-001 — pageviews exist but no goal matches a signup-style name (Plausible reports goals separately from pageviews; without one, you see traffic shape but not conversions).

  • API key auth, Growth tier, supports self-hosted via host scope.
  • Existing pruneIntegrationsBeyondPlan map fixed in passing — it was

missing PostHog / Stripe / Sentry, so a downgrade kept those rows active even after the tier check forbade re-connect. All four Growth-tier platforms now properly prune.

2026-05-04 — M10.x.3: Frontend-exposed LLM key rule (Secure pillar)

  • LLM-FRONTEND-001 — emerging 2025 pattern in AI-built apps:

Cursor / Bolt / v0-generated code declares LLM API keys with a NEXT_PUBLIC_ / VITE_ / PUBLIC_ / REACT_APP_ / EXPO_PUBLIC_ prefix because the AI tool sees the variable used in a client component and "fixes" the runtime error by promoting it to the public namespace. Result: every visitor receives the API key in their JS bundle. Existing AI-RATE / AI-COST rules don't help — abuse traffic comes from the leaked key in any browser, not the founder's server.

  • Scans .env.example/.sample/.template (+ monorepo

apps/<name>/.env.example) and framework configs (next.config.*, vite.config.*, astro.config.*). Snippet redaction strips long values so the report doesn't round-trip a real key.

2026-05-04 — M10.x.2: MCP server security rule pack

  • Two new Secure-pillar rules scan committed MCP configs

(.mcp.json, .cursor/mcp.json, .claude/mcp_servers.json, mcp.config.json) for risky patterns: - MCP-SEC-001 — hardcoded secret in an env field. The MCP spec supports ${VARNAME} references; literal API-key-looking values suggest a credential pasted straight into the config. - MCP-SEC-002npx -y (or npx without a pinned version) used as the server command. Fetches the latest published package at every start — supply-chain risk if the upstream package is compromised.

  • Snippets redact the literal secret (<redacted>) so the report

doesn't round-trip the credential. Each finding points at the specific line in the config.

2026-05-04 — M10.x.1: Migration-safety rule pack

  • Four new Stable-pillar rules scan committed migration files for

patterns that historically take down small startups during a deploy: - MIGRATION-SAFETY-001ADD COLUMN ... NOT NULL without DEFAULT (locks the table to update every row). - MIGRATION-SAFETY-002DROP COLUMN (permanent data loss; whatever you think is unused often isn't). - MIGRATION-SAFETY-003ALTER COLUMN ... TYPE (most type changes rewrite the entire table — minutes-long lock on a large one). - MIGRATION-SAFETY-004DELETE FROM <table>; with no WHERE clause (mass delete in a migration; almost always a mistake).

  • Scans migrations/, db/migrations/, prisma/migrations/,

supabase/migrations/, drizzle/, apps/api/migrations/. Caps at 500 files / 256KB per file so big monorepos don't fan out.

  • Each finding points at a specific file + line. Founder copy explains

the failure mode + a safe alternative.

  • Registry version bumped to 3 — version-aware drift / launch-baseline

diff fences off the transition cleanly.

2026-05-04 — M9.x.2: Demotion + email consolidation + copy refresh

  • Public Readiness Badge demoted. Renamed the project-settings

section from "Sharing" → "Embeds" and removed the redundant outer header; the badge component now speaks for itself in a quieter collapsed accordion at the bottom of the stack. Anyone looking for it still finds it; it stops competing with actively-used settings.

  • Mark-as-launched email steps lighter when the first-fix email

already fired. Previously both said "watching for drift across the seven pillars" — now the launched email focuses on the monitoring-mode-specific value (launch baseline captured, "Since launch · …" delta tracking) when the founder has already been celebrated.

  • Verdict subline copy refresh. ready_to_launch now anchors

the next action ("Mark as launched when you ship and PulseLight will switch to monitoring mode") instead of reading as an instruction; risky_but_shippable softens "could hurt activation or reliability" → "are worth fixing before real users come"; monitoring_only is specific about what's tracked ("watching for drift since launch").

2026-05-04 — M9.x: Fix-in-progress card state + 24h nudge

  • In-progress pill on Fix Queue cards (and Project Overview Top 3).

When you've consumed a Fix-with-AI prompt for a finding, the card now shows "in progress · started Xh ago" — the queue reads as a continuation of work rather than a fresh list every visit. Survives re-scans by matching on fingerprint.

  • 24h "still stuck?" nudge email. If the founder consumed a fix

prompt, 24h have passed, and the same fingerprint is still on the latest scan, daily sweep sends one nudge per consumption cycle. Re-consuming the prompt resets the cycle.

  • migration 058 tracks (project, fingerprint, consumed_at) so re-runs

don't re-fire and a fresh attempt earns a fresh nudge.

2026-05-04 — M12: VS Code extension + marketing playbooks

  • VS Code extension (apps/vscode). Three commands —

*What's blocking my launch?*, *Re-scan project*, *Open dashboard* — plus a calm status-bar verdict that shows the current launch state without leaving the editor. Reuses the CLI / MCP credentials at ~/.config/pulselight/credentials.json so one login covers all three editor surfaces.

  • Marketing playbooks in marketing/ — outreach playbook

(audiences, channels, hooks, anti-patterns), demo-recording checklist (timing, what to show / not show), newsletter cadence (bi-weekly, structure, anti-patterns), 50-AI-repos data report outline (sourcing posture, structure, distribution).

(Demo GIF, the actual data report, peer benchmark digest deferred — each needs operator work that lives outside this repo.)

2026-05-04 — M11: PR comment slash commands

  • /pulselight rescan — comment this on any PR or issue in a repo

with the GitHub App installed and PulseLight triggers a fresh scan on the default branch, then replies with a link to the dashboard. No-op if a scan is already running.

  • /pulselight help — posts the list of available commands.
  • Slash commands respect the existing project-not-found / non-bot

filter rules, so noise stays low. Supports the in-between use case where the founder fixed something on a platform (Vercel, Supabase, …) without a code change and wants a fresh scan immediately.

(Other M11 scope — Clerk, Lemon Squeezy, Better Stack, Plausible, Canny Connected Checks plus the bidirectional Slack bot and prompt outcome telemetry surfaces — deferred. Each new Connected Check is its own milestone-sized integration.)

2026-05-04 — M10: Stage-transition retention emails

  • Stage-transition emails fire when a founder flips a project's

launch_stage (pre_launch → first_100_users, or → scaling). Each stage's email frames the *new* priorities for that window — payment- success / activation / failed-signup signals when entering First 100 Users; AI / API token spend, DB hotspots, churn risk when entering Scaling. Idempotent per (project, new_stage) so toggles don't re-fire.

(M10's wider rule-pack scope — migration safety, MCP server security, AI session diff sentinel, LLM spend / loop guardrails, DB backup, domain deliverability — needs scanner-side Rust work and is deferred to M10.x.)

2026-05-04 — M9: Soft cap meter + win-back

  • Soft cap meter on the dashboard. Renders past 60% project-cap

utilisation with a calm progress bar; switches to a warning state at cap with an inline upgrade link. Hard 402 enforcement still lives in POST /projects — this is the calm pre-emptive surface so founders see "you have one slot left" before they hit a wall.

  • Day-30 / Day-60 workspace win-back emails. New sweep targets

workspaces that haven't scanned anything in 30+ days. Frames around "what's new since you last looked" — new Connected Checks, the Investor Report Pack, MCP server. 90-day cooldown so Day-30 and Day-60 don't stack.

(Fix-in-progress card state, Public Badge demotion, email consolidation, and the broader vibe-check copy refresh deferred to a follow-up M9.x — this slice ships the highest-leverage activation pieces.)

2026-05-04 — M8: Agency expansion

  • Agency white-label branding at workspace level. Toggle `Settings →

Agency branding`, set brand name, logo URL, and accent color — share- page report headers (incl. the Investor Report Pack) pick the override up automatically. PulseLight attribution stays in the footer.

  • /for-agencies landing — explicit positioning for agencies and

consultancies running pre-launch audits, quarterly reviews, and M&A due diligence on client codebases.

2026-05-04 — M7: Distribution wedge

  • MCP server (@pulselight/mcp) — _early access, npm publish in

flight._ Three tools — pulse_status, pulse_top_blockers, pulse_fix_prompt — let Cursor and Claude Code ground their suggestions in the founder’s real launch readiness state without leaving the editor. Same MCP server, same .mcp.json shape, works in any MCP-aware host. Authenticates via a Personal Access Token minted from Settings → API tokens (server-side audit done; UI shipping in v0.2 of the dashboard).

  • PulseLight CLI (@pulselight/cli) — _internal-only._

Following a publish-readiness audit (system-architect + scanner-engineer), the public CLI was descoped from v1: every scanner-side capability is preserved by the GitHub App + the MCP + a forthcoming GitHub Action, with no rule-pack divergence. Public CI gating ships as @pulselight/scan-action, a thin TS Action that hits the same archive-upload endpoint the CLI did internally. The CLI source remains in the monorepo as an internal dev tool.

  • Claude Code Skill (pulse-fix) — _design pending._ The

Skill encodes a procedural fix-and-ship loop for founders who prefer a single phrase trigger ("is this safe to ship?"). It rides on the same Top 3 + v2 prompt contract as the MCP, but needs the CLI distribution to be settled before its install flow is publicly stable. Revisited once a non-GitHub design partner asks for the standalone CLI; until then the MCP route covers the same Claude Code use case.

  • /works-with-cursor and /works-with-claude-code landing

pages. Each shows a preview of the MCP install flow with an early-access banner until the npm package is public.

  • Public changelog (this page).

2026-05-04 — M6.5: Investor / Advisor Report Pack

  • One-time $99 Investor Report Pack add-on per scan. Productises

the Launch Readiness Report as a branded share-link — anyone with the URL can read the report, no PulseLight account required. Stripe handles checkout in mode: 'payment'; webhook mints the share token and emails the buyer.

  • Reports tab now carries Buy / Resume / Copy share link states for the

pack alongside the existing Launch Readiness Report and Founder Checklist cards.

2026-05-04 — M6: Monetisation tightening

  • Project cap enforcement: Pro = 3, Growth = 10, Studio = unlimited.

Adding past the cap returns 402 with requiredPlan so the upgrade prompt is one click.

  • Yearly cadence surfaced inline on the trial-ending banner:

"· Save 17% with yearly · Switch to yearly →".

  • Day-7 trial recap is now value-led — it names the connected

platforms still working, the worst-blockers project, and the founder's midpoint progress instead of a generic countdown.

2026-05-04 — M5: Connected Check trio

  • PostHog, Stripe, Sentry Connected Checks complete the M5

pillar trio — each cross-pollinates with existing pillars (Measurable, Billable, Stable). PR comments now lead with Connected Check attribution chips when a finding was first surfaced from a connected platform.

How releases are versioned

PulseLight ships continuously. Milestones (M1, M2, …) group themed work; individual changes inside a milestone are tracked in commit history. The public changelog summarises what changed for founders — internal refactors and infra-only changes are omitted.