# D1 CLOSE — REVIEW ZERO FINDINGS (report; mount NOT performed) 2026-07-31. Nothing changed: no mount, no row edit, no data threading. `git diff` = docs only. ## Why this stopped at Review Zero The order scopes this as "mount only — NO row refactor." Reading the real components shows the mount is **not** a mount, and one finding needs a decision before anything is surfaced. ### 0.1/0.2 — THE RATIONALE DOES NOT REACH THE ROW (VERIFIED) `StripProp` (`components/vyndr/StatStrip.tsx`) carries stat · line · side · grade · gradedAt · delta · awaiting · outcome · movement · revisedFrom · book · bestBook · dead · history — **no `reasoning`, no `kill_conditions_triggered`.** `buildPlayerStripsFromProps` never threads them either. So mounting the hover requires **adding a field to the strip contract and threading it through the slate adapter** — additive, but a data-path change, not a mount. ### 0.3 — THE PREMISE INVERTS: THE RATIONALE IS **ALREADY PUBLIC** (VERIFIED LIVE) The order asks me to ensure "a free-tier user's hover shows nothing, not the paid reasoning." Measured against prod, anonymously: GET https://api.vyndr.app/api/snapshot/wnba (no auth) reasoning.summary present : True reasoning.locked : None kill_conditions_triggered : 1 **`stripModelPrice` strips `model_odds`/`p_win`/`ev_pct`/`value`/`takeable` — it does NOT strip `reasoning` or `kill_conditions_triggered`.** So the full model rationale is already shipped to every anonymous browser on the main board endpoint. **Two consequences, and they pull in opposite directions:** 1. Mounting the hover **leaks nothing new** — it renders bytes the browser already has. 2. But it **surfaces** something currently shipped-but-unrendered, and the same content **IS** tier-gated on the scan path (`utils/tierGating.js` redacts `reasoning` for free tier). So the product currently gates the reasoning in one place and serves it openly in another. **This is a monetization/consistency decision, not an implementation detail** — which is why it is reported rather than resolved unilaterally. Three coherent options: - **(a)** Gate `reasoning` on `/api/snapshot` the way scan does, then mount the hover for entitled viewers only. Consistent, but removes content free users already receive. - **(b)** Accept it as intentionally free (board reasoning is the funnel) and mount for everyone. Consistent the other way; makes the scan-path gating the odd one out. - **(c)** Leave the payload alone and don't surface it. Status quo. ### THE THIRD BLOCKER — ROW-GRAMMAR IS LAW AND LOCKS StatStrip's SOURCE ORDER (VERIFIED) `tests/unit/rowGrammar.test.js` asserts StatStrip's element order by **`src.indexOf(...)` on the component source** (slots: identity → viability → stat+line → market context → model output → outcome → actions → provenance). Adding a rationale affordance or a team chip **moves those offsets**, so `specs/ROW-GRAMMAR.md` and the test must be amended **in the same commit** — per CLAUDE.md, that spec is LAW. That makes this a spec-amending change, not an additive mount, and the amendment needs its own slot decision (where does a rationale affordance sit in the grammar? where does a team chip sit relative to identity?). ## WHAT IS SAFELY MOUNTABLE WITHOUT ANY OF THE ABOVE - **`reveal.js`** — wraps the row LIST, touches no StatStrip internals, no new data, no grammar slot. This one is genuinely a mount. - **`teamChips.js`** — needs a grammar slot (it sits before the team abbr, inside identity), so it is small but spec-touching. - **`rowRationale.js`** — needs the data threading AND the gating decision AND a grammar slot. ## RECOMMENDATION Split D1-close into: **(1)** mount `reveal` now (no blockers), **(2)** a ROW-GRAMMAR amendment order that adds the team-chip slot + the rationale-affordance slot to the spec and test, and **(3)** the rationale mount, after the gating decision above is made. ## TAGS VERIFIED: strip contract lacks reasoning; anon snapshot serves reasoning + kills; ROW-GRAMMAR locks source order. CANNOT DETERMINE: none. **BLOCKED: the rationale mount — on a gating decision (a/b/c) and a ROW-GRAMMAR amendment.**