On this page

Codegen create modify iterate๏ƒ

๐Ÿ”ต Expert ยท Lesson 26

THE LOOP TURNED MORE THAN ONCE - AND THE TWO BOOKS IT WRITES. Expert 12 drove the codegen verbs once. This iterates them, and in doing so hits the distinction that catches everyone: a codegen room and a research record keep DIFFERENT BOOKS, and only one is about your code.

THE TURN - four verbs, only two of which change anything: research_preview(code, frame_name=) what WOULD this do validate_codegen(code, frame_name=) am I permitted execute_codegen(code, frame_name=) do it materialize_codegen(code, module_name=, frame_name=) keep it Running is not keeping. materialize takes a module_name because durability needs an ADDRESS, and that is a separate decision from having run the code.

research_preview is CODEGEN-ROOMS-ONLY, and that is the tell for why room types differ at all: it TAKES CODE, so it only exists where writing code is already the room's business. A codegen room owns the full 34-command research family; a capability room owns twenty-one reads; a static room none.

THE TWO BOOKS THE ROOM'S what CODE was written. One record per SUCCESSFUL TOP-LEVEL public command - every command, not just codegen ones - with a call-depth counter suppressing the tree underneath each call. THE RESEARCH what VERSIONS exist. Written by bind (active), bind_inactive (staged) and a notch (promotion), and by NOTHING else. So execute_codegen writing a module does not mint a version. A BIND does. Cutting a lane and running three codegen turns leaves that lane EMPTY, and this lesson asserts it.

AND SINGLE RESIDENCE IS WHY YOU CANNOT JUST FILE IT ELSEWHERE. One spell_id - the SHA256 of a version's code - lives in exactly ONE lane, network wide, permanently - there is no release verb. bind_inactive already declared the staged version onto default, so register_spell(..., lane=...) for that id raises the REDISCOVERY signal naming the holding lane. That raise is a signal, not a failure: identical code always mints the same SHA, and this is the system saying "you built this before, here". The way to file it under a name is a different SET - a set is its own residence partition, so a version resident in one is simply unknown to another.

A STAGED VERSION IS BOUND THE WAY THE INDEX'S FIRST ONE WAS. Rate is bound under the string category 'Rate' with binding name 'iterate-rate' - the address a bare bind of Rate has, so a meld of 'Rate' still finds it - and RateV2 is staged the same way. Bound bare, RateV2 would be addressed by its own name, and bind_inactive refuses a version bound any other way (2026-10-25).

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/26_codegen_create_modify_iterate.py
py -3.14t UX_and_AIX_experiences/04_expert/26_codegen_create_modify_iterate.py

Download this collection ยท Source on GitHub

Public surface๏ƒ

CodegenCommandSystem.research_preview / validate_codegen / execute_codegen / materialize_codegen / research_create_lane / research_walk, MutationResearch.research_set / create_research_set, ResearchSet.register_spell / create_lane / walk, Conduit.bind_inactive

Code๏ƒ

  1"""
  2TIER: expert (26)
  3GOAL: THE LOOP TURNED MORE THAN ONCE - AND THE TWO BOOKS IT WRITES.
  4      Expert 12 drove the codegen verbs once. This iterates them, and in
  5      doing so hits the distinction that catches everyone: a codegen room
  6      and a research record keep DIFFERENT BOOKS, and only one is about
  7      your code.
  8
  9      THE TURN - four verbs, only two of which change anything:
 10        research_preview(code, frame_name=)  what WOULD this do
 11        validate_codegen(code, frame_name=)  am I permitted
 12        execute_codegen(code, frame_name=)   do it
 13        materialize_codegen(code, module_name=, frame_name=)   keep it
 14      Running is not keeping. `materialize` takes a module_name because
 15      durability needs an ADDRESS, and that is a separate decision from
 16      having run the code.
 17
 18      `research_preview` is CODEGEN-ROOMS-ONLY, and that is the tell for
 19      why room types differ at all: it TAKES CODE, so it only exists
 20      where writing code is already the room's business. A codegen room
 21      owns the full 34-command research family; a capability room owns
 22      twenty-one reads; a static room none.
 23
 24      THE TWO BOOKS
 25        THE ROOM'S      what CODE was written. One record per SUCCESSFUL
 26                        TOP-LEVEL public command - every command, not
 27                        just codegen ones - with a call-depth counter
 28                        suppressing the tree underneath each call.
 29        THE RESEARCH    what VERSIONS exist. Written by `bind` (active),
 30                        `bind_inactive` (staged) and a notch (promotion),
 31                        and by NOTHING else.
 32      So `execute_codegen` writing a module does not mint a version. A
 33      BIND does. Cutting a lane and running three codegen turns leaves
 34      that lane EMPTY, and this lesson asserts it.
 35
 36      AND SINGLE RESIDENCE IS WHY YOU CANNOT JUST FILE IT ELSEWHERE.
 37      One spell_id - the SHA256 of a version's code - lives in exactly
 38      ONE lane, network wide, permanently - there is no release verb.
 39      `bind_inactive` already declared the staged version onto `default`,
 40      so `register_spell(..., lane=...)` for that id raises the
 41      REDISCOVERY signal naming the holding lane. That raise is a signal,
 42      not a failure: identical code always mints the same SHA, and this
 43      is the system saying "you built this before, here".
 44      The way to file it under a name is a different SET - a set is its
 45      own residence partition, so a version resident in one is simply
 46      unknown to another.
 47
 48      A STAGED VERSION IS BOUND THE WAY THE INDEX'S FIRST ONE WAS. Rate
 49      is bound under the string category 'Rate' with binding name
 50      'iterate-rate' - the address a bare bind of Rate has, so a meld of
 51      'Rate' still finds it - and RateV2 is staged the same way. Bound
 52      bare, RateV2 would be addressed by its own name, and bind_inactive
 53      refuses a version bound any other way (2026-10-25).
 54SURFACE EXERCISED: CodegenCommandSystem.research_preview /
 55                   validate_codegen / execute_codegen /
 56                   materialize_codegen / research_create_lane /
 57                   research_walk,
 58                   MutationResearch.research_set / create_research_set,
 59                   ResearchSet.register_spell / create_lane / walk,
 60                   Conduit.bind_inactive
 61VERIFY: RUN GREEN 2026-10-25 on 3.14t, GIL off and on; asserts are the
 62        contract.
 63"""
 64import melder as md
 65
 66
 67FRAME = "iterate-world"
 68
 69
 70class Rate:
 71    def __init__(self) -> None:
 72        self.value = 1
 73
 74
 75class RateV2:
 76    def __init__(self) -> None:
 77        self.value = 2
 78
 79
 80TURNS = (
 81    ("turn-1", "rate_multiplier = 1\nresult = rate_multiplier\n"),
 82    ("turn-2", "rate_multiplier = 2\nresult = rate_multiplier * 10\n"),
 83    ("turn-3", "rate_multiplier = 3\nresult = rate_multiplier * 100\n"),
 84)
 85
 86UNGRANTED = "import socket\nresult = socket\n"
 87
 88
 89def main() -> None:
 90    # Custody and record FIRST: the research seams no-op unless the root
 91    # already exists and is active, and they never construct one.
 92    crystallizer = md.Crystallizer()
 93    crystallizer.activate(
 94        md.CrystallizerConfigurationBuilder().with_defaults().activate(),
 95    )
 96    research = md.MutationResearch()
 97    configuration = research.create_configuration()
 98    configuration.with_defaults().activate()
 99    research.activate(configuration)
100
101    # A recorded world must be born configured, and POSTURE GOES BEFORE
102    # BIND - a bind into a not-yet-dynamic frame declares nothing.
103    spellbook_configuration = (
104        md.SpellbookConfiguration(FRAME).with_defaults().finalize()
105    )
106    book = md.Spellbook(aetheric_frame=FRAME,
107                        configuration=spellbook_configuration)
108    book.configure_aether_frame(
109        system_state="dynamic",
110        disposal=None,
111        disposal_method_names=None,
112        rift_enabled=True,
113        ai_native=True,
114    )
115    v1 = book.bind(spell=Rate, spellframe="Rate", existence="unique",
116                   permissions="create", binding_name="iterate-rate")
117    conduit = book.conjure(name="iterate-root")
118    print("v1 bound - an ACTIVE world entry:", v1[:12], "...")
119
120    nexus = md.Nexus()
121    system_configuration = nexus.create_configuration()
122    system_configuration.with_rift_creation_enabled(True)
123    system_configuration.with_allowed_target_frame_names([FRAME])
124    nexus.activate(system_configuration)
125    rift_configuration = nexus.create_rift_configuration()
126    rift_configuration.with_space_type("codegen")
127    rift = nexus.create_rift(configuration=rift_configuration,
128                             rift_name="iterator")
129    rift.mark_active()
130    rift.create_frame_link(FRAME)
131    room = rift.space
132    commands = room.command_system
133
134    # Subscribe before acting: `memory_enabled` is literally "is anyone
135    # listening", so a room with no subscriber keeps nothing.
136    written = []
137    assert room.memory_system.memory_enabled is False
138    subscription = room.memory_system.register_memory_callback(written.append)
139    assert room.memory_system.memory_enabled is True
140
141    # A lane cut BEFORE the loop, so we can prove what the loop does not
142    # write to it. Anchoring records ancestry only - it copies nothing.
143    cut = commands.research_create_lane(
144        "codegen-turns", attach_to="default", attach_at_spell_id=v1,
145        reason="does a codegen turn mint a version? (it does not)",
146    )
147    assert cut["anchor_spell_id"] == v1
148    assert len(cut["nodes"]) == 0
149
150    print()
151    for label, code in TURNS:
152        preview = commands.research_preview(code, frame_name=FRAME)
153        verdict = commands.validate_codegen(code, frame_name=FRAME)
154        outcome = commands.execute_codegen(code, frame_name=FRAME)
155        kept = commands.materialize_codegen(
156            code,
157            module_name="iterate_policy_%s" % label.replace("-", "_"),
158            frame_name=FRAME,
159        )
160        print("%s: preview(%s) -> validate(%s) -> execute(%s) -> keep(%s)" % (
161            label, type(preview).__name__, type(verdict).__name__,
162            type(outcome).__name__, type(kept).__name__))
163
164    # A refusal mid-loop changes the verdict, not the structure. Nothing
165    # compiled, nothing ran, and the loop reads it rather than breaking.
166    denied = commands.validate_codegen(UNGRANTED, frame_name=FRAME)
167    refused = commands.execute_codegen(UNGRANTED, frame_name=FRAME)
168    print("ungranted import: validate ->", type(denied).__name__,
169          "| execute ->", type(refused).__name__)
170
171    room.memory_system.unregister_memory_callback(subscription)
172    assert room.memory_system.memory_enabled is False
173    print()
174    print("room memory:", len(written), "records - the unit is the COMMAND,")
175    print("  not the turn:", len(TURNS), "turns x 4 verbs plus the lane cut")
176
177    # THE RESEARCH BOOK IS UNTOUCHED BY ALL OF IT.
178    walked_turns = commands.research_walk("codegen-turns")
179    assert len(walked_turns) == 0, (
180        "a codegen turn is not a version - executing and materializing "
181        "code writes the ROOM's book, never the research record"
182    )
183    print("research_walk('codegen-turns') ->", len(walked_turns),
184          "nodes, and correctly so")
185
186    # Now mint versions the only way that works: bind / bind_inactive.
187    index = conduit.get_spell_by_spell_id(v1).spell_index
188    assert index.spells_in_index() == {v1}
189    assert conduit.meld("Rate", binding_name="iterate-rate").value == 1
190
191    # Staged the way the index's first version was bound, or refused.
192    staged = conduit.bind_inactive(
193        spell=RateV2, spell_index=index,
194        spellframe="Rate", binding_name="iterate-rate",
195        existence="unique", permissions="create",
196    )
197    assert index.spells_in_index() == {v1, staged}
198    assert index.selected_spell_id == v1, "staging must NOT move selection"
199    assert conduit.meld("Rate", binding_name="iterate-rate").value == 1
200    print("v2 STAGED: 2 members, selection unchanged, candidate inert")
201
202    walked_default = commands.research_walk("default")
203    assert len(walked_default) >= 1, (
204        "bind and bind_inactive declare world entries once the MR root is "
205        "active - if this is empty the root was activated too late"
206    )
207    print("research_walk('default') ->", len(walked_default),
208          "nodes - the binds recorded; the codegen calls did not")
209
210    # SINGLE RESIDENCE. The staged id already lives on `default`.
211    try:
212        research.research_set().register_spell(staged, lane="codegen-turns")
213        raise AssertionError("expected the rediscovery signal")
214    except RuntimeError as rediscovery:
215        print()
216        print("register_spell(staged, lane='codegen-turns') REFUSED:")
217        print("  ", str(rediscovery)[:110])
218
219    # A different SET is its own residence partition, so the same id
220    # files cleanly there.
221    #
222    # AND THIS IS THE ONE PLACE THE LESSON LEAVES THE ROOM COMMANDS, for a
223    # reason worth stating plainly: NONE of the room's 34 research verbs
224    # takes a set argument. They reach the record two ways and both land on
225    # the same set - the lane verbs call `research_set()` with no name, and
226    # the group/recent verbs call engine methods that DO accept `set_name`
227    # (`group_impact_view`, `group_drift_view`, `recent_activity_view` and
228    # eleven more) without passing it. Either way: one set.
229    # So a second set cannot be named through the room today, and holding
230    # it directly is the only way to show residence is PER-SET.
231    # `MutationResearch.research_set(name)` and `ResearchSet` are both
232    # public surface - a different LAYER of the public API, not a private
233    # door. Everywhere the room CAN answer, ask the room.
234    audit = research.create_research_set("codegen-audit")
235    audit.create_lane("turns", lane_type="experiment")
236    audit.register_spell(staged, lane="turns", reason="independent audit")
237    assert len(audit.walk("turns")) == 1
238    print("the SAME id accepted in a second set - residence is per-set")
239
240    # Promotion is expert 17's lesson: notch_spell(spell_index=...,
241    # spell_id=staged) makes the staged version active. This lesson keeps
242    # it parked: a lookup by its spell_id answers the staged version itself
243    # (until 0.2.8253 it answered the ACTIVE member), and v1 stays selected.
244    assert conduit.get_spell_by_spell_id(staged).spell_id == staged
245    assert index.selected_spell_id == v1
246    assert hasattr(conduit, "notch_spell")
247
248    print()
249    print("preview, permit, run, keep - four questions, four verbs")
250    print("two books: the room keeps CODE, research keeps VERSIONS")
251    print("a lane you never register into is empty, and that is not a bug")
252
253
254if __name__ == "__main__":
255    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๏ƒ