@bobfrankston/mailx-settings 0.1.35 → 0.1.37

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.
@@ -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.35",
3
+ "version": "0.1.37",
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.24",
20
+ "@bobfrankston/mailx-types": "^0.1.26",
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.24",
36
+ "@bobfrankston/mailx-types": "^0.1.26",
37
37
  "jsonc-parser": "^3.3.1"
38
38
  }
39
39
  }