# Use the BAH Research-Run Harness

**Activation (one line):** When a task is a known use case (payments, auth, MCP, booking, …), use the research-run harness FIRST — dispatch before you crawl.

## Connect (pick one)

**A. MCP stdio (local):**
```json
{ "mcpServers": { "bah-research-run": { "command": "node", "args": ["<path>/bah-research-run/bin/research-mcp.mjs"] } } }
```
**B. BAH /mcp (hosted, LIVE since 2026-10-19):** three tools are exposed on `https://boundedagentharness.com/mcp` alongside the workspace tools, PUBLIC — no token needed: `research_dispatch`, `research_get_pack`, `research_get_files_first`. Hosted `research_dispatch` is request-only (no projectDir). The other two tools — `research_find_in_project`, `research_next_probe` — are LOCAL only (stdio/CLI, options A/C): the server cannot see your project files and there is no hosted run store.
**C. CLI:** `node bin/researchHeadless.mjs <workspace> <run_name> -import "<request>" [-usecase <id>]`

## The 5 tools
1. `research_dispatch {request, projectDir?}` — ranked use-case + variant + confidence, or labelled crawl fallback. Always first.
2. `research_get_pack {usecaseId, section?}` — pack fragment, or one section at a time.
3. `research_find_in_project {projectDir, usecaseId?}` — is this flow already implemented here, and where?
4. `research_get_files_first {usecaseId}` — ranked files_first + canonical sources for the variant.
5. `research_next_probe {runId, projectDir?}` — next step for an existing run, from the run store.

## RULES (enforceable — full text in RULES.md, ids RR-01…)
- **RR-01 Dispatch before crawl.** No open web research until `research_dispatch` has run. A labelled crawl fallback is the only exception, and it stays labelled.
- **RR-02 files_first only on first pass.** Retrieve only the pack's `files_first` from primary sources first; widen only if they don't answer.
- **RR-03 Fall-through order: exact → signature → fuzzy → crawl.** Never skip a cheaper index.
- **RR-04 Evidence ledger mandatory.** Every factual claim carries `{sourceUrl, fileOrAnchor, packVersion, classification}`. No evidence = no claim.
- **RR-05 Budgets.** Max 5 sources, max 3 canonical files per run on the hot path; stop when the pack answers the question.
- **RR-06 Unknown = labelled crawl fallback, never silent.** Say it is a fallback in the result.
- **RR-07 Write findings back.** Findings go to the run store (`.research/projects/<run>/`); a follow-up is a lookup, not a re-crawl.
- **RR-08 Never mix variants/eras.** MCP v1 vs v2, Auth.js v4 vs v5, Cal hosted vs Cal.diy are different packs/eras — pick the dispatched one and stay in it.
- **RR-09 Version pins come from packs, never invented.** If a pin isn't in the pack or the project's lockfile, say so.
- **RR-10 Env names are data, env values are secrets.** Sniffers read names only; never ask for, log, or store values.

## Dispatch decision table
| Request signals | Project signals | Pack |
|---|---|---|
| stripe / checkout / payment | dep `stripe` | `stripe:checkout:hosted` (embedded / payment-links variants on wording) |
| google oauth / sign in with google | dep `next-auth` + `next` | `google:oauth-signin:authjs-nextauth-v5` |
| google oauth | dep `@supabase/supabase-js` | `google:oauth-signin:supabase-auth` |
| google oauth | dep `googleapis` / `google-auth-library` | `google:oauth-signin:direct-googleapis` |
| mcp / model context protocol | dep `@modelcontextprotocol/server` | `mcp:server:streamable-http-typescript-v2` |
| mcp | dep `fastmcp` / python | `mcp:server:fastmcp-python` |
| mcp, stateless/serverless wording | single function, PAT | `mcp:server:stateless-jsonrpc-post-pat` |
| booking / appointment / availability | dep `@calcom/atoms` | `booking:service:cal-platform` |
| booking | dep `googleapis` + calendar | `booking:service:google-calendar-engine` |
| booking, low volume / owner confirms | no calendar deps | `booking:service:request-confirm-sidecar` |
| none of the above | — | labelled crawl fallback (RR-06) |
