On this page
Taking a checkpoint๏
๐ Advanced ยท Lesson 17
TAKING A CHECKPOINT - and settling which configuration ladder is the house rule.
YOU HAVE NOW SEEN THREE SUBSYSTEMS COME UP.
lesson 07 Aether you finalize, you activate the config, THEN aether.activate() - and handing it a merely-frozen config raises lesson 08 Nexus you hand over a config and activate() finalizes it FOR you lesson 17 Crystallizer ...follows AETHER.
The Crystallizer contract says it in the same capitals Aether used:
"ORDERING RULE: THE CONFIGURATION MUST BE ACTIVATED FIRST... Two distinct failure modes: 'not configured' and 'configuration not activated'."
So it is two against one. Caller-driven activation is the house rule; Nexus is the exception. That is worth knowing before you meet a fourth subsystem - guess Aether's ladder and you will be right more often than not.
AND THE BUILDER HERE IS THE MOST GENEROUS IN THE LIBRARY. CrystallizerConfigurationBuilder offers THREE terminators, one per rung, so you choose where to get off:
build() hand me the configuration finalize() ...frozen activate() ...and in force
Compare AetherConfigurationBuilder, which offers only build() and leaves rung 2 to you. Same pattern, different generosity - which is exactly the kind of divergence the configuration-uniformity program exists to catalogue.
THE CHECKPOINT DOOR create_checkpoint(profile_name=None, description=None) -> str It hands back an ID. Everything else keys off that ID: list_checkpoint_ids() what exists describe_checkpoint(id) what is in one analyze_checkpoint(id) a deeper read verify_checkpoint_chain(...) is the lineage intact Lesson 18 does the loading half.
TWO BITS, FIFTH APPEARANCE: activated / is_activated on the Crystallizer, and activated on its configuration. By now you should expect it.
Before you run๏
Use the Advanced 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/03_advanced/17_taking_a_checkpoint.py
py -3.14t UX_and_AIX_experiences/03_advanced/17_taking_a_checkpoint.py
Public surface๏
md.Crystallizer, md.CrystallizerConfiguration, md.CrystallizerConfigurationBuilder, create_checkpoint, list_checkpoint_ids, describe_checkpoint
Code๏
1"""
2TIER: advanced (17)
3GOAL: TAKING A CHECKPOINT - and settling which configuration ladder is
4 the house rule.
5
6 YOU HAVE NOW SEEN THREE SUBSYSTEMS COME UP.
7
8 lesson 07 Aether you finalize, you activate the config,
9 THEN aether.activate() - and handing it a
10 merely-frozen config raises
11 lesson 08 Nexus you hand over a config and activate()
12 finalizes it FOR you
13 lesson 17 Crystallizer ...follows AETHER.
14
15 The Crystallizer contract says it in the same capitals Aether used:
16
17 "ORDERING RULE: THE CONFIGURATION MUST BE ACTIVATED FIRST...
18 Two distinct failure modes: 'not configured' and 'configuration
19 not activated'."
20
21 So it is two against one. Caller-driven activation is the house
22 rule; Nexus is the exception. That is worth knowing before you meet
23 a fourth subsystem - guess Aether's ladder and you will be right
24 more often than not.
25
26 AND THE BUILDER HERE IS THE MOST GENEROUS IN THE LIBRARY.
27 CrystallizerConfigurationBuilder offers THREE terminators, one per
28 rung, so you choose where to get off:
29
30 build() hand me the configuration
31 finalize() ...frozen
32 activate() ...and in force
33
34 Compare AetherConfigurationBuilder, which offers only build() and
35 leaves rung 2 to you. Same pattern, different generosity - which is
36 exactly the kind of divergence the configuration-uniformity program
37 exists to catalogue.
38
39 THE CHECKPOINT DOOR
40 create_checkpoint(profile_name=None, description=None) -> str
41 It hands back an ID. Everything else keys off that ID:
42 list_checkpoint_ids() what exists
43 describe_checkpoint(id) what is in one
44 analyze_checkpoint(id) a deeper read
45 verify_checkpoint_chain(...) is the lineage intact
46 Lesson 18 does the loading half.
47
48 TWO BITS, FIFTH APPEARANCE: activated / is_activated on the
49 Crystallizer, and `activated` on its configuration. By now you
50 should expect it.
51SURFACE EXERCISED: md.Crystallizer, md.CrystallizerConfiguration,
52 md.CrystallizerConfigurationBuilder, create_checkpoint,
53 list_checkpoint_ids, describe_checkpoint
54VERIFY: rides the owner's 3.14t run; asserts are the contract.
55"""
56import melder as md
57
58
59def main() -> None:
60 crystallizer = md.Crystallizer()
61 print("crystallizer activated at start:", crystallizer.activated)
62 assert crystallizer.activated is False
63
64 # THE CONFIG. Bare constructor - unlike the frame posture in lesson 06,
65 # this one you build empty and fill in.
66 config = md.CrystallizerConfiguration()
67 config.with_defaults()
68
69 # AETHER'S LADDER, NOT NEXUS'S. Rung 1: seal it.
70 config.finalize()
71 assert config.activated is False
72 print("config finalized - activated:", config.activated)
73
74 # Rung 2: the caller activates. Nexus would have done this for us;
75 # Aether and Crystallizer both make it explicit.
76 config.activate()
77 assert config.activated is True
78 print("config activated - activated:", config.activated)
79
80 # Rung 3: the subsystem comes up.
81 crystallizer.activate(config)
82 assert crystallizer.activated is True
83 # NOTE: `is_activated` is a PROPERTY, not a method - calling it gives
84 # "TypeError: 'bool' object is not callable". Two read names for one
85 # bit, both properties.
86 assert crystallizer.is_activated is True
87 print("crystallizer activated:", crystallizer.activated)
88
89 # THE THREE-EXIT BUILDER. Same destination, you pick the rung. This is
90 # a SECOND configuration object - the one above is already installed.
91 builder = md.CrystallizerConfigurationBuilder()
92 for terminator in ("build", "finalize", "activate"):
93 assert hasattr(builder, terminator), terminator
94 print()
95 print("CrystallizerConfigurationBuilder terminators: build/finalize/activate")
96 print("AetherConfigurationBuilder offers only build() - rung 2 is yours")
97
98 ready = md.CrystallizerConfigurationBuilder().with_defaults().activate()
99 assert isinstance(ready, md.CrystallizerConfiguration)
100 assert ready.activated is True
101 print("builder.activate() -> a config already in force")
102
103 # ------------------------------------------------------------------
104 # THE CHECKPOINT
105 # ------------------------------------------------------------------
106 before = crystallizer.list_checkpoint_ids()
107 assert isinstance(before, list)
108 print()
109 print("checkpoints before:", len(before))
110
111 checkpoint_id = crystallizer.create_checkpoint(
112 description="advanced lesson 17 - first checkpoint",
113 )
114 assert isinstance(checkpoint_id, str) and checkpoint_id
115 print("created checkpoint:", checkpoint_id)
116
117 after = crystallizer.list_checkpoint_ids()
118 assert checkpoint_id in after
119 assert len(after) == len(before) + 1
120 print("checkpoints after: ", len(after))
121
122 # THE ID IS THE HANDLE. Everything else keys off it.
123 described = crystallizer.describe_checkpoint(checkpoint_id)
124 assert isinstance(described, dict)
125 print("describe_checkpoint ->", len(described), "keys")
126 print(" keys:", sorted(described)[:6])
127
128 # A second checkpoint gets its own id - they are not overwritten.
129 second_id = crystallizer.create_checkpoint(description="second")
130 assert second_id != checkpoint_id
131 assert len(crystallizer.list_checkpoint_ids()) == len(before) + 2
132 print("second checkpoint is a distinct id, not an overwrite")
133
134 print()
135 print("caller-driven activation is the house rule - nexus is the exception")
136 print("create_checkpoint hands back an ID; the ID is the whole handle")
137
138
139if __name__ == "__main__":
140 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.