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.6 —
marketing/OFFICE-HOURS.mdplaybook (operational). - M16.8 —
marketing/CO-MARKETING-PITCH.md— four ≤200-word
pitch templates (Anthropic / Cursor / Vercel / Stripe).
- M16.1 —
marketing/DATA-REPORT-Q1-EDITION.md— first quarterly
edition working draft; depends on M13.5 for live aggregates.
- M16.3 —
/storiespage (markdown-driven, mirrors/changelog)
+ harvest-discipline editor notes.
- M16.5 —
/wrappedprivate 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 in→3 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)
cannyjoins 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)
clerkjoins 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)
betterstackjoins 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/v2surface.
2026-05-04 — M11.x.2: Lemon Squeezy Connected Check (Billable pillar)
lemonsqueezyjoins 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)
plausiblejoins 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
hostscope. - Existing
pruneIntegrationsBeyondPlanmap 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-002 — npx -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-001 — ADD COLUMN ... NOT NULL without DEFAULT (locks the table to update every row). - MIGRATION-SAFETY-002 — DROP COLUMN (permanent data loss; whatever you think is unused often isn't). - MIGRATION-SAFETY-003 — ALTER COLUMN ... TYPE (most type changes rewrite the entire table — minutes-long lock on a large one). - MIGRATION-SAFETY-004 — DELETE 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_launchnow 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.