{"vulnerability": "cve-2026-22732", "sightings": [{"uuid": "3d8e8ac9-f2f3-4a91-90f7-61c46abaac50", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "cve-2026-22732", "type": "seen", "source": "https://cyber.gc.ca/en/alerts-advisories/spring-security-advisory-av26-259", "content": "", "creation_timestamp": "2026-03-19T18:03:42.000000Z"}, {"uuid": "1238c6a8-14a9-4b5e-85f6-6e03925a0701", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "cve-2026-22732", "type": "seen", "source": "https://infosec.exchange/users/offseq/statuses/116258560707903134", "content": "", "creation_timestamp": "2026-03-20T00:00:55.299160Z"}, {"uuid": "ee83bd16-9763-4116-bfab-083289da4ce0", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-22732", "type": "seen", "source": "https://bsky.app/profile/thehackerwire.bsky.social/post/3mhh5kxyjyh25", "content": "", "creation_timestamp": "2026-03-19T23:25:23.151443Z"}, {"uuid": "ee509d88-cc58-483f-b039-c2927fd9fc20", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "cve-2026-22732", "type": "seen", "source": "https://bsky.app/profile/offseq.bsky.social/post/3mhh7kldzju26", "content": "", "creation_timestamp": "2026-03-20T00:00:57.453510Z"}, {"uuid": "bda19918-f010-4f6f-b8b6-50c48bbef3cf", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "86ecb4e1-bb32-44d5-9f39-8a4673af8385", "vulnerability": "CVE-2026-22732", "type": "seen", "source": "https://ccb.belgium.be/advisories/warning-multiple-types-client-side-attacks-spring-security-patch-immediately", "content": "", "creation_timestamp": "2026-03-20T16:25:57.000000Z"}, {"uuid": "f155cb96-038a-42c9-9f7a-9c8dcaf4c045", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-22732", "type": "published-proof-of-concept", "source": "Telegram/gwCxVX_Kdi2486yrOtjel8-BzBIljmHnhHz-TFHu13JlTG4", "content": "", "creation_timestamp": "2026-04-07T19:00:11.000000Z"}, {"uuid": "5183b303-0668-4a0c-98b8-3c2190f54d1c", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-22732", "type": "seen", "source": "https://bsky.app/profile/openrewrite.github.io/post/3ml23txnkc22j", "content": "CVE-2026-22732: a 9.1 critical vulnerability in Spring Security that silently drops your security headers. No error. No log. Just gone.\n\nWe had detection + remediation running in under a day. Whole-perimeter coverage. \n\n\ud83d\udee1\ufe0f This is what zero-day defense looks like: buff.ly/eHVhQOm", "creation_timestamp": "2026-05-04T16:30:47.618546Z"}, {"uuid": "714e9a0f-2a68-4e03-849b-906261cd3b36", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-22732", "type": "published-proof-of-concept", "source": "Telegram/Wl9CrQOxsQx4KE-BWCuSJcJWoX1uryv_sC7BNGTK9kDjsYQ", "content": "", "creation_timestamp": "2026-04-07T21:00:05.000000Z"}, {"uuid": "1f063527-8dec-4550-bb88-202cd7f55eec", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-22732", "type": "published-proof-of-concept", "source": "https://t.me/bdufstecru/3031", "content": "\u0423\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c Java-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 Spring Security \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u043f\u0440\u044f\u043c\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u043e\u0439 \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442. \u042d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u044f \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u043d\u0430\u0440\u0443\u0448\u0438\u0442\u0435\u043b\u044e, \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c\u0443 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0443\u0442\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u0430\n\nBDU:2026-03480\nCVE-2026-22732\n\n\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439 \u0438\u0437 \u0434\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432. \u0412 \u0441\u0432\u044f\u0437\u0438 \u0441\u043e \u0441\u043b\u043e\u0436\u0438\u0432\u0448\u0435\u0439\u0441\u044f \u043e\u0431\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439 \u0438 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u0430\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u043f\u0440\u043e\u0442\u0438\u0432 \u0420\u043e\u0441\u0441\u0438\u0439\u0441\u043a\u043e\u0439 \u0424\u0435\u0434\u0435\u0440\u0430\u0446\u0438\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u043e\u0446\u0435\u043d\u043a\u0438 \u0432\u0441\u0435\u0445 \u0441\u043e\u043f\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0440\u0438\u0441\u043a\u043e\u0432.\n\n\u041a\u043e\u043c\u043f\u0435\u043d\u0441\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0440\u044b:\n- \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432 \u043c\u0435\u0436\u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0443\u0440\u043e\u0432\u043d\u044f \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (WAF) \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0442\u0440\u0430\u0444\u0438\u043a\u0430;\n- \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u043c\u0443 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0445\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043f\u043e \u00ab\u0431\u0435\u043b\u044b\u043c \u0441\u043f\u0438\u0441\u043a\u0430\u043c\u00bb;\n- \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 SIEM-\u0441\u0438\u0441\u0442\u0435\u043c \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438;\n- \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438\u0437 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0441\u0435\u0442\u0435\u0439 (\u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442).\n\n\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439:\nhttps://spring.io/security/cve-2026-22732", "creation_timestamp": "2026-03-23T14:26:48.000000Z"}, {"uuid": "888183a4-7fe1-4533-804f-0ac4bac0e1aa", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-22732", "type": "seen", "source": "https://bsky.app/profile/o2cloud.bsky.social/post/3mmc3hklk2m2e", "content": "\ud83d\udd17 CVE : CVE-2026-22029, CVE-2026-22732, CVE-2026-24734, CVE-2026-24880, CVE-2026-25639, CVE-2026-26960, CVE-2026-29062, CVE-2026-29129, CVE-2026-29145, CVE-2026-29146, CVE-2026-29786, CVE-2026-31802, CVE-2026-33750, CVE-2026-34483, CVE-2026-34487", "creation_timestamp": "2026-05-20T14:10:20.179973Z"}, {"uuid": "44c0af14-1730-450a-bb3e-9c33e4494b07", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2026-22732", "type": "seen", "source": "https://gist.github.com/jaydjj/4243667fde9bb67e39b616d49cefa0dd", "content": "# What's New \u2014 Implementation Roadmap\n\n## What's in the mockup today\n\nThe page at `/whats-new` renders a feed of product update cards with filtering, a recipe digest, and a subscribe dialog. Everything is currently **hardcoded fixture data**.\n\n### Mockup element \u2192 derived source \u2192 production data path\n\n| Mockup element | What's in the code today | Derived from (research) | Production data source | Exists in codebase? |\n|---|---|---|---|---|\n| **Post feed** (hero, standard, spotlight cards) | `STUB_WHATS_NEW_POSTS` \u2014 18 hardcoded posts in `whats-new.fixtures.ts` | 11 monthly customer bulletin drafts (Jun 2025 \u2013 Apr 2026) from a single rolling Google Doc. Each fixture maps 1:1 to a real bulletin item. | Content feed \u2014 see \"Content source\" section below | No |\n| **Status badges** (Available, Coming Soon, In Beta, In Preview) | `WhatsNewStatus` union type with 4 values | Bulletin tagging vocabulary: `[Coming in ]`, `[Coming soon]`, `[In beta]`, `[In design]`, `GA`, `Available` \u2014 used consistently across all 11 issues | Metadata field on each post | N/A (depends on content source) |\n| **Area filter chips** (Platform, CLI, OpenRewrite, Language, Security, Docs) | `WhatsNewArea` union type with 6 values | Bulletin section structure \u2014 every issue groups content by Platform releases, CLI releases, OpenRewrite releases, Language support, Recipe/security drops, and Documentation highlights | Metadata field on each post | N/A (depends on content source) |\n| **Card density** (hero, standard, spotlight) | `WhatsNewDensity` union type \u2014 hero cards pin to top via `pinnedUntil`, spotlight cards get branded styling | Bulletin already mixes density: hero items (CLI v4 with sub-bullets) alongside terse release bullets alongside full-focus recipe spotlights | Metadata field on each post | N/A (depends on content source) |\n| **Release version badges** (e.g. \"OpenRewrite 8.72.0\", \"CLI v4.0.11\") | `WhatsNewReleaseMeta` type with `versionLabel` + `releaseNotesHref` | Bulletin footer \"Product resources\" links \u2014 every issue links to Platform Changelog, CLI/DX Changelog, OpenRewrite Changelog | Could auto-populate from GitHub releases API for CLI and OpenRewrite repos | `release` field on GraphQL `RecipeDescriptor` has version info; GitHub releases API is external |\n| **Coming \u2192 GA lifecycle** (`precededBy` field) | `cli-v4-release` links back to `cli-v4-coming-soon` via `precededBy` | Bulletin pattern: same feature appears in \"Coming Soon\" for 1\u20133 months before flipping to GA section | Metadata relationship between posts | N/A (depends on content source) |\n| **Recipe digest \u2014 top recipes by run count** | `STUB_TOP_RECIPES` \u2014 5 hardcoded recipes with `runs` count | Fidelity telemetry showing 95% of recipe usage is Spring Boot upgrades; most orgs lean on 3\u20135 recipes | `recipe_runs` telemetry table (confirmed by Shannon) \u2014 query for top-N by org | Not wired. Table exists in backend but no GraphQL query exposes per-org recipe run counts. |\n| **Recipe digest \u2014 \"Updated\" flag** | `updated: boolean` + `updateNote` on each recipe | Kiel's per-customer \"heads up, update your recipes\" messages \u2014 TAMs manually notify when recipe versions change | Recipe version diff detection: compare installed recipe versions (recipes.csv / marketplace API) against latest published versions | Partial. `recipeInstallations` query (`queries/federation/recipe.graphql:179`) returns installed recipes. No diff-against-latest query exists. |\n| **Recipe digest \u2014 recipe links** | `Link` component with `recipeDetailsUrl({ id })` | Codebase: `helpers/link.helper.ts` builds `/recipes/[recipeId]` URLs | Already works \u2014 `recipeDetailsUrl` is production code | **Yes** \u2014 `helpers/link.helper.ts`, `pages/recipes/[recipeId].tsx` |\n| **Recipe digest \u2014 new recipe suggestions** | `STUB_NEW_RECIPES` \u2014 2 hardcoded recipes with `id`, `name`, `blurb` | Bulletin \"Recipe corner\" section (~6 of 11 issues) + Kiel's \"automagically deploy new recipes\" request | Diff of newly available recipes in marketplace vs. what org has installed | Partial. `recipeInstallations` query exists. No \"newly added to marketplace this week\" query. |\n| **Subscribe dialog** | `WhatsNewSubscribeDialog` with email input \u2014 purely UI, no backend | Bulletin pre-announcement (Nov/Dec 2025): \"We're developing new ways to help you share\u2026 what tools would help you most\" | Email notification service (does not exist) | No |\n| **\"What's New\" in help menu** | `RESOURCE_LINKS` entry in `help-menu.data.ts` \u2192 links to `/whats-new` | Codebase IA analysis: help menu already groups Resources (Docs, Changelog, Status, Feedback) | Static link \u2014 already implemented | **Yes** \u2014 shipped in this PR |\n| **1-click recipe install CTA** (not yet in mockup) | Not implemented | Codebase: `installRecipesUniversal`, `installRecipesForOrganization`, `installRecipesForCurrentUser` mutations in `queries/federation/recipe.graphql:99\u2013251` with full polling via `recipeInstallationStatus` | Existing mutations \u2014 just need a button on recipe cards | **Yes** \u2014 mutations and polling exist, used by Builder and Deploy pages |\n\n### Existing codebase data points we could pull from\n\nThese GraphQL queries and helpers already exist and could power parts of the page without new backend work:\n\n| Data point | Query / helper | Location | What it gives us |\n|---|---|---|---|\n| Recipe detail + deep link | `recipeDetailsUrl({ id })` | `helpers/link.helper.ts` | Link any recipe name to its detail page |\n| Recipe install (personal) | `installRecipesUniversal` mutation | `queries/federation/recipe.graphql:99` | 1-click install CTA on recipe cards |\n| Recipe install (org-scoped) | `installRecipesForOrganization` mutation | `queries/federation/recipe.graphql:115` | Org-level install CTA (admin-gated) |\n| Install status polling | `recipeInstallationStatus` query | `queries/federation/recipe.graphql:257` | Show install progress after CTA click |\n| Installed recipes list | `recipeInstallations` query | `queries/federation/recipe.graphql:179` | Know which recipes an org already has |\n| Recipe search | `recipeSearch` query | `queries/federation/recipe.graphql` | Power \"new recipes you might like\" with real marketplace data |\n| Help menu customization | `useHelpMenuCustomizationsQuery` | `__generated__/apollo-hooks.ts` | Tenant-specific help links (already renders) |\n| Beta-seen badge pattern | `useBetaSeen()` hook | `hooks/use-beta-seen.hooks.ts` | Unread-dot / \"new\" indicator for the nav link |\n\n---\n\n## Implementation order (easiest \u2192 hardest)\n\n### Phase 1 \u2014 The bulletin goes in-app (1\u20132 weeks)\n\nShip the page with the same content that's already in the monthly customer bulletin, just displayed in the app instead of email. No new backend services needed.\n\n**Cards you get in Phase 1:**\n- **Product announcements** \u2014 the big launches like C# support, CLI v4, Prethink (the hero and standard cards in the mockup). These come straight from the bulletin's \"Product updates \u2014 GA\" and \"Coming soon\" sections.\n- **Recipe spotlights** \u2014 featured recipes like the CVE-2026-22732 zero-day response and the OWASP A05 composite. These map to the bulletin's \"Recipe corner\" section.\n- **Release notes** \u2014 OpenRewrite versions, CLI patch releases, and platform deploys. Each gets a compact card with version badge and bullet points, matching the bulletin's release sections.\n- **Documentation updates** \u2014 new docs pages and guides, matching the bulletin's occasional \"Documentation highlight\" section.\n- **Coming soon / In beta previews** \u2014 features in development like Moderne Factory and Go/Scala support, with expected dates. These are the bulletin's \"[Coming in Q3]\" and \"[In beta]\" items.\n- **Status and area filters** \u2014 users can filter by status (Available, Coming Soon, In Beta, In Preview) and by area (Platform, CLI, OpenRewrite, Language, Security, Docs). These categories come directly from the bulletin's existing vocabulary.\n\nContent lives in a JSON file in the codebase. To publish an update, someone copies the new bulletin content into the JSON file and merges a PR \u2014 the site rebuilds automatically. Not a CMS, but matches the monthly cadence of the bulletin.\n\n| Step | What it does |\n|---|---|\n| 1a | Move the fixture data into a JSON content file that gets loaded when the site builds. Anyone can edit it via a pull request. |\n| 1b | Recipe names in the digest link to their actual recipe pages in the app (already working in this PR) |\n| 1c | Add a \"new\" dot on the help menu so users know there are unread updates |\n| 1d | Simplify the subscribe button to a feedback/mailto link (no email infrastructure yet) |\n\n**What this gets you:** the page is live with real bulletin content. Customers see the same announcements they'd get via email, but in the app \u2014 searchable, filterable, and always available. No more \"I never got the newsletter.\"\n\n### Phase 2 \u2014 Personalized recipe digest (2\u20133 weeks)\n\nThe recipe digest card in the mockup shows \"your most-used recipes\" with run counts and \"new recipes you might like.\" Phase 1 ships this with placeholder data. Phase 2 makes it real and personalized to each customer's organization.\n\n**Cards you get in Phase 2:**\n- **Weekly Recipe Digest (live)** \u2014 shows the customer's actual top 5 most-run recipes with real usage counts, links to each recipe, and flags for recipes that have been updated since last run. Also surfaces new recipes in the marketplace that the org hasn't installed yet.\n- **1-click install buttons** \u2014 any card that mentions a recipe can offer an \"Install\" button that adds it to the customer's marketplace with one click. The backend APIs for this already exist (Builder and Deploy pages use them today).\n\n| Step | What it does |\n|---|---|\n| 2a | Backend team adds a query that returns \"top N recipes by run count for this org\" (the data already exists in a telemetry table \u2014 just needs a new way to ask for it) |\n| 2b | Connect the digest component to real data instead of stubs |\n| 2c | Compare what's installed vs. what's available in the marketplace to power \"new recipes you might like\" |\n| 2d | Add install buttons to recipe cards using the same install flow that the Deploy page already uses |\n\n**What this gets you:** the digest is fully live and org-personalized. Each customer sees their own usage patterns and gets notified about recipe updates relevant to them. This is the card that replaces Kiel's manual \"heads up, update your recipes\" messages to every customer channel.\n\n### Phase 3 \u2014 Content source automation (3\u20134 weeks)\n\nPhase 1's JSON file works if updates are monthly. If the team wants faster content updates or less engineer involvement, we need to decide how content gets authored. This is the \"do we need a CMS\" question.\n\nOptions ranked by effort:\n\n| Option | Effort | Who it's for |\n|---|---|---|\n| **A. Keep the JSON file** (stay on Phase 1) | Already done | Monthly updates, engineer pastes from bulletin. Good enough if cadence doesn't change. |\n| **B. Auto-sync from the Google Doc** | ~1 week | A script reads the existing bulletin Google Doc and converts it to JSON automatically. Marketing keeps their existing workflow and the page updates without engineer involvement. |\n| **C. Full CMS (Contentful, Sanity, etc.)** | 2\u20134 weeks | Editorial dashboard with drafts, scheduling, preview. Worth it only if content goes weekly with multiple authors. |\n| **D. GitHub Issues as content** | ~1 week | Each post is a GitHub Issue with labels for status/area. Free, reviewable, no new system. Limited formatting. |\n| **E. RSS feed from marketing's tool** | ~3 days | If marketing adopts a tool that publishes a feed (Beehiiv, Substack, etc.), the page just reads from it. Cheapest option but depends on a marketing tooling decision. |\n\n**Recommendation:** Start with **A** (JSON in repo). If that becomes a bottleneck, move to **B** (Google Doc sync) since the Doc already exists. Only consider **C** if content needs to go weekly with multiple authors and preview workflows.\n\n### Phase 4 \u2014 Polish and deeper integrations (ongoing)\n\n**Cards and features you get in Phase 4:**\n- **Auto-generated release cards** \u2014 CLI and OpenRewrite releases automatically create cards from their GitHub release notes. No manual content entry for version bumps.\n- **\"What changed\" modal on first visit** \u2014 the existing welcome modal that appears when you first land in the app would pull its content from the What's New feed instead of being hand-coded each release.\n- **Compact feed widget** \u2014 a small version of the feed embedded on the Home or DevCenter page, showing the 2\u20133 most recent updates without navigating away.\n- **Email subscribe** \u2014 actual email notifications when new posts are published (requires building or adopting a notification service).\n- **Coming \u2192 Available lifecycle** \u2014 when a \"Coming Soon\" feature ships, the card automatically updates to \"Available\" and links back to the original preview announcement, so customers who were tracking it see the payoff.\n", "creation_timestamp": "2026-05-29T14:07:17.000000Z"}]}