# SPEC — WAVE 1: WIRE THE WORKING SURFACES + /marketplace HONESTY (shipped) 2026-07-31. Wiring + one copy pass. No grade, ledger, model, or scoring change. ## REVIEW ZERO — each surface proven BEFORE wiring - **0.1 `/intelligence` vs `/system` — NOT duplicates; nothing to resolve away.** `System.dc.html` is a MULTI-surface artboard (it contains TERMINAL, INTELLIGENCE and WIRE sections), not the design for a distinct `/system` route. Its INTELLIGENCE section is **already realised** as the live `app/intelligence/page.tsx`. **No `/system` page exists and none should be built as a second copy** — the prod 404 is correct. Only `/intelligence` was wired. ✅ - **0.2 `/intelligence` renders live + gates correctly.** Real feed (`/api/intelligence/feed`), 160 lines, zero placeholders. **Entitlement is enforced SERVER-side, not by blur**: the proxy requires auth and limits by tier — **desk 50 signals / non-desk 8** — and returns `401 Not signed in` to an anonymous caller (**verified live in prod**). So making it nav-reachable leaks nothing. ✅ - **0.3 `/slip` functions END TO END on a real slip.** Parsed the real DraftKings fixture: **3/3 legs, `needs_review: false`**, leg 1 = `Aaron Judge · total_bases · over 1.5 @ -115`. ✅ **Honest limit recorded:** the parsers are layout-rigid. A slip in an unsupported layout yields **zero legs rather than wrong ones** — correct per the NEVER-GUESS contract, but it means real-world OCR hit-rate across layouts is **CANNOT DETERMINE** until real user slips arrive. - **0.4 `/parlay` direct route hits the working surface.** `app/parlay/page.tsx` is the real correlation builder on the **same `ParlayContext`** the drawer uses — not a separate unbuilt page. ✅ - **0.5 `/marketplace`** advertises four unbuilt things (API access · custom alerts · "The Edge" playbook · merch capsule). **No performance/edge/profit claim was present** (the worse category — clean). The capture was already REAL: `fetch('/api/waitlist')` → `src/routes/waitlist.js` upserts to a `waitlist` table. The gap was tense: bodies read as present-tense descriptions. ## PHASE 1 — WIRED (all three passed) `Nav.tsx MORE`: **Intelligence**, **Slip Reader**, **Marketplace** added; **Parlay Lab re-pointed from `#parlay` (drawer-only) to `/parlay`** (the real page). The drawer is unaffected — `ParlayPanel` stays mounted in the layout with its floating badge, its natural in-context use from a prop row. **Gating change (one line, principled):** `/intelligence` added to `GATED_ROUTES`. Its feed 401s signed-out, so an ungated nav link would land visitors on a permanently empty page. `/slip` was already gated (personal surface). **`/parlay` deliberately stays OPEN** — it is the free parlay funnel and gating it would be a monetization regression (same rule as dashboard/scan). ## PHASE 2 — /marketplace HONESTY PASS Every item body now opens **"Not built yet."** / "Not written yet." / "Not produced yet." followed by what is *planned*. The subhead is explicit: *"None of the below is built yet… joining a list records your interest, nothing more. It is not a purchase, not a pre-order, and not a promise of a ship date."* The playbook item carries **"No profit claim, no promised return."** The capture stays REAL (no fake button). Unit-locked: every body must contain a not-yet marker, and the page must carry no guaranteed/win-rate/ROI/beat-the-book language. ## PHASE 3 — VERIFY Grade, ledger, model, scoring **untouched** (diff empty across `intelligence/`, `ledgerService`, `outcomeService`, `gradeSlateService`). **315 suites / 3,920 tests green** (12 new), **web build exit 0**. **Chrome audit manifest — Wave 1 additions:** | surface | state | check | |---|---|---| | `/intelligence` | **signed-out** → should redirect to `/login` (now gated) | no empty-feed page | | `/intelligence` | **free** vs **ENTITLED (Desk)** | free sees 8 signals + lock overlay; **Desk sees 50** — *entitled path needs Kev* | | `/slip` | **free (signed-in)** | upload/paste → editable legs; unsupported layout → empty, not wrong | | `/parlay` | **logged-out** | direct nav entry loads the full lab; free 2-leg cap + payout blur | | `/marketplace` | logged-out | "Not built yet" on every item; Join waitlist records and confirms | ## TAGS VERIFIED: 0.1–0.5, all wiring, gating, copy. **CANNOT DETERMINE: real-world slip OCR hit-rate across book layouts** (no user slips yet). BLOCKED: none. ## POST-DEPLOY FINGERPRINT (commit `ff7f5d8`) **Deploy CONFIRMED landed** — the new `/marketplace` copy is live in prod (`"None of the below is built yet"`, `"Not built yet"`, `"not a pre-order"` all served). All four routes 200: `/intelligence`, `/slip`, `/parlay`, `/marketplace`. `/api/intelligence/feed` **still returns `{"error":"Not signed in."}`** to an anonymous caller — gating intact after the change. **⚠️ The nav ENTRIES could not be verified by curl, and I am not claiming they were.** The MORE dropdown's labels are not present in any JS chunk referenced by the initial `/dashboard` HTML. **Control test proves this is a probe limitation, not a failure:** the PRE-EXISTING entries `"Parlay Lab"` and `"The Report"` — live before this change — are **equally absent** from the same 18 sampled chunks, while `"Explore"` (also a main-nav item) is present. The dropdown is client-rendered from a lazily-fetched chunk. **→ Added to the Chrome audit manifest:** confirm the MORE dropdown actually shows **Intelligence · Slip Reader · Marketplace · Parlay Lab→/parlay**, and that a signed-out click on Intelligence lands on `/login` (the new gate) rather than an empty feed. Checkable logged-out; no entitled session needed.