# Discovery notes — post-review-backlog plan

Single source of truth for project context. Specialists: read this first, do NOT re-grep what is here.
Search further only for what your domain needs that is not covered.

## Tech stack

- Monorepo, pnpm workspaces: `apps/server` (BooChat — Fastify + postgres, native inference, read-only tools),
  `apps/web` (React + Vite SPA), `apps/coder` (BooCoder — host systemd service, write tools + external-agent
  dispatch, port 9502), `apps/booterm` (PTY/tmux). TypeScript strict, NodeNext (`.js` import suffixes) on
  server + coder.
- Tests: vitest (pinned ^3). server `pnpm -C apps/server test`; coder `pnpm -C apps/coder test`
  (`globals:false` — import describe/it/expect). Include glob `src/**/__tests__/**/*.test.ts`. No web test
  harness, no linters. DB-integration tests opt-in via `DATABASE_URL` + `describe.runIf`.
- Deploy: apps/coder → `sudo systemctl restart boocoder`; apps/web|server → `docker compose up --build -d boocode`.
- Postgres 16, DB `boochat`. Two schema files: `apps/server/src/schema.sql` (sessions/chats/messages/
  message_parts) + `apps/coder/src/schema.sql` (agent_sessions, worktrees, pending_changes, available_agents,
  checkpoints, claude_session_entries, tasks extension).

## ADRs / coding standards found

- No `docs/adr/` directory. Architectural decisions live in `boocode_roadmap.md` (Decisions log) +
  per-app `CLAUDE.md` files (auto-loaded when editing that subtree) + `openspec/changes/archived/`.
- Coding standards: `docs/coding-standards/` (canonical), surfaced via `.claude/rules/coding-standards/`
  path-scoped index files. Not loaded automatically; open on demand.
- Cross-cutting conventions in root `CLAUDE.md` "Conventions" section (WS-frame parity, sentinels, JSONB
  via `sql.json`, event dedup discipline, deploy-by-surface).

## Code touch points (per scope-brief item)

- **F1 task-cancel:** `apps/coder/src/services/dispatcher.ts` (private `ac=new AbortController()` at
  ~316/655/991/1248; `inflight=Map<sessionId,Promise>` at :56 — no per-task AbortController registry);
  `apps/coder/src/routes/tasks.ts:110-148` (cancel route — inference.cancel + DB only); `routes/messages.ts:388`
  (session stop); backends honor `ctx.signal`: `pty-dispatch.ts:159` (child.kill), `backends/warm-acp.ts:318`
  (session/cancel), `backends/opencode-server.ts:775` (session.abort), `backends/claude-sdk.ts:209` (interrupt).
  Frontend `apps/web/src/components/panes/CoderPane.tsx:987` handleStop; `api/client.ts:395` cancelTask.
- **F2 parser prune:** `apps/server/src/services/inference/tool-call-parser.ts` (exports extractToolCallBlocks,
  stripToolMarkup, parseXmlToolCall, parseInvokeToolCall, isPlaceholderArgValue, XML_/INVOKE_ consts).
  Live consumers: `stream-phase.ts:263-284` (extractToolCallBlocks, text-delta fallback path), `:285-294`
  (structured tool-call path — authoritative today), `tool-phase.ts:122` + `error-handler.ts:25,106`
  (stripToolMarkup). llama-swap native `--jinja` parsing confirmed ON (external host `:8401`).
- **F3 xml logging:** `tool-call-parser.ts:65` console.debug; one call site in `stream-phase.ts` executeStreamPhase.
- **F4 notify-hook:** agent config paths `~/.claude/settings.json`, `~/.qwen/settings.json`,
  `~/.config/goose/`; existing readers `claude-command-discovery.ts:84`, `qwen-settings.ts`,
  `provider-registry.ts`. Existing normalize helper `apps/coder/src/services/normalize-agent-status.ts`
  (`normalizeAgentEvent`). Existing status publish wired at dispatcher turn boundaries (v2.7.6);
  `index.ts:86` references #10. `permission-waiter.ts:47` has a `PermissionHooks` registry.
- **F5 compaction surfacing:** `apps/coder/src/services/backends/opencode-server.ts` SSE arm handling
  (~215-311 region); WS frame parity → server `ws-frames.ts` + web `apps/web/src/api/types.ts` (`WsFrame`).
- **F6 resilience:** `apps/server/src/services/inference/stream-phase.ts:261` (`for await ... result.fullStream`),
  abort check at :333, usage at :343. Frontend 60s `discard_stale` watchdog is the only stall guard today.
- **F7 session-history MCP tool:** `apps/coder/src/services/mcp-server.ts` (existing BooCoder MCP tools);
  read path `messages_with_parts` view.
- **F8 diff-line UX:** diff UI component NOT located by `git ls-files apps/web | grep -i diff` (returned
  empty) — UX specialist must locate the actual diff/changes panel component (BOOCODER.md calls it
  "DiffPanel"; may be named differently or nested). Routes through dispatcher + AgentComposerBar.
- **F9 retire :9502:** `apps/coder/web/` package + static serve in `apps/coder/src/index.ts` + coder build
  scripts/Dockerfile. KEEP WS + REST routes.

## Recent activity / precedent

- HEAD `e5ce01a` (v2.7.11). v2.7.x line (relicense, write-edit-robustness, sampling-streamjson-tokens,
  mistake-tracker-ledger, claude-sdk-sessionstore, agent-status-normalize, UI batches) all shipped 2026-06-01.
- Pure-helper + TDD precedent for extraction: `backends/turn-guard.ts`, `backends/lifecycle-decisions.ts`,
  `mistake-tracker.ts` (pure module + unit test, then wire). F1/F2/F6 should follow it.
- Parallel-disjoint-file agent precedent: v2.7.0/v2.7.1/v2.7.3 each built by 3 parallel agents over disjoint
  files — relevant to decomposition/sequencing.

## Enumerated gaps (searched, not found)

- No `feature-specification.md` — `scope-brief.md` is the ground-truth stand-in.
- No `docs/adr/`.
- Diff UI component filename not found via naive grep (F8) — needs UX specialist location.
- llama-swap config is NOT in-repo (external host `:8401`); native-jinja state confirmed by live probe only.
- F8 (diff-line UX) and F4 (notify-hook) are the two items most likely to need their own plan-a-feature; they
  have no behavioral spec beyond the review-doc pattern description.
