Skip to main content

Release notes

What's new

A plain-language record of what changed and when. We ship constantly; this page is how we keep ourselves honest about it.

  1. We have a new name — Celestivya

    • The site you're reading is now called Celestivya. Same team, same four traditions, same honest stance — new name. The original short domain we hoped for was already taken, so we secured celestivya.com instead. The new domain is being wired up; until DNS finishes propagating worldwide, the site continues to load at its existing address.
    • The rename touched every page, every chat reply, every report, every email, every push notification, and the home-screen install prompts. If you spot a stray "CosmicPath" anywhere, that is a leftover in our docs (not in the product) and we will sweep it.
    • Your account, your saved memory, your reading history, your subscription state, and any reports you have already bought are fully preserved — the underlying database, payment integration, and user IDs are unchanged. You will not need to sign in again or repurchase anything.
  2. Stale-cache fix — every deploy now reaches every browser

    • Fixed a subtle but serious stale-cache bug where browsers that visited the site early (before recent checkout fixes) could be stuck on outdated JavaScript for up to a year. Our edge cache rules marked /static/* as immutable, 1 year, but the underlying files weren't content-hashed — same filename across deploys. Result: returning visitors silently got the old code while new visitors got the new code.
    • Two-part fix: (1) edge cache headers now expire /static/ JavaScript every 5 minutes (with revalidation) instead of caching for a year; (2) every <script> tag now includes a ?v=<build-sha> query string, so every deploy is a brand-new URL the browser has never seen — bypassing any stale cache entirely. Net effect: a fix shipped today reaches every browser on the very next page navigation, no hard-refresh needed.
    • Also enabled a temporary email sandbox fallback so magic-link signin works while we finish verifying the cosmicpath.ai domain with our email provider.

    commit 8f05b59 →

  3. International checkout — now live for 180+ countries

    • We now accept payments from 135+ currencies across 180+ countries via Razorpay International. International buyers pay in USD with their foreign-issued Visa, Mastercard, or Amex; Indian buyers continue to pay in INR with all the usual options (UPI, netbanking, cards, wallets, EMI, pay-later). Same modal, same secure flow, end-to-end tested.
    • Previously the checkout was wired to route non-Indian buyers to a payment provider that wasn't configured yet — they'd click Buy and see "Checkout is being set up" even though we had a working processor live. Fixed by re-routing all checkouts through Razorpay, which is the only provider currently wired and supports the full international card matrix.
    • No-op for existing Indian buyers — the INR path is unchanged. The fix is purely additive: international markets that previously saw a "coming soon" message can now complete real purchases.

    commit 67e626c →

  4. Razorpay checkout fix — modal now opens correctly

    • Fixed a silent CSP regression that left the Razorpay payment modal invisibly broken for INR-paying users. The Razorpay checkout script lazy-loads its actual user interface from two other CDN origins (cdn.razorpay.com for icons + risk detection, checkout-static-next.razorpay.com for the UI chunks and fonts). Neither was on our Content-Security-Policy allowlist, so the browser silently blocked the chunks. The iframe was created but stayed 0×0 invisible — hence the "opening but not opening" symptom. Both origins are now allow-listed; modal renders end-to-end with all card networks, banks, wallets, UPI, and pay-later options.
    • Headless-browser verification: post-fix, the Razorpay iframe loads at full 1280×800, all 30+ asset fetches return 200, and the underlying api.razorpay.com/v1/standard_checkout/checkout/order call succeeds with the pre-created order ID.
    • Added narrowly-scoped self-debug tooling — a POST /auth/_dev_signin endpoint and a ?cp_geo=XX query override — both hard-gated on a DEV_SIGNIN_TOKEN env binding. They return 404 / no-op in production once the binding is removed, and are marked in code for one-diff removal once magic-link email is wired and the operator can self-serve.

    commit 6ef4c06 →

  5. Operator scaffolding + HTML cache-header HEAD-request fix

    • Closed the last "where do I paste credentials?" gap. Every remaining production-grade integration (Sentry, Resend, Razorpay, Stripe, VAPID, OpenAI, Turnstile, Google OAuth, Cron token, Auth secret, Cloudflare Analytics, custom-domain switch) now has its code-side wiring complete. New OPERATOR_RUNBOOK.md lists every credential, the exact wrangler pages secret put command to set it, where to obtain it, and which source file already consumes it.
    • Sentry error tracking is now wired into the HTML shell — gated entirely on a SENTRY_DSN secret. When the operator sets it, the Sentry browser SDK loads asynchronously and stamps every captured error with the build SHA, so issues group by exact deploy. When the secret is absent, nothing ships and there is zero cost. Sister to the existing client-error tracker we already write to our own database.
    • The brand canonical domain is now env-driven. Setting BRAND_DOMAIN=cosmicpath.ai after DNS lands flips deploy-preview canonicalisation and structured-data fallback URLs without a code change or redeploy. (Live request URLs already flowed through automatically — this just fixes the fallback path.)
    • Fixed /.well-known/security.txt — the contact address was previously derived from the brand URL's hostname, which produced the non-routable placeholder [email protected]. Now uses the proper [email protected] from the brand config directly.
    • Edge cache headers now also apply to HEAD requests. Real visitors (who use GET) were always getting cache headers — that part worked. But Cloudflare's edge cache uses HEAD to revalidate freshness, and our middleware was explicitly skipping HEAD, which meant CF's revalidation pings paid full origin cost. Smoke tests using curl -I (HEAD) were also misleadingly showing "no cache headers" for the same reason. Both fixed in one line.

    commit 88a45b7 →

  6. Production hardening II — faster page loads, CSP observability, monitor-friendly health checks

    • The site is now noticeably faster on repeat visits. Static assets (CSS, fonts, brand icons, OG images, favicons) now ship with proper long-lived cache headers — the Tailwind CSS bundle in particular is now cached for a year (it changes filename when its content changes, so a year-long cache is correct). Before, every visitor refetched every static file on every page, which was wasteful and slowed first paint.
    • Moved the page-edge-cache middleware out of dead-code position (it had been registered AFTER all the page route handlers, which in Hono means it never actually ran on those pages). Also expanded the safe-to-cache page list from 17 entries to 30 (added /methodology, /accuracy, /contact, /changelog, /blog, etc.) plus pattern prefixes for /learn/*, /blog/*, /nakshatras/*, /tarot/*. Production verification of the header emission is pending.
    • Added CSP violation reporting. If a future deploy accidentally introduces an inline <script> (or hot-links a third-party CDN that's not on our allow-list), modern browsers now POST a violation report to /api/log/csp-report, which lands in our database for triage. Previously, CSP regressions would have shipped unnoticed until a user reported something broken.
    • Added /api/version for ops monitors (Datadog, Grafana, etc.) that probe that convention. Returns the same brand + build metadata as /api/health/version. Sister to the existing /healthz (Kubernetes convention) alias.
    • Internal: X-Frame-Options legacy header now matches the modern CSP frame-ancestors 'none' directive (was inconsistent — legacy browsers could iframe the site even though modern browsers couldn't). Both now say "no embedding anywhere", consistently.

    commit 5c33fff →

  7. Production hardening — iOS home-screen icon + analytics + honest error tracking

    • When you save CosmicPath to your iPhone home screen, iOS Safari now finds the right icon. Before this release, the browser probed /apple-touch-icon.png at the site root and got a 404, falling back to an ugly screenshot of the page. The 180×180 brand icon (and its older-iOS sibling apple-touch-icon-precomposed.png) now live at the root and the home-screen install is clean.
    • We turned on Cloudflare Web Analytics for the site. It is privacy-friendly — no cookies, no GDPR popup, no third-party trackers — and is gated on a server-side secret, so preview deploys and local dev stay completely clean. We are using it to understand which pages are landing well and which are quietly broken, not to follow individual readers around.
    • Added honest client-side error tracking. When a JavaScript bug fires in your browser — a crashed widget, a failed promise, a stray undefined — the page now quietly reports just the error message and the path it happened on (no IPs, no user identifiers, no full URLs with question text) so we can find and fix bugs we would otherwise never hear about. The reporter is heavily throttled (max 5 per page-load, 30 seconds apart) so a single broken page cannot flood the channel.
    • Internal: the /api/health endpoint now appends -dirty to the commit SHA when the deploy was built from an uncommitted working tree. Previously the health endpoint could quietly report a clean SHA for a release that did not actually match the code on GitHub — now it tells the truth, which makes diagnosing "is the fix live yet?" questions instant.

    commit 93449e3 →

  8. OG image coverage — 4 new SKUs unbroken + dynamic OG endpoint

    • Fixed broken social-link previews for the 4 newest reports — Muhurta Selector, Vastu Audit, Past-Life Pattern, and Year of Two Halves. When someone shared those product pages on Twitter / LinkedIn / WhatsApp / Slack / Discord, the preview image was returning 404 because the per-SKU JPGs had never been shipped after Session 2.10 added the SKUs themselves. The product pages worked, but every social share looked broken.
    • Rather than ship 4 more hand-crafted JPGs, we extended the existing dynamic OG image endpoint at /api/og/:type/:slug (which already powered tarot card + nakshatra detail previews) to support a report type. Every report product page now serves a brand-aligned 1200×630 SVG card built on the fly with the report's own name as the title and its short tagline as the subtitle — no static assets to ship per release. Any future SKU gets a working social card automatically.
    • Also fixed a quiet bug where og:image:type was hard-coded as image/jpeg for every page including the SVG-based tarot, nakshatra, and blog cards. Some crawlers (notably WhatsApp) reject the preview when the declared MIME type does not match the actual response. MIME is now inferred from the URL: /api/og/*image/svg+xml, .pngimage/png, otherwise image/jpeg.
    • Cleanup: removed 840 KB of unreferenced static JPGs from public/images/reports/. The dynamic endpoint replaces all of them.

    commit 68ef770 →

  9. Top-nav restructure + landing page closure

    • The Reports mega-menu in the global site header had been silently broken on every page: all items linked to the bare /reports catalog instead of their own product pages, 3 listed items did not even exist as SKUs (Birth Chart Deep Dive, Marriage Compatibility, Career & Vocation), the 4 new SKUs from Session 2.10 were completely invisible in the top nav, and "Membership pricing" carried a false new badge. All four bugs fixed in one restructure.
    • The Reports menu now shows 3 columns × all 10 real SKUs, each linking directly to its own product page. Columns grouped by theme: Decision & love (Life Crossroads, Love & Relationship, Past-Life Pattern), Work & timing (Career & Money, Annual Forecast, Year of Two Halves, Muhurta Selector), Vedic & inner-work (Vedic Premium, Soul Path, Vastu Audit). 4 new SKUs carry a new badge for discoverability. A 4th utility column keeps Pricing / How-we-write / Refund-policy / All-reports links accessible.
    • The homepage landing section Reports preview now reads Paid reports — ten in the library instead of six. This was the last remaining "six" reference on a user-visible surface.
    • 5 internal code comments referencing "all 6/six SKUs" refreshed to "all 10 SKUs" in productPage.ts, catalogPages.ts, admin/reports-preview.tsx, reports.ts, and the renderer sample-data block. Cosmetic but keeps the codebase honest for future engineers.

    commit 866b219 →

  10. Stale-copy + saved-readings UX polish — 10 gaps closed

    • The /reports page now correctly says "Ten readings. One library." and "Ten reports. One-time payment." instead of stale "Six" — Sessions 2.10/2.11 added 4 new SKUs but never refreshed the hero and trust banner. The SEO title and description on /reports now list all 10 reports by name so Google crawls them properly.
    • /pricing CTA button now says "Browse the ten reports" instead of "six".
    • Your saved-readings library at /account/readings finally has filter chips for Oracle, Numerology, and Daily Mirror — Session 2.11 wired the save hooks but the filter row was still Tarot + Snapshot only. If you have run 30 Oracle questions, you can now filter to just those.
    • The page lede and empty-state copy on /account/readings now mention all 5 save sources (tarot, snapshot, oracle, numerology, daily mirror) instead of just the original two. Three new CTA buttons in the empty state link to Ask the Oracle, Numerology, and Today's Mirror alongside the existing tarot + snapshot buttons.
    • List rows for Oracle, Numerology, and Daily Mirror readings now show meaningful titles instead of just the bare type label. An Oracle row shows the question (trimmed to 80 chars), a Numerology row shows the person's name, a Daily Mirror row shows the body title or date. Same scannable pattern tarot rows have always had.

    commit aec7ccd →

Older entries live in CHANGELOG.md on GitHub.