On this page

Loading a whole world back๏ƒ

๐Ÿ”ต Expert ยท Lesson 24

SEAL A WORLD, THEN UNFOLD IT AGAIN. Expert 01 taught the pod-boot ORDER; expert 09 taught what crosses the wire. This is the round trip itself - checkpoint a live world, put it in the cache, and unfold it back into the runtime.

THE FIVE VERBS, IN ORDER create_checkpoint(profile, description) -> a ULID id describe_checkpoint(id) -> what got captured flush_checkpoint(id) -> seal it into the cache reload_cached_checkpoint(id) -> cache back into ledger load_checkpoint(id) -> UNFOLD into the runtime Only the last one touches the live world. The first four move a record around; load_checkpoint is the boot verb. The lesson retires its original root before replay so the saved root name and binding identities are available. The recorder itself stays alive.

A RESTORE IS NOT A RESURRECTION, AND THE REPORT SAYS SO load_checkpoint hands back a RestoreReport carrying: status did it complete built counts how many of each kind came back shortfall entries what could NOT be rebuilt identity translation map OLD id -> NEW id That last field is the one to understand. Rebuilt objects get NEW identities - the world that comes back is equivalent, not identical - and the map is how you follow one thing across a boot. Anything holding a raw pre-restore id and expecting it to still resolve is holding a stale address, and the map is the only honest way to translate it.

SHORTFALLS ARE REPORTED, NOT HIDDEN A spell whose class can no longer be imported, a module that moved, a binding whose target is gone - each becomes a shortfall ENTRY rather than a silent omission. Expert 18's law at the boot grain: a restore that quietly dropped what it could not rebuild would look identical to a world that never had those things, and the second invites everyone downstream to invent.

CHECKPOINTS ACCUMULATE; THEY NEVER OVERWRITE Every create_checkpoint mints a new ULID and list_checkpoint_ids() returns them in exact ledger creation order. There is no "the checkpoint" - there is a history of them, and an id is the whole handle.

AND THE OPERATOR'S ONE-CALL VERSION md.CrystallizerBootstrap() .with_crystallizer_configuration(...) .with_profile(...) .with_pull_remote(False) .bootstrap() That is expert 01's flow: the same steps in a fixed sequence, for the case where you are starting a process rather than inspecting a round trip. Note with_preflight_gate is an ACCEPTED NO-OP - the knob still exists and does nothing, and its own docstring says so rather than pretending.

Before you run๏ƒ

Use the Expert guide for prerequisite concepts. Run from a checkout with Melder installed and Python 3.14 free-threading selected. The collection download includes the level's local helper modules.

Run the saved script๏ƒ

python UX_and_AIX_experiences/04_expert/24_loading_a_whole_world_back.py
py -3.14t UX_and_AIX_experiences/04_expert/24_loading_a_whole_world_back.py

Download this collection ยท Source on GitHub

Public surface๏ƒ

md.Crystallizer create_checkpoint / describe_checkpoint / flush_checkpoint / list_cached_checkpoint_ids / list_checkpoint_ids / reload_cached_checkpoint / load_checkpoint, and md.CrystallizerBootstrap

Code๏ƒ

  1"""
  2TIER: expert (24)
  3GOAL: SEAL A WORLD, THEN UNFOLD IT AGAIN. Expert 01 taught the pod-boot
  4      ORDER; expert 09 taught what crosses the wire. This is the round
  5      trip itself - checkpoint a live world, put it in the cache, and
  6      unfold it back into the runtime.
  7
  8      THE FIVE VERBS, IN ORDER
  9        create_checkpoint(profile, description) -> a ULID id
 10        describe_checkpoint(id)                 -> what got captured
 11        flush_checkpoint(id)                    -> seal it into the cache
 12        reload_cached_checkpoint(id)            -> cache back into ledger
 13        load_checkpoint(id)                     -> UNFOLD into the runtime
 14      Only the last one touches the live world. The first four move a
 15      record around; `load_checkpoint` is the boot verb.
 16      The lesson retires its original root before replay so the saved root name
 17      and binding identities are available. The recorder itself stays alive.
 18
 19      A RESTORE IS NOT A RESURRECTION, AND THE REPORT SAYS SO
 20      `load_checkpoint` hands back a RestoreReport carrying:
 21        status                      did it complete
 22        built counts                how many of each kind came back
 23        shortfall entries           what could NOT be rebuilt
 24        identity translation map    OLD id -> NEW id
 25      That last field is the one to understand. Rebuilt objects get NEW
 26      identities - the world that comes back is equivalent, not
 27      identical - and the map is how you follow one thing across a boot.
 28      Anything holding a raw pre-restore id and expecting it to still
 29      resolve is holding a stale address, and the map is the only honest
 30      way to translate it.
 31
 32      SHORTFALLS ARE REPORTED, NOT HIDDEN
 33      A spell whose class can no longer be imported, a module that
 34      moved, a binding whose target is gone - each becomes a shortfall
 35      ENTRY rather than a silent omission. Expert 18's law at the boot
 36      grain: a restore that quietly dropped what it could not rebuild
 37      would look identical to a world that never had those things, and
 38      the second invites everyone downstream to invent.
 39
 40      CHECKPOINTS ACCUMULATE; THEY NEVER OVERWRITE
 41      Every `create_checkpoint` mints a new ULID and
 42      `list_checkpoint_ids()` returns them in exact ledger creation
 43      order. There is no "the checkpoint" - there is a history of them,
 44      and an id is the whole handle.
 45
 46      AND THE OPERATOR'S ONE-CALL VERSION
 47        md.CrystallizerBootstrap()
 48            .with_crystallizer_configuration(...)
 49            .with_profile(...)
 50            .with_pull_remote(False)
 51            .bootstrap()
 52      That is expert 01's flow: the same steps in a fixed sequence, for
 53      the case where you are starting a process rather than inspecting a
 54      round trip. Note `with_preflight_gate` is an ACCEPTED NO-OP - the
 55      knob still exists and does nothing, and its own docstring says so
 56      rather than pretending.
 57SURFACE EXERCISED: md.Crystallizer create_checkpoint /
 58                   describe_checkpoint / flush_checkpoint /
 59                   list_cached_checkpoint_ids / list_checkpoint_ids /
 60                   reload_cached_checkpoint / load_checkpoint, and
 61                   md.CrystallizerBootstrap
 62VERIFY: rides the owner's 3.14t harness; asserts are the contract.
 63"""
 64import melder as md
 65
 66FRAME = "restore-world"
 67
 68
 69class Ledger:
 70    def __init__(self) -> None:
 71        self.entries = []
 72
 73
 74class Auditor:
 75    def __init__(self) -> None:
 76        self.checked = 0
 77
 78
 79def main() -> None:
 80    """Seal and replay a complete world while keeping its in-memory recorder alive.
 81
 82    Contract:
 83        Establish recording posture before binds, retire original runtime claims
 84        before replay and assert that rebuilt application state starts fresh.
 85        A retained ordinary Ledger reference has no disposer in this example.
 86    Returns:
 87        None.
 88    """
 89    # Custody first - nothing is recorded into a crystallizer that is not
 90    # yet recording (expert 22's ordering law).
 91    crystallizer = md.Crystallizer()
 92    crystallizer.activate(
 93        md.CrystallizerConfigurationBuilder().with_defaults().activate(),
 94    )
 95    research = md.MutationResearch()
 96    configuration = research.create_configuration()
 97    configuration.with_defaults().activate()
 98    research.activate(configuration)
 99    print("custody recording:", crystallizer.activated)
100
101    # A REAL WORLD with two spells and a live object.
102    # A RECORDED WORLD MUST BE BORN CONFIGURED. With custody active, a
103    # dynamic conjure REFUSES if any bind ran before the configuration
104    # was finalized - the profile record and default bootstrap would
105    # otherwise durably persist binds made against unsettled config.
106    spellbook_configuration = (
107        md.SpellbookConfiguration(FRAME).with_defaults().finalize()
108    )
109    book = md.Spellbook(aetheric_frame=FRAME,
110                        configuration=spellbook_configuration)
111    # Establish dynamic recording posture before binding custody. Configuring
112    # the frame afterward cannot retroactively record earlier automatic binds.
113    book.configure_aether_frame(
114        system_state="dynamic",
115        disposal=None,
116        disposal_method_names=None,
117    )
118    book.bind(spell=Ledger, existence="unique",
119              permissions="create", binding_name="restore-ledger")
120    book.bind(spell=Auditor, existence="many",
121              permissions="create", binding_name="restore-auditor")
122    conduit = book.conjure(name="restore-root")
123    ledger = conduit.meld("Ledger", binding_name="restore-ledger")
124    ledger.entries.append("before the checkpoint")
125    print("world up; ledger holds", len(ledger.entries), "entry")
126
127    # 1. SEAL IT. A checkpoint is minted, not overwritten.
128    first_id = crystallizer.create_checkpoint()
129    second_id = crystallizer.create_checkpoint()
130    assert first_id != second_id
131    ledger_of_ids = crystallizer.list_checkpoint_ids()
132    print()
133    print("two checkpoints minted:", first_id[:10], "...,", second_id[:10])
134    print("list_checkpoint_ids() ->", len(ledger_of_ids),
135          "in ledger creation order")
136    print("  checkpoints ACCUMULATE - there is no 'the' checkpoint, and")
137    print("  the id is the whole handle")
138
139    # 2. WHAT IS ACTUALLY IN ONE?
140    described = crystallizer.describe_checkpoint(second_id)
141    print()
142    print("describe_checkpoint keys:", sorted(described)[:8])
143    counts = described.get("captured_counts")
144    if isinstance(counts, dict):
145        live = {k: v for k, v in counts.items() if v}
146        print("captured:", live)
147
148    # 3. SEAL IT INTO THE CACHE. Advanced 18's warning still applies -
149    #    the cache is FIFO bounded, so a flush can evict an older entry.
150    flushed = crystallizer.flush_checkpoint(second_id)
151    assert second_id in flushed
152    cached = crystallizer.list_cached_checkpoint_ids()
153    assert second_id in cached
154    print()
155    print("flushed ->", len(flushed), " cached now:", len(cached))
156
157    # 4. CACHE BACK INTO THE LEDGER. This is history bookkeeping, not a
158    #    world change - nothing has been unfolded yet.
159    summary = crystallizer.reload_cached_checkpoint(second_id)
160    assert isinstance(summary, dict)
161    print("reload_cached_checkpoint -> the checkpoint's own summary")
162    print("  still no live object touched; that is the NEXT verb")
163
164    # 5. THE BOOT VERB. Release the old runtime's name and binding claims first;
165    # the sealed checkpoint and its predecessor remain in the living recorder.
166    conduit.permanent_cleanup()
167    report = crystallizer.load_checkpoint(second_id)
168    assert report["status"] == "complete"
169    restored_conduit = md.Aether().get_conduit_by_name("restore-root", FRAME)
170    restored_ledger = restored_conduit.meld("Ledger", binding_name="restore-ledger")
171    assert restored_ledger is not ledger
172    assert restored_ledger.entries == []
173    print()
174    print("load_checkpoint -> RestoreReport keys:", sorted(report))
175    print("   status:", report.get("status"))
176
177    # THE IDENTITY TRANSLATION MAP is the field that changes how you
178    # think about a restore.
179    translation = None
180    for key in ("identity_translation", "identity_translation_map",
181                "translation_map", "identity_map"):
182        if key in report:
183            translation = report[key]
184            print(f"   {key}: {len(translation)} remapped identities")
185            break
186    if translation is None:
187        print("   (identity map under another key - see the keys above)")
188    print("  rebuilt objects get NEW ids: the world that comes back is")
189    print("  EQUIVALENT, not identical. A raw pre-restore id is a stale")
190    print("  address, and this map is the only honest way to translate")
191
192    # SHORTFALLS: what could not be rebuilt, named rather than dropped.
193    for key in ("shortfall", "shortfalls", "shortfall_entries"):
194        if key in report:
195            entries = report[key]
196            print()
197            print(f"   {key}: {len(entries)} entr(y/ies)")
198            for entry in list(entries)[:3]:
199                print("      ", str(entry)[:88])
200            print("  a restore that silently dropped what it could not")
201            print("  rebuild would look exactly like a world that never")
202            print("  had those things - so it names them instead")
203            break
204
205    # This Ledger has no disposer. Our ordinary Python reference therefore
206    # still holds its earlier data; it is not the object in the rebuilt runtime.
207    # Objects with disposal contracts may be unusable after their scope ends.
208    assert ledger.entries == ["before the checkpoint"]
209    print()
210    print("the object we held across all of this is untouched:",
211          ledger.entries)
212    print("  the rebuilt ledger is a different object with fresh empty state")
213
214    # 6. THE OPERATOR'S ONE-CALL VERSION exists and is exported.
215    assert hasattr(md, "CrystallizerBootstrap")
216    print()
217    print("md.CrystallizerBootstrap() is the pod-boot form of all of the")
218    print("above - same steps, fixed order (expert 01). Note one of its")
219    print("knobs, with_preflight_gate, is an ACCEPTED NO-OP that says so")
220    print("in its own docstring rather than quietly doing nothing")
221
222    print()
223    print("seal, cache, reload, unfold - and only the last one is a boot")
224    print("a restore rebuilds an EQUIVALENT world and hands you the map")
225    restored_conduit.permanent_cleanup()
226
227
228if __name__ == "__main__":
229    main()

Check the outcome๏ƒ

The script contains its own assertions or demonstrated refusal paths. Run it to evaluate those checks against your installed version. The code above is taken directly from the saved file; no run output is invented here.

More expert examples ยท Level guide

API contracts๏ƒ