> ## Documentation Index
> Fetch the complete documentation index at: https://docs.highailabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cannabis Coach — Phase 1 Spike

> What the parked Phase 1 implementation actually built, why it stopped, and the checklist for resuming it. Engineering record for the feat/cannabis-coach-phase1 branch.

<Note>
  **Status:** Parked — code preserved on a branch, not merged
  **Branch:** `feat/cannabis-coach-phase1` (branched 2026-04-08)
  **PR:** [#1246](https://github.com/jmegan/tiwih/pull/1246) — closed 2026-08-03, reopenable
  **Blocker:** the MCP-vs-alternatives data-bridge decision is still unresolved
</Note>

<Warning>
  This page is an **engineering record of a parked spike**, not a description of shipped behavior. None of the endpoints below exist in staging or production. For what Coach is meant to *be* — the product design, user value, and rollout gates — see [Cannabis Coach](/planning/features/cannabis-coach).
</Warning>

## Why this page exists

Phase 1 produced roughly 2,654 lines across 16 files, then stopped on an architecture question rather than a technical failure. That is the kind of work that quietly evaporates: the branch drifts, the context leaves with whoever wrote it, and the next person re-derives it from scratch.

This page records what was built and what it would take to resume, so the design survives independently of the branch.

## Why it was parked

The spike bridges user data into an Anthropic Managed Agent by standing up an MCP server. That was the open question, and it never got answered:

* **We do not have an MCP yet.** The spike *builds* one, but adopting MCP as the data-bridge for user context was never actually decided — the spike was meant to inform that decision, not presuppose it.
* Merging carried disproportionate risk for unreviewed code (see [Merge hazards](#merge-hazards)).
* After \~4 months of drift it conflicts with `main` on 5 files.

Parking was the correct call. It is still the correct call until the data-bridge question is settled.

## What was built

<CardGroup cols={2}>
  <Card title="Coach API routes" icon="route">
    `apps/api/src/routes/coach/index.ts` — 611 lines
  </Card>

  <Card title="Coach-context MCP server" icon="plug">
    `apps/api/src/mcp/coach-context/` — 592 lines
  </Card>

  <Card title="Managed Agents client" icon="robot">
    `apps/api/src/services/coach/` — 677 lines
  </Card>

  <Card title="Convex session + context state" icon="database">
    `apps/mobile/convex/` — 538 lines
  </Card>
</CardGroup>

### API surface

Four routes, mounted at `/coach`:

| Route                   | Purpose                         |
| ----------------------- | ------------------------------- |
| `POST /coach/start`     | Open a new coach session        |
| `POST /coach/message`   | Send a turn                     |
| `POST /coach/resume`    | Reattach to an existing session |
| `POST /coach/workspace` | Inspect the agent workspace     |

### MCP server

A Streamable-HTTP MCP server named `tiwih-coach-context`, mounted at `/mcp/coach-context`. The Managed Agent config (`apps/api/src/services/coach/coach-agent.json`) points at this URL. It exposes three read-only context tools:

* `get_user_context`
* `get_shopping_context`
* `get_strain_details`

<Warning>
  One handler in the spike is explicitly marked **"SPIKE ONLY. Debug endpoint — remove before GA."** Anything resuming this work must audit for that marker before exposing the server.
</Warning>

### Convex tables

Two tables were added to `apps/mobile/convex/schema.ts`:

**`coachSessions`** — one row per conversation, tracking cost and lifecycle:
`clerkUserId`, `sessionId` (the Anthropic `session_id`), `createdAt`, `lastActiveAt`, `status`, `turnCount`, `totalCostCents`, `workspaceSizeBytes`

**`shoppingContext`** — what the user is looking at while shopping:
`clerkUserId`, `dispensaryDomain` (e.g. `sunnyside.shop`), `currentUrl`, `pageTitle`, `cartContents[]`, `viewedProducts[]`

The cost fields are worth noting: session cost was designed in from the start rather than bolted on, which matters for a Pro-tier feature billed against a metered agent API.

## Merge hazards

These are the specific reasons this could not simply be merged, and they will still apply whenever it is resumed.

<Steps>
  <Step title="The API auto-deploys; Convex does not">
    Merging to `main` triggers Vercel's GitHub integration, which deploys the API to production automatically. The Convex schema deploys **manually** via `npx convex deploy --prod`. Merge alone therefore puts coach routes in production referencing `coachSessions` and `shoppingContext` tables that do not exist yet.
  </Step>

  <Step title="It mounts a public MCP server">
    `/mcp/coach-context` becomes publicly reachable on the production API the moment the code deploys. An MCP server that vends user context is not something to expose incidentally.
  </Step>

  <Step title="It conflicts with main on 5 files">
    `apps/api/package.json`, `apps/api/src/app.ts`, `apps/mobile/convex/schema.ts`, `apps/mobile/convex/_generated/api.d.ts`, `pnpm-lock.yaml`.
  </Step>
</Steps>

## Resume checklist

1. **Settle the data-bridge decision first.** MCP is one option; the spike exists to inform that choice, not to foreclose it. Everything below is wasted effort if the answer is "not MCP."
2. Rebase `feat/cannabis-coach-phase1` onto current `main` and resolve the 5 conflicts.
3. Gate `/coach` routes and the `/mcp/coach-context` mount behind an env flag that is **off** in production, so the code can land without exposing anything.
4. Deploy the Convex schema (`npx convex deploy --prod`) *before* enabling the flag.
5. Audit for the `SPIKE ONLY` debug handler and remove it.
6. Confirm the Managed Agents API surface still matches `client.ts` — this was written against a beta API in April 2026 and has had months to move.
7. Work through the Phase 1–4 gates in [Cannabis Coach](/planning/features/cannabis-coach#local-testing-guide).

## Related

* [Cannabis Coach](/planning/features/cannabis-coach) — product design, user value, rollout gates
* `apps/api/src/services/coach/RUNBOOK.md` (on the branch) — operational runbook written alongside the spike
