# ai-agent fragment

**ID:** `fvcms.fragment.ai-agent.001`

## What it is

The **AI Agent** panel. v0.1: takes a natural-language proposal, classifies it into SMALL/MEDIUM/LARGE per the 3-tier approval rule (`app-pact` §3.13), logs the proposal to the audit panel, and shows a preview. The real LLM call + write plan comes in v0.2.

Per `app-pact` §3.11: "Manual + AI both, always. The operator can do any task manually via the chrome. The AI can do the same task via the chrome. Neither mode is privileged."

Per §3.12: "AI scope is explicit. The operator can see the scope before the AI acts. The AI never acts outside its declared scope without asking first."

Per §3.14: "The store is the source of truth. Whatever the AI writes, the store holds. Whatever the operator writes manually, the store holds. The chrome is a view onto the store, not a parallel source of truth."

## Public API

```js
import { openAiAgent, renderAiAgent, classifyTier } from 'app-fragments/ai-agent/index.js';

const panel = openAiAgent();
const tier = classifyTier([{type:'content:save'}]); // 'SMALL' | 'MEDIUM' | 'LARGE' | null
```

## Recipe (10-item, abbreviated)

1. **purpose** — natural-language → classified proposal
2. **inputs** — operator text, `annotation.json`, `roles-config.json`
3. **outputs** — proposal classified into 3-tier, logged to audit
4. **state machine** — same as other panels
5. **event bus** — emits `ai:proposed`, `ai:approved`, `ai:rejected`
6. **dependencies** — `admin-audit` (for logging)
7. **constitutional refs** — app-pact §3.11, §3.12, §3.13, §3.14
8. **tier** — T2
9. **canonical home** — `app-fragments/ai-agent/`
10. **recipe** — this file

## v0.1 limitations (for the operator)

- The agent does NOT call an LLM. The proposal text is treated as a single "write" and classified as SMALL. v0.2 will wire the LLM call and produce a real write plan.
- No actual writes happen. v0.1 is a preview/UI.
- The "approve" buttons are placeholders. v0.2 will wire them to the store path per §3.14.

## v0.2 plan (next iteration)

1. Wire the LLM call (operator's choice of provider: groq, anthropic, openai, zai, local). Use the rotator pattern from VibeCoder's 10 ingredients.
2. Parse the LLM response into a write plan (an array of {type, scope, payload} entries).
3. Classify the plan into SMALL/MEDIUM/LARGE based on the count + types.
4. Show a preview (for MEDIUM) or a full diff (for LARGE).
5. Wire the approve/reject buttons to the store path (per §3.14).
6. Subscribe to the event bus (§12.7) to track AI activity.
