blob: 5f0df99886e110b0971c0a8076e22668a1c9af3f [file] [view]
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Mail-source adapter — IMAP (stub)](#mail-source-adapter--imap-stub)
- [Capability claim](#capability-claim)
- [Auth + setup](#auth--setup)
- [Threading model](#threading-model)
- [What an adopter declares in `project.md`](#what-an-adopter-declares-in-projectmd)
- [Why this is a stub](#why-this-is-a-stub)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Mail-source adapter — IMAP (stub)
Reference adapter for a generic IMAP mailbox as a backend for the
`security-issue-import` family of skills. **Stub status** — this
document describes the contract; the concrete CLI / MCP wiring is
TBD and will land when an adopter actually wires IMAP in. The
contract here lets that adopter know *what* they need to provide
without re-deriving it from scratch.
See [`../contract.md`](../contract.md) for the abstract
mail-source-backend operations + capability matrix + adopter
resolution rules this adapter conforms to.
## Capability claim
| Operation | Supported? | Notes |
|---|:---:|---|
| `list_recent_threads(list, since)` | ✓ | `IMAP SEARCH SINCE <date>` against the inbox / `<security-list>` subfolder |
| `read_thread(thread_id)` | ✓ | Fetch all messages whose `References:` / `In-Reply-To:` chain reaches the thread root; thread ID = root Message-ID |
| `list_drafts(thread_id)` | depends | Only if the IMAP server exposes the `Drafts` mailbox writably to the agent's account. Many corporate IMAPs do; many shared role mailboxes don't |
| `list_sent_since(thread_id, since)` | ✓ | `IMAP SEARCH` against the `Sent` mailbox filtering on the thread root's Message-ID in `In-Reply-To:` / `References:` |
| `create_draft(thread_id, body, …)` | depends | Same gating as `list_drafts` — the agent's IMAP account needs `INSERT` rights on the `Drafts` mailbox. Subject and threading headers are set per [`../../gmail/threading.md`](../../gmail/threading.md) (the threading rule is shared across backends) |
| `thread_url(thread_id)` | ✓ (best-effort) | If the project has a public mailing-list archive (PonyMail, Pipermail, hyperkitty), construct the deep-link URL from the Message-ID per the archive's template. If there is no public archive, return a `imap://<host>/<mailbox>;UID=<n>` URL that only works for someone with the same IMAP credentials |
| `thread_id_kind` | `rfc5322-message-id` | RFC-5322 `Message-ID` of the thread root |
## Auth + setup
An adopter wiring IMAP needs to declare:
1. **Server connection** — host, port, TLS preference, server-side
capabilities the agent will rely on (`IDLE`, `MOVE`, `UIDPLUS`).
2. **Account** — the IMAP user the agent authenticates as. For a
shared role mailbox (security-triage@example.org) prefer an
app-password / service-account credential so it can be rotated
without disrupting individual triagers.
3. **Folder layout** — the inbox path for `<security-list>`, the
sent path, the drafts path (or `null` to declare the drafts ops
unsupported).
4. **Credential storage** — where the agent reads credentials from.
The framework convention is the same shell-env / secret-manager
pattern other adapters use (see
[`../../gmail/oauth-draft/README.md`](../../gmail/oauth-draft/README.md)
as a reference for how a credential lifecycle is documented).
## Threading model
IMAP servers don't have a native "thread" concept — the client
reconstructs threads from `References:` / `In-Reply-To:` chains.
The adapter MUST canonicalise on the **root Message-ID** as the
thread identifier (not the most recent message, not a server-side
folder UID, which can change). This matches the contract's
`thread_id_kind: rfc5322-message-id` so the tracker can store a
stable identifier across reconnects, folder moves, and server
migrations.
## What an adopter declares in `project.md`
```markdown
## Mail sources
| Backend | Role | Mandatory | Notes |
|---|---|---|---|
| `imap` | primary | yes | Subscribed to `security@example.org` via the team mailbox; drafts via Sent-as |
```
…plus an `imap_*` section under *Mail sources* documenting the
host / account / folders / credential path. Use the same shape the
other backends in `<project-config>/project.md` use for their
per-tool config (see the *Gmail and PonyMail* section in the
template for the pattern).
## Why this is a stub
The reference adopter (`airflow-s` / `apache-airflow`) does not
currently use IMAP — Gmail covers the primary path and PonyMail
covers the archive backstop. The stub exists so an adopter that
*does* live on a corporate IMAP (or a self-hosted Postfix +
Dovecot setup) can declare it as the primary backend without
authoring the contract from scratch. When the first adopter wires
it in, the concrete CLI / MCP wiring lands in this directory
alongside this README.