---
mode: subagent
---

# t2857: `aidevops case draft` agent (RAG, human-gated, provenance)

## Pre-flight

- [x] Memory recall: `rag retrieval generation provenance human gate` → no relevant lessons
- [x] Discovery: PageIndex + sensitivity routing + cases plane all land in earlier MVP phases; this task composes them
- [x] File refs verified: parent brief; `tools/context/pageindex.md`; future helpers `llm-routing-helper.sh`, `knowledge-index-helper.sh`, `case-helper.sh`
- [x] Tier: `tier:thinking` — RAG retrieval design and prompt architecture have non-obvious choices (case-scoped vs corpus-wide, evidence-citation format, draft vs final separation)

## Origin

- Created: 2026-04-25
- Parent task: t2840 / GH#20892
- Phase: P6 (AI comms agent)

## What

`aidevops case draft <case-id> --intent "..." [--include-case <id>]` produces a strategic communication draft (letter, email, response) using RAG over the case's `sources.toon` (cross-case privilege firewall enforced by default), with full provenance footer citing every source consulted. Drafts are **always human-gated** — the helper writes to `_cases/<case-id>/drafts/<timestamp>-<intent-slug>.md` and never auto-sends.

**Concrete deliverables:**

1. `scripts/case-draft-helper.sh draft <case-id> --intent "..." [flags]` — generates draft, writes to drafts/, opens preview
2. Default scope: only `_knowledge/sources/<id>/` for sources in this case's `sources.toon`. Cross-case access via `--include-case <id>` (logged in `_cases/<case-id>/comms/cross-case-access.jsonl` for audit)
3. RAG composition: tree-walk via `knowledge-index-helper.sh query` (case-scoped) → top N excerpts → LLM call via `llm-routing-helper.sh route --tier <max-of-source-tiers>` with prompt that mandates evidence citation
4. Provenance footer (mandatory in every draft): "Drafted with reference to: source-id (kind: invoice, sensitivity: pii, sha: abc...), source-id, ... Generated by: aidevops v.X.Y, model: <name>, at: <timestamp>"
5. Tier escalation: if any source attached to the case is `privileged`, the draft routes through local LLM (Ollama via t2848) — no cloud calls, hard fail if Ollama down
6. CLI flags: `--intent <free-text>`, `--tone <neutral|formal|conciliatory|firm>`, `--length <short|medium|long>`, `--cite <strict|loose>`, `--dry-run` (print draft to stdout, don't write)
7. Re-draft: `aidevops case draft <case-id> --revise <draft-file> --feedback "..."` reads existing draft + feedback, generates revision

## Why

Strategic communications carry weight — a misworded dispute response or contract clause can have material consequences. AI drafting reduces blank-page friction (10x productivity gain on first-draft work) but final approval must be human. Auto-send for strategic comms is forbidden (P6b handles routine chasers).

Provenance footers serve two purposes: (1) the human can verify the draft cites the right sources before sending, (2) the audit trail shows exactly which knowledge was consulted — important for legal/compliance review.

Cross-case privilege firewall is critical for matters with multiple unrelated cases — bleed of one case's privileged content into another case's draft is a discovery nightmare. Requiring explicit `--include-case` opt-in + audit log makes cross-case retrieval a deliberate, traceable act.

Tier escalation (privileged-attached → local LLM mandatory) is the routing layer's hard-fail guarantee in action: privileged content never sees cloud.

## How (Approach)

1. **RAG retrieval** — `case-draft-helper.sh draft`:
   - Read `dossier.toon` for case context (parties, kind, status, recent timeline)
   - Read `sources.toon` for attached source IDs
   - Compose retrieval intent: `"<user-provided intent>; case kind: <kind>; parties: <parties>"` 
   - Call `knowledge-index-helper.sh query --intent "..." --scope case=<case-id>` (extension to t2850's CLI)
   - Retrieve top N=8 excerpts with anchors; cap total context size (8K tokens for short drafts, 32K for long)
2. **Tier resolution** — `_max_tier(sources)`: pick maximum sensitivity over all attached sources for the case. Use this as `--tier` to `llm-routing-helper.sh route`. If `privileged`, also force `--task draft` and let routing layer hard-fail if Ollama down.
3. **Prompt template** — `templates/case-draft-prompt.md`:
   ```
   You are drafting a {tone} {kind} for case {case-id} on behalf of {party-self}.
   The intent is: {intent}.
   Recent case timeline: {last 5 timeline entries}.
   Available evidence:
   {numbered list of excerpts with [source-id]: "excerpt..." anchors}
   
   Produce a draft that:
   - Cites every claim with [source-id] anchors
   - Stays {tone}; avoids speculation beyond the evidence
   - Length: {length}
   At the end, list "Drafted with reference to:" with each consulted source.
   ```
4. **Output writing** — write to `_cases/<case-id>/drafts/<timestamp>-<intent-slug>.md`:
   - Markdown with frontmatter: `case_id, intent, tone, length, model, generated_at, sources_consulted, cross_case_includes`
   - Body: the LLM output verbatim
   - Provenance footer (auto-appended even if model omits it): explicit list of source-ids with kind + sensitivity + sha
5. **Cross-case access** — `--include-case <id>`: validates `<id>` exists, appends audit entry to `_cases/<self-case-id>/comms/cross-case-access.jsonl` `{at, included_case, included_by, reason?}`, then queries that case's sources too
6. **Tone library** — `_config/draft-tones.json` defines tone presets (system-prompt fragments) so users can add custom tones per repo
7. **Revise mode** — `--revise <file> --feedback "..."`:
   - Read existing draft
   - Compose prompt: `"Revise this draft per feedback: {feedback}. Original draft: {body}"`
   - Same routing path; new file at `_cases/<case-id>/drafts/<timestamp>-<intent>-rev2.md`
8. **Tests** — covers happy path with mocked LLM, tier escalation when privileged-attached, cross-case access requires `--include-case` flag, provenance footer always present, revise mode preserves prior context

### Files Scope

- NEW: `.agents/scripts/case-draft-helper.sh`
- NEW: `.agents/templates/case-draft-prompt.md`
- NEW: `.agents/templates/draft-tones-config.json` (default `_config/draft-tones.json`)
- EDIT: `.agents/cli/aidevops` (add `case draft` subcommand)
- EDIT: `.agents/scripts/knowledge-index-helper.sh` (add `--scope case=<id>` filter to `query`)
- NEW: `.agents/tests/test-case-draft.sh`
- EDIT: `.agents/aidevops/cases-plane.md` (drafting section + privilege firewall doc)

## Acceptance Criteria

- [ ] `aidevops case draft case-2026-0001-foo --intent "request payment of overdue invoice"` produces a draft file in `_cases/.../drafts/`
- [ ] Draft contains cited [source-id] anchors for every factual claim
- [ ] Provenance footer lists every source consulted with kind + sensitivity + sha
- [ ] Case with `privileged`-attached source: routing forces local LLM; draft fails if Ollama down
- [ ] Cross-case access without `--include-case`: only own case's sources appear in retrieval (verifiable via audit log)
- [ ] `--include-case <other-id>` flag: appends audit entry to `cross-case-access.jsonl`, includes other case's sources in retrieval
- [ ] `--tone formal` vs `--tone conciliatory`: visible difference in output style
- [ ] `--revise <file> --feedback "..."`: produces new revision file referencing prior draft
- [ ] `--dry-run` prints to stdout, does not write file
- [ ] Audit log records: case-id, intent, tone, model, sources consulted, tier, cross-case includes, generated_at
- [ ] No `auto-send` flag exists (drafts cannot trigger send)
- [ ] ShellCheck zero violations
- [ ] Tests pass: `bash .agents/tests/test-case-draft.sh`
- [ ] Documentation: drafting section in `.agents/aidevops/cases-plane.md`

## Dependencies

- **Blocked by:** t2851 (P4a — case dossier), t2852 (P4b — sources.toon, attach), t2850 (P1c — knowledge-index-helper query), t2847 (P0.5b — LLM routing), t2848 (P0.5c — Ollama for privileged)
- **Soft-blocked by:** t2856 (P5c — thread context for email-derived drafts)
- **Blocks:** post-MVP refinement; no MVP child blocked by this

## Reference

- Parent brief: `todo/tasks/t2840-brief.md` § "AI comms agent" + "Cross-case privilege firewall"
- RAG pattern: `.agents/tools/context/pageindex.md` (vectorless tree-walk RAG)
- Prompt design: model on prompts in `.agents/tools/document/extraction-schemas/*.md`
- Audit log pattern: t2847 (LLM routing audit log) + t2853 (case alarm audit) — same shape
