@cotal-ai/core 0.17.0 → 0.19.0

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 (112) hide show
  1. package/dist/acls.d.ts +0 -7
  2. package/dist/acls.d.ts.map +1 -1
  3. package/dist/acls.js +10 -7
  4. package/dist/acls.js.map +1 -1
  5. package/dist/agui-kind.d.ts +71 -0
  6. package/dist/agui-kind.d.ts.map +1 -0
  7. package/dist/agui-kind.js +95 -0
  8. package/dist/agui-kind.js.map +1 -0
  9. package/dist/endpoint-action.d.ts +3 -3
  10. package/dist/endpoint-action.js +4 -4
  11. package/dist/endpoint-action.js.map +1 -1
  12. package/dist/endpoint-binding.d.ts +48 -5
  13. package/dist/endpoint-binding.d.ts.map +1 -1
  14. package/dist/endpoint-binding.js +82 -6
  15. package/dist/endpoint-binding.js.map +1 -1
  16. package/dist/endpoint-cluster.d.ts +20 -0
  17. package/dist/endpoint-cluster.d.ts.map +1 -1
  18. package/dist/endpoint-cluster.js +47 -0
  19. package/dist/endpoint-cluster.js.map +1 -1
  20. package/dist/endpoint-contract-store.d.ts +6 -0
  21. package/dist/endpoint-contract-store.d.ts.map +1 -1
  22. package/dist/endpoint-contract-store.js +21 -2
  23. package/dist/endpoint-contract-store.js.map +1 -1
  24. package/dist/endpoint-effects.d.ts +73 -0
  25. package/dist/endpoint-effects.d.ts.map +1 -0
  26. package/dist/endpoint-effects.js +46 -0
  27. package/dist/endpoint-effects.js.map +1 -0
  28. package/dist/endpoint-envelope.d.ts +32 -1
  29. package/dist/endpoint-envelope.d.ts.map +1 -1
  30. package/dist/endpoint-envelope.js +56 -2
  31. package/dist/endpoint-envelope.js.map +1 -1
  32. package/dist/endpoint-epname.d.ts +62 -0
  33. package/dist/endpoint-epname.d.ts.map +1 -0
  34. package/dist/endpoint-epname.js +273 -0
  35. package/dist/endpoint-epname.js.map +1 -0
  36. package/dist/endpoint-error.d.ts +155 -1
  37. package/dist/endpoint-error.d.ts.map +1 -1
  38. package/dist/endpoint-error.js +114 -2
  39. package/dist/endpoint-error.js.map +1 -1
  40. package/dist/endpoint-goaleff.d.ts +56 -0
  41. package/dist/endpoint-goaleff.d.ts.map +1 -0
  42. package/dist/endpoint-goaleff.js +212 -0
  43. package/dist/endpoint-goaleff.js.map +1 -0
  44. package/dist/endpoint-grants.d.ts +46 -0
  45. package/dist/endpoint-grants.d.ts.map +1 -1
  46. package/dist/endpoint-grants.js +68 -0
  47. package/dist/endpoint-grants.js.map +1 -1
  48. package/dist/endpoint-invoke.d.ts +1 -1
  49. package/dist/endpoint-invoke.d.ts.map +1 -1
  50. package/dist/endpoint-invoke.js +162 -27
  51. package/dist/endpoint-invoke.js.map +1 -1
  52. package/dist/endpoint-journal.d.ts +103 -0
  53. package/dist/endpoint-journal.d.ts.map +1 -1
  54. package/dist/endpoint-journal.js +290 -0
  55. package/dist/endpoint-journal.js.map +1 -1
  56. package/dist/endpoint-records.d.ts.map +1 -1
  57. package/dist/endpoint-records.js +37 -0
  58. package/dist/endpoint-records.js.map +1 -1
  59. package/dist/endpoint-serve.d.ts.map +1 -1
  60. package/dist/endpoint-serve.js +45 -1
  61. package/dist/endpoint-serve.js.map +1 -1
  62. package/dist/endpoint-subjects.d.ts +10 -0
  63. package/dist/endpoint-subjects.d.ts.map +1 -1
  64. package/dist/endpoint-subjects.js +10 -0
  65. package/dist/endpoint-subjects.js.map +1 -1
  66. package/dist/endpoint-verbs.d.ts +12 -3
  67. package/dist/endpoint-verbs.d.ts.map +1 -1
  68. package/dist/endpoint-verbs.js +113 -19
  69. package/dist/endpoint-verbs.js.map +1 -1
  70. package/dist/endpoint.d.ts +170 -6
  71. package/dist/endpoint.d.ts.map +1 -1
  72. package/dist/endpoint.js +472 -37
  73. package/dist/endpoint.js.map +1 -1
  74. package/dist/event-channel.d.ts +107 -0
  75. package/dist/event-channel.d.ts.map +1 -0
  76. package/dist/event-channel.js +139 -0
  77. package/dist/event-channel.js.map +1 -0
  78. package/dist/evict.d.ts +47 -0
  79. package/dist/evict.d.ts.map +1 -1
  80. package/dist/evict.js +191 -59
  81. package/dist/evict.js.map +1 -1
  82. package/dist/identity.d.ts +15 -0
  83. package/dist/identity.d.ts.map +1 -1
  84. package/dist/identity.js +34 -0
  85. package/dist/identity.js.map +1 -1
  86. package/dist/index.d.ts +5 -0
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +5 -0
  89. package/dist/index.js.map +1 -1
  90. package/dist/membership-feed.d.ts.map +1 -1
  91. package/dist/membership-feed.js +35 -12
  92. package/dist/membership-feed.js.map +1 -1
  93. package/dist/parts.d.ts +29 -5
  94. package/dist/parts.d.ts.map +1 -1
  95. package/dist/parts.js +46 -3
  96. package/dist/parts.js.map +1 -1
  97. package/dist/provision.d.ts +19 -7
  98. package/dist/provision.d.ts.map +1 -1
  99. package/dist/provision.js +75 -14
  100. package/dist/provision.js.map +1 -1
  101. package/dist/resolve.d.ts.map +1 -1
  102. package/dist/resolve.js +38 -0
  103. package/dist/resolve.js.map +1 -1
  104. package/dist/streams.d.ts +142 -3
  105. package/dist/streams.d.ts.map +1 -1
  106. package/dist/streams.js +192 -17
  107. package/dist/streams.js.map +1 -1
  108. package/dist/subjects.d.ts +49 -15
  109. package/dist/subjects.d.ts.map +1 -1
  110. package/dist/subjects.js +130 -15
  111. package/dist/subjects.js.map +1 -1
  112. package/package.json +5 -2
@@ -0,0 +1,273 @@
1
+ /**
2
+ * `epname` — the durable name claim (SPEC §13.4; the closed machine).
3
+ *
4
+ * A name is an identity that outlives the process holding it. The row answers three questions that
5
+ * a live process cannot answer about itself: who holds this name, which lifecycle it names, and
6
+ * WHICH INCARNATION owns the handle table for it. The third is the one that keeps being got wrong,
7
+ * because it is the only one whose answer is invisible from the row's own subject.
8
+ *
9
+ * TWO RULES THAT COST MORE THAN THEY LOOK.
10
+ *
11
+ * `runtimeOwner` IS MOVED, NOT DERIVED. It is written at `launching → live` from the executor that
12
+ * made the spawn call — recorded at the moment it becomes true rather than reconstructed later —
13
+ * and every subsequent edge CARRIES it. It is deliberately never re-derived from a slot row,
14
+ * because user mode has no slot row at all, so a derivation is unevaluable on a supported path,
15
+ * and an unevaluable predicate is one that either refuses forever or falls back to absence.
16
+ * `instanceId` alone will not do: an identity is not an incarnation, and a restarted process with
17
+ * the same id has an empty handle table, which is the absence of knowledge rather than knowledge
18
+ * of absence.
19
+ *
20
+ * `draining` HAS EXACTLY ONE EXIT, AND IT IS THE OPERATOR. The ordinary edge required its actor to
21
+ * be the row's `runtimeOwner` attesting that the runtime is gone. That actor cannot exist: an owner
22
+ * still alive has no queryable per-attempt handle to attest about, and a restarted one is a
23
+ * different incarnation. The edge was satisfiable only by the party least entitled to satisfy it,
24
+ * so it is removed rather than weakened — and `draining` is a state an operator clears by hand
25
+ * until a durable runtime-attempt token exists. That cost is real and is recorded rather than
26
+ * hidden inside a predicate that reads as satisfiable.
27
+ */
28
+ import { EpEnvelopeError } from "./endpoint-error.js";
29
+ function fail(message) {
30
+ throw new EpEnvelopeError("bad-request", `epname: ${message}`);
31
+ }
32
+ const BASE = ["v", "ts", "state", "claimant"];
33
+ /** The COMPLETE legal field set per state. § S2's variants are per-state for the reason § S1's are:
34
+ * a single broad object with everything optional cannot say that `executor` is present IFF a launch
35
+ * is in flight, and "present iff" is the only form in which that field is useful. */
36
+ const STATE_FIELDS = {
37
+ claimed: BASE,
38
+ launching: [...BASE, "lifecycleUid", "launchAttemptId", "executor"],
39
+ live: [...BASE, "lifecycleUid", "runtimeOwner"],
40
+ preserved: [...BASE, "lifecycleUid", "runtimeOwner"],
41
+ relaunching: [...BASE, "lifecycleUid", "launchAttemptId", "executor"],
42
+ draining: [...BASE, "lifecycleUid", "runtimeOwner", "enteredAt"],
43
+ released: BASE,
44
+ };
45
+ function parseIncarnation(v, what) {
46
+ if (typeof v !== "object" || v === null || Array.isArray(v))
47
+ fail(`\`${what}\` must be an object`);
48
+ const o = v;
49
+ const extra = Object.keys(o).filter((k) => k !== "instanceId" && k !== "processEpoch");
50
+ if (extra.length > 0)
51
+ fail(`unknown field(s) on \`${what}\`: ${extra.join(", ")}`);
52
+ if (typeof o.instanceId !== "string" || o.instanceId.length === 0)
53
+ fail(`\`${what}.instanceId\` must be a non-empty string`);
54
+ if (typeof o.processEpoch !== "number" || !Number.isSafeInteger(o.processEpoch) || o.processEpoch < 0)
55
+ fail(`\`${what}.processEpoch\` must be a non-negative safe integer — an incarnation, not an identity`);
56
+ return { instanceId: o.instanceId, processEpoch: o.processEpoch };
57
+ }
58
+ function parseClaimant(v) {
59
+ if (typeof v !== "object" || v === null || Array.isArray(v))
60
+ fail("`claimant` must be an object");
61
+ const o = v;
62
+ const legal = {
63
+ action: ["kind", "goalId", "gen"],
64
+ direct: ["kind", "instanceId", "processEpoch", "opId"],
65
+ incumbent: ["kind", "backfillId"],
66
+ };
67
+ const kind = o.kind;
68
+ // `Object.hasOwn`, not `in` — see the state check below.
69
+ if (typeof kind !== "string" || !Object.hasOwn(legal, kind))
70
+ fail(`unknown claimant kind ${JSON.stringify(kind)} — the legal set is action|direct|incumbent`);
71
+ const extra = Object.keys(o).filter((k) => !legal[kind].includes(k));
72
+ if (extra.length > 0)
73
+ fail(`unknown field(s) on a ${kind} claimant: ${extra.join(", ")}`);
74
+ const missing = legal[kind].filter((k) => !(k in o));
75
+ if (missing.length > 0)
76
+ fail(`a ${kind} claimant is missing: ${missing.join(", ")}`);
77
+ if (kind === "action") {
78
+ if (typeof o.goalId !== "string" || o.goalId.length === 0)
79
+ fail("`claimant.goalId` must be a non-empty string");
80
+ if (typeof o.gen !== "number" || !Number.isSafeInteger(o.gen))
81
+ fail("`claimant.gen` must be a safe integer");
82
+ return { kind: "action", goalId: o.goalId, gen: o.gen };
83
+ }
84
+ if (kind === "direct") {
85
+ if (typeof o.opId !== "string" || o.opId.length === 0)
86
+ fail("`claimant.opId` must be a non-empty string");
87
+ const inc = parseIncarnation({ instanceId: o.instanceId, processEpoch: o.processEpoch }, "claimant");
88
+ return { kind: "direct", instanceId: inc.instanceId, processEpoch: inc.processEpoch, opId: o.opId };
89
+ }
90
+ if (typeof o.backfillId !== "string" || o.backfillId.length === 0)
91
+ fail("`claimant.backfillId` must be a non-empty string");
92
+ return { kind: "incumbent", backfillId: o.backfillId };
93
+ }
94
+ /** Parse a row from CURRENT BYTES with no knowledge of history — which is the property that makes a
95
+ * sweeper able to act on a row it did not write. */
96
+ export function parseEpName(value) {
97
+ if (typeof value !== "object" || value === null || Array.isArray(value))
98
+ fail("row must be a JSON object");
99
+ const o = value;
100
+ const state = o.state;
101
+ // `Object.hasOwn`, NOT `in`: the `in` operator walks the PROTOTYPE CHAIN, so a row whose
102
+ // discriminant is `toString`, `constructor` or `hasOwnProperty` passed this test and then
103
+ // crashed with an uncontrolled TypeError instead of the declared bad-request refusal. An
104
+ // attacker-supplied string reaching a plain-object lookup is exactly where that matters.
105
+ if (typeof state !== "string" || !Object.hasOwn(STATE_FIELDS, state))
106
+ fail(`unknown state ${JSON.stringify(state)} — the legal set is ${Object.keys(STATE_FIELDS).join("|")}`);
107
+ const s = state;
108
+ const legal = STATE_FIELDS[s];
109
+ const unknown = Object.keys(o).filter((k) => !legal.includes(k));
110
+ if (unknown.length > 0)
111
+ fail(`unknown field(s) for state ${s}: ${unknown.join(", ")} — each state names the COMPLETE legal set`);
112
+ const missing = legal.filter((k) => !(k in o));
113
+ if (missing.length > 0)
114
+ fail(`state ${s} is missing required field(s): ${missing.join(", ")}`);
115
+ if (o.v !== 1)
116
+ fail("`v` must be exactly 1");
117
+ if (typeof o.ts !== "number" || !Number.isSafeInteger(o.ts))
118
+ fail("`ts` must be a safe integer");
119
+ // `claimant` is NON-NULL in every state but `released`. A `live` row with a null claimant cannot
120
+ // support the identity checks every release depends on, so admitting one moves the failure to
121
+ // whichever release reads it next — far from the write that caused it.
122
+ const row = { v: 1, ts: o.ts, state: s, claimant: null };
123
+ if (s === "released") {
124
+ if (o.claimant !== null)
125
+ fail("`released` REQUIRES a null `claimant` — the name is unheld");
126
+ }
127
+ else {
128
+ if (o.claimant === null)
129
+ fail(`state ${s} REQUIRES a non-null \`claimant\`: a held name with no holder cannot answer the identity check every release makes`);
130
+ row.claimant = parseClaimant(o.claimant);
131
+ }
132
+ if (legal.includes("lifecycleUid")) {
133
+ if (typeof o.lifecycleUid !== "string" || o.lifecycleUid.length === 0)
134
+ fail("`lifecycleUid` must be a non-empty string");
135
+ row.lifecycleUid = o.lifecycleUid;
136
+ }
137
+ if (legal.includes("launchAttemptId")) {
138
+ if (typeof o.launchAttemptId !== "string" || o.launchAttemptId.length === 0)
139
+ fail("`launchAttemptId` must be a non-empty string");
140
+ row.launchAttemptId = o.launchAttemptId;
141
+ }
142
+ if (legal.includes("executor"))
143
+ row.executor = parseIncarnation(o.executor, "executor");
144
+ if (legal.includes("runtimeOwner"))
145
+ row.runtimeOwner = parseIncarnation(o.runtimeOwner, "runtimeOwner");
146
+ if (legal.includes("enteredAt")) {
147
+ if (typeof o.enteredAt !== "number" || !Number.isSafeInteger(o.enteredAt))
148
+ fail("`enteredAt` must be a safe integer");
149
+ row.enteredAt = o.enteredAt;
150
+ }
151
+ return row;
152
+ }
153
+ /** The § S2 edge table. Every legal transition, and nothing else.
154
+ *
155
+ * `live → relaunching` IS ABSENT ON PURPOSE. Round 11 had it, and it reused ONE state for both a
156
+ * running agent and a stopped one: the holder could rotate the nonce and spawn a second process,
157
+ * and a crash after the spawn call was byte-identical to the state before it. Both are exactly
158
+ * what `launching` exists to prevent, reintroduced one level down. Ordinary `live` authorizes NO
159
+ * relaunch; only `preserved` does.
160
+ *
161
+ * `draining → released` carries EXACTLY ONE actor, the operator. See the module header. */
162
+ const EDGES = [
163
+ { from: "—", to: "claimed", actors: ["allocator"] },
164
+ { from: "released", to: "claimed", actors: ["allocator"] },
165
+ { from: "claimed", to: "launching", actors: ["claimant"] },
166
+ { from: "launching", to: "live", actors: ["claimant"] },
167
+ { from: "live", to: "preserved", actors: ["holder"] },
168
+ { from: "preserved", to: "relaunching", actors: ["holder"] },
169
+ { from: "relaunching", to: "live", actors: ["holder"] },
170
+ { from: "claimed", to: "released", actors: ["claimant", "sweeper"] },
171
+ { from: "launching", to: "draining", actors: ["sweeper"] },
172
+ { from: "live", to: "draining", actors: ["sweeper"] },
173
+ { from: "preserved", to: "draining", actors: ["sweeper"] },
174
+ { from: "relaunching", to: "draining", actors: ["sweeper"] },
175
+ { from: "draining", to: "released", actors: ["operator"] },
176
+ { from: "—", to: "live", actors: ["cutover"] },
177
+ ];
178
+ function sameInc(a, b) {
179
+ if (a === undefined && b === undefined)
180
+ return true;
181
+ if (a === undefined || b === undefined)
182
+ return false;
183
+ return a.instanceId === b.instanceId && a.processEpoch === b.processEpoch;
184
+ }
185
+ function sameClaimant(a, b) {
186
+ return JSON.stringify(a) === JSON.stringify(b);
187
+ }
188
+ /**
189
+ * Validate a transition against § S2. `prev` is `null` for the two creation edges.
190
+ *
191
+ * `gateSatisfied` is the caller's attestation that the edge's external precondition holds — the
192
+ * `goaleff` election won, the process authoritatively quiesced, the executor dead by the gate
193
+ * predicate, the operator's host-level attestation. It is a REQUIRED argument for the same reason
194
+ * `terminalExists` is in § S1: a precondition the caller can satisfy by not mentioning it is not a
195
+ * precondition.
196
+ */
197
+ export function assertEpNameEdge(prev, next, actor, opts) {
198
+ const from = prev === null ? "—" : prev.state;
199
+ const to = next.state;
200
+ const edge = EDGES.find((e) => e.from === from && e.to === to);
201
+ if (edge === undefined) {
202
+ const legal = EDGES.filter((e) => e.from === from).map((e) => e.to);
203
+ fail(legal.length === 0
204
+ ? `\`${from}\` has no outgoing edge at all (attempted ${from} → ${to})`
205
+ : `${from} → ${to} is not a legal edge; from \`${from}\` the legal set is ${legal.join(", ")}`);
206
+ }
207
+ // CLOSED AT RUNTIME for the same reason as `goaleff`: an unknown role must be refused, not
208
+ // silently measured against a list it cannot be in. Here it happens to fail closed via
209
+ // `includes`, but relying on that is relying on an accident of the check's shape.
210
+ const ROLES = ["claimant", "holder", "sweeper", "operator", "allocator", "cutover"];
211
+ if (!ROLES.includes(actor.role))
212
+ fail(`unknown actor role ${JSON.stringify(actor.role)} — the legal set is ${ROLES.join("|")}`);
213
+ if (!edge.actors.includes(actor.role))
214
+ fail(`a ${actor.role} may not take ${from} → ${to}; that edge belongs to: ${edge.actors.join(", ")}`);
215
+ if (!opts.gateSatisfied)
216
+ fail(`${from} → ${to} requires its gate to hold FIRST, and the caller did not attest it`);
217
+ if (actor.role === "holder" && prev !== null && actor.lifecycleUid !== prev.lifecycleUid)
218
+ fail(`this edge is for the EXACT \`lifecycleUid\` holder only: row ${JSON.stringify(prev.lifecycleUid)}, `
219
+ + `actor ${JSON.stringify(actor.lifecycleUid)}`);
220
+ // ---- creation edges ------------------------------------------------------------------------
221
+ if (prev === null) {
222
+ if (to === "live") {
223
+ // The cutover backfill. `runtimeOwner` comes from the incumbent's LIVE gate row, and if no
224
+ // such row names an incarnation the key is NOT backfilled — it is recorded as a casualty. A
225
+ // `live` row whose owner is unknown is the row § R15-A exists to forbid, and inventing one
226
+ // here puts the unevaluable value in the durable record where every later release reads it.
227
+ if (next.runtimeOwner === undefined)
228
+ fail("the cutover may not backfill a `live` row without a `runtimeOwner` read from the incumbent's "
229
+ + "live gate row — record a cutover CASUALTY instead of inventing an owner");
230
+ if (next.claimant?.kind !== "incumbent")
231
+ fail("a cutover backfill claims as `incumbent`; any other claimant kind is a different edge");
232
+ }
233
+ return;
234
+ }
235
+ // ---- claimant / lifecycle immutability -----------------------------------------------------
236
+ const reclaim = from === "released" && to === "claimed";
237
+ const releasing = to === "released";
238
+ if (!reclaim && !releasing && !sameClaimant(prev.claimant, next.claimant))
239
+ fail(`\`claimant\` is immutable while a claim is held: ${JSON.stringify(prev.claimant)} → ${JSON.stringify(next.claimant)}`);
240
+ if (releasing && next.claimant !== null)
241
+ fail("a release CLEARS `claimant`");
242
+ if (prev.lifecycleUid !== undefined && next.lifecycleUid !== undefined
243
+ && prev.lifecycleUid !== next.lifecycleUid)
244
+ fail(`\`lifecycleUid\` is immutable while a claim is held: ${prev.lifecycleUid} → ${next.lifecycleUid}`);
245
+ // ---- runtimeOwner: MOVED on the launch-completing edges, CARRIED everywhere else ------------
246
+ const completesLaunch = (from === "launching" || from === "relaunching") && to === "live";
247
+ const drainsFromLaunch = (from === "launching" || from === "relaunching") && to === "draining";
248
+ if (completesLaunch || drainsFromLaunch) {
249
+ // The FULL incarnation moves, both fields. `instanceId` alone is an identity, and the row would
250
+ // then name a process rather than the run of it that holds the handle table.
251
+ if (!sameInc(next.runtimeOwner, prev.executor))
252
+ fail(`${from} → ${to} MOVES the full \`executor\` into \`runtimeOwner\`: expected `
253
+ + `${JSON.stringify(prev.executor)}, got ${JSON.stringify(next.runtimeOwner)} — `
254
+ + `an \`instanceId\` without its \`processEpoch\` is an identity, not the incarnation that holds the handle`);
255
+ if (next.launchAttemptId !== undefined)
256
+ fail(`${from} → ${to} CLEARS \`launchAttemptId\``);
257
+ }
258
+ else if (to === "draining" || to === "preserved" || to === "live") {
259
+ // CARRIED, never re-derived. The derivation a reader reaches for is the slot row's
260
+ // ownerInstanceId, and user mode has no slot row at all — so it is unevaluable on a supported
261
+ // path, which is the same failure as a predicate whose actor cannot exist.
262
+ if (!sameInc(prev.runtimeOwner, next.runtimeOwner))
263
+ fail(`${from} → ${to} CARRIES \`runtimeOwner\` unchanged (${JSON.stringify(prev.runtimeOwner)} → `
264
+ + `${JSON.stringify(next.runtimeOwner)}) — it is installed once, when the spawn call returns, and never re-derived`);
265
+ }
266
+ if (to === "draining" && next.enteredAt === undefined)
267
+ fail("`draining` SETS `enteredAt`");
268
+ if (from === "draining" && to === "released") {
269
+ if (next.lifecycleUid !== undefined || next.runtimeOwner !== undefined || next.enteredAt !== undefined)
270
+ fail("the operator edge CLEARS `lifecycleUid`, `runtimeOwner` and `enteredAt`");
271
+ }
272
+ }
273
+ //# sourceMappingURL=endpoint-epname.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint-epname.js","sourceRoot":"","sources":["../src/endpoint-epname.ts"],"names":[],"mappings":"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"}
@@ -15,11 +15,164 @@ export interface EpErrorDetail {
15
15
  kind: string;
16
16
  [key: string]: unknown;
17
17
  }
18
+ /**
19
+ * `details[].kind` for a refusal raised because a responder ANSWERED but was not the incarnation
20
+ * this handle resolved against (§13.2): `failed-precondition` for a DIFFERENT instance, `expired`
21
+ * for the SAME instance at another EPOCH. It marks what the code alone cannot say — **the request
22
+ * drew an attributed reply from a live responder** — which rules out the reading "the incarnation
23
+ * is gone, resolve again". The reply may be a refusal or a result and the marker does not say
24
+ * which, so a retry here is a SECOND ATTEMPT that may duplicate an effect, never a repair.
25
+ */
26
+ export declare const EP_UNBOUND_RESPONDER = "ai.cotal.ep.unbound-responder";
27
+ /** The {@link EP_UNBOUND_RESPONDER} payload. Two producers: the describe-bound currency check (a
28
+ * DIFFERENT instance) sets `answeredBy`/`boundTo`; the stale-epoch refusal (the SAME instance at
29
+ * another epoch) sets `answeredEpoch`/`heldEpoch` and says in `reference` which epoch `heldEpoch`
30
+ * is — `bind`, this caller's own resolve (so the handle is the stale side), or `registry`, the
31
+ * responder's current registered epoch (so a responder behind it is superseded and still
32
+ * answering). `boundTo` is set only where a bind exists. */
33
+ export interface EpUnboundResponderDetail extends EpErrorDetail {
34
+ kind: typeof EP_UNBOUND_RESPONDER;
35
+ endpoint: string;
36
+ command: string;
37
+ /** The instance whose attributed reply was refused. */
38
+ answeredBy: string;
39
+ /** The instance this handle resolved against; absent when the caller holds no bind. */
40
+ boundTo?: string;
41
+ answeredEpoch?: number;
42
+ heldEpoch?: number;
43
+ reference?: "bind" | "registry";
44
+ /** Whether the call addressed one instance (`inst` rail) rather than the class queue. */
45
+ pinned: boolean;
46
+ }
47
+ /** True iff `e` carries the {@link EP_UNBOUND_RESPONDER} marker: a responder ANSWERED the request
48
+ * (an attributed reply, which may be a refusal or a result), so retrying it is a second attempt
49
+ * that may duplicate an effect, not a repair. */
50
+ export declare function respondedButUnbound(e: unknown): boolean;
51
+ /**
52
+ * `details[].kind` for a refusal raised because NO VALID REPLY REACHED THE CALLER: no responder on
53
+ * the subject, or the deadline elapsed with nothing attributed to the request's nonce. A frame that
54
+ * fails the request binding is dropped and is not an answer, so the marker means nothing
55
+ * ATTRIBUTABLE arrived, not that no bytes did. `unavailable`/`deadline-exceeded` alone is not
56
+ * evidence of silence — the same codes are raised where something did answer, or where a
57
+ * caller-side read failed after the describe — so a consumer stating a reachability verdict keys on
58
+ * this marker, never on the code.
59
+ */
60
+ export declare const EP_UNANSWERED = "ai.cotal.ep.unanswered";
61
+ /** The {@link EP_UNANSWERED} payload: the call that drew no reply. */
62
+ export interface EpUnansweredDetail extends EpErrorDetail {
63
+ kind: typeof EP_UNANSWERED;
64
+ endpoint: string;
65
+ command: string;
66
+ }
67
+ /** True iff `e` carries the {@link EP_UNANSWERED} marker: no valid reply reached the caller (no
68
+ * responder, or the deadline elapsed with nothing attributed to the request). */
69
+ export declare function unansweredRequest(e: unknown): boolean;
70
+ /**
71
+ * `details[].kind` for a refusal raised because a caller-side read of the SERVICE REGISTRY failed
72
+ * or did not settle: the scatter's freeze (§13.5) or its mandatory reconcile. It marks the failure
73
+ * as the caller's own, establishing NOTHING about the responders — the freeze fails before any
74
+ * request goes out, and the reconcile fails after the gather, where members may all have answered
75
+ * and their replies simply could not be classified. A consumer must not read it as their silence.
76
+ */
77
+ export declare const EP_REGISTRY_READ_FAILED = "ai.cotal.ep.registry-read-failed";
78
+ /** The {@link EP_REGISTRY_READ_FAILED} payload: the call whose registry read failed. */
79
+ export interface EpRegistryReadFailedDetail extends EpErrorDetail {
80
+ kind: typeof EP_REGISTRY_READ_FAILED;
81
+ endpoint: string;
82
+ command: string;
83
+ }
84
+ /** True iff `e` carries the {@link EP_REGISTRY_READ_FAILED} marker: a caller-side registry read
85
+ * failed; the responders were not the failure. */
86
+ export declare function registryReadFailed(e: unknown): boolean;
87
+ /**
88
+ * `details[].kind` for a refusal raised by the RESPONDER because the request declared a bound
89
+ * incarnation (`bind`, §13.3) that is not this instance: `failed-precondition` for a different
90
+ * instance, `expired` for the same instance at another epoch. It marks what no caller-side check
91
+ * can establish: **the command did not run, and no effect of it exists.**
92
+ *
93
+ * Set before the handler, before args validation, and before any seam that can consume a one-use
94
+ * proof, by the only party that knows which incarnation it is. {@link EP_UNBOUND_RESPONDER} is
95
+ * raised by the CALLER on the reply, after the responder has already acted — a report, not a
96
+ * guard. So a caller holding THIS marker may re-resolve and re-issue without risking a duplicate,
97
+ * which is exactly what a caller holding that one must not do.
98
+ */
99
+ export declare const EP_BIND_REFUSED = "ai.cotal.ep.bind-refused";
100
+ /** The {@link EP_BIND_REFUSED} payload: the incarnation the caller bound, and the one that
101
+ * refused. Both ids are stated because either field alone can be the mismatching one — a
102
+ * different instance, or the same instance at any other epoch — and the reader needs to see
103
+ * which. */
104
+ export interface EpBindRefusedDetail extends EpErrorDetail {
105
+ kind: typeof EP_BIND_REFUSED;
106
+ endpoint: string;
107
+ command: string;
108
+ /** What the request's `bind` block declared. */
109
+ boundTo: {
110
+ instanceId: string;
111
+ epoch: number;
112
+ };
113
+ /** The refusing instance's own identity. */
114
+ servedBy: {
115
+ instanceId: string;
116
+ epoch: number;
117
+ };
118
+ }
119
+ /** True iff an `EpError` CARRIES the {@link EP_BIND_REFUSED} marker, saying nothing about whether
120
+ * the marker is believable. It is the claim's presence, not its acceptance.
121
+ *
122
+ * The two questions come apart, and conflating them is what this pair exists to prevent. Whether a
123
+ * caller may ACT on a bind refusal — re-issue a command it would otherwise never repeat — needs
124
+ * the marker AND an explicit `not-executed`, which is {@link replyRefusedBeforeEffect}. Whether a
125
+ * reply is CHECKED for self-consistency needs only the claim, because the contradiction being
126
+ * checked is between the reply's BODY and the subject the broker pinned, and that is a
127
+ * contradiction whatever the outcome field says — or does not say.
128
+ *
129
+ * Gating the checks on the stronger predicate meant a reply could skip them by OMITTING a field,
130
+ * so the least credible shape drew the least scrutiny. */
131
+ export declare function bindRefusalMarked(e: EpError | undefined): boolean;
132
+ /** True iff an `EpError` carries the {@link EP_BIND_REFUSED} marker: a responder refused BEFORE
133
+ * executing, because it is not the incarnation the caller bound — the command did not run.
134
+ *
135
+ * It takes an `EpError` and not a thrown value, unlike its sibling predicates, because this
136
+ * refusal never arrives as a throw: it is the responder's own application-level failure and
137
+ * those ride the reply (§13.5). A consumer reads it off `reply.error`.
138
+ *
139
+ * A REPLY THAT CONTRADICTS ITSELF IS NOT A REFUSAL. The marker IS the assertion that the command
140
+ * did not run, and {@link EpError.outcome} says a responder refusing before dispatch MUST carry
141
+ * `not-executed` — but {@link EpBindRefusedDetail} carries no outcome of its own, so nothing in the
142
+ * type stops a reply pairing the marker with `executed`. That combination is not merely odd: the
143
+ * only consumer of this predicate re-issues a command **without** the {@link isRepeatSafeCommand}
144
+ * gate, on the strength of the marker, so resolving the contradiction toward "refused" re-sends a
145
+ * command the reply just said had ALREADY RUN. A present outcome that disagrees therefore wins, and
146
+ * the reply is not read as a refusal.
147
+ *
148
+ * AN ABSENT OUTCOME IS NOT A REFUSAL EITHER, and it is the same answer as `unknown` because the
149
+ * spec says they are the same value: SPEC 1510, "an error reply that omits `outcome` MUST be read
150
+ * as `unknown`". An earlier revision accepted absence, on the argument that a responder too old to
151
+ * know the field emits exactly that and refusing it would stop core repairing splits for a third
152
+ * party that is otherwise behaving. That argument does not survive SPEC 2271: a client MUST NOT
153
+ * automatically re-issue a command declared `write` after any outcome that does not prove
154
+ * non-execution, whatever `id` the re-issue carries, and `unknown` proves nothing. Since this
155
+ * predicate is what licenses a re-issue that SKIPS {@link isRepeatSafeCommand}, accepting absence
156
+ * made core re-issue writes on an outcome the spec says is `unknown`.
157
+ *
158
+ * The cost is real and it is bounded: a responder that omits the field no longer has its splits
159
+ * repaired. That responder is already non-conforming, because §13.3 requires a refusal raised
160
+ * before dispatch to carry `not-executed`, so what it loses is a repair it was never owed. This
161
+ * endpoint's own responder sets the field, so conforming deployments are unaffected. */
162
+ export declare function replyRefusedBeforeEffect(e: EpError | undefined): boolean;
163
+ /** §13.3 **Effect outcome**: whether the command's effect occurred. Emitted by the RESPONDER,
164
+ * which is the only party that knows. An omitted `outcome` MUST be read as `unknown`, so absence
165
+ * is never evidence of non-execution. */
166
+ export type EpEffectOutcome = "executed" | "not-executed" | "unknown";
18
167
  /** The `EndpointReply.error` shape. */
19
168
  export interface EpError {
20
169
  code: string;
21
170
  message: string;
22
171
  details?: EpErrorDetail[];
172
+ /** §13.3. A responder refusing BEFORE dispatching to the handler MUST carry `not-executed`;
173
+ * one refusing AFTER the handler ran MUST carry `executed`; one that cannot tell MUST carry
174
+ * `unknown` rather than guess. Absent on a caller-raised refusal, which is not a reply. */
175
+ outcome?: EpEffectOutcome;
23
176
  }
24
177
  /** A consuming-boundary rejection: the catalog code plus a human message. Boundaries convert it
25
178
  * to an `EndpointReply` error via {@link EpEnvelopeError.toEpError} (or, on reply-less planes,
@@ -27,7 +180,8 @@ export interface EpError {
27
180
  export declare class EpEnvelopeError extends Error {
28
181
  readonly code: EpErrorCode;
29
182
  readonly details?: EpErrorDetail[] | undefined;
30
- constructor(code: EpErrorCode, message: string, details?: EpErrorDetail[] | undefined);
183
+ readonly outcome?: EpEffectOutcome | undefined;
184
+ constructor(code: EpErrorCode, message: string, details?: EpErrorDetail[] | undefined, outcome?: EpEffectOutcome | undefined);
31
185
  toEpError(): EpError;
32
186
  }
33
187
  //# sourceMappingURL=endpoint-error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-error.d.ts","sourceRoot":"","sources":["../src/endpoint-error.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;mDACmD;AACnD,eAAO,MAAM,cAAc,0XAMhB,CAAC;AACZ,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,uCAAuC;AACvC,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED;;qEAEqE;AACrE,qBAAa,eAAgB,SAAQ,KAAK;IAC5B,QAAQ,CAAC,IAAI,EAAE,WAAW;IAAmB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE;gBAAtE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAW,OAAO,CAAC,EAAE,aAAa,EAAE,YAAA;IAI3F,SAAS,IAAI,OAAO;CAGrB"}
1
+ {"version":3,"file":"endpoint-error.d.ts","sourceRoot":"","sources":["../src/endpoint-error.ts"],"names":[],"mappings":"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"}
@@ -15,20 +15,132 @@ export const EP_ERROR_CODES = Object.freeze([
15
15
  "deadline-exceeded", "cancelled", "expired", "unavailable", "unimplemented",
16
16
  "resource-exhausted", "internal",
17
17
  ]);
18
+ /**
19
+ * `details[].kind` for a refusal raised because a responder ANSWERED but was not the incarnation
20
+ * this handle resolved against (§13.2): `failed-precondition` for a DIFFERENT instance, `expired`
21
+ * for the SAME instance at another EPOCH. It marks what the code alone cannot say — **the request
22
+ * drew an attributed reply from a live responder** — which rules out the reading "the incarnation
23
+ * is gone, resolve again". The reply may be a refusal or a result and the marker does not say
24
+ * which, so a retry here is a SECOND ATTEMPT that may duplicate an effect, never a repair.
25
+ */
26
+ export const EP_UNBOUND_RESPONDER = "ai.cotal.ep.unbound-responder";
27
+ /** True iff `e` carries the {@link EP_UNBOUND_RESPONDER} marker: a responder ANSWERED the request
28
+ * (an attributed reply, which may be a refusal or a result), so retrying it is a second attempt
29
+ * that may duplicate an effect, not a repair. */
30
+ export function respondedButUnbound(e) {
31
+ return e instanceof EpEnvelopeError && (e.details ?? []).some((d) => d.kind === EP_UNBOUND_RESPONDER);
32
+ }
33
+ /**
34
+ * `details[].kind` for a refusal raised because NO VALID REPLY REACHED THE CALLER: no responder on
35
+ * the subject, or the deadline elapsed with nothing attributed to the request's nonce. A frame that
36
+ * fails the request binding is dropped and is not an answer, so the marker means nothing
37
+ * ATTRIBUTABLE arrived, not that no bytes did. `unavailable`/`deadline-exceeded` alone is not
38
+ * evidence of silence — the same codes are raised where something did answer, or where a
39
+ * caller-side read failed after the describe — so a consumer stating a reachability verdict keys on
40
+ * this marker, never on the code.
41
+ */
42
+ export const EP_UNANSWERED = "ai.cotal.ep.unanswered";
43
+ /** True iff `e` carries the {@link EP_UNANSWERED} marker: no valid reply reached the caller (no
44
+ * responder, or the deadline elapsed with nothing attributed to the request). */
45
+ export function unansweredRequest(e) {
46
+ return e instanceof EpEnvelopeError && (e.details ?? []).some((d) => d.kind === EP_UNANSWERED);
47
+ }
48
+ /**
49
+ * `details[].kind` for a refusal raised because a caller-side read of the SERVICE REGISTRY failed
50
+ * or did not settle: the scatter's freeze (§13.5) or its mandatory reconcile. It marks the failure
51
+ * as the caller's own, establishing NOTHING about the responders — the freeze fails before any
52
+ * request goes out, and the reconcile fails after the gather, where members may all have answered
53
+ * and their replies simply could not be classified. A consumer must not read it as their silence.
54
+ */
55
+ export const EP_REGISTRY_READ_FAILED = "ai.cotal.ep.registry-read-failed";
56
+ /** True iff `e` carries the {@link EP_REGISTRY_READ_FAILED} marker: a caller-side registry read
57
+ * failed; the responders were not the failure. */
58
+ export function registryReadFailed(e) {
59
+ return e instanceof EpEnvelopeError && (e.details ?? []).some((d) => d.kind === EP_REGISTRY_READ_FAILED);
60
+ }
61
+ /**
62
+ * `details[].kind` for a refusal raised by the RESPONDER because the request declared a bound
63
+ * incarnation (`bind`, §13.3) that is not this instance: `failed-precondition` for a different
64
+ * instance, `expired` for the same instance at another epoch. It marks what no caller-side check
65
+ * can establish: **the command did not run, and no effect of it exists.**
66
+ *
67
+ * Set before the handler, before args validation, and before any seam that can consume a one-use
68
+ * proof, by the only party that knows which incarnation it is. {@link EP_UNBOUND_RESPONDER} is
69
+ * raised by the CALLER on the reply, after the responder has already acted — a report, not a
70
+ * guard. So a caller holding THIS marker may re-resolve and re-issue without risking a duplicate,
71
+ * which is exactly what a caller holding that one must not do.
72
+ */
73
+ export const EP_BIND_REFUSED = "ai.cotal.ep.bind-refused";
74
+ /** True iff an `EpError` CARRIES the {@link EP_BIND_REFUSED} marker, saying nothing about whether
75
+ * the marker is believable. It is the claim's presence, not its acceptance.
76
+ *
77
+ * The two questions come apart, and conflating them is what this pair exists to prevent. Whether a
78
+ * caller may ACT on a bind refusal — re-issue a command it would otherwise never repeat — needs
79
+ * the marker AND an explicit `not-executed`, which is {@link replyRefusedBeforeEffect}. Whether a
80
+ * reply is CHECKED for self-consistency needs only the claim, because the contradiction being
81
+ * checked is between the reply's BODY and the subject the broker pinned, and that is a
82
+ * contradiction whatever the outcome field says — or does not say.
83
+ *
84
+ * Gating the checks on the stronger predicate meant a reply could skip them by OMITTING a field,
85
+ * so the least credible shape drew the least scrutiny. */
86
+ export function bindRefusalMarked(e) {
87
+ return (e?.details ?? []).some((d) => d.kind === EP_BIND_REFUSED);
88
+ }
89
+ /** True iff an `EpError` carries the {@link EP_BIND_REFUSED} marker: a responder refused BEFORE
90
+ * executing, because it is not the incarnation the caller bound — the command did not run.
91
+ *
92
+ * It takes an `EpError` and not a thrown value, unlike its sibling predicates, because this
93
+ * refusal never arrives as a throw: it is the responder's own application-level failure and
94
+ * those ride the reply (§13.5). A consumer reads it off `reply.error`.
95
+ *
96
+ * A REPLY THAT CONTRADICTS ITSELF IS NOT A REFUSAL. The marker IS the assertion that the command
97
+ * did not run, and {@link EpError.outcome} says a responder refusing before dispatch MUST carry
98
+ * `not-executed` — but {@link EpBindRefusedDetail} carries no outcome of its own, so nothing in the
99
+ * type stops a reply pairing the marker with `executed`. That combination is not merely odd: the
100
+ * only consumer of this predicate re-issues a command **without** the {@link isRepeatSafeCommand}
101
+ * gate, on the strength of the marker, so resolving the contradiction toward "refused" re-sends a
102
+ * command the reply just said had ALREADY RUN. A present outcome that disagrees therefore wins, and
103
+ * the reply is not read as a refusal.
104
+ *
105
+ * AN ABSENT OUTCOME IS NOT A REFUSAL EITHER, and it is the same answer as `unknown` because the
106
+ * spec says they are the same value: SPEC 1510, "an error reply that omits `outcome` MUST be read
107
+ * as `unknown`". An earlier revision accepted absence, on the argument that a responder too old to
108
+ * know the field emits exactly that and refusing it would stop core repairing splits for a third
109
+ * party that is otherwise behaving. That argument does not survive SPEC 2271: a client MUST NOT
110
+ * automatically re-issue a command declared `write` after any outcome that does not prove
111
+ * non-execution, whatever `id` the re-issue carries, and `unknown` proves nothing. Since this
112
+ * predicate is what licenses a re-issue that SKIPS {@link isRepeatSafeCommand}, accepting absence
113
+ * made core re-issue writes on an outcome the spec says is `unknown`.
114
+ *
115
+ * The cost is real and it is bounded: a responder that omits the field no longer has its splits
116
+ * repaired. That responder is already non-conforming, because §13.3 requires a refusal raised
117
+ * before dispatch to carry `not-executed`, so what it loses is a repair it was never owed. This
118
+ * endpoint's own responder sets the field, so conforming deployments are unaffected. */
119
+ export function replyRefusedBeforeEffect(e) {
120
+ if (!bindRefusalMarked(e))
121
+ return false;
122
+ return e?.outcome === "not-executed";
123
+ }
18
124
  /** A consuming-boundary rejection: the catalog code plus a human message. Boundaries convert it
19
125
  * to an `EndpointReply` error via {@link EpEnvelopeError.toEpError} (or, on reply-less planes,
20
126
  * to the §13.4 decision/quarantine fact carrying the same code). */
21
127
  export class EpEnvelopeError extends Error {
22
128
  code;
23
129
  details;
24
- constructor(code, message, details) {
130
+ outcome;
131
+ constructor(code, message, details, outcome) {
25
132
  super(message);
26
133
  this.code = code;
27
134
  this.details = details;
135
+ this.outcome = outcome;
28
136
  this.name = "EpEnvelopeError";
29
137
  }
30
138
  toEpError() {
31
- return { code: this.code, message: this.message, ...(this.details ? { details: this.details } : {}) };
139
+ return {
140
+ code: this.code, message: this.message,
141
+ ...(this.details ? { details: this.details } : {}),
142
+ ...(this.outcome ? { outcome: this.outcome } : {}),
143
+ };
32
144
  }
33
145
  }
34
146
  //# sourceMappingURL=endpoint-error.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint-error.js","sourceRoot":"","sources":["../src/endpoint-error.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;mDACmD;AACnD,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,aAAa,EAAE,qBAAqB,EAAE,aAAa,EAAE,gBAAgB,EAAE,iBAAiB;IACxF,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,WAAW,EAAE,gBAAgB;IACxF,UAAU,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,qBAAqB;IAC1E,mBAAmB,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe;IAC3E,oBAAoB,EAAE,UAAU;CACxB,CAAC,CAAC;AAgBZ;;qEAEqE;AACrE,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACnB;IAA6C;IAAlE,YAAqB,IAAiB,EAAE,OAAe,EAAW,OAAyB;QACzF,KAAK,CAAC,OAAO,CAAC,CAAC;QADI,SAAI,GAAJ,IAAI,CAAa;QAA4B,YAAO,GAAP,OAAO,CAAkB;QAEzF,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;IACD,SAAS;QACP,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACxG,CAAC;CACF"}
1
+ {"version":3,"file":"endpoint-error.js","sourceRoot":"","sources":["../src/endpoint-error.ts"],"names":[],"mappings":"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"}