@remit/api-openapi-types 0.0.79 → 0.0.81

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.
Files changed (2) hide show
  1. package/package.json +4 -1
  2. package/types.d.ts +351 -272
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "@remit/api-openapi-types",
3
- "version": "0.0.79",
3
+ "version": "0.0.81",
4
4
  "type": "module",
5
5
  "main": "types.d.ts",
6
6
  "types": "types.d.ts",
7
+ "dependencies": {
8
+ "openapi-client-axios": "^7.9.1"
9
+ },
7
10
  "license": "MIT",
8
11
  "publishConfig": {
9
12
  "access": "public"
package/types.d.ts CHANGED
@@ -53,6 +53,10 @@ writer can reach is a vocabulary that lies about what the field means.
53
53
  `MissingEnvelope` is absent for the same reason: see QuarantineFailureStage.
54
54
  */
55
55
  export type QuarantineFailureCode = "UnknownCharset" | "UnreadableBody";
56
+ /**
57
+ * The sync step a message failed at.
58
+ */
59
+ export type SyncWarningStage = "Header" | "Body";
56
60
  /**
57
61
  * Lifecycle state of an account configuration
58
62
  */
@@ -134,7 +138,7 @@ current enum emitter anyway, so the wire contract uses the bare form.
134
138
  */
135
139
  export type FilterMatchOperator = "And" | "Or";
136
140
  /**
137
- * Message attribute a FilterClause matches against — RFC 031's Tier 0 literal predicates plus the RFC 038 D2 additions (list membership and sender domain). Every member is matched vector-free at index time and in the back-apply corpus projection.
141
+ * Message attribute a FilterClause matches against — RFC 031's Tier 0 literal predicates plus the RFC 038 D2 additions (list membership and sender domain). Every member is matched at index time and in the back-apply corpus projection.
138
142
  */
139
143
  export type FilterClauseField = "From" | "Subject" | "HasWords" | "ListId" | "FromDomain";
140
144
  /**
@@ -220,10 +224,6 @@ explained to the user as a failed delete.
220
224
  * Actionable placement verdict — the direction Remit decided to move a message. `leave` is not represented: a left-in-place verdict means the placement sub-model is absent.
221
225
  */
222
226
  export type PlacementAction = "MoveToInbox" | "MoveToJunk";
223
- /**
224
- * Allowed chunk types that may be the best match for a semantic-search hit
225
- */
226
- export type SemanticSearchChunkType = "sender" | "recipient" | "subject" | "attachment" | "body" | "entities";
227
227
  /**
228
228
  * Status of an outbox message in the send queue
229
229
  */
@@ -348,6 +348,10 @@ distinguishable from a network failure without parsing prose.
348
348
  * Which piece of configuration a still-unbound folder reference belongs to. A mailbox id is regenerated by every discovery, so an imported file names folders by IMAP path and the binder writes the row once a path resolves.
349
349
  */
350
350
  export type ConfigImportRefKind = "FolderRole" | "MailboxOverride" | "FilterAction";
351
+ /**
352
+ * Whether sync still retries a warned message. Derived from stage and attempts, never stored.
353
+ */
354
+ export type SyncWarningState = "Retrying" | "GaveUp";
351
355
  /**
352
356
  * Explicit state engine for a pending placement-move marker (issue #1271, epic #1281). Recovery keys off this field, not control-flow inference: a redelivered/retried call drives a marker forward from whichever state it is actually in, rather than re-deriving intent by comparing the message's current location.
353
357
  */
@@ -679,14 +683,13 @@ version it now has. `code` is `precondition_failed`.
679
683
  details?: Record;
680
684
  }
681
685
  /**
682
- * The same flat 409 body, with the two codes this endpoint can answer with.
683
-
684
- `code: "folder_role_unresolved"` — as everywhere else, with `details` carrying `role`, `accountId` and `reason`.
685
-
686
- `code: "message_placement_unsettled"` — as `MessagePlacementConflict`, with `details` carrying `accountId`, `messageId` and `reason`.
686
+ * No message answers to this id, or the caller may not learn that one does.
687
+ `code` is `not_found`, or `message_gone_from_server` when the mail server no
688
+ longer holds the message at its UID — another client expunged it or moved it
689
+ away before its body was stored. That answer carries `details.messageId`.
687
690
  */
688
- export interface DeleteMessagesConflict {
689
- statusCode: 409;
691
+ export interface MessageNotFoundError {
692
+ statusCode: 404;
690
693
  /**
691
694
  * Stable token naming the refusal. Branch on this, never on `message`.
692
695
  */
@@ -720,6 +723,28 @@ version it now has. `code` is `precondition_failed`.
720
723
  */
721
724
  details?: Record;
722
725
  }
726
+ /**
727
+ * The same flat 409 body, with the two codes this endpoint can answer with.
728
+
729
+ `code: "folder_role_unresolved"` — as everywhere else, with `details` carrying `role`, `accountId` and `reason`.
730
+
731
+ `code: "message_placement_unsettled"` — as `MessagePlacementConflict`, with `details` carrying `accountId`, `messageId` and `reason`.
732
+ */
733
+ export interface DeleteMessagesConflict {
734
+ statusCode: 409;
735
+ /**
736
+ * Stable token naming the refusal. Branch on this, never on `message`.
737
+ */
738
+ code: string;
739
+ /**
740
+ * Human-readable error message
741
+ */
742
+ message: string;
743
+ /**
744
+ * Additional error details
745
+ */
746
+ details?: Record;
747
+ }
723
748
  export interface AmazonApiGatewayIntegration {
724
749
  type: "aws_proxy";
725
750
  httpMethod: "POST";
@@ -910,13 +935,21 @@ version it now has. `code` is `precondition_failed`.
910
935
  errorMessage?: string;
911
936
  }
912
937
  /**
913
- * Everything quarantined for the current user, newest first. The list is small by design — a mailbox with a growing quarantine list is a bug being reported, not a page to paginate.
938
+ * Everything quarantined for the current user, newest first, beside the sync warnings that have failed enough rounds to surface. The quarantine list is small by design — a mailbox with a growing quarantine list is a bug being reported, not a page to paginate.
914
939
  */
915
940
  export interface QuarantineListResponse {
916
941
  /**
917
942
  * Quarantined messages, newest first.
918
943
  */
919
944
  entries: QuarantineResponse[];
945
+ /**
946
+ * The 200 newest sync warnings that have failed at least BODY_SYNC_MAX_ATTEMPTS rounds, newest first. One failing server quirk writes a row per message, so the list is capped.
947
+ */
948
+ warnings: SyncWarningResponse[];
949
+ /**
950
+ * Every sync warning at or past the attempt threshold, counting those beyond the cap on `warnings`.
951
+ */
952
+ warningsTotal: number;
920
953
  }
921
954
  /**
922
955
  * A message the sync path could not apply, set aside so the mailbox cursor can
@@ -1141,6 +1174,93 @@ never from a raw content-type line — parameters carry `name=` and
1141
1174
  createdAt: number;
1142
1175
  updatedAt: number;
1143
1176
  }
1177
+ /**
1178
+ * A message that failed to sync and was not set aside (issue #1400).
1179
+
1180
+ A warning only observes: it never filters a uid out of a round or moves a
1181
+ cursor. Each failure raises `attempts` on one row, and the row is deleted
1182
+ when the message later syncs. Whether a row is retrying or has given up is
1183
+ derived from `stage` and `attempts`, never stored.
1184
+ */
1185
+ export interface SyncWarning {
1186
+ /**
1187
+ * Deterministic v5 identity derived from accountId, mailboxId, uidValidity, uid and stage.
1188
+ */
1189
+ syncWarningId: UUID;
1190
+ /**
1191
+ * Owning account configuration — the user.
1192
+ */
1193
+ accountConfigId: UUID;
1194
+ /**
1195
+ * Mail account the message arrived on.
1196
+ */
1197
+ accountId: UUID;
1198
+ /**
1199
+ * Mailbox the message arrived in.
1200
+ */
1201
+ mailboxId: UUID;
1202
+ /**
1203
+ * UIDVALIDITY of the mailbox when the message failed. Only uidValidity + uid names a message forever (RFC 9051 2.3.1.1).
1204
+ */
1205
+ uidValidity: number;
1206
+ /**
1207
+ * The IMAP uid that failed.
1208
+ */
1209
+ uid: number;
1210
+ /**
1211
+ * The sync step the message failed at.
1212
+ */
1213
+ stage: SyncWarningStage;
1214
+ /**
1215
+ * Rounds that failed on this message so far.
1216
+ */
1217
+ attempts: number;
1218
+ /**
1219
+ * Epoch millis of the first failure.
1220
+ */
1221
+ createdAt: number;
1222
+ }
1223
+ /**
1224
+ * One sync warning as the settings surface sees it.
1225
+ */
1226
+ export interface SyncWarningResponse {
1227
+ /**
1228
+ * Deterministic v5 identity derived from accountId, mailboxId, uidValidity, uid and stage.
1229
+ */
1230
+ syncWarningId: UUID;
1231
+ /**
1232
+ * Owning account configuration — the user.
1233
+ */
1234
+ accountConfigId: UUID;
1235
+ /**
1236
+ * Mail account the message arrived on.
1237
+ */
1238
+ accountId: UUID;
1239
+ /**
1240
+ * Mailbox the message arrived in.
1241
+ */
1242
+ mailboxId: UUID;
1243
+ /**
1244
+ * UIDVALIDITY of the mailbox when the message failed. Only uidValidity + uid names a message forever (RFC 9051 2.3.1.1).
1245
+ */
1246
+ uidValidity: number;
1247
+ /**
1248
+ * The IMAP uid that failed.
1249
+ */
1250
+ uid: number;
1251
+ /**
1252
+ * The sync step the message failed at.
1253
+ */
1254
+ stage: SyncWarningStage;
1255
+ /**
1256
+ * Rounds that failed on this message so far.
1257
+ */
1258
+ attempts: number;
1259
+ /**
1260
+ * Epoch millis of the first failure.
1261
+ */
1262
+ createdAt: number;
1263
+ }
1144
1264
  /**
1145
1265
  * Full configuration description including accounts
1146
1266
  */
@@ -1154,13 +1274,13 @@ never from a raw content-type line — parameters carry `name=` and
1154
1274
  */
1155
1275
  accounts: AccountResponse[];
1156
1276
  /**
1157
- * Absent unless a configuration import is still waiting on folders IMAP has not produced yet (#1021). Nothing polls a separate route for it.
1277
+ * The commit the serving build was made from, or `dev` for a build made outside CI and git
1158
1278
  */
1159
- pendingImport?: PendingConfigImport;
1279
+ buildCommit: string;
1160
1280
  /**
1161
- * Whether this instance stores a vector for every message — SEARCH_EMBEDDING_PROVIDER is anything but `off`. False is a setting an operator turns on (`remit semantic on`), not a failure: the Organize semantic widen and semantic (anchor) filters read stored vectors and have none, so they render an off state rather than an empty result. It rides the config read because it is a property of the deployment, not of a query (#1068).
1281
+ * Absent unless a configuration import is still waiting on folders IMAP has not produced yet (#1021). Nothing polls a separate route for it.
1162
1282
  */
1163
- semanticSearchEnabled: boolean;
1283
+ pendingImport?: PendingConfigImport;
1164
1284
  }
1165
1285
  /**
1166
1286
  * Configuration container for user accounts. Groups multiple IMAP accounts under a single user.
@@ -1968,6 +2088,16 @@ with `onExisting: merge` to upsert instead.
1968
2088
  */
1969
2089
  displayNameOverride?: String256;
1970
2090
  }
2091
+ /**
2092
+ * A page of an account's mailboxes.
2093
+ */
2094
+ export interface MailboxListResponse {
2095
+ /**
2096
+ * Opaque, server-minted cursor: absent means the first (or last) page, present means resume from here. Echo it back unchanged to fetch the next page. Every listing endpoint that accepts it rejects a token it cannot decode with 400 ValidationError rather than silently restarting from the first page (#136, #172).
2097
+ */
2098
+ continuationToken?: String800;
2099
+ items: MailboxResponse[];
2100
+ }
1971
2101
  /**
1972
2102
  * Input for creating a new mailbox
1973
2103
  */
@@ -2008,14 +2138,10 @@ with `onExisting: merge` to upsert instead.
2008
2138
  mailboxId: string | any;
2009
2139
  }
2010
2140
  /**
2011
- * A standing user rule that matches messages by literal clauses and/or a
2012
- semantic anchor (RFC 031, RFC 034). One row per **standing** filter —
2013
- `Standing` or `Temporary` scope only. The one-time "just these" / "all like
2014
- these" batch actions never create one (RFC 034 recap).
2015
-
2016
- Kept lean: the semantic anchor payload lives on the sibling `FilterAnchor`
2017
- row (RFC 034 Decision 2.3) so listing/evaluating filters never pulls vector
2018
- data through `byAccountAndState`.
2141
+ * A standing user rule that matches messages by literal clauses (RFC 031,
2142
+ RFC 034). One row per **standing** filter — `Standing` or `Temporary` scope
2143
+ only. The one-time "just these" / "all like these" batch actions never
2144
+ create one (RFC 034 recap).
2019
2145
  */
2020
2146
  export interface Filter {
2021
2147
  /**
@@ -2031,7 +2157,7 @@ data through `byAccountAndState`.
2031
2157
  */
2032
2158
  name: String256;
2033
2159
  /**
2034
- * Standing (permanent) or Temporary (expires). Governs whether expiresAt/ttl are present (RFC 034 Decision 1). Mutable on update (reader #266): switching scope re-derives ttl and re-evaluates state from expiresAt, and bumps ruleChangedAt so a lapsed filter's back-application can be offered again. The semantic anchor stays immutable regardless — repointing it would silently change what a saved filter matches with nothing visible changing, which deserves a new filter instead.
2160
+ * Standing (permanent) or Temporary (expires). Governs whether expiresAt/ttl are present (RFC 034 Decision 1). Mutable on update (reader #266): switching scope re-derives ttl and re-evaluates state from expiresAt, and bumps ruleChangedAt so a lapsed filter's back-application can be offered again.
2035
2161
  */
2036
2162
  scope: FilterScope;
2037
2163
  /**
@@ -2050,24 +2176,20 @@ data through `byAccountAndState`.
2050
2176
  * Why this filter is Disabled; `None` whenever state is not Disabled. Written together with state, never on its own: turning a filter on clears it.
2051
2177
  */
2052
2178
  disabledReason: FilterDisabledReason;
2053
- /**
2054
- * Whether a sibling FilterAnchor row exists for this filter (RFC 034 Decision 2.3). Lets the index-time worker skip the FilterAnchor `get` entirely for purely-literal filters instead of probing for a row that may not exist.
2055
- */
2056
- hasAnchor: boolean;
2057
2179
  /**
2058
2180
  * Epoch seconds, written whenever the predicate, the action, the scope, or the expiry changes (reader #266) — never on a cosmetic rename. This is the broad "the user asserted something new about this rule" signal the settings UI uses to decide whether to re-offer a lapsed filter's back-application. It is deliberately NOT the precedence signal for the exclusive move action — see actionChangedAt for that (RFC 034 Decision 3.2, reader #384). Distinct from ElectroDB's own updatedAt, which bumps on any write.
2059
2181
  */
2060
2182
  ruleChangedAt: number;
2061
2183
  /**
2062
- * Epoch seconds, written only when the predicate (literalClauses, hasAnchor) or the action (actionLabelId, actionMailboxId) changes — never on scope, expiresAt, or a cosmetic rename. Backs most-recently-changed-filter-wins precedence for the exclusive move action (RFC 034 Decision 3.2). Split out from ruleChangedAt (reader #384): extending a filter's expiry or flipping its scope changes its lifecycle, not what it matches or does, so it must not promote the filter to move-winner.
2184
+ * Epoch seconds, written only when the predicate (literalClauses) or the action (actionLabelId, actionMailboxId) changes — never on scope, expiresAt, or a cosmetic rename. Backs most-recently-changed-filter-wins precedence for the exclusive move action (RFC 034 Decision 3.2). Split out from ruleChangedAt (reader #384): extending a filter's expiry or flipping its scope changes its lifecycle, not what it matches or does, so it must not promote the filter to move-winner.
2063
2185
  */
2064
2186
  actionChangedAt: number;
2065
2187
  /**
2066
- * How literalClauses combine. Meaningless when literalClauses is empty.
2188
+ * How literalClauses combine.
2067
2189
  */
2068
2190
  matchOperator: FilterMatchOperator;
2069
2191
  /**
2070
- * Literal from/subject/has-words predicate clauses (RFC 031). Empty when the filter relies solely on its semantic anchor (see hasAnchor).
2192
+ * Literal from/subject/has-words predicate clauses (RFC 031). A filter carries at least one.
2071
2193
  */
2072
2194
  literalClauses: FilterClause[];
2073
2195
  /**
@@ -2111,7 +2233,7 @@ data through `byAccountAndState`.
2111
2233
  */
2112
2234
  name: String256;
2113
2235
  /**
2114
- * Standing (permanent) or Temporary (expires). Governs whether expiresAt/ttl are present (RFC 034 Decision 1). Mutable on update (reader #266): switching scope re-derives ttl and re-evaluates state from expiresAt, and bumps ruleChangedAt so a lapsed filter's back-application can be offered again. The semantic anchor stays immutable regardless — repointing it would silently change what a saved filter matches with nothing visible changing, which deserves a new filter instead.
2236
+ * Standing (permanent) or Temporary (expires). Governs whether expiresAt/ttl are present (RFC 034 Decision 1). Mutable on update (reader #266): switching scope re-derives ttl and re-evaluates state from expiresAt, and bumps ruleChangedAt so a lapsed filter's back-application can be offered again.
2115
2237
  */
2116
2238
  scope: FilterScope;
2117
2239
  /**
@@ -2126,24 +2248,20 @@ data through `byAccountAndState`.
2126
2248
  * Why this filter is Disabled; `None` whenever state is not Disabled. Written together with state, never on its own: turning a filter on clears it.
2127
2249
  */
2128
2250
  disabledReason: FilterDisabledReason;
2129
- /**
2130
- * Whether a sibling FilterAnchor row exists for this filter (RFC 034 Decision 2.3). Lets the index-time worker skip the FilterAnchor `get` entirely for purely-literal filters instead of probing for a row that may not exist.
2131
- */
2132
- hasAnchor: boolean;
2133
2251
  /**
2134
2252
  * Epoch seconds, written whenever the predicate, the action, the scope, or the expiry changes (reader #266) — never on a cosmetic rename. This is the broad "the user asserted something new about this rule" signal the settings UI uses to decide whether to re-offer a lapsed filter's back-application. It is deliberately NOT the precedence signal for the exclusive move action — see actionChangedAt for that (RFC 034 Decision 3.2, reader #384). Distinct from ElectroDB's own updatedAt, which bumps on any write.
2135
2253
  */
2136
2254
  ruleChangedAt: number;
2137
2255
  /**
2138
- * Epoch seconds, written only when the predicate (literalClauses, hasAnchor) or the action (actionLabelId, actionMailboxId) changes — never on scope, expiresAt, or a cosmetic rename. Backs most-recently-changed-filter-wins precedence for the exclusive move action (RFC 034 Decision 3.2). Split out from ruleChangedAt (reader #384): extending a filter's expiry or flipping its scope changes its lifecycle, not what it matches or does, so it must not promote the filter to move-winner.
2256
+ * Epoch seconds, written only when the predicate (literalClauses) or the action (actionLabelId, actionMailboxId) changes — never on scope, expiresAt, or a cosmetic rename. Backs most-recently-changed-filter-wins precedence for the exclusive move action (RFC 034 Decision 3.2). Split out from ruleChangedAt (reader #384): extending a filter's expiry or flipping its scope changes its lifecycle, not what it matches or does, so it must not promote the filter to move-winner.
2139
2257
  */
2140
2258
  actionChangedAt: number;
2141
2259
  /**
2142
- * How literalClauses combine. Meaningless when literalClauses is empty.
2260
+ * How literalClauses combine.
2143
2261
  */
2144
2262
  matchOperator: FilterMatchOperator;
2145
2263
  /**
2146
- * Literal from/subject/has-words predicate clauses (RFC 031). Empty when the filter relies solely on its semantic anchor (see hasAnchor).
2264
+ * Literal from/subject/has-words predicate clauses (RFC 031). A filter carries at least one.
2147
2265
  */
2148
2266
  literalClauses: FilterClause[];
2149
2267
  /**
@@ -2160,12 +2278,8 @@ data through `byAccountAndState`.
2160
2278
  /**
2161
2279
  * Input for creating a filter (RFC 034). `ttl` is omitted — it is derived
2162
2280
  server-side from `expiresAt` when `scope` is `Temporary` (RFC 034 Decision
2163
- 1.3), never client-supplied. `state`, `hasAnchor`, `ruleChangedAt`, and
2164
- `filterId` are all server-derived and excluded by their Read-only visibility.
2165
-
2166
- When `anchorMessageId` is set, the server builds and persists the filter's
2167
- semantic anchor from that message's indexed vectors (RFC 034 Decision 2) and
2168
- sets `hasAnchor`. Absent for a purely-literal filter.
2281
+ 1.3), never client-supplied. `state`, `ruleChangedAt`, and `filterId` are
2282
+ all server-derived and excluded by their Read-only visibility.
2169
2283
  */
2170
2284
  export interface CreateFilterInput {
2171
2285
  /**
@@ -2173,7 +2287,7 @@ sets `hasAnchor`. Absent for a purely-literal filter.
2173
2287
  */
2174
2288
  name: String256;
2175
2289
  /**
2176
- * Standing (permanent) or Temporary (expires). Governs whether expiresAt/ttl are present (RFC 034 Decision 1). Mutable on update (reader #266): switching scope re-derives ttl and re-evaluates state from expiresAt, and bumps ruleChangedAt so a lapsed filter's back-application can be offered again. The semantic anchor stays immutable regardless — repointing it would silently change what a saved filter matches with nothing visible changing, which deserves a new filter instead.
2290
+ * Standing (permanent) or Temporary (expires). Governs whether expiresAt/ttl are present (RFC 034 Decision 1). Mutable on update (reader #266): switching scope re-derives ttl and re-evaluates state from expiresAt, and bumps ruleChangedAt so a lapsed filter's back-application can be offered again.
2177
2291
  */
2178
2292
  scope: FilterScope;
2179
2293
  /**
@@ -2181,11 +2295,11 @@ sets `hasAnchor`. Absent for a purely-literal filter.
2181
2295
  */
2182
2296
  expiresAt?: string;
2183
2297
  /**
2184
- * How literalClauses combine. Meaningless when literalClauses is empty.
2298
+ * How literalClauses combine.
2185
2299
  */
2186
2300
  matchOperator: FilterMatchOperator;
2187
2301
  /**
2188
- * Literal from/subject/has-words predicate clauses (RFC 031). Empty when the filter relies solely on its semantic anchor (see hasAnchor).
2302
+ * Literal from/subject/has-words predicate clauses (RFC 031). A filter carries at least one.
2189
2303
  */
2190
2304
  literalClauses: FilterClause[];
2191
2305
  /**
@@ -2196,10 +2310,6 @@ sets `hasAnchor`. Absent for a purely-literal filter.
2196
2310
  * Mailbox matched messages are moved into — exclusive action, since a message lives in exactly one mailbox (RFC 034 Decision 3.1). On conflict between filters, the one with the latest actionChangedAt wins. `"None"` means no move action.
2197
2311
  */
2198
2312
  actionMailboxId: string;
2199
- /**
2200
- * Anchor message for a semantic filter — provenance for the persisted anchor the server builds at save time (RFC 034 Decision 2.1). Absent for a purely-literal filter.
2201
- */
2202
- anchorMessageId?: UUID;
2203
2313
  }
2204
2314
  /**
2205
2315
  * Response body for POST /accounts/{accountId}/filters: the created filter, plus the back-apply job that runs it over the inbox.
@@ -2218,7 +2328,7 @@ sets `hasAnchor`. Absent for a purely-literal filter.
2218
2328
  */
2219
2329
  name: String256;
2220
2330
  /**
2221
- * Standing (permanent) or Temporary (expires). Governs whether expiresAt/ttl are present (RFC 034 Decision 1). Mutable on update (reader #266): switching scope re-derives ttl and re-evaluates state from expiresAt, and bumps ruleChangedAt so a lapsed filter's back-application can be offered again. The semantic anchor stays immutable regardless — repointing it would silently change what a saved filter matches with nothing visible changing, which deserves a new filter instead.
2331
+ * Standing (permanent) or Temporary (expires). Governs whether expiresAt/ttl are present (RFC 034 Decision 1). Mutable on update (reader #266): switching scope re-derives ttl and re-evaluates state from expiresAt, and bumps ruleChangedAt so a lapsed filter's back-application can be offered again.
2222
2332
  */
2223
2333
  scope: FilterScope;
2224
2334
  /**
@@ -2233,24 +2343,20 @@ sets `hasAnchor`. Absent for a purely-literal filter.
2233
2343
  * Why this filter is Disabled; `None` whenever state is not Disabled. Written together with state, never on its own: turning a filter on clears it.
2234
2344
  */
2235
2345
  disabledReason: FilterDisabledReason;
2236
- /**
2237
- * Whether a sibling FilterAnchor row exists for this filter (RFC 034 Decision 2.3). Lets the index-time worker skip the FilterAnchor `get` entirely for purely-literal filters instead of probing for a row that may not exist.
2238
- */
2239
- hasAnchor: boolean;
2240
2346
  /**
2241
2347
  * Epoch seconds, written whenever the predicate, the action, the scope, or the expiry changes (reader #266) — never on a cosmetic rename. This is the broad "the user asserted something new about this rule" signal the settings UI uses to decide whether to re-offer a lapsed filter's back-application. It is deliberately NOT the precedence signal for the exclusive move action — see actionChangedAt for that (RFC 034 Decision 3.2, reader #384). Distinct from ElectroDB's own updatedAt, which bumps on any write.
2242
2348
  */
2243
2349
  ruleChangedAt: number;
2244
2350
  /**
2245
- * Epoch seconds, written only when the predicate (literalClauses, hasAnchor) or the action (actionLabelId, actionMailboxId) changes — never on scope, expiresAt, or a cosmetic rename. Backs most-recently-changed-filter-wins precedence for the exclusive move action (RFC 034 Decision 3.2). Split out from ruleChangedAt (reader #384): extending a filter's expiry or flipping its scope changes its lifecycle, not what it matches or does, so it must not promote the filter to move-winner.
2351
+ * Epoch seconds, written only when the predicate (literalClauses) or the action (actionLabelId, actionMailboxId) changes — never on scope, expiresAt, or a cosmetic rename. Backs most-recently-changed-filter-wins precedence for the exclusive move action (RFC 034 Decision 3.2). Split out from ruleChangedAt (reader #384): extending a filter's expiry or flipping its scope changes its lifecycle, not what it matches or does, so it must not promote the filter to move-winner.
2246
2352
  */
2247
2353
  actionChangedAt: number;
2248
2354
  /**
2249
- * How literalClauses combine. Meaningless when literalClauses is empty.
2355
+ * How literalClauses combine.
2250
2356
  */
2251
2357
  matchOperator: FilterMatchOperator;
2252
2358
  /**
2253
- * Literal from/subject/has-words predicate clauses (RFC 031). Empty when the filter relies solely on its semantic anchor (see hasAnchor).
2359
+ * Literal from/subject/has-words predicate clauses (RFC 031). A filter carries at least one.
2254
2360
  */
2255
2361
  literalClauses: FilterClause[];
2256
2362
  /**
@@ -2272,7 +2378,7 @@ sets `hasAnchor`. Absent for a purely-literal filter.
2272
2378
  * Input for updating a filter (RFC 034, reader #266). The name, predicate,
2273
2379
  action, scope, and expiresAt are all updatable; `ttl` is always
2274
2380
  server-derived from `scope`/`expiresAt`, never client-supplied, and
2275
- `disabledReason`/`hasAnchor`/`ruleChangedAt`/`actionChangedAt`/`filterId` are
2381
+ `disabledReason`/`ruleChangedAt`/`actionChangedAt`/`filterId` are
2276
2382
  server-derived too. `state` takes `Active` or `Disabled`: the user turns a
2277
2383
  filter off or back on, and turning it on clears `disabledReason`. `Expired`
2278
2384
  is refused; the expiry is set through `scope`/`expiresAt`. A patch touching the predicate, the action, `scope`, or
@@ -2281,12 +2387,6 @@ Decision 3.2, reader #266). Only a patch touching the predicate or the
2281
2387
  action bumps `actionChangedAt`, the narrower signal exclusive-move
2282
2388
  precedence reads (reader #384) — a scope/expiresAt-only edit leaves it
2283
2389
  untouched.
2284
-
2285
- The semantic anchor has no field here at all — it is set once, from
2286
- `anchorMessageId`, only on `CreateFilterInput`. Repointing an anchor would
2287
- silently change what a saved filter matches with nothing visible changing;
2288
- that deserves a new filter, so the server rejects any attempt to smuggle an
2289
- anchor change through this body (reader #266).
2290
2390
  */
2291
2391
  export interface UpdateFilterInput {
2292
2392
  /**
@@ -2294,7 +2394,7 @@ anchor change through this body (reader #266).
2294
2394
  */
2295
2395
  name: String256;
2296
2396
  /**
2297
- * Standing (permanent) or Temporary (expires). Governs whether expiresAt/ttl are present (RFC 034 Decision 1). Mutable on update (reader #266): switching scope re-derives ttl and re-evaluates state from expiresAt, and bumps ruleChangedAt so a lapsed filter's back-application can be offered again. The semantic anchor stays immutable regardless — repointing it would silently change what a saved filter matches with nothing visible changing, which deserves a new filter instead.
2397
+ * Standing (permanent) or Temporary (expires). Governs whether expiresAt/ttl are present (RFC 034 Decision 1). Mutable on update (reader #266): switching scope re-derives ttl and re-evaluates state from expiresAt, and bumps ruleChangedAt so a lapsed filter's back-application can be offered again.
2298
2398
  */
2299
2399
  scope: FilterScope;
2300
2400
  /**
@@ -2306,11 +2406,11 @@ anchor change through this body (reader #266).
2306
2406
  */
2307
2407
  state: FilterState;
2308
2408
  /**
2309
- * How literalClauses combine. Meaningless when literalClauses is empty.
2409
+ * How literalClauses combine.
2310
2410
  */
2311
2411
  matchOperator: FilterMatchOperator;
2312
2412
  /**
2313
- * Literal from/subject/has-words predicate clauses (RFC 031). Empty when the filter relies solely on its semantic anchor (see hasAnchor).
2413
+ * Literal from/subject/has-words predicate clauses (RFC 031). A filter carries at least one.
2314
2414
  */
2315
2415
  literalClauses: FilterClause[];
2316
2416
  /**
@@ -2406,30 +2506,21 @@ anchor change through this body (reader #266).
2406
2506
  * The predicate + action for a one-time "all like these" back-apply (RFC 034
2407
2507
  recap, #1278). A distinct model, deliberately NOT a Filter: it carries no
2408
2508
  `scope`, `expiresAt`, or `name`, so it structurally cannot create a standing
2409
- rule. The anchor is derived transiently from `anchorMessageId`'s existing chunk
2410
- vectors at match time and never persisted as a FilterAnchor row.
2509
+ rule.
2411
2510
  */
2412
2511
  export interface OrganizeInput {
2413
2512
  /**
2414
- * Back-apply this standing filter instead of the predicate in this body. The server reads the filter's persisted predicate, action and FilterAnchor, runs the pass over the inbox, and skips a move another active filter outranks, as index time does. The predicate and action fields of this body are ignored when it is set.
2513
+ * Back-apply this standing filter instead of the predicate in this body. The server reads the filter's persisted predicate and action, runs the pass over the inbox, and skips a move another active filter outranks, as index time does. The predicate and action fields of this body are ignored when it is set.
2415
2514
  */
2416
2515
  filterId?: UUID;
2417
- /**
2418
- * Anchor message for the semantic half — "all like this one". Absent for a purely-literal back-apply. The anchor vector is pooled transiently from this message's indexed chunk vectors and never written to a FilterAnchor row.
2419
- */
2420
- anchorMessageId?: UUID;
2421
2516
  /**
2422
2517
  * How literalClauses combine. Meaningless when literalClauses is empty.
2423
2518
  */
2424
2519
  matchOperator: FilterMatchOperator;
2425
2520
  /**
2426
- * Literal from/subject/has-words clauses (RFC 031), reusing the Filter predicate shape. Empty when the back-apply relies solely on the semantic anchor.
2521
+ * Literal from/subject/has-words clauses (RFC 031), reusing the Filter predicate shape.
2427
2522
  */
2428
2523
  literalClauses: FilterClause[];
2429
- /**
2430
- * Cosine cut-off for the semantic match. Absent uses the server default (the same threshold the index-time filter pipeline applies).
2431
- */
2432
- similarityThreshold?: number;
2433
2524
  /**
2434
2525
  * Label applied to every matching message — additive action (RFC 034 Decision 3.1). The `"None"` sentinel means no label action.
2435
2526
  */
@@ -2465,14 +2556,6 @@ vectors at match time and never persisted as a FilterAnchor row.
2465
2556
  * Ids of the matching messages, bounded to the same cap the apply pass uses
2466
2557
  */
2467
2558
  messageIds: string[];
2468
- /**
2469
- * True when the semantic widen could not run because this deployment ships no vector pipeline (self-host without sqlite-vec / the embedding model). The matched set is then the literal matches only, or empty for an anchor-only predicate; literal search is unaffected. Absent on deployments where the widen ran.
2470
- */
2471
- semanticUnavailable?: boolean;
2472
- /**
2473
- * True when the widen ran but this account's semantic index held nothing to answer with — no vectors at all, or none yet for the anchor message. A zero count is then a fact about the index, which is still filling, rather than about the rule. Absent when the index answered.
2474
- */
2475
- semanticIndexEmpty?: boolean;
2476
2559
  }
2477
2560
  /**
2478
2561
  * An async "all like these" back-apply job (RFC 034 recap, #1278). Modeled on
@@ -2481,7 +2564,7 @@ to Running, then to Complete/Failed, self-reaping via the table-wide `ttl`.
2481
2564
 
2482
2565
  The predicate + action are snapshotted onto the row (the same fields as
2483
2566
  OrganizeInput) so the worker runs exactly what was requested. This job never
2484
- writes a Filter or FilterAnchor row — it is a single batch pass, nothing
2567
+ writes a Filter row — it is a single batch pass, nothing
2485
2568
  standing to persist.
2486
2569
  */
2487
2570
  export interface OrganizeJobRequest {
@@ -2505,10 +2588,6 @@ standing to persist.
2505
2588
  * The standing filter this job back-applies, or the `"None"` sentinel for an "all like these" pass. A sentinel, not an optional field, so the persisted entity has no optional attributes (RFC 032).
2506
2589
  */
2507
2590
  filterId: string;
2508
- /**
2509
- * Snapshot of the anchor message id, or the `"None"` sentinel for a purely-literal back-apply. A sentinel, not an optional field, so the persisted entity has no optional attributes (RFC 032).
2510
- */
2511
- anchorMessageId: string;
2512
2591
  /**
2513
2592
  * Snapshot of how literalClauses combine
2514
2593
  */
@@ -2517,10 +2596,6 @@ standing to persist.
2517
2596
  * Snapshot of the literal predicate clauses
2518
2597
  */
2519
2598
  literalClauses: FilterClause[];
2520
- /**
2521
- * Snapshot of the semantic cut-off applied for this run
2522
- */
2523
- similarityThreshold: number;
2524
2599
  /**
2525
2600
  * Snapshot of the additive label action, or `"None"`
2526
2601
  */
@@ -2582,10 +2657,6 @@ standing to persist.
2582
2657
  * The standing filter this job back-applies, or the `"None"` sentinel for an "all like these" pass. A sentinel, not an optional field, so the persisted entity has no optional attributes (RFC 032).
2583
2658
  */
2584
2659
  filterId: string;
2585
- /**
2586
- * Snapshot of the anchor message id, or the `"None"` sentinel for a purely-literal back-apply. A sentinel, not an optional field, so the persisted entity has no optional attributes (RFC 032).
2587
- */
2588
- anchorMessageId: string;
2589
2660
  /**
2590
2661
  * Snapshot of how literalClauses combine
2591
2662
  */
@@ -2594,10 +2665,6 @@ standing to persist.
2594
2665
  * Snapshot of the literal predicate clauses
2595
2666
  */
2596
2667
  literalClauses: FilterClause[];
2597
- /**
2598
- * Snapshot of the semantic cut-off applied for this run
2599
- */
2600
- similarityThreshold: number;
2601
2668
  /**
2602
2669
  * Snapshot of the additive label action, or `"None"`
2603
2670
  */
@@ -3649,7 +3716,7 @@ asking "is this slot free" never has to do the merging itself.
3649
3716
  */
3650
3717
  subject?: string;
3651
3718
  /**
3652
- * Normalized `List-Id` header value (bracketed identifier, case-folded), denormalized at body-sync so the back-apply corpus projection can match a `ListId` clause vector-free. Absent when the message carries no `List-Id` header or was body-synced before this field existed.
3719
+ * Normalized `List-Id` header value (bracketed identifier, case-folded), denormalized at body-sync so the back-apply corpus projection can match a `ListId` clause. Absent when the message carries no `List-Id` header or was body-synced before this field existed.
3653
3720
  */
3654
3721
  listId?: String256;
3655
3722
  /**
@@ -3885,6 +3952,16 @@ asking "is this slot free" never has to do the merging itself.
3885
3952
  */
3886
3953
  reportedAt: number;
3887
3954
  }
3955
+ /**
3956
+ * A page of thread messages.
3957
+ */
3958
+ export interface ThreadMessageListResponse {
3959
+ /**
3960
+ * Opaque, server-minted cursor: absent means the first (or last) page, present means resume from here. Echo it back unchanged to fetch the next page. Every listing endpoint that accepts it rejects a token it cannot decode with 400 ValidationError rather than silently restarting from the first page (#136, #172).
3961
+ */
3962
+ continuationToken?: String800;
3963
+ items: ThreadMessageResponse[];
3964
+ }
3888
3965
  /**
3889
3966
  * Aggregate response for the filterable thread listings — `searchThreads` and
3890
3967
  `listAllThreads`. Carries the matching rows (`items`), a pagination
@@ -3929,47 +4006,6 @@ page length presented as a total. A client with no number renders none.
3929
4006
  */
3930
4007
  count?: number;
3931
4008
  }
3932
- /**
3933
- * A single semantic-search hit. Display fields (fromName, subject, sentDate) are denormalized at index time and present for messages indexed after this feature was deployed. Older entries may omit them; clients should render a fallback when absent.
3934
- */
3935
- export interface SemanticSearchResult {
3936
- /**
3937
- * Matched message id
3938
- */
3939
- messageId: UUID;
3940
- /**
3941
- * Thread id the matched message belongs to
3942
- */
3943
- threadId: UUID;
3944
- /**
3945
- * Cosine similarity (or backend-equivalent) of the best matching chunk for this message; higher is more relevant
3946
- */
3947
- score: number;
3948
- /**
3949
- * Chunk type that produced the best match for this message
3950
- */
3951
- matchedChunkType: SemanticSearchChunkType;
3952
- /**
3953
- * All mailbox ids the matched message currently lives in
3954
- */
3955
- mailboxIds: UUID[];
3956
- /**
3957
- * Display name of the sender (From header). Present for messages indexed after display-field enrichment was deployed.
3958
- */
3959
- fromName?: string;
3960
- /**
3961
- * Message subject. Present for messages indexed after display-field enrichment was deployed.
3962
- */
3963
- subject?: string;
3964
- /**
3965
- * Sent date as Unix epoch seconds. Present for messages indexed after display-field enrichment was deployed.
3966
- */
3967
- sentDate?: number;
3968
- /**
3969
- * Header-derived category of the matched message. Present for messages indexed after category enrichment was deployed; older entries omit it.
3970
- */
3971
- category?: MessageCategory;
3972
- }
3973
4009
  /**
3974
4010
  * Input for creating an outbox message
3975
4011
  */
@@ -4281,6 +4317,16 @@ garbage, which is the only thing the sweep needs to know.
4281
4317
  */
4282
4318
  contentUrl: string;
4283
4319
  }
4320
+ /**
4321
+ * A page of the current account's outbox messages.
4322
+ */
4323
+ export interface OutboxMessageListResponse {
4324
+ /**
4325
+ * Opaque, server-minted cursor: absent means the first (or last) page, present means resume from here. Echo it back unchanged to fetch the next page. Every listing endpoint that accepts it rejects a token it cannot decode with 400 ValidationError rather than silently restarting from the first page (#136, #172).
4326
+ */
4327
+ continuationToken?: String800;
4328
+ items: OutboxMessageResponse[];
4329
+ }
4284
4330
  /**
4285
4331
  * Input for updating a draft outbox message
4286
4332
  */
@@ -4825,7 +4871,7 @@ either way and cannot tell which it received.
4825
4871
  /**
4826
4872
  * Core message entity. The combination of Mailbox.uidValidity + Message.uid uniquely identifies a message forever per RFC 9051 Section 2.3.1.1.
4827
4873
  */
4828
- export interface Message {
4874
+ export interface MessageRecord {
4829
4875
  /**
4830
4876
  * Primary identifier (internal UUID)
4831
4877
  */
@@ -4850,10 +4896,6 @@ either way and cannot tell which it received.
4850
4896
  * Server receipt timestamp (INTERNALDATE)
4851
4897
  */
4852
4898
  internalDate: number;
4853
- /**
4854
- * Message-ID header value for quick reference
4855
- */
4856
- messageIdHeader?: string;
4857
4899
  /**
4858
4900
  * Reference to parsed envelope data
4859
4901
  */
@@ -5022,9 +5064,9 @@ either way and cannot tell which it received.
5022
5064
  decidedAt: number;
5023
5065
  }
5024
5066
  /**
5025
- * Core message metadata for API responses
5067
+ * Core message entity as the API carries it: the stored row plus the Message-ID header, which is stored on the message's thread row.
5026
5068
  */
5027
- export interface MessageSummaryResponse {
5069
+ export interface Message {
5028
5070
  /**
5029
5071
  * Primary identifier (internal UUID)
5030
5072
  */
@@ -5037,6 +5079,10 @@ either way and cannot tell which it received.
5037
5079
  * IMAP UID - unique within mailbox, strictly ascending, never reused under same UIDVALIDITY
5038
5080
  */
5039
5081
  uid: number;
5082
+ /**
5083
+ * Relative position (1-based), changes on EXPUNGE
5084
+ */
5085
+ sequenceNumber: number;
5040
5086
  /**
5041
5087
  * Message size in octets in RFC 5322 format
5042
5088
  */
@@ -5045,10 +5091,117 @@ either way and cannot tell which it received.
5045
5091
  * Server receipt timestamp (INTERNALDATE)
5046
5092
  */
5047
5093
  internalDate: number;
5094
+ /**
5095
+ * Reference to parsed envelope data
5096
+ */
5097
+ envelopeId: UUID;
5098
+ /**
5099
+ * Reference to root body part for BODYSTRUCTURE
5100
+ */
5101
+ rootBodyPartId: UUID;
5102
+ /**
5103
+ * Storage URI for the message body (set when body has been fetched and stored)
5104
+ */
5105
+ bodyStorageKey?: string;
5106
+ /**
5107
+ * Message lifecycle status for move/delete operations. Defaults to `active` (normal, visible).
5108
+ */
5109
+ status: MessageStatus;
5110
+ /**
5111
+ * Sync status for move/delete operations, read as a pair with `status` (imap-mutations R3). The `synced` column default only applies to a row written without the field: the repository always supplies one, and an ordinary inbound sync writes `pending`, which nothing later promotes. So `pending` here does not mean an outstanding move or delete — `status` names that, `failed` marks an attempt about to be redelivered, and `abandoned` marks a mutation that gave up.
5112
+ */
5113
+ syncStatus: MessageSyncStatus;
5114
+ /**
5115
+ * Which mutation gave up on this message. Meaningful only while `syncStatus` is `abandoned`; `none` everywhere else, so the absent state is a named value rather than a missing attribute. Written by the same transition that writes `abandoned`, because a hand-back sets `status` back to `active` and that is the field which named the mutation.
5116
+ */
5117
+ abandonedMutation: MessageMutation;
5118
+ /**
5119
+ * Original mailbox ID before move (for restore from trash)
5120
+ */
5121
+ originalMailboxId?: UUID;
5122
+ /**
5123
+ * Original UID before move (for debugging/audit)
5124
+ */
5125
+ originalUid?: number;
5126
+ /**
5127
+ * Header-derived category. Defaults to `uncategorized`, a named value rather than absence. It covers two states — metadata-synced but not yet classified, and classified with nothing to say — and `classificationState` is what tells them apart.
5128
+ */
5129
+ category: MessageCategory;
5130
+ /**
5131
+ * Whether the header classifier has examined this message's body. Defaults to `NotExamined`, the named pending state every message written before this field existed carries. A field of its own rather than a reading of `category` or of `bodyStorageKey`: `uncategorized` is both the pending value and the classifier's own "nothing to say", and key presence is the storage fact, not the derivation's. Persistence-only — no response model exposes it — and it is what a later backfill selects the never-examined cohort by.
5132
+ */
5133
+ classificationState: MessageClassificationState;
5134
+ /**
5135
+ * Structured sender-authenticity signal derived from DKIM headers at classification time. Absent for messages classified before this field was introduced — absence means no signal.
5136
+ */
5137
+ authenticity?: MessageAuthenticity;
5138
+ /**
5139
+ * Sender-authenticity tier resolved at body-sync. Defaults to `NotEvaluated`, the named pending state every message written before the derivation existed carries. Top-level rather than a member of `authenticity` on purpose: that blob is absent for all unsigned mail, so a guard keyed on its absence cannot tell "never derived" from "nothing to derive" and would re-derive unsigned mail forever.
5140
+ */
5141
+ authenticityVerdict: AuthenticityVerdict;
5142
+ /**
5143
+ * Provider authentication-results signal parsed from Authentication-Results header. Absent for messages synced before this field was introduced.
5144
+ */
5145
+ authResult?: MessageAuthResult;
5146
+ /**
5147
+ * Provider spam-filter signal from X-Spam-* / X-SpamExperts-Class headers. Absent for messages synced before this field was introduced.
5148
+ */
5149
+ providerSpam?: MessageProviderSpam;
5150
+ /**
5151
+ * True when a List-Unsubscribe header is present, indicating a bulk/mailing-list sender. Defaults to false.
5152
+ */
5153
+ hasListUnsubscribe: boolean;
5154
+ /**
5155
+ * Set to true when Remit auto-moved this message out of Junk via the rescue heuristic. Guards against re-rescue loops. Defaults to false.
5156
+ */
5157
+ movedByRemit: boolean;
5158
+ /**
5159
+ * Remit's placement verdict, recorded when Remit decided to act (action != leave). Absent means left-in-place or synced before placement rolled out. Recorded in dry-run too, so the dark-ship distribution is queryable.
5160
+ */
5161
+ placementVerdict?: MessagePlacementVerdict;
5162
+ /**
5163
+ * Recorded when a standing filter moved this message at body-sync time (RFC 034). Absent means no filter moved it — a classifier move records `placementVerdict` instead, and a retroactive back-apply records neither. Drives the arbitrary-destination auto-moved badge and its undo.
5164
+ */
5165
+ filterMove?: MessageFilterMove;
5166
+ /**
5167
+ * Body-sync timestamp (epoch millis) the classifier's placement verdict was first decided, whether the verdict was to move the message or to leave it in place. Absent means placement has never been evaluated for this message. Guards `computePlacement` against a re-entrant body-sync pass (`fetchAndGetBody`'s `NoSuchKey` fallback, `syncBodies(..., force: true)`) re-deciding — and possibly reversing — a placement a user has since overridden by hand. `movedByRemit` remains the guard for a message that was placement-decided before this field existed.
5168
+ */
5169
+ placementDecidedAt?: number;
5170
+ /**
5171
+ * Recorded when the user reported this message as spam. Absent means never reported, or reported and then undone (`POST /messages/not-spam` clears it). Independent of the message's current folder — deliberately not derived from "sits in Junk", which is also true of a message Remit moved on its own.
5172
+ */
5173
+ spamReport?: MessageSpamReport;
5174
+ createdAt: number;
5175
+ updatedAt: number;
5048
5176
  /**
5049
5177
  * Message-ID header value for quick reference
5050
5178
  */
5051
5179
  messageIdHeader?: string;
5180
+ }
5181
+ /**
5182
+ * Core message metadata for API responses
5183
+ */
5184
+ export interface MessageSummaryResponse {
5185
+ /**
5186
+ * Primary identifier (internal UUID)
5187
+ */
5188
+ messageId: UUID;
5189
+ /**
5190
+ * Reference to parent mailbox
5191
+ */
5192
+ mailboxId: UUID;
5193
+ /**
5194
+ * IMAP UID - unique within mailbox, strictly ascending, never reused under same UIDVALIDITY
5195
+ */
5196
+ uid: number;
5197
+ /**
5198
+ * Message size in octets in RFC 5322 format
5199
+ */
5200
+ rfc822Size: number;
5201
+ /**
5202
+ * Server receipt timestamp (INTERNALDATE)
5203
+ */
5204
+ internalDate: number;
5052
5205
  /**
5053
5206
  * Message lifecycle status for move/delete operations. Defaults to `active` (normal, visible).
5054
5207
  */
@@ -5065,6 +5218,10 @@ either way and cannot tell which it received.
5065
5218
  * Structured sender-authenticity signal derived from DKIM headers at classification time. Absent for messages classified before this field was introduced — absence means no signal.
5066
5219
  */
5067
5220
  authenticity?: MessageAuthenticity;
5221
+ /**
5222
+ * Message-ID header value for quick reference
5223
+ */
5224
+ messageIdHeader?: string;
5068
5225
  /**
5069
5226
  * Present only when Remit auto-moved this message on body-sync. Absent means the message was not auto-moved by Remit.
5070
5227
  */
@@ -5173,7 +5330,7 @@ either way and cannot tell which it received.
5173
5330
  */
5174
5331
  parentBodyPartId?: UUID;
5175
5332
  /**
5176
- * IMAP section path (e.g., '1', '1.2', '2.1.3')
5333
+ * Storage path of the part within its message: '0' is the root, otherwise the IMAP section number (e.g., '1', '1.2', '2.1.3'). '<path>.0' is the root of the forwarded message a message/rfc822 part at <path> carries, which is not an IMAP section.
5177
5334
  */
5178
5335
  partPath: string;
5179
5336
  /**
@@ -5243,6 +5400,10 @@ either way and cannot tell which it received.
5243
5400
  * Primary identifier
5244
5401
  */
5245
5402
  bodyPartId: UUID;
5403
+ /**
5404
+ * Storage path of the part within its message: '0' is the root, otherwise the IMAP section number (e.g., '1', '1.2', '2.1.3'). '<path>.0' is the root of the forwarded message a message/rfc822 part at <path> carries, which is not an IMAP section.
5405
+ */
5406
+ partPath: string;
5246
5407
  /**
5247
5408
  * MIME type (TEXT, IMAGE, APPLICATION, etc.)
5248
5409
  */
@@ -6197,6 +6358,21 @@ domain already uses"; it does not close it.
6197
6358
  createdAt: number;
6198
6359
  updatedAt: number;
6199
6360
  }
6361
+ /**
6362
+ * A message whose body part rows a repair dropped because they were stored
6363
+ wrong, queued for message sync to read its BODYSTRUCTURE again from the mail
6364
+ server. Message sync drains the queue once per message: the row goes when
6365
+ the message is saved again or the server no longer holds it, whatever parts
6366
+ came back.
6367
+ */
6368
+ export interface BodyStructureRefetch {
6369
+ /**
6370
+ * The message whose structure is to be read again.
6371
+ */
6372
+ messageId: UUID;
6373
+ createdAt: number;
6374
+ updatedAt: number;
6375
+ }
6200
6376
  /**
6201
6377
  * Reference to the complete raw message stored externally
6202
6378
  */
@@ -6299,33 +6475,6 @@ domain already uses"; it does not close it.
6299
6475
  createdAt: number;
6300
6476
  updatedAt: number;
6301
6477
  }
6302
- /**
6303
- * Inline storage for small body parts (typically < 64KB). Avoids external storage overhead.
6304
- */
6305
- export interface BodyPartContent {
6306
- /**
6307
- * Primary identifier
6308
- */
6309
- bodyPartContentId: UUID;
6310
- /**
6311
- * Reference to parent message
6312
- */
6313
- messageId: UUID;
6314
- /**
6315
- * Reference to parent body part
6316
- */
6317
- bodyPartId: UUID;
6318
- /**
6319
- * The actual content (for small inline content only)
6320
- */
6321
- content: string;
6322
- /**
6323
- * Content length in bytes
6324
- */
6325
- contentLength: number;
6326
- createdAt: number;
6327
- updatedAt: number;
6328
- }
6329
6478
  /**
6330
6479
  * One occurrence of a CalendarObject, flattened so a date range can be queried
6331
6480
  instead of expanded (issue #15). Every row is derived from
@@ -6463,49 +6612,6 @@ single `get` checks whether it is already set.
6463
6612
  createdAt: number;
6464
6613
  updatedAt: number;
6465
6614
  }
6466
- /**
6467
- * Persisted semantic-anchor payload for a Filter with `hasAnchor: true` (RFC
6468
- 034 Decision 2). One row only for a filter with a semantic anchor — a
6469
- purely-literal filter has none.
6470
-
6471
- Keys mirror `Filter`'s primary key, so once the index-time worker has a
6472
- candidate `filterId` from `byAccountAndState`, fetching its anchor is a
6473
- single deterministic `get`, never a query.
6474
-
6475
- Deliberately sets no `gsi1pk`/`gsi1sk`: never a member of
6476
- `byAccountAndState`, so it is never replicated into that GSI and never
6477
- loaded by the index-time worker's per-message filter listing — only by the
6478
- explicit `get` once a filter is already a semantic candidate (RFC 034
6479
- Decision 2.3).
6480
- */
6481
- export interface FilterAnchor {
6482
- /**
6483
- * Owning account configuration — mirrors the sibling Filter row's key
6484
- */
6485
- accountConfigId: UUID;
6486
- /**
6487
- * Filter this anchor belongs to — mirrors the sibling Filter row's key
6488
- */
6489
- filterId: UUID;
6490
- /**
6491
- * Persisted anchor vector: mean-pooled (or dominant-chunk) from the anchor message's chunk vectors at save time (RFC 034 Decision 2.1). ~18 KB as DynamoDB decimal-string-encoded numbers (Decision 2.3) — well under the 400 KB item limit, written once, never grown.
6492
- */
6493
- anchorEmbedding: number[];
6494
- /**
6495
- * `<modelId>@<dimensions>` identifier, e.g. "amazon.titan-embed-text-v2:0@1024" — the same id packages/search-service/src/embeddings.ts derives for chunk vectors. Lets a migration detect anchors whose model has gone stale (RFC 034 Decision 2.4).
6496
- */
6497
- anchorEmbeddingId: string;
6498
- /**
6499
- * The anchor message's textPreview at save time, bounded to buildTextPreview's existing budget (RFC 034 Decision 2.1). Retained so a stale anchor is always re-embeddable without depending on the source message still existing (Decision 2.4).
6500
- */
6501
- anchorSourceText: String512;
6502
- /**
6503
- * Provenance/display only — "based on this message" (RFC 034 Decision 2.1). Never re-read at match time. May dangle if the source message is later deleted; anchorEmbedding/anchorSourceText are unaffected, since they are copies, not references.
6504
- */
6505
- anchorMessageId: UUID;
6506
- createdAt: number;
6507
- updatedAt: number;
6508
- }
6509
6615
  export interface MicrosoftOAuthStartRequest {
6510
6616
  /**
6511
6617
  * Optional email hint for the Microsoft login page
@@ -7196,23 +7302,6 @@ declare namespace Paths {
7196
7302
  export type $401 = void;
7197
7303
  }
7198
7304
  }
7199
- namespace SemanticSearch {
7200
- export interface QueryParameters {
7201
- query: string;
7202
- mailboxId?: Components.Schemas.UUID;
7203
- sentDateFrom?: number;
7204
- sentDateTo?: number;
7205
- hasAttachment?: boolean;
7206
- hasStars?: boolean;
7207
- isRead?: boolean;
7208
- category?: Components.Schemas.MessageCategory;
7209
- limit?: number;
7210
- }
7211
- namespace Responses {
7212
- export type $200 = void;
7213
- export type $401 = void;
7214
- }
7215
- }
7216
7305
  namespace CreateOutboxMessage {
7217
7306
  export type RequestBody = Components.Schemas.CreateOutboxMessageInput;
7218
7307
  namespace Responses {
@@ -7329,6 +7418,7 @@ declare namespace Paths {
7329
7418
  namespace Responses {
7330
7419
  export type $200 = void;
7331
7420
  export type $404 = void;
7421
+ export type $409 = void;
7332
7422
  export type $422 = void;
7333
7423
  export type $401 = void;
7334
7424
  }
@@ -7340,6 +7430,7 @@ declare namespace Paths {
7340
7430
  namespace Responses {
7341
7431
  export type $200 = void;
7342
7432
  export type $404 = void;
7433
+ export type $409 = void;
7343
7434
  export type $401 = void;
7344
7435
  }
7345
7436
  }
@@ -7702,7 +7793,7 @@ export interface OperationMethods {
7702
7793
  config?: AxiosRequestConfig
7703
7794
  ): OperationResponse<Paths.DeleteLabel.Responses.$204>;
7704
7795
  /**
7705
- * createOrganizeJob - Start a one-time "all like these" back-apply: match the corpus against the given predicate and apply the action to every match, in one pass. Returns immediately with an organizeJobId; poll GET /accounts/{accountId}/organize/{organizeJobId} for state and counts. Never creates a Filter or FilterAnchor row (RFC 034 recap).
7796
+ * createOrganizeJob - Start a one-time "all like these" back-apply: match the corpus against the given predicate and apply the action to every match, in one pass. Returns immediately with an organizeJobId; poll GET /accounts/{accountId}/organize/{organizeJobId} for state and counts. Never creates a Filter row (RFC 034 recap).
7706
7797
  */
7707
7798
  'createOrganizeJob'(
7708
7799
  parameters?: Parameters<Paths.CreateOrganizeJob.PathParameters> | null,
@@ -8034,14 +8125,6 @@ Counting: `count=true` answers how many CONVERSATIONS match, over the whole scop
8034
8125
  data?: any,
8035
8126
  config?: AxiosRequestConfig
8036
8127
  ): OperationResponse<Paths.SearchThreads.Responses.$200>;
8037
- /**
8038
- * semanticSearch - Run a semantic vector search across the caller's indexed messages.
8039
- */
8040
- 'semanticSearch'(
8041
- parameters?: Parameters<Paths.SemanticSearch.QueryParameters> | null,
8042
- data?: any,
8043
- config?: AxiosRequestConfig
8044
- ): OperationResponse<Paths.SemanticSearch.Responses.$200>;
8045
8128
  /**
8046
8129
  * createOutboxMessage - Create a new outbox message (draft or send immediately). A send-immediately create from an account whose syncedServices leave out Mail is refused with 400 `mail_sync_off`.
8047
8130
  */
@@ -8529,7 +8612,7 @@ export interface PathsDictionary {
8529
8612
  };
8530
8613
  ['/accounts/{accountId}/organize']: {
8531
8614
  /**
8532
- * createOrganizeJob - Start a one-time "all like these" back-apply: match the corpus against the given predicate and apply the action to every match, in one pass. Returns immediately with an organizeJobId; poll GET /accounts/{accountId}/organize/{organizeJobId} for state and counts. Never creates a Filter or FilterAnchor row (RFC 034 recap).
8615
+ * createOrganizeJob - Start a one-time "all like these" back-apply: match the corpus against the given predicate and apply the action to every match, in one pass. Returns immediately with an organizeJobId; poll GET /accounts/{accountId}/organize/{organizeJobId} for state and counts. Never creates a Filter row (RFC 034 recap).
8533
8616
  */
8534
8617
  'post'(
8535
8618
  parameters?: Parameters<Paths.CreateOrganizeJob.PathParameters> | null,
@@ -8904,16 +8987,6 @@ Counting: `count=true` answers how many CONVERSATIONS match, over the whole scop
8904
8987
  config?: AxiosRequestConfig
8905
8988
  ): OperationResponse<Paths.SearchThreads.Responses.$200>;
8906
8989
  };
8907
- ['/search/semantic']: {
8908
- /**
8909
- * semanticSearch - Run a semantic vector search across the caller's indexed messages.
8910
- */
8911
- 'get'(
8912
- parameters?: Parameters<Paths.SemanticSearch.QueryParameters> | null,
8913
- data?: any,
8914
- config?: AxiosRequestConfig
8915
- ): OperationResponse<Paths.SemanticSearch.Responses.$200>;
8916
- };
8917
8990
  ['/outbox']: {
8918
8991
  /**
8919
8992
  * createOutboxMessage - Create a new outbox message (draft or send immediately). A send-immediately create from an account whose syncedServices leave out Mail is refused with 400 `mail_sync_off`.
@@ -9222,8 +9295,9 @@ export type FolderRoleConflict = Components.Schemas.FolderRoleConflict;
9222
9295
  export type AppointFolderRoleConflict = Components.Schemas.AppointFolderRoleConflict;
9223
9296
  export type MailboxNotSettled = Components.Schemas.MailboxNotSettled;
9224
9297
  export type PreconditionFailedError = Components.Schemas.PreconditionFailedError;
9225
- export type DeleteMessagesConflict = Components.Schemas.DeleteMessagesConflict;
9298
+ export type MessageNotFoundError = Components.Schemas.MessageNotFoundError;
9226
9299
  export type MessagePlacementConflict = Components.Schemas.MessagePlacementConflict;
9300
+ export type DeleteMessagesConflict = Components.Schemas.DeleteMessagesConflict;
9227
9301
  export type AmazonApiGatewayIntegration = Components.Schemas.AmazonApiGatewayIntegration;
9228
9302
  export type InternalServerError = Components.Schemas.InternalServerError;
9229
9303
  export type DeleteMeInput = Components.Schemas.DeleteMeInput;
@@ -9237,6 +9311,8 @@ export type QuarantineListResponse = Components.Schemas.QuarantineListResponse;
9237
9311
  export type Quarantine = Components.Schemas.Quarantine;
9238
9312
  export type QuarantineMimeNode = Components.Schemas.QuarantineMimeNode;
9239
9313
  export type QuarantineResponse = Components.Schemas.QuarantineResponse;
9314
+ export type SyncWarning = Components.Schemas.SyncWarning;
9315
+ export type SyncWarningResponse = Components.Schemas.SyncWarningResponse;
9240
9316
  export type ConfigDescriptionResponse = Components.Schemas.ConfigDescriptionResponse;
9241
9317
  export type AccountConfig = Components.Schemas.AccountConfig;
9242
9318
  export type AccountConfigResponse = Components.Schemas.AccountConfigResponse;
@@ -9257,6 +9333,7 @@ export type SystemUpdateRun = Components.Schemas.SystemUpdateRun;
9257
9333
  export type ApplyUpdateInput = Components.Schemas.ApplyUpdateInput;
9258
9334
  export type Mailbox = Components.Schemas.Mailbox;
9259
9335
  export type MailboxResponse = Components.Schemas.MailboxResponse;
9336
+ export type MailboxListResponse = Components.Schemas.MailboxListResponse;
9260
9337
  export type CreateMailboxInput = Components.Schemas.CreateMailboxInput;
9261
9338
  export type RenameMailboxInput = Components.Schemas.RenameMailboxInput;
9262
9339
  export type AppointFolderRoleInput = Components.Schemas.AppointFolderRoleInput;
@@ -9309,13 +9386,14 @@ export type MessageAuthenticity = Components.Schemas.MessageAuthenticity;
9309
9386
  export type AutoMovedInfo = Components.Schemas.AutoMovedInfo;
9310
9387
  export type LabelSummaryResponse = Components.Schemas.LabelSummaryResponse;
9311
9388
  export type MessageSpamReport = Components.Schemas.MessageSpamReport;
9389
+ export type ThreadMessageListResponse = Components.Schemas.ThreadMessageListResponse;
9312
9390
  export type ThreadSearchResponse = Components.Schemas.ThreadSearchResponse;
9313
- export type SemanticSearchResult = Components.Schemas.SemanticSearchResult;
9314
9391
  export type CreateOutboxMessageInput = Components.Schemas.CreateOutboxMessageInput;
9315
9392
  export type OutboxMessage = Components.Schemas.OutboxMessage;
9316
9393
  export type OutboxMessageResponse = Components.Schemas.OutboxMessageResponse;
9317
9394
  export type OutboxAttachment = Components.Schemas.OutboxAttachment;
9318
9395
  export type OutboxAttachmentResponse = Components.Schemas.OutboxAttachmentResponse;
9396
+ export type OutboxMessageListResponse = Components.Schemas.OutboxMessageListResponse;
9319
9397
  export type UpdateOutboxMessageInput = Components.Schemas.UpdateOutboxMessageInput;
9320
9398
  export type MintOutboxAttachmentInput = Components.Schemas.MintOutboxAttachmentInput;
9321
9399
  export type MintOutboxAttachmentResponse = Components.Schemas.MintOutboxAttachmentResponse;
@@ -9336,11 +9414,12 @@ export type AddressResponse = Components.Schemas.AddressResponse;
9336
9414
  export type UpdateAddressInput = Components.Schemas.UpdateAddressInput;
9337
9415
  export type UpdateAddressFlagsInput = Components.Schemas.UpdateAddressFlagsInput;
9338
9416
  export type DescribeMessageResponse = Components.Schemas.DescribeMessageResponse;
9339
- export type Message = Components.Schemas.Message;
9417
+ export type MessageRecord = Components.Schemas.MessageRecord;
9340
9418
  export type MessageAuthResult = Components.Schemas.MessageAuthResult;
9341
9419
  export type MessageProviderSpam = Components.Schemas.MessageProviderSpam;
9342
9420
  export type MessagePlacementVerdict = Components.Schemas.MessagePlacementVerdict;
9343
9421
  export type MessageFilterMove = Components.Schemas.MessageFilterMove;
9422
+ export type Message = Components.Schemas.Message;
9344
9423
  export type MessageSummaryResponse = Components.Schemas.MessageSummaryResponse;
9345
9424
  export type EnvelopeResponse = Components.Schemas.EnvelopeResponse;
9346
9425
  export type EnvelopeAddressResponse = Components.Schemas.EnvelopeAddressResponse;
@@ -9384,13 +9463,12 @@ export type MessageFlagPush = Components.Schemas.MessageFlagPush;
9384
9463
  export type Envelope = Components.Schemas.Envelope;
9385
9464
  export type SenderSignerStanding = Components.Schemas.SenderSignerStanding;
9386
9465
  export type BodyPartParameter = Components.Schemas.BodyPartParameter;
9466
+ export type BodyStructureRefetch = Components.Schemas.BodyStructureRefetch;
9387
9467
  export type RawMessageStorage = Components.Schemas.RawMessageStorage;
9388
9468
  export type BodyPartStorage = Components.Schemas.BodyPartStorage;
9389
- export type BodyPartContent = Components.Schemas.BodyPartContent;
9390
9469
  export type CalendarEventIndex = Components.Schemas.CalendarEventIndex;
9391
9470
  export type CalendarFeedToken = Components.Schemas.CalendarFeedToken;
9392
9471
  export type MessageLabel = Components.Schemas.MessageLabel;
9393
- export type FilterAnchor = Components.Schemas.FilterAnchor;
9394
9472
  export type MicrosoftOAuthStartRequest = Components.Schemas.MicrosoftOAuthStartRequest;
9395
9473
  export type MicrosoftOAuthStartResponse = Components.Schemas.MicrosoftOAuthStartResponse;
9396
9474
  export type IndexType = Components.Schemas.IndexType;
@@ -9398,6 +9476,7 @@ export type AccountExportState = Components.Schemas.AccountExportState;
9398
9476
  export type CanonicalMailboxRole = Components.Schemas.CanonicalMailboxRole;
9399
9477
  export type QuarantineFailureStage = Components.Schemas.QuarantineFailureStage;
9400
9478
  export type QuarantineFailureCode = Components.Schemas.QuarantineFailureCode;
9479
+ export type SyncWarningStage = Components.Schemas.SyncWarningStage;
9401
9480
  export type AccountConfigState = Components.Schemas.AccountConfigState;
9402
9481
  export type AccountAuthType = Components.Schemas.AccountAuthType;
9403
9482
  export type AccountService = Components.Schemas.AccountService;
@@ -9436,7 +9515,6 @@ export type MessageStatus = Components.Schemas.MessageStatus;
9436
9515
  export type MessageSyncStatus = Components.Schemas.MessageSyncStatus;
9437
9516
  export type MessageMutation = Components.Schemas.MessageMutation;
9438
9517
  export type PlacementAction = Components.Schemas.PlacementAction;
9439
- export type SemanticSearchChunkType = Components.Schemas.SemanticSearchChunkType;
9440
9518
  export type OutboxMessageStatus = Components.Schemas.OutboxMessageStatus;
9441
9519
  export type OutboxAttachmentState = Components.Schemas.OutboxAttachmentState;
9442
9520
  export type OutboxAttachmentRejectionReason = Components.Schemas.OutboxAttachmentRejectionReason;
@@ -9466,6 +9544,7 @@ export type SenderOverride = Components.Schemas.SenderOverride;
9466
9544
  export type AccountSettingName = Components.Schemas.AccountSettingName;
9467
9545
  export type ConfigImportState = Components.Schemas.ConfigImportState;
9468
9546
  export type ConfigImportRefKind = Components.Schemas.ConfigImportRefKind;
9547
+ export type SyncWarningState = Components.Schemas.SyncWarningState;
9469
9548
  export type MessagePlacementMoveState = Components.Schemas.MessagePlacementMoveState;
9470
9549
  export type FlagPushOperation = Components.Schemas.FlagPushOperation;
9471
9550
  export type MessageFlagPushState = Components.Schemas.MessageFlagPushState;