# Edita PA Runbook

# Edita PA Runbook

## TLDR

- **Edita** = Alem's AI Personal Assistant. Daemon `com.john.edita-loop` (LaunchAgent), script `~/system/agents/pa/edita-loop.js`. Reports to John, who reports to Alem.
- Runs **email triage every 5 min** on `info@alai.no` (Migadu). Classifies ARCHIVE / REPLY_TEMPLATE / ESCALATE, writes drafts, never auto-sends.
- **`AUTO_REPLY_ENABLED = false`** — hardcoded CEO kill switch (order 2026-03-07). Drafts only land in `~/system/intake/drafts/`; nothing goes out without a human/John send.
- Calendar tick and memory-consolidation tick exist in the loop but are **stub code ("Faza 3")** — not yet active. Only email triage (Faza 1) and the incoming-message handler (Faza 2, event-driven Slack/Telegram) run for real.
- Check it's alive: `launchctl list | grep com.john.edita-loop` and `cat ~/system/logs/edita-loop-heartbeat.json`.
- Restart: `launchctl kickstart -k gui/$(id -u)/com.john.edita-loop`.

## Identity

| Field | Value |
|---|---|
| Name | Edita |
| Role | Personal Assistant, ALAI Holding AS |
| Boss | Alem Basic (CEO, alem@alai.no) |
| Manager | John (AI Director) |
| Primary mailbox | info@alai.no (Migadu) |
| System prompt | `~/system/agents/pa/edita-system-prompt.md` |

Language: mirrors the user (Bosnian/English/Norwegian mix OK). Tone: direct, warm, professional, max 3 sentences for routine replies. Edita never says "I can't" — she escalates to John instead.

## What Edita does

- Triages inbound email: ARCHIVE / REPLY_TEMPLATE / ESCALATE
- Answers Telegram/Slack messages from Alem
- Creates and updates MC tasks
- Checks calendar, reminds about meetings (stub — not active yet)
- Writes draft email replies (never sends automatically)
- Consolidates memory/session context (stub, delegated to `edita-memory-writer.js`)
- Coordinates and escalates — **does not deploy, does not build, does not commit code**

## What Edita does NOT do

- Send email automatically without passing the Gate 3 kill switch
- Commit code or deploy services
- Make business decisions without confirmation
- Touch financial systems directly

## Escalation rules (always → John → Alem)

- VIP sender (see `~/system/agents/pa/memory/contacts-vip.json`)
- Money/legal keywords: ugovor, faktura, ponuda, legal, NDA, payment
- New/unknown client contact
- Classifier confidence < 0.6

## Architecture — the loop

Script: `~/system/agents/pa/edita-loop.js` (extends `daemon-base.js` — signal handling, heartbeat, circuit breaker).

```
masterTick()
  A. emailTriageTick()          — every 5 min   [ACTIVE]
  B. calendarTick()             — every 15 min  [STUB — Faza 3, not active]
  C. memoryConsolidationTick()  — every 30 min  [STUB — Faza 3, delegated to edita-memory-writer.js]
  D. incomingMessageHandler()   — event-driven  [ACTIVE — Slack/Telegram, Faza 2]
  validationTick()              — every 6h, always active (incl. dry-run)
```

Email triage flow (`emailTriageTick`):
1. Pull unclassified mail for `info@alai.no` from `~/system/databases/email-inbox.db`.
2. Classify via Ollama (`TRIAGE_MODEL = llama3.1:8b`, `OLLAMA_HOST` default `http://localhost:11434`).
3. Write-back classification even in dry-run, so items aren't re-examined every tick.
4. If reply warranted: build draft, write to `~/system/intake/drafts/draft-<ts>-<subject>.md`.
5. Gate 3 check: `autoReplyEnabled = config.auto_reply_enabled || AUTO_REPLY_ENABLED` (`AUTO_REPLY_ENABLED` is hardcoded `false` in code) — if false, hold and log `GATE3_HOLD`, notify John. No send happens.

### Key config/paths

| Const | Path |
|---|---|
| `INTAKE_CONFIG` | `~/system/config/intake-config.json` |
| `DRAFTS_DIR` | `~/system/intake/drafts/` |
| `DECISIONS_LOG` | `~/system/logs/edita-decisions.jsonl` |
| `HEARTBEAT_FILE` | `~/system/logs/edita-loop-heartbeat.json` |
| `SYSTEM_PROMPT_FILE` | `~/system/agents/pa/edita-system-prompt.md` |
| `EMAIL_INBOX_DB` | `~/system/databases/email-inbox.db` |
| `VIP_CONTACTS` | `~/system/agents/pa/memory/contacts-vip.json` |

## Run modes

```bash
node ~/system/agents/pa/edita-loop.js               # live (LaunchAgent default)
node ~/system/agents/pa/edita-loop.js --dry-run      # Faza 1: logs decisions only, no drafts sent
node ~/system/agents/pa/edita-loop.js --allow-archive  # next safe step after dry-run: allows ARCHIVE action, still no sends
```

## Operations

```bash
# Status
launchctl list | grep com.john.edita-loop
cat ~/system/logs/edita-loop-heartbeat.json

# Restart
launchctl kickstart -k gui/$(id -u)/com.john.edita-loop

# Recent decisions
tail -50 ~/system/logs/edita-decisions.jsonl

# Pending drafts (never auto-sent — review before send)
ls -la ~/system/intake/drafts/
```

Plist: `~/Library/LaunchAgents/com.john.edita-loop.plist`.

## Troubleshooting

**Edita not triaging new mail**
1. Confirm daemon is running: `launchctl list | grep com.john.edita-loop` (should show a PID, not `-`).
2. Check heartbeat freshness: `cat ~/system/logs/edita-loop-heartbeat.json` — stale timestamp means the tick loop died silently; kickstart it.
3. Check Ollama circuit breaker: `grep "circuit breaker open" ~/system/logs/edita-loop.log` — if tripped, Ollama (`localhost:11434`) is unreachable; test with `curl -s localhost:11434/api/tags`.
4. Confirm `info@alai.no` is actually being scanned — see [[Email System Runbook]] for the account/daemon relationship (separate daemon, `email-agent.js`, ingests mail into `email-inbox.db`; Edita reads from that same DB, it does not do its own IMAP fetch).

**A draft never turned into a sent email**
This is expected — `AUTO_REPLY_ENABLED = false` is a deliberate CEO gate, not a bug. Drafts sit in `~/system/intake/drafts/`; John or Alem must review and send manually via the paths in [[Email System Runbook]].

**Calendar reminders / auto-memory-consolidation not happening**
Expected — both are Faza 3 stub code in `edita-loop.js` (`calendarTick`, `memoryConsolidationTick` are no-ops that just log a debug line). Not a regression; they were never activated.

## Related

- [[Email System Runbook]] — the underlying email ingest/audit/send pipeline Edita's triage tick reads from and drafts against.
- `~/system/agents/pa/edita-memory-writer.js` — standalone memory consolidation script (the real implementation behind the Faza 3 stub).