@bobfrankston/mailx-settings 0.1.35 → 0.1.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/annotation-registry.md +74 -0
- package/package.json +3 -3
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Annotation registry — companion annotator for imail (design sketch)
|
|
2
|
+
|
|
3
|
+
*Status: DRAFT 2026-07-16 — captured from discussion; Bob thinking it over. TODO item C155.*
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
A companion app annotates each letter **before** sorting. imail's sorter (and any
|
|
8
|
+
other consumer — rmfmail UI, agents, future tools) reads the annotations and acts.
|
|
9
|
+
The mechanism should be general — not private to imail the way its `ai/` cache is.
|
|
10
|
+
|
|
11
|
+
## Decision so far: keywords on the message + a shared JSON registry
|
|
12
|
+
|
|
13
|
+
Two-layer design, no shared database required:
|
|
14
|
+
|
|
15
|
+
1. **Data plane — tags on the message itself.** IMAP keywords (core RFC 3501,
|
|
16
|
+
not Dovecot-specific: any server advertising `\*` in PERMANENTFLAGS). The
|
|
17
|
+
message carries its own annotations; they survive folder moves; IMAP STORE is
|
|
18
|
+
atomic per message so concurrency is the server's problem, already solved.
|
|
19
|
+
Provider mapping for the same concept:
|
|
20
|
+
| Provider | Mechanism |
|
|
21
|
+
|---|---|
|
|
22
|
+
| Dovecot / Cyrus / Fastmail / iCloud / Yahoo IMAP | user keywords (atoms) |
|
|
23
|
+
| Gmail | API labels (Gmail IMAP ignores custom keywords) |
|
|
24
|
+
| Outlook / Graph | categories |
|
|
25
|
+
| JMAP | keywords (unified with IMAP's by design) |
|
|
26
|
+
|
|
27
|
+
2. **Vocabulary plane — one shared JSON registry** (`annotations.jsonc`, draft
|
|
28
|
+
next to this doc) with MCP-tool-style entries per keyword: `label`,
|
|
29
|
+
`description`, `whenToApply`, `exclusiveGroup`, `setBy`, `sortAction`.
|
|
30
|
+
The registry does triple duty:
|
|
31
|
+
- the AI annotator's prompt is generated from `description` / `whenToApply`
|
|
32
|
+
(same way MCP tool descriptions steer an agent);
|
|
33
|
+
- the sorter maps keyword → action from `sortAction`;
|
|
34
|
+
- UIs (rmfmail chips, Thunderbird tags) get display names from `label`.
|
|
35
|
+
Adding a category = editing one file. No schema migration, no API change.
|
|
36
|
+
|
|
37
|
+
## Constraints / cautions
|
|
38
|
+
|
|
39
|
+
- **Keyword budget**: Dovecot on maildir caps keywords ~26/mailbox (filename
|
|
40
|
+
letters). Registry stays small and curated; `exclusiveGroup` keeps categories
|
|
41
|
+
mutually exclusive instead of accreting.
|
|
42
|
+
- **Atoms only**: no spaces, ASCII, prefix everything `im_` so the vocabulary
|
|
43
|
+
can't collide with `$Junk`, `$Forwarded`, etc.
|
|
44
|
+
- **Tags, not key-value**: scores get bucketed (`im_spam_high`); anything
|
|
45
|
+
non-enumerable (extracted dates, reasoning text, summaries) does NOT fit.
|
|
46
|
+
If rich values are needed later, a sidecar store comes back *only for that
|
|
47
|
+
residue* — the keyword layer stays as the interoperable spine. (imail's
|
|
48
|
+
`.ics` writer is precedent: rich results can also just be files.)
|
|
49
|
+
- **Registry distribution**: share it the way accounts.jsonc is shared — GDrive
|
|
50
|
+
via API with a local cache, never a file on a network path. Slots into
|
|
51
|
+
rmfmail's existing config-editor/watch machinery; imail (self-contained by
|
|
52
|
+
policy) keeps its own cached copy.
|
|
53
|
+
- **Shared SQLite over SMB is ruled out** (WAL needs shared memory; SMB locking
|
|
54
|
+
corrupts). If a shared rich store is ever needed: a small annotation service
|
|
55
|
+
owning WAL SQLite behind HTTP/MCP (the rmfmail-daemon pattern), or libSQL
|
|
56
|
+
embedded replicas for multi-machine.
|
|
57
|
+
|
|
58
|
+
## Fit with existing TODO items
|
|
59
|
+
|
|
60
|
+
- **Q113 / Q113-AI** (per-message metadata shape): this design answers the
|
|
61
|
+
cross-app half — message-attached keywords + registry. A local
|
|
62
|
+
`message_meta` table remains a possible rmfmail-internal cache/residue store.
|
|
63
|
+
- **Q103-AI / C39 / P19** (rules engine + screener): `sortAction` in the
|
|
64
|
+
registry is a candidate rule shape; imail experiments feed this directly.
|
|
65
|
+
|
|
66
|
+
## Open questions for Bob
|
|
67
|
+
|
|
68
|
+
1. Starter vocabulary — which categories actually earn one of the ~26 slots?
|
|
69
|
+
2. Does the annotator mirror keywords → Gmail labels / Graph categories from
|
|
70
|
+
day one, or Dovecot-only first (bobma is the hot path)?
|
|
71
|
+
3. Where does the annotator run — IDLE-driven daemon on new mail (before
|
|
72
|
+
imail's scheduled pass), or a stage inside imail's own loop?
|
|
73
|
+
4. Should rmfmail render `im_*` keywords as chips in the message list (it
|
|
74
|
+
already syncs them in `flags_json` — display-only change)?
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/mailx-settings",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.36",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
},
|
|
18
18
|
"license": "ISC",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@bobfrankston/mailx-types": "^0.1.
|
|
20
|
+
"@bobfrankston/mailx-types": "^0.1.25",
|
|
21
21
|
"jsonc-parser": "^3.3.1"
|
|
22
22
|
},
|
|
23
23
|
"repository": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
".transformedSnapshot": {
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@bobfrankston/mailx-types": "^0.1.
|
|
36
|
+
"@bobfrankston/mailx-types": "^0.1.25",
|
|
37
37
|
"jsonc-parser": "^3.3.1"
|
|
38
38
|
}
|
|
39
39
|
}
|