@engramx/idl 0.16.0-rc.1
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/LICENSE +190 -0
- package/README.md +27 -0
- package/dist/engram.did +4045 -0
- package/dist/engram.idl.d.ts +3839 -0
- package/dist/engram.idl.js +1423 -0
- package/dist/market.did +1402 -0
- package/dist/market.idl.d.ts +1354 -0
- package/dist/market.idl.js +551 -0
- package/dist/registry.did +1671 -0
- package/dist/registry.idl.d.ts +1692 -0
- package/dist/registry.idl.js +522 -0
- package/package.json +50 -0
|
@@ -0,0 +1,3839 @@
|
|
|
1
|
+
import type { Principal } from '@icp-sdk/core/principal';
|
|
2
|
+
import type { ActorMethod } from '@icp-sdk/core/agent';
|
|
3
|
+
import type { IDL } from '@icp-sdk/core/candid';
|
|
4
|
+
|
|
5
|
+
export interface About {
|
|
6
|
+
verifiedHuman: boolean;
|
|
7
|
+
guardianCount: bigint;
|
|
8
|
+
totalMemoryWrites: bigint;
|
|
9
|
+
lastAgentWriteAtNs: [] | [bigint];
|
|
10
|
+
distinctReaderPrincipals: bigint;
|
|
11
|
+
lastWriteAtNs: [] | [bigint];
|
|
12
|
+
totalBackupSize: bigint;
|
|
13
|
+
backupCount: bigint;
|
|
14
|
+
lastAgentReadAtNs: [] | [bigint];
|
|
15
|
+
firstWriteAtNs: [] | [bigint];
|
|
16
|
+
agentCount: bigint;
|
|
17
|
+
paidMemoryReadEnabled: boolean;
|
|
18
|
+
version: string;
|
|
19
|
+
paymentsFrozen: boolean;
|
|
20
|
+
agentMemoryWrites: bigint;
|
|
21
|
+
agentMemoryReads: bigint;
|
|
22
|
+
auditLogSize: bigint;
|
|
23
|
+
memoryFileCount: bigint;
|
|
24
|
+
firstAgentWriteAtNs: [] | [bigint];
|
|
25
|
+
lastReadAtNs: [] | [bigint];
|
|
26
|
+
writesPaused: boolean;
|
|
27
|
+
distinctReaderClients: bigint;
|
|
28
|
+
totalMemoryReads: bigint;
|
|
29
|
+
walletActivatedAtNs: [] | [bigint];
|
|
30
|
+
encryptionEnabled: boolean;
|
|
31
|
+
paidMemoryWriteEnabled: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface ActionAuth {
|
|
34
|
+
signature: Uint8Array | number[];
|
|
35
|
+
pubkey: Uint8Array | number[];
|
|
36
|
+
nonce: bigint;
|
|
37
|
+
}
|
|
38
|
+
export interface ActivitySnapshot {
|
|
39
|
+
atNs: bigint;
|
|
40
|
+
memoryReads: bigint;
|
|
41
|
+
memoryWrites: bigint;
|
|
42
|
+
}
|
|
43
|
+
export interface AgentCard {
|
|
44
|
+
x402Support: boolean;
|
|
45
|
+
name: string;
|
|
46
|
+
description: string;
|
|
47
|
+
services: Array<ServiceEntry>;
|
|
48
|
+
}
|
|
49
|
+
export type AgentEndReason =
|
|
50
|
+
| { Resigned: null }
|
|
51
|
+
| { OwnerRevoked: null }
|
|
52
|
+
| { Reset: null }
|
|
53
|
+
| { KillSwitch: null }
|
|
54
|
+
| { GuardianRevoked: null };
|
|
55
|
+
export interface AgentEnding {
|
|
56
|
+
day: bigint;
|
|
57
|
+
reason: AgentEndReason;
|
|
58
|
+
}
|
|
59
|
+
export interface AgentPaymentSignatures {
|
|
60
|
+
agent: Principal;
|
|
61
|
+
signedToday: bigint;
|
|
62
|
+
root: Principal;
|
|
63
|
+
}
|
|
64
|
+
export interface AgentPermissions {
|
|
65
|
+
canReadMemory: boolean;
|
|
66
|
+
scopes: [] | [Array<string>];
|
|
67
|
+
canReadBackup: [] | [boolean];
|
|
68
|
+
callsPerMinute: bigint;
|
|
69
|
+
canAppendMemory: boolean;
|
|
70
|
+
canReadWallet: boolean;
|
|
71
|
+
}
|
|
72
|
+
export interface AgentRecord {
|
|
73
|
+
status: AgentStatus;
|
|
74
|
+
earlierKeys: Array<HeldKey>;
|
|
75
|
+
permissions: AgentPermissions;
|
|
76
|
+
principal: Principal;
|
|
77
|
+
keyRotationCount: bigint;
|
|
78
|
+
publicKeyHash: [] | [string];
|
|
79
|
+
pairedAtNs: bigint;
|
|
80
|
+
enrolment: EnrolmentProof;
|
|
81
|
+
lastSeenNs: bigint;
|
|
82
|
+
name: string;
|
|
83
|
+
root: Principal;
|
|
84
|
+
ended: [] | [AgentEnding];
|
|
85
|
+
keyNomination: [] | [KeyNomination];
|
|
86
|
+
keyRotatedAtNs: bigint;
|
|
87
|
+
keyHeldFrom: LogPosition;
|
|
88
|
+
}
|
|
89
|
+
export type AgentStatus = { Active: null } | { Resigned: null } | { Revoked: null };
|
|
90
|
+
export interface AgentWriteReview {
|
|
91
|
+
cursor: bigint;
|
|
92
|
+
head: bigint;
|
|
93
|
+
rows: Array<AgentWriteRow>;
|
|
94
|
+
earliest: bigint;
|
|
95
|
+
capped: boolean;
|
|
96
|
+
}
|
|
97
|
+
export interface AgentWriteRow {
|
|
98
|
+
source: [] | [string];
|
|
99
|
+
path: [] | [string];
|
|
100
|
+
entry: AuditEntry;
|
|
101
|
+
version: [] | [bigint];
|
|
102
|
+
connector: [] | [string];
|
|
103
|
+
}
|
|
104
|
+
export interface AlertConfig {
|
|
105
|
+
url: [] | [string];
|
|
106
|
+
money: boolean;
|
|
107
|
+
classes: [] | [Array<[string, boolean]>];
|
|
108
|
+
agentWrites: boolean;
|
|
109
|
+
guardian: boolean;
|
|
110
|
+
approvals: boolean;
|
|
111
|
+
}
|
|
112
|
+
export interface AlertStatus {
|
|
113
|
+
lastDeliveredAtNs: [] | [bigint];
|
|
114
|
+
failures: bigint;
|
|
115
|
+
totalAudit: bigint;
|
|
116
|
+
cursor: bigint;
|
|
117
|
+
disabled: boolean;
|
|
118
|
+
config: AlertConfig;
|
|
119
|
+
}
|
|
120
|
+
export interface AnchorPushStatus {
|
|
121
|
+
anchorTickAtNs: [] | [bigint];
|
|
122
|
+
okAtNs: [] | [bigint];
|
|
123
|
+
cadenceSeconds: bigint;
|
|
124
|
+
attemptTotal: bigint;
|
|
125
|
+
currentTotal: bigint;
|
|
126
|
+
timerTickAtNs: [] | [bigint];
|
|
127
|
+
okTotal: bigint;
|
|
128
|
+
carrierArmedAtNs: bigint;
|
|
129
|
+
attemptAtNs: [] | [bigint];
|
|
130
|
+
skipCursor: bigint;
|
|
131
|
+
lastError: string;
|
|
132
|
+
}
|
|
133
|
+
export interface ApprovalRequest {
|
|
134
|
+
id: string;
|
|
135
|
+
expiresAtNs: bigint;
|
|
136
|
+
status: ApprovalStatus;
|
|
137
|
+
denialReason: [] | [string];
|
|
138
|
+
policyField: string;
|
|
139
|
+
approvedBy: [] | [Principal];
|
|
140
|
+
createdAtNs: bigint;
|
|
141
|
+
approvedAtNs: [] | [bigint];
|
|
142
|
+
binding: string;
|
|
143
|
+
operation: string;
|
|
144
|
+
rationale: string;
|
|
145
|
+
policyLimit: bigint;
|
|
146
|
+
caller: Principal;
|
|
147
|
+
amount: bigint;
|
|
148
|
+
}
|
|
149
|
+
export type ApprovalStatus =
|
|
150
|
+
{ Used: null } | { Approved: null } | { Denied: null } | { Expired: null } | { Pending: null };
|
|
151
|
+
export interface AuditEntry {
|
|
152
|
+
id: bigint;
|
|
153
|
+
entryHash: Uint8Array | number[];
|
|
154
|
+
callerRole: Role;
|
|
155
|
+
operation: string;
|
|
156
|
+
details: string;
|
|
157
|
+
caller: Principal;
|
|
158
|
+
success: boolean;
|
|
159
|
+
timestampNs: bigint;
|
|
160
|
+
}
|
|
161
|
+
export interface AuditHead {
|
|
162
|
+
headHash: Uint8Array | number[];
|
|
163
|
+
size: bigint;
|
|
164
|
+
}
|
|
165
|
+
export type AuthorityClass =
|
|
166
|
+
{ standingAuthority: null } | { valueBearing: null } | { standard: null };
|
|
167
|
+
export interface BackupMetadata {
|
|
168
|
+
status: BackupStatus;
|
|
169
|
+
sha256: string;
|
|
170
|
+
backupId: string;
|
|
171
|
+
createdBy: Principal;
|
|
172
|
+
createdAtNs: bigint;
|
|
173
|
+
totalSize: bigint;
|
|
174
|
+
backupLabel: [] | [string];
|
|
175
|
+
backupType: BackupType;
|
|
176
|
+
dbType: string;
|
|
177
|
+
chunkCount: bigint;
|
|
178
|
+
parentBackupId: [] | [string];
|
|
179
|
+
}
|
|
180
|
+
export interface BackupRetentionReport {
|
|
181
|
+
maxBackups: bigint;
|
|
182
|
+
dbType: string;
|
|
183
|
+
prunedBackups: bigint;
|
|
184
|
+
}
|
|
185
|
+
export type BackupStatus = { Uploading: null } | { Failed: null } | { Finalized: null };
|
|
186
|
+
export type BackupType =
|
|
187
|
+
{ PartialSnapshot: null } | { IncrementalDiff: null } | { FullSnapshot: null };
|
|
188
|
+
export interface BatchReadItem {
|
|
189
|
+
result: { Ok: MemoryFile } | { Err: Error };
|
|
190
|
+
path: string;
|
|
191
|
+
}
|
|
192
|
+
export interface BearerToken {
|
|
193
|
+
expiresAtNs: bigint;
|
|
194
|
+
status: BearerTokenStatus;
|
|
195
|
+
lastUsedNs: bigint;
|
|
196
|
+
permissions: AgentPermissions;
|
|
197
|
+
tokenId: string;
|
|
198
|
+
clientLabel: string;
|
|
199
|
+
issuedAtNs: bigint;
|
|
200
|
+
tokenHash: string;
|
|
201
|
+
issuedBy: Principal;
|
|
202
|
+
}
|
|
203
|
+
export type BearerTokenStatus = { Active: null } | { Revoked: null } | { Expired: null };
|
|
204
|
+
export interface CallerSignatureCount {
|
|
205
|
+
count: bigint;
|
|
206
|
+
role: Role;
|
|
207
|
+
root: [] | [Principal];
|
|
208
|
+
caller: Principal;
|
|
209
|
+
}
|
|
210
|
+
export interface CertifiedAuditHead {
|
|
211
|
+
total: bigint;
|
|
212
|
+
certificate: [] | [Uint8Array | number[]];
|
|
213
|
+
headHash: Uint8Array | number[];
|
|
214
|
+
size: bigint;
|
|
215
|
+
witness: [] | [Uint8Array | number[]];
|
|
216
|
+
}
|
|
217
|
+
export interface CheckpointPage {
|
|
218
|
+
firstAvailableSeq: bigint;
|
|
219
|
+
page: Page_15;
|
|
220
|
+
scannedThroughSeq: bigint;
|
|
221
|
+
}
|
|
222
|
+
export interface ChildAllowanceRow {
|
|
223
|
+
root: Principal;
|
|
224
|
+
remaining: bigint;
|
|
225
|
+
}
|
|
226
|
+
export interface ChildOpening {
|
|
227
|
+
attachCycles: bigint;
|
|
228
|
+
balance: bigint;
|
|
229
|
+
allowances: Array<ChildAllowanceRow>;
|
|
230
|
+
floorCycles: bigint;
|
|
231
|
+
}
|
|
232
|
+
export interface CondenseCheckpointRow {
|
|
233
|
+
by: Principal;
|
|
234
|
+
seq: bigint;
|
|
235
|
+
toSeq: bigint;
|
|
236
|
+
opsRoot: Uint8Array | number[];
|
|
237
|
+
atNs: bigint;
|
|
238
|
+
fromSeq: bigint;
|
|
239
|
+
headAtBoundary: Uint8Array | number[];
|
|
240
|
+
opCount: bigint;
|
|
241
|
+
}
|
|
242
|
+
export interface CondensePreview {
|
|
243
|
+
scannedFromSeq: bigint;
|
|
244
|
+
scanTruncated: boolean;
|
|
245
|
+
firstAvailableSeq: bigint;
|
|
246
|
+
unlocked: boolean;
|
|
247
|
+
totalEvents: bigint;
|
|
248
|
+
maxUnlockableToSeq: bigint;
|
|
249
|
+
bestUnfilteredReceipt: [] | [{ seq: bigint; toSeq: bigint; fromSeq: bigint }];
|
|
250
|
+
opCountInRange: bigint;
|
|
251
|
+
filteredReceiptsSeen: bigint;
|
|
252
|
+
coveringReceipt: [] | [{ seq: bigint; toSeq: bigint; fromSeq: bigint }];
|
|
253
|
+
proposedToSeq: bigint;
|
|
254
|
+
}
|
|
255
|
+
export interface CondenseResult {
|
|
256
|
+
seq: bigint;
|
|
257
|
+
toSeq: bigint;
|
|
258
|
+
opsRoot: Uint8Array | number[];
|
|
259
|
+
head: Uint8Array | number[];
|
|
260
|
+
fromSeq: bigint;
|
|
261
|
+
headAtBoundary: Uint8Array | number[];
|
|
262
|
+
newFirstAvailableSeq: bigint;
|
|
263
|
+
historyBytesDelta: bigint;
|
|
264
|
+
opCount: bigint;
|
|
265
|
+
}
|
|
266
|
+
export type ControlHandover =
|
|
267
|
+
{ MovedByRegistry: null } | { NotHeldHere: null } | { MovedByEngram: null };
|
|
268
|
+
export interface CycleSnapshot {
|
|
269
|
+
seq: bigint;
|
|
270
|
+
source: { balance: null } | { self: null };
|
|
271
|
+
atNs: bigint;
|
|
272
|
+
cycles: bigint;
|
|
273
|
+
}
|
|
274
|
+
export interface Eip3009Authorization {
|
|
275
|
+
r: Uint8Array | number[];
|
|
276
|
+
s: Uint8Array | number[];
|
|
277
|
+
v: number;
|
|
278
|
+
to: string;
|
|
279
|
+
value: bigint;
|
|
280
|
+
from: string;
|
|
281
|
+
validAfter: bigint;
|
|
282
|
+
nonce: Uint8Array | number[];
|
|
283
|
+
validBefore: bigint;
|
|
284
|
+
}
|
|
285
|
+
export interface Eip712Registration {
|
|
286
|
+
encodeTypeString: string;
|
|
287
|
+
cooloffEndsAtNs: bigint;
|
|
288
|
+
typeId: Uint8Array | number[];
|
|
289
|
+
}
|
|
290
|
+
export interface Eip712SignatureOut {
|
|
291
|
+
r: Uint8Array | number[];
|
|
292
|
+
s: Uint8Array | number[];
|
|
293
|
+
v: number;
|
|
294
|
+
rendered: string;
|
|
295
|
+
digest: Uint8Array | number[];
|
|
296
|
+
}
|
|
297
|
+
export type Eip712Value =
|
|
298
|
+
| { string: string }
|
|
299
|
+
| { bool: boolean }
|
|
300
|
+
| { uint: bigint }
|
|
301
|
+
| { address: string }
|
|
302
|
+
| { fixedBytes: Uint8Array | number[] }
|
|
303
|
+
| { bytes: Uint8Array | number[] };
|
|
304
|
+
export interface Engram {
|
|
305
|
+
/**
|
|
306
|
+
* / ⟨0.16.0⟩ `about()` — the ONE public projection, replacing `status()` and absorbing `metrics()`.
|
|
307
|
+
* /
|
|
308
|
+
* / Two public projections of one canister was the L2.2 defect: both answered "what is this engram
|
|
309
|
+
* / like", disagreed about which counters they carried, and `status()` additionally masked two
|
|
310
|
+
* / fields behind an `authorized` flag whose own declaration admitted the problem — "a consumer
|
|
311
|
+
* / that must remember to check a sibling flag is one that will eventually forget."
|
|
312
|
+
* /
|
|
313
|
+
* / The fix is not a better flag. The gated fields MOVED (see `getOwnerConsole`), so there is no
|
|
314
|
+
* / masked field to forget and no flag to check. Reaching the gated record is the authorization.
|
|
315
|
+
* /
|
|
316
|
+
* / Ungated by design and marked for the L8 gate-grep.
|
|
317
|
+
* / PUBLIC: existence, shape, posture and day-floored activity. No principal, no balance, no
|
|
318
|
+
* / precise timestamp — nothing here identifies a person or reveals when they are at the keyboard.
|
|
319
|
+
*/
|
|
320
|
+
about: ActorMethod<[], About>;
|
|
321
|
+
/**
|
|
322
|
+
* / The NEW key accepts the nomination the agent's current key (`agentKey`) made of it, and takes
|
|
323
|
+
* / over the agent's record: the same lasting identity, enrolment statement, invite and
|
|
324
|
+
* / permissions, today's spending and signature totals, and any spending limit the owner set for
|
|
325
|
+
* / that agent. From this message on, `agentKey` is not an agent of this engram and every call it
|
|
326
|
+
* / makes as one is refused. The registry is not called: it goes on naming the same open
|
|
327
|
+
* / engagement (`KeyReplacement`'s header says why and what a modified engram could do with it).
|
|
328
|
+
* /
|
|
329
|
+
* / ONE MESSAGE, NO AWAIT: every check, the move of the record and of each per-key total, and the
|
|
330
|
+
* / record entry happen together, so no call can fall between a check and the move, and no total
|
|
331
|
+
* / is ever held by both keys or by neither. Answers the record as the new key now holds it.
|
|
332
|
+
* /
|
|
333
|
+
* / WHO MAY CALL is decided by `KeyReplacement.accepted`: only the key a pending, unexpired
|
|
334
|
+
* / nomination names. That check compares the caller inside the module, where
|
|
335
|
+
* / test/key-replacement.test.mo runs it; this body names no roster gate, because the caller holds
|
|
336
|
+
* / no role here until the move.
|
|
337
|
+
*/
|
|
338
|
+
acceptAgentKeyNomination: ActorMethod<[Principal], Result_70>;
|
|
339
|
+
/**
|
|
340
|
+
* / Consensus transform for the alert webhook outcall: collapse the response to status-only so
|
|
341
|
+
* / replicas agree regardless of response headers/body (we only care that the POST landed 2xx).
|
|
342
|
+
* /
|
|
343
|
+
* / PUBLIC: not a choice. The management canister invokes a transform on every replica as part of
|
|
344
|
+
* / the HTTP-outcall protocol, and that invocation carries no caller identity to gate on — a gate
|
|
345
|
+
* / here would refuse the only caller there is and break every alert this canister sends. Safe
|
|
346
|
+
* / because it is total and stateless: it reads its argument and returns, touching nothing.
|
|
347
|
+
*/
|
|
348
|
+
actionAlertTransform: ActorMethod<
|
|
349
|
+
[{ context: Uint8Array | number[]; response: HttpRequestResult }],
|
|
350
|
+
HttpRequestResult
|
|
351
|
+
>;
|
|
352
|
+
/**
|
|
353
|
+
* / Register a typed-data shape as signable. Owner-only, freeze-gated (a registration is a grant
|
|
354
|
+
* / of FUTURE authority — a frozen engram must not be able to widen what it can sign), and the
|
|
355
|
+
* / shape is IMMUTABLE: any change mints a new typeId.
|
|
356
|
+
*/
|
|
357
|
+
addEip712Type: ActorMethod<
|
|
358
|
+
[
|
|
359
|
+
{
|
|
360
|
+
primaryType: string;
|
|
361
|
+
canonicalTypeString: string;
|
|
362
|
+
domainName: string;
|
|
363
|
+
verifyingContract: string;
|
|
364
|
+
dailySignCap: bigint;
|
|
365
|
+
fields: Array<[string, string]>;
|
|
366
|
+
destinationFields: Array<string>;
|
|
367
|
+
authorityClass: { standingAuthority: null } | { valueBearing: null } | { standard: null };
|
|
368
|
+
chainId: bigint;
|
|
369
|
+
domainVersion: string;
|
|
370
|
+
ackIrrevocable: boolean;
|
|
371
|
+
},
|
|
372
|
+
],
|
|
373
|
+
Result_69
|
|
374
|
+
>;
|
|
375
|
+
/**
|
|
376
|
+
* / Owner-managed destination allowlist (D7). Additions LOOSEN and wait 24h; removals TIGHTEN
|
|
377
|
+
* / and apply instantly — the ratified asymmetry, applied to the one mutable policy surface.
|
|
378
|
+
*/
|
|
379
|
+
addEvmWithdrawDestination: ActorMethod<[string], Result_68>;
|
|
380
|
+
/**
|
|
381
|
+
* / ⟨0.16.0, L1⟩ THE ROLE-CONFLICT ARM, and why three refusals here are not the same refusal.
|
|
382
|
+
* /
|
|
383
|
+
* / This method had five distinct ways to say no through one `text`, and a caller could only tell
|
|
384
|
+
* / them apart by matching prose. They are now three different arms because they call for three
|
|
385
|
+
* / different responses: `#Invalid` means fix the argument and retry, `#Refused` means you are not
|
|
386
|
+
* / the owner and retrying changes nothing, and `#Conflict` means the request was well-formed and
|
|
387
|
+
* / permitted but this engram's state says no — the principal already holds an incompatible role,
|
|
388
|
+
* / or the roster is full. Only the last is worth an agent's time to resolve.
|
|
389
|
+
*/
|
|
390
|
+
addGuardian: ActorMethod<[Principal, string, GuardianPermissions], Result_1>;
|
|
391
|
+
/**
|
|
392
|
+
* / Returns the write RECEIPT, not just the version.
|
|
393
|
+
* /
|
|
394
|
+
* / The receipt was always computed and then thrown away: MemoryRouter hands back
|
|
395
|
+
* / {seq; version; contentRoot; head}, the audit detail stringifies `seq=`/`head=` into prose, and
|
|
396
|
+
* / the caller got a bare Nat. So a writer could be told their write landed but not be given the
|
|
397
|
+
* / evidence it landed — they had to read the audit log back and parse a string to learn the head
|
|
398
|
+
* / their own write produced. `head` is the chain head AFTER this write; it transitively commits
|
|
399
|
+
* / to contentRoot, which is why the root is not repeated here (the same ruling that dropped
|
|
400
|
+
* / per-entry contentRoot from the audit entries).
|
|
401
|
+
* /
|
|
402
|
+
* / This is the half of a consumer request that costs nothing: the commitment ledger was still
|
|
403
|
+
* / "trust whoever runs the service" one hop from the proof — a third party can now be handed the receipt
|
|
404
|
+
* / directly by whoever wrote the content. A return-TYPE change cannot be absorbed by the client
|
|
405
|
+
* / subset rule, so it can only ride an interface break; this release is one.
|
|
406
|
+
*/
|
|
407
|
+
appendMemory: ActorMethod<[string, Uint8Array | number[], [] | [MemorySource]], Result>;
|
|
408
|
+
/**
|
|
409
|
+
* / Replace the retained log prefix through `toSeq` with a single checkpoint.
|
|
410
|
+
* /
|
|
411
|
+
* / PREFIX-ONLY: there is no `fromSeq`, because the library made that unrepresentable rather than
|
|
412
|
+
* / merely checked — a condense always starts at the current floor. It refuses unless an
|
|
413
|
+
* / UNFILTERED export receipt already covers the whole range; call previewCondense first,
|
|
414
|
+
* / which reports how far your existing receipts reach.
|
|
415
|
+
* /
|
|
416
|
+
* / `historyBytesDelta` is SIGNED, and the sign is the point. A condense subtracts the dropped
|
|
417
|
+
* / entries' canonical bytes and adds the checkpoint's own, so condensing a short prefix of small
|
|
418
|
+
* / entries can leave the history meter HIGHER than it found it. The owner is told which happened
|
|
419
|
+
* / rather than left to assume the number went down.
|
|
420
|
+
* /
|
|
421
|
+
* / Gated on requireWritesNotPaused — unlike the export. This one destroys retained entries, which
|
|
422
|
+
* / is exactly what a guardian pause exists to hold. No action alert is raised: the operation is
|
|
423
|
+
* / owner-initiated, owner-only, and already chained into the audit log.
|
|
424
|
+
*/
|
|
425
|
+
applyCondense: ActorMethod<[bigint], Result_67>;
|
|
426
|
+
/**
|
|
427
|
+
* / Owner-only: activate a guardian who has registered against an invite.
|
|
428
|
+
* /
|
|
429
|
+
* / Until this call the guardian is `#Pending` and can do NOTHING — registering is a claim, this
|
|
430
|
+
* / is the grant. That two-step is what stops a leaked invite code from producing a live guardian
|
|
431
|
+
* / on its own.
|
|
432
|
+
* /
|
|
433
|
+
* / `#Conflict("Guardian is already active")` when there is nothing to do — the refusal says the
|
|
434
|
+
* / state the caller asked for is the state that holds, rather than pretending it acted.
|
|
435
|
+
*/
|
|
436
|
+
approveGuardian: ActorMethod<[Principal], Result_1>;
|
|
437
|
+
/**
|
|
438
|
+
* / Owner-only: approve one pending over-limit request, letting the agent retry the operation
|
|
439
|
+
* / its policy refused.
|
|
440
|
+
* /
|
|
441
|
+
* / ⚠ THE APPROVAL IS SINGLE-USE AND EXPIRES IN ONE HOUR. Approving does not perform the
|
|
442
|
+
* / operation and does not raise the policy — it opens a window. The agent must retry within
|
|
443
|
+
* / the hour, and the retry CONSUMES the approval (`#Used`); a second attempt needs a second
|
|
444
|
+
* / approval. Past the hour it becomes `#Expired` on first touch. Neither state is recoverable by
|
|
445
|
+
* / approving again — the owner approves a NEW request.
|
|
446
|
+
* / ⟨2026-09-29, review finding X-11⟩ One exception, made by the engram and not by the owner: when
|
|
447
|
+
* / the retry's signer FAILS, nothing was signed, so the approval goes back from `#Used` to
|
|
448
|
+
* / `#Approved` with its original expiry and an `approval.released` entry says so.
|
|
449
|
+
* /
|
|
450
|
+
* / ⚠ IT IS BOUND TO THE EXACT OPERATION THAT WAS REQUESTED, not to the agent. An approval
|
|
451
|
+
* / carries the operation, the amount and the binding it was raised for, and consuming it checks
|
|
452
|
+
* / all three — so approving a request does not grant the agent a general allowance for the
|
|
453
|
+
* / hour, and cannot be redirected at a different recipient or a larger sum.
|
|
454
|
+
* /
|
|
455
|
+
* / Refuses `#NotFound` for an unknown id, and `#Conflict` NAMING THE STATUS when the request is
|
|
456
|
+
* / no longer pending — already approved, denied or expired. The status is in the message because
|
|
457
|
+
* / "not pending" is the one refusal here an owner acts on differently depending on which it is.
|
|
458
|
+
*/
|
|
459
|
+
approveRequest: ActorMethod<[string], Result_1>;
|
|
460
|
+
/**
|
|
461
|
+
* / Discard a backup started by `backupInit` and never finalized. The way out of a failed upload,
|
|
462
|
+
* / and the reason a stalled one need not occupy space indefinitely. Same gate as the rest of the
|
|
463
|
+
* / write half: owner, or an agent holding `canAppendMemory`.
|
|
464
|
+
*/
|
|
465
|
+
backupAbort: ActorMethod<[string], Result_1>;
|
|
466
|
+
/**
|
|
467
|
+
* / Close a backup started by `backupInit` and mark it usable.
|
|
468
|
+
* /
|
|
469
|
+
* / ⚠ ONLY THE CREATOR MAY FINALIZE — `#Refused("Not the creator of this backup")`. An agent
|
|
470
|
+
* / cannot close an upload someone else began, so a half-finished backup belongs to whoever
|
|
471
|
+
* / started it.
|
|
472
|
+
* /
|
|
473
|
+
* / Refuses with `#Conflict` when the backup is already finalized, when it is marked failed, and
|
|
474
|
+
* / when it holds ZERO chunks or zero total size — an empty backup is refused rather than recorded
|
|
475
|
+
* / as a success, which is the difference between "no backup" and "a backup of nothing".
|
|
476
|
+
* /
|
|
477
|
+
* / It does NOT verify the `sha256` declared at init; see that method for what the digest is and
|
|
478
|
+
* / is not.
|
|
479
|
+
*/
|
|
480
|
+
backupFinalize: ActorMethod<[string], Result_1>;
|
|
481
|
+
/**
|
|
482
|
+
* / Begin a chunked backup upload. Returns the `backupId` every later call in the sequence needs.
|
|
483
|
+
* /
|
|
484
|
+
* / **THE SEQUENCE**, which no individual signature here conveys:
|
|
485
|
+
* / `backupInit` → `backupPushChunk` × N → `backupFinalize`, or `backupAbort` to discard. A backup
|
|
486
|
+
* / that is never finalized is not a backup; `backupFinalize` refuses one with zero chunks or zero
|
|
487
|
+
* / total size rather than recording an empty success.
|
|
488
|
+
* /
|
|
489
|
+
* / ⚠ THE `sha256` IS YOUR DECLARATION, NOT THIS CANISTER'S FINDING. It is taken here, before any
|
|
490
|
+
* / bytes arrive, stored with the metadata and carried through finalize UNCHANGED — verified at
|
|
491
|
+
* / the site 2026-08-21: `Backup.finalizeBackup` checks existence, creator, state and non-emptiness
|
|
492
|
+
* / and does NOT recompute or compare a digest. So it is a commitment a restorer can check the
|
|
493
|
+
* / bytes against LATER, and it is not evidence the bytes match. Treating it as a canister-verified
|
|
494
|
+
* / hash is the misreading to avoid — and it is an easy one to reach, because the REGISTRY's
|
|
495
|
+
* / chunked upload (`engramWasmInit`/`PushChunk`/`Finalize`) has the same shape and DOES verify:
|
|
496
|
+
* / it hashes the assembled bytes and refuses on mismatch. Same protocol, opposite semantics.
|
|
497
|
+
* /
|
|
498
|
+
* / **TWO DIFFERENT PERMISSIONS GUARD THE TWO HALVES.** Writing (init, push, finalize, abort) is
|
|
499
|
+
* / owner-or-agent and an AGENT additionally needs `canAppendMemory`; reading
|
|
500
|
+
* / (`backupPullChunk`) needs `read_backup`. An agent can therefore be able to upload a backup
|
|
501
|
+
* / and unable to download one, or the reverse, which is the point of splitting them.
|
|
502
|
+
* /
|
|
503
|
+
* / The write half also refuses while writes are PAUSED.
|
|
504
|
+
*/
|
|
505
|
+
backupInit: ActorMethod<[string, BackupType, [] | [string], string, [] | [string]], Result_43>;
|
|
506
|
+
/**
|
|
507
|
+
* / Read one chunk of a finalized backup, by index.
|
|
508
|
+
* /
|
|
509
|
+
* / ⚠ GATED ON `read_backup`, which is NOT the permission the upload half uses — that one is
|
|
510
|
+
* / `canAppendMemory`. Holding one says nothing about the other, deliberately: taking a backup and
|
|
511
|
+
* / carrying it away are different authorities.
|
|
512
|
+
*/
|
|
513
|
+
backupPullChunk: ActorMethod<[string, bigint], Result_59>;
|
|
514
|
+
backupPushChunk: ActorMethod<[string, bigint, Uint8Array | number[]], Result_1>;
|
|
515
|
+
/**
|
|
516
|
+
* / The OWNER cancels an agent's pending key nomination; the agent keeps its current key. Refused
|
|
517
|
+
* / by name when the agent is unknown or has nothing pending — never a silent success.
|
|
518
|
+
*/
|
|
519
|
+
cancelAgentKeyNomination: ActorMethod<[Principal], Result_1>;
|
|
520
|
+
/**
|
|
521
|
+
* / Close a session the caller paid for: settle what was consumed, refund the remainder.
|
|
522
|
+
* /
|
|
523
|
+
* / PAYER-ONLY, enforced inside the gateway. This is the exit that did not exist — `endSession`
|
|
524
|
+
* / and `forceCloseSession` were on the MARKET, which is withheld, and whose escrow subaccount is
|
|
525
|
+
* / under a different principal entirely, so its close could never have reached these funds.
|
|
526
|
+
*/
|
|
527
|
+
closeSession: ActorMethod<[string], Result_1>;
|
|
528
|
+
/**
|
|
529
|
+
* / Convert the engram's OWN earned ckUSDC/ckUSDT into its OWN cycles, via the cashier — the
|
|
530
|
+
* / engram-self top-up path. Owner-only; per-call cap + cooldown (irreversible); NOT freeze-gated
|
|
531
|
+
* / (infrastructure funding). Flow: read the engram's deposit address on the cashier, move the
|
|
532
|
+
* / engram's tokens there, then have the cashier convert — the cashier self-authorizes because the
|
|
533
|
+
* / caller (this engram) is a registered active engram (registry isRegisteredActiveEngram seam).
|
|
534
|
+
* / (The owner-funded path lives entirely in the frontend: owner → cashier deposit → topUp.)
|
|
535
|
+
* / ⟨0.16.0, L4 — `token : Text` KEPT, deliberately, and this note exists so the sweep that finds
|
|
536
|
+
* / it does not re-litigate it.⟩
|
|
537
|
+
* /
|
|
538
|
+
* / `ownerWithdraw` and the market's `recoverEscrow` both took `Wire.TokenAmount` because they
|
|
539
|
+
* / accept ICP (e8s) BESIDE the stablecoins (e6) — mixed decimals behind one number is a real
|
|
540
|
+
* / hundred-fold error. This method accepts ckUSDC and ckUSDT only. Both are e6, so there is no
|
|
541
|
+
* / unit to get wrong, and the census (row 258) rules the pair as `(token, amountE6)`.
|
|
542
|
+
* /
|
|
543
|
+
* / `Wire.TokenAmount` would be actively WORSE here: its `#Icp` arm is a token this path cannot
|
|
544
|
+
* / convert, so the type would make an unacceptable value REPRESENTABLE and hand back a runtime
|
|
545
|
+
* / rejection anyway — losing the one property the variant is for while gaining a wider type.
|
|
546
|
+
* /
|
|
547
|
+
* / ⟨2026-10-02⟩ The second parameter is NAMED `amountE6` now, as the census row above rules the
|
|
548
|
+
* / pair — e6 base units of the token named first. A name only: Candid passes arguments by
|
|
549
|
+
* / position, so nothing on the wire moved.
|
|
550
|
+
*/
|
|
551
|
+
convertEarningsToCycles: ActorMethod<[string, bigint], Result_8>;
|
|
552
|
+
/**
|
|
553
|
+
* / Owner-only: mint a single-use invite code an agent redeems with `pairAgent`.
|
|
554
|
+
* /
|
|
555
|
+
* / ⚠ READ THIS BEFORE INVITING SOMEONE BACK. Pairing is ONE-SHOT PER PRINCIPAL on
|
|
556
|
+
* / this engram: `pairAgent` refuses ANY caller that already holds a record — `#Active`,
|
|
557
|
+
* / `#Revoked` or `#Resigned` alike — so a principal you have revoked can NEVER redeem another
|
|
558
|
+
* / invite, however many you mint. That is deliberate, because `revokeAgent` is a soft status
|
|
559
|
+
* / change and a revoked key talking its way back in would undo it. The remedy is a DIFFERENT
|
|
560
|
+
* / WALLET; the only thing that clears the record is `resetEngram`, which severs everything else
|
|
561
|
+
* / too.
|
|
562
|
+
* /
|
|
563
|
+
* / Two caps, each refusing with `#Conflict` and naming its own limit: concurrent ACTIVE agents
|
|
564
|
+
* / (multi-agent owners legitimately need several — a connector host plus a coding agent), and
|
|
565
|
+
* / concurrent unexpired INVITES. Neither is a rate limit; both are ceilings you clear by revoking
|
|
566
|
+
* / or by letting invites lapse.
|
|
567
|
+
* /
|
|
568
|
+
* / A principal that is already a GUARDIAN cannot become an agent — a guardian is an
|
|
569
|
+
* / independent check on agents, so one wallet must not hold both.
|
|
570
|
+
*/
|
|
571
|
+
createAgentInvite: ActorMethod<[string, AgentPermissions], Result_43>;
|
|
572
|
+
/**
|
|
573
|
+
* / Owner-only: mint an invite for a GUARDIAN — an independent check on agents, not a
|
|
574
|
+
* / co-owner and not a recovery agent.
|
|
575
|
+
* /
|
|
576
|
+
* / ⚠ WHAT A GUARDIAN CAN DO IS EXACTLY THREE THINGS, all of them BRAKES: revoke agents,
|
|
577
|
+
* / freeze payments, pause writes. That is the whole permission set (`GuardianPermissions`), and
|
|
578
|
+
* / the three flags are FROZEN — any future permission arrives as a scope string instead.
|
|
579
|
+
* /
|
|
580
|
+
* / ⚠ WHAT A GUARDIAN CANNOT DO, said plainly because the word invites the opposite reading: they
|
|
581
|
+
* / cannot read memory, cannot move money, cannot transfer ownership, and **cannot recover a lost
|
|
582
|
+
* / owner key**. A guardian is not a recovery mechanism. An owner appointing one against the day
|
|
583
|
+
* / they lose access is appointing the wrong thing.
|
|
584
|
+
* /
|
|
585
|
+
* / Two steps, and the invite is only the first: the invitee registers, which leaves them
|
|
586
|
+
* / `#Pending` and INERT, and `approveGuardian` is what makes them active. A guardian who has
|
|
587
|
+
* / registered but not been approved can do none of the three.
|
|
588
|
+
* /
|
|
589
|
+
* / ⚠ AN AGENT CANNOT BECOME A GUARDIAN, and the refusal lands at REGISTRATION rather than
|
|
590
|
+
* / here: this call will happily mint an invite for a principal that already holds an agent
|
|
591
|
+
* / record, and `registerGuardian` then refuses it with "An agent cannot also be a guardian".
|
|
592
|
+
* / So an invite that fails to redeem for that reason is not a bad code. The rule exists because
|
|
593
|
+
* / a check must be independent of the thing it checks.
|
|
594
|
+
*/
|
|
595
|
+
createGuardianInvite: ActorMethod<[string, GuardianPermissions], Result_43>;
|
|
596
|
+
/**
|
|
597
|
+
* / OWNER-ONLY deletion of a stored backup.
|
|
598
|
+
* /
|
|
599
|
+
* / ⚠ NOT THE SAME GATE AS THE REST OF THE FAMILY, and the asymmetry is deliberate: `backupInit`,
|
|
600
|
+
* / `backupPushChunk`, `backupFinalize` and `backupAbort` accept an agent holding
|
|
601
|
+
* / `canAppendMemory`, and `backupPullChunk` accepts one holding `read_backup`. Only the OWNER may
|
|
602
|
+
* / delete. So an agent can take backups and carry them away and cannot destroy one —
|
|
603
|
+
* / creating is delegable, destroying is not.
|
|
604
|
+
* /
|
|
605
|
+
* / `backupAbort` is the agent's way out of a failed UPLOAD; it discards something never
|
|
606
|
+
* / finalized. This removes a finished backup, which is a different act on a different object.
|
|
607
|
+
*/
|
|
608
|
+
deleteBackup: ActorMethod<[string], Result_1>;
|
|
609
|
+
/**
|
|
610
|
+
* / ⟨0.16.0, census §10 item 16⟩ RETURNS A REAL RECEIPT, not `R<()>`. The receipt was already
|
|
611
|
+
* / being computed and written into the audit line — `receiptSuffix(r)` — and then discarded, so
|
|
612
|
+
* / a caller could not cite the seq its own delete produced and had to go looking for it in a log
|
|
613
|
+
* / it may not be allowed to read. A delete is an EVENT on the chain; an event that will not tell
|
|
614
|
+
* / you where it landed is evidence nobody can point at. Same projection as writeMemory.
|
|
615
|
+
*/
|
|
616
|
+
deleteMemoryFile: ActorMethod<[string], Result>;
|
|
617
|
+
/**
|
|
618
|
+
* / Owner-only: deny one pending over-limit request, with a `reason` the agent can read.
|
|
619
|
+
* /
|
|
620
|
+
* / The reason is stored on the request rather than discarded, which is the point of taking it —
|
|
621
|
+
* / an agent told only "denied" retries, and one told why can adapt or stop asking. It is the
|
|
622
|
+
* / owner's message to whoever raised the request, not an audit-only field.
|
|
623
|
+
* /
|
|
624
|
+
* / Terminal: a denied request cannot be approved afterwards. Like `approveRequest` it refuses
|
|
625
|
+
* / `#NotFound` for an unknown id and `#Conflict` when the request is no longer pending, and it
|
|
626
|
+
* / does not change the policy — the next request over the same limit will be raised again.
|
|
627
|
+
*/
|
|
628
|
+
denyRequest: ActorMethod<[string, string], Result_1>;
|
|
629
|
+
/**
|
|
630
|
+
* / Force the tECDSA derivation and return the address.
|
|
631
|
+
* /
|
|
632
|
+
* / It exists because the gateway's own derivation fires from a timer that is lazy on some
|
|
633
|
+
* / replicas, and until it lands the EVM quote advertises the `0x0` fallback and settle fails
|
|
634
|
+
* / closed — a live money surface quoting an address that cannot receive.
|
|
635
|
+
* /
|
|
636
|
+
* / ⟨0.16.0, B-2⟩ Derivation now comes from `EvmIdentity`, and the return type carries the
|
|
637
|
+
* / outcome: this used to answer `""` on failure, which is a Text a caller can and did paste into
|
|
638
|
+
* / a payment flow. An empty string is not an address, and saying so is the difference between a
|
|
639
|
+
* / failed derivation and an address of nothing.
|
|
640
|
+
* /
|
|
641
|
+
* / ⚠ TRANSITIONAL: it also primes the ic402 gate, because the gate still settles commerce on this
|
|
642
|
+
* / canister until those 47 methods move. That second call disappears with them — it is listed in
|
|
643
|
+
* / the move order in the spec's B-2 addendum, not left for someone to find.
|
|
644
|
+
* /
|
|
645
|
+
* / PUBLIC: it inherits `getEvmAddress`'s gate rather than choosing one, and could not usefully be
|
|
646
|
+
* / narrower — it exists so a caller can make the derivation happen BEFORE a payment flow, and the
|
|
647
|
+
* / derivation itself is ungated. Idempotent and bounded to the same one-derivation-per-lifetime
|
|
648
|
+
* / work, so an anonymous caller can cause it once and no more.
|
|
649
|
+
* / ⟨L7⟩ UPDATE, NOT QUERY, and this one does not merely await — it WRITES. The body awaits
|
|
650
|
+
* / `EvmIdentity.deriveAddress` (the management canister's `ecdsa_public_key`) and
|
|
651
|
+
* / `gate.deriveEvmRecipientAt` ⟨renamed 2026-09-22 with the path⟩, then caches the result in `evmAddressCache`. So a query is
|
|
652
|
+
* / impossible twice over: it could not await the derivation, and it could not keep the answer.
|
|
653
|
+
* / Named `ensure*` rather than `get*` for that reason — the write is the point, and a read verb
|
|
654
|
+
* / would have promised a cheapness this cannot deliver.
|
|
655
|
+
* /
|
|
656
|
+
* / ⟨Marker added 2026-08-23; the census row said "L7 mark added per review" and no mark was at
|
|
657
|
+
* / the site.⟩
|
|
658
|
+
*/
|
|
659
|
+
ensureEvmReady: ActorMethod<[], Result_43>;
|
|
660
|
+
/**
|
|
661
|
+
* / Record that log entries [fromSeq, toSeq] were served, and return the root that proves it.
|
|
662
|
+
* /
|
|
663
|
+
* / This is the receipt ledgerfs Q2 requires before any of those entries may be condensed away.
|
|
664
|
+
* / The canister cannot know the owner KEPT the bytes it served — it can only prove they were
|
|
665
|
+
* / SERVED — and `opsRoot` is what makes a kept copy verifiable forever afterwards. Keep it with
|
|
666
|
+
* / the archive; without it the download is just bytes.
|
|
667
|
+
* /
|
|
668
|
+
* / NOT gated on requireWritesNotPaused, deliberately. A guardian pause is an emergency brake on
|
|
669
|
+
* / changing the record; an export changes nothing about the files and only appends its own
|
|
670
|
+
* / attestation. Trapping the owner's own data behind the brake would make the pause a hostage
|
|
671
|
+
* / situation rather than a safety measure. It IS gated on requireMemoryAttached: a store that
|
|
672
|
+
* / failed its integrity check must not attest anything it cannot vouch for.
|
|
673
|
+
*/
|
|
674
|
+
exportMemoryRange: ActorMethod<[bigint, bigint, [] | [Principal]], Result_66>;
|
|
675
|
+
/**
|
|
676
|
+
* / ⟨0.16.0, L2.2 — renamed from `guardianFreezePayments`⟩ The prefix LIED about who may call it.
|
|
677
|
+
* / The gate is `requireOwnerOrGuardian`, and an owner freezing their own payments is the ordinary
|
|
678
|
+
* / case — the guardian is the exceptional one. A name that says otherwise sends an owner looking
|
|
679
|
+
* / for a method that does not exist. `unfreezePayments`, its owner-only inverse, never carried the
|
|
680
|
+
* / prefix, so the pair read as unrelated.
|
|
681
|
+
* /
|
|
682
|
+
* / WHAT THE FREEZE ACTUALLY COVERS ⟨enumerated 2026-08-21 from the eight `requirePaymentsNotFrozen`
|
|
683
|
+
* / call sites, because it was written down nowhere and had to be re-derived to be trusted⟩:
|
|
684
|
+
* /
|
|
685
|
+
* / · EVERY SIGNING PATH, which is the point of the brake. `signX402Payment` and
|
|
686
|
+
* / `sysSignX402Payment` through `x402SignFor`; `signEip712` and `sysSignEip712` through
|
|
687
|
+
* / `eip712SignFor`; `signEngramRegistration` directly. ⟨The two helpers are why a grep of an
|
|
688
|
+
* / individual method's body finds nothing — the check is one level down.⟩
|
|
689
|
+
* / · `addEip712Type` and `addEvmWithdrawDestination` — pre-staging for a later payout is the
|
|
690
|
+
* / thing a brake most needs to stop, so the destination list is frozen along with the signing.
|
|
691
|
+
* / · `sessionReadMemory` and `sessionAppendMemory` — the paid-memory rail, money coming IN.
|
|
692
|
+
* /
|
|
693
|
+
* / AND WHAT IT DELIBERATELY DOES NOT, stated so the absence is not read as an oversight:
|
|
694
|
+
* /
|
|
695
|
+
* / · `convertEarningsToCycles` — the owner's OWN earnings becoming their OWN engram's fuel. A
|
|
696
|
+
* / frozen engram still burns cycles, so freezing this would let a brake starve the thing it
|
|
697
|
+
* / is protecting. Owner-only, capped per call, and it moves nothing outward.
|
|
698
|
+
* / · `approveRequest` — an approval is not a spend. The spend it authorises goes through
|
|
699
|
+
* / `x402SignFor`, which IS frozen, so an approval granted during a freeze simply waits.
|
|
700
|
+
* / · `transferOwnership` — ownership is not a payment, and a guardian's PAYMENTS brake is not
|
|
701
|
+
* / a veto on who owns the engram.
|
|
702
|
+
* /
|
|
703
|
+
* / ⚠ The three exclusions are a reading of intent, not a ruling: no declaration stated the scope
|
|
704
|
+
* / before this one. If any of them is wrong, this comment is where the argument should happen.
|
|
705
|
+
*/
|
|
706
|
+
freezePayments: ActorMethod<[], Result_1>;
|
|
707
|
+
/**
|
|
708
|
+
* / Delivery status + config readback. Owner-only (the URL is a secret).
|
|
709
|
+
*/
|
|
710
|
+
getActionAlertStatus: ActorMethod<[], Result_57>;
|
|
711
|
+
/**
|
|
712
|
+
* / Agents need to know what they may revise, so they can read it too. Whole-value config, same
|
|
713
|
+
* / carve-out as getProtectedPaths — and kept a SEPARATE method from it deliberately (L2.2): a
|
|
714
|
+
* / protected path and a revisable path are opposite grants, and one accessor for both would be a
|
|
715
|
+
* / name that lies about which power it reports.
|
|
716
|
+
* /
|
|
717
|
+
* / Refusal reason preserved from the trap: a grant is a power, and its absence and its
|
|
718
|
+
* / concealment are different facts.
|
|
719
|
+
*/
|
|
720
|
+
getAgentRevisablePaths: ActorMethod<[], Result_53>;
|
|
721
|
+
/**
|
|
722
|
+
* / OWNER-ONLY: every engagement's seat weeks on this engram, with the agent's root — the day it
|
|
723
|
+
* / paired, the days of its first and last payment signature, a 64-week map whose bit 0 is the week
|
|
724
|
+
* / of the last one, and how many were produced. Never an amount, a recipient or a nonce.
|
|
725
|
+
* /
|
|
726
|
+
* / WHY THE OWNER ALWAYS READS IT: these are the rows the metrics reader the registry designated may
|
|
727
|
+
* / read (`sysGetAgentSeatWeeks`), and an owner deciding whether to leave that read on must be able
|
|
728
|
+
* / to see exactly what it is handed. The reader's rows are these rows without the root, in the same
|
|
729
|
+
* / order. Anyone else is refused by name (`#Refused getAgentSeatWeeks: …`), never answered with an
|
|
730
|
+
* / empty page. Paged; `total` is every engagement ever paired here (a reset keeps the rows).
|
|
731
|
+
* / Two rows can name one root: an agent paired again after it left is a second engagement.
|
|
732
|
+
*/
|
|
733
|
+
getAgentSeatWeeks: ActorMethod<[bigint, bigint], Result_64>;
|
|
734
|
+
/**
|
|
735
|
+
* / Owner: everything written into this engram by someone other than the owner since the last
|
|
736
|
+
* / markAgentWritesReviewed() — agent appends/revisions AND paid-session appends (see
|
|
737
|
+
* / qualifiesForReview for why those two families are recognised differently).
|
|
738
|
+
* / `capped=true` means exactly 200 rows were returned and MORE unreviewed writes exist beyond
|
|
739
|
+
* / them — the UI must page (markAgentWritesReviewed(?lastShownId)) and must NOT present 200
|
|
740
|
+
* / as a total. `earliest` discloses ring eviction — if cursor < earliest, entries between them
|
|
741
|
+
* / aged out of the ring (the CHAIN still proves total count; this view can't show their bodies).
|
|
742
|
+
*/
|
|
743
|
+
getAgentWriteReview: ActorMethod<[], Result_63>;
|
|
744
|
+
/**
|
|
745
|
+
* / Why anchoring is or is not advancing. PUBLIC: ungated on purpose — detecting a stalled
|
|
746
|
+
* / engram is the point, a gated read would fail-to-empty and hand a third party fabricated zeros,
|
|
747
|
+
* / and none of these fields is a secret — `total` is already public via getCertifiedAuditHead.
|
|
748
|
+
* / See the field comments above for how to read the combinations.
|
|
749
|
+
*/
|
|
750
|
+
getAnchorPushStatus: ActorMethod<[], AnchorPushStatus>;
|
|
751
|
+
/**
|
|
752
|
+
* / The plain chain head — size and hash, world-readable, no certificate.
|
|
753
|
+
* /
|
|
754
|
+
* / ⟨0.16.0, census `keep (NEW)`⟩ It was specced and never built. `Wire.AuditHead`'s own
|
|
755
|
+
* / declaration says why it matters: heads exist TO BE COMPARED (L8), a head nobody can read
|
|
756
|
+
* / witnesses nothing, and the registry and cashier already served exactly this shape — so the
|
|
757
|
+
* / engram, "the canister that IS the evidence product", was the one chain a verifier could not
|
|
758
|
+
* / ask for a head without also asking for a certificate it may not want.
|
|
759
|
+
* /
|
|
760
|
+
* / PUBLIC: bare, and it cannot refuse — a chain head discloses nothing about content or callers,
|
|
761
|
+
* / and gating it would make the comparison it exists for depend on permission. `getCertifiedAuditHead`
|
|
762
|
+
* / below serves the same head WITH the subnet certificate for a caller that needs to verify it
|
|
763
|
+
* / was signed rather than asserted.
|
|
764
|
+
*/
|
|
765
|
+
getAuditHead: ActorMethod<[], AuditHead>;
|
|
766
|
+
getBackupMetadata: ActorMethod<[string], Result_62>;
|
|
767
|
+
/**
|
|
768
|
+
* / The cashier this engram recognises as its rent biller — `null` until the registry pushes one.
|
|
769
|
+
* /
|
|
770
|
+
* / PUBLIC: a payer about to send money needs to know which cashier this engram will accept credit
|
|
771
|
+
* / from, BEFORE sending it — paying a cashier this engram does not recognise collects funds that
|
|
772
|
+
* / never become rent. The registry publishes the same fact as `getRentBiller`; publishing it here
|
|
773
|
+
* / too is what lets the two be COMPARED, which is the only way to catch a mismatch.
|
|
774
|
+
*/
|
|
775
|
+
getBillerId: ActorMethod<[], [] | [Principal]>;
|
|
776
|
+
/**
|
|
777
|
+
* / ⟨0.16.0, L9/L10 — census row⟩ `Wire.CertifiedAuditHead`, not an anonymous record. The
|
|
778
|
+
* / registry, market and cashier already served the shared type; the engram — the canister that
|
|
779
|
+
* / IS the evidence product — was the one chain still answering in a shape of its own, missing
|
|
780
|
+
* / `witness` entirely. One certified-head shape on every chain is the point: a verifier that can
|
|
781
|
+
* / read three of them and not the fourth has to special-case the one that matters most.
|
|
782
|
+
* /
|
|
783
|
+
* / `witness = null` is the honest answer here and is NOT the same as an empty proof. This engram
|
|
784
|
+
* / certifies its head via `CertifiedData` but keeps no witness tree, so there is no reveal to
|
|
785
|
+
* / encode; `?Blob` lets it say "I do not serve a proof" rather than fabricate one.
|
|
786
|
+
* /
|
|
787
|
+
* / PUBLIC: the certificate is the point — it lets a stranger verify against the NNS root key
|
|
788
|
+
* / instead of trusting this replica, and a proof that requires a role to fetch rests on exactly
|
|
789
|
+
* / the authority it was introduced to remove.
|
|
790
|
+
*/
|
|
791
|
+
getCertifiedAuditHead: ActorMethod<[], CertifiedAuditHead>;
|
|
792
|
+
/**
|
|
793
|
+
* / The allowance of the agent holding `agentPrincipal`: its lasting key and the openings left.
|
|
794
|
+
* / Readable by the owner and by that agent's own key — refused loudly to anyone else, never a zero
|
|
795
|
+
* / (a zero would be a claim about another owner's grant).
|
|
796
|
+
* /
|
|
797
|
+
* / ⟨2026-10-01, review F2⟩ A QUERY, so the refusal is deliberately NOT written to the denial log: a
|
|
798
|
+
* / query's state writes are discarded when it returns, and the `denied` call first written here
|
|
799
|
+
* / recorded nothing while reading as if it did. The refusal is loud in the reply instead. WHAT
|
|
800
|
+
* / WOULD MAKE THIS WRONG: a reason to record who asked — then this becomes an update that says so.
|
|
801
|
+
*/
|
|
802
|
+
getChildAllowance: ActorMethod<[Principal], Result_61>;
|
|
803
|
+
/**
|
|
804
|
+
* / Owner-only, Billing-class: what opening an engram costs this engram, the balance below which an
|
|
805
|
+
* / agent's request is refused, the balance now, and every agent's allowance. The console's cost
|
|
806
|
+
* / sentence reads it. Cycles are owner-class information, as on the owner's console read.
|
|
807
|
+
*/
|
|
808
|
+
getChildOpening: ActorMethod<[], Result_60>;
|
|
809
|
+
/**
|
|
810
|
+
* / Derive the shared memory-encryption key, encrypted under the caller's transport
|
|
811
|
+
* / public key. Gated to owner + read-agents (the same principals allowed to read
|
|
812
|
+
* / memory). The client decrypts it locally with its transport secret key.
|
|
813
|
+
* / ⟨0.16.0⟩ THE FOLD: `epoch` is now an optional argument here, and the separate
|
|
814
|
+
* / `getEncryptedMemoryKeyForEpoch` is gone. Two methods differing only by whether one parameter
|
|
815
|
+
* / is present is what an optional argument is for, and the split forced a client to decide which
|
|
816
|
+
* / to call before it knew whether it needed rotation.
|
|
817
|
+
* /
|
|
818
|
+
* / `null` means CURRENT — not epoch 0. Those coincide today (nothing increments the epoch yet)
|
|
819
|
+
* / and will not after the first rotation, which is exactly when a caller that meant "the key that
|
|
820
|
+
* / seals my memory now" must not silently receive a superseded one. `?0` still names epoch 0
|
|
821
|
+
* / explicitly for a client rebuilding an old cache entry.
|
|
822
|
+
* /
|
|
823
|
+
* / Refusing a FUTURE epoch is not a bounds check, it is the rotation invariant: pre-deriving a
|
|
824
|
+
* / key for an epoch nobody has reached would make rotating to it meaningless.
|
|
825
|
+
* /
|
|
826
|
+
* / Also converted off the lowercase `#ok/#err` dialect (L5) — that spelling arrived from ic402
|
|
827
|
+
* / and had no business on a vetKD path, which touches nothing of ic402's.
|
|
828
|
+
* /
|
|
829
|
+
* / ⟨L7⟩ UPDATE, NOT QUERY, and this is the system call that forces it: the body awaits
|
|
830
|
+
* / `VetKeys.ManagementCanister.vetKdDeriveKey`. A query cannot await, so the round trip is the
|
|
831
|
+
* / cost. Stated here because L7 requires the reason be readable from the interface rather than
|
|
832
|
+
* / inferred by opening the body — which is exactly what had to happen to write this line.
|
|
833
|
+
*/
|
|
834
|
+
getEncryptedMemoryKey: ActorMethod<[[] | [bigint], Uint8Array | number[]], Result_59>;
|
|
835
|
+
/**
|
|
836
|
+
* / ⟨0.16.0, owner ruling 2026-08-20 — option (a)⟩ `x402Support` REPORTS THE RAIL, not a constant.
|
|
837
|
+
* /
|
|
838
|
+
* / The card's config hardcodes `x402Support = true`, answering a buyer's question with a fact
|
|
839
|
+
* / about the software rather than about THIS engram. B1 moved the 402 challenge machinery to the
|
|
840
|
+
* / market; the one x402-payable rail the engram kept is `sessionReadMemory`, gated by
|
|
841
|
+
* / `paidMemoryReadEnabled`, which DEFAULTS TO FALSE. So a discovering agent was told this engram
|
|
842
|
+
* / takes x402 payments while every paid read on a default engram is refused with "the owner has
|
|
843
|
+
* / not opened the monetized read rail". Ruled (a) over keeping `true` to mean "can PARTICIPATE in
|
|
844
|
+
* / x402, including as a payer" — defensible, but not what a service card says to a buyer.
|
|
845
|
+
* /
|
|
846
|
+
* / Overridden HERE rather than at the config because the card is built once as a `public let`
|
|
847
|
+
* / while the flag is runtime state, and `getCard()` belongs to the VENDORED ic402 module, which
|
|
848
|
+
* / is not ours to edit.
|
|
849
|
+
* /
|
|
850
|
+
* / ⚠ `signEngramRegistration` also reads `getCard()` and is deliberately NOT changed. It signs an
|
|
851
|
+
* / ERC-8004 registration for on-chain publication — a point-in-time attestation nobody can
|
|
852
|
+
* / re-sign every time an owner opens or closes the rail. Whether a signed record should carry
|
|
853
|
+
* / mutable operational state at all is a different decision, it is signing-adjacent, and the
|
|
854
|
+
* / ruling did not reach it. Filed, not folded in.
|
|
855
|
+
* /
|
|
856
|
+
* / PUBLIC: an agent card is a DISCOVERY document — its entire function is to tell a party that
|
|
857
|
+
* / has never met this engram what it is and how to transact with it. A card behind a gate cannot
|
|
858
|
+
* / be discovered, and the ERC-8004 ecosystem it participates in assumes an open read.
|
|
859
|
+
*/
|
|
860
|
+
getEngramCard: ActorMethod<[], AgentCard>;
|
|
861
|
+
/**
|
|
862
|
+
* / PUBLIC: the engram's permanent spawn ordinal — a provable, non-sensitive fact. It identifies a
|
|
863
|
+
* / canister, never a person.
|
|
864
|
+
* / null = spawned before numbering existed; the owner can backfill via syncEngramNumber().
|
|
865
|
+
*/
|
|
866
|
+
getEngramNumber: ActorMethod<[], [] | [bigint]>;
|
|
867
|
+
/**
|
|
868
|
+
* / Re-pointed at `EvmIdentity` (B-2): custody derivation no longer routes through the ic402
|
|
869
|
+
* / Gateway, which is leaving for the market canister. Behaviour is unchanged for a caller — same
|
|
870
|
+
* / address, same tECDSA key — but the engram no longer needs a marketplace to know its own
|
|
871
|
+
* / address, which is the whole point of the split.
|
|
872
|
+
* /
|
|
873
|
+
* / ⟨2026-08-21⟩ DO NOT FOLD THIS WITH `getEvmSignerAddress`. The 0.16.0 census carried the fold
|
|
874
|
+
* / as an open item, conditional on "if the derivation is identical". It is not, and the condition
|
|
875
|
+
* / is decidable here rather than by reading either comment:
|
|
876
|
+
* /
|
|
877
|
+
* / this method EvmIdentity.deriveAddress -> derivation_path = []
|
|
878
|
+
* / the signer eip712PublicKey -> derivation_path = ["eip712"]
|
|
879
|
+
* /
|
|
880
|
+
* / ⟨CORRECTED 2026-09-22 — the two paths above are what the code passed until KEY-PATHS §4 step 5;
|
|
881
|
+
* / the table is kept because the ARGUMENT it makes is unchanged and is the reason the fold is
|
|
882
|
+
* / still refused.⟩ The signer now reads `KeyPaths.EIP712` = `["engramx","eip712","secp256k1","v1"]`
|
|
883
|
+
* / and this method still derives at the empty path, because `pay` is the one row the genesis could
|
|
884
|
+
* / not move — ic402 2.15.0 parameterises `EvmSigner` but not `Gateway.deriveEvmRecipient`,
|
|
885
|
+
* / `EvmSender` or `Identity`, and moving the signer without them would split receiving from
|
|
886
|
+
* / spending. The paths are still DIFFERENT, which is the whole of the argument below, and they get
|
|
887
|
+
* / further apart at the genesis rather than closer.
|
|
888
|
+
* /
|
|
889
|
+
* / ⟨SHIPPED 2026-09-22, ic402 2.16.0 — the table is now BOTH rows labelled, and the argument is
|
|
890
|
+
* / unchanged, which is the point of keeping every version of it here:
|
|
891
|
+
* /
|
|
892
|
+
* / this method EvmIdentity.deriveAddress -> KeyPaths.PAY = ["engramx","pay","secp256k1","v1"]
|
|
893
|
+
* / the signer eip712PublicKey -> KeyPaths.EIP712 = ["engramx","eip712","secp256k1","v1"]
|
|
894
|
+
* /
|
|
895
|
+
* / Two paths, one master key, therefore two addresses — exactly as when one of them was `[]`.
|
|
896
|
+
* / The fold stays refused for the reason below, not because one side happened to be a default.
|
|
897
|
+
* / What changed upstream is that `Gateway`, `EvmSender` and `Identity` all take a path now, so
|
|
898
|
+
* / the payment identity could move as ONE thing: this derivation, the gateway's inbound
|
|
899
|
+
* / recipient and outbound sender, and `Payments.evmSigner`. The genesis install derives them.⟩
|
|
900
|
+
* /
|
|
901
|
+
* / Same master key and curve, different paths, therefore different public keys and DIFFERENT
|
|
902
|
+
* / ADDRESSES — that is what a derivation path is for. The difference is also deliberate and
|
|
903
|
+
* / security-bearing, not incidental: the signer key is declared "outbound-only, N=1, never the
|
|
904
|
+
* / payment path — this key must never be able to move ic402 pool funds", so merging the two
|
|
905
|
+
* / would hand the signing surface the payment key. `getEvmSignerAddress` carries the warning
|
|
906
|
+
* / from its side ("the payment key's address is NOT this one, by design"); this is the other
|
|
907
|
+
* / side, because a fold is proposed by whoever reads either declaration first.
|
|
908
|
+
* /
|
|
909
|
+
* / The gates differ too, which a fold would also have to collapse: this method is UNGATED (any
|
|
910
|
+
* / caller may cause the derivation) and `getEvmSignerAddress` is owner-only.
|
|
911
|
+
* /
|
|
912
|
+
* / PUBLIC: an address is a destination, not a capability — publishing it lets anyone PAY this
|
|
913
|
+
* / engram and lets nobody spend from it. It has to be readable by a stranger because a stranger
|
|
914
|
+
* / is exactly who needs it. The write it causes is bounded to one derivation and one
|
|
915
|
+
* / set-once custody stamp per engram lifetime, which is what keeps "any caller may cause it"
|
|
916
|
+
* / safe rather than merely permitted.
|
|
917
|
+
* / ⟨L7⟩ UPDATE, NOT QUERY, and this is the system call that forces it: the body awaits
|
|
918
|
+
* / `EvmIdentity.deriveAddress`, which reaches the management canister's `ecdsa_public_key`. A
|
|
919
|
+
* / query cannot await it.
|
|
920
|
+
* /
|
|
921
|
+
* / ⟨Marker added 2026-08-23; the census row already said "L7 marked (ecdsa_public_key)" and the
|
|
922
|
+
* / site did not carry the mark. Same `public func` form as its two neighbours above.⟩
|
|
923
|
+
* /
|
|
924
|
+
* / ⟨2026-09-28⟩ THE REPLY IS A RECORD, `Types.EvmAddresses` — the payment address (`pay`, what this
|
|
925
|
+
* / method returned alone until then) and the address that signs the engram's own registrations
|
|
926
|
+
* / (`engramRegistration`). The owner decided that date to publish the registration address as a new
|
|
927
|
+
* / field on an existing address reply, not as a new method; nothing served it before, so an
|
|
928
|
+
* / agent could not read the address whose nonce `signEngramRegistration` needs and whose ETH
|
|
929
|
+
* / pays its gas. The registration address is read FROM THE SIGNER ITSELF
|
|
930
|
+
* / (`engramRegSigner.getEvmAddress`), not re-derived beside it, so the published address is by
|
|
931
|
+
* / construction the one the signatures come from. It is cached inside that signer object; the
|
|
932
|
+
* / cache is not stable, so the first call after an upgrade re-derives it once — the same one
|
|
933
|
+
* / public-key read, bounded, that the payment branch does on a null cache.
|
|
934
|
+
* /
|
|
935
|
+
* / It refuses rather than half-answers: if either address cannot be derived the reply is
|
|
936
|
+
* / `#Err`, never a record carrying an empty string (ic402's `getEvmAddress` answers `""` on a
|
|
937
|
+
* / failed derivation — that is fail-to-empty on a money surface, and it stops here).
|
|
938
|
+
*/
|
|
939
|
+
getEvmAddress: ActorMethod<[], Result_58>;
|
|
940
|
+
/**
|
|
941
|
+
* / The owner's OWN EVM address, if they registered one — distinct from `getEvmAddress`, which is
|
|
942
|
+
* / the address this canister derives for itself.
|
|
943
|
+
* /
|
|
944
|
+
* / PUBLIC: an address is a public identifier on every chain it exists on; it is a destination,
|
|
945
|
+
* / not a capability, and knowing it confers nothing. `null` means the owner registered none,
|
|
946
|
+
* / which a payer needs to be able to tell from an address they failed to read.
|
|
947
|
+
*/
|
|
948
|
+
getEvmOwnerAddress: ActorMethod<[], [] | [string]>;
|
|
949
|
+
/**
|
|
950
|
+
* / D1 ships with this: the address of the DEDICATED signing key. Without it the owner funds the
|
|
951
|
+
* / wrong address — the payment key's address is NOT this one, by design.
|
|
952
|
+
* /
|
|
953
|
+
* / ⟨L7⟩ UPDATE, NOT QUERY, and this is the system call that forces it: `eip712PublicKey()` awaits
|
|
954
|
+
* / the management canister's `ecdsa_public_key`. A query cannot await, so the round-trip is the
|
|
955
|
+
* / cost — stated here because L7 requires the reason be readable from the interface rather than
|
|
956
|
+
* / inferred by opening the body.
|
|
957
|
+
*/
|
|
958
|
+
getEvmSignerAddress: ActorMethod<[], Result_43>;
|
|
959
|
+
/**
|
|
960
|
+
* / PUBLIC: where this chain begins, for the stranger deciding whether to trust it.
|
|
961
|
+
* /
|
|
962
|
+
* / The fourth of the four evidence methods (`getAuditHead`, `getCertifiedAuditHead`,
|
|
963
|
+
* / `listAuditEntries`, this) that every chain canister now serves in the same shape. Ungated for
|
|
964
|
+
* / the same reason the head is: a verifier who must ask permission to learn where a chain starts
|
|
965
|
+
* / cannot verify it, and nothing here identifies anybody.
|
|
966
|
+
*/
|
|
967
|
+
getGenesisNote: ActorMethod<[], GenesisNote>;
|
|
968
|
+
/**
|
|
969
|
+
* / A guardian's own channel status (their URL is their secret — each guardian sees only theirs).
|
|
970
|
+
*/
|
|
971
|
+
getGuardianAlertStatus: ActorMethod<[], Result_57>;
|
|
972
|
+
/**
|
|
973
|
+
* / The market this engram will accept signing requests from — `null` until the registry pushes
|
|
974
|
+
* / one at spawn, which is why `requireMarket` refuses fleet-wide today.
|
|
975
|
+
* /
|
|
976
|
+
* / PUBLIC: this is the whole of what stands between a stranger and this engram's signing key. A
|
|
977
|
+
* / counterparty evaluating an engram's market claim has to be able to read which market it is
|
|
978
|
+
* / pinned to, and `null` — "pinned to nobody, so it signs for nobody" — is the most important
|
|
979
|
+
* / answer it can give.
|
|
980
|
+
*/
|
|
981
|
+
getMarketId: ActorMethod<[], [] | [Principal]>;
|
|
982
|
+
/**
|
|
983
|
+
* / FD, the one coordinated interface break: history no longer carries per-version CONTENT.
|
|
984
|
+
* /
|
|
985
|
+
* / The legacy shape returned a full snapshot of every version, which is what made history cost
|
|
986
|
+
* / O(total bytes ever written) and forced a per-version truncation cap that silently mangled
|
|
987
|
+
* / large files. What a reader gets now is the COMMITMENT — size and content root per version —
|
|
988
|
+
* / and content is read per version through readMemoryBytes, verified as it is served.
|
|
989
|
+
* /
|
|
990
|
+
* / Two deliberate shape changes beyond dropping the bytes:
|
|
991
|
+
* /
|
|
992
|
+
* / * it is a RESULT. The old surface returned `[]` for "no such file", "you may not read
|
|
993
|
+
* / this", and "this file genuinely has no history" alike — a gated empty indistinguishable
|
|
994
|
+
* / from a real one, which is the exact failure class this store exists to end. A refusal
|
|
995
|
+
* / now says so.
|
|
996
|
+
* / * the counts ride along. `everCount` vs `retainedCount` makes byte eviction impossible to
|
|
997
|
+
* / hide: a reader who sees them differ knows something was reclaimed, and `evictions`
|
|
998
|
+
* / carries the disclosure — chain sequence and evicted root — for each range.
|
|
999
|
+
* /
|
|
1000
|
+
* / Paging is by version number, which works as its own cursor because versions are dense and
|
|
1001
|
+
* / never renumbered: the next page starts at the last version returned plus one. Defaults
|
|
1002
|
+
* / return the whole history of any file a pre-FD engram could have held.
|
|
1003
|
+
*/
|
|
1004
|
+
getMemoryHistory: ActorMethod<[string, [] | [bigint], [] | [bigint]], Result_56>;
|
|
1005
|
+
/**
|
|
1006
|
+
* / PUBLIC: the epoch alone, and deliberately nothing else (rotation study D4). A `rotatedAt[]`
|
|
1007
|
+
* / history would be a public, fleet-enumerable feed of when each owner terminated a trust
|
|
1008
|
+
* / relationship — readable by, among others, the party just terminated.
|
|
1009
|
+
*/
|
|
1010
|
+
getMemoryKeyEpoch: ActorMethod<[], bigint>;
|
|
1011
|
+
/**
|
|
1012
|
+
* / BLS verification key for the shared memory-encryption key. Used by the
|
|
1013
|
+
* / client to verify the derived key. Static per (context, key_id) — cacheable.
|
|
1014
|
+
* /
|
|
1015
|
+
* / PUBLIC: intentionally unauthenticated — a vetKD public key reveals nothing secret and
|
|
1016
|
+
* / cannot decrypt anything — the sensitive derivation is getEncryptedMemoryKey
|
|
1017
|
+
* / below, which IS gated (read_memory) and returns key material encrypted to the
|
|
1018
|
+
* / caller's transport key. Do not add an auth guard here (breaks client caching).
|
|
1019
|
+
* / ⟨L7⟩ UPDATE, NOT QUERY, and this is the system call that forces it: the body awaits
|
|
1020
|
+
* / `VetKeys.ManagementCanister.vetKdPublicKey`. A query cannot await, so the round trip is the
|
|
1021
|
+
* / cost of getting a key nobody has to trust us for — which is the point of publishing it.
|
|
1022
|
+
* /
|
|
1023
|
+
* / ⟨Marker added 2026-08-23; the census row already said "L7 (vetKD pubkey call)" and the site did
|
|
1024
|
+
* / not carry it. Declared `public func` rather than `public shared`, which is why the naming rule
|
|
1025
|
+
* / in check-update-for-read.mjs did not see it — the census population did.⟩
|
|
1026
|
+
*/
|
|
1027
|
+
getMemoryKeyVerificationKey: ActorMethod<[], Uint8Array | number[]>;
|
|
1028
|
+
/**
|
|
1029
|
+
* / Memory maintenance liveness. PUBLIC: ungated on purpose, like the anchor-push status — a stalled
|
|
1030
|
+
* / sweep or a failed storage check is exactly what a third party must be able to observe, and
|
|
1031
|
+
* / a gated read that failed to empty would report a healthy zero to anyone without a role.
|
|
1032
|
+
* / Counts and flags only — the paths involved are in the chained audit entries, where the
|
|
1033
|
+
* / access rules that govern them already apply.
|
|
1034
|
+
*/
|
|
1035
|
+
getMemoryMaintainStatus: ActorMethod<[], MemoryMaintainStatus>;
|
|
1036
|
+
/**
|
|
1037
|
+
* / The DECLARED policy. Read it together with getMemoryRetentionGuards — on its own it is not
|
|
1038
|
+
* / what governs eviction.
|
|
1039
|
+
* / ⟨0.16.0⟩ ONE PROJECTION, absorbing what were two methods — and the fold is a correctness fix,
|
|
1040
|
+
* / not tidying.
|
|
1041
|
+
* /
|
|
1042
|
+
* / Declared policy and the guards holding it back were separate reads, and a console rendering
|
|
1043
|
+
* / only the first told an owner their policy was in force while a guard still held it. The old
|
|
1044
|
+
* / `.did` warned in prose that the two had to be read TOGETHER; a comment is not a mechanism, and
|
|
1045
|
+
* / the guard arms on the FIRST policy an owner ever sets — so the surface misled every owner who
|
|
1046
|
+
* / ever touched retention, from first use. Making it one record makes reading half of it
|
|
1047
|
+
* / impossible: the trap becomes structure.
|
|
1048
|
+
* /
|
|
1049
|
+
* / Refusal reasons of both merge: an empty policy reads as "nothing is capped, every version kept
|
|
1050
|
+
* / forever" — a claim about what this engram will DESTROY — and an empty guard list reads as
|
|
1051
|
+
* / "nothing is held back".
|
|
1052
|
+
*/
|
|
1053
|
+
getMemoryRetentionPolicy: ActorMethod<[], Result_55>;
|
|
1054
|
+
/**
|
|
1055
|
+
* / The metrics reader this engram answers — `null` until the spawning registry names one.
|
|
1056
|
+
* /
|
|
1057
|
+
* / PUBLIC: an owner deciding whether to switch the read off needs to know who it is, and anyone
|
|
1058
|
+
* / comparing this engram's copy with the reader the registry publishes (`getMetricsReader` there)
|
|
1059
|
+
* / needs the same value. A canister id is not a secret.
|
|
1060
|
+
*/
|
|
1061
|
+
getMetricsReaderId: ActorMethod<[], [] | [Principal]>;
|
|
1062
|
+
/**
|
|
1063
|
+
* / A guardian asking about their OWN standing.
|
|
1064
|
+
* /
|
|
1065
|
+
* / #NotFound and not #Refused, deliberately, even though this reads a roster no stranger may
|
|
1066
|
+
* / see: the only row it can ever return is the caller's own, so "you are not a guardian here" is
|
|
1067
|
+
* / a fact about the caller, told to the caller. There is nothing to leak by omission — which is
|
|
1068
|
+
* / the test the #NotFound arm sets.
|
|
1069
|
+
*/
|
|
1070
|
+
getMyGuardianStatus: ActorMethod<[], Result_15>;
|
|
1071
|
+
/**
|
|
1072
|
+
* / ⟨0.16.0, NEW⟩ The gated half of the status() split.
|
|
1073
|
+
* /
|
|
1074
|
+
* / Every field is bare — no masking, no `authorized` discriminator — because reaching this record
|
|
1075
|
+
* / AT ALL is the authorization. An unauthorized caller gets `#Err(#Refused …)` and no record.
|
|
1076
|
+
* /
|
|
1077
|
+
* / `cyclesBalance` is a bare `Nat`, and that retires an argument this repo carried for weeks. It
|
|
1078
|
+
* / was `nat`, then widened to `opt nat` so a refusal could be `null`, which broke every published
|
|
1079
|
+
* / client (rule 4) and bought a masked answer nobody had asked for — the census could not even
|
|
1080
|
+
* / find a consumer that read the masked `0`. Behind a gate there is nobody to mask it from.
|
|
1081
|
+
*/
|
|
1082
|
+
getOwnerConsole: ActorMethod<[], Result_54>;
|
|
1083
|
+
/**
|
|
1084
|
+
* / Owner + agents only (agents need it to avoid writing protected paths).
|
|
1085
|
+
* /
|
|
1086
|
+
* / A NAMED RECORD, not a Page: the setter replaces this list wholesale, so there is no window to
|
|
1087
|
+
* / page over and no `total` that could differ from `items.size()`. Forcing the Page shape here
|
|
1088
|
+
* / would be uniformity for its own sake — the census ratified the whole-value-config carve-out
|
|
1089
|
+
* / precisely so L3 does not become a rule applied past its meaning.
|
|
1090
|
+
* /
|
|
1091
|
+
* / The trap's `whyNotEmpty` clause is preserved as the `#Refused` reason: `[]` would read as "no
|
|
1092
|
+
* / path on this engram is protected", and an agent consults this list precisely to avoid
|
|
1093
|
+
* / writing one — so a fabricated empty here does not merely misinform, it invites the write the
|
|
1094
|
+
* / list exists to prevent.
|
|
1095
|
+
*/
|
|
1096
|
+
getProtectedPaths: ActorMethod<[], Result_53>;
|
|
1097
|
+
/**
|
|
1098
|
+
* / Whether the metrics reader's read is answered — `true` from birth.
|
|
1099
|
+
* /
|
|
1100
|
+
* / PUBLIC: the promise that an owner can switch this read off can be checked only if the switch
|
|
1101
|
+
* / can be read — the reason the reader pointer is public too. It discloses one setting, never a row.
|
|
1102
|
+
*/
|
|
1103
|
+
getSeatWeeksReadEnabled: ActorMethod<[], boolean>;
|
|
1104
|
+
/**
|
|
1105
|
+
* / Owner-only, Billing-class: the signing floor, the balance, one signature's price, and how many
|
|
1106
|
+
* / payment signatures the balance carries above the floor before `signX402Payment` is refused by
|
|
1107
|
+
* / name. The same numbers the check uses, so Billing can say only what the engram enforces.
|
|
1108
|
+
*/
|
|
1109
|
+
getSigningFloor: ActorMethod<[], Result_52>;
|
|
1110
|
+
/**
|
|
1111
|
+
* / The registry that spawned this engram, if it recorded one.
|
|
1112
|
+
* /
|
|
1113
|
+
* / PUBLIC: it is the provenance claim. An engram asserting it is part of a fleet, under that
|
|
1114
|
+
* / fleet's attested template and rent rail, is asserting something a stranger must be able to
|
|
1115
|
+
* / check against the registry named here — and a provenance you need permission to read is not
|
|
1116
|
+
* / provenance. `null` says this engram makes no such claim, which is equally worth serving.
|
|
1117
|
+
*/
|
|
1118
|
+
getSpawnedBy: ActorMethod<[], [] | [Principal]>;
|
|
1119
|
+
/**
|
|
1120
|
+
* / Read the engram-wide daily ceiling and what has been spent against it today, across every
|
|
1121
|
+
* / caller. ⟨2026-09-28, the owner's decision to add the ceiling⟩
|
|
1122
|
+
* / ⟨CORRECTED 2026-09-29, review finding X-8: "spent" means signed in x402 payments; typed-data
|
|
1123
|
+
* / and the engram's registration signatures are not counted here — see `setSpendCeiling`.⟩
|
|
1124
|
+
* /
|
|
1125
|
+
* / OWNER-ONLY, for the reason `getSpendPolicy` is: the limits are the owner's custody
|
|
1126
|
+
* / configuration, and the engram-wide total would also tell one agent how much the others spent.
|
|
1127
|
+
* / A refusal names this method (`Gated.gatedResult`) rather than answering null/0 — a ceiling of
|
|
1128
|
+
* / "none" and a spend of 0 are both real answers, so a fabricated one would be read as fact.
|
|
1129
|
+
*/
|
|
1130
|
+
getSpendCeiling: ActorMethod<[], Result_51>;
|
|
1131
|
+
/**
|
|
1132
|
+
* / Read the caps in force for a caller.
|
|
1133
|
+
* /
|
|
1134
|
+
* / OWNER-ONLY, and this is where it diverges from the market's inbound twin, which is public.
|
|
1135
|
+
* / There the limits ride inside every 402 challenge, so withholding them would hide nothing.
|
|
1136
|
+
* / Here the engram serves no 402s at all: these caps are the owner's private custody
|
|
1137
|
+
* / configuration, and publishing them would tell any caller exactly how large a signing request
|
|
1138
|
+
* / can be before it needs an approval nobody is watching for.
|
|
1139
|
+
*/
|
|
1140
|
+
getSpendPolicy: ActorMethod<[[] | [Principal]], Result_50>;
|
|
1141
|
+
getStorageStats: ActorMethod<[], Result_49>;
|
|
1142
|
+
/**
|
|
1143
|
+
* / Timer arm-state. PUBLIC and deliberately so: these timers are self-arming to save cycles,
|
|
1144
|
+
* / and an optimisation nobody can verify is an optimisation nobody should trust. Cheap to read,
|
|
1145
|
+
* / leaks nothing (booleans about our own scheduling).
|
|
1146
|
+
* /
|
|
1147
|
+
* / IDLE STEADY STATE (no webhook, no x402 sessions, no service jobs):
|
|
1148
|
+
* / alertTimerArmed=false sessionExpiryArmed=false jobExpiryArmed=false jobExpiryFastMode=false
|
|
1149
|
+
* /
|
|
1150
|
+
* / ⚠ CORRECTED 2026-08-19. This said `jobExpiryArmed=TRUE` and that it "stays true by design —
|
|
1151
|
+
* / ic402 keeps an hourly idle POLL because createJobFromReceipt is synchronous and cannot disarm a
|
|
1152
|
+
* / timer itself". Both halves are stale, and an ops reader comparing a live engram against this
|
|
1153
|
+
* / paragraph would have seen `false` and gone looking for a fault that is not there.
|
|
1154
|
+
* /
|
|
1155
|
+
* / The engram sets `setExpiryIdlePollSeconds(0)` in its actor body, and ic402's ServiceRegistry
|
|
1156
|
+
* / CANCELS the timer outright at 0 rather than re-arming it — so the hourly tick this paragraph
|
|
1157
|
+
* / promised has not existed since that line landed. Independently, B1 moved job creation to the
|
|
1158
|
+
* / market: the engram now serves no job method at all, so nothing can arm the timer in the first
|
|
1159
|
+
* / place. `jobExpiryArmed` reads false on an idle engram, and false is CORRECT.
|
|
1160
|
+
* /
|
|
1161
|
+
* / EXPECTED FALSE POSITIVE: for up to one interval after any install or upgrade,
|
|
1162
|
+
* / sessionExpiryArmed reads true with zero sessions. ic402's startTimers arms unconditionally
|
|
1163
|
+
* / because a persistent actor re-runs its init body BEFORE postupgrade restores stable sessions,
|
|
1164
|
+
* / so a predicate-gated arm would skip exactly the canisters that have live ones. The first tick
|
|
1165
|
+
* / disarms it. Still true minutes after an upgrade is a real bug — report it upstream.
|
|
1166
|
+
* / NOT the whole timer story. The hourly CYCLE timer — which also carries audit anchoring — is
|
|
1167
|
+
* / deliberately absent: it is a `transient let` armed unconditionally at init, so an "armed"
|
|
1168
|
+
* / boolean for it would read true forever and tell you nothing, exactly the false-positive the
|
|
1169
|
+
* / paragraph above describes for sessionExpiryArmed. Use getAnchorPushStatus() instead: last-tick
|
|
1170
|
+
* / TIMESTAMPS are evidence where an arm flag is only an intention.
|
|
1171
|
+
* /
|
|
1172
|
+
* / PUBLIC: the same standing as the two liveness reads above. Booleans and timestamps about this
|
|
1173
|
+
* / canister's own timers — nothing about content, callers or money — and a liveness signal only
|
|
1174
|
+
* / its owner can read cannot tell a third party that the engram is still running.
|
|
1175
|
+
*/
|
|
1176
|
+
getTimerHealth: ActorMethod<[], TimerHealth>;
|
|
1177
|
+
/**
|
|
1178
|
+
* / PUBLIC: a cap identifies no user, and a caller deserves to know the rule before it stops them.
|
|
1179
|
+
* /
|
|
1180
|
+
* / ⟨0.16.0, L8⟩ Was owner-gated behind a trap. The disclosure law asks what the value reveals, and
|
|
1181
|
+
* / the answer here is nothing about anybody — it is a policy ceiling, not a balance or a history.
|
|
1182
|
+
* / Publishing it removes the trap AND the envelope: an ungated read has no refusal to carry, so
|
|
1183
|
+
* / wrapping it in `Result` would be ceremony that implies a gate exists.
|
|
1184
|
+
* /
|
|
1185
|
+
* / Predictability is itself the honesty posture: a limit that only reveals itself by refusing a
|
|
1186
|
+
* / top-up teaches the caller by failure. `/// PUBLIC:` is the marker the L8 gate greps for.
|
|
1187
|
+
*/
|
|
1188
|
+
getTopUpLimits: ActorMethod<[], { cooldownSeconds: bigint; maxCkusdcE6s: bigint }>;
|
|
1189
|
+
/**
|
|
1190
|
+
* / ⟨0.16.0⟩ `walletBalance()` DELETED — a ONE-LETTER trap beside `walletBalances()`, and a strict
|
|
1191
|
+
* / projection of it: it returned `ExperimentalCycles.balance()`, which is `WalletBalances.cycles`.
|
|
1192
|
+
* /
|
|
1193
|
+
* / Two methods whose names differ by a single character, with the same gate and one a subset of
|
|
1194
|
+
* / the other, is a call site waiting to be written wrong — and wrong in the direction that
|
|
1195
|
+
* / silently reads cycles when it meant to read money. Doc callers (CLI-REFERENCE, Docs.vue) sweep
|
|
1196
|
+
* / to the survivor.
|
|
1197
|
+
* / RENAMED from `walletBalances` (L2.1: `get*` for a single value).
|
|
1198
|
+
* /
|
|
1199
|
+
* / Stays an UPDATE, marked per L7: it awaits three ICRC-1 ledgers. The name cannot say that, so
|
|
1200
|
+
* / the declaration does — a caller budgeting round-trips needs to know this is not a query.
|
|
1201
|
+
* /
|
|
1202
|
+
* / The ledger failure is `#Unavailable`, not `#Invalid`: a dependency refused or timed out, the
|
|
1203
|
+
* / request was fine, and retry is the correct response. That is the one arm in the whole set that
|
|
1204
|
+
* / means "try again", and it is the reason `Error` is a closed variant rather than a sentence.
|
|
1205
|
+
* /
|
|
1206
|
+
* / ⟨L7⟩ MARKER ADDED 2026-08-23, reasoning above UNCHANGED — this block already said "Stays an
|
|
1207
|
+
* / UPDATE, marked per L7: it awaits three ICRC-1 ledgers". It was marked in prose and invisible
|
|
1208
|
+
* / to any gate; the glyph is what `scripts/check-update-for-read.mjs` matches.
|
|
1209
|
+
*/
|
|
1210
|
+
getWalletBalances: ActorMethod<[], Result_48>;
|
|
1211
|
+
/**
|
|
1212
|
+
* / Refusal reason preserved, and it is the clearest case of why a masked read is worse than no
|
|
1213
|
+
* / read: three empty strings with `configured = false` is a VALID-LOOKING answer meaning "this
|
|
1214
|
+
* / engram has no World ID configuration" — handed to a caller who merely lacks a grant. The
|
|
1215
|
+
* / fabrication is indistinguishable from the truth by construction.
|
|
1216
|
+
*/
|
|
1217
|
+
getWorldIdConfig: ActorMethod<[], Result_47>;
|
|
1218
|
+
/**
|
|
1219
|
+
* / ⟨L7⟩ UPDATE, NOT QUERY: this awaits THREE system calls — `raw_rand()` for the nonce,
|
|
1220
|
+
* / `Call.signWithEcdsa` for the signature, and `worldIdRpPublicKey()` for the derived key. A
|
|
1221
|
+
* / query can do none of them.
|
|
1222
|
+
* /
|
|
1223
|
+
* / Owner-only: produce a World ID 4.0 relying-party context for the frontend's IDKit request.
|
|
1224
|
+
* / Valid iff the derived signer address (getWorldIdRpSignerAddress) is registered for this rp_id in
|
|
1225
|
+
* / the World Developer Portal. Short-lived (300s TTL, idkit-server's default) and single-purpose —
|
|
1226
|
+
* / it authorizes opening one verification request, nothing else.
|
|
1227
|
+
*/
|
|
1228
|
+
getWorldIdRpContext: ActorMethod<[], Result_46>;
|
|
1229
|
+
/**
|
|
1230
|
+
* / Owner-only: the EVM address derived from the engram's dedicated World ID RP signing key (the
|
|
1231
|
+
* / "worldid-rp" tECDSA path). Register THIS address as the rp_id's signer in the World Developer
|
|
1232
|
+
* / Portal — the engram never holds or exports a private key (only threshold shares exist, on the
|
|
1233
|
+
* / subnet). Distinct from the payment/EVM address by construction.
|
|
1234
|
+
* /
|
|
1235
|
+
* / ⟨L7⟩ UPDATE, NOT QUERY, for TWO reasons and the second is the one a reader would miss. It
|
|
1236
|
+
* / awaits `worldIdRpPublicKey()` (management `ecdsa_public_key`), and it calls `denied()` on
|
|
1237
|
+
* / refusal — a state write, which a query cannot perform. So even if the key were cached this
|
|
1238
|
+
* / could not become a query without silently retiring its denial record (ADR-0002's class).
|
|
1239
|
+
*/
|
|
1240
|
+
getWorldIdRpSignerAddress: ActorMethod<[], Result_43>;
|
|
1241
|
+
/**
|
|
1242
|
+
* / The verified IDKitResult, verbatim, as World's /api/v4/verify accepted it — the re-checkable
|
|
1243
|
+
* / artifact behind verifiedHuman. Role-gated because it carries the NULLIFIER.
|
|
1244
|
+
* / `Result<opt Text>` — and the double wrapper is the entire point, not redundancy.
|
|
1245
|
+
* /
|
|
1246
|
+
* / `#Ok(null)` means HONEST ABSENCE: no verification is on record, and you were entitled to ask.
|
|
1247
|
+
* / `#Err(#Refused …)` means you may not ask. Under the old bare `?Text` those two collapsed into
|
|
1248
|
+
* / one `null`, so a caller lacking a grant was told an unverified human stands behind this engram
|
|
1249
|
+
* / — a false claim about a person, produced by an authorization failure.
|
|
1250
|
+
* /
|
|
1251
|
+
* / The artifact stays role-gated because it carries the NULLIFIER. The public, anonymous answer to
|
|
1252
|
+
* / "is a human behind this engram" is `about().verifiedHuman`, which is a boolean and leaks
|
|
1253
|
+
* / nothing.
|
|
1254
|
+
* /
|
|
1255
|
+
* / ⟨CORRECTED 2026-08-21 — this said `metrics().verifiedHuman`, and `metrics()` no longer exists:
|
|
1256
|
+
* / L2.2 folded it and `status()` into `about()`, which carries the field. The sentence is a
|
|
1257
|
+
* / `///`, so the dead name was PUBLISHED in engram.did and pointed every client at a method the
|
|
1258
|
+
* / canister does not serve. The tombstones below and at `about()` are historical and correct as
|
|
1259
|
+
* / written; this one was present tense, which is the difference that matters.⟩
|
|
1260
|
+
*/
|
|
1261
|
+
getWorldIdVerification: ActorMethod<[], Result_45>;
|
|
1262
|
+
/**
|
|
1263
|
+
* / ⟨0.16.0, L1⟩ THE EMERGENCY FAMILY. Every refusal below is `#Refused` or `#NotFound`, and the
|
|
1264
|
+
* / absence of a `#Conflict` here is the point: these are the calls someone makes while something
|
|
1265
|
+
* / is going wrong, and the only two answers that help are "you may not do this" and "there is
|
|
1266
|
+
* / nothing by that name". A missing PERMISSION is `#Refused` rather than `#Conflict` — the
|
|
1267
|
+
* / guardian's standing is what fell short, and no change to engram state would let them through.
|
|
1268
|
+
*/
|
|
1269
|
+
guardianRevokeAgent: ActorMethod<[Principal], Result_1>;
|
|
1270
|
+
/**
|
|
1271
|
+
* / The HTTP surface: canister-info JSON, OAuth discovery documents, and the MCP route's query
|
|
1272
|
+
* / half. See the `http_request_update` twin below for what upgrades and why.
|
|
1273
|
+
* /
|
|
1274
|
+
* / PUBLIC: not a choice. The boundary node invokes this for every inbound HTTP request with no
|
|
1275
|
+
* / caller identity to gate on, so a gate here would refuse the only caller there is. Authorization
|
|
1276
|
+
* / lives INSIDE, per route — `/mcp` demands a bearer token, the discovery documents are meant to
|
|
1277
|
+
* / be world-readable by their own specs, and the canister-info JSON serves only facts already
|
|
1278
|
+
* / published by the queries above it.
|
|
1279
|
+
*/
|
|
1280
|
+
http_request: ActorMethod<[HttpRequest], HttpResponse>;
|
|
1281
|
+
/**
|
|
1282
|
+
* / The update twin of the router above — the routes the query half UPGRADES so their responses
|
|
1283
|
+
* / are consensus-certified and served on the certified hostname.
|
|
1284
|
+
* /
|
|
1285
|
+
* / PUBLIC: for the same reason as its twin, and it must match. A route the query half upgrades
|
|
1286
|
+
* / but this half does not handle falls through to the 404 at the end, turning a serving fault
|
|
1287
|
+
* / into what reads as a wrong URL — half a fix being worse than none, as the /oauth/authorize
|
|
1288
|
+
* / arm inside records.
|
|
1289
|
+
*/
|
|
1290
|
+
http_request_update: ActorMethod<[HttpRequest], HttpResponse>;
|
|
1291
|
+
/**
|
|
1292
|
+
* / ⟨0.16.0⟩ `isPaidMemoryReadEnabled()` DELETED — folded to `about().paidMemoryReadEnabled`
|
|
1293
|
+
* / (L2.6: one idiom for a boolean feature — a setter plus the flag on its family's projection).
|
|
1294
|
+
* / Its callers are a buyer's pre-check and the market canister, both ANONYMOUS, so the public
|
|
1295
|
+
* / projection is exactly where it belongs.
|
|
1296
|
+
* / PUBLIC: a wallet calls this BEFORE its user has any standing on this engram — that is what the
|
|
1297
|
+
* / call is for — so gating it would make the message unreadable at exactly the moment it is
|
|
1298
|
+
* / needed, and a signature given without it is a signature given blind.
|
|
1299
|
+
*/
|
|
1300
|
+
icrc21_canister_call_consent_message: ActorMethod<
|
|
1301
|
+
[
|
|
1302
|
+
{
|
|
1303
|
+
arg: Uint8Array | number[];
|
|
1304
|
+
method: string;
|
|
1305
|
+
user_preferences: {};
|
|
1306
|
+
},
|
|
1307
|
+
],
|
|
1308
|
+
| {
|
|
1309
|
+
Ok: {
|
|
1310
|
+
metadata: {
|
|
1311
|
+
utc_offset_minutes: [] | [number];
|
|
1312
|
+
language: string;
|
|
1313
|
+
};
|
|
1314
|
+
consent_message: { GenericDisplayMessage: string };
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
| { Err: { description: string; error_code: bigint } }
|
|
1318
|
+
>;
|
|
1319
|
+
/**
|
|
1320
|
+
* / Owner-only: is the derived EVM address CACHED right now, without deriving it to find out.
|
|
1321
|
+
* /
|
|
1322
|
+
* / WHY A SEPARATE METHOD AND NOT A FIELD ON `getEvmAddress`. That method cannot answer this
|
|
1323
|
+
* / question by construction: when the cache is null it DERIVES, caches the result and returns it,
|
|
1324
|
+
* / so by the time a caller sees the reply the cache is populated either way. Asking it whether the
|
|
1325
|
+
* / cache had been populated changes the answer.
|
|
1326
|
+
* /
|
|
1327
|
+
* / WHY IT EXISTS AT ALL, since a public surface is never free on a canister meant to go public.
|
|
1328
|
+
* / `evmAddressCache` is money-classed and its annotation says why: derivation is deterministic, so
|
|
1329
|
+
* / a lost cache LOOKS harmless, but until something re-derives, the EVM payment quote advertises
|
|
1330
|
+
* / the fallback — an address that cannot receive. A window in which a live money surface publishes
|
|
1331
|
+
* / an unreceivable address is a money defect, not a cache miss. Nothing else in this canister
|
|
1332
|
+
* / reads that var — one reader and two writers, all in this file — so before this method there was
|
|
1333
|
+
* / no observation anywhere that could tell a survived cache from a rebuilt one, and the upgrade
|
|
1334
|
+
* / coverage gate carried a money-classed var nothing could prove.
|
|
1335
|
+
* /
|
|
1336
|
+
* / ⚠ IT MUST NEVER DERIVE. A version that fell back to deriving would answer `true` always and
|
|
1337
|
+
* / prove nothing — the same trap `getEvmAddress` sets for anyone trying to use it as a witness.
|
|
1338
|
+
* / It reads the var and nothing else, and it is a `query` precisely so that it CANNOT make the
|
|
1339
|
+
* / inter-canister call a derivation requires: the restriction is enforced by the system, not by
|
|
1340
|
+
* / this comment.
|
|
1341
|
+
* /
|
|
1342
|
+
* / Owner-gated because it reports on custody posture, and answered as a Result so that a
|
|
1343
|
+
* / wrong-identity caller gets a refusal rather than a bare `false` that reads as "no address yet".
|
|
1344
|
+
*/
|
|
1345
|
+
isEvmAddressCached: ActorMethod<[], Result_44>;
|
|
1346
|
+
/**
|
|
1347
|
+
* / Issue an OAuth authorization code. Called by an OAuth client's sign-in bridge
|
|
1348
|
+
* / (an `/auth/connector`-style route) after II authentication. The client then
|
|
1349
|
+
* / redirects the user's browser to `redirectUri` with `?code=<this>` so the
|
|
1350
|
+
* / MCP client (e.g. claude.ai) can exchange it for a bearer token at /oauth/token.
|
|
1351
|
+
* /
|
|
1352
|
+
* / Owner-only: only the engram owner can authorize a Connector install.
|
|
1353
|
+
*/
|
|
1354
|
+
issueAuthCode: ActorMethod<[string, string, string, [] | [string]], Result_43>;
|
|
1355
|
+
/**
|
|
1356
|
+
* / ⟨0.16.0⟩ `getCycleSnapshotSource` DELETED — folded into `CycleSnapshot.source`, one label per
|
|
1357
|
+
* / ROW. A single label for a whole ring misattributes every row recorded under the other source,
|
|
1358
|
+
* / and the source flips by design (self-call first, balance on fallback). Its documentation of
|
|
1359
|
+
* / what the two values mean lives on the type.
|
|
1360
|
+
* / Hourly (timestamp, totalMemoryReads, totalMemoryWrites) snapshots, ~30 days.
|
|
1361
|
+
* / Same guard + fail-to-empty shape as getCycleHistory. Diff consecutive rows for a
|
|
1362
|
+
* / per-engram activity time-series (retention instrumentation).
|
|
1363
|
+
* / RENAMED from `getActivityHistory` (L2.1); named fields replace a bare 3-tuple whose two Nats
|
|
1364
|
+
* / were positionally indistinguishable.
|
|
1365
|
+
* /
|
|
1366
|
+
* / Refusal reason preserved, and it is the sharpest of this family: a masked `[]` reads as a
|
|
1367
|
+
* / DORMANT engram and corrupts retention math — a fabricated empty here does not just misinform a
|
|
1368
|
+
* / reader, it feeds a wrong number into a decision about destroying data.
|
|
1369
|
+
*/
|
|
1370
|
+
listActivitySnapshots: ActorMethod<[bigint, bigint], Result_42>;
|
|
1371
|
+
/**
|
|
1372
|
+
* / ⟨0.16.0⟩ THE PAGE EXEMPLAR. Trap → `#Refused`, bare array → `Result<Page<T>>` (L1 + L3).
|
|
1373
|
+
* /
|
|
1374
|
+
* / The refusal prose that used to be `gatedTrap`'s `whyNotEmpty` argument is not lost — it is why
|
|
1375
|
+
* / this method could never fail soft, and it now travels ON THE WIRE inside `#Refused` where a
|
|
1376
|
+
* / caller can actually read it, instead of inside a trap message only a log sees.
|
|
1377
|
+
* /
|
|
1378
|
+
* / `total` is the ROSTER SIZE, not `items.size()`. That distinction is the whole reason this
|
|
1379
|
+
* / shape exists here: `MAX_AGENTS` clamps the returned rows, and the old code returned the
|
|
1380
|
+
* / clamped array with nothing saying it had clamped — a caller reading 100 agents could not
|
|
1381
|
+
* / tell whether that was all of them. Now a clamped answer is self-describing, and the previous
|
|
1382
|
+
* / behaviour (silently truncate, look complete) is unrepresentable.
|
|
1383
|
+
* /
|
|
1384
|
+
* / `withheld` is 0: this roster is owner-only in whole, so there is no partial-visibility case.
|
|
1385
|
+
* / A method that filters rows by caller sets it — see L1's row-level honesty rule.
|
|
1386
|
+
*/
|
|
1387
|
+
listAgents: ActorMethod<[bigint, bigint], Result_41>;
|
|
1388
|
+
/**
|
|
1389
|
+
* / The GUARDIAN-audience projection of the agent roster — three fields, not the full record.
|
|
1390
|
+
* /
|
|
1391
|
+
* / Two audiences, two methods (L1/L8), rather than one method masking fields by caller: a
|
|
1392
|
+
* / guardian needs enough to revoke (who, what they are called, whether they are active) and no
|
|
1393
|
+
* / more. Field-masking would make the same call return different shapes to different callers,
|
|
1394
|
+
* / which is the design L1 abolished — and it would put the decision about what a guardian may see
|
|
1395
|
+
* / inside a build closure where no gate can read it.
|
|
1396
|
+
* /
|
|
1397
|
+
* / Refusal reason preserved: `[]` reads as "this engram has no agents", and this is the list a
|
|
1398
|
+
* / guardian consults BEFORE REVOKING ONE. A fabricated empty here does not merely misinform —
|
|
1399
|
+
* / it tells someone acting under emergency powers that there is nothing to act on.
|
|
1400
|
+
*/
|
|
1401
|
+
listAgentsForGuardian: ActorMethod<[bigint, bigint], Result_40>;
|
|
1402
|
+
/**
|
|
1403
|
+
* / Owner-only: rows carry caller, amount, operation and free-text rationale. The SDK omits it.
|
|
1404
|
+
* /
|
|
1405
|
+
* / The optional leading filter SURVIVES the L3 reshape — ratified (census tier-2 #8) rather than
|
|
1406
|
+
* / assumed, because Billing.vue calls the filtered form live and pushing the filter client-side
|
|
1407
|
+
* / would make the console fetch a queue to discard most of it.
|
|
1408
|
+
* /
|
|
1409
|
+
* / `total` counts the FILTERED set, not the whole queue: with a filter applied, "how many match"
|
|
1410
|
+
* / is the number a pager needs, and reporting the unfiltered count would make every filtered view
|
|
1411
|
+
* / claim more pages than it has.
|
|
1412
|
+
* /
|
|
1413
|
+
* / Refusal reason preserved: `[]` reads as "nothing is awaiting the owner's decision".
|
|
1414
|
+
*/
|
|
1415
|
+
listApprovalRequests: ActorMethod<[[] | [ApprovalStatus], bigint, bigint], Result_28>;
|
|
1416
|
+
/**
|
|
1417
|
+
* / ⟨0.16.0⟩ `total` IS THE HEAD COUNTER, and on this method that is the entire point.
|
|
1418
|
+
* /
|
|
1419
|
+
* / The audit log is a bounded RING: it trims its tail, so "rows you can read" and "entries that
|
|
1420
|
+
* / have ever existed" are different numbers. The old bare array published only the first, which
|
|
1421
|
+
* / made a trimmed log indistinguishable from a complete one — and this is the evidence surface,
|
|
1422
|
+
* / where that difference IS the product. `totalAppended()` is monotonic across trims and is the
|
|
1423
|
+
* / same number `getCertifiedAuditHead` publishes, so a caller comparing page against head gets
|
|
1424
|
+
* / agreement by construction rather than by luck.
|
|
1425
|
+
* /
|
|
1426
|
+
* / Refusal reason preserved: for an unauthenticated integrity check the caller wants
|
|
1427
|
+
* / `getCertifiedAuditHead()`, which is public and subnet-certified. The BODIES are role-gated.
|
|
1428
|
+
* /
|
|
1429
|
+
* / ⟨2026-09-29, owner ruling follow-up 16 (B)⟩ AN AGENT READS ONLY THE ENTRIES IT CAUSED; the
|
|
1430
|
+
* / owner and guardians read everything (`RecordView`). So `limit` is a SPAN — how many record ids
|
|
1431
|
+
* / to examine from `start` — and an agent's page holds the entries in that span whose caller is
|
|
1432
|
+
* / its own key, with `withheld` counting the rest: `items.size() + withheld` is the span examined.
|
|
1433
|
+
* / For the owner and a guardian `withheld` is 0 and the page is the span. WHAT WOULD MAKE THIS
|
|
1434
|
+
* / WRONG: a reader who must see the whole record without being the owner or a guardian — the
|
|
1435
|
+
* / public certified head is the answer for integrity, and nothing else is.
|
|
1436
|
+
*/
|
|
1437
|
+
listAuditEntries: ActorMethod<[bigint, bigint], Result_23>;
|
|
1438
|
+
/**
|
|
1439
|
+
* / ⟨0.16.0, L1 + L3 — census-ruled⟩ THE TWO-MECHANISM EXCEPTION DISSOLVES.
|
|
1440
|
+
* /
|
|
1441
|
+
* / This method used to answer THREE ways to one question: a list, an `#Err` text, and a trap,
|
|
1442
|
+
* / picked by which kind of caller asked. That split existed only because the return type could
|
|
1443
|
+
* / not carry a refusal — with `Result<Page<T>>` it can, so every caller gets one shape and the
|
|
1444
|
+
* / arm says which no it is. A paired agent lacking `canReadBackup` is `#Refused`; so is
|
|
1445
|
+
* / everyone else who may not ask. The trap is gone: `Debug.trap` is for invariant violations,
|
|
1446
|
+
* / never authorization (L1), and a refusal a caller cannot catch is not a better refusal.
|
|
1447
|
+
* /
|
|
1448
|
+
* / ⚠ THE RATIFIED LOCKSTEP EXCEPTION THIS CARRIED IS SUPERSEDED, not quietly dropped.
|
|
1449
|
+
* / `ADR-0002-listBackups-refusal-lockstep/listBackups` existed because published
|
|
1450
|
+
* / @engramx/client 0.15.0 declares `IDL.Vec(BackupMetadata)` here and cannot decode a variant at
|
|
1451
|
+
* / all — it throws — and @engramx/openclaw's dedup probe catches that throw and degrades to
|
|
1452
|
+
* / "skipped", so every database silently stops being backed up while the CLI reports success.
|
|
1453
|
+
* / That analysis was correct and is still correct. What changed is its PREMISE: plan v2 measured
|
|
1454
|
+
* / the installed base at zero external users (prod = two engrams, both ours; npm published
|
|
1455
|
+
* / 2026-08-14), so the population the ceremony protected does not exist. The SDK is republished
|
|
1456
|
+
* / at 0.16.0 in this same campaign. If an outside caller ever appears before that ships,
|
|
1457
|
+
* / this reasoning is void and the lockstep is owed again.
|
|
1458
|
+
* /
|
|
1459
|
+
* / `dbTypeFilter` DIES on the wire (census). The capability does not: `EngramClient.listBackups`
|
|
1460
|
+
* / keeps its optional filter and applies it to the page, so no caller loses the ability to ask
|
|
1461
|
+
* / "backups of this database" — it stops being a thing the canister has to page around.
|
|
1462
|
+
*/
|
|
1463
|
+
listBackups: ActorMethod<[bigint, bigint], Result_39>;
|
|
1464
|
+
/**
|
|
1465
|
+
* / List all bearer tokens — Active, Revoked, and Expired. Owner uses this in
|
|
1466
|
+
* / the dashboard to show installed Connectors (claude.ai, Claude Desktop, etc.).
|
|
1467
|
+
* / Refusal reason preserved from the trap: `[]` reads as "no connector is installed on this
|
|
1468
|
+
* / engram" — a claim about what can REACH it. An owner auditing access cannot tell that from
|
|
1469
|
+
* / "you may not see the list", and the two are opposite facts.
|
|
1470
|
+
* /
|
|
1471
|
+
* / `bearerTokenStore.list()` already resolves each token's status at read time (a token that
|
|
1472
|
+
* / merely stopped being used is reported `#Expired`, not a stale `#Active`), so the page carries
|
|
1473
|
+
* / the same honesty the store gained on 2026-08-17.
|
|
1474
|
+
*/
|
|
1475
|
+
listBearerTokens: ActorMethod<[bigint, bigint], Result_38>;
|
|
1476
|
+
/**
|
|
1477
|
+
* / The condense checkpoints in the retained log at or above `startSeq`, oldest first.
|
|
1478
|
+
* /
|
|
1479
|
+
* / ⟨0.16.0, NEW⟩ The other half of the split above. A checkpoint is the only surviving record of a
|
|
1480
|
+
* / stretch of chain that no longer exists, so this is the list that accounts for the distance
|
|
1481
|
+
* / between `firstAvailableSeq` and the entries an owner remembers writing — without it, a
|
|
1482
|
+
* / condensed prefix is a gap the owner has to take on trust.
|
|
1483
|
+
* /
|
|
1484
|
+
* / Owner-only like every other archive surface, and for the same structural reason: these rows
|
|
1485
|
+
* / carry the chain positions and roots of entries whose paths were inside the hash preimage.
|
|
1486
|
+
*/
|
|
1487
|
+
listCondenseCheckpoints: ActorMethod<[bigint, bigint], Result_37>;
|
|
1488
|
+
/**
|
|
1489
|
+
* / ⟨0.16.0⟩ `metrics()` DELETED — absorbed by `about()`.
|
|
1490
|
+
* /
|
|
1491
|
+
* / Two public projections of one canister (L2.2): `metrics()` and `status()` both answered "what
|
|
1492
|
+
* / is this engram like" and disagreed on which counters they carried, so a consumer had to fetch
|
|
1493
|
+
* / both and know which one owned each field. Every field here survives on `about()`, day-flooring
|
|
1494
|
+
* / included.
|
|
1495
|
+
*/
|
|
1496
|
+
listCycleSnapshots: ActorMethod<[bigint, bigint], Result_36>;
|
|
1497
|
+
/**
|
|
1498
|
+
* / Same `withheld` treatment as listMemoryFiles — the tombstone listing filtered reserved paths
|
|
1499
|
+
* / for non-owners just as silently, and a caller could not tell a filtered tombstone list from a
|
|
1500
|
+
* / complete one. Counted before slicing, so policy-hidden rows never blur into paging.
|
|
1501
|
+
*/
|
|
1502
|
+
listDeletedMemoryFiles: ActorMethod<[bigint, bigint], Result_35>;
|
|
1503
|
+
/**
|
|
1504
|
+
* / The registered shapes — E3: encodeTypeString is the display artifact, verbatim.
|
|
1505
|
+
* / Stays on the engram under B1 (hybrid): EIP-712 signing is custody, and custody does not leave.
|
|
1506
|
+
* /
|
|
1507
|
+
* / Refusal reason preserved: `[]` reads as "this engram can sign nothing" — a claim about SIGNING
|
|
1508
|
+
* / AUTHORITY, which is not a thing to hand an unauthorized reader. The public trail of every
|
|
1509
|
+
* / registration remains the audit chain under getCertifiedAuditHead.
|
|
1510
|
+
*/
|
|
1511
|
+
listEip712Types: ActorMethod<[bigint, bigint], Result_34>;
|
|
1512
|
+
/**
|
|
1513
|
+
* / Stays on the engram under B1 (hybrid): withdrawal custody does not leave.
|
|
1514
|
+
* /
|
|
1515
|
+
* / NAMED item, not a `(Text, Int)` tuple. The Int is an activation time, and a bare Int beside a
|
|
1516
|
+
* / bare Text told a reader nothing about which was which — the same defect fixed on the purge log.
|
|
1517
|
+
* /
|
|
1518
|
+
* / Refusal reason preserved, and it has two halves that matter separately: `[]` reads as "this
|
|
1519
|
+
* / engram may withdraw nowhere", OR — worse — as "no allowlist is in force", which is the
|
|
1520
|
+
* / opposite security posture. It also erases any pending 24h activation from view.
|
|
1521
|
+
*/
|
|
1522
|
+
listEvmWithdrawDestinations: ActorMethod<[bigint, bigint], Result_33>;
|
|
1523
|
+
/**
|
|
1524
|
+
* / Accessible by owner and guardians.
|
|
1525
|
+
* /
|
|
1526
|
+
* / Refusal reason carried over from the trap, because it is the sharpest example of why this
|
|
1527
|
+
* / surface may not fail soft: `[]` reads as "this engram has nobody who can freeze payments or
|
|
1528
|
+
* / pause writes" — a claim about who can STOP it. A caller who cannot tell that from "you may not
|
|
1529
|
+
* / see the roster" has been told the engram is unguarded when it may be fully guarded.
|
|
1530
|
+
*/
|
|
1531
|
+
listGuardians: ActorMethod<[bigint, bigint], Result_32>;
|
|
1532
|
+
/**
|
|
1533
|
+
* / The export receipts in the retained log at or above `startSeq`, oldest first.
|
|
1534
|
+
* /
|
|
1535
|
+
* / ⟨0.16.0, L3⟩ ONE LIST, ONE QUESTION. This method used to return receipts AND checkpoints
|
|
1536
|
+
* / together behind a backward `before`/`max` cursor. They answer different questions — what may be
|
|
1537
|
+
* / condensed, and what already was — so a caller wanting one paid to decode the other, and the
|
|
1538
|
+
* / merged shape had to carry two arrays, a truncation flag and an opaque cursor to stay honest
|
|
1539
|
+
* / about a walk that served both. `listCondenseCheckpoints` is the other half.
|
|
1540
|
+
* /
|
|
1541
|
+
* / The cursor dies with it (census R6): paging is by ABSOLUTE SEQ now, forward, so a caller resumes
|
|
1542
|
+
* / at `scannedThroughSeq + 1` and is finished when that passes `page.total`. `scanTruncated` is
|
|
1543
|
+
* / gone because it has nothing left to say — "I stopped at entry N" is the same claim it made, and
|
|
1544
|
+
* / says it as a position rather than a flag a reader has to pair with a second field.
|
|
1545
|
+
* /
|
|
1546
|
+
* / Read `MemoryRouter.ReceiptPage` before reading `page.total` as a receipt count. It is not one;
|
|
1547
|
+
* / it is the chain's length, and the declaration says why.
|
|
1548
|
+
*/
|
|
1549
|
+
listMemoryExportReceipts: ActorMethod<[bigint, bigint], Result_31>;
|
|
1550
|
+
/**
|
|
1551
|
+
* / ⟨0.16.0⟩ THE `withheld` EXEMPLAR — L1 names this exact method as the defect it fixes.
|
|
1552
|
+
* /
|
|
1553
|
+
* / A non-owner's answer silently dropped every `config/` and `secrets/` row. Not "refused the
|
|
1554
|
+
* / call" and not "returned a marker" — the rows simply were not there, with nothing in band
|
|
1555
|
+
* / saying so, and the filtering happened INSIDE a combinator closure where neither honesty gate
|
|
1556
|
+
* / could see it. Meanwhile `readMemory` returned an explicit refusal for the very same paths.
|
|
1557
|
+
* / Same policy, same caller, two answers, and the quiet one was the lie.
|
|
1558
|
+
* /
|
|
1559
|
+
* / `withheld` is now the count of rows policy removed. It leaks no names — which is the point:
|
|
1560
|
+
* / the caller learns THAT something is hidden without learning WHAT, so an agent can tell a
|
|
1561
|
+
* / short listing from a complete one and stop inferring the engram is emptier than it is.
|
|
1562
|
+
* /
|
|
1563
|
+
* / Note the count is computed from the unfiltered list before slicing, so it reports rows hidden
|
|
1564
|
+
* / by POLICY, never rows merely off the end of this page — those are `total`'s job. Conflating
|
|
1565
|
+
* / the two would rebuild the ambiguity in a new place.
|
|
1566
|
+
*/
|
|
1567
|
+
listMemoryFiles: ActorMethod<[bigint, bigint], Result_30>;
|
|
1568
|
+
/**
|
|
1569
|
+
* / One page of the memory log, seq-ordered, optionally narrowed to one author.
|
|
1570
|
+
* /
|
|
1571
|
+
* / THE WINDOW IS THE CURSOR, and the page now states it. The window is
|
|
1572
|
+
* / `items.size() + withheld` entries starting at `max(startSeq, firstAvailableSeq)`; advance by
|
|
1573
|
+
* / that, never by "last entry returned + 1", which stalls forever on the first empty page. Stop
|
|
1574
|
+
* / when the window passes `total`.
|
|
1575
|
+
* /
|
|
1576
|
+
* / ⟨0.16.0, L3 — CENSUS CONFLICT, RECORDED⟩ The census row says `→R<P<MemoryLogEvent>>` and
|
|
1577
|
+
* / "authorFilter dropped (kills the filtered-window cursor stall)". The stall is real and the
|
|
1578
|
+
* / diagnosis is right; amputating the filter is not the only cure, and it is the expensive one —
|
|
1579
|
+
* / `Archive.vue` ships a working author-filter UI, and "what did this agent write" is a
|
|
1580
|
+
* / question an owner asks of an evidence log. The filter STAYS. What kills the stall instead is
|
|
1581
|
+
* / `withheld`: it carries the count this filter removed from the window, so a short or empty
|
|
1582
|
+
* / filtered page is no longer ambiguous between "nobody wrote here" and "the window was small",
|
|
1583
|
+
* / and the correct cursor advance is computable from the page itself. `pageCap` therefore dies
|
|
1584
|
+
* / with nothing lost — it existed only to disclose a window that `items.size() + withheld` now
|
|
1585
|
+
* / states directly.
|
|
1586
|
+
* /
|
|
1587
|
+
* / `firstAvailableSeq` and `head` sit BESIDE the page rather than in it. They are facts about the
|
|
1588
|
+
* / chain, not this slice: the condense floor tells a caller reading an archived range where the
|
|
1589
|
+
* / log now begins instead of letting them read it as empty, and the head is what a third party
|
|
1590
|
+
* / checks the page against. Flattening to a bare `Page` to satisfy the shape would buy uniformity
|
|
1591
|
+
* / with the disclosures that make the page verifiable — the hidden-bound defect the census itself
|
|
1592
|
+
* / names on previewCondense's row.
|
|
1593
|
+
*/
|
|
1594
|
+
listMemoryLog: ActorMethod<[bigint, bigint, [] | [Principal]], Result_29>;
|
|
1595
|
+
/**
|
|
1596
|
+
* / The caller's OWN spend-approval requests. ⟨0.16.0, L1 + L3 — fixed 2026-08-18⟩
|
|
1597
|
+
* /
|
|
1598
|
+
* / Two defects in seven lines, and the first is the one this release exists to remove:
|
|
1599
|
+
* /
|
|
1600
|
+
* / · `if (Principal.isAnonymous(msg.caller)) return []` is a FABRICATED EMPTY. An anonymous
|
|
1601
|
+
* / caller was told "you have no approval requests", which is a claim about their queue rather
|
|
1602
|
+
* / than about their identity, and is indistinguishable from the honest answer. It refuses now.
|
|
1603
|
+
* / · The reply was uncapped over `pendingApprovals`, which NEVER SHRINKS — the hourly expiry
|
|
1604
|
+
* / timer flips a row's status to `#Expired` and deletes nothing. So the array grew for the
|
|
1605
|
+
* / life of the engram, and a caller with enough history would eventually get a reply too
|
|
1606
|
+
* / large to decode: not a truncated list, no list at all.
|
|
1607
|
+
* /
|
|
1608
|
+
* / The caller-scoping is not `withheld`: rows belonging to someone else were never this caller's
|
|
1609
|
+
* / to see, so `total` over their own rows is the honest count and nothing is hidden FROM them.
|
|
1610
|
+
* / (The unbounded MAP is filed separately — pruning an approval record destroys evidence of what
|
|
1611
|
+
* / was asked, which is a retention ruling rather than a shape fix.)
|
|
1612
|
+
*/
|
|
1613
|
+
listMyApprovalRequests: ActorMethod<[bigint, bigint], Result_28>;
|
|
1614
|
+
/**
|
|
1615
|
+
* / The payer's own sessions, live ones first. PAYER-SCOPED: a caller sees only their own, which
|
|
1616
|
+
* / is why this needs no role — a session id is not a secret from the person who paid for it.
|
|
1617
|
+
* /
|
|
1618
|
+
* / ⟨2026-10-02, paged⟩ Takes `(start, limit)` like every other list here, capped at
|
|
1619
|
+
* / `MAX_SESSIONS_PAGE` rows per call; `total` is how many of the caller's sessions still exist.
|
|
1620
|
+
* / It took no arguments, and a cursor added after the freeze is an argument-list change every
|
|
1621
|
+
* / client would break on — the market paged its own pending withdrawals before its cut for the
|
|
1622
|
+
* / same reason. The order is the order sessions were opened.
|
|
1623
|
+
*/
|
|
1624
|
+
listMySessions: ActorMethod<[bigint, bigint], Result_27>;
|
|
1625
|
+
/**
|
|
1626
|
+
* /
|
|
1627
|
+
* / ⟨0.16.0, L3⟩ Paged and enveloped like every other `list*`, and the envelope here is uniformity
|
|
1628
|
+
* / rather than gating: this method cannot refuse anybody, so `#Err` is unreachable on it. That is
|
|
1629
|
+
* / deliberate — the off-chain verifier that reads this chain reads several other lists beside it,
|
|
1630
|
+
* / and one shape for all of them is worth more than saving a variant tag on the one that is
|
|
1631
|
+
* / public. `total` is the FULL chain length, so a verifier holding a short page can tell it has
|
|
1632
|
+
* / not seen the whole custody history — the distinction a bare array could not express.
|
|
1633
|
+
* /
|
|
1634
|
+
* / PUBLIC: custody history is the answer to "is this engram what it claims to be", and it is
|
|
1635
|
+
* / asked by strangers. `verifyEngramActiveOwner` on the registry answers only about the owner
|
|
1636
|
+
* / IT recorded, so this chain is what a caller composes with when currency matters — which it
|
|
1637
|
+
* / cannot do if it needs a role here.
|
|
1638
|
+
*/
|
|
1639
|
+
listOwnershipTransfers: ActorMethod<[bigint, bigint], Result_26>;
|
|
1640
|
+
/**
|
|
1641
|
+
* / ⟨2026-09-29, the platform's question from the build review⟩ OWNER-ONLY: how many payment
|
|
1642
|
+
* / signatures each agent has obtained today, and the daily limit (200, `PaymentSignCap`). The
|
|
1643
|
+
* / owner's console stated the rule and showed no number, because nothing served one; a number it
|
|
1644
|
+
* / made up would be a fabricated zero. Anyone else is refused by name (`#Refused
|
|
1645
|
+
* / listPaymentSignatureCounts: …`), never answered with zeros. Paged like `listAgents`, in the same
|
|
1646
|
+
* / order, one row per agent in the roster; each count is the agent's, taken by its root as the
|
|
1647
|
+
* / signer takes it, so every key the agent holds here shows the same number. The owner is not
|
|
1648
|
+
* / counted and has no row; the marketplace's count is not an agent's and is not here. WHAT WOULD
|
|
1649
|
+
* / MAKE THIS WRONG: a count kept by something other than the agent's root (`PaymentSignCap.rowFor`
|
|
1650
|
+
* / says so beside it).
|
|
1651
|
+
* /
|
|
1652
|
+
* / ⟨2026-09-30, following the owner's answer 4 of that date⟩ "is not here" no longer holds: the
|
|
1653
|
+
* / marketplace's one shared count today is in the reply's `marketplace` field, with the limit this
|
|
1654
|
+
* / engram enforces for it — beside the agents, never a row among them
|
|
1655
|
+
* / (`PaymentSignCap.marketplaceRow`). Null when no marketplace is set.
|
|
1656
|
+
*/
|
|
1657
|
+
listPaymentSignatureCounts: ActorMethod<[bigint, bigint], Result_25>;
|
|
1658
|
+
/**
|
|
1659
|
+
* / Agent records removed by a reset. Each row is a NAMED record with the fields `principal`,
|
|
1660
|
+
* / `name`, `registeredAt` and `purgedAt` — read them BY NAME, never by position.
|
|
1661
|
+
* / ⟨2026-09-29, the vocabulary ruling: pairing is the one verb that admits an agent⟩ The field
|
|
1662
|
+
* / this prose calls `registeredAt` is now `pairedAt`, on the served row and on the agent record
|
|
1663
|
+
* / it is copied from. What is said below about the two timestamps holds for `pairedAt`.
|
|
1664
|
+
* /
|
|
1665
|
+
* / The names are the whole point, not decoration. Both timestamps are a bare Int, so they were
|
|
1666
|
+
* / positionally indistinguishable at the client: a decoder that swapped registeredAt and
|
|
1667
|
+
* / purgedAt would type-check everywhere and show up only as nonsense in a UI. This prose used to
|
|
1668
|
+
* / describe the row as a positional 4-tuple and readers duly destructured it as one — the same
|
|
1669
|
+
* / bug, twice, in two different repos (corrected 2026-08-16). `agentPurgeLog` really is a
|
|
1670
|
+
* / 4-tuple in stable state; the SERVED shape is not, and that seam is where the mistake starts.
|
|
1671
|
+
* /
|
|
1672
|
+
* / resetEngram HARD-DELETES agent records so a purged principal can be invited back
|
|
1673
|
+
* / (owner ruling 2026-08-15). That makes the reset a genuine clear rather than a permanent burn —
|
|
1674
|
+
* / but it also means the `agents` map is no longer evidence that a principal ever held access,
|
|
1675
|
+
* / and the audit chain cannot stand in: it is a bounded ring that trims its oldest entries, so
|
|
1676
|
+
* / agent.pair rows are evicted over the life the rent model assumes. This is that
|
|
1677
|
+
* / evidence, and it is why the tombstone is written rather than the roster simply dropped.
|
|
1678
|
+
* /
|
|
1679
|
+
* / Owner-gated and TRAPS on refusal: an empty list must mean "no reset has removed an agent",
|
|
1680
|
+
* / never "you may not ask".
|
|
1681
|
+
* / ⟨CORRECTED 2026-10-02: it no longer traps. It is gated through `gatedResult`, so a refusal
|
|
1682
|
+
* / comes back as an `Err` VALUE that names this method — still never as an empty page, which is
|
|
1683
|
+
* / the property the sentence above was protecting.⟩
|
|
1684
|
+
* / RENAMED from `getOperatorPurgeLog` (L2.1: `get*` returns one value, `list*` returns a Page —
|
|
1685
|
+
* / the old name promised a scalar and delivered an array).
|
|
1686
|
+
* /
|
|
1687
|
+
* / Refusal reason preserved: an empty list must mean "no reset has removed an agent", never
|
|
1688
|
+
* / "you may not ask". On an evidence trail those are not close.
|
|
1689
|
+
* /
|
|
1690
|
+
* / Named record, not a 4-tuple. Both Ints are timestamps and were positionally indistinguishable
|
|
1691
|
+
* / at the client — swapping registeredAt and purgedAt would have type-checked everywhere and been
|
|
1692
|
+
* / visible only as nonsense in a UI.
|
|
1693
|
+
* /
|
|
1694
|
+
* / ⟨2026-09-29, review finding LIFE-2⟩ Each row now also carries the agent's `root`, the
|
|
1695
|
+
* / `invite` its enrolment named, and `ended` — why and on what day its engagement ended (its own
|
|
1696
|
+
* / earlier ending, or the reset) — the facts `resyncAgentEdges` re-sends. The stored rows are
|
|
1697
|
+
* / served as they are.
|
|
1698
|
+
*/
|
|
1699
|
+
listPurgedAgents: ActorMethod<[bigint, bigint], Result_24>;
|
|
1700
|
+
/**
|
|
1701
|
+
* / ⟨0.16.0⟩ ONE ACCESSOR, folding `readReadLog` and `getDenialLog` — and the fold only became
|
|
1702
|
+
* / safe because of a change made earlier in this same leg.
|
|
1703
|
+
* /
|
|
1704
|
+
* / They were two methods over the SAME log behind the SAME gate. `getDenialLog`'s own declaration
|
|
1705
|
+
* / explained why the split existed: nothing published this log's head, so a client could only
|
|
1706
|
+
* / reach the OLDEST retained entries, and a "recent refusals" band built on `readReadLog` would
|
|
1707
|
+
* / have rendered the oldest slice of a 10,000-entry ring under those words. That rationale died
|
|
1708
|
+
* / when the Page conversion started publishing `total = totalAppended()` — the head is now a fact
|
|
1709
|
+
* / a caller can read, so paging backward from it is ordinary arithmetic.
|
|
1710
|
+
* /
|
|
1711
|
+
* / The census proposed deleting `readReadLog` outright as a "duplicate accessor". Checked at the
|
|
1712
|
+
* / site, that premise was false: `getDenialLog` filtered `not e.success`, so deleting the other
|
|
1713
|
+
* / would have removed the only way to read SUCCESSFUL entries — and this ring is overwhelmingly
|
|
1714
|
+
* / successful MCP reads. Folded instead, which keeps both capabilities and still ends the pair.
|
|
1715
|
+
* /
|
|
1716
|
+
* / ⚠ `limit` IS A SPAN, NOT A ROW COUNT, and the same in both modes: it is how many log ids to
|
|
1717
|
+
* / EXAMINE starting at `start`. Unfiltered, items == the entries in that span. Filtered, items is
|
|
1718
|
+
* / however many of them matched — fewer, and that is not truncation. This is the one honest
|
|
1719
|
+
* / reading, because the alternative (keep scanning until `limit` rows match) hides how far it
|
|
1720
|
+
* / looked, which is precisely what `getDenialLog` had to disclose with `scannedFrom`/`more`.
|
|
1721
|
+
* / A caller knows exactly which ids were examined: `[start, start + limit)`.
|
|
1722
|
+
* /
|
|
1723
|
+
* / `earliest` is gone as a field and lost nothing: entries carry their own `id`, so a caller
|
|
1724
|
+
* / paging from 0 reads the oldest retained id off the first item. That is L3's stated design —
|
|
1725
|
+
* / items self-identify — rather than a second number to keep in sync.
|
|
1726
|
+
* /
|
|
1727
|
+
* / `withheld` is 0 even when filtering. The filter is CALLER-REQUESTED; `withheld` means rows
|
|
1728
|
+
* / POLICY removed. Overloading it would rebuild the ambiguity this campaign exists to remove.
|
|
1729
|
+
* /
|
|
1730
|
+
* / ⚠ **CORRECTED 2026-08-21, BESIDE the paragraph above because it is what the caller contract
|
|
1731
|
+
* / USED to be: THAT RULE WAS REVERSED ON 2026-08-18 AND THIS COMMENT DID NOT FOLLOW.** The body
|
|
1732
|
+
* / below computes `withheld = examined.size() - kept.size()`, and its own dated note explains
|
|
1733
|
+
* / why: `withheld = 0` beside a filter is the FABRICATED-COMPLETE PAGE, and this is the worst
|
|
1734
|
+
* / method in the file to have it on — `successFilter = ?false` is how the denial band asks "who
|
|
1735
|
+
* / was refused here", and a short page claiming nothing was withheld says the engram examined
|
|
1736
|
+
* / this window and found no refusals, when it examined `span` rows of which most were successes.
|
|
1737
|
+
* /
|
|
1738
|
+
* / So `withheld` now means BOTH policy-removed and filter-removed rows, and a caller can recover
|
|
1739
|
+
* / the examined span as `items.size() + withheld` — which is the successor to the retired
|
|
1740
|
+
* / `scannedFrom`/`head` window, and the number a UI needs to say what it actually looked at
|
|
1741
|
+
* / rather than implying it looked at everything.
|
|
1742
|
+
* /
|
|
1743
|
+
* / This mattered beyond the file: doc comments are emitted into `engram.did`, so every SDK and
|
|
1744
|
+
* / hand-written client has been reading the pre-fix rule off the interface for three days.
|
|
1745
|
+
* /
|
|
1746
|
+
* / Named `listReadLog`, not the census's `listDenialEntries`: that name assumed only the denial
|
|
1747
|
+
* / half survived. A method serving every row must not be named for one of them.
|
|
1748
|
+
* /
|
|
1749
|
+
* / Refusal reason preserved from both: this log has NO public counterpart — no certified head to
|
|
1750
|
+
* / fall back to — so an empty answer would falsely assert nobody has read this record, and an
|
|
1751
|
+
* / empty denial band would assert nobody has ever been refused here.
|
|
1752
|
+
* /
|
|
1753
|
+
* / WHAT "success = false" MEANS, PRECISELY, kept from getDenialLog because it is easy to misread:
|
|
1754
|
+
* / REFUSED-OR-FAILED, not authorization-denied alone. `denied()` writes authz refusals here, and
|
|
1755
|
+
* / so do settle failures, webhook auto-disables, expiry sweeps and MCP rate limits. Do not narrow
|
|
1756
|
+
* / this to a name it does not carry.
|
|
1757
|
+
* /
|
|
1758
|
+
* / ⟨2026-09-29, owner ruling follow-up 16 (B)⟩ An agent reads only the entries it caused, here as
|
|
1759
|
+
* / on the chained record — the same `RecordView` filter, and `withheld` counts what it removed
|
|
1760
|
+
* / together with what `successFilter` removed. WHAT WOULD MAKE THIS WRONG: see `listAuditEntries`.
|
|
1761
|
+
*/
|
|
1762
|
+
listReadLog: ActorMethod<[[] | [boolean], bigint, bigint], Result_23>;
|
|
1763
|
+
/**
|
|
1764
|
+
* / Same visibility as listAuditEntries: the owner, this engram's agents, and ACTIVE guardians
|
|
1765
|
+
* / see disputes. An unauthorized read REFUSES — it does not return an empty list, because an
|
|
1766
|
+
* / empty list reads as "no disputes have been filed", which is a claim, not an absence of one.
|
|
1767
|
+
* / RENAMED from `getRepudiations` (L2.1). Refusal reason preserved: an empty list would read as
|
|
1768
|
+
* / "no disputes have been filed" — and a dispute record that can be mistaken for an absence of
|
|
1769
|
+
* / disputes is worse than no record at all. Not public by design.
|
|
1770
|
+
* /
|
|
1771
|
+
* / ⟨CORRECTED 2026-09-29, owner ruling follow-up 16 (B)⟩ "Same visibility as listAuditEntries"
|
|
1772
|
+
* / still holds, and so the first sentence no longer does: an agent reads only the record entries it
|
|
1773
|
+
* / caused, and every dispute here is the owner's own `memory.repudiate` entry. So the owner and
|
|
1774
|
+
* / guardians get the rows; an agent gets an empty page whose `withheld` counts the rows in its
|
|
1775
|
+
* / window — which says disputes exist without showing them, never "none have been filed". WHAT
|
|
1776
|
+
* / WOULD MAKE THIS WRONG: a ruling that an agent may see the disputes of its own writes; this would
|
|
1777
|
+
* / then have to look up each disputed version's writer, which it does not do today.
|
|
1778
|
+
*/
|
|
1779
|
+
listRepudiations: ActorMethod<[bigint, bigint], Result_22>;
|
|
1780
|
+
/**
|
|
1781
|
+
* / Owner: advance the review cursor — "I have seen everything up to and including uptoAuditId"
|
|
1782
|
+
* / (null = everything at the current head). Bounded so the attestation can never cover entries
|
|
1783
|
+
* / the console did not render; clamped monotonic (the cursor never moves backward) and to the
|
|
1784
|
+
* / current head (never attests the future). Logged, so the review itself is part of the record.
|
|
1785
|
+
* /
|
|
1786
|
+
* / Deliberately filter-agnostic: the cursor is a plain audit id in the CHAINED log's one id space
|
|
1787
|
+
* / (every family qualifiesForReview admits is written to auditLogger, so they share that space),
|
|
1788
|
+
* / and this never inspects an operation or a role. Widening what the review shows therefore
|
|
1789
|
+
* / changes only which ids the console can pass here — it cannot desynchronise the cursor.
|
|
1790
|
+
*/
|
|
1791
|
+
markAgentWritesReviewed: ActorMethod<[[] | [bigint]], Result_8>;
|
|
1792
|
+
/**
|
|
1793
|
+
* / The AGENT's current key nominates the key that will replace it. Nothing moves yet: the new
|
|
1794
|
+
* / key must accept, by its own call, within 24 hours (`acceptAgentKeyNomination`). One pending
|
|
1795
|
+
* / nomination per agent — a new one replaces the earlier one, and the record says which. Refused,
|
|
1796
|
+
* / with nothing changed, for a caller that is not an active agent here and for a key that could
|
|
1797
|
+
* / not hold the record (`KeyReplacement.nomineeRefusal`).
|
|
1798
|
+
*/
|
|
1799
|
+
nominateAgentKey: ActorMethod<[Principal], Result_1>;
|
|
1800
|
+
/**
|
|
1801
|
+
* / An AGENT paired here asks this engram to open an engram of its own. This engram attaches 1.3 T of
|
|
1802
|
+
* / its own cycles to the registry's `sysSpawnChild`; the agent's lasting key owns what is opened, and
|
|
1803
|
+
* / the engram is recorded as opened through this one. Answers the new engram's canister id.
|
|
1804
|
+
* /
|
|
1805
|
+
* / APPROVING IS GIVING: the owner allowed this with `setChildAllowance`, and what is attached is the
|
|
1806
|
+
* / agent's from the moment that engram exists. Nothing is ever taken back, and the registry never
|
|
1807
|
+
* / funds that engram — its owner (the agent) tops it up.
|
|
1808
|
+
* /
|
|
1809
|
+
* / ORDER, with no await before the allowance is taken: the caller is an active agent; there is a
|
|
1810
|
+
* / registry; payments are not frozen (opening sends this engram's cycles out of it, and a freeze is
|
|
1811
|
+
* / the brake a guardian holds over resources leaving); the balance carries the attachment above this
|
|
1812
|
+
* / engram's own reserve; then one opening is TAKEN from the agent's allowance in this message, and only
|
|
1813
|
+
* / then is the registry called. If the registry refuses or cannot be reached, the opening is GIVEN
|
|
1814
|
+
* / BACK (one added to the current count) and the cycles the call did not use come back by the
|
|
1815
|
+
* / network's refund. Every outcome is written to the record under `agent.openChild` in the message
|
|
1816
|
+
* / that hears the registry's answer, before the reply — in the alerts' money class.
|
|
1817
|
+
* /
|
|
1818
|
+
* / ⟨CORRECTED 2026-10-01, review F1 and F4 — the sentence "If the registry refuses or cannot be
|
|
1819
|
+
* / reached, the opening is GIVEN BACK" above is what was first built.⟩ The opening is given back only
|
|
1820
|
+
* / when the WHOLE attachment came back as the call's refund (the registry accepted none of it) and
|
|
1821
|
+
* / the owner has not set this agent's count since the take (`ChildAllowance.settle`). A refusal after
|
|
1822
|
+
* / the registry accepted the cycles (the template would not install, or the key came to own an
|
|
1823
|
+
* / engram meanwhile) leaves the 1.3 T in a canister the agent's key controls; giving the opening back
|
|
1824
|
+
* / then let an allowance of 1 drain this engram 1.3 T per call. Now that opening is spent and the
|
|
1825
|
+
* / reply says so.
|
|
1826
|
+
* /
|
|
1827
|
+
* / WHAT WOULD MAKE THIS WRONG: an await added between `ChildAllowance.take` and the registry call; the
|
|
1828
|
+
* / registry's `CHILD_MIN_ATTACHED_CYCLES` moving without `CHILD_ATTACH_CYCLES`.
|
|
1829
|
+
*/
|
|
1830
|
+
openChildEngram: ActorMethod<[], Result_21>;
|
|
1831
|
+
openSession: ActorMethod<[SessionConfig, PaymentSignature], Result_20>;
|
|
1832
|
+
/**
|
|
1833
|
+
* / Withdraw tokens to the owner's principal. This is the ONLY way to
|
|
1834
|
+
* / move tokens out of the engram to an external address, and the
|
|
1835
|
+
* / destination is always hardcoded to the owner.
|
|
1836
|
+
* / NOT freeze-gated: the owner always controls their own funds.
|
|
1837
|
+
* / Guardian freeze only blocks agent/public operations.
|
|
1838
|
+
*/
|
|
1839
|
+
ownerWithdraw: ActorMethod<[TokenAmount, [] | [ActionAuth]], Result_8>;
|
|
1840
|
+
/**
|
|
1841
|
+
* / ⟨0.16.0⟩ `payRentFromEarnings` DELETED — ruled TWICE (B1 and B2), and it was the single
|
|
1842
|
+
* / clearest violation of the OSS/platform split in this repo.
|
|
1843
|
+
* /
|
|
1844
|
+
* / It hand-declared four cashier methods inline, read `getFeeSchedule`, computed
|
|
1845
|
+
* / `priceE6 = rentUsdE6PerEngramYear * months / 12`, and deposited `priceE6 + 3 * CKUSDC_FEE`
|
|
1846
|
+
* / under a comment explaining that three is "the three token fees the cashier's rail spends" —
|
|
1847
|
+
* / a PUBLIC canister hardcoding how many ledger fees a PRIVATE one consumes internally. Any
|
|
1848
|
+
* / change to the cashier's rail silently mispriced this call.
|
|
1849
|
+
* /
|
|
1850
|
+
* / It also carried the only RE-ENTRANT cross-canister chain in the system: engram →
|
|
1851
|
+
* / cashier.payRentWithStablecoin → (registry, ledger, CMC …) → back into the SAME engram's
|
|
1852
|
+
* / sysRecordFeeEvent while the originating message was still suspended, both writing the same audit
|
|
1853
|
+
* / ring, with no lock.
|
|
1854
|
+
* /
|
|
1855
|
+
* / Rent is the cashier's entirely (B2). Owners pay through the cashier's rails; the engram keeps
|
|
1856
|
+
* / append-only receipts and no fee math.
|
|
1857
|
+
* / ⟨0.16.0, L1 — census-ruled⟩ THE ONE-SHOT ARM. Re-redemption is `#Err(#Conflict)`, named in
|
|
1858
|
+
* / the census row for this method, and it is the arm the whole guard exists to express: this
|
|
1859
|
+
* / principal HAS held agent access, and no code will give it back. A caller reading
|
|
1860
|
+
* / `#Conflict` knows to pair a fresh key; a caller reading `#Refused` would keep presenting the
|
|
1861
|
+
* / same identity, which is exactly the loop the one-shot rule was written to stop.
|
|
1862
|
+
* / Redeem an invite code minted by `createAgentInvite`. The CALLER becomes the agent, so
|
|
1863
|
+
* / redeem from the wallet that will do the work.
|
|
1864
|
+
* /
|
|
1865
|
+
* / ⚠ IT REFUSES ANY CALLER THAT ALREADY HOLDS A RECORD — `#Active`, `#Revoked` or `#Resigned`.
|
|
1866
|
+
* / The `#Revoked` case is the one that matters: revocation is a soft status change, so allowing
|
|
1867
|
+
* / a revoked principal to redeem a fresh invite would be a self-un-revoke. To CHANGE an existing
|
|
1868
|
+
* / agent's permissions the owner uses `setAgentPermissions`; this method is only ever the
|
|
1869
|
+
* / first admission of a principal.
|
|
1870
|
+
* /
|
|
1871
|
+
* / A GUARDIAN cannot redeem one either. A guardian is an independent check on agents, so one
|
|
1872
|
+
* / wallet must not hold both roles — use a separate wallet.
|
|
1873
|
+
* /
|
|
1874
|
+
* / Anonymous callers are refused, and every refusal above is recorded in the denial log.
|
|
1875
|
+
* /
|
|
1876
|
+
* / ⟨RESHAPED 2026-09-28, owner decision: one lasting identity per agent — one root key per agent,
|
|
1877
|
+
* / with an enrolled key per client⟩ The argument is one record: the invite `code` and an
|
|
1878
|
+
* / `enrolment` statement signed by the agent's ROOT key naming this engram, the calling key and
|
|
1879
|
+
* / this code (`Enrolment.verify`). The root is stored on the record and is what the registry keeps
|
|
1880
|
+
* / the track record under. REQUIRED, not optional: every engram launches on this code (the
|
|
1881
|
+
* / building-phase rule, 2026-09-27), so there is no key without a root and no second path for one.
|
|
1882
|
+
* / Two more refusals, each leaving the invite unconsumed: a statement that does not verify, and a
|
|
1883
|
+
* / root that already holds an ACTIVE key here (`Enrolment.activeKeyOf` — one active key per agent
|
|
1884
|
+
* / per engram). The one-shot rule and the five-active cap are unchanged and still read the KEY.
|
|
1885
|
+
* / ⟨CORRECTED 2026-09-29, the cycle-drain hole measured that day⟩ "each leaving the invite
|
|
1886
|
+
* / unconsumed" holds only until the invite's fifth failed statement check: every failed check
|
|
1887
|
+
* / counts against the invite whoever sends it, the fifth voids it (the refusal says so, and the
|
|
1888
|
+
* / record gets `agent.invite.void`), and after that every attempt with it is refused
|
|
1889
|
+
* / `#Conflict` before any check is made (`InviteFailures`).
|
|
1890
|
+
* /
|
|
1891
|
+
* / ⟨RESHAPED 2026-09-29, review finding LIFE-3⟩ The reply is `Types.Pairing`: the agent
|
|
1892
|
+
* / record AND `trackRecord`, which says plainly when the registry refused or failed to record the
|
|
1893
|
+
* / engagement on the agent's track record, and what to do. Before, the reply was `#Ok` with the
|
|
1894
|
+
* / record alone even when the registry had refused the start, so the agent was never told.
|
|
1895
|
+
*/
|
|
1896
|
+
pairAgent: ActorMethod<[{ enrolment: Enrolment; code: string }], Result_19>;
|
|
1897
|
+
/**
|
|
1898
|
+
* / ⟨0.16.0, L2.2 — renamed from `guardianPauseWrites`⟩ Same correction as freezePayments above:
|
|
1899
|
+
* / owner-or-guardian, and `resumeWrites` never carried the prefix either.
|
|
1900
|
+
*/
|
|
1901
|
+
pauseWrites: ActorMethod<[], Result_1>;
|
|
1902
|
+
/**
|
|
1903
|
+
* / What condensing through `toSeq` would do, and whether it is unlocked. COMMITS NOTHING — it is
|
|
1904
|
+
* / a query, so it structurally cannot; a preview that wrote would be its own trap.
|
|
1905
|
+
* /
|
|
1906
|
+
* / It does not ask the library, because the library's refusal cannot answer the owner's question.
|
|
1907
|
+
* / `Chain.prepareCondense` reports `lastExported = null` whenever the only receipts present are
|
|
1908
|
+
* / author-FILTERED, since a filtered receipt never satisfies the gate and is never recorded as a
|
|
1909
|
+
* / near-miss — and an owner who exported minutes ago would read that as "you have never
|
|
1910
|
+
* / exported". So `filteredReceiptsSeen` is counted separately, and `maxUnlockableToSeq` says how
|
|
1911
|
+
* / far the receipts already on file reach, so a console can offer that instead of only "no".
|
|
1912
|
+
* /
|
|
1913
|
+
* / `maxUnlockableToSeq` is a maximum over every retained unfiltered receipt, and a NEWER receipt
|
|
1914
|
+
* / may cover a SHORTER range than an older one — so the scan cannot stop at the first hit. It is
|
|
1915
|
+
* / bounded by entry count instead, and `scannedFromSeq` / `scanTruncated` say where it stopped
|
|
1916
|
+
* / and whether the bound was the reason. A bounded scan that hid its bound would report "no
|
|
1917
|
+
* / receipts" for "I did not look far enough", which is this codebase's own defect class.
|
|
1918
|
+
* /
|
|
1919
|
+
* / `unlocked` is the export-receipt gate ONLY. It is not a promise the condense will land: the
|
|
1920
|
+
* / history-budget delta is checked at commit time and can still refuse a short prefix.
|
|
1921
|
+
*/
|
|
1922
|
+
previewCondense: ActorMethod<[bigint], Result_18>;
|
|
1923
|
+
/**
|
|
1924
|
+
* / A quote for a session this caller has not opened and is not committed to — the intent a
|
|
1925
|
+
* / buyer signs against. Pure dry run, no state, no funds.
|
|
1926
|
+
* /
|
|
1927
|
+
* / PUBLIC: a price list nobody can read is not a price list. A buyer has to see the deposit
|
|
1928
|
+
* / minimum and per-call cost BEFORE signing anything, and gating the quote behind a role would
|
|
1929
|
+
* / mean the only way to learn this engram's price is to already be permitted to pay it.
|
|
1930
|
+
* /
|
|
1931
|
+
* / ⟨CORRECTED 2026-08-24 — this said "⟨L7⟩ UPDATE, NOT QUERY" and cited a market ruling that
|
|
1932
|
+
* / DEC-107 had already closed.⟩ QUERY, per the ruled quote convention: FAST READS. Both
|
|
1933
|
+
* / `quotePayment` and `previewOpenSession` become queries, and L7's open-ruling exception
|
|
1934
|
+
* / retires with them — so the argument written here for keeping it an update was arguing the
|
|
1935
|
+
* / losing side of a decision already made, and was added the same day by not reading forward
|
|
1936
|
+
* / to the ruling. `gate.offerSession` is pure — it validates the intent and returns it — so
|
|
1937
|
+
* / nothing forced the update in the first place.
|
|
1938
|
+
* /
|
|
1939
|
+
* / ONE-REPLICA CAVEAT, stated here because the ruling requires it at both sites: a query is one
|
|
1940
|
+
* / replica's word and is NOT a settleable challenge. Nothing quoted here can be redeemed. The
|
|
1941
|
+
* / commitment happens in `openSession`, which IS a certified update call, and a buyer who needs
|
|
1942
|
+
* / the price attested rather than quoted takes it from that reply.
|
|
1943
|
+
* /
|
|
1944
|
+
* / ⟨RESTORED 2026-08-24, owner ruling R-A1⟩ Named to match the market's, because it is the
|
|
1945
|
+
* / same act against a different seller and a reader comparing the two should not have to learn
|
|
1946
|
+
* / two verbs for it.
|
|
1947
|
+
* /
|
|
1948
|
+
* / ⟨2026-10-02⟩ Answers the house `Types.SessionIntent` — ic402's intent with `expiry` spelled
|
|
1949
|
+
* / `expiryNs`. Same value, same meaning; only the name carries the unit now.
|
|
1950
|
+
*/
|
|
1951
|
+
previewOpenSession: ActorMethod<[], SessionIntent>;
|
|
1952
|
+
/**
|
|
1953
|
+
* / Read one memory file at its current version.
|
|
1954
|
+
* /
|
|
1955
|
+
* / Gated on the `read_memory` permission, so an agent holding that grant reaches it — unlike
|
|
1956
|
+
* / `writeMemory`, which is owner-only.
|
|
1957
|
+
* /
|
|
1958
|
+
* / ⚠ `config/` AND `secrets/` ARE OWNER-ONLY whatever the grant says, and the refusal is
|
|
1959
|
+
* / `#Refused` rather than `#Invalid` deliberately: the path is well-formed and the file may well
|
|
1960
|
+
* / exist — the caller simply may not have it. Under L1 that distinction is the caller's to branch
|
|
1961
|
+
* / on, which is the whole reason `Error` is a closed variant rather than a sentence.
|
|
1962
|
+
* /
|
|
1963
|
+
* / ⚠ A QUERY, so it does NOT count as a read. The IC discards query-path state changes, so a
|
|
1964
|
+
* / counter here could never persist; read counting lives on the update path
|
|
1965
|
+
* / (`sessionReadContext` and the MCP reads). A caller measuring engram usage from this method
|
|
1966
|
+
* / will measure nothing.
|
|
1967
|
+
*/
|
|
1968
|
+
readMemory: ActorMethod<[string], Result_11>;
|
|
1969
|
+
/**
|
|
1970
|
+
* / Read many paths in one call. Per-path Results are KEPT — partial success is the point, and
|
|
1971
|
+
* / one unreadable path must not fail the other nine.
|
|
1972
|
+
* /
|
|
1973
|
+
* / ⟨0.16.0⟩ The OUTER envelope is new, and it fixes two ways this used to answer dishonestly:
|
|
1974
|
+
* /
|
|
1975
|
+
* / · Over the path cap it returned `[("", #Err(#Invalid …))]` — ONE row, for a path the caller
|
|
1976
|
+
* / never asked about. A consumer looping rows saw a result for the empty path and no result
|
|
1977
|
+
* / for any real one. The call as a whole failed; dressing that as a per-path outcome is the
|
|
1978
|
+
* / fabrication ADR-0002 is about.
|
|
1979
|
+
* / · An AUTHORIZATION refusal was fanned out across every requested path, so one "no" arrived
|
|
1980
|
+
* / as N per-path noes and read like N independent permission facts about N files.
|
|
1981
|
+
* /
|
|
1982
|
+
* / Both are now what they are: a single `#Err` for the whole call. `#Ok` still carries a row per
|
|
1983
|
+
* / path, each with its own Result — a refused RESERVED path sits beside a readable one, which is
|
|
1984
|
+
* / a genuine per-path fact.
|
|
1985
|
+
*/
|
|
1986
|
+
readMemoryBatch: ActorMethod<[Array<string>], Result_17>;
|
|
1987
|
+
/**
|
|
1988
|
+
* / ⟨0.16.0⟩ `getMemoryRetentionGuards` DELETED — folded into `getMemoryRetentionPolicy` above.
|
|
1989
|
+
* / It was the second L2.1 array-returning `get*`, and separating it from the policy it modifies
|
|
1990
|
+
* / was the defect described there. Its own docs are preserved at the fold site.
|
|
1991
|
+
* / One page of a file's content — the paged read the whole-file surfaces point at.
|
|
1992
|
+
* /
|
|
1993
|
+
* / `version = null` reads the live file; a version reads that version as it was recorded.
|
|
1994
|
+
* / The store clamps a page to one chunk, and `more` DISCLOSES the clamp: a caller that cannot
|
|
1995
|
+
* / see it cannot know whether it has the whole range, which is how silent truncation gets
|
|
1996
|
+
* / reintroduced. Loop while `more` is true, advancing by the bytes actually returned.
|
|
1997
|
+
*/
|
|
1998
|
+
readMemoryBytes: ActorMethod<[string, bigint, bigint, [] | [bigint]], Result_16>;
|
|
1999
|
+
/**
|
|
2000
|
+
* / The escrow exit for a session whose settle cannot pay.
|
|
2001
|
+
* /
|
|
2002
|
+
* / PAYER-ONLY, enforced inside the gateway, and deliberately not owner-triggered: the payer's own
|
|
2003
|
+
* / deposit is the only thing here, so making them wait for anyone else would be a worse rail than
|
|
2004
|
+
* / the one this replaces. (The market's twin is admin-triggered because a marketplace session has
|
|
2005
|
+
* / a counterparty; a memory session does not.)
|
|
2006
|
+
* /
|
|
2007
|
+
* / WHY IT IS NEEDED AT ALL: `closeSessionInternal` settles only when
|
|
2008
|
+
* / `deposited >= consumed + fee`, and vouchers may consume up to the full deposit — so a payer
|
|
2009
|
+
* / who spends their whole budget makes their own session unsettleable, with no adversary
|
|
2010
|
+
* / involved. Before this, the refusal text told them to call `recoverEscrow`, which existed on no
|
|
2011
|
+
* / canister they could reach. RB2 caps consumable spend so ordinary use cannot reach that state;
|
|
2012
|
+
* / this is the way back for a session that already has.
|
|
2013
|
+
* /
|
|
2014
|
+
* / ⟨CORRECTION 2026-09-30, beside the paragraph above and the first line⟩ No longer true. ic402
|
|
2015
|
+
* / 2.17.0's `closeSessionInternal` settles `min(consumed, deposited − fee)` and skips a refund of
|
|
2016
|
+
* / zero, so a session spent to its whole budget still closes, and under the one-fee reserve a clean
|
|
2017
|
+
* / close leaves the escrow holding nothing or less than one fee, which no transfer can move. The
|
|
2018
|
+
* / way back is for a REFUND LEG THAT FAILED (a transient ledger error): the settle went through,
|
|
2019
|
+
* / ic402 marks the session closed, and the remainder stays in escrow until the payer calls this.
|
|
2020
|
+
* / A failed settle is not this method's case: ic402 puts that session back to open, where this
|
|
2021
|
+
* / method refuses, and the close is retried instead. WHAT WOULD MAKE THIS WRONG: an ic402 whose
|
|
2022
|
+
* / close stops capping the settle, or a live ckUSDC fee above `Env.CKUSDC_FEE`.
|
|
2023
|
+
* /
|
|
2024
|
+
* / ckUSDC only — an engram session's intent names `Env.CKUSDC_LEDGER` and nothing else, so there
|
|
2025
|
+
* / is no token to choose and no wrong one to pass.
|
|
2026
|
+
* /
|
|
2027
|
+
* / ⟨2026-10-02, decided — the twin divergence is deliberate⟩ The market's `recoverEscrow` takes
|
|
2028
|
+
* / `Wire.TokenAmount`; this one takes a bare `nat`, and the two stay different on purpose. The
|
|
2029
|
+
* / market escrows more than one token, so the amount has to say which; this engram's sessions
|
|
2030
|
+
* / escrow ckUSDC only, and a `TokenAmount` here would make an `#Icp` amount representable and then
|
|
2031
|
+
* / refuse it at runtime — the argument `convertEarningsToCycles` makes. What changed is the NAME:
|
|
2032
|
+
* / `amountE6`, ckUSDC base units. Candid passes arguments by position, so nothing on the wire moved.
|
|
2033
|
+
* /
|
|
2034
|
+
* / ⚠ `#Conflict` HERE ALSO COVERS "NOT THE SESSION'S PAYER". ⟨2026-10-02, audited at this site⟩
|
|
2035
|
+
* / The payer check is ic402's (`recoverEscrow` authorizes `caller == session.payer`), and the
|
|
2036
|
+
* / library answers every refusal down one text channel, so "Not authorized: only session payer can
|
|
2037
|
+
* / recover escrow" arrives as `#Conflict`, beside the state refusals (an open session, nothing to
|
|
2038
|
+
* / recover, no such session). Read the MESSAGE, not the arm. This is the 0.16.0 contract as
|
|
2039
|
+
* / ratified on 2026-10-02; giving the library one arm per kind of refusal is post-cut dependency
|
|
2040
|
+
* / work. (The payments-frozen refusal in the body is this engram's own, and is state.)
|
|
2041
|
+
* /
|
|
2042
|
+
* / ⟨2026-10-05, ic402 2.17.3 — beside the list above⟩ A fourth state refusal: a session that reads
|
|
2043
|
+
* / `closing` or `expired`, whose close has not finished. Escrow comes back only from a session that
|
|
2044
|
+
* / reads `closed`, and the refusal moves nothing. A close that stopped part-way (its refund call
|
|
2045
|
+
* / rejected, or a trap) leaves the session reading `closing`, and no method on this engram moves it.
|
|
2046
|
+
*/
|
|
2047
|
+
recoverEscrow: ActorMethod<[string, bigint], Result_8>;
|
|
2048
|
+
/**
|
|
2049
|
+
* / ⟨0.16.0, L1⟩ A REDEMPTION PATH, where the arm choice is a disclosure decision.
|
|
2050
|
+
* /
|
|
2051
|
+
* / Four of these refusals are about the CODE and one is about the caller. The code arms restate
|
|
2052
|
+
* / exactly what the text already said — an unknown code is `#NotFound`, a used or expired one is
|
|
2053
|
+
* / `#Conflict` — so no fact is newly disclosed by the arms; the anti-enumeration control here is
|
|
2054
|
+
* / the attempt throttle above, not vagueness in the reply. Throttling is itself `#Conflict` (at
|
|
2055
|
+
* / capacity) rather than `#Unavailable`: nothing failed, and the caller's own recent behaviour is
|
|
2056
|
+
* / what closed the door, so "try again" is true only after the stated wait.
|
|
2057
|
+
* /
|
|
2058
|
+
* / ⟨2026-10-02⟩ Answers the `GuardianRecord` it created — `#Pending` until the owner approves —
|
|
2059
|
+
* / rather than `()`. The new guardian learns, in the same reply, the name and permissions the
|
|
2060
|
+
* / owner's invite gave them and that they cannot act until approved; before, that took a second
|
|
2061
|
+
* / read they had no reason to know to make.
|
|
2062
|
+
*/
|
|
2063
|
+
registerGuardian: ActorMethod<[string], Result_15>;
|
|
2064
|
+
/**
|
|
2065
|
+
* / Remove a per-caller override so that caller reverts to — and keeps TRACKING — the global caps.
|
|
2066
|
+
* /
|
|
2067
|
+
* / It travels with its pair and is never dropped alone: without it the only way "back" from an
|
|
2068
|
+
* / override is to overwrite it with a frozen copy of the global policy, which then stops
|
|
2069
|
+
* / following later changes. That makes every override permanent in effect.
|
|
2070
|
+
*/
|
|
2071
|
+
removeCallerSpendPolicy: ActorMethod<[Principal], Result_1>;
|
|
2072
|
+
/**
|
|
2073
|
+
* / De-register a type that has NEVER SIGNED. Exists because of a hazard the first external
|
|
2074
|
+
* / validation found within hours (consumer report, 2026-08-06): a bare-name #standard registration —
|
|
2075
|
+
* / cheap, no watcher preconditions — permanently blocked the guarded namespaced registration
|
|
2076
|
+
* / via the collision rule, with no way out. An owner typo could brick a venue integration for
|
|
2077
|
+
* / the engram's lifetime. Never-signed is the whole gate: a type that signed even once is part
|
|
2078
|
+
* / of what the audit chain's eip712.sign entries mean, and stays resolvable forever — this
|
|
2079
|
+
* / removes only authority that was never exercised, which is removing nothing but the mistake.
|
|
2080
|
+
* / NOT freeze-gated, same reasoning as removeEvmWithdrawDestination: this is TIGHTENING, and a
|
|
2081
|
+
* / frozen engram must still be able to shrink what it could sign.
|
|
2082
|
+
*/
|
|
2083
|
+
removeEip712Type: ActorMethod<[Uint8Array | number[]], Result_1>;
|
|
2084
|
+
removeEvmWithdrawDestination: ActorMethod<[string], Result_1>;
|
|
2085
|
+
/**
|
|
2086
|
+
* / Owner-only: remove a guardian from the roster.
|
|
2087
|
+
* /
|
|
2088
|
+
* / Unlike revoking an agent this is NOT terminal for the principal — the guardian roster does
|
|
2089
|
+
* / not carry the one-shot rule that blocks a revoked agent from ever pairing again, so the
|
|
2090
|
+
* / same wallet can be invited again.
|
|
2091
|
+
* /
|
|
2092
|
+
* / `#NotFound` rather than `#Refused` when there is no such guardian: only the owner reaches this
|
|
2093
|
+
* / line, so the roster is theirs and its contents are not a secret being withheld from them.
|
|
2094
|
+
*/
|
|
2095
|
+
removeGuardian: ActorMethod<[Principal], Result_1>;
|
|
2096
|
+
/**
|
|
2097
|
+
* / Owner disavows a specific memory write, in the open. Marks — never deletes: the content and
|
|
2098
|
+
* / the original audit entry stay exactly where they were; this appends a chained
|
|
2099
|
+
* / `memory.repudiate` entry and lists the (path, version) so readers can see the dispute.
|
|
2100
|
+
*/
|
|
2101
|
+
repudiateMemoryWrite: ActorMethod<[string, bigint, string], Result_8>;
|
|
2102
|
+
/**
|
|
2103
|
+
* / ⚠ OWNER-ONLY BULK RESET. Destructive, and wider than its name suggests.
|
|
2104
|
+
* /
|
|
2105
|
+
* / It severs EVERY grant surface that can outlive a role — agents, guardians, invites and
|
|
2106
|
+
* / connector tokens — clears memory, and returns the operational flags (encryption, writes-paused,
|
|
2107
|
+
* / payments-frozen) to a fresh baseline. Anyone holding access through any of those loses it.
|
|
2108
|
+
* /
|
|
2109
|
+
* / What SURVIVES, deliberately:
|
|
2110
|
+
* / · the cumulative counters, which never reset — an engram cannot make itself look new;
|
|
2111
|
+
* / · memory DELETES are soft, so version history is retained and paths stay enumerable via
|
|
2112
|
+
* / `listDeletedMemoryFiles`;
|
|
2113
|
+
* / · `agentPurgeLog`, which is the durable record of who was severed;
|
|
2114
|
+
* / · ⟨2026-09-29⟩ today's spending totals — each caller's and the engram-wide one — and the
|
|
2115
|
+
* / owner's engram-wide ceiling. A reset severs access; it never gives back a day's allowance
|
|
2116
|
+
* / already spent, so a key re-admitted after a reset keeps what it spent today (the totals are
|
|
2117
|
+
* / kept per calling key).
|
|
2118
|
+
* / · ⟨2026-10-02⟩ the seat weeks of every engagement (`agentSeatWeeks`), with the signature count
|
|
2119
|
+
* / they sit beside, and the owner's switch over the metrics reader's read and the reader it
|
|
2120
|
+
* / names — a reset severs access, it does not change who may read what was kept.
|
|
2121
|
+
* /
|
|
2122
|
+
* / ⟨2026-10-02⟩ It tells the spawning registry that it happened (`sysNoteReset`), on every reset.
|
|
2123
|
+
* /
|
|
2124
|
+
* / It is recorded as ONE chained `engram.reset` entry that also names the flag transitions.
|
|
2125
|
+
* /
|
|
2126
|
+
* / ⚠ AND THE LIMIT OF THAT RECORD, because a caller relying on it should know: the audit chain is
|
|
2127
|
+
* / NOT unbounded. It caps at MAX_ENTRIES and trims its oldest tenth on overflow, so on any engram
|
|
2128
|
+
* / long-lived enough for the rent model to apply, the reset entry is not guaranteed to still be
|
|
2129
|
+
* / there. `agentPurgeLog` is the evidence that does not age out — which is why it exists.
|
|
2130
|
+
*/
|
|
2131
|
+
resetEngram: ActorMethod<[], Result_14>;
|
|
2132
|
+
/**
|
|
2133
|
+
* / ⟨2026-09-28, owner decision: an agent can resign from an engram, and the resignation is
|
|
2134
|
+
* / recorded⟩ The AGENT ends its own engagement with this engram.
|
|
2135
|
+
* /
|
|
2136
|
+
* / WHY IT EXISTS: before this, every ending was something done TO an agent — revoked by the
|
|
2137
|
+
* / owner, by a guardian, by the kill switch, or by a reset — so an agent that wanted to leave
|
|
2138
|
+
* / cleanly had to wait to be fired, and its track record across engrams could not tell a clean exit
|
|
2139
|
+
* / from a firing. This is the one ending the agent itself chooses, and the registry records it
|
|
2140
|
+
* / under its own reason (`#Resigned`), never folded into a revocation.
|
|
2141
|
+
* /
|
|
2142
|
+
* / TERMINAL for this principal on this engram, exactly like a revocation: the record stays (status
|
|
2143
|
+
* / `#Resigned`, auditable), and `pairAgent` refuses any principal that already holds a
|
|
2144
|
+
* / record, so returning means a different principal and a fresh invite from the owner.
|
|
2145
|
+
* /
|
|
2146
|
+
* / SELF-SERVICE, so the refusals are about the record's state, not the caller's standing:
|
|
2147
|
+
* / `#NotFound` for a caller that is not an agent here, `#Conflict` for one already ended.
|
|
2148
|
+
* / The roster change and its chained audit line commit BEFORE the registry is told, so a registry
|
|
2149
|
+
* / that is down cannot leave the agent half-resigned; a missed notice is logged by
|
|
2150
|
+
* / `notifyRegistryAgentEdge`. WHAT WOULD MAKE THIS WRONG: a second path that sets `#Resigned`.
|
|
2151
|
+
*/
|
|
2152
|
+
resignAgent: ActorMethod<[], Result_1>;
|
|
2153
|
+
/**
|
|
2154
|
+
* / OWNER-ONLY release of the write pause, with the same one-way shape as `unfreezePayments`: a
|
|
2155
|
+
* / guardian holding `canPauseWrites` can stop writes without the owner and cannot restart them,
|
|
2156
|
+
* / and the owner can always restart them. A tripwire rather than a lock.
|
|
2157
|
+
*/
|
|
2158
|
+
resumeWrites: ActorMethod<[], Result_1>;
|
|
2159
|
+
/**
|
|
2160
|
+
* / Self-heal: re-send every ACTIVE agent's start to the spawning registry (idempotent — the
|
|
2161
|
+
* / registry mints no duplicate for an open engagement), for when a notice was missed. Owner-only.
|
|
2162
|
+
* / Returns how many the registry ACKNOWLEDGED. ⟨2026-09-28: it used to count sends that did not
|
|
2163
|
+
* / throw, against a method that could not say no; it now counts `#Ok` answers.⟩ It re-sends
|
|
2164
|
+
* / starts only: an ending carries a reason this roster does not keep per principal.
|
|
2165
|
+
* /
|
|
2166
|
+
* / ⟨CORRECTED 2026-09-29, review finding LIFE-2 — owner's option A⟩ It now re-sends ENDINGS as
|
|
2167
|
+
* / well as starts, endings first (`AgentEdges.resyncPlan` says why): every ended record on the
|
|
2168
|
+
* / roster and every agent a reset removed keeps its ending's reason and day
|
|
2169
|
+
* / (`Types.AgentEnding`), so an ending the registry never received — the one loss that used to
|
|
2170
|
+
* / show an engram's engagement as live on the agent's record forever and block the agent's later starts here —
|
|
2171
|
+
* / is recorded by one call of this. The registry answers an ending it already holds `#Ok`.
|
|
2172
|
+
* / RESHAPED REPLY: `Types.ResyncReport` in place of a bare count — the endings and starts the
|
|
2173
|
+
* / registry acknowledged, and every notice it did not, with its own words, so the owner can tell
|
|
2174
|
+
* / an expected answer (an ending for a start that was never recorded says so) from a real one.
|
|
2175
|
+
* / The calls leave in batches of `RESYNC_BATCH`, each batch in order and wholly answered before the
|
|
2176
|
+
* / next leaves, so the order above holds at the registry.
|
|
2177
|
+
* / ⟨2026-09-29⟩ WHAT A RESYNC CANNOT DO: record an engagement whose start the registry never
|
|
2178
|
+
* / recorded and which has since ENDED. A start is re-sent only for an agent still active here, so
|
|
2179
|
+
* / all that is left to send is the ending, and the registry has nothing to end. The report lists
|
|
2180
|
+
* / each such engagement under `cannotBeRecorded` (key, root, invite, and how and when it ended),
|
|
2181
|
+
* / apart from `notRecorded`, so the owner sees them rather than silence.
|
|
2182
|
+
*/
|
|
2183
|
+
resyncAgentEdges: ActorMethod<[], Result_13>;
|
|
2184
|
+
/**
|
|
2185
|
+
* / Return to managed custody: the engram adds the registry back as a controller ALONGSIDE the
|
|
2186
|
+
* / owner — it does not remove the owner. The inverse of `claimSovereignty`, and the reason
|
|
2187
|
+
* / sovereignty is not a one-way door.
|
|
2188
|
+
*/
|
|
2189
|
+
returnToManaged: ActorMethod<[], Result_1>;
|
|
2190
|
+
/**
|
|
2191
|
+
* / Replace the whole content of an EXISTING file.
|
|
2192
|
+
* /
|
|
2193
|
+
* / This is the one thing agents could never do before: every agent write was an append,
|
|
2194
|
+
* / so a file could only ever grow. The ruling that opened it is narrow, and every part of the
|
|
2195
|
+
* / narrowness is enforced below — an agent may replace content only on a path the owner has
|
|
2196
|
+
* / granted, only where retention is not #vault, and only where the file already exists. Vault
|
|
2197
|
+
* / paths stay append-only forever, which is the claim the product makes about them.
|
|
2198
|
+
* /
|
|
2199
|
+
* / Replacing is safe here in a way it was not in the legacy store: the prior version is not
|
|
2200
|
+
* / overwritten, it is superseded. It stays readable, its hash stays committed, and the agent
|
|
2201
|
+
* / floor keeps its bytes for the window a counterparty needs to extract them.
|
|
2202
|
+
* / ⟨0.16.0, L1⟩ FIVE AGENT REFUSALS, ALL `#Refused`, AND THE UNIFORMITY IS THE FINDING.
|
|
2203
|
+
* /
|
|
2204
|
+
* / Reserved path, protected path, missing permission, ungranted revise path, `#vault` class — a
|
|
2205
|
+
* / caller could previously tell these apart only by reading five different sentences, and every
|
|
2206
|
+
* / one of them ends the same way: this agent may not make this write, and no retry by this
|
|
2207
|
+
* / agent changes that. The prose already said "Not operator-retryable" four times over,
|
|
2208
|
+
* / because a text field was the only place to put it. It is an arm now.
|
|
2209
|
+
* /
|
|
2210
|
+
* / The one that could tempt a different arm is `#vault`, which looks like a state fact. It is
|
|
2211
|
+
* / not: the class is an AUTHORIZATION statement about who may replace content there, and it
|
|
2212
|
+
* / resolves to the same "you may not", forever, for everyone but the owner.
|
|
2213
|
+
*/
|
|
2214
|
+
reviseMemory: ActorMethod<[string, Uint8Array | number[]], Result>;
|
|
2215
|
+
/**
|
|
2216
|
+
* / Owner-only: revoke one agent.
|
|
2217
|
+
* /
|
|
2218
|
+
* / ⚠ SOFT AND TERMINAL, which sounds contradictory and is not. The record is not deleted — the
|
|
2219
|
+
* / status becomes `#Revoked` and the row survives, which is what makes the revocation auditable.
|
|
2220
|
+
* / And because `pairAgent` refuses any principal that already holds a record of ANY
|
|
2221
|
+
* / status, this is permanent FOR THAT PRINCIPAL: they cannot be re-invited. Re-admitting the same
|
|
2222
|
+
* / human means a different wallet.
|
|
2223
|
+
* /
|
|
2224
|
+
* / To narrow what an agent may do rather than end its access, use `setAgentPermissions`.
|
|
2225
|
+
*/
|
|
2226
|
+
revokeAgent: ActorMethod<[Principal], Result_1>;
|
|
2227
|
+
/**
|
|
2228
|
+
* / Owner-only panic button: revoke EVERY active agent at once. Returns how many were revoked.
|
|
2229
|
+
* /
|
|
2230
|
+
* / ⚠ IT REVOKES ONLY AGENTS. Invites and connector bearer tokens are separate surfaces with
|
|
2231
|
+
* / their own buttons (`revokeAllInvites`, `revokeAllBearerTokens`), and an owner reaching for one
|
|
2232
|
+
* / of these in an emergency almost certainly wants all three. Nothing here cascades.
|
|
2233
|
+
* /
|
|
2234
|
+
* / ⚠ AND IT IS IRREVERSIBLE PER PRINCIPAL, which a "revoke all" reads as temporary and is not.
|
|
2235
|
+
* / Each agent's record is set to `#Revoked` rather than deleted, and `pairAgent`
|
|
2236
|
+
* / refuses any principal holding a record of ANY status — so every wallet this touches can never
|
|
2237
|
+
* / be an agent on this engram again. Re-admitting the same agents means new keys. Only
|
|
2238
|
+
* / `resetEngram` clears the records, and it severs everything else with them.
|
|
2239
|
+
* /
|
|
2240
|
+
* / The revocation is committed BEFORE the registry is told: state is cleared, the audit line is
|
|
2241
|
+
* / written, and only then does it await one notification per revoked agent. So a notification
|
|
2242
|
+
* / that fails leaves the agents revoked here regardless — a partial notify is not a partial
|
|
2243
|
+
* / revocation, which is the direction that matters for a panic button.
|
|
2244
|
+
*/
|
|
2245
|
+
revokeAllAgents: ActorMethod<[], Result_8>;
|
|
2246
|
+
/**
|
|
2247
|
+
* / Owner-only panic button: revoke every connector bearer token at once. Returns how many.
|
|
2248
|
+
* /
|
|
2249
|
+
* / The THIRD independent surface — hosted connectors authenticate with bearer tokens, not with
|
|
2250
|
+
* / agent records or invites, so neither of the buttons above touches them. An owner cutting
|
|
2251
|
+
* / off access completely needs all three, and this is the one that reaches an AI host already
|
|
2252
|
+
* / holding a live session.
|
|
2253
|
+
* /
|
|
2254
|
+
* / Tokens are re-issuable: revoking them is not permanent the way revoking an agent is.
|
|
2255
|
+
*/
|
|
2256
|
+
revokeAllBearerTokens: ActorMethod<[], Result_8>;
|
|
2257
|
+
/**
|
|
2258
|
+
* / ⟨0.16.0⟩ `removeAllGuardians` DELETED — test-only (L6), and verified NOT part of KILL-SWITCH's
|
|
2259
|
+
* / mass-revoke set. The destructive phase-07 suite iterates `removeGuardian` instead, so nothing
|
|
2260
|
+
* / loses a capability: what dies is a bulk spelling no runbook ever invoked.
|
|
2261
|
+
* / Owner-only panic button: void every unredeemed invite. Returns how many were voided.
|
|
2262
|
+
* /
|
|
2263
|
+
* / Separate from `revokeAllAgents`: this stops invites that have NOT been redeemed yet and
|
|
2264
|
+
* / touches no existing agent. An invite already redeemed is an agent, and only the other
|
|
2265
|
+
* / button reaches it.
|
|
2266
|
+
* /
|
|
2267
|
+
* / Unlike revoking an agent, this costs nothing permanently — an invite is a one-time code,
|
|
2268
|
+
* / so voiding it and minting a fresh one is the ordinary path.
|
|
2269
|
+
*/
|
|
2270
|
+
revokeAllInvites: ActorMethod<[], Result_8>;
|
|
2271
|
+
/**
|
|
2272
|
+
* / Revoke a bearer token by its public tokenId. Idempotent.
|
|
2273
|
+
* / Subsequent /mcp requests using this token will be rejected.
|
|
2274
|
+
*/
|
|
2275
|
+
revokeBearerToken: ActorMethod<[string], Result_1>;
|
|
2276
|
+
/**
|
|
2277
|
+
* / ⟨0.16.0, census §10 item 16⟩ RETURNS A REAL RECEIPT, not `R<()>` — same reason as the delete
|
|
2278
|
+
* / above, and sharper here: a rollback WRITES A NEW VERSION, so the caller's next question is
|
|
2279
|
+
* / always "which version am I on now". `r.version` was already read for the audit line.
|
|
2280
|
+
*/
|
|
2281
|
+
rollbackMemory: ActorMethod<[string, bigint], Result>;
|
|
2282
|
+
/**
|
|
2283
|
+
* / SELF-SERVICE, and that is the surprising part: the AGENT calls this, not the owner. An
|
|
2284
|
+
* / agent rotates its own CallerKey binding without needing the owner to act.
|
|
2285
|
+
* /
|
|
2286
|
+
* / ⚠ IT ROTATES THE KEY, NOT THE PRINCIPAL. Only `publicKeyHash` changes; the agent record
|
|
2287
|
+
* / stays keyed on the same principal, keeps its permissions, and keeps its place against the
|
|
2288
|
+
* / one-shot registration rule. So this is the answer to "my key is compromised", and it is NOT a
|
|
2289
|
+
* / way to move an agent seat to a different wallet — that is a new invite, and only if the
|
|
2290
|
+
* / old principal was never revoked.
|
|
2291
|
+
* / ⟨CORRECTED 2026-09-29, the owner's ruling of that date (follow-up 10, option A)⟩ Two sentences
|
|
2292
|
+
* / above are no longer true. An agent's record CAN now move to a different key, in one step and
|
|
2293
|
+
* / with no new invite: `nominateAgentKey` from the current key, then `acceptAgentKeyNomination`
|
|
2294
|
+
* / from the new one. And a compromised key is answered by that move — this method only changes a
|
|
2295
|
+
* / recorded hash, and the compromised principal keeps calling as the agent. This method still
|
|
2296
|
+
* / does what it says; the move is the one that changes which key the engram answers.
|
|
2297
|
+
* /
|
|
2298
|
+
* / `#Conflict` rather than `#Refused` for a `#Revoked` or `#Resigned` record: the caller IS the
|
|
2299
|
+
* / agent on that record, so its standing is not the problem — the record's state is. An
|
|
2300
|
+
* / agent reading `#Refused` would go looking for a permission that was never missing.
|
|
2301
|
+
*/
|
|
2302
|
+
rotateAgentKeyHash: ActorMethod<[string], Result_1>;
|
|
2303
|
+
/**
|
|
2304
|
+
* / One-time onboarding seed: writes a starter file so the first read-back is non-empty.
|
|
2305
|
+
* /
|
|
2306
|
+
* / Owner-only, and it REFUSES once any memory exists — so it can only ever add the initial
|
|
2307
|
+
* / placeholder and can never overwrite real content. Deliberately NOT counted as a write (no
|
|
2308
|
+
* / `totalMemoryWrites`, no `firstWriteAt`): it is a system seed rather than activity, and
|
|
2309
|
+
* / counting it would corrupt both the write metrics and time-to-first-write for every engram.
|
|
2310
|
+
*/
|
|
2311
|
+
seedMemory: ActorMethod<[string, Uint8Array | number[]], Result>;
|
|
2312
|
+
/**
|
|
2313
|
+
* / Append to a memory file against a PAID x402 session voucher — the write half of the paid rail,
|
|
2314
|
+
* / authorized by the voucher rather than by a role.
|
|
2315
|
+
* / ⟨2026-09-30, ic402 2.17.0⟩ Authorized by the payer's own call with the voucher: only the
|
|
2316
|
+
* / principal that opened the session, calling as that key, can spend it (see `sessionReadMemory`).
|
|
2317
|
+
* / ⟨CORRECTED 2026-09-30, the owner's answer "2 fresh key"⟩ Authorized by the session KEY's own
|
|
2318
|
+
* / call: the fresh key the payer named at open. The write is attributed to the payer, who paid;
|
|
2319
|
+
* / the record row also names the key that made it.
|
|
2320
|
+
* /
|
|
2321
|
+
* / ⚠ AS WITH `sessionReadMemory`, EVERY REFUSAL FIRES BEFORE THE VOUCHER IS CONSUMED — nothing is
|
|
2322
|
+
* / written and no funds move. It refuses when payments are frozen, when writes are PAUSED, and
|
|
2323
|
+
* / when the engram is client-side encrypted: a paid session appending plaintext to an encrypted
|
|
2324
|
+
* / store would CORRUPT it, so that refusal is protecting the owner's data rather than gating
|
|
2325
|
+
* / access. Append through the EngramX client/SDK instead.
|
|
2326
|
+
* / ⟨API-101/DEC-101, 2026-08-24 — v3 phase X3⟩ RETURNS THE SAME RECEIPT THE FREE WRITER DOES.
|
|
2327
|
+
* / It answered `Wire.Result<Nat>`: the version, and nothing else. The free `writeMemory` returns
|
|
2328
|
+
* / `{ version; seq; head }`, so a PAYING writer got strictly LESS evidence than a caller who paid
|
|
2329
|
+
* / nothing — on the one rail a stranger can buy, where the receipt is the whole product. The head
|
|
2330
|
+
* / is what makes an append verifiable by someone who was not there; a bare version number is not
|
|
2331
|
+
* / checkable against anything.
|
|
2332
|
+
* /
|
|
2333
|
+
* / It cost nothing to fix: `r` was already in scope and already being read — the old body did
|
|
2334
|
+
* / `let v = r.version` and passed `r` to `receiptSuffix(r)` for the audit line, then discarded
|
|
2335
|
+
* / everything but the version on the way out. Free until the cut, breaking forever after, which
|
|
2336
|
+
* / is why it lands now rather than after the test migration (ruling R-A2).
|
|
2337
|
+
*/
|
|
2338
|
+
sessionAppendMemory: ActorMethod<[Voucher, string, Uint8Array | number[]], Result>;
|
|
2339
|
+
/**
|
|
2340
|
+
* / The whole engram in one call — newest-first, byte-capped — for an AI host to inject at session
|
|
2341
|
+
* / start. The "read me back" that continuity is built on. `clientLabel` names the reading host
|
|
2342
|
+
* / (e.g. "openclaw", "claude.ai") for the distinct-reader set.
|
|
2343
|
+
* /
|
|
2344
|
+
* / ⚠ AN UPDATE, NOT A QUERY, AND ON PURPOSE (L7). `readMemory`/`readMemoryBatch` are queries and
|
|
2345
|
+
* / therefore CANNOT persist a read count; this runs on the update path and bumps the reuse
|
|
2346
|
+
* / counters, so a builder whose SDK calls `startSession()` registers a weekly-reused engram as a
|
|
2347
|
+
* / byproduct of normal use rather than through an elective, separate read. Callers should expect
|
|
2348
|
+
* / update latency and consensus cost here, and get a recorded read in exchange.
|
|
2349
|
+
* /
|
|
2350
|
+
* / ⚠ IT DOES NOT RETURN EVERYTHING, and the omission is deliberate: `config/` and `secrets/` are
|
|
2351
|
+
* / SKIPPED. Those are operational, not agent memory, and must never be blindly spilled into a
|
|
2352
|
+
* / model's context window — so a caller must not treat this as a complete listing of the engram.
|
|
2353
|
+
* /
|
|
2354
|
+
* / ⚠ RAW STORED BYTES, like `readMemoryBatch`. On a Private (encrypted) engram the content is
|
|
2355
|
+
* / CIPHERTEXT; the key-holding SDK decrypts it. A caller without the key gets bytes it cannot
|
|
2356
|
+
* / read, not an error.
|
|
2357
|
+
*/
|
|
2358
|
+
sessionReadContext: ActorMethod<[string], Result_12>;
|
|
2359
|
+
/**
|
|
2360
|
+
* / Read one memory file against a PAID x402 session voucher. No role, no invite — the voucher is
|
|
2361
|
+
* / the authorization, which is what makes this the engram's one rail a stranger can pay to use.
|
|
2362
|
+
* /
|
|
2363
|
+
* / ⟨2026-09-30, ic402 2.17.0⟩ WHO MAY SPEND A SESSION: only its payer, calling as the same raw
|
|
2364
|
+
* / Ed25519 key that opened it. The voucher still carries the amount and the sequence; the
|
|
2365
|
+
* / authorization is now the call itself, and the canister no longer checks a voucher signature.
|
|
2366
|
+
* / A stranger can still pay to use this rail — by opening a session of their own.
|
|
2367
|
+
* / ⟨CORRECTED 2026-09-30, the owner's answer "2 fresh key"⟩ Not the payer: the session's own key
|
|
2368
|
+
* / — the fresh Ed25519 key the payer named at open — calling as itself. The payer, who opened
|
|
2369
|
+
* / the session and closes it, is refused here like anyone else who is not that key.
|
|
2370
|
+
* / ⟨CORRECTED 2026-09-30, review⟩ …unless the payer named their own identity key at open, which
|
|
2371
|
+
* / nothing refuses: then the payer IS that key and spends.
|
|
2372
|
+
* /
|
|
2373
|
+
* / ⚠ EVERY REFUSAL BELOW HAPPENS BEFORE THE VOUCHER IS CONSUMED, so **no funds move on any of
|
|
2374
|
+
* / them**. That is the property a payer most needs and the one a signature cannot express: a
|
|
2375
|
+
* / refusal here costs nothing, and retrying after the owner changes something costs nothing extra.
|
|
2376
|
+
* /
|
|
2377
|
+
* / It refuses when:
|
|
2378
|
+
* / · **Paid reads are not enabled — and they are OFF BY DEFAULT.** Selling the owner's memory to
|
|
2379
|
+
* / any voucher-bearer is a deliberate choice, not a default posture, so on a fresh engram this
|
|
2380
|
+
* / is the refusal you will get. `getEngramCard`'s `x402Support` reports this same flag, so a
|
|
2381
|
+
* / buyer can check before paying rather than discover it here.
|
|
2382
|
+
* / · **The engram is Private (client-side encrypted).** A paid session holds no key and the
|
|
2383
|
+
* / canister never decrypts, so it could only return ciphertext. Read through the EngramX
|
|
2384
|
+
* / client/SDK instead — this is not a permission problem and no setting fixes it.
|
|
2385
|
+
* / · **The path is `config/` or `secrets/`.** Owner-only on every other surface, and a paid
|
|
2386
|
+
* / session must not be the side door: without this guard a stranger holding a fraction-of-a-
|
|
2387
|
+
* / cent voucher could read `secrets/*`.
|
|
2388
|
+
* / · Payments are frozen on this engram.
|
|
2389
|
+
*/
|
|
2390
|
+
sessionReadMemory: ActorMethod<[Voucher, string], Result_11>;
|
|
2391
|
+
/**
|
|
2392
|
+
* / Configure action alerts: an https webhook that receives new chained-audit entries matching the
|
|
2393
|
+
* / enabled event classes (money / approvals / guardian / agentWrites), batched, at most one
|
|
2394
|
+
* / POST per minute. Owner-only. Payloads carry audit METADATA (operation, caller, role, bounded
|
|
2395
|
+
* / details) — never memory file contents. Setting a URL (re)arms delivery FROM NOW: the cursor
|
|
2396
|
+
* / jumps to the current end of the log so history is not replayed. Passing url = null disables.
|
|
2397
|
+
* / The URL itself is never written to the audit log (webhook URLs often embed secret tokens).
|
|
2398
|
+
*/
|
|
2399
|
+
setActionAlertConfig: ActorMethod<[AlertConfig], Result_1>;
|
|
2400
|
+
/**
|
|
2401
|
+
* / Owner-only: replace an existing agent's permission set. The way to NARROW what an agent
|
|
2402
|
+
* / may do without ending their access — `revokeAgent` is terminal for that principal, this is
|
|
2403
|
+
* / not.
|
|
2404
|
+
* /
|
|
2405
|
+
* / ⚠ ONE GRANT IS REFUSED OUTRIGHT: memory-read to the EngramX PLATFORM principal while this
|
|
2406
|
+
* / engram is Private (encrypted), because that principal could then derive the decryption key and
|
|
2407
|
+
* / Private mode would be a claim rather than a property. It is the mirror of the guard on
|
|
2408
|
+
* / `setEncryptionEnabled`, which refuses to ENABLE Private while that grant already exists —
|
|
2409
|
+
* / between them the invariant holds whichever order an owner works in.
|
|
2410
|
+
* /
|
|
2411
|
+
* / That refusal is `#Refused` ABOUT THE SUBJECT, not about the caller: the owner is authorized
|
|
2412
|
+
* / and the grantee is not eligible. It is standing rather than a conflict to resolve, so the way
|
|
2413
|
+
* / forward is to grant read to your own agents instead, or to switch to Connected mode first —
|
|
2414
|
+
* / both of which the message says.
|
|
2415
|
+
*/
|
|
2416
|
+
setAgentPermissions: ActorMethod<[Principal, AgentPermissions], Result_1>;
|
|
2417
|
+
/**
|
|
2418
|
+
* / Paths an agent holding a grant may REVISE rather than only append to.
|
|
2419
|
+
* /
|
|
2420
|
+
* / Matching is EXACT, except that an entry ending in "/" grants everything beneath it. A grant
|
|
2421
|
+
* / is a power, so the default reading is the narrow one; the directory form exists because the
|
|
2422
|
+
* / real use case is rotating dated files under a prefix, and per-file grants would be unusable
|
|
2423
|
+
* / for that. What a bare prefix would do — "MEMORY.md" also matching "MEMORY.md.bak" — is the
|
|
2424
|
+
* / kind of accident a permission surface must not have.
|
|
2425
|
+
*/
|
|
2426
|
+
setAgentRevisablePaths: ActorMethod<[Array<string>], Result_1>;
|
|
2427
|
+
/**
|
|
2428
|
+
* / ⟨0.16.0 — census row⟩ Returns the APPLIED config, which is how this closes the
|
|
2429
|
+
* / setter-without-a-getter gap without adding a method: the write is the read.
|
|
2430
|
+
* /
|
|
2431
|
+
* / `prunedBackups` is the part that matters. Enforcing a retention cap DELETES finalized backups
|
|
2432
|
+
* / beyond it, and this method used to answer `#Ok(())` over that — the module's own comment
|
|
2433
|
+
* / called it an "ops floor: retention enforcement deletes owner backup data silently", mitigated
|
|
2434
|
+
* / by a `Debug.print` nobody reads. An owner lowering the cap is destroying their own backups;
|
|
2435
|
+
* / they are told how many, in the reply and in the audit line.
|
|
2436
|
+
*/
|
|
2437
|
+
setBackupRetention: ActorMethod<[string, bigint], Result_10>;
|
|
2438
|
+
/**
|
|
2439
|
+
* / Override the caps for ONE caller — an agent this owner trusts more, or less, than the rest.
|
|
2440
|
+
*/
|
|
2441
|
+
setCallerSpendPolicy: ActorMethod<[Principal, SpendingPolicy], Result_1>;
|
|
2442
|
+
/**
|
|
2443
|
+
* / Owner-only: set how many engrams `agentPrincipal`'s agent may open of its own through this
|
|
2444
|
+
* / engram. Kept by the agent's lasting key, so it carries over a key replacement. Any count is
|
|
2445
|
+
* / accepted; the registry lets a lasting key open one engram through a parent, ever, so 1 or more
|
|
2446
|
+
* / behaves as 1. 0 withdraws it.
|
|
2447
|
+
* /
|
|
2448
|
+
* / APPROVING IS GIVING: what this engram attaches to open an engram (1.3 T cycles) is the agent's
|
|
2449
|
+
* / from the moment that engram exists — the agent's lasting key owns it, and nothing is ever taken
|
|
2450
|
+
* / back. The change is written to the record under `agent.childAllowance.set`, which is in the
|
|
2451
|
+
* / alerts' money class (`ActionAlerts.classify`), so an owner or guardian with an alert channel
|
|
2452
|
+
* / hears of it.
|
|
2453
|
+
*/
|
|
2454
|
+
setChildAllowance: ActorMethod<[Principal, bigint], Result_1>;
|
|
2455
|
+
/**
|
|
2456
|
+
* / ⟨0.16.0⟩ `getEncryptedMemoryKeyForEpoch` DELETED — folded into `getEncryptedMemoryKey`'s epoch
|
|
2457
|
+
* / argument — see that method for the fold and the `null`-means-CURRENT rule.
|
|
2458
|
+
* / Owner-only: turn client-side memory encryption (Private mode) on or off for FUTURE writes.
|
|
2459
|
+
* /
|
|
2460
|
+
* / ⚠ IT DOES NOT TOUCH EXISTING FILES, and this is the fact that decides whether calling it alone
|
|
2461
|
+
* / is safe. Verified at the site 2026-08-21: the body sets the flag and writes an audit line —
|
|
2462
|
+
* / there is no migration pass. So
|
|
2463
|
+
* / · turning it ON leaves everything already stored as PLAINTEXT at rest, and
|
|
2464
|
+
* / · turning it OFF leaves everything already stored as CIPHERTEXT, which the hosted connector
|
|
2465
|
+
* / cannot read.
|
|
2466
|
+
* / Either direction leaves a MIXED store that the flag alone misdescribes. The owner console
|
|
2467
|
+
* / pairs this call with a migration (`useMemoryEncryption`'s `migrate` / `migrateToPlaintext`)
|
|
2468
|
+
* / for exactly that reason; a caller reaching this method directly gets the flag and nothing else.
|
|
2469
|
+
* /
|
|
2470
|
+
* / ⚠ ENABLING IS REFUSED while the EngramX platform principal holds memory-read access as an
|
|
2471
|
+
* / agent — it could derive the decryption key, which would make Private mode a claim rather
|
|
2472
|
+
* / than a property. Revoke that agent's read access first. The refusal says so, and it is a
|
|
2473
|
+
* / `#Conflict` rather than a `#Refused` because the caller IS the owner and the problem is the
|
|
2474
|
+
* / engram's state, not their standing.
|
|
2475
|
+
* /
|
|
2476
|
+
* / Private mode also closes the paid read rail by construction: a paid session holds no key, so
|
|
2477
|
+
* / `sessionReadMemory` refuses on an encrypted engram whatever `setPaidMemoryReadEnabled` says.
|
|
2478
|
+
*/
|
|
2479
|
+
setEncryptionEnabled: ActorMethod<[boolean], Result_1>;
|
|
2480
|
+
/**
|
|
2481
|
+
* / Register the owner's EVM address for withdrawals.
|
|
2482
|
+
* /
|
|
2483
|
+
* / First set: immediate — no guardian needed.
|
|
2484
|
+
* / Change: only allowed if an active guardian exists (proving the owner
|
|
2485
|
+
* / has a safety net). Without a guardian, the address is locked after
|
|
2486
|
+
* / first set — this prevents a compromised II from silently redirecting
|
|
2487
|
+
* / EVM withdrawals when no one is watching.
|
|
2488
|
+
* /
|
|
2489
|
+
* / The guardian doesn't approve the change — the owner is sovereign.
|
|
2490
|
+
* / The guardian's existence is the gate, not their active consent.
|
|
2491
|
+
*/
|
|
2492
|
+
setEvmOwnerAddress: ActorMethod<[string], Result_1>;
|
|
2493
|
+
/**
|
|
2494
|
+
* / A guardian arms their OWN webhook over the guarded engram's audit stream (same event
|
|
2495
|
+
* / classes and payload as the owner channel — audit metadata, never memory file contents;
|
|
2496
|
+
* / the guardian honesty rail: integrity, not content). Active guardians only. Arming starts
|
|
2497
|
+
* / from NOW (no history replay); url = null disarms and frees the slot.
|
|
2498
|
+
*/
|
|
2499
|
+
setGuardianAlertConfig: ActorMethod<[AlertConfig], Result_1>;
|
|
2500
|
+
/**
|
|
2501
|
+
* / Per-prefix retention policy. Longest prefix wins; anything unmatched keeps everything.
|
|
2502
|
+
* /
|
|
2503
|
+
* / A CHANGE does not take effect immediately, in EITHER direction: every prefix whose EFFECTIVE
|
|
2504
|
+
* / class moves is guarded for the same window as the agent floor, so history cannot be
|
|
2505
|
+
* / thinned in the same sweep as the decision to thin it. Loosening waits too — distinguishing
|
|
2506
|
+
* / "tightened" from "loosened" precisely would mean comparing two cap lattices, so armGuards
|
|
2507
|
+
* / (RetentionPolicy.mo) guards any change it sees. That is the conservative reading, and its
|
|
2508
|
+
* / only cost is a delay on keeping MORE, which destroys nothing.
|
|
2509
|
+
*/
|
|
2510
|
+
setMemoryRetentionPolicy: ActorMethod<[Array<[string, RetentionClassSpec]>], Result_1>;
|
|
2511
|
+
/**
|
|
2512
|
+
* / Owner-only: open or close the monetized read rail. When disabled (the default), sessionReadMemory
|
|
2513
|
+
* / fails closed for every voucher-bearer — selling the owner's memory is opt-in, not the default.
|
|
2514
|
+
* /
|
|
2515
|
+
* / ⚠ ENABLING IT IS NOT SUFFICIENT. On a Private (encrypted) engram `sessionReadMemory` still
|
|
2516
|
+
* / refuses, because a paid session holds no key and the canister never decrypts — see
|
|
2517
|
+
* / `setEncryptionEnabled`. An owner who turns this on and still sees refusals should check that
|
|
2518
|
+
* / flag before looking anywhere else.
|
|
2519
|
+
* /
|
|
2520
|
+
* / `getEngramCard`'s `x402Support` reports THIS flag, so a buyer can read the rail's state before
|
|
2521
|
+
* / paying rather than discovering it in a refusal.
|
|
2522
|
+
*/
|
|
2523
|
+
setPaidMemoryReadEnabled: ActorMethod<[boolean], Result_1>;
|
|
2524
|
+
/**
|
|
2525
|
+
* / Open or close the paid-memory WRITE rail (RB4). Owner-only, like its read twin.
|
|
2526
|
+
* /
|
|
2527
|
+
* / Kept as a SEPARATE flag rather than widening `setPaidMemoryReadEnabled` into one switch: an
|
|
2528
|
+
* / owner selling read access has not thereby agreed to sell write access, and a single flag makes
|
|
2529
|
+
* / the larger permission ride in on the smaller one. Two flags is the shape that lets an owner
|
|
2530
|
+
* / say yes to one and no to the other, which is the common case.
|
|
2531
|
+
*/
|
|
2532
|
+
setPaidMemoryWriteEnabled: ActorMethod<[boolean], Result_1>;
|
|
2533
|
+
/**
|
|
2534
|
+
* / ⟨0.16.0, L1⟩ Every validation refusal here is `#Invalid` and the cap is `#Conflict`, and the
|
|
2535
|
+
* / split is worth stating once for the whole whole-value-config family below: a malformed path is
|
|
2536
|
+
* / the CALLER'S to fix and retrying with a corrected list works, while "max 20" is a property of
|
|
2537
|
+
* / this engram that no argument gets around. A caller that cannot tell those apart either edits
|
|
2538
|
+
* / forever or gives up on a request that was one character from valid.
|
|
2539
|
+
*/
|
|
2540
|
+
setProtectedPaths: ActorMethod<[Array<string>], Result_1>;
|
|
2541
|
+
/**
|
|
2542
|
+
* / OWNER-ONLY: switch the metrics reader's read of the seat weeks off (`false`) or back on (`true`).
|
|
2543
|
+
* / On from birth, by the owner's ruling of 2026-10-02. Off, `sysGetAgentSeatWeeks` refuses the
|
|
2544
|
+
* / reader by name, naming this switch; the rows are still kept and the owner still reads them. Each
|
|
2545
|
+
* / call is a chained record entry (`metrics.setSeatWeeksReadEnabled`, the new and the old value), so
|
|
2546
|
+
* / when the read was on or off is part of the record. Anyone else is refused by name.
|
|
2547
|
+
*/
|
|
2548
|
+
setSeatWeeksReadEnabled: ActorMethod<[boolean], Result_1>;
|
|
2549
|
+
/**
|
|
2550
|
+
* / Set the most this engram may spend per day ACROSS EVERY CALLER — five agents, the owner and the
|
|
2551
|
+
* / marketplace together. `null` removes the ceiling. ⟨2026-09-28⟩
|
|
2552
|
+
* / ⟨CORRECTED 2026-09-29, review finding X-8: "spend" was too wide. The ceiling covers the x402
|
|
2553
|
+
* / payments this engram signs (`signX402Payment` and the marketplace's `sysSignX402Payment`) and
|
|
2554
|
+
* / nothing else: it is the most this engram may sign in x402 payments per day. Two other signing
|
|
2555
|
+
* / paths are NOT counted against it — typed-data signatures (`signEip712` / `sysSignEip712`),
|
|
2556
|
+
* / bounded instead by each registered type's daily count and destination list; and agent-
|
|
2557
|
+
* / registration transactions (`signEngramRegistration`), bounded by three per caller per day and
|
|
2558
|
+
* / the 500-gwei gas ceiling. Whether the ceiling should cover them is a separate owner question.⟩
|
|
2559
|
+
* /
|
|
2560
|
+
* / WHY: the owner decided on 2026-09-28 to add one daily spending ceiling across all callers on an
|
|
2561
|
+
* / engram and keep the limit of five agents. Every other spending limit is per caller, so without
|
|
2562
|
+
* / this the engram's daily exposure was the SUM of up to seven allowances ($35.00 at the defaults)
|
|
2563
|
+
* / and nobody could see it. The amount is in the same minor units the per-caller caps compare
|
|
2564
|
+
* / (USDC's six decimals: 5_000_000 = $5.00), and like them it does not distinguish tokens.
|
|
2565
|
+
* /
|
|
2566
|
+
* / A payment that would take today's engram-wide total past this number is not signed: the caller
|
|
2567
|
+
* / gives a reason and it becomes a row in the approval queue, exactly as over a per-caller cap.
|
|
2568
|
+
* / `0` is allowed and means every payment needs the owner's approval.
|
|
2569
|
+
* / ⟨CORRECTED 2026-09-29, review finding X-2: not every payment — a payment of amount 0 crosses no
|
|
2570
|
+
* / limit, so it is signed under a ceiling of 0 too. Whether amount-0 payments should be refused is
|
|
2571
|
+
* / an open owner question.⟩ ⟨CORRECTED 2026-09-29, later — the owner ruled (follow-up 15, option A):
|
|
2572
|
+
* / a payment of amount 0 is now refused by name before any limit is read (`X402Input.refusal`), so
|
|
2573
|
+
* / under a ceiling of 0 every payment that can be signed at all does need the owner's approval.
|
|
2574
|
+
* / And a new engram no longer starts with no ceiling: it starts at `SpendCeiling.DEFAULT_ENGRAM_DAY`
|
|
2575
|
+
* / ($10.00 a day; follow-up 9, option A).⟩ Takes effect on the next
|
|
2576
|
+
* / payment, counted against what was ALREADY spent today (the total is kept whether or not a
|
|
2577
|
+
* / ceiling is set), so setting a ceiling at noon does not grant a fresh day.
|
|
2578
|
+
* /
|
|
2579
|
+
* / Unlike `setSpendPolicy`, this does NOT auto-approve pending requests it now covers — a request
|
|
2580
|
+
* / held by the ceiling waits for `approveRequest`, or the caller retries against the new ceiling.
|
|
2581
|
+
* / The auto-approval exists for per-caller raises and is kept away from the ceiling on purpose
|
|
2582
|
+
* / (see `resolvePendingOnPolicyRaise`).
|
|
2583
|
+
* /
|
|
2584
|
+
* / The record entry `spend.setCeiling` carries the new AND the previous value, so a widening is
|
|
2585
|
+
* / distinguishable from a tightening afterwards — the reason `spend.setPolicy` records its limits.
|
|
2586
|
+
* / Not blocked by a payments freeze, like `setSpendPolicy`: setting a limit moves no money.
|
|
2587
|
+
*/
|
|
2588
|
+
setSpendCeiling: ActorMethod<[[] | [bigint]], Result_1>;
|
|
2589
|
+
/**
|
|
2590
|
+
* / Set this engram's spending caps.
|
|
2591
|
+
* /
|
|
2592
|
+
* / The audit row records the LIMITS, not merely that a change happened, so a WIDENING is
|
|
2593
|
+
* / distinguishable from a tightening afterwards. A quiet policy raise is the shape most custody
|
|
2594
|
+
* / incidents take, and "policy changed" alone cannot tell an investigator which way it moved.
|
|
2595
|
+
* /
|
|
2596
|
+
* / Raising a cap RESOLVES pending approval requests it now covers — that is the second half of
|
|
2597
|
+
* / the escalation an agent starts when it hits a limit, and without it the queue is a place
|
|
2598
|
+
* / requests go to expire.
|
|
2599
|
+
*/
|
|
2600
|
+
setSpendPolicy: ActorMethod<[SpendingPolicy], Result_1>;
|
|
2601
|
+
/**
|
|
2602
|
+
* / Owner-only: set YOUR OWN safety rails on the funding path — a per-top-up ckUSDC ceiling and a
|
|
2603
|
+
* / minimum gap between top-ups. Read them back with `getTopUpLimits`.
|
|
2604
|
+
* /
|
|
2605
|
+
* / ⚠ THESE ARE THE OWNER'S LIMITS, NOT THE PLATFORM'S. "Limits" reads like something imposed;
|
|
2606
|
+
* / nothing outside this engram sets them, and an owner may raise them at will. They exist so a
|
|
2607
|
+
* / compromised agent key or a runaway agent cannot drain a wallet in one call or in a fast loop,
|
|
2608
|
+
* / which is a bound on YOUR OWN blast radius rather than on what you are permitted to spend.
|
|
2609
|
+
* /
|
|
2610
|
+
* / The cooldown defaults to five minutes. `cooldownSeconds = 0` removes the gap entirely, which
|
|
2611
|
+
* / is a real choice and not an error.
|
|
2612
|
+
* / ⟨API-105, 2026-08-24 — v3 phase X3⟩ ONE RECORD, NOT TWO ADJACENT NATS. This took
|
|
2613
|
+
* / `(newMaxCkusdcE6s : Nat, cooldownSeconds : Nat)` — the documented swap class, and a live one:
|
|
2614
|
+
* / the suite calls `setTopUpLimits(10_000_000n, 300n)`, and a caller who transposes those gets a
|
|
2615
|
+
* / 300-e6 cap with a 116-DAY cooldown. Candid matches positionally and both are `nat`, so the
|
|
2616
|
+
* / wire accepts it, the types accept it, and the engram is quietly unable to top itself up.
|
|
2617
|
+
* /
|
|
2618
|
+
* / The field names are NOT a new vocabulary — they are `getTopUpLimits`'s, which already answers
|
|
2619
|
+
* / `{ cooldownSeconds; maxCkusdcE6s }`. Setter and getter now share one shape, so read-modify-
|
|
2620
|
+
* / write is expressible and neither side can drift from the other without the compiler saying so.
|
|
2621
|
+
*/
|
|
2622
|
+
setTopUpLimits: ActorMethod<[{ cooldownSeconds: bigint; maxCkusdcE6s: bigint }], Result_1>;
|
|
2623
|
+
/**
|
|
2624
|
+
* / Owner sets the World ID app_id + action + rp_id from their World Developer Portal (rp_id appears
|
|
2625
|
+
* / after "Enable World ID 4.0" on a production app). The action MUST be configured there with
|
|
2626
|
+
* / max_verifications = Unlimited (idempotent /verify → survives IC consensus). After setting this,
|
|
2627
|
+
* / register getWorldIdRpSignerAddress() as the rp_id's signer address in the Portal.
|
|
2628
|
+
*/
|
|
2629
|
+
setWorldIdConfig: ActorMethod<[string, string, string], Result_1>;
|
|
2630
|
+
/**
|
|
2631
|
+
* / Submit a verified-human proof: the IDKitResult from the frontend's World ID flow, forwarded
|
|
2632
|
+
* / VERBATIM (compact JSON, as JSON.stringify emits) to World's /api/v4/verify/{rp_id} over an HTTPS
|
|
2633
|
+
* / outcall (never trust the client). The v4 endpoint verifies both 4.0 proofs and legacy 3.0 proofs,
|
|
2634
|
+
* / so the OrbLegacy migration path and the 4.0 endgame ride the same method. Owner-only. `nullifier`
|
|
2635
|
+
* / is the claimed unique-human pseudonym; it must appear verbatim inside resultJson, binding what we
|
|
2636
|
+
* / store to the payload the verifier actually accepted. Only proof_of_human credentials are accepted
|
|
2637
|
+
* / (selfie is farmable, passport/mnc are document identity — a different tier). Sets worldIdVerified
|
|
2638
|
+
* / and stores the result ONLY on a real verification success — never self-asserted.
|
|
2639
|
+
*/
|
|
2640
|
+
setWorldIdProof: ActorMethod<[string, string], Result_1>;
|
|
2641
|
+
/**
|
|
2642
|
+
* / Sign a registered type. ONE call, owner-only, freeze-gated — the delay lives on registration
|
|
2643
|
+
* / (D2), never here: an emergency withdrawal must not need two owner round-trips.
|
|
2644
|
+
* /
|
|
2645
|
+
* / ⟨0.16.0⟩ PERSISTS beside the market's `sysSignEip712` (census row 177, ruled). The owner does
|
|
2646
|
+
* / not lose the ability to sign because a marketplace gained it, and the two share every control
|
|
2647
|
+
* / below the caller gate.
|
|
2648
|
+
*/
|
|
2649
|
+
signEip712: ActorMethod<[Uint8Array | number[], Array<[string, Eip712Value]>], Result_4>;
|
|
2650
|
+
/**
|
|
2651
|
+
* / Sign the engram's own ERC-8004 registration tx for client-side broadcast: the engram signs, the client
|
|
2652
|
+
* / broadcasts and keeps the resulting registration id.
|
|
2653
|
+
* /
|
|
2654
|
+
* / Agent-accessible. The comment here claimed "saves ~55-85M cycles vs registerAgent" until
|
|
2655
|
+
* / 2026-08-17; `registerAgent` — the engram method that broadcast the registration itself — left
|
|
2656
|
+
* / the candid surface in commit d25b53b, so the comparison had outlived its other term. The
|
|
2657
|
+
* / saving was real and is now simply the shape of this method: no RPC outcall, no receipt poll.
|
|
2658
|
+
* / ⟨API-105, 2026-08-24 — v3 phase X3⟩ ONE REQUEST RECORD, not three adjacent nats.
|
|
2659
|
+
* /
|
|
2660
|
+
* / ⟨Ruling R-B3⟩ This method KEEPS. Census row 309 dispositions it `die` ("test-only; folds into
|
|
2661
|
+
* / signEip712 + registered type") and row 311 records the owner's answer: RULED 2026-08-20 —
|
|
2662
|
+
* / KEEP, ERC-8004 stays. Both halves of the `die` rationale fail at the site: it is not
|
|
2663
|
+
* / test-only (a downstream web client's billing page calls it), and it is not a shipped customer
|
|
2664
|
+
* / capability either — that panel sits behind `evmBilling: { mode: 'off' }` in both the flag
|
|
2665
|
+
* / defaults and the shipped config, and its own dialog says the signature is dormant and not
|
|
2666
|
+
* / broadcastable. It is a real surface in a disabled state, which is neither thing the census
|
|
2667
|
+
* / row claimed.
|
|
2668
|
+
* /
|
|
2669
|
+
* / THE SWAP CLASS, and here it is three-deep: `nonce`, `maxFeePerGas` and `maxPriorityFeePerGas`
|
|
2670
|
+
* / were adjacent and all `Nat`. Transposing the two gas fields type-checks, decodes, and signs a
|
|
2671
|
+
* / transaction whose priority fee exceeds its max fee — invalid on chain, and the 500-gwei
|
|
2672
|
+
* / ceiling below cannot see it because both values are individually under the cap. Named fields
|
|
2673
|
+
* / remove the class.
|
|
2674
|
+
* /
|
|
2675
|
+
* / ⟨2026-09-28⟩ LIMITED PER CALLER PER DAY. The owner decided to cap this signature rather than
|
|
2676
|
+
* / delete it: each caller (the owner, or an active agent) may obtain
|
|
2677
|
+
* / `EngramRegCap.MAX_PER_CALLER_PER_DAY` registration signatures per UTC day; the next is refused
|
|
2678
|
+
* / with `#Conflict` naming this method. A signature that fails does not count. The `nonce` must
|
|
2679
|
+
* / be the REGISTRATION address's nonce — `getEvmAddress().engramRegistration` — below 2^64 − 1.
|
|
2680
|
+
*/
|
|
2681
|
+
signEngramRegistration: ActorMethod<
|
|
2682
|
+
[
|
|
2683
|
+
{
|
|
2684
|
+
maxFeePerGas: bigint;
|
|
2685
|
+
nonce: bigint;
|
|
2686
|
+
maxPriorityFeePerGas: bigint;
|
|
2687
|
+
},
|
|
2688
|
+
],
|
|
2689
|
+
Result_9
|
|
2690
|
+
>;
|
|
2691
|
+
/**
|
|
2692
|
+
* / Sign an EIP-3009 authorization for x402 payment. Agent-accessible.
|
|
2693
|
+
* / Client probes the URL, extracts chain/token/recipient/amount from the 402, and calls this.
|
|
2694
|
+
* / Canister signs → returns header → client retries with header.
|
|
2695
|
+
* /
|
|
2696
|
+
* / ⟨0.16.0⟩ PERSISTS beside the market's `sysSignX402Payment` (census row 177, ruled). An agent
|
|
2697
|
+
* / with an x402 rail does not lose it because a marketplace gained one, and both run the same body.
|
|
2698
|
+
* / ⟨API-105, 2026-08-24 — v3 phase X3⟩ ONE REQUEST RECORD, not eight positional arguments.
|
|
2699
|
+
* /
|
|
2700
|
+
* / THE HAZARD IS FUNDS MISDIRECTION, and it is the sharpest case in this batch. `tokenAddress`
|
|
2701
|
+
* / and `recipient` were ADJACENT and both `Text`. Candid matches positionally, so transposing
|
|
2702
|
+
* / them type-checks, decodes, and signs a payment whose payee is the TOKEN CONTRACT rather than
|
|
2703
|
+
* / the intended one — an irreversible outbound signature spending the engram's own key, with
|
|
2704
|
+
* / nothing between the mistake and the money. `tokenName`/`tokenVersion` are a second adjacent
|
|
2705
|
+
* / Text pair; that one only corrupts the EIP-712 domain, so it fails loudly instead.
|
|
2706
|
+
* /
|
|
2707
|
+
* / Named fields remove the class outright: a transposition is now a decode error at the edge.
|
|
2708
|
+
* /
|
|
2709
|
+
* / The body is UNCHANGED. Each parameter was referenced exactly once below, so the record is
|
|
2710
|
+
* / destructured on entry rather than threaded through — the diff is the signature and this line,
|
|
2711
|
+
* / which is what makes a reshape of a money path reviewable.
|
|
2712
|
+
*/
|
|
2713
|
+
signX402Payment: ActorMethod<
|
|
2714
|
+
[
|
|
2715
|
+
{
|
|
2716
|
+
tokenVersion: string;
|
|
2717
|
+
tokenAddress: string;
|
|
2718
|
+
approvalId: [] | [string];
|
|
2719
|
+
recipient: string;
|
|
2720
|
+
rationale: [] | [string];
|
|
2721
|
+
tokenName: string;
|
|
2722
|
+
chainId: bigint;
|
|
2723
|
+
amount: bigint;
|
|
2724
|
+
},
|
|
2725
|
+
],
|
|
2726
|
+
Result_3
|
|
2727
|
+
>;
|
|
2728
|
+
/**
|
|
2729
|
+
* / Self-heal: if the registry's spawn-time push was missed, the owner pulls the number from
|
|
2730
|
+
* / the spawning registry. Idempotent; fails closed if the registry has no record.
|
|
2731
|
+
*/
|
|
2732
|
+
syncEngramNumber: ActorMethod<[], Result_8>;
|
|
2733
|
+
/**
|
|
2734
|
+
* / Genesis seed — the atomic "spawn only when there's real content" primitive. The spawning
|
|
2735
|
+
* / REGISTRY pushes the owner's first real memory immediately after install, so a canister is
|
|
2736
|
+
* / never spawned holding nothing (see the registry's `provisionEngram` optional genesis).
|
|
2737
|
+
* /
|
|
2738
|
+
* / Gated `spawnedBy`-only and ONE-SHOT: it refuses once any file exists, so it can seed and never
|
|
2739
|
+
* / overwrite. Unlike the owner-only `seedMemory` placeholder this is REAL owner content, so it
|
|
2740
|
+
* / IS counted as an owner write (`firstWriteAt`, `totalMemoryWrites`) and is authored by the
|
|
2741
|
+
* / OWNER rather than by the registry principal that called it. It never touches the
|
|
2742
|
+
* / agent metrics.
|
|
2743
|
+
* /
|
|
2744
|
+
* / ⚠ THE PAYLOAD IS `Nat` AND MUST STAY `Nat`, which is a constraint on any client of this
|
|
2745
|
+
* / method rather than an internal detail. Its only caller is the registry, over an
|
|
2746
|
+
* / inter-canister boundary, through a hand-declared actor type — and the registry is ROUTINELY a
|
|
2747
|
+
* / different version from the engram template it is seeding: it upgrades before the fleet does,
|
|
2748
|
+
* / and during a transition it can serve a template older than itself. A return-type change here
|
|
2749
|
+
* / breaks genesis provisioning across that skew. That is measured, not predicted: the registry
|
|
2750
|
+
* / trapped with "IDL error: unexpected IDL type when parsing Nat" while seeding an engram built
|
|
2751
|
+
* / at the staging tag. A receipt would buy nothing anyway — the caller does `ignore await`.
|
|
2752
|
+
* /
|
|
2753
|
+
* / ⚠ ORDERING: upload the engram TEMPLATE first, then upgrade the registry. The reverse leaves a
|
|
2754
|
+
* / window where a spawn seeds an old-shape engram with a new-shape expectation; the reply fails
|
|
2755
|
+
* / to decode and `provisionEngram` dies on a trap its own `try/catch` cannot reach (ADR-0001),
|
|
2756
|
+
* / failing the WHOLE SPAWN rather than just the seed.
|
|
2757
|
+
*/
|
|
2758
|
+
sysApplyGenesisSeed: ActorMethod<[string, Uint8Array | number[]], Result_8>;
|
|
2759
|
+
/**
|
|
2760
|
+
* / OWNER force-close, for a session the payer abandoned.
|
|
2761
|
+
* /
|
|
2762
|
+
* / ⟨R1b, ruled 2026-08-26: owner-gated, NO guardian.⟩ It moves someone else's money, and only ever
|
|
2763
|
+
* / BACK TO THEM — the destination is the session's own payer and is not caller-influenced, so the
|
|
2764
|
+
* / guardian ceremony that guards destination changes buys nothing here and would strand payers on
|
|
2765
|
+
* / engrams that have no guardian.
|
|
2766
|
+
* /
|
|
2767
|
+
* / Calls the gateway's NO-AUTH variant deliberately. `gate.closeSession` is payer-only, which is
|
|
2768
|
+
* / why the market's admin-gated `forceCloseSession` could never work: it authorised an admin and
|
|
2769
|
+
* / then delegated to a method that rejects everyone but the payer.
|
|
2770
|
+
* /
|
|
2771
|
+
* / ⟨NOTE 2026-10-02 — NOT RENAMED, deliberately, and this is the one `sys` method that still has a
|
|
2772
|
+
* / human caller.⟩ The sys-tier retier (ruled 2026-08-24, executed 2026-10-02 on the registry and
|
|
2773
|
+
* / the market) named FOUR admin-called methods; this one became owner-gated two days after that
|
|
2774
|
+
* / list was made, so the ruling never named it. Its caller is the OWNER, a person, which is the
|
|
2775
|
+
* / exact thing the retier removes from the `sys` tier — so "a `sys` method has no human caller"
|
|
2776
|
+
* / stays false here until it is renamed too. Left for the owner: the rename is free until the cut
|
|
2777
|
+
* / and a break after it, and it also moves `packages/client/README.md` and
|
|
2778
|
+
* / `docs/AGENT-ONBOARDING.md`, which name it.
|
|
2779
|
+
*/
|
|
2780
|
+
sysForceCloseSession: ActorMethod<[string], Result_1>;
|
|
2781
|
+
/**
|
|
2782
|
+
* / The metrics reader the registry designated reads every engagement's seat weeks, in one call.
|
|
2783
|
+
* /
|
|
2784
|
+
* / CALLER: the metrics reader the spawning registry named on this engram (`metricsReaderId`), and
|
|
2785
|
+
* / nobody else — not the owner (who reads `getAgentSeatWeeks`), an agent, a guardian, the registry,
|
|
2786
|
+
* / the biller or the market (ADR-0020: a `sys` method names its caller). Answered only while the
|
|
2787
|
+
* / owner leaves it on (`seatWeeksReadEnabled`, on from birth by the owner's ruling of 2026-10-02).
|
|
2788
|
+
* /
|
|
2789
|
+
* / WHAT LEAVES: per engagement, the pairing day, the first and last payment-signature days, the
|
|
2790
|
+
* / 64-week map and the count — NO root, NO invite, NO amount, recipient or nonce. The reader matches
|
|
2791
|
+
* / rows to the registry's engagements by day, so no agent's identity leaves this engram here.
|
|
2792
|
+
* /
|
|
2793
|
+
* / ⟨L7⟩ UPDATE, NOT QUERY, so a refusal leaves its `sysGetAgentSeatWeeks.denied` row naming the
|
|
2794
|
+
* / caller's class, and an answered read leaves a `sysGetAgentSeatWeeks` row in the read log — the
|
|
2795
|
+
* / owner can see every time the reader read. A refusal is `#Refused` naming this method and the
|
|
2796
|
+
* / class (`SeatWeeks.readRefusal`), never an empty list: an empty list is a real answer ("no agent
|
|
2797
|
+
* / has paired here"), and a fabricated one would be counted as one.
|
|
2798
|
+
*/
|
|
2799
|
+
sysGetAgentSeatWeeks: ActorMethod<[], Result_7>;
|
|
2800
|
+
/**
|
|
2801
|
+
* / The metrics reader the registry designated reads this engram's paid-rail health, in one call:
|
|
2802
|
+
* / the balance and the line it must stay above, the memory that line is computed from, the sessions
|
|
2803
|
+
* / by state, the escrow open sessions hold, the vouchers spent and the refused ones
|
|
2804
|
+
* / (`RailHealth.RailHealth` says what each is, and what is never in it).
|
|
2805
|
+
* /
|
|
2806
|
+
* / CALLER: the metrics reader the spawning registry named on this engram (`metricsReaderId`), and
|
|
2807
|
+
* / nobody else — the owner reads its balance through `getOwnerConsole`. Answered only while the
|
|
2808
|
+
* / owner leaves that reader's read on (`seatWeeksReadEnabled`): the SAME gate and the SAME switch
|
|
2809
|
+
* / as `sysGetAgentSeatWeeks`, because it is the same reader and the owner has one switch over it.
|
|
2810
|
+
* /
|
|
2811
|
+
* / A QUERY, AND A DEPARTURE FROM THE SYS METHODS BESIDE IT, ON PURPOSE ⟨2026-10-02⟩. It is read
|
|
2812
|
+
* / every hour, and as an update it would leave a row in this engram's read log every hour — about
|
|
2813
|
+
* / 720 a month in a record whose rows are what its owner reads. What a query cannot do is write the
|
|
2814
|
+
* / denial row of a refusal (a query's writes are discarded) — the trade `getOwnerConsole` makes. A
|
|
2815
|
+
* / refusal is still `#Err(#Refused …)` naming this method and the caller's class
|
|
2816
|
+
* / (`RailHealth.readRefusal`), never a zero balance: a made-up zero would read as an engram about
|
|
2817
|
+
* / to freeze. Called by another canister, a query runs replicated and this engram pays for it —
|
|
2818
|
+
* / a few million cycles an hour, the cost of being watched.
|
|
2819
|
+
*/
|
|
2820
|
+
sysGetRailHealth: ActorMethod<[], Result_6>;
|
|
2821
|
+
/**
|
|
2822
|
+
* / The cashier reads how many signatures this engram has produced, per caller and in total.
|
|
2823
|
+
* / ⟨2026-09-28⟩ The owner's decision of that date: a running counter on the engram, exported to
|
|
2824
|
+
* / the cashier — and to nobody else (`AccessControl.requireCashierForSignatureCounts`).
|
|
2825
|
+
* /
|
|
2826
|
+
* / ONE NEW METHOD ON THE ENGRAM, not a field on the registry's `sysMeterEngram` reply. The study
|
|
2827
|
+
* / ruled out widening that reply to protect deployed clients, and that reason is gone (nothing is
|
|
2828
|
+
* / launched; the next release reinstalls every canister). The deciding fact is a different one,
|
|
2829
|
+
* / read at the site: `sysMeterEngram` is the REGISTRY's method and answers from the management
|
|
2830
|
+
* / canister's `canister_status` — the registry holds no signature count. Carrying the count in its
|
|
2831
|
+
* / reply would add a registry-to-engram call inside the meter and a second trust hop between the
|
|
2832
|
+
* / counter and the biller. The cashier is already the engram's recognised biller (`cashierId`) and
|
|
2833
|
+
* / already calls it directly (`sysRecordFeeEvent`), so it reads the count at the source.
|
|
2834
|
+
* /
|
|
2835
|
+
* / UPDATE, NOT QUERY, so that a refusal leaves its `sysGetSignatureCounts.denied` row: a refused
|
|
2836
|
+
* / query cannot write one (see `Gated.mo`'s header). A refusal is `#Refused` naming this method,
|
|
2837
|
+
* / never an empty list or a zero — a zero is a real answer, and a fabricated one would be billed.
|
|
2838
|
+
* /
|
|
2839
|
+
* / ⟨2026-09-29⟩ Each row names the key, the agent it was enrolled under (none for the owner and
|
|
2840
|
+
* / the marketplace) and the role, so one agent's keys can be added up. And a limit for whoever
|
|
2841
|
+
* / bills from this: the number comes from a canister its owner controls and can reinstall, so bill
|
|
2842
|
+
* / only engrams the registry confirms run published code, and read a lower count than last time as
|
|
2843
|
+
* / a reinstall — the reasoning is at `signaturesByCaller`.
|
|
2844
|
+
*/
|
|
2845
|
+
sysGetSignatureCounts: ActorMethod<[], Result_5>;
|
|
2846
|
+
/**
|
|
2847
|
+
* / Rent lifecycle notice — how the OWNER (not the agent) learns their subscription lapsed. D6
|
|
2848
|
+
* / shipped the handoff but every alarm it added talks to the operating service's watchdog; the
|
|
2849
|
+
* / doc named the debt plainly: "an owner learns of their own lapse only by looking." This closes
|
|
2850
|
+
* / it through the channel the owner already has: the entry lands in the audit log under `rent.*`,
|
|
2851
|
+
* / ActionAlerts classifies that as #money (default ON), and the drain delivers it to the owner's
|
|
2852
|
+
* / webhook. No new channel, no new config — an owner who armed alerts gets told.
|
|
2853
|
+
* /
|
|
2854
|
+
* / Gated exactly like sysRecordFeeEvent (spawnedBy or cashierId): the sweep is the only thing that
|
|
2855
|
+
* / OBSERVES the transition, so it is the only thing that can report it. The state whitelist is
|
|
2856
|
+
* / closed — this is a lifecycle feed, not a free-text push surface into the owner's audit chain.
|
|
2857
|
+
*/
|
|
2858
|
+
sysNotifyRentLifecycle: ActorMethod<[string, string], Result_1>;
|
|
2859
|
+
/**
|
|
2860
|
+
* / ⟨0.16.0⟩ `getWalletActivation()` DELETED — folded to `about().walletActivatedAtNs`, with its
|
|
2861
|
+
* / custody-posture rationale carried onto the field. "Can this thing hold money" is a question a
|
|
2862
|
+
* / counterparty is entitled to ask before dealing with an engram, which is why it stays public.
|
|
2863
|
+
* / ⟨0.16.0, sys tier⟩ THE MARKET TELLING CUSTODY, which is the half of the wallet-activation
|
|
2864
|
+
* / story the engram cannot see for itself.
|
|
2865
|
+
* /
|
|
2866
|
+
* / B1 moved the storefront to the market, so listing an endpoint — a seller offering to be paid —
|
|
2867
|
+
* / happens on a canister this one does not observe. `walletActivatedAt` exists to raise a custody
|
|
2868
|
+
* / decision (a wallet-bearing engram is sovereign-by-default and its owner has a claimSovereignty
|
|
2869
|
+
* / still to complete), and a seller who has never derived an EVM address would have gone
|
|
2870
|
+
* / unstamped forever. That is the under-reporting direction, which is the harmful one: a missing
|
|
2871
|
+
* / flag retires a decision that is still pending.
|
|
2872
|
+
* /
|
|
2873
|
+
* / ONE METHOD, NOT A FAMILY (L6). The other surface the old comment named — opening a payment
|
|
2874
|
+
* / session — is NOT here and is not an omission: measured at the market 2026-08-20, `openSession`'s
|
|
2875
|
+
* / caller is a BUYER, and a buying engram signs with a key it derived through `getEvmAddress`,
|
|
2876
|
+
* / which stamps. It is already marked before it can pay. Adding a case for it would be surface
|
|
2877
|
+
* / bought for a gap that does not exist.
|
|
2878
|
+
* /
|
|
2879
|
+
* / THE SURFACE WHITELIST IS CLOSED, exactly as `sysNotifyRentLifecycle`'s state whitelist is, and
|
|
2880
|
+
* / for the same reason: this is a lifecycle feed, not a free-text push into the owner's audit
|
|
2881
|
+
* / chain. The market is trusted to REPORT, never to compose what the owner reads.
|
|
2882
|
+
* /
|
|
2883
|
+
* / IDEMPOTENT AND SILENT WHEN ALREADY STAMPED. `markWalletActivated` returns early once the var is
|
|
2884
|
+
* / set, so a second notice writes nothing and still answers `#Ok` — a retry learns it succeeded
|
|
2885
|
+
* / rather than that it failed. The stamp keeps the FIRST wallet-bearing moment, which is the one a
|
|
2886
|
+
* / custody audit wants; a later notice must not overwrite it with its own time.
|
|
2887
|
+
* /
|
|
2888
|
+
* / The audit line records this engram as the subject, and `surface=endpoint-listed` is what names
|
|
2889
|
+
* / the origin: only the configured market can pass that value, so the line cannot be produced by
|
|
2890
|
+
* / any other caller.
|
|
2891
|
+
*/
|
|
2892
|
+
sysNotifyWalletActivity: ActorMethod<[string], Result_1>;
|
|
2893
|
+
/**
|
|
2894
|
+
* / The rent RECEIPT seam (B2): the cashier tells this engram that money moved on its behalf, and
|
|
2895
|
+
* / the engram appends a `fee.recorded` line to its own audit chain. It computes nothing.
|
|
2896
|
+
* /
|
|
2897
|
+
* / ⚠ GATED TO TWO PRINCIPALS AND NEITHER IS THE OWNER — the SPAWNING REGISTRY or the CONFIGURED
|
|
2898
|
+
* / CASHIER. An owner cannot write their own fee receipts, which is the point: a receipt an owner
|
|
2899
|
+
* / could forge is not evidence. `getBillerId` publishes which cashier this engram accepts, so the
|
|
2900
|
+
* / same fact is checkable from outside.
|
|
2901
|
+
* /
|
|
2902
|
+
* / This is the whole of what B2 left on the engram. Entitlement, custody and fee math live on the
|
|
2903
|
+
* / cashier; here there is an append-only record and no arithmetic — so a disagreement between the
|
|
2904
|
+
* / two is visible rather than reconciled silently.
|
|
2905
|
+
* / ⟨API-105/ARCH-108, 2026-08-24 — v3 phase X3⟩ ONE FEE-EVENT RECORD, not three positional
|
|
2906
|
+
* / arguments. ARCH-108 records that the census prescribed this fold and it "was refused for a
|
|
2907
|
+
* / wire-break reason the ruling voids", with the instruction to execute it or ratify
|
|
2908
|
+
* / positional-forever with a dated note — "silence spends the window". Executed.
|
|
2909
|
+
* /
|
|
2910
|
+
* / The argument for a record here is EVOLUTION, not transposition: unlike `setTopUpLimits`'s two
|
|
2911
|
+
* / adjacent nats, these three types differ, so a swap would not type-check. What positional
|
|
2912
|
+
* / arguments cost is the next field. A fee event is exactly the shape that grows one — token,
|
|
2913
|
+
* / amount, rate — and ADR-0018's rule is that an INBOUND record gains optional fields forever
|
|
2914
|
+
* / while an argument LIST cannot gain anything without breaking every caller at once.
|
|
2915
|
+
* /
|
|
2916
|
+
* / ⚠ ALL FOUR CALLERS MOVE IN THE SAME CHANGE, and this is ADR-0001's fatal direction: three
|
|
2917
|
+
* / inline hand-IDLs in the cashier and one in the registry declare this method's argument shape
|
|
2918
|
+
* / structurally. Every one of them sits inside `try { … } catch (_e) {}`, which reads as
|
|
2919
|
+
* / containment and is not: a reply-decode mismatch calls `ic0.trap` INSIDE the caller's own
|
|
2920
|
+
* / callback, and Motoko's `catch` sees rejects, never traps. That is the failure that took
|
|
2921
|
+
* / production monitoring dark for ~33h. The ENGRAM WASM MUST SHIP BEFORE its callers, and
|
|
2922
|
+
* / `check-didc-compat` is suspended for the cut, so nothing mechanical will catch a wrong order.
|
|
2923
|
+
*/
|
|
2924
|
+
sysRecordFeeEvent: ActorMethod<
|
|
2925
|
+
[
|
|
2926
|
+
{
|
|
2927
|
+
paidThroughNs: [] | [bigint];
|
|
2928
|
+
cycles: bigint;
|
|
2929
|
+
scheduleVersion: [] | [string];
|
|
2930
|
+
},
|
|
2931
|
+
],
|
|
2932
|
+
Result_1
|
|
2933
|
+
>;
|
|
2934
|
+
/**
|
|
2935
|
+
* / Point this engram at the biller that converts its tokens → cycles. Settable, not hardcoded:
|
|
2936
|
+
* / coupling is by principal id, so the same wasm runs against any deployment's biller.
|
|
2937
|
+
* /
|
|
2938
|
+
* / ⟨0.16.0, B2⟩ Renamed from `setCashierId`, and NARROWED to the spawning registry (census row
|
|
2939
|
+
* / 266, ruled). Two changes, for two reasons:
|
|
2940
|
+
* / · "cashier" is a PLATFORM word and this is the OSS wire. `biller` names the role, not the
|
|
2941
|
+
* / product that fills it.
|
|
2942
|
+
* / · The write is now sys-tier. It previously accepted the OWNER as well, and that second
|
|
2943
|
+
* / writer is what the ruling removed — three writers for one field (owner, spawner, and the
|
|
2944
|
+
* / frontend acting for the owner) is a last-write-wins race over a money-routing target.
|
|
2945
|
+
* /
|
|
2946
|
+
* / ⚠ THE COST, RULED AND ACCEPTED: an engram whose registry never set this has NO owner remedy.
|
|
2947
|
+
* / `convertEarningsToCycles` fails closed against a null biller, and with the owner leg gone
|
|
2948
|
+
* / nobody but the spawning registry can fix it. That refusal therefore names the real remedy
|
|
2949
|
+
* / rather than telling an owner to run a call they can no longer make.
|
|
2950
|
+
*/
|
|
2951
|
+
sysSetBillerId: ActorMethod<[Principal], Result_1>;
|
|
2952
|
+
/**
|
|
2953
|
+
* / One-shot assignment of the spawn ordinal — callable ONLY by the spawning registry, ONLY
|
|
2954
|
+
* / while unset. Neither the owner nor any later registry can change an assigned number.
|
|
2955
|
+
*/
|
|
2956
|
+
sysSetEngramNumber: ActorMethod<[bigint], Result_1>;
|
|
2957
|
+
/**
|
|
2958
|
+
* / Point this engram at the commerce satellite allowed to ask it for signatures. ⟨0.16.0, B1⟩
|
|
2959
|
+
* /
|
|
2960
|
+
* / SAME AUTHORITY AS `sysSetBillerId`, and for a stronger reason. That one routes money; this one
|
|
2961
|
+
* / confers the capability to ask this canister to sign with its own tECDSA key. Three writers for
|
|
2962
|
+
* / one field would be a last-write-wins race over a SIGNING target — so the spawning registry is
|
|
2963
|
+
* / the only writer, and an engram with no registry has no market to be pointed at.
|
|
2964
|
+
* /
|
|
2965
|
+
* / The same accepted cost applies, one notch sharper: an engram whose registry never set this can
|
|
2966
|
+
* / never be sold through the market, and no owner action fixes it. Both `sysSign*` methods refuse
|
|
2967
|
+
* / against a null pointer and their refusals name the registry as the remedy rather than telling
|
|
2968
|
+
* / an owner to run a call they cannot make.
|
|
2969
|
+
*/
|
|
2970
|
+
sysSetMarketId: ActorMethod<[Principal], Result_1>;
|
|
2971
|
+
/**
|
|
2972
|
+
* / Name the metrics reader allowed to read this engram's seat weeks (`sysGetAgentSeatWeeks`).
|
|
2973
|
+
* / ⟨2026-10-02, the owner's ruling of that day⟩
|
|
2974
|
+
* /
|
|
2975
|
+
* / CALLER: the registry that spawned this engram, and nobody else (ADR-0020) — the same authority
|
|
2976
|
+
* / as `sysSetBillerId` and `sysSetMarketId`. The registry calls it once, at spawn, last of its
|
|
2977
|
+
* / pushes, with exactly this interface: `sysSetMetricsReaderId : (Principal) -> async
|
|
2978
|
+
* / Wire.Result<()>`. ⚠ THAT CLIENT DECLARATION IS HAND-WRITTEN AT THE REGISTRY: a different NAME
|
|
2979
|
+
* / here leaves every newborn with no reader, silently (the push is best-effort and its reject is
|
|
2980
|
+
* / caught), and a different REPLY type traps inside the registry's callback. Rename neither without
|
|
2981
|
+
* / the registry; test/seat-weeks-wiring.test.ts compares the two.
|
|
2982
|
+
* /
|
|
2983
|
+
* / A CANISTER ONLY: a person's principal, the anonymous principal or the management canister is
|
|
2984
|
+
* / refused `#Invalid` and nothing changes — a person named here would be handed this engram's seat
|
|
2985
|
+
* / counts. Set or replaced, never cleared: the owner's control is the switch
|
|
2986
|
+
* / (`setSeatWeeksReadEnabled`), not the pointer. The chained record entry
|
|
2987
|
+
* / (`metrics.sysSetMetricsReaderId`) is the evidence of when the read was granted, and to whom.
|
|
2988
|
+
*/
|
|
2989
|
+
sysSetMetricsReaderId: ActorMethod<[Principal], Result_1>;
|
|
2990
|
+
/**
|
|
2991
|
+
* / The market asks this engram to sign a registered type — B1's seam, settlement leg. ⟨0.16.0⟩
|
|
2992
|
+
* /
|
|
2993
|
+
* / THE ENGRAM DOES NOT TRUST THE MARKET WITH ANYTHING BEYOND "ask". Every control that bounds
|
|
2994
|
+
* / what may be signed stays here and is unchanged: the type must already be OWNER-REGISTERED
|
|
2995
|
+
* / (the market cannot introduce a shape), its cool-off must have elapsed, its per-type daily cap
|
|
2996
|
+
* / still binds, the destination allowlist still fails closed, and a payments freeze still stops
|
|
2997
|
+
* / it. What the market supplies is the request; what the engram supplies is the whole policy.
|
|
2998
|
+
* /
|
|
2999
|
+
* / That is what "signatures only" means in code, and it is why this method needs no new authority
|
|
3000
|
+
* / model: an unregistered typeId is refused for the market exactly as it is for the owner.
|
|
3001
|
+
*/
|
|
3002
|
+
sysSignEip712: ActorMethod<[Uint8Array | number[], Array<[string, Eip712Value]>], Result_4>;
|
|
3003
|
+
/**
|
|
3004
|
+
* / The market asks this engram to sign an x402 payment — B1's seam, the paid-request leg. ⟨0.16.0⟩
|
|
3005
|
+
* /
|
|
3006
|
+
* / THE MARKET SUPPLIES THE REQUEST; THE ENGRAM SUPPLIES THE POLICY. Every control below the caller
|
|
3007
|
+
* / gate is unchanged and still binds: a payments freeze stops it, the recipient must be on the
|
|
3008
|
+
* / owner's EVM allowlist if the owner has set one, the per-transaction and per-day caps hold, and
|
|
3009
|
+
* / an over-policy request goes to the OWNER'S approval queue rather than through.
|
|
3010
|
+
* /
|
|
3011
|
+
* / `#ApprovalPending` is a real answer here, not an error, exactly as it is for an agent: the
|
|
3012
|
+
* / market is told the spend needs the owner and can retry with the `approvalId` once granted. A
|
|
3013
|
+
* / caller that treats it as a failure will simply never complete a spend the owner would have
|
|
3014
|
+
* / allowed — which is the safe direction, and the reason it rides inside `Ok` (L5).
|
|
3015
|
+
* /
|
|
3016
|
+
* / READ `x402SignFor`'s declaration before setting a policy for this caller. The cap is ONE bucket
|
|
3017
|
+
* / for ALL market traffic; per-seller limits are not expressible in the store it reads.
|
|
3018
|
+
*/
|
|
3019
|
+
sysSignX402Payment: ActorMethod<
|
|
3020
|
+
[bigint, string, string, bigint, string, string, [] | [string], [] | [string]],
|
|
3021
|
+
Result_3
|
|
3022
|
+
>;
|
|
3023
|
+
/**
|
|
3024
|
+
* / Write an `alerts.test` entry into the audit log; the drain timer delivers it to the webhook
|
|
3025
|
+
* / within ~60s. Owner-only; requires a configured URL so the test can actually go somewhere.
|
|
3026
|
+
*/
|
|
3027
|
+
testActionAlert: ActorMethod<[], Result_1>;
|
|
3028
|
+
/**
|
|
3029
|
+
* / Guardian test alert — an audited guardian action (`alerts.test`, role Guardian) that every
|
|
3030
|
+
* / armed channel (owner + guardians) receives within ~60s. Requires the caller's own channel
|
|
3031
|
+
* / to be armed so the test has somewhere to land for them.
|
|
3032
|
+
*/
|
|
3033
|
+
testGuardianAlert: ActorMethod<[], Result_1>;
|
|
3034
|
+
/**
|
|
3035
|
+
* / RENAMED from `init` (L2.4). This is the OWNERSHIP-TRANSFER method — the most consequential
|
|
3036
|
+
* / owner-facing operation on the canister — and it was named for first-time setup, colliding with
|
|
3037
|
+
* / the actor's own `service : (initArgs)`. A reader scanning for "how does ownership move" found
|
|
3038
|
+
* / nothing; a reader scanning for `init` found a constructor.
|
|
3039
|
+
* /
|
|
3040
|
+
* / Its read counterpart is `listOwnershipTransfers` (was `getOwnershipHistory`), which now shares
|
|
3041
|
+
* / the stem — the pair was previously unfindable from either half.
|
|
3042
|
+
* / ⟨0.16.0, L1⟩ TWO OF THESE REFUSALS ARE THE FIRST-CLAIM PATH, and they are not authorization.
|
|
3043
|
+
* /
|
|
3044
|
+
* / On an unowned engram there is no owner to refuse anyone, so "caller must set themselves as
|
|
3045
|
+
* / owner" is a rule about the ARGUMENT — pass your own principal and it succeeds. `#Invalid` says
|
|
3046
|
+
* / retrying with a different argument can work; `#Refused` would tell a first claimant their
|
|
3047
|
+
* / standing was the problem, on the one call where nobody has standing yet.
|
|
3048
|
+
* /
|
|
3049
|
+
* / ⟨2026-09-29, owner ruling follow-up 8 (option A)⟩ A CHANGE OF OWNER HANDS OVER CONTROL OF THE
|
|
3050
|
+
* / CODE. The new owner becomes a controller of this canister and the former owner stops being one;
|
|
3051
|
+
* / the answer says who moved it (`ControlHandover`). Managed: the registry moves it while it
|
|
3052
|
+
* / accepts the transfer. Sovereign: the registry answers `#EngramMustMove` and this engram sets
|
|
3053
|
+
* / its own controllers. THE OWNER CHANGES HERE ONLY AFTER CONTROL HAS MOVED — if it cannot move,
|
|
3054
|
+
* / the registry's record is put back and nothing is transferred; if even that fails, the refusal
|
|
3055
|
+
* / says who the registry now records and that the same call again finishes it. A standalone
|
|
3056
|
+
* / engram (no registry) cannot know who controls it and changes the owner only, answering
|
|
3057
|
+
* / `#NotHeldHere`. The rules are `src/shared/ControlHandover.mo`'s.
|
|
3058
|
+
* /
|
|
3059
|
+
* / ⟨2026-09-29, review PR-3: a half-finished change of owner⟩ The registry now MARKS a change of
|
|
3060
|
+
* / owner as unfinished from the moment it moves its record until it sees control move. A sovereign
|
|
3061
|
+
* / engram therefore reports the move (`sysConfirmOwnershipTransfer`) after setting its own
|
|
3062
|
+
* / controllers; until the registry hears it, the registry refuses the new owner's
|
|
3063
|
+
* / `claimSovereignty`, `returnToManaged`, `abandonMyEngram` and `upgradeMyEngram` for this engram.
|
|
3064
|
+
* / While a transfer is marked unfinished, a transfer to anyone but its would-be owner is refused by
|
|
3065
|
+
* / the registry, by name; calling this again with that owner finishes it.
|
|
3066
|
+
* /
|
|
3067
|
+
* / ⟨2026-09-29, review finding RV-4⟩ THE OWNER NAMING THEMSELVES IS A REPORT, NOT A HAND-ON. It is
|
|
3068
|
+
* / the way out when the registry did not hear that a sovereign engram moved control: it moves
|
|
3069
|
+
* / control to the same owner again and reports it, and it writes NO entry to
|
|
3070
|
+
* / `listOwnershipTransfers` (until this day it wrote one from the owner to themselves, a hand-on
|
|
3071
|
+
* / that did not happen). The record entry says it was a report. `ControlHandover.isReport`.
|
|
3072
|
+
*/
|
|
3073
|
+
transferOwnership: ActorMethod<[Principal], Result_2>;
|
|
3074
|
+
/**
|
|
3075
|
+
* / OWNER-ONLY release of the payment freeze — and the asymmetry with `freezePayments` is the
|
|
3076
|
+
* / governance design, not an oversight.
|
|
3077
|
+
* /
|
|
3078
|
+
* / ⚠ A GUARDIAN CAN PULL THIS BRAKE AND CANNOT RELEASE IT. `freezePayments` accepts the owner OR
|
|
3079
|
+
* / a guardian holding `canFreezePayments`; only the owner reaches this method. Two consequences,
|
|
3080
|
+
* / and both parties should know them before the role is accepted:
|
|
3081
|
+
* / · a guardian can stop payments in an emergency WITHOUT the owner, which is the point;
|
|
3082
|
+
* / · a guardian cannot hold the engram hostage, because the owner releases it immediately and
|
|
3083
|
+
* / unilaterally.
|
|
3084
|
+
* / So a guardian's freeze is a TRIPWIRE, not a lock — it buys the time it takes the owner to
|
|
3085
|
+
* / look, and no more.
|
|
3086
|
+
*/
|
|
3087
|
+
unfreezePayments: ActorMethod<[], Result_1>;
|
|
3088
|
+
/**
|
|
3089
|
+
* / Consensus transform for the World ID /verify outcall. Replicas each call independently, so the raw
|
|
3090
|
+
* / response (timestamps, `uses`, request-id headers) is non-deterministic. Collapse it to a single
|
|
3091
|
+
* / canonical byte — "1" iff HTTP 200 AND the body asserts success — with no headers, so every replica
|
|
3092
|
+
* / agrees. The caller keys off this byte, never the raw body.
|
|
3093
|
+
* /
|
|
3094
|
+
* / PUBLIC: not a choice, exactly as `actionAlertTransform` above — the management canister calls
|
|
3095
|
+
* / it on every replica with no caller identity attached. Stateless and total, so being callable
|
|
3096
|
+
* / by anyone grants nothing: an outsider invoking it learns only what they already passed in.
|
|
3097
|
+
*/
|
|
3098
|
+
worldIdTransform: ActorMethod<
|
|
3099
|
+
[{ context: Uint8Array | number[]; response: HttpRequestResult }],
|
|
3100
|
+
HttpRequestResult
|
|
3101
|
+
>;
|
|
3102
|
+
/**
|
|
3103
|
+
* / Write a memory file, creating it or adding a version to it. Returns a write receipt — the new
|
|
3104
|
+
* / `version`, the audit `seq`, and the chain `head` after the write — so a caller can prove what
|
|
3105
|
+
* / it wrote without a second read.
|
|
3106
|
+
* /
|
|
3107
|
+
* / ⚠ OWNER-ONLY, and this is the one most likely to surprise: an agent holding `write_memory`
|
|
3108
|
+
* / does NOT reach this method. Agent writes go through the agent surface, which applies the
|
|
3109
|
+
* / grant and the protected-path rules on top. `#Refused` here means the caller is not the owner,
|
|
3110
|
+
* / not that a permission is missing.
|
|
3111
|
+
* /
|
|
3112
|
+
* / It also refuses while writes are PAUSED and while memory is not attached — both are states an
|
|
3113
|
+
* / owner can be in without knowing, so they answer as themselves rather than as a generic failure.
|
|
3114
|
+
* /
|
|
3115
|
+
* / ⚠ THE FILE-COUNT CAP BLOCKS NEW FILES ONLY. At the cap, creating a new path is refused and
|
|
3116
|
+
* / APPENDING TO AN EXISTING FILE STILL WORKS — the refusal says so, because "you are full" and
|
|
3117
|
+
* / "you cannot write at all" lead to different next actions. A TOMBSTONED path counts as absent,
|
|
3118
|
+
* / so writing to a deleted path is a new file and is capped like one; the delete record survives
|
|
3119
|
+
* / either way.
|
|
3120
|
+
* /
|
|
3121
|
+
* / Path and content are validated before the caller is even checked, so a malformed request gets
|
|
3122
|
+
* / `#Invalid` rather than a refusal it would waste time investigating.
|
|
3123
|
+
*/
|
|
3124
|
+
writeMemory: ActorMethod<[string, Uint8Array | number[]], Result>;
|
|
3125
|
+
}
|
|
3126
|
+
export interface EngramSessionState {
|
|
3127
|
+
id: string;
|
|
3128
|
+
status: EngramSessionStatus;
|
|
3129
|
+
deposited: bigint;
|
|
3130
|
+
openedAtNs: bigint;
|
|
3131
|
+
lastActivityAtNs: bigint;
|
|
3132
|
+
consumed: bigint;
|
|
3133
|
+
voucherCount: bigint;
|
|
3134
|
+
remaining: bigint;
|
|
3135
|
+
payer: Principal;
|
|
3136
|
+
}
|
|
3137
|
+
export type EngramSessionStatus =
|
|
3138
|
+
{ closed: null } | { expired: null } | { other: string } | { open: null } | { closing: null };
|
|
3139
|
+
export interface Enrolment {
|
|
3140
|
+
signature: Uint8Array | number[];
|
|
3141
|
+
enrolledKey: Principal;
|
|
3142
|
+
rootPubkey: Uint8Array | number[];
|
|
3143
|
+
engram: Principal;
|
|
3144
|
+
}
|
|
3145
|
+
export interface EnrolmentProof {
|
|
3146
|
+
signature: Uint8Array | number[];
|
|
3147
|
+
enrolledKey: Principal;
|
|
3148
|
+
rootPubkey: Uint8Array | number[];
|
|
3149
|
+
inviteCode: string;
|
|
3150
|
+
}
|
|
3151
|
+
export type Error =
|
|
3152
|
+
| { Invalid: string }
|
|
3153
|
+
| { NotFound: string }
|
|
3154
|
+
| { Refused: string }
|
|
3155
|
+
| { Other: string }
|
|
3156
|
+
| { Unavailable: string }
|
|
3157
|
+
| { Conflict: string };
|
|
3158
|
+
export interface EvmAddresses {
|
|
3159
|
+
pay: string;
|
|
3160
|
+
engramRegistration: string;
|
|
3161
|
+
}
|
|
3162
|
+
export interface ExportReceiptRow {
|
|
3163
|
+
by: Principal;
|
|
3164
|
+
seq: bigint;
|
|
3165
|
+
toSeq: bigint;
|
|
3166
|
+
opsRoot: Uint8Array | number[];
|
|
3167
|
+
atNs: bigint;
|
|
3168
|
+
fromSeq: bigint;
|
|
3169
|
+
authorFilter: [] | [Principal];
|
|
3170
|
+
}
|
|
3171
|
+
export interface GenesisNote {
|
|
3172
|
+
predecessorSize: [] | [bigint];
|
|
3173
|
+
predecessorHeadHash: [] | [Uint8Array | number[]];
|
|
3174
|
+
note: string;
|
|
3175
|
+
version: string;
|
|
3176
|
+
genesisAtNs: bigint;
|
|
3177
|
+
}
|
|
3178
|
+
export interface GuardianPermissions {
|
|
3179
|
+
canFreezePayments: boolean;
|
|
3180
|
+
canRevokeAgents: boolean;
|
|
3181
|
+
scopes: [] | [Array<string>];
|
|
3182
|
+
canPauseWrites: boolean;
|
|
3183
|
+
}
|
|
3184
|
+
export interface GuardianRecord {
|
|
3185
|
+
status: GuardianStatus;
|
|
3186
|
+
permissions: GuardianPermissions;
|
|
3187
|
+
principal: Principal;
|
|
3188
|
+
name: string;
|
|
3189
|
+
addedAtNs: bigint;
|
|
3190
|
+
}
|
|
3191
|
+
export type GuardianStatus = { Active: null } | { Pending: null };
|
|
3192
|
+
export interface HeldKey {
|
|
3193
|
+
key: Principal;
|
|
3194
|
+
from: LogPosition;
|
|
3195
|
+
until: LogPosition;
|
|
3196
|
+
}
|
|
3197
|
+
export interface HttpHeader {
|
|
3198
|
+
value: string;
|
|
3199
|
+
name: string;
|
|
3200
|
+
}
|
|
3201
|
+
export interface HttpRequest {
|
|
3202
|
+
url: string;
|
|
3203
|
+
method: string;
|
|
3204
|
+
body: Uint8Array | number[];
|
|
3205
|
+
headers: Array<[string, string]>;
|
|
3206
|
+
}
|
|
3207
|
+
export interface HttpRequestResult {
|
|
3208
|
+
status: bigint;
|
|
3209
|
+
body: Uint8Array | number[];
|
|
3210
|
+
headers: Array<HttpHeader>;
|
|
3211
|
+
}
|
|
3212
|
+
export interface HttpResponse {
|
|
3213
|
+
body: Uint8Array | number[];
|
|
3214
|
+
headers: Array<[string, string]>;
|
|
3215
|
+
upgrade: [] | [boolean];
|
|
3216
|
+
status_code: number;
|
|
3217
|
+
}
|
|
3218
|
+
export interface KeyNomination {
|
|
3219
|
+
key: Principal;
|
|
3220
|
+
atNs: bigint;
|
|
3221
|
+
}
|
|
3222
|
+
export interface LogPage {
|
|
3223
|
+
firstAvailableSeq: bigint;
|
|
3224
|
+
head: Uint8Array | number[];
|
|
3225
|
+
page: Page_7;
|
|
3226
|
+
}
|
|
3227
|
+
export interface LogPosition {
|
|
3228
|
+
reads: bigint;
|
|
3229
|
+
record: bigint;
|
|
3230
|
+
}
|
|
3231
|
+
export interface MarketplacePaymentSignatures {
|
|
3232
|
+
marketplace: Principal;
|
|
3233
|
+
sharedSignedToday: bigint;
|
|
3234
|
+
limit: bigint;
|
|
3235
|
+
}
|
|
3236
|
+
export interface MemoryByteChunk {
|
|
3237
|
+
more: boolean;
|
|
3238
|
+
fileSize: bigint;
|
|
3239
|
+
bytes: Uint8Array | number[];
|
|
3240
|
+
}
|
|
3241
|
+
export interface MemoryEviction {
|
|
3242
|
+
evictSeq: bigint;
|
|
3243
|
+
fromVersion: bigint;
|
|
3244
|
+
evictedRoot: Uint8Array | number[];
|
|
3245
|
+
trigger:
|
|
3246
|
+
| { globalCap: null }
|
|
3247
|
+
| { thinTail: null }
|
|
3248
|
+
| { perFileCap: null }
|
|
3249
|
+
| { thinLogSpaced: null }
|
|
3250
|
+
| { policy: null };
|
|
3251
|
+
cause: { maxVersions: null } | { maxBytes: null };
|
|
3252
|
+
toVersion: bigint;
|
|
3253
|
+
}
|
|
3254
|
+
export interface MemoryFile {
|
|
3255
|
+
content: Uint8Array | number[];
|
|
3256
|
+
path: string;
|
|
3257
|
+
version: bigint;
|
|
3258
|
+
lastModifiedBy: Principal;
|
|
3259
|
+
lastModifiedAtNs: bigint;
|
|
3260
|
+
}
|
|
3261
|
+
export interface MemoryHistory {
|
|
3262
|
+
evictions: Array<MemoryEviction>;
|
|
3263
|
+
oldestRetainedVersion: bigint;
|
|
3264
|
+
everCount: bigint;
|
|
3265
|
+
retainedCount: bigint;
|
|
3266
|
+
versions: Array<MemoryVersionSummary>;
|
|
3267
|
+
evictedCount: bigint;
|
|
3268
|
+
}
|
|
3269
|
+
export interface MemoryLogChunkRef {
|
|
3270
|
+
hash: Uint8Array | number[];
|
|
3271
|
+
size: bigint;
|
|
3272
|
+
birthSeq: bigint;
|
|
3273
|
+
}
|
|
3274
|
+
export interface MemoryLogEvent {
|
|
3275
|
+
by: Principal;
|
|
3276
|
+
op: MemoryLogOp;
|
|
3277
|
+
seq: bigint;
|
|
3278
|
+
contentRoot: Uint8Array | number[];
|
|
3279
|
+
atNs: bigint;
|
|
3280
|
+
path: string;
|
|
3281
|
+
prev: Uint8Array | number[];
|
|
3282
|
+
size: bigint;
|
|
3283
|
+
version: bigint;
|
|
3284
|
+
}
|
|
3285
|
+
export type MemoryLogImportNote =
|
|
3286
|
+
| { legacyDelete: null }
|
|
3287
|
+
| {
|
|
3288
|
+
legacyTruncated: {
|
|
3289
|
+
prefixHash: Uint8Array | number[];
|
|
3290
|
+
storedBytes: bigint;
|
|
3291
|
+
};
|
|
3292
|
+
}
|
|
3293
|
+
| { legacyGap: { firstSurviving: bigint } }
|
|
3294
|
+
| {
|
|
3295
|
+
legacyUnreconstructable: {
|
|
3296
|
+
contentHash: Uint8Array | number[];
|
|
3297
|
+
reason: string;
|
|
3298
|
+
};
|
|
3299
|
+
}
|
|
3300
|
+
| { genesis: { boundTo: [] | [Uint8Array | number[]] } };
|
|
3301
|
+
export interface MemoryLogManifest {
|
|
3302
|
+
contentRoot: Uint8Array | number[];
|
|
3303
|
+
totalSize: bigint;
|
|
3304
|
+
chunks: Array<MemoryLogChunkRef>;
|
|
3305
|
+
}
|
|
3306
|
+
export type MemoryLogOp =
|
|
3307
|
+
| { set: { manifest: MemoryLogManifest } }
|
|
3308
|
+
| {
|
|
3309
|
+
exported: {
|
|
3310
|
+
toSeq: bigint;
|
|
3311
|
+
opsRoot: Uint8Array | number[];
|
|
3312
|
+
fromSeq: bigint;
|
|
3313
|
+
authorFilter: [] | [Principal];
|
|
3314
|
+
};
|
|
3315
|
+
}
|
|
3316
|
+
| { imported: MemoryLogImportNote }
|
|
3317
|
+
| { restore: { toVersion: bigint; manifest: MemoryLogManifest } }
|
|
3318
|
+
| {
|
|
3319
|
+
evict: {
|
|
3320
|
+
fromVersion: bigint;
|
|
3321
|
+
evictedRoot: Uint8Array | number[];
|
|
3322
|
+
toVersion: bigint;
|
|
3323
|
+
chunkCount: bigint;
|
|
3324
|
+
byteCount: bigint;
|
|
3325
|
+
};
|
|
3326
|
+
}
|
|
3327
|
+
| {
|
|
3328
|
+
append: {
|
|
3329
|
+
deltaHash: Uint8Array | number[];
|
|
3330
|
+
deltaSize: bigint;
|
|
3331
|
+
newSize: bigint;
|
|
3332
|
+
};
|
|
3333
|
+
}
|
|
3334
|
+
| { tombstone: null }
|
|
3335
|
+
| {
|
|
3336
|
+
condense: {
|
|
3337
|
+
toSeq: bigint;
|
|
3338
|
+
opsRoot: Uint8Array | number[];
|
|
3339
|
+
fromSeq: bigint;
|
|
3340
|
+
headAtBoundary: Uint8Array | number[];
|
|
3341
|
+
opCount: bigint;
|
|
3342
|
+
};
|
|
3343
|
+
};
|
|
3344
|
+
export interface MemoryMaintainStatus {
|
|
3345
|
+
attachOk: boolean;
|
|
3346
|
+
attachDetail: string;
|
|
3347
|
+
totalEvictions: bigint;
|
|
3348
|
+
refusedQuota: string;
|
|
3349
|
+
more: boolean;
|
|
3350
|
+
lastEvictions: bigint;
|
|
3351
|
+
lastScrubbed: bigint;
|
|
3352
|
+
lastMaintainAtNs: [] | [bigint];
|
|
3353
|
+
totalFindings: bigint;
|
|
3354
|
+
refused: boolean;
|
|
3355
|
+
}
|
|
3356
|
+
export interface MemoryRangeExport {
|
|
3357
|
+
seq: bigint;
|
|
3358
|
+
toSeq: bigint;
|
|
3359
|
+
opsRoot: Uint8Array | number[];
|
|
3360
|
+
atNs: bigint;
|
|
3361
|
+
head: Uint8Array | number[];
|
|
3362
|
+
fromSeq: bigint;
|
|
3363
|
+
authorFilter: [] | [Principal];
|
|
3364
|
+
}
|
|
3365
|
+
export interface MemoryRetentionPolicy {
|
|
3366
|
+
entries: Array<[string, RetentionClassSpec]>;
|
|
3367
|
+
guards: Array<{ notBeforeNs: bigint; prefix: string }>;
|
|
3368
|
+
}
|
|
3369
|
+
export type MemorySource =
|
|
3370
|
+
| { sessionTranscript: null }
|
|
3371
|
+
| { human: null }
|
|
3372
|
+
| { fileSync: null }
|
|
3373
|
+
| { agentDerived: null }
|
|
3374
|
+
| { deterministic: null };
|
|
3375
|
+
export interface MemoryVersionSummary {
|
|
3376
|
+
by: Principal;
|
|
3377
|
+
seq: bigint;
|
|
3378
|
+
contentRoot: Uint8Array | number[];
|
|
3379
|
+
atNs: bigint;
|
|
3380
|
+
kind: { set: null } | { restore: null } | { append: null } | { tombstone: null };
|
|
3381
|
+
size: bigint;
|
|
3382
|
+
version: bigint;
|
|
3383
|
+
}
|
|
3384
|
+
export interface OwnerConsole {
|
|
3385
|
+
pendingApprovalCount: bigint;
|
|
3386
|
+
memoryKeyEpoch: bigint;
|
|
3387
|
+
owner: [] | [Principal];
|
|
3388
|
+
agentRevisablePathCount: bigint;
|
|
3389
|
+
protectedPathCount: bigint;
|
|
3390
|
+
cyclesBalance: bigint;
|
|
3391
|
+
unknownSessionRefusals: bigint;
|
|
3392
|
+
}
|
|
3393
|
+
export interface OwnerRow {
|
|
3394
|
+
pairedDay: bigint;
|
|
3395
|
+
lastPaymentDay: [] | [bigint];
|
|
3396
|
+
root: Principal;
|
|
3397
|
+
weeks: bigint;
|
|
3398
|
+
produced: bigint;
|
|
3399
|
+
firstPaymentDay: [] | [bigint];
|
|
3400
|
+
}
|
|
3401
|
+
export interface OwnershipTransfer {
|
|
3402
|
+
to: Principal;
|
|
3403
|
+
atNs: bigint;
|
|
3404
|
+
from: [] | [Principal];
|
|
3405
|
+
authorizedBy: Principal;
|
|
3406
|
+
}
|
|
3407
|
+
export interface Page {
|
|
3408
|
+
total: bigint;
|
|
3409
|
+
withheld: bigint;
|
|
3410
|
+
items: Array<Repudiation>;
|
|
3411
|
+
}
|
|
3412
|
+
export interface Page_1 {
|
|
3413
|
+
total: bigint;
|
|
3414
|
+
withheld: bigint;
|
|
3415
|
+
items: Array<AuditEntry>;
|
|
3416
|
+
}
|
|
3417
|
+
export interface Page_10 {
|
|
3418
|
+
total: bigint;
|
|
3419
|
+
withheld: bigint;
|
|
3420
|
+
items: Array<GuardianRecord>;
|
|
3421
|
+
}
|
|
3422
|
+
export interface Page_11 {
|
|
3423
|
+
total: bigint;
|
|
3424
|
+
withheld: bigint;
|
|
3425
|
+
items: Array<{ activeFromNs: bigint; address: string }>;
|
|
3426
|
+
}
|
|
3427
|
+
export interface Page_12 {
|
|
3428
|
+
total: bigint;
|
|
3429
|
+
withheld: bigint;
|
|
3430
|
+
items: Array<RegisteredType>;
|
|
3431
|
+
}
|
|
3432
|
+
export interface Page_13 {
|
|
3433
|
+
total: bigint;
|
|
3434
|
+
withheld: bigint;
|
|
3435
|
+
items: Array<string>;
|
|
3436
|
+
}
|
|
3437
|
+
export interface Page_14 {
|
|
3438
|
+
total: bigint;
|
|
3439
|
+
withheld: bigint;
|
|
3440
|
+
items: Array<CycleSnapshot>;
|
|
3441
|
+
}
|
|
3442
|
+
export interface Page_15 {
|
|
3443
|
+
total: bigint;
|
|
3444
|
+
withheld: bigint;
|
|
3445
|
+
items: Array<CondenseCheckpointRow>;
|
|
3446
|
+
}
|
|
3447
|
+
export interface Page_16 {
|
|
3448
|
+
total: bigint;
|
|
3449
|
+
withheld: bigint;
|
|
3450
|
+
items: Array<BearerToken>;
|
|
3451
|
+
}
|
|
3452
|
+
export interface Page_17 {
|
|
3453
|
+
total: bigint;
|
|
3454
|
+
withheld: bigint;
|
|
3455
|
+
items: Array<BackupMetadata>;
|
|
3456
|
+
}
|
|
3457
|
+
export interface Page_18 {
|
|
3458
|
+
total: bigint;
|
|
3459
|
+
withheld: bigint;
|
|
3460
|
+
items: Array<{ status: AgentStatus; principal: Principal; name: string }>;
|
|
3461
|
+
}
|
|
3462
|
+
export interface Page_19 {
|
|
3463
|
+
total: bigint;
|
|
3464
|
+
withheld: bigint;
|
|
3465
|
+
items: Array<AgentRecord>;
|
|
3466
|
+
}
|
|
3467
|
+
export interface Page_2 {
|
|
3468
|
+
total: bigint;
|
|
3469
|
+
withheld: bigint;
|
|
3470
|
+
items: Array<PurgedAgent>;
|
|
3471
|
+
}
|
|
3472
|
+
export interface Page_20 {
|
|
3473
|
+
total: bigint;
|
|
3474
|
+
withheld: bigint;
|
|
3475
|
+
items: Array<ActivitySnapshot>;
|
|
3476
|
+
}
|
|
3477
|
+
export interface Page_21 {
|
|
3478
|
+
total: bigint;
|
|
3479
|
+
withheld: bigint;
|
|
3480
|
+
items: Array<OwnerRow>;
|
|
3481
|
+
}
|
|
3482
|
+
export interface Page_3 {
|
|
3483
|
+
total: bigint;
|
|
3484
|
+
withheld: bigint;
|
|
3485
|
+
items: Array<AgentPaymentSignatures>;
|
|
3486
|
+
}
|
|
3487
|
+
export interface Page_4 {
|
|
3488
|
+
total: bigint;
|
|
3489
|
+
withheld: bigint;
|
|
3490
|
+
items: Array<OwnershipTransfer>;
|
|
3491
|
+
}
|
|
3492
|
+
export interface Page_5 {
|
|
3493
|
+
total: bigint;
|
|
3494
|
+
withheld: bigint;
|
|
3495
|
+
items: Array<EngramSessionState>;
|
|
3496
|
+
}
|
|
3497
|
+
export interface Page_6 {
|
|
3498
|
+
total: bigint;
|
|
3499
|
+
withheld: bigint;
|
|
3500
|
+
items: Array<ApprovalRequest>;
|
|
3501
|
+
}
|
|
3502
|
+
export interface Page_7 {
|
|
3503
|
+
total: bigint;
|
|
3504
|
+
withheld: bigint;
|
|
3505
|
+
items: Array<MemoryLogEvent>;
|
|
3506
|
+
}
|
|
3507
|
+
export interface Page_8 {
|
|
3508
|
+
total: bigint;
|
|
3509
|
+
withheld: bigint;
|
|
3510
|
+
items: Array<{ path: string; version: bigint; lastModifiedAtNs: bigint }>;
|
|
3511
|
+
}
|
|
3512
|
+
export interface Page_9 {
|
|
3513
|
+
total: bigint;
|
|
3514
|
+
withheld: bigint;
|
|
3515
|
+
items: Array<ExportReceiptRow>;
|
|
3516
|
+
}
|
|
3517
|
+
export interface Pairing {
|
|
3518
|
+
agent: AgentRecord;
|
|
3519
|
+
trackRecord: TrackRecordNotice;
|
|
3520
|
+
}
|
|
3521
|
+
export interface PaymentSignature {
|
|
3522
|
+
signature: Uint8Array | number[];
|
|
3523
|
+
asset: [] | [string];
|
|
3524
|
+
publicKey: [] | [Uint8Array | number[]];
|
|
3525
|
+
scheme: string;
|
|
3526
|
+
network: string;
|
|
3527
|
+
sender: string;
|
|
3528
|
+
nonce: Uint8Array | number[];
|
|
3529
|
+
authorization: [] | [Eip3009Authorization];
|
|
3530
|
+
}
|
|
3531
|
+
export interface PaymentSignatureCounts {
|
|
3532
|
+
day: bigint;
|
|
3533
|
+
marketplace: [] | [MarketplacePaymentSignatures];
|
|
3534
|
+
agents: Page_3;
|
|
3535
|
+
limit: bigint;
|
|
3536
|
+
}
|
|
3537
|
+
export interface PurgedAgent {
|
|
3538
|
+
principal: Principal;
|
|
3539
|
+
pairedAtNs: bigint;
|
|
3540
|
+
name: string;
|
|
3541
|
+
root: Principal;
|
|
3542
|
+
enrolledKey: Principal;
|
|
3543
|
+
ended: AgentEnding;
|
|
3544
|
+
invite: string;
|
|
3545
|
+
purgedAtNs: bigint;
|
|
3546
|
+
}
|
|
3547
|
+
export interface RailHealth {
|
|
3548
|
+
sessionsExpired: bigint;
|
|
3549
|
+
sessionsClosed: bigint;
|
|
3550
|
+
paidVouchersConsumed: bigint;
|
|
3551
|
+
escrowOpen: [] | [bigint];
|
|
3552
|
+
sessionsOpen: bigint;
|
|
3553
|
+
sessionsClosing: bigint;
|
|
3554
|
+
cycles: bigint;
|
|
3555
|
+
sendHeadroom: bigint;
|
|
3556
|
+
memoryBytes: bigint;
|
|
3557
|
+
freezeReservation: bigint;
|
|
3558
|
+
unknownSessionRefusals: bigint;
|
|
3559
|
+
}
|
|
3560
|
+
export interface ReceiptPage {
|
|
3561
|
+
firstAvailableSeq: bigint;
|
|
3562
|
+
page: Page_9;
|
|
3563
|
+
scannedThroughSeq: bigint;
|
|
3564
|
+
}
|
|
3565
|
+
export interface RegisteredType {
|
|
3566
|
+
primaryType: string;
|
|
3567
|
+
encodeTypeString: string;
|
|
3568
|
+
cooloffEndsAtNs: bigint;
|
|
3569
|
+
domainName: string;
|
|
3570
|
+
typeId: Uint8Array | number[];
|
|
3571
|
+
verifyingContract: string;
|
|
3572
|
+
dailySignCap: bigint;
|
|
3573
|
+
fields: Array<[string, string]>;
|
|
3574
|
+
domainSeparator: Uint8Array | number[];
|
|
3575
|
+
destinationFields: Array<string>;
|
|
3576
|
+
authorityClass: AuthorityClass;
|
|
3577
|
+
typeHash: Uint8Array | number[];
|
|
3578
|
+
registeredAtNs: bigint;
|
|
3579
|
+
chainId: bigint;
|
|
3580
|
+
domainVersion: string;
|
|
3581
|
+
ackIrrevocable: boolean;
|
|
3582
|
+
}
|
|
3583
|
+
export interface Repudiation {
|
|
3584
|
+
atNs: bigint;
|
|
3585
|
+
path: string;
|
|
3586
|
+
auditId: bigint;
|
|
3587
|
+
version: bigint;
|
|
3588
|
+
reason: string;
|
|
3589
|
+
}
|
|
3590
|
+
export interface ResetReport {
|
|
3591
|
+
agentsRemoved: bigint;
|
|
3592
|
+
agentsPurged: bigint;
|
|
3593
|
+
guardiansRemoved: bigint;
|
|
3594
|
+
filesCleared: bigint;
|
|
3595
|
+
}
|
|
3596
|
+
export type Result = { Ok: WriteReceipt } | { Err: Error };
|
|
3597
|
+
export type Result_1 = { Ok: null } | { Err: Error };
|
|
3598
|
+
export type Result_10 = { Ok: BackupRetentionReport } | { Err: Error };
|
|
3599
|
+
export type Result_11 = { Ok: MemoryFile } | { Err: Error };
|
|
3600
|
+
export type Result_12 = { Ok: SessionContext } | { Err: Error };
|
|
3601
|
+
export type Result_13 = { Ok: ResyncReport } | { Err: Error };
|
|
3602
|
+
export type Result_14 = { Ok: ResetReport } | { Err: Error };
|
|
3603
|
+
export type Result_15 = { Ok: GuardianRecord } | { Err: Error };
|
|
3604
|
+
export type Result_16 = { Ok: MemoryByteChunk } | { Err: Error };
|
|
3605
|
+
export type Result_17 = { Ok: Array<BatchReadItem> } | { Err: Error };
|
|
3606
|
+
export type Result_18 = { Ok: CondensePreview } | { Err: Error };
|
|
3607
|
+
export type Result_19 = { Ok: Pairing } | { Err: Error };
|
|
3608
|
+
export type Result_2 = { Ok: ControlHandover } | { Err: Error };
|
|
3609
|
+
export type Result_20 = { Ok: EngramSessionState } | { Err: Error };
|
|
3610
|
+
export type Result_21 = { Ok: Principal } | { Err: Error };
|
|
3611
|
+
export type Result_22 = { Ok: Page } | { Err: Error };
|
|
3612
|
+
export type Result_23 = { Ok: Page_1 } | { Err: Error };
|
|
3613
|
+
export type Result_24 = { Ok: Page_2 } | { Err: Error };
|
|
3614
|
+
export type Result_25 = { Ok: PaymentSignatureCounts } | { Err: Error };
|
|
3615
|
+
export type Result_26 = { Ok: Page_4 } | { Err: Error };
|
|
3616
|
+
export type Result_27 = { Ok: Page_5 } | { Err: Error };
|
|
3617
|
+
export type Result_28 = { Ok: Page_6 } | { Err: Error };
|
|
3618
|
+
export type Result_29 = { Ok: LogPage } | { Err: Error };
|
|
3619
|
+
export type Result_3 = { Ok: X402SignOutcome } | { Err: Error };
|
|
3620
|
+
export type Result_30 = { Ok: Page_8 } | { Err: Error };
|
|
3621
|
+
export type Result_31 = { Ok: ReceiptPage } | { Err: Error };
|
|
3622
|
+
export type Result_32 = { Ok: Page_10 } | { Err: Error };
|
|
3623
|
+
export type Result_33 = { Ok: Page_11 } | { Err: Error };
|
|
3624
|
+
export type Result_34 = { Ok: Page_12 } | { Err: Error };
|
|
3625
|
+
export type Result_35 = { Ok: Page_13 } | { Err: Error };
|
|
3626
|
+
export type Result_36 = { Ok: Page_14 } | { Err: Error };
|
|
3627
|
+
export type Result_37 = { Ok: CheckpointPage } | { Err: Error };
|
|
3628
|
+
export type Result_38 = { Ok: Page_16 } | { Err: Error };
|
|
3629
|
+
export type Result_39 = { Ok: Page_17 } | { Err: Error };
|
|
3630
|
+
export type Result_4 = { Ok: Eip712SignatureOut } | { Err: Error };
|
|
3631
|
+
export type Result_40 = { Ok: Page_18 } | { Err: Error };
|
|
3632
|
+
export type Result_41 = { Ok: Page_19 } | { Err: Error };
|
|
3633
|
+
export type Result_42 = { Ok: Page_20 } | { Err: Error };
|
|
3634
|
+
export type Result_43 = { Ok: string } | { Err: Error };
|
|
3635
|
+
export type Result_44 = { Ok: boolean } | { Err: Error };
|
|
3636
|
+
export type Result_45 = { Ok: [] | [string] } | { Err: Error };
|
|
3637
|
+
export type Result_46 = { Ok: WorldIdRpContext } | { Err: Error };
|
|
3638
|
+
export type Result_47 = { Ok: WorldIdConfig } | { Err: Error };
|
|
3639
|
+
export type Result_48 = { Ok: WalletBalances } | { Err: Error };
|
|
3640
|
+
export type Result_49 = { Ok: StorageReport } | { Err: Error };
|
|
3641
|
+
export type Result_5 = { Ok: SignatureCounts } | { Err: Error };
|
|
3642
|
+
export type Result_50 = { Ok: SpendingPolicy } | { Err: Error };
|
|
3643
|
+
export type Result_51 = { Ok: SpendCeiling } | { Err: Error };
|
|
3644
|
+
export type Result_52 = { Ok: SigningFloorStatus } | { Err: Error };
|
|
3645
|
+
export type Result_53 = { Ok: { paths: Array<string> } } | { Err: Error };
|
|
3646
|
+
export type Result_54 = { Ok: OwnerConsole } | { Err: Error };
|
|
3647
|
+
export type Result_55 = { Ok: MemoryRetentionPolicy } | { Err: Error };
|
|
3648
|
+
export type Result_56 = { Ok: MemoryHistory } | { Err: Error };
|
|
3649
|
+
export type Result_57 = { Ok: AlertStatus } | { Err: Error };
|
|
3650
|
+
export type Result_58 = { Ok: EvmAddresses } | { Err: Error };
|
|
3651
|
+
export type Result_59 = { Ok: Uint8Array | number[] } | { Err: Error };
|
|
3652
|
+
export type Result_6 = { Ok: RailHealth } | { Err: Error };
|
|
3653
|
+
export type Result_60 = { Ok: ChildOpening } | { Err: Error };
|
|
3654
|
+
export type Result_61 = { Ok: ChildAllowanceRow } | { Err: Error };
|
|
3655
|
+
export type Result_62 = { Ok: BackupMetadata } | { Err: Error };
|
|
3656
|
+
export type Result_63 = { Ok: AgentWriteReview } | { Err: Error };
|
|
3657
|
+
export type Result_64 = { Ok: Page_21 } | { Err: Error };
|
|
3658
|
+
export type Result_66 = { Ok: MemoryRangeExport } | { Err: Error };
|
|
3659
|
+
export type Result_67 = { Ok: CondenseResult } | { Err: Error };
|
|
3660
|
+
export type Result_68 = { Ok: { activatesAtNs: bigint } } | { Err: Error };
|
|
3661
|
+
export type Result_69 = { Ok: Eip712Registration } | { Err: Error };
|
|
3662
|
+
export type Result_7 = { Ok: Array<Seat> } | { Err: Error };
|
|
3663
|
+
export type Result_70 = { Ok: AgentRecord } | { Err: Error };
|
|
3664
|
+
export type Result_8 = { Ok: bigint } | { Err: Error };
|
|
3665
|
+
export type Result_9 = { Ok: SignedTransaction } | { Err: Error };
|
|
3666
|
+
export interface ResyncReport {
|
|
3667
|
+
startsAcknowledged: bigint;
|
|
3668
|
+
cannotBeRecorded: Array<UnrecordableEngagement>;
|
|
3669
|
+
endingsAcknowledged: bigint;
|
|
3670
|
+
notRecorded: Array<{
|
|
3671
|
+
why: string;
|
|
3672
|
+
principal: Principal;
|
|
3673
|
+
root: Principal;
|
|
3674
|
+
event: string;
|
|
3675
|
+
}>;
|
|
3676
|
+
}
|
|
3677
|
+
export type RetentionClassSpec =
|
|
3678
|
+
| { vault: null }
|
|
3679
|
+
| {
|
|
3680
|
+
working: {
|
|
3681
|
+
maxVersions: [] | [bigint];
|
|
3682
|
+
maxBytes: [] | [bigint];
|
|
3683
|
+
thinning: { tail: null } | { logSpaced: { denseTail: bigint } };
|
|
3684
|
+
};
|
|
3685
|
+
};
|
|
3686
|
+
export type Role =
|
|
3687
|
+
| { Anonymous: null }
|
|
3688
|
+
| { Viewer: null }
|
|
3689
|
+
| { Engram: null }
|
|
3690
|
+
| { Root: null }
|
|
3691
|
+
| { Buyer: null }
|
|
3692
|
+
| { WasmAdmin: null }
|
|
3693
|
+
| { Guardian: null }
|
|
3694
|
+
| { Seller: null }
|
|
3695
|
+
| { Admin: null }
|
|
3696
|
+
| { Agent: null }
|
|
3697
|
+
| { Other: null }
|
|
3698
|
+
| { Owner: null };
|
|
3699
|
+
export interface Seat {
|
|
3700
|
+
pairedDay: bigint;
|
|
3701
|
+
lastPaymentDay: [] | [bigint];
|
|
3702
|
+
weeks: bigint;
|
|
3703
|
+
produced: bigint;
|
|
3704
|
+
firstPaymentDay: [] | [bigint];
|
|
3705
|
+
}
|
|
3706
|
+
export interface ServiceEntry {
|
|
3707
|
+
endpoint: string;
|
|
3708
|
+
name: string;
|
|
3709
|
+
version: string;
|
|
3710
|
+
domains: Array<string>;
|
|
3711
|
+
skills: Array<string>;
|
|
3712
|
+
}
|
|
3713
|
+
export interface SessionConfig {
|
|
3714
|
+
autoClose: boolean;
|
|
3715
|
+
idleTimeout: [] | [bigint];
|
|
3716
|
+
maxDeposit: bigint;
|
|
3717
|
+
}
|
|
3718
|
+
export interface SessionContext {
|
|
3719
|
+
files: Array<MemoryFile>;
|
|
3720
|
+
totalFiles: bigint;
|
|
3721
|
+
truncated: boolean;
|
|
3722
|
+
includedFiles: bigint;
|
|
3723
|
+
totalBytes: bigint;
|
|
3724
|
+
}
|
|
3725
|
+
export interface SessionIntent {
|
|
3726
|
+
token: string;
|
|
3727
|
+
costPerCall: [] | [bigint];
|
|
3728
|
+
minDeposit: [] | [bigint];
|
|
3729
|
+
recipient: string;
|
|
3730
|
+
network: string;
|
|
3731
|
+
description: [] | [string];
|
|
3732
|
+
expiryNs: bigint;
|
|
3733
|
+
suggestedDeposit: bigint;
|
|
3734
|
+
}
|
|
3735
|
+
export interface SignatureCounts {
|
|
3736
|
+
total: bigint;
|
|
3737
|
+
byCaller: Array<CallerSignatureCount>;
|
|
3738
|
+
}
|
|
3739
|
+
export interface SignedAuthorization {
|
|
3740
|
+
paidAmount: bigint;
|
|
3741
|
+
authorization: {
|
|
3742
|
+
to: string;
|
|
3743
|
+
signature: string;
|
|
3744
|
+
value: bigint;
|
|
3745
|
+
from: string;
|
|
3746
|
+
validAfter: bigint;
|
|
3747
|
+
nonce: string;
|
|
3748
|
+
validBefore: bigint;
|
|
3749
|
+
};
|
|
3750
|
+
header: string;
|
|
3751
|
+
}
|
|
3752
|
+
export interface SignedTransaction {
|
|
3753
|
+
txHash: string;
|
|
3754
|
+
rawTx: string;
|
|
3755
|
+
}
|
|
3756
|
+
export interface SigningFloorStatus {
|
|
3757
|
+
floor: bigint;
|
|
3758
|
+
signaturesAboveFloor: bigint;
|
|
3759
|
+
balance: bigint;
|
|
3760
|
+
perSignature: bigint;
|
|
3761
|
+
}
|
|
3762
|
+
export interface SpendCeiling {
|
|
3763
|
+
spentToday: bigint;
|
|
3764
|
+
maxPerDay: [] | [bigint];
|
|
3765
|
+
}
|
|
3766
|
+
export interface SpendingPolicy {
|
|
3767
|
+
maxSessionDeposit: [] | [bigint];
|
|
3768
|
+
blockedCallers: [] | [Array<Principal>];
|
|
3769
|
+
maxPerDay: [] | [bigint];
|
|
3770
|
+
maxSessionDuration: [] | [bigint];
|
|
3771
|
+
sessionIdleTimeout: [] | [bigint];
|
|
3772
|
+
rateLimitPerMinute: [] | [bigint];
|
|
3773
|
+
maxPerTransaction: [] | [bigint];
|
|
3774
|
+
allowedCallers: [] | [Array<Principal>];
|
|
3775
|
+
maxConcurrentSessions: [] | [bigint];
|
|
3776
|
+
}
|
|
3777
|
+
export interface StorageReport {
|
|
3778
|
+
sessionFilesSize: bigint;
|
|
3779
|
+
totalFiles: bigint;
|
|
3780
|
+
memoryFilesSize: bigint;
|
|
3781
|
+
totalContentSize: bigint;
|
|
3782
|
+
backupCount: bigint;
|
|
3783
|
+
memoryFilesCount: bigint;
|
|
3784
|
+
versionHistorySize: bigint;
|
|
3785
|
+
fileLimit: bigint;
|
|
3786
|
+
backupSize: bigint;
|
|
3787
|
+
auditLogSize: bigint;
|
|
3788
|
+
versionHistoryCount: bigint;
|
|
3789
|
+
sessionFilesCount: bigint;
|
|
3790
|
+
}
|
|
3791
|
+
export interface TimerHealth {
|
|
3792
|
+
jobExpiryFastMode: boolean;
|
|
3793
|
+
jobExpiryArmed: boolean;
|
|
3794
|
+
alertTimerArmed: boolean;
|
|
3795
|
+
sessionExpiryArmed: boolean;
|
|
3796
|
+
}
|
|
3797
|
+
export type TokenAmount = { Icp: bigint } | { Ckusdc: bigint } | { Ckusdt: bigint };
|
|
3798
|
+
export type TrackRecordNotice = { Recorded: null } | { NotRecorded: string };
|
|
3799
|
+
export interface UnrecordableEngagement {
|
|
3800
|
+
principal: Principal;
|
|
3801
|
+
root: Principal;
|
|
3802
|
+
ended: AgentEnding;
|
|
3803
|
+
invite: string;
|
|
3804
|
+
}
|
|
3805
|
+
export interface Voucher {
|
|
3806
|
+
signature: Uint8Array | number[];
|
|
3807
|
+
sessionId: string;
|
|
3808
|
+
sequence: bigint;
|
|
3809
|
+
cumulativeAmount: bigint;
|
|
3810
|
+
}
|
|
3811
|
+
export interface WalletBalances {
|
|
3812
|
+
icpE8s: bigint;
|
|
3813
|
+
ckusdcE6s: bigint;
|
|
3814
|
+
ckusdtE6s: bigint;
|
|
3815
|
+
cycles: bigint;
|
|
3816
|
+
}
|
|
3817
|
+
export interface WorldIdConfig {
|
|
3818
|
+
action: string;
|
|
3819
|
+
appId: string;
|
|
3820
|
+
rpId: string;
|
|
3821
|
+
configured: boolean;
|
|
3822
|
+
}
|
|
3823
|
+
export interface WorldIdRpContext {
|
|
3824
|
+
signature: string;
|
|
3825
|
+
expiresAt: bigint;
|
|
3826
|
+
createdAt: bigint;
|
|
3827
|
+
rpId: string;
|
|
3828
|
+
nonce: string;
|
|
3829
|
+
}
|
|
3830
|
+
export interface WriteReceipt {
|
|
3831
|
+
seq: bigint;
|
|
3832
|
+
head: Uint8Array | number[];
|
|
3833
|
+
version: bigint;
|
|
3834
|
+
}
|
|
3835
|
+
export type X402SignOutcome =
|
|
3836
|
+
{ ApprovalPending: ApprovalRequest } | { Signed: SignedAuthorization };
|
|
3837
|
+
export interface _SERVICE extends Engram {}
|
|
3838
|
+
export declare const idlFactory: IDL.InterfaceFactory;
|
|
3839
|
+
export declare const init: (args: { IDL: typeof IDL }) => IDL.Type[];
|