Owly Post
About Owly PostHow it was madePhase reports

Phase 4: operational hardening and launch

What phase 4 delivered, with acceptance evidence, deviations and open items

Status: ✅ code and docs complete; the launch itself is a checklist of account-level actions only Esmee can do. Every automated gate is green.

What was built

  • 30-day deletion job (SPEC decision 13): expired_at (migration 0005) set by the webhook's expired-transition; daily scheduled sweep (ops-daily) wipes all content of tenants expired >30 days via the adapter layer, keeping the account skeleton and billing records (P4-1). Boundary-tested at 29/31 days, idempotent.
  • Monitoring & alerting (monitor, hourly): failed job runs (24h), jobs stuck >2h, eligible tenants with sources but no ingest in 24h, LLM budget ≥80% (warn) / 100% (error); alerts by email to ALERT_EMAIL via Resend. /api/health for external uptime checks. Stripe-webhook health is monitored on Stripe's side (delivery dashboard + automatic retries against our idempotent handlers) — runbook documents the drill.
  • An operational runbook: deploy/migrate order, core-upgrade flow, price changes (data flip), comping, kill switch, incident drills (digests stopped, webhook outage, runaway spend), backup/restore, key rotation.
  • A launch checklist: the complete go-live sequence — repos, hosted database + auth mail + backup drill, hosting, mail-domain authentication, Stripe live mode (Tax on, live Price with tax_behavior: inclusive, webhook, portal), legal review, production smoke test, aftercare.

Acceptance vs SPEC §12 Phase 4

CriterionState
DNS + Resend domain verificationChecklist §4 (needs Esmee's DNS)
Monitoring & alerting✅ built + scheduled; gates green
Backups verifiedChecklist §2 (restore drill on the Frankfurt project)
30-day deletion job✅ built + boundary-tested
Runbook
Launch checklist (Stripe live, real price)✅ written; execution is the go-live
"Production live at app.owlypost.com"⏳ = working through the launch checklist

Definition of Done (SPEC §13) scorecard

  • Stranger can sign up, pay (Stripe, iDEAL/card) and get access — proven end-to-end in sandbox
  • Multiple tenants, zero leakage, proven by automated test (9/9, in CI)
  • Paying customer receives a polished digest per category on schedule — pipeline + dispatcher + UI done; email delivery pending domain verification
  • Payment stops → digests stop — tested
  • LLM cost caps enforced (manual digests + monthly budget + kill switch) — boundary-tested
  • One-sentence value over the bare core — live on /billing/start & terms ("runs for you: no Docker, no maintenance, first digest in minutes")
  • Open source core runs unchanged as self-host — Phase 0 acceptance + Esmee's live instance
  • One real paying customer runs stably — post-launch
  • Logging/monitoring shows digests run and payments arrive — monitor + job_runs + Stripe dashboard (runbook)

Deviations

DECISIONS_LOG P4-1…P4-4.

Open items (all on the launch checklist)

Push owlypost-cloud to GitHub (private) + install Renovate · hosted database setup · hosting · mail domain · Stripe live · legal review · production smoke test. Plus carried over: runDigestNow deep-link, feedback un-rate (would need a core change — Esmee's call as maintainer), first-digest timing.

Addendum 2026-07-09 — untouched-core migration (P4-6)

After this report was written, the core-consumption architecture was migrated to Esmee's final model: the open source repo stays byte-for-byte untouched (flat single-user app, main = 1.0.0); the cloud pins it as the vendor/owlypost git submodule and consumes it through the cloud-owned core-bridge/ package, with per-tenant configuration injected via env per run (runWithTenantEnv) and metering reworked to per-run v2. All gates re-proven after the migration (unit 25, db 10, leakage 10/10, lint+gate, typecheck, build; submodule bump demo typechecks both ways). Details and accepted trade-offs: DECISIONS_LOG P4-6. The leakage count changed from 9 to 10 tests (a metering-isolation test was added).

On this page