@mnemom/mnemom 0.17.34 → 0.17.35
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/dist/commands/agent-config.js +3 -0
- package/dist/commands/agent-goal.d.ts +8 -3
- package/dist/commands/agent-goal.js +22 -8
- package/dist/commands/agent-run.d.ts +10 -2
- package/dist/commands/agent-run.js +19 -6
- package/dist/commands/agent-slack.js +32 -0
- package/dist/commands/durable-inbox.d.ts +51 -0
- package/dist/commands/durable-inbox.js +134 -0
- package/dist/commands/durable-questions.d.ts +64 -0
- package/dist/commands/durable-questions.js +161 -0
- package/dist/durable/seat-proxy.d.ts +12 -1
- package/dist/durable/seat-proxy.js +55 -9
- package/dist/durable/seat-socket.d.ts +20 -2
- package/dist/durable/seat-socket.js +58 -0
- package/dist/durable/turn-chain.d.ts +8 -0
- package/dist/durable/turn-chain.js +25 -4
- package/dist/host/client.d.ts +41 -0
- package/dist/host/client.js +7 -0
- package/dist/host/control.d.ts +7 -0
- package/dist/host/control.js +15 -0
- package/dist/host/daemon.d.ts +20 -0
- package/dist/host/daemon.js +74 -1
- package/dist/host/inbox-delivery.d.ts +174 -0
- package/dist/host/inbox-delivery.js +453 -0
- package/dist/host/run.d.ts +18 -0
- package/dist/host/run.js +61 -0
- package/dist/host/s1-names.d.ts +2 -0
- package/dist/host/s1-names.js +2 -0
- package/dist/host/tmux.d.ts +7 -0
- package/dist/host/tmux.js +19 -0
- package/dist/index.js +59 -1
- package/dist/lib/api.d.ts +5 -0
- package/dist/lib/api.js +16 -0
- package/dist/lib/durable/api.d.ts +11 -0
- package/dist/lib/durable/api.js +28 -3
- package/dist/lib/durable/gate.d.ts +1 -1
- package/dist/lib/durable/gate.js +8 -1
- package/dist/lib/durable/live.d.ts +5 -0
- package/dist/lib/durable/live.js +19 -0
- package/dist/lib/experimental.js +3 -0
- package/dist/lib/goal-api.d.ts +11 -4
- package/dist/lib/goal-api.js +4 -3
- package/dist/lib/launcher-config.d.ts +5 -0
- package/dist/lib/launcher-config.js +17 -2
- package/dist/lib/prompt.d.ts +4 -2
- package/dist/lib/prompt.js +15 -5
- package/dist/lib/runner/job.d.ts +2 -2
- package/dist/lib/runner/job.js +16 -3
- package/dist/lib/runner/pr-body.d.ts +17 -0
- package/dist/lib/runner/pr-body.js +42 -0
- package/dist/lib/runner/proxy.d.ts +18 -3
- package/dist/lib/runner/proxy.js +24 -5
- package/dist/lib/scan/record.d.ts +60 -9
- package/dist/lib/scan/record.js +157 -39
- package/dist/lib/scan/report.d.ts +6 -8
- package/dist/lib/scan/report.js +21 -7
- package/dist/lib/scan/share.d.ts +5 -1
- package/dist/lib/scan/share.js +15 -5
- package/dist/lib/slack-durable.d.ts +123 -0
- package/dist/lib/slack-durable.js +237 -0
- package/dist/lib/slack-router.d.ts +7 -0
- package/dist/lib/slack-router.js +50 -4
- package/dist/vendor/durable-contract/index.js +992 -34
- package/dist/vendor/shared/durable-contract/admission.d.ts +81 -2
- package/dist/vendor/shared/durable-contract/admission.js +319 -2
- package/dist/vendor/shared/durable-contract/cli-surface.js +21 -0
- package/dist/vendor/shared/durable-contract/codes.d.ts +60 -0
- package/dist/vendor/shared/durable-contract/codes.js +22 -0
- package/dist/vendor/shared/durable-contract/events.d.ts +4 -2
- package/dist/vendor/shared/durable-contract/events.js +55 -1
- package/dist/vendor/shared/durable-contract/freeze-record.d.ts +14 -0
- package/dist/vendor/shared/durable-contract/inbox.d.ts +299 -0
- package/dist/vendor/shared/durable-contract/inbox.js +462 -0
- package/dist/vendor/shared/durable-contract/index.d.ts +2 -0
- package/dist/vendor/shared/durable-contract/index.js +2 -0
- package/dist/vendor/shared/durable-contract/question.d.ts +218 -0
- package/dist/vendor/shared/durable-contract/question.js +373 -0
- package/dist/vendor/shared/durable-contract/routes.d.ts +44 -2
- package/dist/vendor/shared/durable-contract/routes.js +43 -1
- package/dist/vendor/shared/durable-contract/turn.d.ts +15 -1
- package/dist/vendor/shared/durable-contract/turn.js +33 -1
- package/dist/vendor/shared/durable-contract/vectors.d.ts +45 -0
- package/dist/vendor/shared/durable-contract/vectors.js +49 -0
- package/package.json +1 -1
- package/plugins/integrity-manifest.json +6 -2
- package/plugins/mnemom/hooks/hooks.json +12 -0
- package/plugins/mnemom/hooks/seat-ask.mjs +221 -0
|
@@ -156,7 +156,9 @@ export const M1_EXCLUDED_KINDS = [
|
|
|
156
156
|
];
|
|
157
157
|
/**
|
|
158
158
|
* Every M1 kind (80) with its group, in §3.7 order, then the Doors amendment's three (rulings
|
|
159
|
-
* 34.02, 34.06),
|
|
159
|
+
* 34.02, 34.06), executor.turn_continued, and inbox.acked (S1 amendment 60: M1 left it out, the
|
|
160
|
+
* inbox ack writes it; M1_EXCLUDED_KINDS stays the frozen M1 record), appended so no existing index
|
|
161
|
+
* moves. Mirrors durable_event_kinds (parity test).
|
|
160
162
|
*/
|
|
161
163
|
export const DURABLE_EVENT_KINDS = [
|
|
162
164
|
"session.registered",
|
|
@@ -243,6 +245,7 @@ export const DURABLE_EVENT_KINDS = [
|
|
|
243
245
|
"session.waiting",
|
|
244
246
|
"session.wait_cleared",
|
|
245
247
|
"executor.turn_continued",
|
|
248
|
+
"inbox.acked",
|
|
246
249
|
];
|
|
247
250
|
export function isDurableEventKind(v) {
|
|
248
251
|
return typeof v === "string" && DURABLE_EVENT_KINDS.includes(v);
|
|
@@ -502,6 +505,57 @@ const KIND_REFS = {
|
|
|
502
505
|
// ---- lead ruling 2026-10-28: the spawn that sent the continue; a separate fact, so
|
|
503
506
|
// executor.spawned's refs stay exactly {spawn_id} ----
|
|
504
507
|
"executor.turn_continued": obj({ spawn_id: UUID }),
|
|
508
|
+
// ---- S1 amendment 60 (signed off by Wassim 2026-11-02): the inbox. Content-free: ids, shas, enums ----
|
|
509
|
+
"inbox.admitted": obj({
|
|
510
|
+
inbox_id: UUID,
|
|
511
|
+
sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }),
|
|
512
|
+
sender_kind: ENUM(["owner", "agent"]),
|
|
513
|
+
sender_agent_id: S({ pattern: "^[A-Za-z0-9_-]{1,64}$" }),
|
|
514
|
+
in_reply_to: UUID,
|
|
515
|
+
}, ["inbox_id", "sha", "sender_kind"], [
|
|
516
|
+
{ field: "sender_kind", equals: "agent", require: ["sender_agent_id"] },
|
|
517
|
+
{ field: "sender_kind", equals: "owner", forbid: ["sender_agent_id"] },
|
|
518
|
+
]),
|
|
519
|
+
"inbox.rejected": obj({
|
|
520
|
+
reason: ENUM([
|
|
521
|
+
"not_allowlisted",
|
|
522
|
+
"not_locked",
|
|
523
|
+
"ended",
|
|
524
|
+
"unsealed",
|
|
525
|
+
"inbox_full",
|
|
526
|
+
"body_too_large",
|
|
527
|
+
"body_invalid",
|
|
528
|
+
"unattended_off",
|
|
529
|
+
]),
|
|
530
|
+
sender_kind: ENUM(["owner", "agent"]),
|
|
531
|
+
}),
|
|
532
|
+
"inbox.coalesced": obj({ inbox_id: UUID, sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }) }),
|
|
533
|
+
"inbox.delivered": obj({
|
|
534
|
+
inbox_id: UUID,
|
|
535
|
+
sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }),
|
|
536
|
+
attempt: INT(1),
|
|
537
|
+
}),
|
|
538
|
+
"inbox.acked": obj({ inbox_id: UUID, sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }) }),
|
|
539
|
+
"inbox.reverted": obj({
|
|
540
|
+
inbox_id: UUID,
|
|
541
|
+
sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }),
|
|
542
|
+
reason: ENUM(["unconfirmed", "refused", "undeliverable"]),
|
|
543
|
+
}),
|
|
544
|
+
"inbox.dead": obj({
|
|
545
|
+
inbox_id: UUID,
|
|
546
|
+
sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }),
|
|
547
|
+
reason: ENUM(["expired", "delivery_limit", "session_ended"]),
|
|
548
|
+
}),
|
|
549
|
+
// ---- S1 amendment 61 (signed off by Wassim 2026-11-02): questions. Content-free: ids, shas, enums ----
|
|
550
|
+
"question.asked": obj({
|
|
551
|
+
approval_id: UUID,
|
|
552
|
+
question_sha: S({ pattern: HEX64_PATTERN, maxLength: 64 }),
|
|
553
|
+
}),
|
|
554
|
+
"question.answered": obj({
|
|
555
|
+
approval_id: UUID,
|
|
556
|
+
outcome: ENUM(["answered", "dismissed"]),
|
|
557
|
+
via: ENUM(["coding_agent", "slack", "webhook", "mcp", "device"]),
|
|
558
|
+
}),
|
|
505
559
|
};
|
|
506
560
|
/** refs_schema for every M1 kind; kinds without a specific schema take EMPTY (refs must be {}). */
|
|
507
561
|
export function refsSchemaOf(kind) {
|
|
@@ -330,6 +330,13 @@ export declare const FREEZE_STRUCTURED: Readonly<{
|
|
|
330
330
|
exec_heartbeat: import("./routes.js").FixedRoute;
|
|
331
331
|
exec_ready_list: import("./routes.js").FixedRoute;
|
|
332
332
|
exec_oidc_exchange: import("./routes.js").FixedRoute;
|
|
333
|
+
exec_inbox: import("./routes.js").ScopedRoute;
|
|
334
|
+
exec_inbox_take: import("./routes.js").ScopedRoute;
|
|
335
|
+
exec_inbox_ack: import("./routes.js").ScopedRoute;
|
|
336
|
+
exec_inbox_release: import("./routes.js").ScopedRoute;
|
|
337
|
+
exec_question: import("./routes.js").ScopedRoute;
|
|
338
|
+
exec_question_poll: import("./routes.js").ScopedRoute;
|
|
339
|
+
exec_question_release: import("./routes.js").ScopedRoute;
|
|
333
340
|
own_lock: import("./routes.js").ScopedRoute;
|
|
334
341
|
own_unlock: import("./routes.js").ScopedRoute;
|
|
335
342
|
own_pause: import("./routes.js").ScopedRoute;
|
|
@@ -339,6 +346,13 @@ export declare const FREEZE_STRUCTURED: Readonly<{
|
|
|
339
346
|
own_amend: import("./routes.js").ScopedRoute;
|
|
340
347
|
own_fail: import("./routes.js").ScopedRoute;
|
|
341
348
|
own_events: import("./routes.js").ScopedRoute;
|
|
349
|
+
own_inbox_send: import("./routes.js").ScopedRoute;
|
|
350
|
+
own_inbox_list: import("./routes.js").ScopedRoute;
|
|
351
|
+
own_inbox_senders: import("./routes.js").ScopedRoute;
|
|
352
|
+
own_inbox_sender_add: import("./routes.js").ScopedRoute;
|
|
353
|
+
own_inbox_sender_remove: import("./routes.js").ScopedRoute;
|
|
354
|
+
own_questions: import("./routes.js").ScopedRoute;
|
|
355
|
+
own_answer: import("./routes.js").ScopedRoute;
|
|
342
356
|
int_events: import("./routes.js").FixedRoute;
|
|
343
357
|
int_arm: import("./routes.js").FixedRoute;
|
|
344
358
|
int_sweep: import("./routes.js").FixedRoute;
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The durable inbox (S1 amendment 60, signed off by Wassim 2026-11-02): how work reaches a locked session
|
|
3
|
+
* without anyone typing into its seat. The owner, or an agent on the owner's allowlist for the
|
|
4
|
+
* recipient agent, sends a message to the session (ROUTES.own_inbox_send); the api stores it
|
|
5
|
+
* (encrypted, as a charter contract is) and journals inbox.admitted. The session's executor takes it
|
|
6
|
+
* (ROUTES.exec_inbox_take: the api marks it delivered at the live epoch and journals
|
|
7
|
+
* inbox.delivered), pastes the delivery text into the seat, and acks it when the turn that answered
|
|
8
|
+
* it ends (ROUTES.exec_inbox_ack: inbox.acked). Between take and ack the message's sha is in the
|
|
9
|
+
* resolver's `inbox_open`, which is what lets amendment 60 (e) admit the seat's `inbox=<sha>` turn
|
|
10
|
+
* unattended.
|
|
11
|
+
*
|
|
12
|
+
* Every inbox.* kind stays api-written (writerOf): delivered and acked are written by the api inside
|
|
13
|
+
* the take and ack routes, in the transaction that moves the inbox row, never through exec_append.
|
|
14
|
+
* So an executor cannot journal a delivery the api did not make, and the gateway can never see a
|
|
15
|
+
* turn whose sha is not yet open.
|
|
16
|
+
*
|
|
17
|
+
* This file holds the limits, the message sha and delivery text recipes, and the closed wire shapes
|
|
18
|
+
* of the inbox routes (routes.ts lists the routes). Nothing here carries message text into the
|
|
19
|
+
* journal: refs are ids, shas and enums only.
|
|
20
|
+
*/
|
|
21
|
+
/** A message body is 1..this many UTF-8 bytes. */
|
|
22
|
+
export declare const INBOX_BODY_MAX_BYTES = 16384;
|
|
23
|
+
/** An admitted or delivered message nobody acks is dead (reason expired) this long after it was sent. */
|
|
24
|
+
export declare const INBOX_TTL_S: number;
|
|
25
|
+
/** A message taken this many times without an ack is dead (reason delivery_limit) instead of taken again. */
|
|
26
|
+
export declare const INBOX_DELIVERY_LIMIT = 5;
|
|
27
|
+
/** exec_inbox_take returns at most this many messages; `limit` defaults to 1. */
|
|
28
|
+
export declare const INBOX_TAKE_LIMIT_MAX = 8;
|
|
29
|
+
/** own_inbox_list returns at most this many messages, newest first. */
|
|
30
|
+
export declare const INBOX_LIST_LIMIT = 100;
|
|
31
|
+
/** At most this many live (unrevoked) allowlisted senders per recipient agent. */
|
|
32
|
+
export declare const INBOX_SENDERS_MAX = 32;
|
|
33
|
+
/** The open-message cap: a send that would open more than this is refused (inbox_full). */
|
|
34
|
+
export declare const INBOX_OPEN_CAP = 64;
|
|
35
|
+
/**
|
|
36
|
+
* Take re-offers a message delivered at the LIVE epoch once its last delivery is this old and it was
|
|
37
|
+
* neither acked nor released (the executor lost track of it: it died between the take and its own
|
|
38
|
+
* record, or gave up on a paste). The executor takes only while it tracks nothing for the seat and
|
|
39
|
+
* the seat is idle, so a re-offer never lands inside the turn answering it. At-least-once.
|
|
40
|
+
*/
|
|
41
|
+
export declare const INBOX_REOFFER_S: number;
|
|
42
|
+
/** idempotency_key: 1..200 of letters, digits and `_ . : -` (a Slack key is `slack:<channel>:<ts>`). */
|
|
43
|
+
export declare const INBOX_IDEMPOTENCY_KEY_RE: RegExp;
|
|
44
|
+
/** An agents.id as the inbox takes it: opaque text, letters, digits, `_` and `-`, at most 64. */
|
|
45
|
+
export declare const INBOX_AGENT_ID_RE: RegExp;
|
|
46
|
+
/** A sender label: one line of printable ASCII without `[` or `]`, 1..128 characters. */
|
|
47
|
+
export declare const INBOX_SENDER_LABEL_RE: RegExp;
|
|
48
|
+
/** durable_inbox.status. admitted and delivered are open; acked and dead are final. */
|
|
49
|
+
export declare const INBOX_STATUSES: readonly ["admitted", "delivered", "acked", "dead"];
|
|
50
|
+
export type InboxStatus = (typeof INBOX_STATUSES)[number];
|
|
51
|
+
/** Who sent a message: the session's owner, or an agent on the owner's allowlist. */
|
|
52
|
+
export declare const INBOX_SENDER_KINDS: readonly ["owner", "agent"];
|
|
53
|
+
export type InboxSenderKind = (typeof INBOX_SENDER_KINDS)[number];
|
|
54
|
+
/** inbox.rejected refs.reason: why a send by an authenticated sender that can see the session was refused. */
|
|
55
|
+
export declare const INBOX_REJECT_REASONS: readonly ["not_allowlisted", "not_locked", "ended", "unsealed", "inbox_full", "body_too_large", "body_invalid", "unattended_off"];
|
|
56
|
+
export type InboxRejectReason = (typeof INBOX_REJECT_REASONS)[number];
|
|
57
|
+
/** inbox.dead refs.reason and durable_inbox.dead_reason. */
|
|
58
|
+
export declare const INBOX_DEAD_REASONS: readonly ["expired", "delivery_limit", "session_ended"];
|
|
59
|
+
export type InboxDeadReason = (typeof INBOX_DEAD_REASONS)[number];
|
|
60
|
+
/**
|
|
61
|
+
* exec_inbox_release body.reason and inbox.reverted refs.reason: why the executor hands a delivered
|
|
62
|
+
* message back undone, instead of acking it.
|
|
63
|
+
* - unconfirmed: pasted, never reached the transcript;
|
|
64
|
+
* - refused: the turn it started ended on a gateway refusal (an API-error turn): no work was done;
|
|
65
|
+
* - undeliverable: the executor will not paste the text.
|
|
66
|
+
*/
|
|
67
|
+
export declare const INBOX_RELEASE_REASONS: readonly ["unconfirmed", "refused", "undeliverable"];
|
|
68
|
+
export type InboxReleaseReason = (typeof INBOX_RELEASE_REASONS)[number];
|
|
69
|
+
/**
|
|
70
|
+
* The `reason` of a 422 durable_inbox_sender_invalid: `sender` / `on_behalf_of` (a send whose
|
|
71
|
+
* sender identity is inconsistent), `agent_id` / `label` (a malformed allowlist change), `self` (the
|
|
72
|
+
* recipient itself), `not_found`, `other_org`, `not_owned` (not one of the owner's agents in the
|
|
73
|
+
* session's org), `too_many` (INBOX_SENDERS_MAX live senders already).
|
|
74
|
+
*/
|
|
75
|
+
export declare const INBOX_SENDER_INVALID_REASONS: readonly ["sender", "on_behalf_of", "agent_id", "label", "self", "not_found", "other_org", "not_owned", "too_many"];
|
|
76
|
+
export type InboxSenderInvalidReason = (typeof INBOX_SENDER_INVALID_REASONS)[number];
|
|
77
|
+
/**
|
|
78
|
+
* The refusal code and HTTP status of each INBOX_REJECT_REASONS value (codes.ts DURABLE_CODES). Each
|
|
79
|
+
* refused send by a sender that may see the session journals inbox.rejected {reason, sender_kind};
|
|
80
|
+
* a caller who cannot see it is refused before anything is read or written.
|
|
81
|
+
*/
|
|
82
|
+
export declare const INBOX_REJECT_CODES: Readonly<{
|
|
83
|
+
readonly not_allowlisted: {
|
|
84
|
+
readonly code: "durable_inbox_not_allowlisted";
|
|
85
|
+
readonly status: 403;
|
|
86
|
+
};
|
|
87
|
+
readonly not_locked: {
|
|
88
|
+
readonly code: "durable_inbox_closed";
|
|
89
|
+
readonly status: 409;
|
|
90
|
+
};
|
|
91
|
+
readonly ended: {
|
|
92
|
+
readonly code: "durable_inbox_closed";
|
|
93
|
+
readonly status: 409;
|
|
94
|
+
};
|
|
95
|
+
readonly unsealed: {
|
|
96
|
+
readonly code: "durable_inbox_closed";
|
|
97
|
+
readonly status: 409;
|
|
98
|
+
};
|
|
99
|
+
readonly inbox_full: {
|
|
100
|
+
readonly code: "durable_inbox_full";
|
|
101
|
+
readonly status: 429;
|
|
102
|
+
};
|
|
103
|
+
readonly body_too_large: {
|
|
104
|
+
readonly code: "durable_inbox_body_invalid";
|
|
105
|
+
readonly status: 422;
|
|
106
|
+
};
|
|
107
|
+
readonly body_invalid: {
|
|
108
|
+
readonly code: "durable_inbox_body_invalid";
|
|
109
|
+
readonly status: 422;
|
|
110
|
+
};
|
|
111
|
+
readonly unattended_off: {
|
|
112
|
+
readonly code: "durable_inbox_closed";
|
|
113
|
+
readonly status: 409;
|
|
114
|
+
};
|
|
115
|
+
}>;
|
|
116
|
+
/** The kinds amendment 60 gives an emitter (they stay in the frozen NO_M1_EMITTER_KINDS M1 baseline). */
|
|
117
|
+
export declare const A60_EMITTED_KINDS: readonly ["inbox.admitted", "inbox.rejected", "inbox.coalesced", "inbox.delivered", "inbox.acked", "inbox.reverted", "inbox.dead"];
|
|
118
|
+
/** What a message's sha commits to. Nulls are explicit, so absent and null hash alike. */
|
|
119
|
+
export interface InboxMessageIdentity {
|
|
120
|
+
readonly session_id: string;
|
|
121
|
+
readonly sender_kind: InboxSenderKind;
|
|
122
|
+
/** The sending agent (sender_kind agent), else null. */
|
|
123
|
+
readonly sender_agent_id: string | null;
|
|
124
|
+
/** The owner an agent sends for, from the allowlist row (never from the caller), else null. */
|
|
125
|
+
readonly on_behalf_of: string | null;
|
|
126
|
+
/** The question approval this message answers, else null. */
|
|
127
|
+
readonly in_reply_to: string | null;
|
|
128
|
+
readonly body: string;
|
|
129
|
+
}
|
|
130
|
+
/** The sha preimage: canonicalJson of the identity plus `v: 1`. */
|
|
131
|
+
export declare function inboxShaPreimage(m: InboxMessageIdentity): string;
|
|
132
|
+
/**
|
|
133
|
+
* A message's sha: sha256 of inboxShaPreimage, lowercase hex. The api computes it at send. The same
|
|
134
|
+
* sender sending the same body to the same session while an earlier copy is still open gets that
|
|
135
|
+
* copy back (coalesced); it is the value the seat stamps as `inbox=<sha>` and the resolver lists in
|
|
136
|
+
* `inbox_open`.
|
|
137
|
+
*/
|
|
138
|
+
export declare function inboxSha(m: InboxMessageIdentity): Promise<string>;
|
|
139
|
+
/** A UTF-8 body within the limits: 1..INBOX_BODY_MAX_BYTES bytes, no control character but TAB, LF, CR. */
|
|
140
|
+
export declare function inboxBodyOk(body: unknown): body is string;
|
|
141
|
+
/** The first line of every delivery text: `[mnemom inbox <sha>]`, then who sent it. */
|
|
142
|
+
export declare const INBOX_MARKER_RE: RegExp;
|
|
143
|
+
export interface InboxDeliveryInput {
|
|
144
|
+
readonly sha: string;
|
|
145
|
+
readonly sender_kind: InboxSenderKind;
|
|
146
|
+
/** The allowlist row's label, else the agent id; ignored for the owner. */
|
|
147
|
+
readonly sender_label: string | null;
|
|
148
|
+
readonly in_reply_to: string | null;
|
|
149
|
+
readonly body: string;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The exact text the seat is given (the api renders it in exec_inbox_take; the daemon pastes it
|
|
153
|
+
* verbatim). Line 1 is the marker and the sender, line 2 is empty, the body follows unchanged:
|
|
154
|
+
* `[mnemom inbox <sha>] from the owner`
|
|
155
|
+
* `[mnemom inbox <sha>] from agent <label> on behalf of the owner`
|
|
156
|
+
* and ` (answer to question <approval_id>)` when the message answers one. The marker is read from
|
|
157
|
+
* line 1 only (inboxMarkerOf), so a body cannot pose as another message.
|
|
158
|
+
*/
|
|
159
|
+
export declare function inboxDeliveryText(m: InboxDeliveryInput): string;
|
|
160
|
+
/**
|
|
161
|
+
* The sha a prompt carries, read from its first line only, or null. The seat proxy stamps
|
|
162
|
+
* `inbox=<sha>` on the turn entry whose text this returns non-null for. Restrict-only: a stamp only
|
|
163
|
+
* makes a turn unattended, and the gateway admits it only while the sha is in `inbox_open`.
|
|
164
|
+
*/
|
|
165
|
+
export declare function inboxMarkerOf(text: string): string | null;
|
|
166
|
+
/** POST own_inbox_send body: exactly {text, idempotency_key}. Sender and on_behalf_of come from the credential and the allowlist, never the body. */
|
|
167
|
+
export declare const INBOX_SEND_BODY_KEYS: readonly ["text", "idempotency_key"];
|
|
168
|
+
/** A send body: exactly INBOX_SEND_BODY_KEYS, text passing inboxBodyOk, idempotency_key INBOX_IDEMPOTENCY_KEY_RE. */
|
|
169
|
+
export declare function inboxSendBodyOk(v: unknown): boolean;
|
|
170
|
+
/**
|
|
171
|
+
* The 200 answer of own_inbox_send, exactly these keys:
|
|
172
|
+
* - inbox_id, sha: the message (a coalesced or deduped send names the earlier, still-open copy);
|
|
173
|
+
* - status: its INBOX_STATUSES value now;
|
|
174
|
+
* - coalesced: an open message with this sha already existed, nothing new was stored;
|
|
175
|
+
* - deduped: this idempotency_key was sent before, this is that send's message;
|
|
176
|
+
* - sender_kind, sender_agent_id, on_behalf_of: as stored (the owner's user id for an agent send);
|
|
177
|
+
* - expires_at: when an unacked message goes dead.
|
|
178
|
+
* A refusal is a durable error (INBOX_REJECT_CODES), never a 200.
|
|
179
|
+
*/
|
|
180
|
+
export declare const INBOX_SEND_RESPONSE: Readonly<{
|
|
181
|
+
inbox_id: "uuid";
|
|
182
|
+
sha: "hex64";
|
|
183
|
+
status: "inbox_status";
|
|
184
|
+
coalesced: "boolean";
|
|
185
|
+
deduped: "boolean";
|
|
186
|
+
sender_kind: "inbox_sender_kind";
|
|
187
|
+
sender_agent_id: "agent_id|null";
|
|
188
|
+
on_behalf_of: "string|null";
|
|
189
|
+
expires_at: "timestamp";
|
|
190
|
+
}>;
|
|
191
|
+
export declare function inboxSendResponseOk(v: unknown): boolean;
|
|
192
|
+
/**
|
|
193
|
+
* One own_inbox_list item, exactly these keys; content-free (no body). GET own_inbox_list answers
|
|
194
|
+
* `{messages: [item, ...]}`, newest first, at most INBOX_LIST_LIMIT.
|
|
195
|
+
*/
|
|
196
|
+
export declare const INBOX_LIST_ITEM: Readonly<{
|
|
197
|
+
inbox_id: "uuid";
|
|
198
|
+
sha: "hex64";
|
|
199
|
+
status: "inbox_status";
|
|
200
|
+
sender_kind: "inbox_sender_kind";
|
|
201
|
+
sender_agent_id: "agent_id|null";
|
|
202
|
+
on_behalf_of: "string|null";
|
|
203
|
+
in_reply_to: "uuid|null";
|
|
204
|
+
body_bytes: "integer>=1";
|
|
205
|
+
delivery_count: "integer";
|
|
206
|
+
dead_reason: "inbox_dead_reason|null";
|
|
207
|
+
created_at: "timestamp";
|
|
208
|
+
delivered_at: "timestamp|null";
|
|
209
|
+
acked_at: "timestamp|null";
|
|
210
|
+
expires_at: "timestamp";
|
|
211
|
+
}>;
|
|
212
|
+
export declare function inboxListItemOk(v: unknown): boolean;
|
|
213
|
+
export declare function inboxListResponseOk(v: unknown): boolean;
|
|
214
|
+
/** POST own_inbox_sender_add body: agent_id required, label optional. */
|
|
215
|
+
export declare const INBOX_SENDER_ADD_BODY_KEYS: readonly ["agent_id", "label"];
|
|
216
|
+
export declare function inboxSenderAddBodyOk(v: unknown): boolean;
|
|
217
|
+
/** DELETE own_inbox_sender_remove body: exactly {agent_id}. */
|
|
218
|
+
export declare const INBOX_SENDER_REMOVE_BODY_KEYS: readonly ["agent_id"];
|
|
219
|
+
export declare function inboxSenderRemoveBodyOk(v: unknown): boolean;
|
|
220
|
+
/**
|
|
221
|
+
* One allowlisted sender, exactly these keys. The allowlist belongs to the recipient AGENT (it
|
|
222
|
+
* outlives any one session); the routes reach it through a session the owner owns. added_by is the
|
|
223
|
+
* owner's user id (null only after a DSR erase).
|
|
224
|
+
*/
|
|
225
|
+
export declare const INBOX_SENDER_ITEM: Readonly<{
|
|
226
|
+
sender_agent_id: "agent_id";
|
|
227
|
+
label: "label|null";
|
|
228
|
+
added_by: "string|null";
|
|
229
|
+
created_at: "timestamp";
|
|
230
|
+
}>;
|
|
231
|
+
export declare function inboxSenderItemOk(v: unknown): boolean;
|
|
232
|
+
/** GET own_inbox_senders: exactly {recipient_agent_id, senders}, the live (unrevoked) rows. */
|
|
233
|
+
export declare function inboxSendersResponseOk(v: unknown): boolean;
|
|
234
|
+
/**
|
|
235
|
+
* POST own_inbox_sender_add / DELETE own_inbox_sender_remove answer: exactly
|
|
236
|
+
* {recipient_agent_id, sender_agent_id, changed}; changed false when the row was already live
|
|
237
|
+
* (add) or already absent or revoked (remove).
|
|
238
|
+
*/
|
|
239
|
+
export declare function inboxSenderChangeResponseOk(v: unknown): boolean;
|
|
240
|
+
/**
|
|
241
|
+
* GET exec_inbox: a content-free summary for a session the executor is home to or holds, exactly
|
|
242
|
+
* {admitted, delivered, oldest_admitted_at}. The daemon reads it to decide whether a parked homed
|
|
243
|
+
* session has work to claim; it marks nothing delivered.
|
|
244
|
+
*/
|
|
245
|
+
export declare function inboxSummaryResponseOk(v: unknown): boolean;
|
|
246
|
+
/** POST exec_inbox_take body: epoch and nonce (the live lease's) required, limit optional. */
|
|
247
|
+
export declare const INBOX_TAKE_BODY_KEYS: readonly ["epoch", "nonce", "limit"];
|
|
248
|
+
export declare function inboxTakeBodyOk(v: unknown): boolean;
|
|
249
|
+
/**
|
|
250
|
+
* One taken message, exactly these keys. `text` is inboxDeliveryText of the message, rendered by
|
|
251
|
+
* the api; the daemon pastes it verbatim. attempt is the message's delivery_count after this take.
|
|
252
|
+
*/
|
|
253
|
+
export declare const INBOX_TAKE_ITEM: Readonly<{
|
|
254
|
+
inbox_id: "uuid";
|
|
255
|
+
sha: "hex64";
|
|
256
|
+
text: "string";
|
|
257
|
+
attempt: "integer>=1";
|
|
258
|
+
sender_kind: "inbox_sender_kind";
|
|
259
|
+
sender_agent_id: "agent_id|null";
|
|
260
|
+
on_behalf_of: "string|null";
|
|
261
|
+
in_reply_to: "uuid|null";
|
|
262
|
+
created_at: "timestamp";
|
|
263
|
+
}>;
|
|
264
|
+
export declare function inboxTakeItemOk(v: unknown): boolean;
|
|
265
|
+
/** POST exec_inbox_take answer: exactly {messages}, oldest first, at most the body's limit. */
|
|
266
|
+
export declare function inboxTakeResponseOk(v: unknown): boolean;
|
|
267
|
+
/** POST exec_inbox_ack body: exactly {epoch, nonce, inbox_id, sha}. */
|
|
268
|
+
export declare const INBOX_ACK_BODY_KEYS: readonly ["epoch", "nonce", "inbox_id", "sha"];
|
|
269
|
+
export declare function inboxAckBodyOk(v: unknown): boolean;
|
|
270
|
+
/**
|
|
271
|
+
* POST exec_inbox_ack answer: exactly {inbox_id, sha, status: "acked", deduped}. A message that is
|
|
272
|
+
* not delivered to this session at this epoch with this sha is 409 durable_inbox_not_open.
|
|
273
|
+
*/
|
|
274
|
+
export declare function inboxAckResponseOk(v: unknown): boolean;
|
|
275
|
+
/** POST exec_inbox_release body: exactly {epoch, nonce, inbox_id, sha, reason}. */
|
|
276
|
+
export declare const INBOX_RELEASE_BODY_KEYS: readonly ["epoch", "nonce", "inbox_id", "sha", "reason"];
|
|
277
|
+
export declare function inboxReleaseBodyOk(v: unknown): boolean;
|
|
278
|
+
/**
|
|
279
|
+
* POST exec_inbox_release answer: exactly {inbox_id, sha, status}. The api moves a message delivered
|
|
280
|
+
* to this session at this epoch back to `admitted` and journals inbox.reverted {inbox_id, sha,
|
|
281
|
+
* reason}, so the next take offers it again; when its delivery_count already reached
|
|
282
|
+
* INBOX_DELIVERY_LIMIT it goes `dead` instead (inbox.dead delivery_limit). Either way its sha leaves
|
|
283
|
+
* `inbox_open` in the same transaction. Anything else is 409 durable_inbox_not_open.
|
|
284
|
+
*/
|
|
285
|
+
export declare function inboxReleaseResponseOk(v: unknown): boolean;
|
|
286
|
+
/** The journal idempotency keys the api uses for inbox events (one event per fact). */
|
|
287
|
+
export declare const inboxIdempotencyKeys: {
|
|
288
|
+
readonly admitted: (inboxId: string) => string;
|
|
289
|
+
readonly coalesced: (inboxId: string, idempotencyKey: string) => string;
|
|
290
|
+
/**
|
|
291
|
+
* A refused send: keyed on the caller's idempotency_key when it is well-formed, else on the api's
|
|
292
|
+
* own request id (a body_invalid refusal may carry no usable key).
|
|
293
|
+
*/
|
|
294
|
+
readonly rejected: (sessionId: string, idempotencyKey: unknown, requestId: string) => string;
|
|
295
|
+
readonly delivered: (inboxId: string, epoch: number, attempt: number) => string;
|
|
296
|
+
readonly acked: (inboxId: string) => string;
|
|
297
|
+
readonly reverted: (inboxId: string, epoch: number, attempt: number) => string;
|
|
298
|
+
readonly dead: (inboxId: string) => string;
|
|
299
|
+
};
|