# CAI — Opportunity Engine & Suggestion Inbox

> Status: **concept** (brainstorm captured 2026-06-26). No code yet.
> This is the shared design direction, not a spec. We build against it, we don't treat it as locked.

## The core idea

CAI today detects **drift**: factual mismatch between the scaffold and the code
(deterministic, backward-looking, triggered by `cai check`). The next layer is
**opportunity detection**: CAI observes how you and the agent actually work,
spots a recurring pattern, and proposes a *condensation* — a skill, a pattern, a
context edit, a compaction — that saves tokens or time. You decide with
**Apply / Snooze**.

Both engines feed **one GUI inbox** (see `docs/gui-mockup.html`): a list of
cards with severity/kind chips and Apply / Snooze / "show diff" / "show in
graph" actions. Drift issues and opportunity suggestions sit side by side.

```
  Drift engine ─────┐
  Opportunity ──────┼──▶  Suggestion[]  ──▶  GUI inbox  ──▶  Apply / Snooze
  providers ────────┘                                          │
                                                               └─▶ learns from Snooze
```

## Why "Condense"

Every suggestion is measured by **estimated saving** — the unifying threshold,
not raw frequency:

```
saving ≈ (tokens or keystrokes saved per occurrence) × frequency
surface a suggestion when:  saving  >  cost-of-the-suggestion-itself
```

This makes token-saving a first-class, measurable metric — the product's namesake.

## Shared abstraction (mirrors the existing DriftChecker)

The drift engine's shape — `DriftContext` → `DriftChecker[]` → `DriftIssue[]` —
is the template. The opportunity engine reuses it:

| Drift engine (exists)        | Opportunity engine (new)         |
|------------------------------|----------------------------------|
| `DriftContext`               | `ObservationContext`             |
| `DriftChecker`               | `SuggestionProvider`             |
| `DriftIssue`                 | `Suggestion`                     |
| `cai check` (on demand)      | background hooks + periodic scan |

A `Suggestion` carries: `kind`, `title`, `rationale`, `estimatedSaving`,
`apply` (the concrete action), and `snoozeKey` (for the learning loop).
"More ideas later" = "another provider" — no core rewrite. This is the same
depth we just brought to the drift checkers (one shared seam, providers plug in).

## Signal sources → provider families

All five chosen. Each is a `SuggestionProvider` family.

### 1. Shell history
- Repeated command chain → propose a **skill / alias** (e.g. `ship` for
  `build && test && push`). Apply writes a skill or `patterns/` file
  (`cai pattern add` already exists as the fix path).
- Flag verdensification (always the same flags) → suggest a default profile.
- Fail→fix→success loops → distil a **debug pattern**.
- Stable A-before-B ordering → encode as a pattern's step sequence.

### 2. Agent session logs  *(largest token lever)*
- Knowledge re-derived across N sessions ("where's the pipeline code") →
  **anchor it in `context/`**. Proactive GROW.
- A `context/` file never appears as read in any session → **dead context, prune**.
- Big file, only one paragraph ever referenced → **split, archive the rest**.
- Same *kind* of task solved 3× with no pattern → trigger GROW proactively.

### 3. Scaffold structure
- Frontmatter `edges` graph: islands (nothing points in), dead ends, cycles →
  the agent navigates inefficiently. (Reuses the edges checker. "Show in graph".)
- Two patterns ≥70% overlap → **merge**.
- Pattern not loaded in 90 days → **archive**.

### 4. Code ↔ scaffold correlation  *(bridge to the drift engine)*
- High git churn + no `context/` entry → **hot and undocumented, document it**.
- A `context/` section referencing code that never changes → possibly stale.

### 5. Session watchdog  *(live — the real-time condense)*
Claude Code (and any agent) degrades noticeably past ~50–60% context fill —
attention drops, early facts slip. The watchdog acts **before** the session
goes dumb. This is the most immediate "Condense" value because it saves
quality/tokens in real time.

- **Mechanic:** both live paths — **hook-based** where available (Claude Code
  hooks fire at CAI on tool/stop), with a **transcript heuristic** fallback
  (read the running session JSONL under `~/.claude/projects/.../`, sum tokens,
  warn past threshold).
- **Actions on threshold:**
  - **Compact now** — and *ship the compaction instruction with it*: CAI tells
    the agent **what to keep** (open tasks, key decisions, the scaffold pointers)
    and **what to drop** (finished tasks, stale tool outputs). The agent just
    executes the condense brief CAI prepared. ← this is the heart of it.
  - **Split session + handoff** — CAI builds a handoff brief (scaffold + open
    items) for a fresh session. The Condense core: distil the essential, shed ballast.
  - **Scaffold instead of history** — when the agent is reconstructing something
    that already lives in `context/`, suggest "load the file, don't carry it in
    the transcript".

The watchdog **closes the loop** with source 2: what it sees live as
"re-derived again and again," it reports retrospectively as "anchor this in
`context/`." Live symptom → structural cure.

## Cross-cutting decisions (locked in this brainstorm)

1. **Threshold = estimated saving** (tokens/keystrokes × frequency > suggestion cost).
2. **Learn from Snooze** — e.g. snoozed 3× ⇒ suppress that pattern. Needs a
   little local state keyed by `snoozeKey`.
3. **Privacy** (implied, to confirm at build time): observations stay strictly
   local — e.g. `.cai/observations.jsonl`. Shell history and session logs are
   sensitive; nothing leaves the machine.

## Open questions for build time
- Exact `Suggestion` schema and the `apply` action contract (idempotent? reversible?).
- Watchdog token-estimation accuracy from transcript vs. hook signal.
- Where suggestion state + snooze memory live, and its format.
- GUI: local server vs. static file driven by `cai` JSON output.

## Tool landscape — don't rebuild what exists (scan 2026-06-26)

A scan of the surrounding tooling changed the provider strategy. Three of the
five signal sources are **already covered** by neighbouring tools. CAI should
**aggregate and specialise**, not duplicate.

| Our source                | Already exists                         | CAI's role becomes |
|---------------------------|----------------------------------------|--------------------|
| 1. Shell history → skill  | **`rtk discover`** — scans CC sessions, finds repeated commands, **estimates savings** already | **consume** its output into the inbox |
| 5. Session watchdog (live)| **`gsd-context-monitor.js`** hook — reads live ctx % from a statusline bridge (`/tmp/claude-ctx-{id}.json`), warns at 35%/25% remaining, injects to the **agent** | **extend** it |
| Fail→fix pattern          | **`rtk learn`** — learns CLI corrections from error history | tap as a source |
| Session token totals      | **`rtk session`** — output tokens per session, RTK adoption % | use as data |

**What no neighbour does — CAI's unclaimed core:**
- Sources **2 / 3 / 4 are scaffold-aware**, and the scaffold is CAI's moat.
  RTK and GSD have no scaffold. Only CAI can say: "this knowledge is re-derived
  every session → anchor it in `context/`", "this edges graph has islands",
  "this file is hot in git but undocumented".
- **The condense brief.** `gsd-context-monitor` says "wrap up / save state" but
  does **not** ship the keep/drop instruction, and it can't — it has no
  scaffold. CAI fills exactly that gap: at the threshold, hand the agent a brief
  built from scaffold + open tasks ("keep X, drop Y, reload `context/...`").

**Revised thesis:** CAI is the **aggregator + scaffold specialist**. It pulls
RTK's and GSD's raw signals into one inbox, adds its unique scaffold
intelligence, and is the only tool offering a *structural* fix rather than just
a warning. RTK condenses each command; CAI condenses the *knowledge and the
session*.

### Integration notes
- RTK has no `--json` yet (`rtk discover --json` errors). Either parse its
  table output or upstream a JSON flag. `rtk discover`, `rtk session`,
  `rtk learn` are the three feeds.
- `gsd-context-monitor` already proves the live mechanic works via the
  statusline bridge file — CAI can read the same bridge instead of reinventing
  transcript parsing. Hook infra (PreToolUse guards etc.) already exists in
  `~/.claude/hooks/`.

## Architecture-suggestion tools (e.g. `/improve-codebase-architecture`) — fit?

The `/improve-codebase-architecture` skill is an **LLM-judgment** tool: it reads
code, *judges* shallow-vs-deep, proposes refactors. Non-deterministic,
token-heavy — the opposite of CAI's deterministic/zero-token/CI moat. So:

- **As a tool we run on CAI:** yes, already doing it. Not a CAI feature.
- **As a feature *in* CAI:** not the refactor-linter version (that's LLM judgment
  + a different market: Sonar / CodeScene / clean-code skills — scope drift).
- **The on-moat version that DOES fit:** CAI provides the *deterministic trigger*,
  an LLM (Claude, via `cai sync`-style delegation) optionally does the *fix*. This
  is exactly the empty-quadrant bet: cheap structural signal → structural
  suggestion. Candidate command (working title) **`cai suggest`**:
  - anchor knowledge re-derived across sessions (source 2)
  - merge ≥70%-overlapping patterns (source 3)
  - document a git hotspot that has no `context/` entry (source 4)
  - flag edges-graph islands / dead ends (source 3)

  Detection is deterministic (no LLM); applying can be delegated to Claude like
  `cai sync` already does. Same inbox model.

**Boundary:** CAI finds the opportunity deterministically; the LLM only ever
*applies*. We do not put code-quality/refactor *judgment* inside CAI.

## Relationship to current code
- Drift engine refactor (commit `91d0efd`) already established the pattern this
  reuses: one shared context, thin providers, a single result type, derived counts.
- `cai pattern add` is a partial Apply path for skill/pattern suggestions.
- The edges checker already builds the graph the structure provider needs.
