@engramx/idl 0.16.0-rc.2 → 0.16.0-rc.21

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.
@@ -22,8 +22,10 @@ export interface AnchorConflict {
22
22
  }
23
23
  export interface AnchorStats {
24
24
  lastAnchorAtNs: [] | [bigint];
25
+ lastEngramAnchorAtNs: [] | [bigint];
25
26
  engramsAnchored: bigint;
26
27
  totalAnchors: bigint;
28
+ engramChainsAnchored: [] | [bigint];
27
29
  engramsWithConflicts: bigint;
28
30
  }
29
31
  export interface AnchorView {
@@ -69,6 +71,10 @@ export interface CertifiedAuditHead {
69
71
  size: bigint;
70
72
  witness: [] | [Uint8Array | number[]];
71
73
  }
74
+ export interface CertifiedBirth {
75
+ certificate: [] | [Uint8Array | number[]];
76
+ witness: Uint8Array | number[];
77
+ }
72
78
  export interface CertifiedStanding {
73
79
  certificate: [] | [Uint8Array | number[]];
74
80
  leaf: StandingLeaf;
@@ -116,6 +122,18 @@ export interface EngagementRow {
116
122
  startedDay: bigint;
117
123
  engram: Principal;
118
124
  }
125
+ export interface EngramComputeView {
126
+ restartOpenUntilNs: [] | [bigint];
127
+ idlePerDay: bigint;
128
+ line: bigint;
129
+ quiet: boolean;
130
+ eraseAboutNs: [] | [bigint];
131
+ cycles: bigint;
132
+ runState: { stopped: null } | { stopping: null } | { running: null };
133
+ thresholdSecs: bigint;
134
+ updateWaiting: boolean;
135
+ frozen: boolean;
136
+ }
119
137
  export interface EngramRecordView {
120
138
  status: EngramStatus;
121
139
  owner: Principal;
@@ -254,6 +272,13 @@ export interface PrivateMetrics {
254
272
  totalEngrams: bigint;
255
273
  activeEngrams: bigint;
256
274
  }
275
+ export interface RecordPage {
276
+ ringFloor: bigint;
277
+ total: bigint;
278
+ sealed: Array<SealedEntry>;
279
+ items: Array<AuditEntry>;
280
+ hashFirstFrom: bigint;
281
+ }
257
282
  export interface ReferralCounts {
258
283
  firstOrReopened: PairedSoon;
259
284
  openedThroughParentLive: bigint;
@@ -270,28 +295,61 @@ export interface ReserveGateConfig {
270
295
  inviteIssuer: Principal;
271
296
  trustedSigners: Array<Principal>;
272
297
  }
298
+ export interface RestartReply {
299
+ securityInstalled: boolean;
300
+ lentCycles: bigint;
301
+ updateWaiting: boolean;
302
+ installError: [] | [string];
303
+ engramTold: boolean;
304
+ }
305
+ export interface RestartStatus {
306
+ nextRestartAtNs: [] | [bigint];
307
+ loanOwed: bigint;
308
+ openUntilNs: [] | [bigint];
309
+ }
310
+ export interface RestartTotals {
311
+ repaid: bigint;
312
+ advanceOutstanding: bigint;
313
+ outstanding: bigint;
314
+ lent: bigint;
315
+ advanceReturned: bigint;
316
+ writtenOff: bigint;
317
+ advanceWrittenOff: bigint;
318
+ advancePaid: bigint;
319
+ }
273
320
  export type Result = { Ok: null } | { Err: Error };
274
321
  export type Result_1 = { Ok: Principal } | { Err: Error };
275
- export type Result_10 = { Ok: Page_3 } | { Err: Error };
276
- export type Result_11 = { Ok: Array<OpenedEngram> } | { Err: Error };
277
- export type Result_12 = { Ok: Page_5 } | { Err: Error };
278
- export type Result_13 = { Ok: Page_6 } | { Err: Error };
279
- export type Result_14 = { Ok: [] | [string] } | { Err: Error };
280
- export type Result_15 = { Ok: ReferralCounts } | { Err: Error };
281
- export type Result_16 = { Ok: OpeningCounts } | { Err: Error };
282
- export type Result_17 = { Ok: PrivateMetrics } | { Err: Error };
283
- export type Result_18 = { Ok: Uint8Array | number[] } | { Err: Error };
284
- export type Result_19 = { Ok: OpenedThrough } | { Err: Error };
285
- export type Result_2 = { Ok: ControlStep } | { Err: Error };
286
- export type Result_20 = { Ok: CertifiedStanding } | { Err: Error };
287
- export type Result_21 = { Ok: FleetCycleHealth } | { Err: Error };
288
- export type Result_3 = { Ok: MeterReading } | { Err: Error };
289
- export type Result_4 = { Ok: bigint } | { Err: Error };
290
- export type Result_5 = { Ok: CustodyMode } | { Err: Error };
291
- export type Result_6 = { Ok: Array<string> } | { Err: Error };
292
- export type Result_7 = { Ok: Page } | { Err: Error };
293
- export type Result_8 = { Ok: Page_1 } | { Err: Error };
294
- export type Result_9 = { Ok: Page_2 } | { Err: Error };
322
+ export type Result_10 = { Ok: CustodyMode } | { Err: Error };
323
+ export type Result_11 = { Ok: Array<string> } | { Err: Error };
324
+ export type Result_12 = { Ok: Page } | { Err: Error };
325
+ export type Result_13 = { Ok: Page_1 } | { Err: Error };
326
+ export type Result_14 = { Ok: Page_2 } | { Err: Error };
327
+ export type Result_15 = { Ok: Page_3 } | { Err: Error };
328
+ export type Result_16 = { Ok: Array<OpenedEngram> } | { Err: Error };
329
+ export type Result_17 = { Ok: Page_5 } | { Err: Error };
330
+ export type Result_18 = { Ok: RecordPage } | { Err: Error };
331
+ export type Result_19 = { Ok: Page_6 } | { Err: Error };
332
+ export type Result_2 = { Ok: { accepted: bigint } } | { Err: Error };
333
+ export type Result_20 = { Ok: [] | [string] } | { Err: Error };
334
+ export type Result_21 = { Ok: ReferralCounts } | { Err: Error };
335
+ export type Result_22 = { Ok: OpenedThrough } | { Err: Error };
336
+ export type Result_23 = { Ok: OpeningCounts } | { Err: Error };
337
+ export type Result_24 = { Ok: RestartStatus } | { Err: Error };
338
+ export type Result_25 = { Ok: PrivateMetrics } | { Err: Error };
339
+ export type Result_26 = { Ok: Uint8Array | number[] } | { Err: Error };
340
+ export type Result_27 = { Ok: CertifiedStanding } | { Err: Error };
341
+ export type Result_28 = { Ok: FleetCycleHealth } | { Err: Error };
342
+ export type Result_3 = { Ok: ControlStep } | { Err: Error };
343
+ export type Result_4 = { Ok: MeterReading } | { Err: Error };
344
+ export type Result_5 = { Ok: { repaid: bigint; stillOwed: bigint } } | { Err: Error };
345
+ export type Result_6 =
346
+ | {
347
+ Ok: { updateWaiting: boolean; finishByNs: bigint };
348
+ }
349
+ | { Err: Error };
350
+ export type Result_7 = { Ok: bigint } | { Err: Error };
351
+ export type Result_8 = { Ok: RestartReply } | { Err: Error };
352
+ export type Result_9 = { Ok: EngramComputeView } | { Err: Error };
295
353
  export type Role =
296
354
  | { Anonymous: null }
297
355
  | { Viewer: null }
@@ -313,6 +371,11 @@ export interface RowEnding {
313
371
  day: bigint;
314
372
  reason: EndReason;
315
373
  }
374
+ export interface SealedEntry {
375
+ id: bigint;
376
+ entryHash: Uint8Array | number[];
377
+ digest: Uint8Array | number[];
378
+ }
316
379
  export interface StandingLeaf {
317
380
  disputes: bigint;
318
381
  live: bigint;
@@ -402,7 +465,7 @@ export interface _SERVICE {
402
465
  * / protocol and are not, and the difference matters most on this one: it decides what code every
403
466
  * / engram in the fleet will run.
404
467
  */
405
- engramWasmFinalize: ActorMethod<[string], Result_4>;
468
+ engramWasmFinalize: ActorMethod<[string], Result_7>;
406
469
  /**
407
470
  * / Chunked WASM upload — for WASMs that exceed single-call ingress limits.
408
471
  * / Flow: engramWasmInit → engramWasmPushChunk (×N) → engramWasmFinalize(hash)
@@ -421,7 +484,7 @@ export interface _SERVICE {
421
484
  * / to clear and begin afresh. The messages say so because a caller who retries a chunk against a
422
485
  * / full buffer will retry forever.
423
486
  */
424
- engramWasmPushChunk: ActorMethod<[Uint8Array | number[]], Result_4>;
487
+ engramWasmPushChunk: ActorMethod<[Uint8Array | number[]], Result_7>;
425
488
  /**
426
489
  * / Fleet cycle-health scan. Admin or metrics-viewer, PAGINATED with a hard max of 50 per page —
427
490
  * / each managed engram costs one `canister_status` await, so pages stay small to bound the
@@ -451,7 +514,7 @@ export interface _SERVICE {
451
514
  * / this one is a noun. That gate now reads the census's L7 citations as a second population for
452
515
  * / exactly this blind spot.⟩
453
516
  */
454
- fleetCycleHealth: ActorMethod<[bigint, bigint, bigint], Result_21>;
517
+ fleetCycleHealth: ActorMethod<[bigint, bigint, bigint], Result_28>;
455
518
  /**
456
519
  * / PUBLIC: ⟨0.16.0, L2.4⟩ `fleetSummary` — the ONE public projection of this registry,
457
520
  * / replacing `status()` and ABSORBING `publicMetrics()`.
@@ -564,7 +627,7 @@ export interface _SERVICE {
564
627
  * / `listAgents`. "The agent itself" is a caller holding that root key. A key for one engram has no
565
628
  * / record of its own here; asking about one gets the refusal or, from the key itself, `#NotFound`.
566
629
  */
567
- getAgentStanding: ActorMethod<[Principal], Result_20>;
630
+ getAgentStanding: ActorMethod<[Principal], Result_27>;
568
631
  /**
569
632
  * / Fleet-wide anchoring liveness. Exists because ABSENCE is otherwise uninformative: an engram
570
633
  * / that never wrote, one still on a template without the push, and one whose push is broken all
@@ -575,6 +638,12 @@ export interface _SERVICE {
575
638
  * / alive SOMEWHERE, which is what makes an individual engram's silence interpretable.
576
639
  * /
577
640
  * / PUBLIC: the same reader who needs the anchors needs to know whether to believe their absence.
641
+ * /
642
+ * / ⟨2026-10-11⟩ The ring also holds the TREASURY ANCHORER's chain (`getTreasuryAnchorId`), and
643
+ * / `engramsAnchored`, `totalAnchors` and `lastAnchorAtNs` count it as one more chain. The
644
+ * / engram-only pair leaves it out: `engramChainsAnchored` (always present on a registry that
645
+ * / serves it, 0 when no engram has anchored) and `lastEngramAnchorAtNs`. Read those to ask
646
+ * / whether ENGRAMS are anchoring — an active money chain must not stand in for them.
578
647
  */
579
648
  getAnchorStats: ActorMethod<[], AnchorStats>;
580
649
  /**
@@ -619,6 +688,22 @@ export interface _SERVICE {
619
688
  * / the authority it was introduced to remove.
620
689
  */
621
690
  getCertifiedAuditHead: ActorMethod<[], CertifiedAuditHead>;
691
+ /**
692
+ * / The certified proof that a birth record's FINGERPRINT is in this registry's tree ⟨2026-10-26, the
693
+ * / owner's lineage ruling L3A⟩ — the half of an engram's birth chain the engram cannot give itself.
694
+ * /
695
+ * / PUBLIC: a proof a caller had to hold a role to fetch rests on the authority it was meant to
696
+ * / replace. It reveals only whether a fingerprint is present: the key is a salted hash (the record's
697
+ * / random secret is inside it) and the value a constant. Whoever holds the record — the engram's
698
+ * / owner, or whomever the owner showed it to — already knows the fingerprint; nobody else can ask
699
+ * / about a record they cannot guess.
700
+ * /
701
+ * / Verify as for `getCertifiedAnchor`, path ["births", <fingerprint>], leaf bytes = [0x01] (the
702
+ * / client's `verifyBirthChain` does it for a whole chain). `null` when absent, as `getCertifiedAnchor`
703
+ * / answers: there is no certified absence proof (spec question Q8). A `fingerprint` that is not 32
704
+ * / bytes is never a fingerprint, and answers `null` before the lookup.
705
+ */
706
+ getCertifiedBirth: ActorMethod<[Uint8Array | number[]], [] | [CertifiedBirth]>;
622
707
  /**
623
708
  * / The ATTESTABLE custody-mode fact (agent-native model item 19): "managed" | "sovereign" |
624
709
  * / "unknown", derived from the registry's OWN transition records (claimSovereignty /
@@ -643,7 +728,7 @@ export interface _SERVICE {
643
728
  * / Derived from records, never probed: a canister_status call would trap for exactly the
644
729
  * / canisters we are not the controller of, i.e. the sovereign ones this read exists to identify.
645
730
  */
646
- getCustodyMode: ActorMethod<[Principal], Result_5>;
731
+ getCustodyMode: ActorMethod<[Principal], Result_10>;
647
732
  /**
648
733
  * / Cycles-health probe — slim, cycles-only shape; the money fields moved to the cashier's
649
734
  * / getCycleReserveStatus. Read by health-alert.mjs in registry mode.
@@ -675,6 +760,9 @@ export interface _SERVICE {
675
760
  * / on two canisters is what a hand-written client cannot tell apart (a structural actor type
676
761
  * / matches either target), so it gets the rule `getMarketCanister` already follows: distinct
677
762
  * / names on distinct canisters. `…Of` says what the argument is for.
763
+ * /
764
+ * / ⟨2026-10-13⟩ The engram no longer serves `getEngramNumber` at all: its copy of the number went
765
+ * / with the genesis seed, so this is the one read of an engram's number.
678
766
  */
679
767
  getEngramNumberOf: ActorMethod<[Principal], [] | [bigint]>;
680
768
  /**
@@ -686,7 +774,7 @@ export interface _SERVICE {
686
774
  * / `#NotFound` only to a permitted reader, for a key that opened nothing: a true answer, like
687
775
  * / `listMyAgentDisputes`'s empty list.
688
776
  */
689
- getEngramOpenedThrough: ActorMethod<[Principal], Result_19>;
777
+ getEngramOpenedThrough: ActorMethod<[Principal], Result_22>;
690
778
  /**
691
779
  * / The i-th 1 MiB slice of the attested engram wasm (0-indexed). The caller reassembles all
692
780
  * / chunks in order and MUST verify sha256(reassembled) == getEngramWasmHash before installing —
@@ -699,17 +787,28 @@ export interface _SERVICE {
699
787
  * / a truncated one, so it would hash a partial wasm and report a mismatch against the official
700
788
  * / list, which reads as "this template is unofficial" rather than "I stopped reading too early".
701
789
  */
702
- getEngramWasmChunk: ActorMethod<[bigint], Result_18>;
790
+ getEngramWasmChunk: ActorMethod<[bigint], Result_26>;
703
791
  /**
704
792
  * / The stored template's release class — FREE and UNGATED, because it is the checkable half of a
705
- * / promise made to people who are not our customers. Pair it with getRentStatus to verify the
706
- * / funding rule was applied: #Security funds every reachable engram; #Feature funds metered ones.
793
+ * / promise made to people who are not our customers. ⟨2026-10-25⟩ The funding rule it checks:
794
+ * / #Security — the registry pays for the install on every running engram it can reach, any size;
795
+ * / #Feature — the registry pays for no install, and each engram runs it on its own compute. (Was:
796
+ * / "pair it with getRentStatus … #Feature funds metered ones" — rent no longer enters it.)
707
797
  * / PUBLIC: ⟨0.16.0, L3⟩ The release class as a VARIANT, not a stringly-typed enum.
708
798
  * /
709
799
  * / It returned "security" or "feature" as `Text`, so every consumer compared strings and no
710
800
  * / compiler anywhere could catch a typo or a third class arriving. A variant makes the set closed
711
801
  * / and the comparison checked — and this value gates whether an upgrade is funded, so a caller
712
802
  * / that silently fails to match "security" funds nothing and reports no error.
803
+ * / ⟨CORRECTED 2026-10-26, later — the owner's restart choice 3A: "pay whenever the engram is
804
+ * / missing any security release, whatever the latest release is labelled"⟩ "#Feature — the
805
+ * / registry pays for no install" no longer holds for every engram: an engram still missing an
806
+ * / earlier security release is paid as a security update even while this reads #Feature, because
807
+ * / the current template carries that fix (UpgradeFunding.effectiveClass) — unless the current
808
+ * / template is itself behind a security release (an older build re-uploaded), which cannot deliver
809
+ * / the fix. An engram missing no security release is still never paid for a #Feature install.
810
+ * / So this value is the declared label, not the whole funding rule: the `upgrade.topUp` audit line
811
+ * / says `class=Security declared=Feature` when the two differ.
713
812
  */
714
813
  getEngramWasmClass: ActorMethod<[], ReleaseClass>;
715
814
  /**
@@ -738,7 +837,7 @@ export interface _SERVICE {
738
837
  * / site. L1 retired the motive of trapping-to-refuse; it did not give queries the ability to
739
838
  * / write, which is the thing this actually depends on.
740
839
  */
741
- getFleetMetrics: ActorMethod<[], Result_17>;
840
+ getFleetMetrics: ActorMethod<[], Result_25>;
742
841
  /**
743
842
  * / PUBLIC: a genesis note that only privileged callers could read would defeat its purpose —
744
843
  * / the reader who most needs it is the stranger deciding whether to trust this chain.
@@ -805,6 +904,18 @@ export interface _SERVICE {
805
904
  * / provision rather than reserve again.
806
905
  */
807
906
  getMyReservation: ActorMethod<[], [] | [ReservationView]>;
907
+ /**
908
+ * / CALLER: the app's restart sheet, for the owner (ADR-0020). What the caller's engram owes from a
909
+ * / restart, when the next restart is allowed, and whether one is open. Refused loudly to anyone
910
+ * / with no engram here — never "0 owed" to a caller it cannot answer for (ADR-0002).
911
+ * / ⟨2026-10-26⟩ `openUntilNs` now reads the open restart's `finishByNs` (`restartsOpen`): when the
912
+ * / call or the sweep will have started the engram. Shape unchanged.
913
+ * / ⟨CORRECTED 2026-10-26, later — the owner's restart choice 2A: "apply the weekly limit only when
914
+ * / we lend"⟩ "when the next restart is allowed" now reads "when the registry can next LEND to a
915
+ * / restart": `nextRestartAtNs` is only the weekly limit on a loan. A restart on the owner's own
916
+ * / compute is allowed now, whatever it says. Field name and shape unchanged.
917
+ */
918
+ getMyRestartStatus: ActorMethod<[], Result_24>;
808
919
  /**
809
920
  * / ⟨2026-10-02⟩ How many engrams were ever opened, and how — lifetime sizes of state this registry
810
921
  * / never deletes, plus the two counters of refused openings (`Funnel.OpeningCounts` names each).
@@ -815,7 +926,24 @@ export interface _SERVICE {
815
926
  * / "nothing was ever opened". A QUERY: counts only, and cheap; its refusal is not in the denial
816
927
  * / log (`denied` says why a query cannot write).
817
928
  */
818
- getOpeningCounts: ActorMethod<[], Result_16>;
929
+ getOpeningCounts: ActorMethod<[], Result_23>;
930
+ /**
931
+ * / Where an engram was opened from ⟨2026-10-26, the owner's lineage ruling L4: "a child reads its own
932
+ * / parent by its canister id"⟩: the engram, the engram it was opened from, and the cut-off's time if
933
+ * / there is one. Closes "a handed-on child cannot read its own parent" — `getEngramOpenedThrough` is
934
+ * / keyed by the lasting key that OPENED the engram, which a new owner does not hold.
935
+ * /
936
+ * / CALLER: the engram's CURRENT owner, the current owner of the engram it was opened from, or this
937
+ * / registry's admin and audit viewers (ADR-0020). Reuses `parentOf`; no new state. The two owners are
938
+ * / answered first; anyone else goes through the registry's combinator (`#adminOrViewer`), which
939
+ * / refuses every other caller in the same words whether or not the id is an engram, so a refusal
940
+ * / tells a stranger nothing. A QUERY, so the refusal is not written to the denial log (`denied`
941
+ * / says why a query cannot write).
942
+ * / `#NotFound` only to a permitted reader: a first engram has no parent (a true answer), and an id
943
+ * / this registry never opened is said to be one, not passed off as a first engram (ADR-0002).
944
+ * / L8C: `listChildrenOf` is unchanged. L7B: the change-of-owner gate is unchanged.
945
+ */
946
+ getParentOf: ActorMethod<[Principal], Result_22>;
819
947
  /**
820
948
  * / ⟨2026-10-02⟩ How far agents reach across owners — COUNTS ONLY: agents by how many trees their
821
949
  * / record spans (1 · 2 · 3–4 · 5+), engrams opened through a parent that are live or cut off, and
@@ -829,7 +957,7 @@ export interface _SERVICE {
829
957
  * / weekly. Anyone else is REFUSED by name with their class — never zeros. A QUERY: its cost grows
830
958
  * / with the agents and engrams it walks (one pass over each), so a reader asks weekly, not hourly.
831
959
  */
832
- getReferralCounts: ActorMethod<[Array<Principal>], Result_15>;
960
+ getReferralCounts: ActorMethod<[Array<Principal>], Result_21>;
833
961
  /**
834
962
  * / PUBLIC: the biller identity is an operational fact a
835
963
  * / payer's cashier must verify BEFORE taking money (paying into a cashier the registry does not
@@ -853,6 +981,33 @@ export interface _SERVICE {
853
981
  * / prospective user can act on.
854
982
  */
855
983
  getReserveGateConfig: ActorMethod<[], ReserveGateConfig>;
984
+ /**
985
+ * / PUBLIC: CALLER: the status page (ADR-0020). What the registry has lent to restart stopped engrams
986
+ * / — lent, repaid, written off, outstanding — and what engrams gave back of the compute a paid
987
+ * / security update advanced them (returned, written off). Ungated, because a subsidy we would not
988
+ * / publish is one we should not spend. `getUpgradeSubsidyTotal` stays the gross figure.
989
+ * / ⟨2026-10-26, the owner's ruling "write it off, but accounting should be exact"⟩ Two exact
990
+ * / identities hold between any two messages: lent = repaid + writtenOff + outstanding, and
991
+ * / advancePaid = advanceReturned + advanceWrittenOff + advanceOutstanding.
992
+ * / ⟨2026-10-26, later — the owner's restart choice 4A: "add the release name to each write-off
993
+ * / record. This needs no new storage."⟩ These totals are fleet-wide. PER RELEASE, read the audit
994
+ * / chain: every line that moves an advance names the release it was paid for, `template=<module
995
+ * / hash>` (and `version=` when the release history names one) — `upgrade.topUp` (paid, `added=`),
996
+ * / `upgrade.advance.returned` (`returned=`, `writtenOff=`) and `upgrade.advance.writtenOff`
997
+ * / (`writtenOff=`, including the 90-day write-off of an advance left outstanding, restart choice 5A).
998
+ * / Summed by `template=`, they give each release's paid, returned and written-off figures exactly;
999
+ * / what is still out per release is paid − returned − written off. Restart-loan lines are not per
1000
+ * / release (a loan pays for no release).
1001
+ * / ⟨CORRECTED 2026-10-26, later — the fix pass (the ledger review)⟩ "exactly" holds only over a
1002
+ * / COMPLETE copy of the audit chain. The registry keeps the most recent 10,000 audit entries
1003
+ * / (AuditLog's `MAX_ENTRIES`; on overflow it drops back to 9,000, oldest first), and a give-back or
1004
+ * / a 90-day write-off can land long after its `upgrade.topUp` line was dropped. A per-release sum
1005
+ * / read from the registry alone can therefore miss lines. Exact per-release figures need an archive
1006
+ * / of the chain kept from the first line on (scripts/audit-chain/monitor.mjs `--archive`); whether
1007
+ * / such an archive is kept durably is an operator's choice, not this registry's. The fleet totals
1008
+ * / this method answers are exact regardless.
1009
+ */
1010
+ getRestartTotals: ActorMethod<[], RestartTotals>;
856
1011
  /**
857
1012
  * / PUBLIC: transparency without a doxx — how many principals the deployment currently screens (0 = seam
858
1013
  * / disarmed, the shipped default). The list itself is never enumerable publicly.
@@ -860,7 +1015,8 @@ export interface _SERVICE {
860
1015
  getScreeningDenylistSize: ActorMethod<[], bigint>;
861
1016
  /**
862
1017
  * / How many engram template releases this registry has declared `#Security` — the class that
863
- * / skips any delay and is funded for every engram. ⟨2026-09-28, owner decision: publish the
1018
+ * / skips any delay and whose install the registry pays for on every running engram (⟨2026-10-25⟩
1019
+ * / was "is funded for every engram"). ⟨2026-09-28, owner decision: publish the
864
1020
  * / count only; the status page shows the number.⟩ It moves only when a template's class is
865
1021
  * / declared INTO `#Security` (`setEngramWasmClass`), never on `#Feature`, never down.
866
1022
  * / ⟨CORRECTED 2026-09-29⟩ It counts TEMPLATES, not declarations: each distinct template (by its
@@ -926,10 +1082,15 @@ export interface _SERVICE {
926
1082
  * / — and the second is a claim about OUR OWN SPEND, not an absence of one. `#Ok(null)` now means
927
1083
  * / never funded, `#Err(#Refused)` means not your business, and no caller has to guess which.
928
1084
  */
929
- getUpgradeFundedTemplate: ActorMethod<[Principal], Result_14>;
1085
+ getUpgradeFundedTemplate: ActorMethod<[Principal], Result_20>;
930
1086
  /**
931
- * / Cumulative cycles the registry has granted to engrams for upgrades — the meter on the
932
- * / never-gated pull path.
1087
+ * / Cumulative cycles the registry has granted to engrams for upgrades — ⟨2026-10-25⟩ the meter on
1088
+ * / security-update funding: the registry pays only for security updates on running engrams (was:
1089
+ * / "the meter on the never-gated pull path"; the pull is still never refused, and a feature update
1090
+ * / it installs is not paid for).
1091
+ * / ⟨CORRECTED 2026-10-26, later — the owner's restart choice 3A⟩ "a feature update it installs is
1092
+ * / not paid for" now excepts an engram still missing an earlier security release: that install is
1093
+ * / paid as a security update and counted here (UpgradeFunding.effectiveClass).
933
1094
  * /
934
1095
  * / PUBLIC: a subsidy we would not publish is one we should not spend. Free and ungated.
935
1096
  */
@@ -989,7 +1150,7 @@ export interface _SERVICE {
989
1150
  * / nowhere" — handed to a caller who merely lacks a grant. Readable by an admin, an audit viewer,
990
1151
  * / or that agent about itself.
991
1152
  */
992
- listAgentEngrams: ActorMethod<[Principal], Result_12>;
1153
+ listAgentEngrams: ActorMethod<[Principal], Result_17>;
993
1154
  /**
994
1155
  * / Contradictory submissions, oldest-first. Empty is the normal case. Never trimmed.
995
1156
  * /
@@ -1018,7 +1179,7 @@ export interface _SERVICE {
1018
1179
  * / while keeping the evidence that two of them disagree — the fabricate-on-refusal shape aimed at
1019
1180
  * / the one reader the anchors exist for.
1020
1181
  */
1021
- listAnchorConflicts: ActorMethod<[Principal, bigint, bigint], Result_13>;
1182
+ listAnchorConflicts: ActorMethod<[Principal, bigint, bigint], Result_19>;
1022
1183
  /**
1023
1184
  * / Witnessed heads for an engram, oldest-first. PUBLIC and ungated — an anchor a stranger cannot
1024
1185
  * / read is not an anchor (ratified: "recorded where counterparties can check them").
@@ -1074,8 +1235,18 @@ export interface _SERVICE {
1074
1235
  * /
1075
1236
  * / The inline record dies for a `Page`: `earliestId` was redundant with the ring's own paging,
1076
1237
  * / and `size`/`headHash` are `getAuditHead`'s answer, published free to everyone.
1238
+ * /
1239
+ * / ⟨2026-10-15, the owner's ruling 6B of 2026-10-14⟩ The reply is the shared `Wire.RecordPage`,
1240
+ * / the shape every chain canister's record read now serves, so one checker reads all of them. A
1241
+ * / viewer sees every entry, so `sealed` is always empty here; what the page adds is `ringFloor`
1242
+ * / (where the ring starts — a `start` below it begins at it) and `hashFirstFrom` (where this
1243
+ * / record switched to the hash-first rule: entries below it were hashed SHA-256(prev ‖ body)).
1244
+ * / `total` is now the head counter, as everywhere else — it was the size of the 1,000-entry window
1245
+ * / this read sliced, which is not a number about the record. The gate is unchanged: hash-only rows
1246
+ * / for strangers were ruled for the engram's record, and the status console decides a signed-in
1247
+ * / visitor's tier by whether this read refuses.
1077
1248
  */
1078
- listAuditEntries: ActorMethod<[bigint, bigint], Result_10>;
1249
+ listAuditEntries: ActorMethod<[bigint, bigint], Result_18>;
1079
1250
  /**
1080
1251
  * / ⟨0.16.0, L2.2⟩ RENAMED from `getMetricsViewers` — the viewer triple unifies on "audit viewer"
1081
1252
  * / across every canister, because a roster that grants audit reads should not be named after
@@ -1085,7 +1256,7 @@ export interface _SERVICE {
1085
1256
  * / on 2026-08-11 while viewers existed. An empty vec reads as "nobody holds read-only ops access"
1086
1257
  * / when the truth was "you are not on the roster".
1087
1258
  */
1088
- listAuditViewers: ActorMethod<[], Result_12>;
1259
+ listAuditViewers: ActorMethod<[], Result_17>;
1089
1260
  /**
1090
1261
  * / PUBLIC: the release history, paged.
1091
1262
  * /
@@ -1107,7 +1278,7 @@ export interface _SERVICE {
1107
1278
  * / Built by a pass over `parentOf` rather than from a second, reverse index: one stored fact and a
1108
1279
  * / pass bounded by the number of opened engrams, instead of two facts to keep in step.
1109
1280
  */
1110
- listChildrenOf: ActorMethod<[Principal], Result_11>;
1281
+ listChildrenOf: ActorMethod<[Principal], Result_16>;
1111
1282
  /**
1112
1283
  * / ⟨0.16.0⟩ RENAMED from `readDenialLog`; the refusal becomes a value.
1113
1284
  * /
@@ -1115,7 +1286,7 @@ export interface _SERVICE {
1115
1286
  * / this log exists to record — so "empty" was never an acceptable answer to a caller who simply
1116
1287
  * / lacks the grant. The old trap said so; this says the same thing as data.
1117
1288
  */
1118
- listDenialEntries: ActorMethod<[bigint, bigint], Result_10>;
1289
+ listDenialEntries: ActorMethod<[bigint, bigint], Result_15>;
1119
1290
  /**
1120
1291
  * / ⟨2026-10-02⟩ ONE ROW PER ENGAGEMENT, for the deployment's own count of use — DAYS, never
1121
1292
  * / instants, and NEVER the agent's root, enrolled key or invite.
@@ -1141,7 +1312,7 @@ export interface _SERVICE {
1141
1312
  * / and a query cannot write (the reason `listEngrams` is an update). This is the most sensitive of
1142
1313
  * / the three reads — one row per engagement — so who was turned away is worth a record.
1143
1314
  */
1144
- listEngagementRows: ActorMethod<[bigint, bigint, bigint, Array<Principal>], Result_9>;
1315
+ listEngagementRows: ActorMethod<[bigint, bigint, bigint, Array<Principal>], Result_14>;
1145
1316
  /**
1146
1317
  * / ⟨0.16.0, L1⟩ THE `authorized : ?Bool` FLAG IS GONE, AND SO IS EVERYTHING BUILT AROUND IT.
1147
1318
  * /
@@ -1174,7 +1345,7 @@ export interface _SERVICE {
1174
1345
  * / own text had to be corrected for — the forcing call is not a system API at all, it is
1175
1346
  * / `denied()`, a state write. See `scripts/check-update-for-read.mjs`.
1176
1347
  */
1177
- listEngrams: ActorMethod<[bigint, bigint], Result_8>;
1348
+ listEngrams: ActorMethod<[bigint, bigint], Result_13>;
1178
1349
  /**
1179
1350
  * / ⟨2026-09-28, owner decision: an agent may read its own record⟩ The caller's OWN dispute
1180
1351
  * / statements, oldest first, verbatim. Keyed by `msg.caller`, so it cannot be pointed at anyone
@@ -1229,12 +1400,12 @@ export interface _SERVICE {
1229
1400
  * / choice in the fleet. That is the consequence this refusal exists to prevent, and it belongs in
1230
1401
  * / the message a caller actually receives.
1231
1402
  */
1232
- listUpdatePrefs: ActorMethod<[bigint, bigint], Result_7>;
1403
+ listUpdatePrefs: ActorMethod<[bigint, bigint], Result_12>;
1233
1404
  /**
1234
1405
  * / Mint one-shot reserve invites (invite-issuer or admin). Codes use IC-secure randomness over a
1235
1406
  * / 32-symbol no-ambiguous alphabet (8 chars ≈ 40 bits). Batch-capped; table hard-capped.
1236
1407
  */
1237
- mintReserveInvites: ActorMethod<[bigint], Result_6>;
1408
+ mintReserveInvites: ActorMethod<[bigint], Result_11>;
1238
1409
  /**
1239
1410
  * / The PROBED twin of `getCustodyMode`: same question, asked of the IC rather than of our
1240
1411
  * / records — hence the `probe` verb rather than a second noun.
@@ -1262,13 +1433,37 @@ export interface _SERVICE {
1262
1433
  * / LIVE from the management canister rather than from a stored transition record, so a query
1263
1434
  * / could not produce it at all, not merely more cheaply.
1264
1435
  */
1265
- probeCustodyMode: ActorMethod<[], Result_5>;
1436
+ probeCustodyMode: ActorMethod<[], Result_10>;
1437
+ /**
1438
+ * / What YOUR OWN engram's compute is, read by the registry — the one read that works while it is
1439
+ * / frozen.
1440
+ * /
1441
+ * / CALLER: the owner, from the app's status strip, Billing and System pages (ADR-0020).
1442
+ * / ⟨2026-10-26, the owner's ruling 1A: tell the owner, using signals that work while frozen⟩ The
1443
+ * / registry is a controller, and the network answers a controller canister's status call for a
1444
+ * / frozen engram where it refuses the owner's own (IC0207, the stopped-engram study's network read
1445
+ * / §6). UPDATE, not query: it awaits the management canister (the `probe` verb, as
1446
+ * / `probeCustodyMode`).
1447
+ * / ⟨L7⟩ ⟨marker added 2026-10-26, Finish phase; the reason above unchanged⟩ The system call that
1448
+ * / forces the update is `canister_status` on the management canister: a query cannot make an
1449
+ * / inter-canister call, so a query could not read the engram's network status at all — and that
1450
+ * / status is the only signal that still answers while the engram is frozen.
1451
+ * / No rate limit (the do-less): each call costs the registry one management
1452
+ * / call — INFERRED a few million cycles, not measured. `eraseAboutNs` is "about" and never invented:
1453
+ * / null when the network reports no idle burn.
1454
+ */
1455
+ probeMyEngramCompute: ActorMethod<[], Result_9>;
1266
1456
  /**
1267
1457
  * / ⟨0.16.0⟩ `Ok` CARRIES THE PRINCIPAL DIRECTLY, not a one-field record wrapping it.
1268
1458
  * /
1269
1459
  * / `#Ok : { canisterId : Principal }` was a record with nothing to disambiguate: the success of a
1270
1460
  * / spawn IS the canister it produced. The wrapper cost every caller a field access to reach the
1271
1461
  * / only thing the call returns, and invited a second field later that would belong somewhere else.
1462
+ * /
1463
+ * / ⟨2026-10-13, the owner's 6A⟩ `opts.genesis` (an optional first file, written as the canister
1464
+ * / spawned) is retired: the console creates an engram with no content (decision 2 B(b),
1465
+ * / 2026-09-30), the owner kit never calls this, and only test harnesses passed one. A caller still
1466
+ * / sending the field is unaffected — Candid ignores a record field the receiver does not declare.
1272
1467
  */
1273
1468
  provisionEngram: ActorMethod<
1274
1469
  [
@@ -1277,7 +1472,6 @@ export interface _SERVICE {
1277
1472
  {
1278
1473
  walletProof: [] | [Uint8Array | number[]];
1279
1474
  invite: [] | [string];
1280
- genesis: [] | [{ content: Uint8Array | number[]; path: string }];
1281
1475
  },
1282
1476
  ],
1283
1477
  ],
@@ -1303,6 +1497,70 @@ export interface _SERVICE {
1303
1497
  ],
1304
1498
  Result
1305
1499
  >;
1500
+ /**
1501
+ * / Admin (the wasm admin): give one grown engram's working memory back, in place. The engram's
1502
+ * / stable graph is copied into its stable memory and the SAME module is reinstalled with
1503
+ * / `wasm_memory_persistence = ?#replace`, so the engram restarts in a fresh, small wasm memory with
1504
+ * / every file, version, record entry, setting and key it had (MemoryReset.mo).
1505
+ * /
1506
+ * / REFUSES, and changes nothing, when: the caller is not the wasm admin; the registry does not know
1507
+ * / the engram; a change of owner or a restart is open; its status cannot be read (a sovereign engram);
1508
+ * / it is not running; it is not on the current template; its wasm memory is under
1509
+ * / `MemoryReset.WASM_FLOOR_BYTES` (nothing to give back — and so a second reset straight after a
1510
+ * / first); its balance is short of the install hold above its own freezing line (no dip, no deposit);
1511
+ * / or one of its own calls is in flight ("Busy, try again").
1512
+ * /
1513
+ * / WHO PAYS: the engram, as for any install — `install_code` is charged to the canister it installs
1514
+ * / on, and the stabilise / rebuild steps are the engram's own messages. The registry deposits
1515
+ * / nothing; it pays only for its own calls. Two installs run: an ordinary one of the same module
1516
+ * / first, which is the network's test for a call in flight while nothing is yet at stake, then the
1517
+ * / replace.
1518
+ * /
1519
+ * / ONCE STARTED it finishes or says the engram is HELD: between the stabilise call and the replace
1520
+ * / install the engram refuses every message, so a failure there answers `#Unavailable` naming the
1521
+ * / step, and running this method again picks up where it stopped (it reads the held state from the
1522
+ * / engram itself). Do not publish a new template while a reset is held.
1523
+ * /
1524
+ * / Never run on production engrams (the owner's ruling). On the staging network, as the wasm admin,
1525
+ * / with the engram's canister id in ENGRAM:
1526
+ * / icp canister call registry-staging resetEngramMemory "(principal \"$ENGRAM\")" -e ic
1527
+ */
1528
+ resetEngramMemory: ActorMethod<[Principal], Result>;
1529
+ /**
1530
+ * / Restart YOUR OWN stopped engram.
1531
+ * /
1532
+ * / CALLER: the owner, from the app's restart sheet (ADR-0020). Afterwards the app runs the engram's
1533
+ * / own `convertEarningsToCycles` as the owner, which pays any loan back FIRST.
1534
+ * /
1535
+ * / ⟨REWRITTEN 2026-10-26, the owner's ruling 2A of that day⟩ What it does, in this order: stops the
1536
+ * / engram; adds compute — the owner's own (already added through `stopMyEngramForRestart` and a
1537
+ * / top-up from their account), or a loan of what it still lacks to run at its OWN setting (at most
1538
+ * / 0.25T, only after the biller confirms the wallet holds enough to repay it); installs the waiting
1539
+ * / security release if the engram is behind one and the owner allows automatic updates (paid as a
1540
+ * / security update — we pay because we do not want security incidents); puts the owner's freezing
1541
+ * / setting back; and only then starts it. It never lowers the setting on a running engram. A step
1542
+ * / that fails never leaves the engram stopped: the registry's sweep finishes it within minutes.
1543
+ * /
1544
+ * / Refused BEFORE anything is stopped, saying why: not your engram; sovereign; a change of owner
1545
+ * / unfinished; restarted in the last 7 days; a loan still owed; an update installing; a restart
1546
+ * / already running; code the registry never published; running (nothing to restart); needing more
1547
+ * / than one loan; a waiting security update that this restart could not cover (it would start old
1548
+ * / code); an engram opened through another engram that would need a loan; the fleet-wide ceiling;
1549
+ * / no biller, or a wallet too low to repay. A restart that lent nothing does not spend the week.
1550
+ * / ⟨CORRECTED 2026-10-26, later — the owner's restart choices 1A and 2A of that day⟩ The list above is
1551
+ * / the record of the build before them. Now: "restarted in the last 7 days" and "a loan still owed"
1552
+ * / refuse ONLY a restart that would LEND (2A: "apply the weekly limit only when we lend") — asked
1553
+ * / once the plan knows the loan, and again after every await before the loan is made
1554
+ * / (`RestartLoan.lendGate`); a restart on the owner's own compute is never refused by them and never
1555
+ * / spends the week, which is taken only in the step that records a loan. "An engram opened through
1556
+ * / another engram that would need a loan" is GONE (1A: "lend to children like any other engram") —
1557
+ * / such an engram is lent to under the same ceiling, wallet check and repay-first as any other: the
1558
+ * / biller reads the engram's OWN wallet by its own id, and the engram's own Convert repays. New: a
1559
+ * / second call while one is still running for the same engram (`restartCallsRunning`), which is
1560
+ * / what now keeps two interleaved calls from both lending or both stopping and starting — the week
1561
+ * / used to double as that guard.
1562
+ */
1563
+ restartMyStoppedEngram: ActorMethod<[], Result_8>;
1306
1564
  /**
1307
1565
  * / Return to managed: user calls AFTER adding registry back as controller
1308
1566
  */
@@ -1372,7 +1630,7 @@ export interface _SERVICE {
1372
1630
  */
1373
1631
  setReserveGateEnabled: ActorMethod<[boolean], Result>;
1374
1632
  setScreeningDenylist: ActorMethod<[Array<Principal>], Result>;
1375
- setSpawnCeiling: ActorMethod<[bigint], Result_4>;
1633
+ setSpawnCeiling: ActorMethod<[bigint], Result_7>;
1376
1634
  setTreasuryAnchorId: ActorMethod<[[] | [Principal]], Result>;
1377
1635
  /**
1378
1636
  * / Set the wallet-canister allowlist for the wallet-rooted exemption (admin-only). Small by
@@ -1394,11 +1652,23 @@ export interface _SERVICE {
1394
1652
  * / Admin dial for the upgrade top-up floor (0 = disabled). Capped at one endowment so the dial
1395
1653
  * / itself cannot turn upgrades into an unbounded drain.
1396
1654
  */
1397
- setUpgradeTopUpFloor: ActorMethod<[bigint], Result_4>;
1655
+ setUpgradeTopUpFloor: ActorMethod<[bigint], Result_7>;
1398
1656
  /**
1399
1657
  * / Root admin assigns the role key (pass null to clear, reverting the role to the root admin).
1400
1658
  */
1401
1659
  setWasmAdmin: ActorMethod<[[] | [Principal]], Result>;
1660
+ /**
1661
+ * / Stop YOUR OWN stopped-or-starving engram so you can add compute from your account and restart it.
1662
+ * /
1663
+ * / CALLER: the owner, from the app's "Add compute from my account" when the engram has stopped and a
1664
+ * / security update is waiting (ADR-0020). ⟨2026-10-26, the owner's ruling 2A⟩ Stops the engram so
1665
+ * / that compute the owner adds next cannot wake its old code; the owner then adds compute through
1666
+ * / the biller's own top-up and calls `restartMyStoppedEngram`, which installs the waiting update and
1667
+ * / starts it. If the owner walks away, the sweep finishes it after 30 minutes: install if covered,
1668
+ * / restore, start. Never left stopped. It lends nothing, so it takes no week; it refuses an engram
1669
+ * / that is not stuck, so a healthy engram is never taken offline (spec question Q15).
1670
+ */
1671
+ stopMyEngramForRestart: ActorMethod<[], Result_6>;
1402
1672
  /**
1403
1673
  * / An engram witnesses its own audit head. Callable ONLY by a registered engram — msg.caller is
1404
1674
  * / the engram principal, so attribution needs no signature and cannot be forged by a third party.
@@ -1422,6 +1692,17 @@ export interface _SERVICE {
1422
1692
  * / hand-written client IDL type-checks against a method that does not exist.
1423
1693
  */
1424
1694
  sysAnchorHead: ActorMethod<[Uint8Array | number[], bigint], Result>;
1695
+ /**
1696
+ * / CALLER: an engram, from inside its owner's `convertEarningsToCycles`, once the conversion landed
1697
+ * / (ADR-0020). Attach up to what is owed: the registry accepts no more than the outstanding loan
1698
+ * / (the network returns the rest) and records it. `#NotFound` when nothing is owed (the loan was
1699
+ * / written off, or repaid): the engram then clears its own record.
1700
+ * / ⟨CHANGED 2026-10-26, the owner's ruling 2A⟩ REPAY-ONLY. It no longer puts a freezing setting back
1701
+ * / (the restart restores it before the start) and no longer queues a security push (the restart
1702
+ * / installs it before the start; the wake watcher covers other wakes). The name and reply are
1703
+ * / unchanged, so the engram's hand client still matches.
1704
+ */
1705
+ sysCloseRestart: ActorMethod<[], Result_5>;
1425
1706
  /**
1426
1707
  * / ⟨2026-09-29, review PR-3: a half-finished change of owner⟩ A SOVEREIGN engram reports that it
1427
1708
  * / moved control of its code to `newOwner`, which ends the change of owner this registry marked
@@ -1444,7 +1725,7 @@ export interface _SERVICE {
1444
1725
  * / cycles-attached like the sweep; same row semantics, one engram, no heartbeat stamp
1445
1726
  * / (a single probe is not a completed round).
1446
1727
  */
1447
- sysMeterEngram: ActorMethod<[Principal], Result_3>;
1728
+ sysMeterEngram: ActorMethod<[Principal], Result_4>;
1448
1729
  /**
1449
1730
  * / ⟨2026-10-02⟩ An engram tells this registry that its owner reset it.
1450
1731
  * /
@@ -1505,7 +1786,7 @@ export interface _SERVICE {
1505
1786
  * / a transfer the engram did not finish, and moves control again (that is the way out `stuck`
1506
1787
  * / names). The rules are in `src/shared/ControlHandover.mo`.
1507
1788
  */
1508
- sysNotifyOwnershipTransfer: ActorMethod<[Principal], Result_2>;
1789
+ sysNotifyOwnershipTransfer: ActorMethod<[Principal], Result_3>;
1509
1790
  /**
1510
1791
  * / ⟨2026-09-28, owner decision: build the full agent track-record design for the launch release⟩
1511
1792
  * / An engram tells this registry that one of its agents started, or ended and WHY.
@@ -1566,6 +1847,43 @@ export interface _SERVICE {
1566
1847
  * / engagement never recorded here is refused `#NotFound` (`Engagements.closeVerdict`).⟩
1567
1848
  */
1568
1849
  sysRecordAgentEdge: ActorMethod<[{ root: Principal; event: EdgeEvent }], Result>;
1850
+ /**
1851
+ * / CALLER: an engram, from inside its `sysReturnUpgradeAdvance` (ADR-0020). Attach what is being
1852
+ * / given back of the compute a paid security update advanced it. The registry accepts no more than
1853
+ * / the outstanding advance (the network returns the rest) and writes off whatever was not returned
1854
+ * / — what the install used and what the engram had to keep — never carried as a debt.
1855
+ * / ⟨2026-10-26, the owner's ruling "accounting should be exact"⟩ The write-off here is the exact
1856
+ * / figure advance − accepted, from the ledger entry and the cycles actually accepted, and the audit
1857
+ * / line carries advance, returned and writtenOff.
1858
+ * / ⟨2026-10-26, later — the owner's restart choices 4A and 5A⟩ The engram may have more than one
1859
+ * / advance out (one per release paid; RestartLoan.repayAdvances): the cycles are accepted up to their
1860
+ * / sum and settled OLDEST FIRST, and each advance gets its own audit line naming the release it was
1861
+ * / paid for (`template=`), with its own returned and written-off parts — the lines sum exactly to
1862
+ * / `accepted` and to the write-off. AN ADVANCE ALREADY WRITTEN OFF (the 90-day sweep) IS NOT ON THE
1863
+ * / LEDGER, so nothing sent for it is accepted — the network returns those cycles to the engram — and
1864
+ * / `advanceReturned` never counts a written-off cycle: no double count. When nothing at all is out,
1865
+ * / the reply is `#NotFound` and nothing is accepted (as before).
1866
+ * / ⟨CORRECTED 2026-10-26, later — the fix pass on 4A⟩ NEWEST first, not oldest first: the engram can
1867
+ * / give back only what it holds above its balance before the latest deposit, so the cycles are the
1868
+ * / newest advance's (RestartLoan.repayAdvances says why, and when that reading is wrong).
1869
+ * / ⟨CHANGED 2026-10-26, the owner's review choice 1B: "take back only what we added; anything left
1870
+ * / over goes to the 90-day write-off"⟩ The engram now names THE ADVANCE it is giving back
1871
+ * / (`advanceId`, which the registry handed it in `sysReturnUpgradeAdvance` — the one this install's
1872
+ * / deposit put on the ledger). The registry accepts AT MOST THAT ADVANCE'S AMOUNT, settles THAT
1873
+ * / entry alone (returned + written off = its amount, one `upgrade.advance.returned` line naming its
1874
+ * / release and id) and leaves every other advance of the engram on the ledger, for its own
1875
+ * / give-back or the 90-day write-off. The paragraphs above about "the sum", "settled OLDEST FIRST"
1876
+ * / and "NEWEST first" describe the shape this replaces. An id that is not on the ledger for this
1877
+ * / caller (already settled, written off after 90 days, or never its own) accepts nothing — the
1878
+ * / network returns the attached cycles to the engram — and answers `#NotFound`; when a recorded
1879
+ * / engram attached cycles, an `upgrade.advance.notOut` line in the registry's unchained refusal log
1880
+ * / says so (never the chained audit log: it moves nothing, and any engram can send it). Nothing is
1881
+ * / ever counted twice.
1882
+ * / WHAT WOULD MAKE THIS WRONG: an engram naming an id other than the one it was handed — it can only
1883
+ * / name one of its OWN advances (the caller must match), so the worst it can do is settle its own
1884
+ * / other advance early with cycles that are still the registry's.
1885
+ */
1886
+ sysRepayUpgradeAdvance: ActorMethod<[{ advanceId: bigint }], Result_2>;
1569
1887
  /**
1570
1888
  * / ⟨2026-09-29, owner ruling follow-up 8⟩ A SOVEREIGN engram could not change its own controllers
1571
1889
  * / after this registry moved its record, and asks for the record back so the transfer does not
@@ -1630,33 +1948,43 @@ export interface _SERVICE {
1630
1948
  * / Admin: upgrade one engram to the current template. RESPECTS the owner's update preference —
1631
1949
  * / an engram set to `#ManualOnly` is not moved by this method, which is what makes the preference
1632
1950
  * / meaningful rather than advisory. The owner's own `upgradeMyEngram` is unaffected either way.
1951
+ * /
1952
+ * / ⟨2026-10-25, the owner's ruling of that day⟩ Same funding decision and dip as the owner's pull:
1953
+ * / paid only for a #Security update on a running engram. A push is the registry's own initiative,
1954
+ * / so where the engram cannot hold the install even with its setting lowered, the push is SKIPPED
1955
+ * / with `#Conflict` and not attempted — the owner can still pull it, and the pull is never refused.
1633
1956
  */
1634
1957
  upgradeEngram: ActorMethod<[Principal], Result>;
1635
1958
  /**
1636
1959
  * / Upgrade YOUR OWN engram to the registry's current template. Self-service — no admin, no
1637
1960
  * / queue, no approval.
1638
1961
  * /
1639
- * / ⚠ THE PULL IS ALWAYS FUNDED, regardless of release class or rent state, and that is a
1640
- * / commitment rather than an implementation detail: `install_code` needs the balance to cover the
1641
- * / install ABOVE the freezing threshold, so the registry lifts the engram over that bar if cycles
1642
- * / are what is stopping it. Refusing an owner their own fix for nonpayment is the ransom the
1643
- * / continuity-rent model forbids, and withholding a security fix would be worse than anything
1644
- * / that model gates. The lift is best-effort: if it fails, the install still runs and returns the
1645
- * / REAL error, so a top-up problem can never masquerade as an upgrade problem or hide one.
1646
- * / ⟨2026-09-28, owner decision: the registry only pays for upgrades of engrams running our
1647
- * / published code⟩ One exception to "always funded": an engram whose installed module is not one
1648
- * / this registry published is not lifted (`fundUpgradeIfNeeded`, audit
1649
- * / `upgrade.topUp.unpublishedCode`). The install is still attempted — the owner is never refused
1650
- * / their fix, only our cycles for it.
1651
- * / ⟨2026-09-29⟩ And when that install then FAILS, the reply says why the registry did not pay and
1652
- * / what the owner can do (`TemplatePolicy.unfundedUpgradeFailure`) — before, the refusal was only
1653
- * / in the registry's own log and the owner saw a bare out-of-cycles error. Same reply type.
1654
- * / ⟨2026-10-01, the owner's ruling of that day (2 A)⟩ A second exception beside the first: an
1655
- * / engram opened through a parent (`parentOf`, written by `sysSpawnChild`) is funded by the
1656
- * / registry never — not at birth, not at an upgrade (`fundUpgradeIfNeeded`, audit
1657
- * / `upgrade.topUp.childEngram`). The install is still attempted; the owner is never refused their
1658
- * / fix, only our cycles for it, and a failed install says so
1659
- * / (`TemplatePolicy.childUnfundedUpgradeFailure`).
1962
+ * / ⟨2026-10-25, the owner's ruling of that day⟩ THE INSTALL IS ALWAYS ATTEMPTED. Refusing an owner
1963
+ * / their own update for nonpayment is the ransom the continuity model forbids, so this method never
1964
+ * / refuses for compute or payment. What the registry PAYS for is narrower: a #Security update on a
1965
+ * / running engram, any size — paid because we do not want security incidents (the owner,
1966
+ * / 2026-10-25). A #Feature update runs on the engram's own compute. Four standing exclusions are
1967
+ * / never paid for: an engram that has stopped (below its running line — it runs nothing, so its old
1968
+ * / code is not exposed while stopped), one opened through a parent (the ruling of 2026-10-01), one
1969
+ * / running a module the registry never published (2026-09-28), and a second deposit for the same
1970
+ * / release.
1971
+ * / ⟨CORRECTED 2026-10-26, the owner's rulings of that day⟩ THREE standing exclusions: an engram
1972
+ * / opened through a parent is now paid for a security update like any other ("including child
1973
+ * / engrams, but not including engrams running unofficial code"), and a #Feature update is never
1974
+ * / paid, rent or no rent ("where rent is paid, feature upgrades are paid by the engram").
1975
+ * / ⟨CORRECTED 2026-10-26, later — the owner's restart choice 3A: "pay whenever the engram is
1976
+ * / missing any security release, whatever the latest release is labelled"⟩ "a #Feature update is
1977
+ * / never paid" now excepts an engram still missing an earlier security release: its install of a
1978
+ * / #Feature template is paid as a security update, because the template carries that fix
1979
+ * / (UpgradeFunding.effectiveClass) — unless the template is itself behind a security release.
1980
+ * / When it helps, the registry lowers the engram's freezing setting to one hour for the
1981
+ * / install and puts the owner's value back after (the dip), so an install needs only ~0.32T above
1982
+ * / an hour's burn rather than the hold above the whole 30-day line.
1983
+ * /
1984
+ * / When the install FAILS after the registry declined to pay, the reply says why and what to do
1985
+ * / (UpgradeFunding.pullFailure): `#Conflict` when the engram needs more compute (the owner's
1986
+ * / action — add compute), `#Unavailable` when the registry could not pay this time (retryable).
1987
+ * / A failure after a paid or unneeded deposit answers `#Unavailable` with the network's reply.
1660
1988
  * /
1661
1989
  * / An engram already on the current template is a silent no-op. A SOVEREIGN engram gets
1662
1990
  * / "registry is no longer a controller" — accurate, because it is no longer ours to install on.