Durable Memory / Handoff
These files are the anti-deadlock handoff layer. If context is compressed or a new agent starts, it reads these first.
memory/PROJECT_STATE.md
# Gmail Outreach Mission State Project: Gmail warm-lead re-engagement system Owner: Ronald / Human Board Orchestrator: Jesus CEO tasking layer: CEO Agent Project root: /root/agency/projects/gmail-outreach Dashboard target: http://<box-ip>:8765 or local http://127.0.0.1:8765 ## Mission Build an agent-operated outreach system that: 1. Accepts Ronald's warm-lead CSV. 2. Gives a Gmail operations agent read/write draft access after authorization. 3. Checks whether prior correspondence exists with each lead. 4. Understands the thread context. 5. Writes a new touch-base email to bring the lead back into the loop. 6. Saves every email as a draft for manual approval; never sends automatically. 7. Processes 20 leads per weekday by default, adjustable from dashboard. 8. Tracks leads, drafts, approvals, responses, tasks, and agent status in a dashboard. ## Non-Negotiables - No email is sent automatically. - Gmail write access is used for draft creation only unless Ronald explicitly changes policy. - Public/external communication requires manual approval. - Context and task state must be durable so agents can resume after compression/restarts. - No deadlocks: blocked tasks must surface visibly in dashboard/task ledger. ## Current Status - Local dashboard foundation built with Python stdlib. - SQLite database: data/outreach.db - Dashboard app: app/dashboard.py - Gmail is not connected yet. - Lead CSV has not been provided yet. - Daily processing cron is not armed yet because Gmail/CSV prerequisites are missing. ## Next Required Inputs From Ronald 1. Gmail authorization path: - Recommended for Gmail only: Gmail app password via IMAP/SMTP/Himalaya, or - Full Google OAuth client for Gmail API draft creation. 2. Lead CSV with at least an email column. 3. Preferred sender identity/name/signature/tone for re-engagement emails. ## Recovery Instructions For Any Agent 1. Read this file. 2. Open /root/agency/projects/gmail-outreach/tasks/TASKS.md. 3. Query dashboard JSON: curl http://127.0.0.1:8765/api/state 4. Inspect SQLite if needed: sqlite3 /root/agency/projects/gmail-outreach/data/outreach.db '.tables' 5. Continue from blocked/needs_input tasks first. ## Self-Healing Operations Dashboard and live terminal are now supervised and self-healing. Public URLs: - Dashboard: http://76.13.185.77:8765 - Live terminal: http://76.13.185.77:8766 Durable services: - `hermes-dashboard.service` runs `/root/agency/projects/gmail-outreach/app/dashboard.py` on port 8765. - `hermes-terminal.service` runs `ttyd` on port 8766 and attaches to tmux session `jesus_dashboard`. - `/usr/local/sbin/hermes-ensure-jesus-tmux` recreates `jesus_dashboard` with `hermes --continue` if the tmux session is missing. - `/usr/local/sbin/hermes-healthcheck` checks both HTTP endpoints, systemd services, and tmux. - `/etc/cron.d/hermes-self-heal` runs the healthcheck once per minute. Recovery behavior: - systemd restarts crashed dashboard/terminal services immediately. - cron healthcheck repairs cases where a service is inactive, an HTTP endpoint fails, or tmux session `jesus_dashboard` disappeared. - Recovery actions are logged to `/var/log/hermes-self-heal.log`. - Recovery actions are inserted into dashboard SQLite `events` with actor `Hermes Self-Heal`. Manual commands: - Status: `systemctl status hermes-dashboard hermes-terminal cron` - Restart: `systemctl restart hermes-dashboard hermes-terminal` - Healthcheck: `/usr/local/sbin/hermes-healthcheck` - Logs: `tail -80 /var/log/hermes-self-heal.log` Cause of 2026-06-29 outage: - Dashboard and ttyd terminal were previously running as background processes, not durable services. - A tmux/session reset left `jesus_dashboard` missing. - With no tmux session and no durable supervisor, ports 8765 and 8766 stopped serving. - This has been corrected with systemd supervision plus cron healthcheck. ## Jesus Agent Operating Profile Jesus/Hermes is configured for complex workloads: - `model.context_length: 1000000` - `agent.reasoning_effort: xhigh` - `agent.max_turns: 300` - `compression.enabled: true` - `compression.threshold: 0.45` - `compression.target_ratio: 0.18` - `compression.protect_first_n: 5` - `compression.protect_last_n: 30` Detailed profile: `/root/agency/projects/gmail-outreach/docs/JESUS_AGENT_OPERATING_PROFILE.md` Operational expectation: use the large context window for synthesis, but keep source-of-truth state in files/SQLite/markdown and use targeted reads instead of dumping huge logs into chat.
tasks/TASKS.md
# Gmail Outreach Task Ledger ## Task States - done: completed and verified - active: currently being worked - pending: ready but not started - blocked: cannot proceed without external input/authorization - needs_input: requires Ronald or data input ## Current Tasks | ID | Owner | Status | Task | Acceptance | |---|---|---|---|---| | GO-001 | Dashboard Engineer Agent | done | Create dashboard foundation | Local web UI shows agents/tasks/leads/drafts/settings/events | | GO-002 | Jesus | done | Persist task/state memory | SQLite + markdown files exist and can recover project state | | GO-003 | Gmail Ops Agent | blocked | Get Gmail authorization | OAuth/app-password available; read/search/draft verified | | GO-004 | Lead Intelligence Agent | needs_input | Ingest Ronald lead CSV | CSV imported; leads visible in dashboard | | GO-005 | Gmail Ops Agent | pending | Implement correspondence scanner | Prior correspondence status and thread summary stored per lead | | GO-006 | Email Copy Agent | pending | Implement personalized draft generator | Drafts created as Gmail drafts, never sent automatically | | GO-007 | Scheduler Agent | pending | Implement 20/day Mon-Fri scheduler | Daily quota adjustable in dashboard and cron respects weekday policy | | GO-008 | Gmail Ops Agent | pending | Implement response monitor | Replies counted and linked to leads | ## Deadlock Policy If a task is blocked for more than one working cycle: 1. Mark the blocker explicitly. 2. Create a smaller unblock task. 3. Surface it to Jesus. 4. Jesus escalates to Ronald only if it needs board-level authorization or data. ## CEO Tasking Model Ronald gives directive → Jesus receives → CEO Agent decomposes into tasks → specialist agents execute → QA verifies → Jesus reports finished work.
docs/GMAIL_INTEGRATION_PLAN.md
# Gmail Integration Plan
## Recommended Path
Because this project needs Gmail thread search/read and draft creation, use Google Workspace OAuth with Gmail API scopes.
Loaded skill: google-workspace
Credential status now: missing google_token.json and google_client_secret.json
## OAuth Setup Required
Ronald must provide either:
1. A Google OAuth Desktop App client_secret JSON file path, or
2. Raw Desktop OAuth client JSON content that Jesus can save to a file.
Then Jesus will run:
```bash
GSETUP="python ${HERMES_HOME:-$HOME/.hermes}/skills/productivity/google-workspace/scripts/setup.py"
$GSETUP --client-secret /path/to/client_secret.json
$GSETUP --auth-url --services email --format json
# Ronald opens URL, approves, and pastes final localhost redirect URL/code.
$GSETUP --auth-code "PASTED_URL_OR_CODE" --format json
$GSETUP --check
```
## Gmail API Operations Needed
- Search messages by lead email.
- Get message/thread bodies.
- Summarize prior correspondence.
- Create draft email or reply draft.
- Monitor inbox for responses.
## Critical Safety Policy
- Use draft creation only.
- Do not send emails automatically.
- Dashboard shows drafts ready for approval.
- Ronald manually sends from Gmail or via future explicit dashboard approval feature.
## Alternative Path
If Ronald wants email-only and simpler setup, use the Himalaya CLI with Gmail App Password. This may be easier for IMAP/SMTP, but Gmail API is stronger for draft/thread operations.