Mutation Forge Lab searches for deterministic Python policies that rank legal graph mutations for HEG. Native v2 uses either the local Codex App Server or an OpenAI-compatible llama.cpp endpoint to generate policy candidates, validates and behavior-probes them in a bounded sandbox, evaluates them against HEG and fixed baselines, and evolves the best candidates across multiple generations.
The project is a standalone, auditable research application. It treats the sibling HEG repository as a read-only mathematical backend and never modifies HEG. Generated policies implement only:
def priority(ctx, proposal):
...They rank host-generated legal proposals; they do not generate graph rewrites, score hidden alternatives, or replace HEG's validation and verification.
For every experiment, Mutation Forge Lab:
- creates an immutable experiment workspace and records repository provenance;
- asks the configured local Codex model for eight differentiated ranking policies;
- validates the structured response, Python AST, declared fields, bounded runtime contract, and proposal-dependent behavior;
- repairs eligible invalid responses within the configured repair limit;
- evaluates accepted policies and the random/structural baselines under matched HEG budgets;
- archives candidates, selects parents with the configured search strategy, and continues until a session boundary or terminal outcome;
- retains prompts, raw responses, transport diagnostics, token usage, evaluations, checkpoints, and winner information.
The installed CLI intentionally exposes only the current native product:
mforge doctor
mforge experiment run
mforge experiment status
Historical stage-specific implementations remain in the repository as regression and research evidence, but they are not public CLI commands.
- Linux;
- Python 3.12 or newer;
- uv;
- a functional sibling HEG checkout, normally at
../heg; - for the Codex provider, an installed and locally authenticated
codexexecutable with App Server support; - alternatively, for Native v2, a llama.cpp/Strata chat-completions endpoint.
Install the locked environment and check the local project/HEG setup:
uv sync --locked
uv run mforge doctor --heg-repo ../hegdoctor does not authenticate Codex and does not start a model turn. Ensure
the local Codex installation is authenticated before running an experiment.
Credentials must not be placed in experiment.toml; credential-bearing
configuration fields are rejected.
Create experiment.toml in the repository root:
schema_version = "mforge.experiment.v2"
exp_id = "heg-ranker-search-01"
workspace = "./workspace"
kind = "heg"
preset = "native"
[run]
wall_seconds = 3600
output = "rich"
profiling_enabled = false
deep_profiling_enabled = false
turn_timeout_base_seconds = 120
max_total_tokens_per_hour = 1_000_000
[model]
provider = "codex"
name = "gpt-5.6-luna"
effort = "xhigh"
concurrency = 8
max_repairs = 1
[search]
population_size = 8
max_generations = "unbounded"
max_model_turns = "unbounded"
selection = "persistent-elite-weighted-diversity"
[evaluation]
graph_mode = "unrestricted_min_degree_3"
order_schedule = "static"
orders = [10, 12]
graph_seeds = [401, 402, 403, 404]
policy_seeds = [
4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008,
4009, 4010, 4011, 4012, 4013, 4014, 4015, 4016,
]
horizon = 32
proposal_pool_size = 12
baselines = ["random", "structural"]
replay = true
[resources]
workers = 8
thread_count = 1Check the resolved target without contacting a model:
uv run mforge experiment status --config experiment.tomlStart or resume the experiment:
uv run mforge experiment run --config experiment.tomlThis command starts Codex App Server model turns and consumes the configured model account's tokens. For machine-readable progress and results:
uv run mforge experiment run --config experiment.toml --json
uv run mforge experiment status --config experiment.toml --jsonexperiment.toml is authoritative. Unknown and legacy keys are rejected
instead of being silently ignored.
| Section | Purpose |
|---|---|
| top level | Experiment identity, workspace, native kind, and preset |
[run] |
Per-invocation wall budget, rolling token cap, output mode, profiling, and timeout base |
[model] |
Codex model, reasoning effort, model concurrency, and repair limit |
[search] |
Population, global generation/turn limits, and parent selection |
[evaluation] |
HEG orders, seeds, horizon, proposal pools, baselines, and replay |
[resources] |
Resource reservation (workers) and native evaluation pool (thread_count) |
Important behavior:
- The production open-ended HEG configuration uses
population_size = 8, matching the eight differentiated mutation briefs. max_generationsandmax_model_turnsare required. Each accepts a positive integer or the exact string"unbounded".- Model-turn accounting remains cumulative when the limit is unbounded.
order_schedule = "static"requires an explicitordersarray.order_schedule = "adaptive"instead requiresmin_order,max_order, andorders_per_generation. The first generation uses the lowest eligible orders. Each later generation expands the eligible prefix byorders_per_generationand evaluates evenly spaced orders from the minimum through the current frontier. The schedule stays fixed after reachingmax_order;cubic_firstskips odd orders.selection = "elite-diversity"keeps the previous generation's best and fills the population with distinct policies. The recommendedselection = "persistent-elite-weighted-diversity"allows repeated parents; for a population of eight it assigns three slots to the all-time best, two to the current-generation best, two by objective-weighted allocation from the current top half, and one by AST diversity from that top half.model.effortmay be changed between resumable sessions without creating a new experiment identity; the next provider turn uses the current value.max_total_tokens_per_houris optional. It accepts a positive integer or"unbounded"and applies to the canonicaltotalTokenscharged during the rolling previous 60 minutes.- Reaching the hourly token cap ends the current session as resumable
IDLEwithstop_reason=hourly_token_limit; no new model turn starts until enough prior usage leaves the rolling window. wall_secondsapplies to one invocation. Reaching it pauses the experiment in resumableidlewithstop_reason=session_wall_seconds.- Uncharged provider infrastructure failures are retried on the same idempotent request, including repair turns, with a bounded exponential backoff. They do not consume the cumulative model-turn budget.
- The effective model-turn timeout is
turn_timeout_base_seconds * (model.concurrency + 1). max_repairsis persisted with every slot and remains enforced after resume.outputis eitherrichorjson;--jsonselects JSON output for the current command.- Model, search, evaluation, and resource settings are locked when the workspace is created. Any scientific change requires a fresh workspace.
The compact model identifier uses the first colon for the provider and the last colon for effort. Everything between them is the model name:
[model]
name = "codex:gpt-6.1-sol:low"
concurrency = 1
max_repairs = 1For the local Strata endpoint:
[model]
name = "llamacpp:qwen3.8-flash-next-ud-q4_k_xl:medium"
base_url = "http://192.168.100.207:8080/v1"
max_output_tokens = 8192
concurrency = 1
max_repairs = 1For example, llamacpp:qwen3:27b:medium selects model qwen3:27b. Effort is
required. The separate legacy provider, name, and effort fields remain
supported; omit both provider and effort when using the compact form.
Both forms resolve to the same Native v2 immutable experiment identity.
llama.cpp effort supports low, medium, high, and xhigh, sent as
chat_template_kwargs.reasoning_effort. The deployed chat template must
support that field; the configured Strata Qwen template does. none omits
this setting and preserves server defaults; it does not disable thinking.
Codex retains its existing effort options and does not accept none.
The HTTP adapter uses non-streaming /chat/completions with JSON Schema,
no tools, a bounded response, and the existing timeout/repair contract. There
is no silent fallback if the server rejects JSON Schema or effort options.
Complete server usage is required: missing usage is retained as unknown and
fails the turn rather than inventing zero tokens. Possibly submitted HTTP
failures are not automatically retried; they conservatively consume a turn
budget, without inventing token usage or a monetary charge.
Endpoint and output limit are immutable scientific settings. Use a new
workspace when switching provider, model, endpoint, or output limit. The
separate Native v3 Python protocol is unchanged and remains Codex-only.
configs/local-llamacpp.toml is a bounded Native v2 example, not a replacement
for an existing Python scientific campaign.
To test only the provider, without HEG computation or generated-code execution:
uv run python scripts/smoke_native_provider.py --model llamacpp:qwen3.8-flash-next-ud-q4_k_xl:low --base-url http://192.168.100.207:8080/v1 --max-output-tokens 8192
uv run python scripts/smoke_native_provider.py --model codex:gpt-6.1-sol:lowEach command makes one model call and retains its evidence in a fresh temporary directory. It checks JSON and usage only; it never runs an experiment or policy.
The first run atomically creates <workspace>/<exp_id>/. Later invocations
with the same configuration resume from the latest durable checkpoint.
| State | Meaning |
|---|---|
not_created |
Configuration is valid, but no workspace exists yet |
running |
A session currently owns the experiment |
idle |
A session wall boundary paused the run; running again resumes work |
paused |
Verification or an administrative policy requires explicit continuation |
interrupted |
The process was interrupted or its owner died; running again resumes |
exhausted |
An explicitly finite generation or model-turn range was consumed |
failed |
A non-recoverable contract, verification, or orchestration failure |
completed |
A counterexample was certified or the operator used stop --final |
Ctrl-C records an interrupted, resumable session. A subsequent
experiment run recovers completed turn artifacts and continues pending work
without replacing already accepted model turns. Running an already completed
experiment creates a zero-work already_completed session and does not call
the provider.
To keep one process running across repeated wall-budget sessions, use:
uv run mforge experiment run --dashboard --until-completeThe loop only continues after a normal session_wall_seconds boundary. A
persistent provider infrastructure failure remains visible as a resumable
failure requiring inspection.
An ordinary q or Ctrl-C remains resumable. To make an explicit terminal
operator decision:
uv run mforge experiment stop --finalUse the read-only status command at any time:
uv run mforge experiment statusIt reports progress, resumability, accepted/evaluated candidates, the current winner and source path, model-turn and token totals, charged failed turns, checkpoint identity, artifact locations, stop reason, and the latest error. It never calls the provider, scorer, oracle, or evaluator.
An experiment retains its full operational and scientific record:
workspace/<exp_id>/
├── experiment.toml
├── experiment.lock.json.gz
├── state.sqlite3
├── checkpoints/
│ └── checkpoint-*.json.gz
└── artifacts/
├── experiment-manifest.json.gz
├── native-generation-checkpoint.json.gz
├── sessions/
│ └── session-NNNNNN/
│ ├── session.json.gz
│ ├── summary.json.gz
│ ├── events.jsonl
│ ├── stdout.log
│ └── stderr.log
├── generations/
│ └── generation-NNNN/slot-NN/
│ ├── initial/
│ ├── repair-NN/
│ └── retry-NN/
├── archive/
├── evaluations/
│ ├── development/
│ └── replay/
└── reports/
Each model turn keeps separate evidence for:
- the exact model-facing request and system prompt;
- the raw and parsed response;
- JSON/schema and App Server transport diagnostics;
- AST validation and source-derived
used_fields; - behavior-probe output and worker telemetry;
- provider identifiers, event/RPC streams, and exact token usage.
There is no separate public report command. experiment status is the
supported summary view; summary.json.gz, archived source files, evaluation
records, and turn artifacts provide the detailed evidence.
Native policies receive the public Stage 2B context/proposal contracts:
The host enforces the generated-policy response schema and a restricted Python AST. Policies cannot use imports, attributes, method calls, comprehensions, generator expressions, randomness, hidden scores, proposal IDs, schema versions, or provenance-only ranking fields. A valid policy must use at least one proposal-specific structural signal and must distinguish proposals in the scientific behavior probe.
HEG owns graph construction, legal proposal generation, rewrite application, scoring, and verification. Only the selected proposal is authoritatively evaluated.
See Generated Python security boundary and Codex App Server integration boundary for the detailed isolation and authority contracts.
The default Rich interface displays generation/slot progress, active model turns, evaluation throughput, CPU/profile summaries, candidates, token usage, and recent activity. JSON mode emits structured events suitable for external monitoring.
Profiling can be enabled in [run] or overridden for one invocation:
uv run mforge experiment run --profile
uv run mforge experiment run --no-profileDeep profiling is independently controlled by
run.deep_profiling_enabled. It adds measurement overhead and should be used
for diagnosis, not throughput comparisons.
The event fields and lifecycle are documented in Event schema.
Run the local verification suite with:
uv run pytest
uv run ruff check .
uv run mypy
uv run python scripts/render_stage3_prompts.py --checkUse uv, never pip, for dependency management. Keep the sibling HEG
repository read-only.
- Native experiment workflow
- Event schema
- Codex App Server integration
- Generated Python security
- Architecture
The milestone plan and retained Stage 1–4 reports are historical research
evidence. They are available under docs/ and
docs/reports/ but are intentionally not part of the primary
product workflow.
CC0-1.0.