1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//! Mail schema: RFC 5322-shaped email messages stored as tribles.
//!
//! Used by `mail.rs` (the faculty CLI). Decomposes incoming and
//! outgoing email into individual triblespace attributes so
//! queries are native pile patterns (joins on sender/recipient,
//! range scans on `sent_at`, BM25 search over body/subject,
//! thread walks via `in_reply_to+` and `references` graph edges).
//!
//! Mail entities use **deterministic ids derived from
//! `blake3(Message-Id).first 16 bytes`** — `in_reply_to` and
//! `references` GenIds point at predicted entity ids, so a
//! thread reference resolves whether or not the referenced
//! message is in our pile yet. When that message arrives later
//! (via a separate fetch, forward, or backup pull), its entity
//! materializes at the predicted id and the link goes live with
//! no patching.
//!
//! Attachments live in the `files` faculty (`KIND_FILE`,
//! `file::content` / `file::name` / `file::mime`); the mail
//! message references them via `mail::attachment: GenId` so
//! attachment dedup (BLAKE3 over file bytes) is automatic
//! across mail and the rest of the pile.
//!
//! Spam is a kind tag (`metadata::tag: &KIND_SPAM`) rather than
//! a boolean attribute — matches the canonical kind-marker
//! convention and lets manual reclassification stay
//! append-only-safe.
use id_hex;
use *;
pub const DEFAULT_BRANCH: &str = "mail";
/// Marks an entity as an RFC 5322-shaped mail message.
pub const KIND_MESSAGE: Id = id_hex!;
/// Tag marker applied via `metadata::tag` to messages classified
/// as spam (typically because the inbound mail carried
/// `X-Spam-Status: Yes`). Messages tagged this way are filtered
/// out of `mail list` / `mail today` / etc. by default; pass
/// `--spam` or `--all` to surface them.
pub const KIND_SPAM: Id = id_hex!;
/// Tag marker for outbound messages that haven't been transmitted
/// yet. `mail draft` mints a KIND_DRAFT entity with all the
/// normal `mail::*` attributes (subject, body, to, cc, bcc); a
/// successful `mail send` adds the KIND_MESSAGE tag and the
/// send-time facts (`sent_at`, `raw`) without dropping
/// KIND_DRAFT — so the history "this used to be a draft, then
/// sent at X" is preserved.
///
/// Send is gated on a linked `decide::KIND_DECISION` (via
/// `decide::about: <draft-id>`) being resolved.
pub const KIND_DRAFT: Id = id_hex!;
/// Message attributes — one per RFC 5322 header field we care
/// about, plus the original raw bytes for round-trip fidelity.