# Research sets lanes and residency **🔵 Expert · Lesson 03** MUTATION RESEARCH - melder's record of how a world CHANGED, not what it currently is. Everything up to here described a runtime. This describes its history. THE SHAPE MutationResearch the subsystem (same ladder as Aether and Crystallizer - you activate the config, then the subsystem; advanced 17 settled that it is 3-to-1 with Nexus the exception) ResearchSet one named body of history ResearchLane a track within it ResearchJournal the ordered record TWO ENUMS, AND THEY ANSWER DIFFERENT QUESTIONS LaneState open / joined / archived - can I still write here? LaneType development / experiment / production / test - what KIND of work is this? A lane has both. State is lifecycle; type is intent. Collapsing them would mean you could not have an archived production lane and an open one at the same time, which is exactly what a real promotion history looks like. LANE TYPE ENFORCEMENT IS A KNOB set_lane_type_enforcement(enabled) Off, the types are labels. On, they are rules. Melder ships the choice rather than assuming which one you are doing - a research set exploring a hypothesis and a research set tracking a production promotion chain want opposite answers. RESIDENCY IS THE IDEA WORTH TAKING AWAY. residence_of(spell_id) -> lane name or None A spell LIVES IN exactly one lane at a time. That is what makes "where is this thing now?" a question with one answer, and it is why promotion is a MOVE rather than a copy. `heads()` gives you the current tip per lane; `walk(lane)` gives the ordered contents; `history(spell_id)` follows one spell across lanes. CAMPAIGNS group work that belongs together across lanes: set_active_campaign / clear_active_campaign / campaign_view Set one and subsequent records join it, so you can ask "what did this campaign touch" without threading an id through every call. ANCESTRY IS STAGED, THEN RECORDED. stage_ancestry(parent_spell_ids) -> record_world_entry(...) You declare the parents BEFORE the entry that uses them. Staging is explicit and clearable, so a half-built lineage is visible as staged-but-unrecorded rather than silently attached to the wrong thing. ## Before you run Use the [Expert guide](../../expert/index.md) 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 ```bash python UX_and_AIX_experiences/04_expert/03_research_sets_lanes_and_residency.py ``` ```powershell py -3.14t UX_and_AIX_experiences/04_expert/03_research_sets_lanes_and_residency.py ``` {download}`Download this collection <../../downloads/expert-examples.zip>` · [Source on GitHub](https://github.com/Synaptic724/melder/blob/90d52e0a12cb0743d62568d5a19ce954a54443bc/UX_and_AIX_experiences/04_expert/03_research_sets_lanes_and_residency.py) ## Public surface md.MutationResearch, md.ResearchSet, md.LaneState, md.LaneType - lanes, residency, campaigns, ancestry ## Code ```{literalinclude} ../../downloads/04_expert/03_research_sets_lanes_and_residency.py :language: python :linenos: ``` ## 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](index.md) · [Level guide](../../expert/index.md) ## Related guides - [Research sets, lanes, residency, and recorded source](../../expert/research.md) ## API contracts - [MutationResearch](../../reference/api/research/mutationresearch.md) - [ResearchSet](../../reference/api/research/researchset.md) - [LaneState](../../reference/api/research/lanestate.md) - [LaneType](../../reference/api/research/lanetype.md)