All deployments

Peter Theill
Peter Theill 
deployed a feature about 1 month ago
about 1 month ago
✨ Press assets page + rubocop fix
packages#assets now renders a download grid (logo in every directory size,
screenshots) with the JSON manifest still available — the Maker feature is
visible instead of a bare JSON endpoint.
📝 Rewrite the pre-pivot copy — about, help, README; strip public submission feed

  • About and help pages now tell the package-once-launch-everywhere story


(the upvote/bookmark/hot-ranking product they described is gone), styled
to the monochrome direction

  • README rewritten as the launch pitch + accurate dev/production setup;


the four docs it linked no longer existed

  • /directories/:slug no longer lists other users' recent submissions


(name + project + status was public), keeping the page as a sales asset
🔥 Purge the directory-era product-discovery stack

  • Delete the 11 crawlers, orchestrator, ProductSource model, its admin UI,


AutoDiscoveryJob and SourceCrawlJob (WebScrapingJob stays — /launch uses
it for enrichment)

  • Drop the product_sources table

  • Remove empty bookmarks/comments/upvotes helpers and the orphaned


upvote/bookmark helper methods

  • Replace the 241-line demo seeds (sample users with password123 — harmful


in production) with idempotent directory CSV import + launch package
seeds only
🔊 Add Sentry error tracking (inactive until a DSN is configured)
🔧 Align Ruby to 3.4.7 everywhere, fix onboarding landing spots

  • Dockerfile built 3.4.2 and the deploy workflow pinned 3.3.9 while CI


tested on .ruby-version (3.4.7) — all three now agree

  • New signups land on /launch instead of the marketing homepage

  • The unauthenticated /launch fallback stores a return-to so sign-in leads


back to the just-created package
🔒️ Close the pre-launch security gaps

  • SSRF guard (SafeUrl) on metadata scraping and favicon downloads: http(s)


only, and no hosts resolving to private/loopback/link-local space

  • Rate limits on sign_up, password resets, unauthenticated project


creation, and the metadata endpoint (sessions already had one)

  • Enforced Content-Security-Policy with per-request script nonces, pinned


script hosts, and frame_ancestors none

  • Drop users.hn_username / hn_password_encrypted: no UI ever wrote them,


stored unencrypted, only fed the paused automation tier

  • Untrack data.dump (a production pg_dump!) and ignore *.dump in git and


docker builds — note: it remains in git history
🔒️ Gate the extension API behind per-user tokens
Implements the recommended call from the launch plan: /api/packages/:slug,
/api/directories/lookup and /api/directories/map now require
Authorization: Bearer <api_token> from a plan with extension access, and
packages/mappings are scoped to the caller's own projects — packages are no
longer publicly enumerable and the Maker tier's headline feature is actually
gated.

  • users.api_token (has_secure_token) + lazy backfill via User#api_token!

  • Token shown on /extension when signed in with extension access

  • Extension v1.7.0: token setting in ⚙, Bearer header on API calls, clear


401/403 messages; stale subdomain copy removed

  • rake extension:build regenerates public/launch-to-win-extension.zip from


source (was a stale hand-made 1.6.0); rebuilt at 1.7.0
:email: Wire production SMTP through Resend and fix the from-address

  • production.rb delivers via smtp.resend.com:465 using the smtp.password


credential (a Resend API key); delivery errors now raise so failures
surface instead of silently defaulting to localhost:25

  • From-address is Launch to Win <hello@mail.launchto.win> instead of the


commanigy.com leftover
Remaining manual steps: create the mail.launchto.win sending domain in
Resend, add its DNS records, and put the API key in credentials as
smtp.password.
🔒️ Make billing production-safe: add stripe gem, refuse simulated checkout in production

  • gem 'stripe' so live mode can actually engage once credentials


(stripe.secret_key, webhook_secret, prices.maker/pro) are added

  • PaymentsService raises NotConfiguredError instead of granting plans for


free when Stripe is unconfigured in production

  • detect_plan re-fetches the checkout session with line_items expanded


(webhook payloads omit them)

  • Webhook lifecycle tests: activation from metadata, price-id fallback,


subscription deleted, payment failed
🔒️ Enforce plan limits server-side

  • ProjectsController new/create check can_create_package? (the /launch form


was reachable past the hidden dashboard button)

  • Directory submissions: free-tier directory_copy_limit enforced per project;


automation_enabled honored only for plans with auto_submit

  • retry_automation requires can_auto_submit?

  • Automation toggle hidden behind the (off) directory_submissions_enabled


flag + plan check, and no longer defaults to checked

  • DirectorySubmissionJob emails failure once after retries are exhausted,


not on every attempt

  • Fix ensure_owner redirects that pointed at the removed GET project route

  • Tests for the new enforcement paths

🚑️ Stop hourly AutoDiscoveryJob, fix admin 500 and dead links, add admin:promote task

  • Remove the hourly production AutoDiscoveryJob schedule that was creating


ownerless projects from crawled sources (and exposing them via the API)

  • admin/projects index no longer calls the removed bookmarks_count column;


Stats now shows directory submission count

  • Admin 'view' links point at the package (project_path only routes DELETE)

  • bin/rails admin:promote EMAIL=... mints the first real admin

💄 Freemium pricing display, pricing-fields UX, form field class normalization
Also save docs/road-to-prime-time.html — the launch-readiness plan.
Support
Support 
deployed a bug fix about 1 month ago
about 1 month ago
🐛 Fix deploy: Dockerfile Ruby 4.0.3 to match .ruby-version; deploy runner only needs kamal, not the app bundle
Peter Theill
Peter Theill 
deployed a styling change about 1 month ago
about 1 month ago
💄 Bricolage Grotesque display over Inter, Geist Mono accents
Peter Theill
Peter Theill 
deployed a styling change about 1 month ago
about 1 month ago
🔥 Remove brand pages and the wildcard-subdomain requirement
Support
Support 
deployed a feature about 1 month ago
Support
Support 
deployed a feature about 1 month ago
Peter Theill
Peter Theill 
deployed a styling change about 1 month ago
Peter Theill
Peter Theill 
deployed a dependency update about 1 month ago
about 1 month ago
⬆️ Upgrade libraries
🔥 Remove domain verification and project claiming
Projects are now owned by their creator from the moment they are made.
The claim/verify flow (meta tag, DNS TXT, file upload, page content),
the ProjectClaim model, the verification columns on projects, and the
verified-owner gate on brand pages are all gone. Existing submitted-but-
unclaimed projects were handed to their submitters in the migration.
Peter Theill
Peter Theill 
deployed a styling change about 1 month ago
about 1 month ago
💄 Inter typography and a headerless sidebar

  • Bundle Inter (variable, latin woff2 from Google Fonts) and use it


throughout with a larger type scale — body 14px, labels 13px,
hints 12px — replacing the system-font 11-13px mix

  • Drop the topbar (logo + name + subtitle): the sidebar's own Chrome


header already identifies the extension. The ⚙ settings toggle
moves into the Package slug section's header row, with the settings
panel opening directly beneath it. Bumps to 1.6.0
Peter Theill
Peter Theill 
deployed a dependency update about 1 month ago
about 1 month ago
⬆️ Update brakeman to 8.0.6
bin/brakeman passes --ensure-latest, which exits 5 without scanning
whenever the gem is behind — the actual reason scan_ruby has failed
in CI since March.