Files
rose-ash/docs/masterplan-sprint.md
giles 8269977751
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m21s
Add two-week sprint plan: 90% of the masterplan in 14 days
Ghost killed by day 5, sexp protocol running internally by day 8,
sexpr.js on every page by day 10. Cut Rust client, IPFS mesh, and
browser extension to later. Everything users touch runs on sexp.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:21:13 +00:00

5.7 KiB

Rose Ash: Two-Week Sprint

The 20-week plan, compressed. Cut everything that isn't code running in production.


What Gets Cut

Deferred Why
Rust native client Needs stable protocol first — build later
Client-as-node / IPFS / GPU mesh Vision is solid, build after protocol exists
Browser extension sexpr.js in a <script> tag works today, extension is optimisation
Scalability Tiers 1-3 Tier 0 is enough, scale when traffic demands
Multi-instance federation One instance first, federate second
Sexp routes (defroute) Nice-to-have, Quart decorators work fine

What stays: everything that produces working infrastructure this fortnight.


Week 1: Kill Ghost, Ship Sexp Content

Day 1-2: Ghost Content Migration

  • Write Lexical → sexp converter script
  • Add body_sexp column to Post model (Alembic migration)
  • Run converter against all posts, verify HTML output matches
  • Switch rendering pipeline: post_data() reads body_sexp, renders via sexp evaluator

Day 2-3: Native Editor & Uploads

  • Editor save endpoint writes sexp directly to DB (bypass Ghost Admin API)
  • Native media upload endpoints on blog service (image, audio, files)
  • Native OEmbed lookup endpoint
  • Editor toolbar actions → sexp nodes

Day 3-4: Membership Decoupling

  • Rename ghost_labelslabels, drop ghost_id
  • Rename ghost_tiersmembership_tiers, drop ghost_id
  • Clean User model (drop ghost fields, add membership_tier_id, membership_status)
  • Native subscriptions table (replace ghost_subscriptions)
  • Wire Stripe directly (Checkout + Webhooks on orders service)

Day 4-5: Newsletter + Delete Ghost

  • Native newsletter model + user_newsletters
  • Email sending via SMTP/SES (transactional, not Ghost)
  • Newsletter templates as sexp → email-safe HTML
  • Post → email campaign workflow
  • Delete all Ghost code — ghost/ directory, ghost_db, webhooks, env vars, Docker service
  • Alembic migration: drop all ghost_id columns
  • Rename model files: ghost_content.pycontent.py, ghost_membership_entities.pymembership.py

Parallel (Week 1): New Relations + Cart Split

  • Add new defrelations (post→post, market→product, calendar→entry, page→marketplace)
  • Migrate CalendarEntryPost junction → ContainerRelation
  • Scaffold likes service (port 8009)
  • Move PageConfig to blog
  • Cart becomes thin CRUD + checkout delegation to orders

Week 2: Sexp Protocol + Client Runtime

Day 6-7: Internal Wire Format

  • Define framing: length-prefixed sexp over Unix sockets
  • Python SexpConnection class: connect, send, receive
  • Quart handler: accept sexp requests, return sexp responses
  • fetch_sexp() — unified replacement for fetch_data() + fetch_fragment()

Day 7-8: Internal Mesh on Sexp

  • Blog ↔ relations on sexp protocol
  • Events ↔ relations on sexp protocol
  • Market ↔ relations on sexp protocol
  • All internal calls on native sexp (HTTP fallback for external)
  • Benchmark: latency/throughput vs HTTP+HMAC

Day 8-9: sexpr.js Core

  • Sexp parser in JS (<5KB gzipped)
  • DOM renderer: sexp tree → DOM nodes
  • swap!, batch!, class! mutation primitives
  • request! — fetch sexp from server, apply mutations
  • Component system: defcomp, content-addressed localStorage cache

Day 9-10: sexpr.js Integration

  • Rose-ash serves sexp via Accept: application/sexp content negotiation
  • <script src="sexpr.js"> on every page — progressive enhancement
  • Partial page updates via sexp mutations (no full reload)
  • DevTools: sexp inspector in browser console
  • Content-addressed caching: hash post body, cache in localStorage

Parallel (Week 2): Stability + Pages

  • Sexp page layouts (base, blog post, market product, event calendar)
  • Fragment endpoints return raw sexp (callers render)
  • Unit tests for new protocol library
  • AP federation test: sexp activities between two instances (Docker)
  • Deploy Tier 0 scalability (DB split, PgBouncer, workers)

End State: Day 14

Before After
Ghost CMS running alongside Python stack Ghost deleted, all content native sexp
Lexical JSON in posts Sexp in body_sexp column
Ghost handles newsletters, membership, Stripe Native newsletter, membership, direct Stripe
HTTP+HMAC between services Native sexp protocol between services
HTML fragments (opaque strings) Sexp trees (structured, filterable, cacheable)
Full page reload on every navigation sexpr.js partial updates, content-addressed cache
No client-side sexp sexpr.js running on every page
6 Ghost-related files + Docker service Zero Ghost code

What "90%" Means

The 10% left after two weeks:

  • Rust native client (Track 8) — needs months of Rust engineering
  • Client-as-node / IPFS / GPU mesh — needs the Rust client
  • Browser extension — nice optimisation, not essential when sexpr.js works
  • Multi-instance federation — test with Docker first, real instances later
  • Scalability Tiers 1-3 — premature until traffic demands it
  • Full newsletter template library — basic sending works, fancy templates iterate

Everything a user touches — browsing, buying, posting, subscribing, federating — runs on sexp end to end. The remaining 10% is optimisation and long-term vision.


Daily Rhythm

Morning:  AI generates code for the day's tasks
Midday:   Test, fix, deploy to dev
Evening:  Commit, push, verify on dev, plan tomorrow

No PRs, no code review, no standups. One developer, AI tools, git push.