On this page

The codegen room agents writing code๏ƒ

๐Ÿ”ต Expert ยท Lesson 07

THE CODEGEN ROOM - where an agent writes code that becomes part of a running world, and the gate it has to get through first. This is the only room kind where the caller supplies EXECUTABLE SOURCE, so it is the only one that has to answer "may I" before "did it work".

THE DEFAULT POSTURE IS DENY, AND THE DENYLIST IS THE THREAT MODEL WRITTEN DOWN. A codegen room with no widening projection ships with imports OFF entirely and thirteen builtins refused by name:

import breakpoint compile dir eval exec getattr globals input locals setattr delattr vars

Read that list as a document rather than a setting. Every entry is a door OUT of the namespace contract: eval/exec/compile execute text the gate never saw, __import__ bypasses the import rules, getattr/setattr/vars/dir reach attributes by computed name, and globals/locals hand back the environment itself. Somebody enumerated the ways out and wrote them down where you can read them.

A REFUSAL IS A VALUE, AND IT NAMES THE OFFENDER. validate_codegen returns a payload, not an exception and not a bare boolean: {"accepted": bool, "frame_name": str, "reason": str, "validation_issues": (str, ...)} Rejected source comes back as accepted: False with a message that names the specific thing - "Builtin 'eval' is not allowed in this codegen mode" - because a bare False would force you to re-run validation with different instrumentation just to learn why.

THE CHAIN IS ORDERED AND IT SHORT-CIRCUITS. Syntax is checked first (a parse failure never reaches a gate), then seven strategies run in a fixed sequence and the FIRST refusal returns immediately:

ast_structure -> import_policy -> builtin_policy -> name_resolution -> attribute_access -> reflection_policy -> recursive_control

So validation_issues is normally ONE issue: the first gate that objected, not an audit of everything wrong. Fix it and re-ask - the next answer may well name a different gate. And the order is observable, which is why it is worth knowing rather than guessing: eval('1 + 1') is refused by builtin_policy, which sits BEFORE name_resolution, so you get the builtin message rather than an unresolved-name one.

READ recursive_control TWICE. It is last in the chain and it exists because generated code that generates code is how a bounded system stops being bounded. Someone thought about an agent escaping its sandbox by writing a smaller one inside it.

VALIDATION RUNS BEFORE THE ENVIRONMENT EXISTS, AND THAT ORDERING IS THE POINT. The gates read the AST, not a live namespace. The execution environment has not been built when they run - and building it to find out whether building it was allowed "would be exactly the escape the gate exists to prevent". That is why validate_codegen is a separate verb rather than a flag on execute: you can learn a boundary without approaching it.

AND MELDER DOES NOT CLAIM THIS IS A PROOF. In its own words, the checks reject OBVIOUS violations, because "static analysis of Python cannot be exhaustive, so the validation chain is defence in depth alongside the namespace denylists and the ACL posture, not a proof of safety on its own". Three layers, named, with the honest limit stated. A system that claimed a guarantee here would be lying, and the willingness to write that down is worth more than the claim.

THE ROOM OVERRIDES A THIRD PROPERTY. Advanced 11 found static and capability each swap TWO - command_system (what you may DO) and frame_viewer (what you may SEE). CodegenRiftSpace adds codegen_system: what you may MAKE. Do / see / make, each by handing over a different class rather than guarding a shared one.

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

Download this collection ยท Source on GitHub

Public surface๏ƒ

validate_codegen driven against accepted source, a denied import and a denied builtin; the validation payload shape; RiftSpace.space_kind / command_system / frame_viewer / codegen_system; list_supported_command_methods

Code๏ƒ

  1"""
  2TIER: expert (07)
  3GOAL: THE CODEGEN ROOM - where an agent writes code that becomes part of
  4      a running world, and the gate it has to get through first. This is
  5      the only room kind where the caller supplies EXECUTABLE SOURCE, so
  6      it is the only one that has to answer "may I" before "did it work".
  7
  8      THE DEFAULT POSTURE IS DENY, AND THE DENYLIST IS THE THREAT MODEL
  9      WRITTEN DOWN. A codegen room with no widening projection ships with
 10      imports OFF entirely and thirteen builtins refused by name:
 11
 12        __import__  breakpoint  compile  dir     eval    exec   getattr
 13        globals     input       locals   setattr delattr vars
 14
 15      Read that list as a document rather than a setting. Every entry is a
 16      door OUT of the namespace contract: `eval`/`exec`/`compile` execute
 17      text the gate never saw, `__import__` bypasses the import rules,
 18      `getattr`/`setattr`/`vars`/`dir` reach attributes by computed name,
 19      and `globals`/`locals` hand back the environment itself. Somebody
 20      enumerated the ways out and wrote them down where you can read them.
 21
 22      A REFUSAL IS A VALUE, AND IT NAMES THE OFFENDER.
 23      `validate_codegen` returns a payload, not an exception and not a
 24      bare boolean:
 25        {"accepted": bool, "frame_name": str, "reason": str,
 26         "validation_issues": (str, ...)}
 27      Rejected source comes back as `accepted: False` with a message that
 28      names the specific thing - "Builtin 'eval' is not allowed in this
 29      codegen mode" - because a bare False would force you to re-run
 30      validation with different instrumentation just to learn why.
 31
 32      THE CHAIN IS ORDERED AND IT SHORT-CIRCUITS. Syntax is checked first
 33      (a parse failure never reaches a gate), then seven strategies run in
 34      a fixed sequence and the FIRST refusal returns immediately:
 35
 36        ast_structure -> import_policy -> builtin_policy ->
 37        name_resolution -> attribute_access -> reflection_policy ->
 38        recursive_control
 39
 40      So `validation_issues` is normally ONE issue: the first gate that
 41      objected, not an audit of everything wrong. Fix it and re-ask - the
 42      next answer may well name a different gate. And the order is
 43      observable, which is why it is worth knowing rather than guessing:
 44      `eval('1 + 1')` is refused by builtin_policy, which sits BEFORE
 45      name_resolution, so you get the builtin message rather than an
 46      unresolved-name one.
 47
 48      READ `recursive_control` TWICE. It is last in the chain and it
 49      exists because generated code that generates code is how a bounded
 50      system stops being bounded. Someone thought about an agent escaping
 51      its sandbox by writing a smaller one inside it.
 52
 53      VALIDATION RUNS BEFORE THE ENVIRONMENT EXISTS, AND THAT ORDERING IS
 54      THE POINT. The gates read the AST, not a live namespace. The
 55      execution environment has not been built when they run - and
 56      building it to find out whether building it was allowed "would be
 57      exactly the escape the gate exists to prevent". That is why
 58      `validate_codegen` is a separate verb rather than a flag on execute:
 59      you can learn a boundary without approaching it.
 60
 61      AND MELDER DOES NOT CLAIM THIS IS A PROOF. In its own words, the
 62      checks reject OBVIOUS violations, because "static analysis of Python
 63      cannot be exhaustive, so the validation chain is defence in depth
 64      alongside the namespace denylists and the ACL posture, not a proof
 65      of safety on its own". Three layers, named, with the honest limit
 66      stated. A system that claimed a guarantee here would be lying, and
 67      the willingness to write that down is worth more than the claim.
 68
 69      THE ROOM OVERRIDES A THIRD PROPERTY. Advanced 11 found static and
 70      capability each swap TWO - `command_system` (what you may DO) and
 71      `frame_viewer` (what you may SEE). CodegenRiftSpace adds
 72      `codegen_system`: what you may MAKE. Do / see / make, each by
 73      handing over a different class rather than guarding a shared one.
 74SURFACE EXERCISED: validate_codegen driven against accepted source, a
 75                   denied import and a denied builtin; the validation
 76                   payload shape; RiftSpace.space_kind / command_system /
 77                   frame_viewer / codegen_system;
 78                   list_supported_command_methods
 79VERIFY: rewritten 2026-08-05 to DRIVE the validator instead of listing
 80        gate names; not yet re-run.
 81"""
 82import melder as md
 83
 84
 85FRAME = "gate-world"
 86
 87SAFE = "result = 2 + 2\n"
 88IMPORTING = "import socket\nresult = socket\n"
 89EVALUATING = "result = eval('1 + 1')\n"
 90
 91# The shipped deny list for a room with no widening projection. Named
 92# here so the lesson can CHECK the refusals against it rather than assert
 93# a number it typed.
 94DENIED_BUILTINS = (
 95    "__import__", "breakpoint", "compile", "dir", "eval", "exec",
 96    "getattr", "globals", "input", "locals", "setattr", "delattr", "vars",
 97)
 98
 99
100def main() -> None:
101    spellbook_configuration = (
102        md.SpellbookConfiguration(FRAME).with_defaults().finalize()
103    )
104    book = md.Spellbook(aetheric_frame=FRAME,
105                        configuration=spellbook_configuration)
106    book.configure_aether_frame(
107        system_state="dynamic",
108        disposal=None,
109        disposal_method_names=None,
110        rift_enabled=True,
111        ai_native=True,
112    )
113    # An empty conjured frame is a real frame - `conjure` realizes it and
114    # publishes it to the Nexus, and spells are cargo rather than a
115    # precondition (expert 33).
116    book.conjure(name="gate-root")
117
118    nexus = md.Nexus()
119    system_configuration = nexus.create_configuration()
120    system_configuration.with_rift_creation_enabled(True)
121    system_configuration.with_allowed_target_frame_names([FRAME])
122    nexus.activate(system_configuration)
123    rift_configuration = nexus.create_rift_configuration()
124    rift_configuration.with_space_type("codegen")
125    rift = nexus.create_rift(configuration=rift_configuration,
126                             rift_name="workshop")
127    rift.mark_active()
128    rift.create_frame_link(FRAME)
129
130    room = rift.space
131    commands = room.command_system
132
133    # DO / SEE / MAKE - three properties, three classes, one room kind.
134    assert room.space_kind == "codegen"
135    print("room kind:", room.space_kind, "->", type(room).__name__)
136    print("  command_system:", type(commands).__name__, "(what you may DO)")
137    print("  frame_viewer  :", type(room.frame_viewer).__name__,
138          "(what you may SEE)")
139    assert hasattr(room, "codegen_system"), "the codegen room adds a third"
140    print("  codegen_system:", type(room.codegen_system).__name__,
141          "(what you may MAKE)")
142
143    # ACCEPTED SOURCE. The payload is a verdict, not a boolean.
144    print()
145    print("ASKING PERMISSION, WITHOUT RUNNING ANYTHING:")
146    accepted = commands.validate_codegen(SAFE, frame_name=FRAME)
147    assert isinstance(accepted, dict), accepted
148    assert accepted["accepted"] is True, accepted
149    assert accepted["frame_name"] == FRAME
150    print("  validate(result = 2 + 2)  -> accepted:", accepted["accepted"],
151          "| reason:", accepted.get("reason"))
152
153    # A DENIED IMPORT. The shipped posture has imports OFF entirely, so
154    # the refusal is about the STATEMENT, not about `socket` specifically.
155    denied_import = commands.validate_codegen(IMPORTING, frame_name=FRAME)
156    assert denied_import["accepted"] is False, denied_import
157    import_issues = denied_import.get("validation_issues", ())
158    assert import_issues, denied_import
159    print()
160    print("  validate(import socket)   -> accepted:",
161          denied_import["accepted"])
162    print("    reason :", denied_import.get("reason"))
163    print("    issue  :", import_issues[0])
164    print("    imports are OFF in the shipped posture, so the refusal is")
165    print("    about the STATEMENT rather than about `socket` - there is")
166    print("    no allow-list to fail yet. A widening ACL projection is")
167    print("    what turns them on, and it is NOT reachable from the")
168    print("    public surface today (see expert 34, withdrawn)")
169
170    # A DENIED BUILTIN. This one DOES name the offender, because the
171    # denylist is per-name.
172    denied_builtin = commands.validate_codegen(EVALUATING, frame_name=FRAME)
173    assert denied_builtin["accepted"] is False, denied_builtin
174    builtin_issues = denied_builtin.get("validation_issues", ())
175    assert builtin_issues, denied_builtin
176    assert "eval" in builtin_issues[0], builtin_issues
177    print()
178    print("  validate(eval('1 + 1'))   -> accepted:",
179          denied_builtin["accepted"])
180    print("    issue  :", builtin_issues[0])
181    print("    it NAMES the builtin. A bare False would make you re-run")
182    print("    validation with different instrumentation to learn why")
183
184    # ONE ISSUE, NOT AN AUDIT. The chain returns on the FIRST refusal, so
185    # a rejected payload carries the first gate's objection and stops.
186    assert len(builtin_issues) == 1, builtin_issues
187    print("    and exactly ONE issue came back - the chain short-circuits,")
188    print("    so this is the first gate that objected, not a list of")
189    print("    everything wrong. Fix it and ask again; the next answer")
190    print("    may name a different gate.")
191
192    # NOTHING RAN. Three verdicts, zero execution - which is the whole
193    # reason validate is its own verb.
194    print()
195    print("three verdicts so far and NOTHING has executed. The gates read")
196    print("the AST; the namespace does not exist yet. Building it to find")
197    print("out whether building it was permitted would be exactly the")
198    print("escape the gate exists to prevent.")
199
200    # THE DENYLIST AS A DOCUMENT.
201    print()
202    print("the shipped builtin denylist -", len(DENIED_BUILTINS), "names:")
203    print("   ", " ".join(DENIED_BUILTINS[:7]))
204    print("   ", " ".join(DENIED_BUILTINS[7:]))
205    print("  every one is a door OUT of the namespace contract:")
206    print("    eval / exec / compile  run text the gate never saw")
207    print("    __import__             bypasses the import rules")
208    print("    getattr / setattr /")
209    print("    vars / dir             reach attributes by computed name")
210    print("    globals / locals       hand back the environment itself")
211
212    # MALFORMED REQUEST IS A DIFFERENT FAILURE FROM DISALLOWED CODE.
213    for bad_code, bad_frame in (("", FRAME), (SAFE, "")):
214        try:
215            commands.validate_codegen(bad_code, frame_name=bad_frame)
216            raise AssertionError("expected ValueError on an empty argument")
217        except ValueError:
218            pass
219    print()
220    print("empty code or empty frame_name RAISE ValueError - a malformed")
221    print("REQUEST is a different failure from disallowed CODE, and they")
222    print("are not spelled the same way")
223
224    # The room enumerates its own authority (the AIX door from advanced 11).
225    supported = commands.list_supported_command_methods()
226    assert isinstance(supported, tuple)
227    assert "validate_codegen" in supported
228    print()
229    print("the room reports", len(supported), "command methods it will answer")
230
231    print()
232    print("validate is a SEPARATE verb - learn a boundary without")
233    print("approaching it. And melder does not call this a proof: the")
234    print("checks reject OBVIOUS violations, and the honest claim is")
235    print("defence in depth across gates, namespace denylists and the ACL")
236    print("posture. A system promising a guarantee here would be lying.")
237
238
239if __name__ == "__main__":
240    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๏ƒ