Run 017 journal. architect

Run: 017 · Date: 2026-05-06 · Phase 1 author · Mission: page-3 PDF interactive demo

Phase 1 Draft. Recommendation

1. Where the demo lives Recommendation: a new public route at chapter.guide/try, served from src/app/try/page.tsx in the existing Next.js app. Not a subdomain, not apps/deals. Reasoning:

chapter.guide is already on Vercel and SSL-terminated. A new route ships in one deploy. A subdomain (try.chapter.guide) requires DNS, a separate Vercel project, separate env vars, separate deploy pipeline. agent currency cost to system-tuner and connectors, zero brand benefit. QR code path-length is irrelevant on a phone scanner. The "wow" lives in the page, not the URL. chapter.guide/try is short enough to type in a meeting. apps/deals is a Vite app. Wrong tool. no SSR, no API routes, would need a separate /api host. Defeats the point of having Next.js at all. Brand consolidation. Reader sees the same domain on the PDF, the QR, and the result page. One trust transaction, not three.

2. Architecture sketch. concrete file layout

LayerFileRole Public form (SSR)src/app/try/page.tsxServer component. Renders the toggle (FIND TARGETS / FIND ACQUIRERS), geo input, EBITDA slider, vertical multiselect. Hydrated client component for interactivity. Form clientsrc/app/try/DemoForm.tsx"use client". Validates inputs, posts to API route, streams progress events, renders result HTML. Submit endpointsrc/app/api/try/route.tsPOST handler. Validates payload, hashes (mode, geo, ebitda, vertical) into a cache key, checks pre-computed cache, returns either cached shortlist or kicks off live job + returns job id. Stream endpointsrc/app/api/try/stream/[jobId]/route.tsSSE/edge stream. Emits progress (queued / discovering / scoring / done) and final HTML payload. Cache storeVercel KV (Upstash) — key prefix try:demo:v1:Maps cache key → pre-rendered shortlist HTML. TTL 30 days for demo-mode keys, 24h for live keys. Live workerengine/buyside-hunt-worker.py (existing skill wrapped as cron-triggered worker)Reads jobs from a Supabase try_jobs table, runs the buyside-hunt pipeline, writes results back. Posts done event to a webhook the stream endpoint subscribes to. Result HTML rendererReuse skills/buyside-hunt/shortlist.html templateExisting template. already styled. Strip header to fit embedded view. Rate-limit middlewaresrc/middleware.ts (or src/app/api/try/_lib/rateLimit.ts)Per-IP and per-fingerprint cap. Backed by Vercel KV. QR + landing copypublic/try/qr.svg + content in page.tsxStatic QR encodes https://chapter.guide/try?src=pdf-p3.

3. Speed budget. solved with cached demo mode + progressive reveal The reader gets a result in <3 seconds, not 60. We do not run buyside-hunt live for the demo. We pre-compute it. Reasoning: per the exa-mastery skill, an Exa Webset takes 5-15 minutes to materialize. Streaming progress for 10 minutes from a PDF QR scan is a churn machine. The reader will close the tab in 30 seconds. Solve the right problem. Three-tier strategy:

Tier 1. Pre-cached canonical demos (covers ~95% of QR scans): we run buyside-hunt once for the 12 most-likely combinations the night before each PDF distribution batch. Examples: "FIND TARGETS · Texas · $2 - 5M EBITDA · HVAC", "FIND ACQUIRERS · Northeast · $5 - 10M · Media". Cache key = SHA1(mode|geo-bucket|ebitda-band|vertical). On submit, the form snaps user-entered geo to the nearest pre-cached bucket. Result returns from KV in <200ms. Reader sees 8-12 real, defensible companies. This IS the wow. Tier 2. Synthetic instant result for off-cache combinations: if the user picks a combination we haven't pre-cached, we return a curated 5-row "preview" pulled from the buyside-hunt library's existing shortlists (e.g., the Capstone, Design Precast, Ches Booker runs already on disk) labeled "live preview. full hunt available on request." Still <3s. Captures the email. Tier 3. Live mode (opt-in only, behind email gate): if the user clicks "run a real hunt for my criteria" we collect email + phone, queue the job, and email the result in 15 minutes. This is the actual lead-gen flow and is not on the critical-second path.

Implementation: a scripts/precompute_demo_cache.ts task that the conductor runs against the buyside-hunt skill ahead of each PDF send. Output written to Vercel KV via the Vercel API.

4. Cost model + abuse prevention Per skills/exa-mastery, an Exa Webset run for buyside-hunt is in the ballpark of $5–$15 depending on vertical breadth and enrichment depth. With Tier 1 cache, the marginal cost per QR scan is essentially zero (KV read = ~$0.0001). Costs are concentrated in the pre-compute batch:

Pre-compute: 12 buckets × ~$10 = ~$120 per refresh. Refresh quarterly for the live PDF cohort = $480/yr. Negligible. Tier 3 (real hunts): $10/run × estimated 5% of submitters who request live = $0.50 amortized per QR scan. Acceptable as lead-gen CAC. Abuse on the form itself: the dangerous case is someone scripting Tier 3 to burn Exa credits.

Abuse prevention (defense in depth, all cheap):

Per-IP rate limit: 5 form submits / hour, 20 / day. Vercel KV-backed, 10-line middleware. Per-fingerprint cap: client-side fingerprint (browser + screen + tz) hashed and rate-limited identically. Backstops VPN rotation by amateurs. hCaptcha or Cloudflare Turnstile on the Tier 3 path only. Tier 1/2 stays frictionless to preserve the wow. Turnstile is free. Tier 3 requires email + phone with a magic-link verify before the job queues. No anon Exa spend, period. Hard daily Exa budget cap in engine/buyside-hunt-worker.py — circuit-breaker at $50/day. If hit, Tier 3 falls back to "we'll get back to you within 24h" and pages Ewing. Honeypot field on the form + 1.5s minimum-fill-time check. Kills 80% of bot traffic for free.

5. Build effort + missing infra

PhaseHoursWhat ships MVP (Tier 1 + Tier 2 only)10-14hPublic route, form, cache lookup, pre-compute script for 12 buckets, styled result reuse of shortlist.html, basic rate limit, QR generation. Polish6-8hTier 3 live-mode path, email/phone verify, Turnstile, KV-backed analytics, A/B headline test, mobile QR-scan optimizations, OG-card for share-back. Total to "ready for the PDF"16-22hOne focused day for MVP, half a day for polish.

Missing infra dependencies (flag to system-tuner / connectors):

Vercel KV / Upstash binding on chapter.guide project — verify it exists; if not, provision via vercel:marketplace. ~10 minutes. Supabase try_jobs table — new table needed for Tier 3 queue. Schema: id, mode, criteria_jsonb, email, phone, status, created_at, completed_at, result_url. ~15 minutes. buyside-hunt non-interactive entrypoint — confirm the skill can run headless from a Python worker (currently invoked via Claude). May need a thin engine/buyside_hunt_runner.py that takes a JSON config and emits results.json without needing a Claude session. This is the only real unknown. If the skill is Claude-only, we either (a) add a deterministic Python wrapper, or (b) call the Claude Agent SDK from the worker. adds 4-6h. Webhook from worker → stream endpoint — trivial, but needs a shared secret in connectors. Turnstile site key — free signup, 5 min.

6. Failure mode under 5,000 hits/hour LinkedIn surge What breaks first, in order:

Nothing, if Tier 1 is doing its job. Vercel edge + KV trivially handles 5k/hr (1.4 req/sec) — that's not a surge, that's a warm-up. Cache hits return in <100ms globally. Tier 3 queue saturates the Exa budget circuit-breaker within minutes if even 2% of users opt in. 5000 × 0.02 = 100 live requests × $10 = $1000. Mitigation: the $50/day cap auto-engages, late submitters get queued with "result tomorrow" — no outage, just delay. Acceptable. Supabase try_jobs insert contention at sustained >50 req/sec. Mitigation: insert is fire-and-forget from the API route, batched via a Vercel queue or just direct Supabase pooled connection. Not a real risk at 5k/hr. Turnstile false-positive cliff — Cloudflare occasionally flags legit traffic during virality bursts. Mitigation: on Turnstile fail, fall back to honeypot+timing check rather than hard-block. Vercel function concurrency limit on the stream endpoint — Hobby tier caps at 100 concurrent. If we're on Pro that's 1000. Mitigation: keep streams short (Tier 1 doesn't need streaming at all, it's a single fast response), reserve streaming for Tier 3 only. The actual catastrophic scenario: someone posts the link on Hacker News and 50k people hit it. Per-IP rate limit holds the line. Real risk is Vercel bandwidth on the result HTML. fix by serving result HTML as a static fragment from the KV CDN edge, not re-rendered per request.

Single best pre-flight defense: run a synthetic load test (k6 or Vercel's built-in) at 100 req/sec for 5 minutes against a staging deploy before the PDF goes out. Two hours of work, eliminates 90% of post-launch panics.

S1. Finding

Build the demo as chapter.guide/try in the existing Next.js app, not as a subdomain or in apps/deals. The reader's "wow in <3 seconds" requirement is incompatible with running buyside-hunt live (5-15 min Exa Webset latency), so the architecture is a three-tier cache: Tier 1 pre-computed canonical shortlists for the 12 most-likely (mode, geo, EBITDA, vertical) buckets, Tier 2 a curated synthetic preview for off-cache inputs, Tier 3 an opt-in live hunt behind an email gate that delivers async. MVP ships in 10-14 hours, with Vercel KV for cache, Supabase for the Tier 3 job queue, per-IP rate-limit middleware, and a $50/day hard Exa budget cap as the financial circuit breaker.

S2. Blind spot

I could not verify whether the buyside-hunt skill has a non-Claude headless entrypoint. Its SKILL.md description in the system manifest implies it runs inside a Claude session today. If the skill is Claude-session-only, the Tier 3 worker either needs a Python wrapper around the deterministic stages (Exa discovery, hardfail gates, scoring rubric, dedup) or needs to invoke the Claude Agent SDK from a Python cron. both viable, both adding 4-6 hours I have not budgeted in the MVP estimate. I also did not verify Vercel KV is already provisioned on the chapter.guide Vercel project; if not, that's another connectors task. Finally, I assumed the Exa cost-per-Webset figure from exa-mastery without re-reading the v2026-04-30 measured numbers. actual cost could be 2x higher for broad verticals, which would change the $50/day cap calibration but not the architecture.

S3. Pattern

Novel run, no prior architectural match in the journals I have access to. The closest prior pattern is the general Next Chapter habit (visible in run #002 and the consolidation commit log) of trying to build new product surfaces as separate apps/repos before realizing chapter.guide should host them. this run is preempting that mistake by recommending the Next.js route from the start. The three-tier cache pattern (pre-computed common cases + synthetic fallback + opt-in expensive path) is the same shape data-architect proposed in earlier runs for the deal-rooms preview surface, so there is a reusable template forming. If this lands cleanly it should be promoted to a system-tuner pattern doc.

S6. What changed about me

Going forward, when a marketing surface needs sub-5-second perceived latency on top of an inherently slow pipeline, I will default to a pre-compute + cache + opt-in-live three-tier shape rather than designing the streaming/progress UI first. because the streaming path is almost always the wrong answer when the reader's attention budget is shorter than the pipeline's wall-clock floor.

Generated from 017__architect.md — do not edit this HTML directly.