@fungi.computer/approvals 0.0.0-stage → 0.0.2

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.
@@ -0,0 +1,1494 @@
1
+ <!-- Generated by Botanical API docs (TypeDoc + typedoc-plugin-markdown). Do not edit. -->
2
+
3
+ **@fungi.computer/approvals**
4
+
5
+ ---
6
+
7
+ # @fungi.computer/approvals
8
+
9
+ ## Classes
10
+
11
+ ### ApprovalLedger
12
+
13
+ SQLite lifecycle beside Mycelium. Native owner transactions serialize every
14
+ transition.
15
+
16
+ #### Constructors
17
+
18
+ ##### Constructor
19
+
20
+ ```ts
21
+ new ApprovalLedger(options): ApprovalLedger;
22
+ ```
23
+
24
+ ###### Parameters
25
+
26
+ | Parameter | Type |
27
+ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
28
+ | `options` | `Readonly`\<\{ `owner`: `WatchdogSqliteOwner`; `home`: [`ApprovalHome`](#approvalhome); `now`: () => `number`; `persistIntent?`: (`record`) => `undefined`; `resultDelivery?`: `Readonly`\<\{ `retryDelay`: (`attempt`) => `number`; `attemptLimit`: `number`; \}\>; \}\> |
29
+
30
+ ###### Returns
31
+
32
+ [`ApprovalLedger`](#approvalledger)
33
+
34
+ #### Methods
35
+
36
+ ##### capability()
37
+
38
+ ```ts
39
+ capability(host): Approvals;
40
+ ```
41
+
42
+ Bound control surface; null identity means membership is gone, never an
43
+ impersonated key.
44
+
45
+ ###### Parameters
46
+
47
+ | Parameter | Type |
48
+ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
49
+ | `host` | `Readonly`\<\{ `actor`: (`record`) => `Promise`\<[`ApprovalAnswerer`](#approvalanswerer) \| `null`\>; `decision`: (`recordId`) => `Promise`\<`void`\>; `setter?`: (`rule`) => `Promise`\<[`ApprovalRuleSetter`](#approvalrulesetter) \| `null`\>; \}\> |
50
+
51
+ ###### Returns
52
+
53
+ [`Approvals`](#approvals)
54
+
55
+ ##### submit()
56
+
57
+ ```ts
58
+ submit(input, host): Promise<
59
+ | {
60
+ kind: "pending_approval";
61
+ recordId: string;
62
+ description: {
63
+ title: string;
64
+ inputBytes: number;
65
+ inputSha256: string;
66
+ };
67
+ }
68
+ | ApprovalApplyResult>;
69
+ ```
70
+
71
+ Normal tool admission returns pending immediately, or applies policy approval
72
+ inline.
73
+
74
+ ###### Parameters
75
+
76
+ | Parameter | Type |
77
+ | --------- | ------------------------------------------- |
78
+ | `input` | [`ApprovalRequest`](#approvalrequest) |
79
+ | `host` | [`ApprovalSubmitHost`](#approvalsubmithost) |
80
+
81
+ ###### Returns
82
+
83
+ `Promise`\< \| \{ `kind`: `"pending_approval"`; `recordId`: `string`;
84
+ `description`: \{ `title`: `string`; `inputBytes`: `number`; `inputSha256`:
85
+ `string`; \}; \} \| [`ApprovalApplyResult`](#approvalapplyresult)\>
86
+
87
+ ##### outcome()
88
+
89
+ ```ts
90
+ outcome(record):
91
+ | {
92
+ kind: "pending_approval";
93
+ recordId: string;
94
+ description: {
95
+ title: string;
96
+ inputBytes: number;
97
+ inputSha256: string;
98
+ };
99
+ }
100
+ | ApprovalApplyResult;
101
+ ```
102
+
103
+ A retried request's current outcome, without claiming any work.
104
+
105
+ ###### Parameters
106
+
107
+ | Parameter | Type |
108
+ | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
109
+ | `record` | \{ `recordId`: `string`; `requester`: \{ `principalId`: `string`; `agentId`: `string` \| `null`; `sessionId`: `string` \| `null`; `displayName`: `string`; \}; `module`: `string`; `operation`: `string`; `access`: `"write"` \| `"external"`; `description`: \{ `title`: `string`; `inputBytes`: `number`; `inputSha256`: `string`; \}; `evidence?`: readonly `object`[]; `authorityFence`: `string`; `reversibility`: `"reversible"` \| `"irreversible-external"`; `state`: \| `"pending"` \| `"expired"` \| `"denied"` \| `"requested"` \| `"approved"` \| `"claimed"` \| `"applied"` \| `"outcome_unknown"`; `by`: \| \{ `kind`: `"human"`; `memberId`: `string`; \} \| \{ `kind`: `"policy"`; \} \| `null`; `reason`: \| `"pending"` \| `"expired"` \| `"not-found"` \| `"not-eligible"` \| `"already-answered"` \| `"stale-revision"` \| `"declined"` \| `"fenced"` \| `"not-granted"` \| `"read-only"` \| `"in-flight"` \| `"outcome-unknown"` \| `"identity-conflict"` \| `null`; `requestedAt`: `number`; `expiresAt`: `number`; `updatedAt`: `number`; `revision`: `number`; \} |
110
+ | `record.recordId` | `string` |
111
+ | `record.requester` | \{ `principalId`: `string`; `agentId`: `string` \| `null`; `sessionId`: `string` \| `null`; `displayName`: `string`; \} |
112
+ | `record.requester.principalId` | `string` |
113
+ | `record.requester.agentId` | `string` \| `null` |
114
+ | `record.requester.sessionId` | `string` \| `null` |
115
+ | `record.requester.displayName` | `string` |
116
+ | `record.module` | `string` |
117
+ | `record.operation` | `string` |
118
+ | `record.access` | `"write"` \| `"external"` |
119
+ | `record.description` | \{ `title`: `string`; `inputBytes`: `number`; `inputSha256`: `string`; \} |
120
+ | `record.description.title` | `string` |
121
+ | `record.description.inputBytes` | `number` |
122
+ | `record.description.inputSha256` | `string` |
123
+ | `record.evidence?` | readonly `object`[] |
124
+ | `record.authorityFence` | `string` |
125
+ | `record.reversibility` | `"reversible"` \| `"irreversible-external"` |
126
+ | `record.state` | \| `"pending"` \| `"expired"` \| `"denied"` \| `"requested"` \| `"approved"` \| `"claimed"` \| `"applied"` \| `"outcome_unknown"` |
127
+ | `record.by` | \| \{ `kind`: `"human"`; `memberId`: `string`; \} \| \{ `kind`: `"policy"`; \} \| `null` |
128
+ | `record.reason` | \| `"pending"` \| `"expired"` \| `"not-found"` \| `"not-eligible"` \| `"already-answered"` \| `"stale-revision"` \| `"declined"` \| `"fenced"` \| `"not-granted"` \| `"read-only"` \| `"in-flight"` \| `"outcome-unknown"` \| `"identity-conflict"` \| `null` |
129
+ | `record.requestedAt` | `number` |
130
+ | `record.expiresAt` | `number` |
131
+ | `record.updatedAt` | `number` |
132
+ | `record.revision` | `number` |
133
+
134
+ ###### Returns
135
+
136
+ \| \{ `kind`: `"pending_approval"`; `recordId`: `string`; `description`: \{
137
+ `title`: `string`; `inputBytes`: `number`; `inputSha256`: `string`; \}; \} \|
138
+ [`ApprovalApplyResult`](#approvalapplyresult)
139
+
140
+ ##### request()
141
+
142
+ ```ts
143
+ request(input, evidence?): Promise<
144
+ | Readonly<{
145
+ kind: "refused";
146
+ reason: | "pending"
147
+ | "expired"
148
+ | "not-found"
149
+ | "not-eligible"
150
+ | "already-answered"
151
+ | "stale-revision"
152
+ | "declined"
153
+ | "fenced"
154
+ | "not-granted"
155
+ | "read-only"
156
+ | "in-flight"
157
+ | "outcome-unknown"
158
+ | "identity-conflict";
159
+ }>
160
+ | Readonly<{
161
+ kind: "record";
162
+ record: {
163
+ recordId: string;
164
+ requester: {
165
+ principalId: string;
166
+ agentId: string | null;
167
+ sessionId: string | null;
168
+ displayName: string;
169
+ };
170
+ module: string;
171
+ operation: string;
172
+ access: "write" | "external";
173
+ description: {
174
+ title: string;
175
+ inputBytes: number;
176
+ inputSha256: string;
177
+ };
178
+ evidence?: readonly object[];
179
+ authorityFence: string;
180
+ reversibility: "reversible" | "irreversible-external";
181
+ state: | "pending"
182
+ | "expired"
183
+ | "denied"
184
+ | "requested"
185
+ | "approved"
186
+ | "claimed"
187
+ | "applied"
188
+ | "outcome_unknown";
189
+ by: | {
190
+ kind: "human";
191
+ memberId: string;
192
+ }
193
+ | {
194
+ kind: "policy";
195
+ }
196
+ | null;
197
+ reason: | "pending"
198
+ | "expired"
199
+ | "not-found"
200
+ | "not-eligible"
201
+ | "already-answered"
202
+ | "stale-revision"
203
+ | "declined"
204
+ | "fenced"
205
+ | "not-granted"
206
+ | "read-only"
207
+ | "in-flight"
208
+ | "outcome-unknown"
209
+ | "identity-conflict"
210
+ | null;
211
+ requestedAt: number;
212
+ expiresAt: number;
213
+ updatedAt: number;
214
+ revision: number;
215
+ };
216
+ created: boolean;
217
+ }>>;
218
+ ```
219
+
220
+ Stage one stable intended effect. Duplicate identities never create another
221
+ action; created says whether this call staged the record.
222
+
223
+ ###### Parameters
224
+
225
+ | Parameter | Type |
226
+ | ----------- | ------------------------------------- |
227
+ | `input` | [`ApprovalRequest`](#approvalrequest) |
228
+ | `evidence?` | readonly `object`[] |
229
+
230
+ ###### Returns
231
+
232
+ `Promise`\< \| `Readonly`\<\{ `kind`: `"refused"`; `reason`: \| `"pending"` \|
233
+ `"expired"` \| `"not-found"` \| `"not-eligible"` \| `"already-answered"` \|
234
+ `"stale-revision"` \| `"declined"` \| `"fenced"` \| `"not-granted"` \|
235
+ `"read-only"` \| `"in-flight"` \| `"outcome-unknown"` \| `"identity-conflict"`;
236
+ \}\> \| `Readonly`\<\{ `kind`: `"record"`; `record`: \{ `recordId`: `string`;
237
+ `requester`: \{ `principalId`: `string`; `agentId`: `string` \| `null`;
238
+ `sessionId`: `string` \| `null`; `displayName`: `string`; \}; `module`:
239
+ `string`; `operation`: `string`; `access`: `"write"` \| `"external"`;
240
+ `description`: \{ `title`: `string`; `inputBytes`: `number`; `inputSha256`:
241
+ `string`; \}; `evidence?`: readonly `object`[]; `authorityFence`: `string`;
242
+ `reversibility`: `"reversible"` \| `"irreversible-external"`; `state`: \|
243
+ `"pending"` \| `"expired"` \| `"denied"` \| `"requested"` \| `"approved"` \|
244
+ `"claimed"` \| `"applied"` \| `"outcome_unknown"`; `by`: \| \{ `kind`:
245
+ `"human"`; `memberId`: `string`; \} \| \{ `kind`: `"policy"`; \} \| `null`;
246
+ `reason`: \| `"pending"` \| `"expired"` \| `"not-found"` \| `"not-eligible"` \|
247
+ `"already-answered"` \| `"stale-revision"` \| `"declined"` \| `"fenced"` \|
248
+ `"not-granted"` \| `"read-only"` \| `"in-flight"` \| `"outcome-unknown"` \|
249
+ `"identity-conflict"` \| `null`; `requestedAt`: `number`; `expiresAt`: `number`;
250
+ `updatedAt`: `number`; `revision`: `number`; \}; `created`: `boolean`; \}\>\>
251
+
252
+ ##### answer()
253
+
254
+ ```ts
255
+ answer(input, actor):
256
+ | Readonly<{
257
+ kind: "refused";
258
+ reason: | "pending"
259
+ | "expired"
260
+ | "not-found"
261
+ | "not-eligible"
262
+ | "already-answered"
263
+ | "stale-revision"
264
+ | "declined"
265
+ | "fenced"
266
+ | "not-granted"
267
+ | "read-only"
268
+ | "in-flight"
269
+ | "outcome-unknown"
270
+ | "identity-conflict";
271
+ }>
272
+ | Readonly<{
273
+ kind: "answered";
274
+ record: {
275
+ recordId: string;
276
+ requester: {
277
+ principalId: string;
278
+ agentId: string | null;
279
+ sessionId: string | null;
280
+ displayName: string;
281
+ };
282
+ module: string;
283
+ operation: string;
284
+ access: "write" | "external";
285
+ description: {
286
+ title: string;
287
+ inputBytes: number;
288
+ inputSha256: string;
289
+ };
290
+ evidence?: readonly object[];
291
+ authorityFence: string;
292
+ reversibility: "reversible" | "irreversible-external";
293
+ state: | "pending"
294
+ | "expired"
295
+ | "denied"
296
+ | "requested"
297
+ | "approved"
298
+ | "claimed"
299
+ | "applied"
300
+ | "outcome_unknown";
301
+ by: | {
302
+ kind: "human";
303
+ memberId: string;
304
+ }
305
+ | {
306
+ kind: "policy";
307
+ }
308
+ | null;
309
+ reason: | "pending"
310
+ | "expired"
311
+ | "not-found"
312
+ | "not-eligible"
313
+ | "already-answered"
314
+ | "stale-revision"
315
+ | "declined"
316
+ | "fenced"
317
+ | "not-granted"
318
+ | "read-only"
319
+ | "in-flight"
320
+ | "outcome-unknown"
321
+ | "identity-conflict"
322
+ | null;
323
+ requestedAt: number;
324
+ expiresAt: number;
325
+ updatedAt: number;
326
+ revision: number;
327
+ };
328
+ }>;
329
+ ```
330
+
331
+ Answering is revision-pinned and never changes the requester's underlying
332
+ grants.
333
+
334
+ ###### Parameters
335
+
336
+ | Parameter | Type |
337
+ | ------------------------ | ---------------------------------------------------------------------------------------------- |
338
+ | `input` | \{ `recordId`: `string`; `decision`: `"approve"` \| `"deny"`; `expectedRevision`: `number`; \} |
339
+ | `input.recordId` | `string` |
340
+ | `input.decision` | `"approve"` \| `"deny"` |
341
+ | `input.expectedRevision` | `number` |
342
+ | `actor` | [`ApprovalAnswerer`](#approvalanswerer) \| `null` |
343
+
344
+ ###### Returns
345
+
346
+ \| `Readonly`\<\{ `kind`: `"refused"`; `reason`: \| `"pending"` \| `"expired"`
347
+ \| `"not-found"` \| `"not-eligible"` \| `"already-answered"` \|
348
+ `"stale-revision"` \| `"declined"` \| `"fenced"` \| `"not-granted"` \|
349
+ `"read-only"` \| `"in-flight"` \| `"outcome-unknown"` \| `"identity-conflict"`;
350
+ \}\> \| `Readonly`\<\{ `kind`: `"answered"`; `record`: \{ `recordId`: `string`;
351
+ `requester`: \{ `principalId`: `string`; `agentId`: `string` \| `null`;
352
+ `sessionId`: `string` \| `null`; `displayName`: `string`; \}; `module`:
353
+ `string`; `operation`: `string`; `access`: `"write"` \| `"external"`;
354
+ `description`: \{ `title`: `string`; `inputBytes`: `number`; `inputSha256`:
355
+ `string`; \}; `evidence?`: readonly `object`[]; `authorityFence`: `string`;
356
+ `reversibility`: `"reversible"` \| `"irreversible-external"`; `state`: \|
357
+ `"pending"` \| `"expired"` \| `"denied"` \| `"requested"` \| `"approved"` \|
358
+ `"claimed"` \| `"applied"` \| `"outcome_unknown"`; `by`: \| \{ `kind`:
359
+ `"human"`; `memberId`: `string`; \} \| \{ `kind`: `"policy"`; \} \| `null`;
360
+ `reason`: \| `"pending"` \| `"expired"` \| `"not-found"` \| `"not-eligible"` \|
361
+ `"already-answered"` \| `"stale-revision"` \| `"declined"` \| `"fenced"` \|
362
+ `"not-granted"` \| `"read-only"` \| `"in-flight"` \| `"outcome-unknown"` \|
363
+ `"identity-conflict"` \| `null`; `requestedAt`: `number`; `expiresAt`: `number`;
364
+ `updatedAt`: `number`; `revision`: `number`; \}; \}\>
365
+
366
+ ##### setAutoApprove()
367
+
368
+ ```ts
369
+ setAutoApprove(input, setter):
370
+ | Readonly<{
371
+ kind: "refused";
372
+ reason: | "pending"
373
+ | "expired"
374
+ | "not-found"
375
+ | "not-eligible"
376
+ | "already-answered"
377
+ | "stale-revision"
378
+ | "declined"
379
+ | "fenced"
380
+ | "not-granted"
381
+ | "read-only"
382
+ | "in-flight"
383
+ | "outcome-unknown"
384
+ | "identity-conflict";
385
+ }>
386
+ | Readonly<{
387
+ kind: "updated";
388
+ rule: {
389
+ scope: {
390
+ agentId: string | null;
391
+ };
392
+ family: {
393
+ module: string | null;
394
+ access: "write" | "external";
395
+ };
396
+ enabled: boolean;
397
+ };
398
+ }>;
399
+ ```
400
+
401
+ Policy changes are attributed; an Agent can never enable its own writes.
402
+
403
+ ###### Parameters
404
+
405
+ | Parameter | Type |
406
+ | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
407
+ | `input` | \{ `scope`: \{ `agentId`: `string` \| `null`; \}; `family`: \{ `module`: `string` \| `null`; `access`: `"write"` \| `"external"`; \}; `enabled`: `boolean`; \} |
408
+ | `input.scope` | \{ `agentId`: `string` \| `null`; \} |
409
+ | `input.scope.agentId` | `string` \| `null` |
410
+ | `input.family` | \{ `module`: `string` \| `null`; `access`: `"write"` \| `"external"`; \} |
411
+ | `input.family.module` | `string` \| `null` |
412
+ | `input.family.access` | `"write"` \| `"external"` |
413
+ | `input.enabled` | `boolean` |
414
+ | `setter` | [`ApprovalRuleSetter`](#approvalrulesetter) \| `null` |
415
+
416
+ ###### Returns
417
+
418
+ \| `Readonly`\<\{ `kind`: `"refused"`; `reason`: \| `"pending"` \| `"expired"`
419
+ \| `"not-found"` \| `"not-eligible"` \| `"already-answered"` \|
420
+ `"stale-revision"` \| `"declined"` \| `"fenced"` \| `"not-granted"` \|
421
+ `"read-only"` \| `"in-flight"` \| `"outcome-unknown"` \| `"identity-conflict"`;
422
+ \}\> \| `Readonly`\<\{ `kind`: `"updated"`; `rule`: \{ `scope`: \{ `agentId`:
423
+ `string` \| `null`; \}; `family`: \{ `module`: `string` \| `null`; `access`:
424
+ `"write"` \| `"external"`; \}; `enabled`: `boolean`; \}; \}\>
425
+
426
+ ##### selectAutoApprove()
427
+
428
+ ```ts
429
+ selectAutoApprove(query): boolean;
430
+ ```
431
+
432
+ Pure policy selection: no record, claim, dispatch, grant widening or containment
433
+ choice.
434
+
435
+ ###### Parameters
436
+
437
+ | Parameter | Type |
438
+ | --------- | --------------------------------------- |
439
+ | `query` | [`AutoApproveQuery`](#autoapprovequery) |
440
+
441
+ ###### Returns
442
+
443
+ `boolean`
444
+
445
+ ##### expirePending()
446
+
447
+ ```ts
448
+ expirePending(): void;
449
+ ```
450
+
451
+ Expire one bounded home-local quantum without a member read or an approval.
452
+
453
+ ###### Returns
454
+
455
+ `void`
456
+
457
+ ##### nextWakeAt()
458
+
459
+ ```ts
460
+ nextWakeAt(): number | null;
461
+ ```
462
+
463
+ Earliest native wake for waiting or unfinished effects; no claim or dispatch.
464
+
465
+ ###### Returns
466
+
467
+ `number` \| `null`
468
+
469
+ ##### pendingApplications()
470
+
471
+ ```ts
472
+ pendingApplications(): readonly string[];
473
+ ```
474
+
475
+ Bounded approved work for the native owner; selection never claims or
476
+ dispatches.
477
+
478
+ ###### Returns
479
+
480
+ readonly `string`[]
481
+
482
+ ##### pendingHandoffs()
483
+
484
+ ```ts
485
+ pendingHandoffs(): readonly string[];
486
+ ```
487
+
488
+ Bounded, home-local terminal notices for the native owner's work loop.
489
+
490
+ ###### Returns
491
+
492
+ readonly `string`[]
493
+
494
+ ##### handoff()
495
+
496
+ ```ts
497
+ handoff(recordId, send): Promise<ApprovalHandoffResult>;
498
+ ```
499
+
500
+ Retry only the ordinary message, with the same recipient-side idempotency key. A
501
+ send rejection leaves the intent pending; it never reopens effect execution. The
502
+ host must return the real Session acceptance, not a success-shaped placeholder.
503
+
504
+ ###### Parameters
505
+
506
+ | Parameter | Type |
507
+ | ---------- | --------------------------------------------------------------------- |
508
+ | `recordId` | `string` |
509
+ | `send` | (`notice`) => `Promise`\<`Readonly`\<\{ `commandId`: `string`; \}\>\> |
510
+
511
+ ###### Returns
512
+
513
+ `Promise`\<[`ApprovalHandoffResult`](#approvalhandoffresult)\>
514
+
515
+ ##### apply()
516
+
517
+ ```ts
518
+ apply(recordId, host): Promise<ApprovalApplyResult>;
519
+ ```
520
+
521
+ The home's work loop: only a durable approved record claims the existing host
522
+ operation, and its result always reaches a waiting Agent as a message.
523
+
524
+ ###### Parameters
525
+
526
+ | Parameter | Type |
527
+ | ---------- | ----------------------------------------- |
528
+ | `recordId` | `string` |
529
+ | `host` | [`ApprovalApplyHost`](#approvalapplyhost) |
530
+
531
+ ###### Returns
532
+
533
+ `Promise`\<[`ApprovalApplyResult`](#approvalapplyresult)\>
534
+
535
+ ##### applyInline()
536
+
537
+ ```ts
538
+ applyInline(recordId, host): Promise<ApprovalApplyResult>;
539
+ ```
540
+
541
+ Apply the caller's own just-staged policy approval inside its live tool call;
542
+ that call's result is the outcome, so no later message is owed.
543
+
544
+ ###### Parameters
545
+
546
+ | Parameter | Type |
547
+ | ---------- | ----------------------------------------- |
548
+ | `recordId` | `string` |
549
+ | `host` | [`ApprovalApplyHost`](#approvalapplyhost) |
550
+
551
+ ###### Returns
552
+
553
+ `Promise`\<[`ApprovalApplyResult`](#approvalapplyresult)\>
554
+
555
+ ##### recoverClaims()
556
+
557
+ ```ts
558
+ recoverClaims(): readonly object[];
559
+ ```
560
+
561
+ Native host boot only: orphaned durable claims must never be redispatched.
562
+
563
+ ###### Returns
564
+
565
+ readonly `object`[]
566
+
567
+ ##### get()
568
+
569
+ ```ts
570
+ get(recordId):
571
+ | {
572
+ recordId: string;
573
+ requester: {
574
+ principalId: string;
575
+ agentId: string | null;
576
+ sessionId: string | null;
577
+ displayName: string;
578
+ };
579
+ module: string;
580
+ operation: string;
581
+ access: "write" | "external";
582
+ description: {
583
+ title: string;
584
+ inputBytes: number;
585
+ inputSha256: string;
586
+ };
587
+ evidence?: readonly object[];
588
+ authorityFence: string;
589
+ reversibility: "reversible" | "irreversible-external";
590
+ state: | "pending"
591
+ | "expired"
592
+ | "denied"
593
+ | "requested"
594
+ | "approved"
595
+ | "claimed"
596
+ | "applied"
597
+ | "outcome_unknown";
598
+ by: | {
599
+ kind: "human";
600
+ memberId: string;
601
+ }
602
+ | {
603
+ kind: "policy";
604
+ }
605
+ | null;
606
+ reason: | "pending"
607
+ | "expired"
608
+ | "not-found"
609
+ | "not-eligible"
610
+ | "already-answered"
611
+ | "stale-revision"
612
+ | "declined"
613
+ | "fenced"
614
+ | "not-granted"
615
+ | "read-only"
616
+ | "in-flight"
617
+ | "outcome-unknown"
618
+ | "identity-conflict"
619
+ | null;
620
+ requestedAt: number;
621
+ expiresAt: number;
622
+ updatedAt: number;
623
+ revision: number;
624
+ }
625
+ | null;
626
+ ```
627
+
628
+ Read a record from this home only; the maintained decoder owns stored JSON.
629
+
630
+ ###### Parameters
631
+
632
+ | Parameter | Type |
633
+ | ---------- | -------- |
634
+ | `recordId` | `string` |
635
+
636
+ ###### Returns
637
+
638
+ \| \{ `recordId`: `string`; `requester`: \{ `principalId`: `string`; `agentId`:
639
+ `string` \| `null`; `sessionId`: `string` \| `null`; `displayName`: `string`;
640
+ \}; `module`: `string`; `operation`: `string`; `access`: `"write"` \|
641
+ `"external"`; `description`: \{ `title`: `string`; `inputBytes`: `number`;
642
+ `inputSha256`: `string`; \}; `evidence?`: readonly `object`[]; `authorityFence`:
643
+ `string`; `reversibility`: `"reversible"` \| `"irreversible-external"`; `state`:
644
+ \| `"pending"` \| `"expired"` \| `"denied"` \| `"requested"` \| `"approved"` \|
645
+ `"claimed"` \| `"applied"` \| `"outcome_unknown"`; `by`: \| \{ `kind`:
646
+ `"human"`; `memberId`: `string`; \} \| \{ `kind`: `"policy"`; \} \| `null`;
647
+ `reason`: \| `"pending"` \| `"expired"` \| `"not-found"` \| `"not-eligible"` \|
648
+ `"already-answered"` \| `"stale-revision"` \| `"declined"` \| `"fenced"` \|
649
+ `"not-granted"` \| `"read-only"` \| `"in-flight"` \| `"outcome-unknown"` \|
650
+ `"identity-conflict"` \| `null`; `requestedAt`: `number`; `expiresAt`: `number`;
651
+ `updatedAt`: `number`; `revision`: `number`; \} \| `null`
652
+
653
+ ## Type Aliases
654
+
655
+ ### PendingApproval
656
+
657
+ ```ts
658
+ type PendingApproval = typeof PendingApprovalSchema.Type;
659
+ ```
660
+
661
+ Deferred apply is delivered later through the existing Agent new-message path.
662
+
663
+ ---
664
+
665
+ ### ApprovalEvidence
666
+
667
+ ```ts
668
+ type ApprovalEvidence = typeof ApprovalEvidenceSchema.Type;
669
+ ```
670
+
671
+ Metadata only: never raw image bytes, prose, URLs or executable content.
672
+
673
+ ---
674
+
675
+ ### ApprovalRecord
676
+
677
+ ```ts
678
+ type ApprovalRecord = typeof ApprovalRecordSchema.Type;
679
+ ```
680
+
681
+ Durable approval visible to every renderer.
682
+
683
+ ---
684
+
685
+ ### ApprovalView
686
+
687
+ ```ts
688
+ type ApprovalView = typeof ApprovalViewSchema.Type;
689
+ ```
690
+
691
+ Current holder's projection. A disabled button is not an authorization check.
692
+
693
+ ---
694
+
695
+ ### ApprovalListInput
696
+
697
+ ```ts
698
+ type ApprovalListInput = typeof ApprovalListInputSchema.Type;
699
+ ```
700
+
701
+ Bounded listing request.
702
+
703
+ ---
704
+
705
+ ### ApprovalAnswerInput
706
+
707
+ ```ts
708
+ type ApprovalAnswerInput = typeof ApprovalAnswerInputSchema.Type;
709
+ ```
710
+
711
+ Revision-pinned answer. No actor identity is accepted on the wire.
712
+
713
+ ---
714
+
715
+ ### AutoApproveInput
716
+
717
+ ```ts
718
+ type AutoApproveInput = typeof AutoApproveInputSchema.Type;
719
+ ```
720
+
721
+ One per-home or per-Agent module/access rule.
722
+
723
+ ---
724
+
725
+ ### ApprovalRefusal
726
+
727
+ ```ts
728
+ type ApprovalRefusal = Readonly<{
729
+ kind: "refused";
730
+ reason: typeof ApprovalRefusalReasonSchema.Type;
731
+ }>;
732
+ ```
733
+
734
+ One typed refusal shared by answer/apply/policy entrypoints.
735
+
736
+ ---
737
+
738
+ ### Approvals
739
+
740
+ ```ts
741
+ type Approvals = Readonly<{
742
+ list: Promise<
743
+ Readonly<{
744
+ items: readonly ApprovalView[];
745
+ nextCursor: string | null;
746
+ }>
747
+ >;
748
+ get: Promise<{
749
+ record: {
750
+ recordId: string;
751
+ requester: {
752
+ principalId: string;
753
+ agentId: string | null;
754
+ sessionId: string | null;
755
+ displayName: string;
756
+ };
757
+ module: string;
758
+ operation: string;
759
+ access: "write" | "external";
760
+ description: {
761
+ title: string;
762
+ inputBytes: number;
763
+ inputSha256: string;
764
+ };
765
+ evidence?: readonly object[];
766
+ authorityFence: string;
767
+ reversibility: "reversible" | "irreversible-external";
768
+ state:
769
+ | "pending"
770
+ | "expired"
771
+ | "denied"
772
+ | "requested"
773
+ | "approved"
774
+ | "claimed"
775
+ | "applied"
776
+ | "outcome_unknown";
777
+ by:
778
+ | {
779
+ kind: "human";
780
+ memberId: string;
781
+ }
782
+ | {
783
+ kind: "policy";
784
+ }
785
+ | null;
786
+ reason:
787
+ | "pending"
788
+ | "expired"
789
+ | "not-found"
790
+ | "not-eligible"
791
+ | "already-answered"
792
+ | "stale-revision"
793
+ | "declined"
794
+ | "fenced"
795
+ | "not-granted"
796
+ | "read-only"
797
+ | "in-flight"
798
+ | "outcome-unknown"
799
+ | "identity-conflict"
800
+ | null;
801
+ requestedAt: number;
802
+ expiresAt: number;
803
+ updatedAt: number;
804
+ revision: number;
805
+ };
806
+ canAnswer: boolean;
807
+ canSetAutoApprove: boolean;
808
+ } | null>;
809
+ answer: Promise<
810
+ | Readonly<{
811
+ kind: "refused";
812
+ reason: typeof ApprovalRefusalReasonSchema.Type;
813
+ }>
814
+ | Readonly<{
815
+ kind: "answered";
816
+ view: ApprovalView;
817
+ }>
818
+ >;
819
+ setAutoApprove: Promise<
820
+ | Readonly<{
821
+ kind: "refused";
822
+ reason: typeof ApprovalRefusalReasonSchema.Type;
823
+ }>
824
+ | Readonly<{
825
+ kind: "updated";
826
+ rule: AutoApproveInput;
827
+ }>
828
+ >;
829
+ }>;
830
+ ```
831
+
832
+ The member-bound capability. Host authentication supplies the actor.
833
+
834
+ ---
835
+
836
+ ### ApprovalHome
837
+
838
+ ```ts
839
+ type ApprovalHome = Readonly<{
840
+ kind: "team" | "oyster" | "local";
841
+ id: string;
842
+ }>;
843
+ ```
844
+
845
+ Native owner of this ledger; the Local runtime supplies its own SQLite owner.
846
+
847
+ ---
848
+
849
+ ### ApprovalRequest
850
+
851
+ ```ts
852
+ type ApprovalRequest = Readonly<{
853
+ requester: ApprovalRecord["requester"];
854
+ module: string;
855
+ operation: string;
856
+ access: ApprovalRecord["access"];
857
+ reversibility: ApprovalRecord["reversibility"];
858
+ authorityFence: string;
859
+ idempotencyKey: string;
860
+ inputJson: string;
861
+ }>;
862
+ ```
863
+
864
+ A request is host-attested metadata and JSON bytes, never renderer-provided
865
+ identity.
866
+
867
+ ---
868
+
869
+ ### AutoApproveQuery
870
+
871
+ ```ts
872
+ type AutoApproveQuery = Readonly<{
873
+ agentId: ApprovalRequest["requester"]["agentId"];
874
+ module: ApprovalRequest["module"];
875
+ access: ApprovalRequest["access"];
876
+ }>;
877
+ ```
878
+
879
+ Host-only policy read for an admitted Agent/module/access selection, not
880
+ execution authority.
881
+
882
+ ---
883
+
884
+ ### ApprovalAnswerer
885
+
886
+ ```ts
887
+ type ApprovalAnswerer =
888
+ | Readonly<{
889
+ kind: "human";
890
+ memberId: string;
891
+ role: "owner" | "admin" | "member";
892
+ actingForAgent: boolean;
893
+ mayUseOperation: boolean;
894
+ }>
895
+ | Readonly<{
896
+ kind: "agent" | "key";
897
+ }>;
898
+ ```
899
+
900
+ Host-attested human identity and current authority over this exact operation.
901
+
902
+ ---
903
+
904
+ ### ApprovalRuleSetter
905
+
906
+ ```ts
907
+ type ApprovalRuleSetter =
908
+ | ApprovalAnswerer
909
+ | (Extract<
910
+ ApprovalAnswerer,
911
+ {
912
+ kind: "human";
913
+ }
914
+ > &
915
+ Readonly<{
916
+ mayManageAgent: boolean;
917
+ }>);
918
+ ```
919
+
920
+ Host-attested authority to write one auto-approve rule. A Team home resolves it
921
+ against the exact rule: mayUseOperation for that family and mayManageAgent
922
+ (agent.manage on that Agent; owners and admins hold it Team-wide). An answerer
923
+ without mayManageAgent never manages an Agent. Oyster and Local homes are
924
+ owner-only.
925
+
926
+ ---
927
+
928
+ ### ApprovalAdmission
929
+
930
+ ```ts
931
+ type ApprovalAdmission =
932
+ | Readonly<{
933
+ kind: "authorized";
934
+ authorityFence: string;
935
+ }>
936
+ | Readonly<{
937
+ kind: "refused";
938
+ reason: "not-granted" | "read-only";
939
+ }>;
940
+ ```
941
+
942
+ Mycelium owns admission; the ledger compares its opaque fence, never grant
943
+ grammar.
944
+
945
+ ---
946
+
947
+ ### ApprovalDispatchCompletion
948
+
949
+ ```ts
950
+ type ApprovalDispatchCompletion =
951
+ | Readonly<{
952
+ kind: "completed";
953
+ output: typeof Schema.Json.Type;
954
+ }>
955
+ | Readonly<{
956
+ kind: "refused";
957
+ reason: "not-granted" | "read-only";
958
+ }>;
959
+ ```
960
+
961
+ Host verdict outside App JSON: only an attested zero-effect refusal is denied.
962
+
963
+ ---
964
+
965
+ ### ApprovalApplyHost
966
+
967
+ ```ts
968
+ type ApprovalApplyHost = Readonly<{
969
+ recheck: (record) => Promise<ApprovalAdmission>;
970
+ dispatch: (request) => Promise<ApprovalDispatchCompletion>;
971
+ }>;
972
+ ```
973
+
974
+ Host-only adapter to the existing operation door; not an Agent continuation.
975
+
976
+ ---
977
+
978
+ ### ApprovalSubmitHost
979
+
980
+ ```ts
981
+ type ApprovalSubmitHost = ApprovalApplyHost &
982
+ Readonly<{
983
+ evidence?: ApprovalEvidence;
984
+ }>;
985
+ ```
986
+
987
+ Only the submitting capability may attach evidence; never spread tool input
988
+ here.
989
+
990
+ ---
991
+
992
+ ### ApprovalApplyResult
993
+
994
+ ```ts
995
+ type ApprovalApplyResult =
996
+ | Readonly<{
997
+ kind: "applied";
998
+ record: ApprovalRecord;
999
+ output: typeof Schema.Json.Type;
1000
+ }>
1001
+ | ApprovalRefusal;
1002
+ ```
1003
+
1004
+ Private result for inline tool output or ordinary deferred new-message delivery.
1005
+
1006
+ ---
1007
+
1008
+ ### ApprovalResultNotice
1009
+
1010
+ ```ts
1011
+ type ApprovalResultNotice = Readonly<{
1012
+ deliveryId: string;
1013
+ record: ApprovalRecord;
1014
+ result: ApprovalApplyResult;
1015
+ }>;
1016
+ ```
1017
+
1018
+ Deferred result cargo; stored request input is not a field on this port.
1019
+
1020
+ ---
1021
+
1022
+ ### ApprovalHandoffResult
1023
+
1024
+ ```ts
1025
+ type ApprovalHandoffResult =
1026
+ | Readonly<{
1027
+ kind: "delivered";
1028
+ commandId: string;
1029
+ }>
1030
+ | Readonly<{
1031
+ kind: "not-required";
1032
+ }>
1033
+ | Readonly<{
1034
+ kind: "undeliverable";
1035
+ }>
1036
+ | ApprovalRefusal;
1037
+ ```
1038
+
1039
+ Ordinary new-message receipt, explicit no-delivery result, or typed refusal.
1040
+
1041
+ ## Variables
1042
+
1043
+ ### ApprovalAccessSchema
1044
+
1045
+ ```ts
1046
+ const ApprovalAccessSchema: Literals<readonly ["write", "external"]>;
1047
+ ```
1048
+
1049
+ The effect class is independent of reversibility; ON includes both.
1050
+
1051
+ ---
1052
+
1053
+ ### ApprovalFamilySchema
1054
+
1055
+ ```ts
1056
+ const ApprovalFamilySchema: Struct<{
1057
+ module: NullOr<String>;
1058
+ access: Literals<readonly ["write", "external"]>;
1059
+ }>;
1060
+ ```
1061
+
1062
+ One operation module, or every module when module is null.
1063
+
1064
+ ---
1065
+
1066
+ ### ApprovalScopeSchema
1067
+
1068
+ ```ts
1069
+ const ApprovalScopeSchema: Struct<{
1070
+ agentId: NullOr<String>;
1071
+ }>;
1072
+ ```
1073
+
1074
+ One requesting Agent, or the entire home when agentId is null.
1075
+
1076
+ ---
1077
+
1078
+ ### ApprovalRequesterSchema
1079
+
1080
+ ```ts
1081
+ const ApprovalRequesterSchema: Struct<{
1082
+ principalId: String;
1083
+ agentId: NullOr<String>;
1084
+ sessionId: NullOr<String>;
1085
+ displayName: String;
1086
+ }>;
1087
+ ```
1088
+
1089
+ Stable requester identity supplied by the host, never by tool arguments.
1090
+
1091
+ ---
1092
+
1093
+ ### ApprovalDescriptionSchema
1094
+
1095
+ ```ts
1096
+ const ApprovalDescriptionSchema: Struct<{
1097
+ title: String;
1098
+ inputBytes: Int;
1099
+ inputSha256: String;
1100
+ }>;
1101
+ ```
1102
+
1103
+ A renderer sees metadata and a byte digest, never the proposed input.
1104
+
1105
+ ---
1106
+
1107
+ ### PendingApprovalSchema
1108
+
1109
+ ```ts
1110
+ const PendingApprovalSchema: Struct<{
1111
+ kind: Literal<"pending_approval">;
1112
+ recordId: String;
1113
+ description: Struct<{
1114
+ title: String;
1115
+ inputBytes: Int;
1116
+ inputSha256: String;
1117
+ }>;
1118
+ }>;
1119
+ ```
1120
+
1121
+ Immediate normal tool result: no effect ran and no Agent turn is suspended.
1122
+
1123
+ ---
1124
+
1125
+ ### ApprovalStateSchema
1126
+
1127
+ ```ts
1128
+ const ApprovalStateSchema: Literals<
1129
+ readonly [
1130
+ "requested",
1131
+ "pending",
1132
+ "approved",
1133
+ "claimed",
1134
+ "applied",
1135
+ "denied",
1136
+ "expired",
1137
+ "outcome_unknown",
1138
+ ]
1139
+ >;
1140
+ ```
1141
+
1142
+ All renderers use these same durable lifecycle states.
1143
+
1144
+ ---
1145
+
1146
+ ### ApprovalRefusalReasonSchema
1147
+
1148
+ ```ts
1149
+ const ApprovalRefusalReasonSchema: Literals<
1150
+ readonly [
1151
+ "not-found",
1152
+ "not-eligible",
1153
+ "already-answered",
1154
+ "stale-revision",
1155
+ "expired",
1156
+ "declined",
1157
+ "fenced",
1158
+ "not-granted",
1159
+ "read-only",
1160
+ "pending",
1161
+ "in-flight",
1162
+ "outcome-unknown",
1163
+ "identity-conflict",
1164
+ ]
1165
+ >;
1166
+ ```
1167
+
1168
+ Why a decision or apply was refused; unknown dispatch is never a denial.
1169
+
1170
+ ---
1171
+
1172
+ ### MAX\_APPROVAL\_EVIDENCE
1173
+
1174
+ ```ts
1175
+ const MAX_APPROVAL_EVIDENCE: 4 = 4;
1176
+ ```
1177
+
1178
+ Defensive display limits, not authority to fetch or interpret image content.
1179
+
1180
+ ---
1181
+
1182
+ ### MAX\_APPROVAL\_EVIDENCE\_BYTES
1183
+
1184
+ ```ts
1185
+ const MAX_APPROVAL_EVIDENCE_BYTES: number;
1186
+ ```
1187
+
1188
+ Maximum attested PNG byte length in one evidence descriptor.
1189
+
1190
+ ---
1191
+
1192
+ ### ApprovalEvidenceSchema
1193
+
1194
+ ```ts
1195
+ const ApprovalEvidenceSchema: $Array<
1196
+ Struct<{
1197
+ kind: Literal<"artifact">;
1198
+ ref: String;
1199
+ mediaType: Literal<"image/png">;
1200
+ bytes: Int;
1201
+ }>
1202
+ >;
1203
+ ```
1204
+
1205
+ Capability-attested content address; image bytes remain untrusted display-only
1206
+ data.
1207
+
1208
+ ---
1209
+
1210
+ ### ApprovalRecordSchema
1211
+
1212
+ ```ts
1213
+ const ApprovalRecordSchema: Struct<{
1214
+ recordId: String;
1215
+ requester: Struct<{
1216
+ principalId: String;
1217
+ agentId: NullOr<String>;
1218
+ sessionId: NullOr<String>;
1219
+ displayName: String;
1220
+ }>;
1221
+ module: String;
1222
+ operation: String;
1223
+ access: Literals<readonly ["write", "external"]>;
1224
+ description: Struct<{
1225
+ title: String;
1226
+ inputBytes: Int;
1227
+ inputSha256: String;
1228
+ }>;
1229
+ evidence: optionalKey<
1230
+ $Array<
1231
+ Struct<{
1232
+ kind: Literal<"artifact">;
1233
+ ref: String;
1234
+ mediaType: Literal<"image/png">;
1235
+ bytes: Int;
1236
+ }>
1237
+ >
1238
+ >;
1239
+ authorityFence: String;
1240
+ reversibility: Literals<readonly ["reversible", "irreversible-external"]>;
1241
+ state: Literals<
1242
+ readonly [
1243
+ "requested",
1244
+ "pending",
1245
+ "approved",
1246
+ "claimed",
1247
+ "applied",
1248
+ "denied",
1249
+ "expired",
1250
+ "outcome_unknown",
1251
+ ]
1252
+ >;
1253
+ by: NullOr<
1254
+ Union<
1255
+ readonly [
1256
+ Struct<{
1257
+ kind: Literal<"human">;
1258
+ memberId: String;
1259
+ }>,
1260
+ Struct<{
1261
+ kind: Literal<"policy">;
1262
+ }>,
1263
+ ]
1264
+ >
1265
+ >;
1266
+ reason: NullOr<
1267
+ Literals<
1268
+ readonly [
1269
+ "not-found",
1270
+ "not-eligible",
1271
+ "already-answered",
1272
+ "stale-revision",
1273
+ "expired",
1274
+ "declined",
1275
+ "fenced",
1276
+ "not-granted",
1277
+ "read-only",
1278
+ "pending",
1279
+ "in-flight",
1280
+ "outcome-unknown",
1281
+ "identity-conflict",
1282
+ ]
1283
+ >
1284
+ >;
1285
+ requestedAt: Int;
1286
+ expiresAt: Int;
1287
+ updatedAt: Int;
1288
+ revision: Int;
1289
+ }>;
1290
+ ```
1291
+
1292
+ Public record. Effect input, output and executable continuations stay
1293
+ host-private.
1294
+
1295
+ ---
1296
+
1297
+ ### ApprovalViewSchema
1298
+
1299
+ ```ts
1300
+ const ApprovalViewSchema: Struct<{
1301
+ record: Struct<{
1302
+ recordId: String;
1303
+ requester: Struct<{
1304
+ principalId: String;
1305
+ agentId: NullOr<String>;
1306
+ sessionId: NullOr<String>;
1307
+ displayName: String;
1308
+ }>;
1309
+ module: String;
1310
+ operation: String;
1311
+ access: Literals<readonly ["write", "external"]>;
1312
+ description: Struct<{
1313
+ title: String;
1314
+ inputBytes: Int;
1315
+ inputSha256: String;
1316
+ }>;
1317
+ evidence: optionalKey<
1318
+ $Array<
1319
+ Struct<{
1320
+ kind: Literal<"artifact">;
1321
+ ref: String;
1322
+ mediaType: Literal<"image/png">;
1323
+ bytes: Int;
1324
+ }>
1325
+ >
1326
+ >;
1327
+ authorityFence: String;
1328
+ reversibility: Literals<readonly ["reversible", "irreversible-external"]>;
1329
+ state: Literals<
1330
+ readonly [
1331
+ "requested",
1332
+ "pending",
1333
+ "approved",
1334
+ "claimed",
1335
+ "applied",
1336
+ "denied",
1337
+ "expired",
1338
+ "outcome_unknown",
1339
+ ]
1340
+ >;
1341
+ by: NullOr<
1342
+ Union<
1343
+ readonly [
1344
+ Struct<{
1345
+ kind: Literal<"human">;
1346
+ memberId: String;
1347
+ }>,
1348
+ Struct<{
1349
+ kind: Literal<"policy">;
1350
+ }>,
1351
+ ]
1352
+ >
1353
+ >;
1354
+ reason: NullOr<
1355
+ Literals<
1356
+ readonly [
1357
+ "not-found",
1358
+ "not-eligible",
1359
+ "already-answered",
1360
+ "stale-revision",
1361
+ "expired",
1362
+ "declined",
1363
+ "fenced",
1364
+ "not-granted",
1365
+ "read-only",
1366
+ "pending",
1367
+ "in-flight",
1368
+ "outcome-unknown",
1369
+ "identity-conflict",
1370
+ ]
1371
+ >
1372
+ >;
1373
+ requestedAt: Int;
1374
+ expiresAt: Int;
1375
+ updatedAt: Int;
1376
+ revision: Int;
1377
+ }>;
1378
+ canAnswer: Boolean;
1379
+ canSetAutoApprove: Boolean;
1380
+ }>;
1381
+ ```
1382
+
1383
+ Rights are recomputed for the holder on each read, not persisted on the record.
1384
+
1385
+ ---
1386
+
1387
+ ### ApprovalListInputSchema
1388
+
1389
+ ```ts
1390
+ const ApprovalListInputSchema: Struct<{
1391
+ state: optionalKey<
1392
+ Literals<
1393
+ readonly [
1394
+ "requested",
1395
+ "pending",
1396
+ "approved",
1397
+ "claimed",
1398
+ "applied",
1399
+ "denied",
1400
+ "expired",
1401
+ "outcome_unknown",
1402
+ ]
1403
+ >
1404
+ >;
1405
+ cursor: optionalKey<String>;
1406
+ limit: optionalKey<Int>;
1407
+ }>;
1408
+ ```
1409
+
1410
+ Bounded reads with an opaque storage cursor.
1411
+
1412
+ ---
1413
+
1414
+ ### ApprovalGetInputSchema
1415
+
1416
+ ```ts
1417
+ const ApprovalGetInputSchema: Struct<{
1418
+ recordId: String;
1419
+ }>;
1420
+ ```
1421
+
1422
+ Locate one public view without carrying actor identity in request data.
1423
+
1424
+ ---
1425
+
1426
+ ### ApprovalAnswerInputSchema
1427
+
1428
+ ```ts
1429
+ const ApprovalAnswerInputSchema: Struct<{
1430
+ recordId: String;
1431
+ decision: Literals<readonly ["approve", "deny"]>;
1432
+ expectedRevision: Int;
1433
+ }>;
1434
+ ```
1435
+
1436
+ An answer is a decision, never a confirm-labelled write itself.
1437
+
1438
+ ---
1439
+
1440
+ ### AutoApproveInputSchema
1441
+
1442
+ ```ts
1443
+ const AutoApproveInputSchema: Struct<{
1444
+ scope: Struct<{
1445
+ agentId: NullOr<String>;
1446
+ }>;
1447
+ family: Struct<{
1448
+ module: NullOr<String>;
1449
+ access: Literals<readonly ["write", "external"]>;
1450
+ }>;
1451
+ enabled: Boolean;
1452
+ }>;
1453
+ ```
1454
+
1455
+ Explicit policy mutation. A false rule narrows a broader true rule.
1456
+
1457
+ ---
1458
+
1459
+ ### ApprovalRefusalSchema
1460
+
1461
+ ```ts
1462
+ const ApprovalRefusalSchema: Struct<{
1463
+ kind: Literal<"refused">;
1464
+ reason: Literals<
1465
+ readonly [
1466
+ "not-found",
1467
+ "not-eligible",
1468
+ "already-answered",
1469
+ "stale-revision",
1470
+ "expired",
1471
+ "declined",
1472
+ "fenced",
1473
+ "not-granted",
1474
+ "read-only",
1475
+ "pending",
1476
+ "in-flight",
1477
+ "outcome-unknown",
1478
+ "identity-conflict",
1479
+ ]
1480
+ >;
1481
+ }>;
1482
+ ```
1483
+
1484
+ Canonical zero-effect or lifecycle refusal at a tool result boundary.
1485
+
1486
+ ---
1487
+
1488
+ ### DEFAULT\_APPROVAL\_EXPIRY\_MS
1489
+
1490
+ ```ts
1491
+ const DEFAULT_APPROVAL_EXPIRY_MS: number;
1492
+ ```
1493
+
1494
+ The initial owner-controlled wait duration; passing the deadline never approves.