docs: Phase 8 documentation - Gitea, Obsidian, Outline, Vikunja, map (AUD-74)
- README: architecture Mermaid, Phase 8 status, Phase 7 endpoints, Documentation index - docs/outline/: AI-context collection (index, system, config, code map, runbook) - docs/email-agent-architecture.mmd + rendered PNG + Archify map (showcase pass) - docs/vikunja-tasks.json (Vikunja project 17, tasks 179-185) - docs/phase8-documentation.md evidence
This commit is contained in:
108
README.md
108
README.md
@@ -7,34 +7,59 @@ replies, and answers the Hub.
|
||||
The build spec is [`AGENTS.md`](AGENTS.md). `ORIGINAL_NOTES.md` is archived
|
||||
pre-planning material and is not authoritative.
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
SAM["Sam<br/>phone or desktop browser"] --> CADDY["Caddy on .35<br/>mail.lab.audasmedia.com.au"]
|
||||
CADDY --> UI["HTMX dashboard<br/>login, inbox, rules, reports"]
|
||||
UI --> DB[("SQLite<br/>email_agent_data")]
|
||||
UI --> GMAIL["Gmail<br/>IMAP :993 / SMTP :587 (IPv4)"]
|
||||
UI --> JEV["JEV / TypeSafe<br/>classify"]
|
||||
UI --> OMNI["OmniRoute :20129<br/>draft reply"]
|
||||
UI --> APPRISE["Apprise :8210<br/>summary email"]
|
||||
HUB["Central AI Hub :8788"] --> API["Hub API<br/>/capabilities /ask /notify"]
|
||||
API --> DB
|
||||
N8N["n8n schedule"] --> JOBS["CLI jobs<br/>-fetch -classify -summary-send"]
|
||||
JOBS --> DB
|
||||
```
|
||||
|
||||
Sources: [`docs/email-agent-architecture.mmd`](docs/email-agent-architecture.mmd)
|
||||
and [`docs/email-agent-map.html`](docs/email-agent-map.html). Interactive map:
|
||||
<https://maps.lab.audasmedia.com.au/email_agent/docs/>.
|
||||
|
||||
## Status
|
||||
|
||||
**Phase 7 — Summary and Hub; retention.** The Go skeleton, session login,
|
||||
and HTMX dashboard (Phase 1), real mail over **IMAP with an app password,
|
||||
forced to IPv4** (Phase 2), **JEV classification** (Phase 3), **bulk triage
|
||||
actions** (Phase 4), **reply drafts** (Phase 5), and now **unsubscribe
|
||||
detection and the rules editor** (Phase 6). Open a message to read it, draft a
|
||||
reply with the LLM through **OmniRoute** from a template, edit it, and send it
|
||||
over Gmail SMTP (IPv4 + STARTTLS). A reply is sent **as the address the mail
|
||||
arrived at** (`X-Pm-Original-To`, FR-15) and returns to the original sender; the
|
||||
reply sets `In-Reply-To`/`References` so Gmail keeps the thread, and the
|
||||
original is filed under its `Replied-to/<address>` label. Sending is a
|
||||
deliberate UI action with a confirmation — there is no auto-send (§10). The
|
||||
**rules editor** (`/rules`) saves and versions the plain-text rules that JEV and
|
||||
the reply model read. **Unsubscribe detection** (`/unsubscribe`) finds RFC
|
||||
2369/8058 links and body links, keeps a domain ignore list, and records what Sam
|
||||
marks — it **never follows a link**. Every action, including drafts, sends,
|
||||
rules edits, and unsubscribe marks, is appended to `actions_log` (FR-13).
|
||||
**Phase 7** adds the daily **summary** (`-summary`, `-summary-send`; delivered
|
||||
by email through Apprise) and the read-only **Hub API** (`/capabilities`,
|
||||
`/ask`, `/notify`). **Retention** (AGENTS.md §7) is enforced by the bounded
|
||||
`-retain` job: it clears message bodies older than one month, keeps metadata,
|
||||
and caps the append-only `actions_log`; see
|
||||
[`docs/retention.md`](docs/retention.md). See
|
||||
[`docs/phase7-summary-hub.md`](docs/phase7-summary-hub.md) for Phase 7,
|
||||
[`docs/phase6-unsubscribe.md`](docs/phase6-unsubscribe.md) for the phase evidence,
|
||||
[`docs/phase5-replies.md`](docs/phase5-replies.md) for Phase 5, and
|
||||
[`docs/phase4-triage.md`](docs/phase4-triage.md) for Phase 4.
|
||||
**Complete and deployed.** All eight AGENTS.md §11 phases are done. The Go
|
||||
skeleton, session login, and HTMX dashboard (Phase 1), real mail over **IMAP with
|
||||
an app password, forced to IPv4** (Phase 2), **JEV classification** (Phase 3),
|
||||
**bulk triage actions** (Phase 4), **reply drafts** (Phase 5), **unsubscribe
|
||||
detection and the rules editor** (Phase 6), and the **daily summary by email plus
|
||||
the read-only Hub API** (Phase 7) run on `.13` behind Caddy. Phase 8 documents
|
||||
the project across Gitea, Obsidian, Outline, Vikunja, and the architecture map.
|
||||
|
||||
Open a message to read it, draft a reply with the LLM through **OmniRoute** from
|
||||
a template, edit it, and send it over Gmail SMTP (IPv4 + STARTTLS). A reply is
|
||||
sent **as the address the mail arrived at** (`X-Pm-Original-To`, FR-15) and
|
||||
returns to the original sender; the reply sets `In-Reply-To`/`References` so
|
||||
Gmail keeps the thread, and the original is filed under its
|
||||
`Replied-to/<address>` label. Sending is a deliberate UI action with a
|
||||
confirmation — there is no auto-send (§10). The **rules editor** (`/rules`)
|
||||
saves and versions the plain-text rules that JEV and the reply model read.
|
||||
**Unsubscribe detection** (`/unsubscribe`) finds RFC 2369/8058 links and body
|
||||
links, keeps a domain ignore list, and records what Sam marks — it **never
|
||||
follows a link**. Every action, including drafts, sends, rules edits, and
|
||||
unsubscribe marks, is appended to `actions_log` (FR-13). **Phase 7** adds the
|
||||
daily **summary** (`-summary`, `-summary-send`; delivered by email through
|
||||
Apprise) and the read-only **Hub API** (`/capabilities`, `/ask`, `/notify`).
|
||||
**Retention** (AGENTS.md §7) is enforced by the bounded `-retain` job: it clears
|
||||
message bodies older than one month, keeps metadata, and caps the append-only
|
||||
`actions_log`; see [`docs/retention.md`](docs/retention.md). Phase evidence:
|
||||
[`docs/phase7-summary-hub.md`](docs/phase7-summary-hub.md),
|
||||
[`docs/phase6-unsubscribe.md`](docs/phase6-unsubscribe.md),
|
||||
[`docs/phase5-replies.md`](docs/phase5-replies.md),
|
||||
[`docs/phase4-triage.md`](docs/phase4-triage.md), and
|
||||
[`docs/phase8-documentation.md`](docs/phase8-documentation.md).
|
||||
|
||||
## Layout
|
||||
|
||||
@@ -52,6 +77,10 @@ internal/unsubscribe/ RFC 2369/8058 + body unsubscribe-link detection (no netw
|
||||
internal/version/ build metadata (set via -ldflags)
|
||||
web/static/ embedded design tokens, Inter fonts, htmx, app.css
|
||||
web/templates/ embedded server-rendered HTML
|
||||
docs/ phase evidence, retention, AI context, map, diagrams
|
||||
docs/outline/ AI-context documents (system, config, code, runbook)
|
||||
docs/archify/ Archify JSON spec for the architecture map
|
||||
docs/diagrams/ rendered Mermaid PNG
|
||||
Dockerfile multi-stage, CGO-free build
|
||||
docker-compose.yml this project's own container and image
|
||||
```
|
||||
@@ -280,6 +309,12 @@ Caddy on `.35` proxies `mail.lab.audasmedia.com.au` to this port.
|
||||
| `POST` | `/unsubscribe/ignore` | session + CSRF | Adds a domain to the ignore list |
|
||||
| `POST` | `/unsubscribe/unignore` | session + CSRF | Removes a domain record |
|
||||
| `POST` | `/unsubscribe/mark` | session + CSRF + confirm | Records a domain for unsubscribe; never contacts the link |
|
||||
| `GET` | `/reports` | session | Reports screen: build, send, and delete a daily summary (FR-10) |
|
||||
| `POST` | `/reports/generate` | session + CSRF | Builds and stores today's summary; sends nothing |
|
||||
| `POST` | `/reports/send` | session + CSRF + confirm | Delivers today's summary by email via Apprise |
|
||||
| `POST` | `/reports/delete` | session + CSRF | Deletes a stored summary |
|
||||
| `GET` | `/capabilities` | Hub bearer | Hub capability list (FR-12) |
|
||||
| `POST` | `/ask` | Hub bearer | Read-only short answer (FR-12); never writes |
|
||||
| `GET` | `/static/…` | public | Embedded `tokens.css`, `app.css`, Inter fonts, `htmx.min.js` |
|
||||
|
||||
Unauthenticated requests to `/` and `/partials/…` redirect to `/login?next=…`.
|
||||
@@ -300,3 +335,24 @@ folders; migration v5 adds `messages.message_id_header` (reply threading) and
|
||||
`drafts.sent_at`; migration v6 adds `messages.list_unsubscribe` and
|
||||
`messages.list_unsubscribe_post` and extends `unsubscribe` with `url` and
|
||||
`updated_at`.
|
||||
|
||||
## Documentation
|
||||
|
||||
Phase 8 recorded the project in five places.
|
||||
|
||||
| Surface | Location |
|
||||
|---|---|
|
||||
| Gitea | This README, `docs/phaseN-*.md`, `docs/outline/`, `docs/email-agent-architecture.mmd`, `docs/email-agent-map.html` |
|
||||
| Obsidian | Note `Email Agent — Family Inbox Triage` in `010 inbox` on `.27` (the sorter files it) |
|
||||
| Outline | Collection `Email Agent` (`00-index`, system overview, config, code map, runbook) |
|
||||
| Vikunja | Project `Email Agent` (human milestones) |
|
||||
| Map | `central_ai_llm_master/docs/hub-architecture-map.html` and this repo's map, published to <https://maps.lab.audasmedia.com.au/email_agent/docs/> |
|
||||
|
||||
Rebuild the map:
|
||||
|
||||
```sh
|
||||
mmdc -i docs/email-agent-architecture.mmd -o docs/diagrams/email-agent-architecture.png --scale 2 -b white
|
||||
~/.agents/skills/project-docs/scripts/publish-maps.sh /home/sam/paseo/projects/email_agent
|
||||
```
|
||||
|
||||
See [`docs/phase8-documentation.md`](docs/phase8-documentation.md) for the evidence.
|
||||
|
||||
Reference in New Issue
Block a user