Minimal-mode research API¶
For the scientific workflow, start with the research loop and evidence and claims. This guide documents the agent-facing operations used by that workflow.
simjecture study launches minimal research. The agent chooses its plan, writes
code and uses its tools; the service records evidence and independently reviews
claims. --workflow minimal remains an alias for --mode minimal.
simjecture-supervise and simjecture-research use the same launcher.
The browser launches the same workflow. Native CLI backends and the built-in
API agent (--backend builtin with a private --provider-config) remain available.
Existing minimal studies preserve their saved contracts and deadlines. Older
classical, DSH, structured and frontier runs remain readable but cannot be resumed;
see migration. No existing evidence is silently converted.
For installation, a complete launch recipe, and monitoring/resume commands, use Run a headless study. The backend uses its existing login. Codex/GLM resume the same native thread; other configured CLI backends preserve the working folder and evidence state. The wall deadline survives process restarts. Operator instructions are frozen before experiments and included in every reviewer packet; changing them requires a new study.
The generated research/lab.py offers a small evidence API. Optional
research memory and comparison helpers keep observations,
interpretations and attempts traceable. Instrument-backed studies also use
methods review. Core operations include:
from lab import lab
experiment = lab.run("calculation.py", args=["--n", "128"],
inputs=["helper.py"], outputs=["result.json"], key="case-128")
state = lab.status() # Compact receipts; compact=False includes full metadata.
# After the experiment reports succeeded:
request = lab.review([experiment["id"]], "The finite result supports ...",
disposition="supported",
challenge={"strategy": "Exhaustive finite-domain test",
"experiments": [experiment["id"]],
"outcome": "Every declared case passed"})
review = lab.review_status(request["id"])
run returns immediately. You may keep working while jobs execute, or end the model turn; the host then waits for a recorded job to finish before resuming the agent. The service snapshots source and declared local inputs,
records their hashes and arguments, and runs the experiment inside Simjecture’s
selected numerical execution backend (Bubblewrap by default; cooperative PRoot
is not a security boundary). An installed capability can be selected
with capability=NAME. New studies automatically expose the available installed
tools. Use the advanced Tool access setting, or --capabilities DIR, to restrict
them; --capabilities none selects Python only. Available tools and the tool
actually used are separate: each receipt binds the selected runtime identity.
Resuming a study keeps its saved registry. Native tools are
available for exploration; execution success alone does not accept a claim.
Request help and receive helper results¶
In a study launched with the research director enabled (--director), the worker
can request assistance explicitly:
help_request = lab.request_help(
"The diagnostic disagrees with the reference. Check the reader and numerical method independently.",
success_criteria="Return a tested reader correction and an independent analysis of the discrepancy.",
context="Describe observations, attempted fixes, relevant assumptions and unresolved questions.",
files=["reader.py", "measurements.json"],
key="diagnostic-help-1",
feedback_requirement="required",
)
lab.wait("Await the requested independent checks", help_requests=[help_request["id"]])
# End this turn. After the host resumes the worker:
response = lab.help_status(help_request["id"])
A new request makes the director eligible immediately instead of waiting for its
normal periodic interval. It still observes provider backoff and the study budget.
The director can return concrete advice through help_replies, or assign one or
several helper_tasks. Each assignment specifies its request ID, bounded task,
completion criteria, required output filenames and timeout. The worker can keep
doing independent work while helpers run; calling lab.wait is optional.
Use feedback_requirement="required" when the worker needs the returned feedback
before finalizing, or "advisory" for optional assistance. The declaration is
stored with the frozen request and helper context. Omitting it preserves the
existing request format and identity; changing it under the same request key is
rejected. A study may require an explicit declaration by setting
helper_policy.require_feedback_requirement in its manifest.
This field records the worker’s stated dependency. Waiting still requires
lab.wait(..., help_requests=[...]); the field does not introduce a new automatic
finalization gate or change scientific review requirements.
Each helper uses the study’s configured worker model/backend in a new context and
its own directory. CONTEXT.json contains the requesting worker’s explanation,
success criteria, original task, operator requirements, recent notes and evidence
identities. Attached files are snapshotted with hashes under inputs/; the
director also supplies recent public worker activity. This is selected context,
not the worker’s private reasoning or its entire native conversation. Attach the
specific source, data and explanations a helper needs.
Two helpers may run concurrently by default; additional assignments queue. The
director may set operating_limits.helper_workers from 1 to 16; null restores
the default of two. Helpers share the existing study deadline and finish before
the protected report period. Their usage is retained separately and included in
the supervisor’s token accounting. They are local agent processes; execution
machines for recorded production simulations retain their existing configuration.
Completion and return¶
The helper writes HELPER_RESULT.json with status (completed or blocked),
summary, artifacts, checks, and unresolved. A successful process exit alone
does not complete the assignment. The host checks the result structure, required
deliverables, unchanged context and inputs, and actual output files, then freezes
the returned artifacts with hashes. Failed, timed-out and cancelled jobs remain
visible. A blocked helper may return partial artifacts with an explicit obstacle.
Use lab.wait(..., helpers=[task_id]) to resume after a particular helper rather
than waiting for the whole group. Help arriving during a worker turn remains pending
until a subsequent turn receives it; unrelated running simulations do not suppress
that wakeup.
A help request becomes resolved when advice is available or all its helper jobs
are terminal. This means a response is ready, not that the original problem is
solved. The parent must inspect each helper’s status, evidence and limitations.
The host checks artifact integrity; it does not mechanically prove that the
helper fulfilled every scientific or semantic completion criterion.
Returned files never overwrite the parent’s working files. Import a selected artifact explicitly to a new destination:
lab.import_helper_artifact("helper_TASK_ID", "corrected_reader.py", "candidate_reader.py")
The import checks the recorded hash and refuses an existing destination. Imported work remains unreviewed and must pass the normal execution, method and claim checks before being used as scientific evidence. Helpers may write code and run bounded local checks; recorded production simulations remain with the parent worker. Helpers cannot approve claims or launch further helpers through this API.
Requests and assignments are durable and replay-safe. Reusing a request key with different content is rejected. A controller restart recognizes running helper processes rather than duplicating them. A dead helper controller produces a failure receipt; its identified native session, including surviving child processes, is stopped. Helpers must keep subprocesses in that session rather than daemonizing or detaching them. Flushed usage counters are recovered after a controller crash; unavailable counters remain explicitly unknown. Pausing or stopping the research supervisor cancels its helpers; raw work and completed results remain available. Supervisor shutdown waits for bounded cleanup and final usage collection. Private workspaces prevent accidental edit collisions between cooperative same-account agents; they are not OS security sandboxes.
Exploratory analysis and advisory progress¶
lab.run defaults to evidence collection. New automatic-tool studies require
methods review for instrument-backed evidence, rather than for merely having
unused tools installed. An explicit operator methods requirement applies to all
evidence, including postprocessing. Older studies keep their whole-study policy.
For diagnostics,
arithmetic validation, or reduction while method approval is pending, use:
analysis = lab.analyze("reader.py", inputs=["recorded-data.json"],
outputs=["analysis.json"], parent_experiment="exp_SOURCE_ID")
This snapshots source and inputs and retains an exploratory diagnostic receipt. It cannot authorize a claim or retrospectively promote exploratory results. Qualify the method and collect fresh evidence before requesting claim acceptance.
Method proposals accept validation_experiments and blocker_experiments as
lists of actual exp_... receipt IDs. The legacy blockers field has the same ID
semantics. Put descriptive scientific caveats in limitations=["..."].
Incorrect types identify the failing field; unknown IDs direct the caller to
lab.status().
An optional target links planning to an actual recorded numeric result:
lab.progress(experiment="exp_EVOLUTION_ID", output="result.json",
path="actual_end_ns", quantity="3D time reached", unit="ns",
target=20.5, baseline=0, estimate_rate=True,
series="same-model-grid-seeded",
limitations=["Startup throughput may change near stagnation"])
The host checks output identity and its numeric value. Quantity, unit, baseline, target and series remain researcher declarations. Use the actual starting time as the baseline for a restart, and separate grids/geometries/windows into distinct series. A linear throughput estimate uses this evolution’s measured wall time; it excludes analysis/review and may change with the physics. Do not substitute postprocessing runtime for evolution cost. Registered targets appear under Scientific coverage & cost in the run monitor’s research trace and in worker and reviewer context. Measured execution costs are also included automatically when no target has been registered. These are advisory planning signals, not acceptance criteria or a prescribed phase schedule.
Identical requests reuse the same receipt. Change key for an intentional
replicate. Changed source, inputs or arguments produce a new experiment identity.
Result files and raw outputs remain under experiments/ID/workspace/; agents can
inspect them but must not modify recorded artifacts. Review rechecks their hashes.
The initial implementation bounds each experiment to 4 GiB and the study to
8 GiB of recorded experiment storage with conservative reservations for active experiments. These bounds do not police arbitrary native working-folder writes.
A review request returns a persistent receipt, independent of the caller’s
working directory. End the model turn after submitting it: the supervisor opens
a fresh reviewer context and records the result. Codex reviewers can inspect
relevant source, data and documentation with read-only tools; they cannot modify
recorded evidence. Other adapters retain their configured review restrictions. Missing evidence
returns explicit gaps. A malformed reviewer response never becomes approval.
Each review targets one explicit claim ID and statement; the host rejects a mismatched target. Under the default CLI repair completion policy, approval of an original
falsification is distinct from completion, which still requires a supported repair.
The answer policy also allows an independently accepted root falsification to
complete the study. The workspace uses answer for new studies; saved policies
are retained on resume. Pending reviews survive pauses and deadlines. Scientific approval authority is
not exposed through lab.
For a repair, commit the prediction and exact commands first:
plan = lab.commit("A bounded refined claim ...", source="validation.py",
cases=[["--case", "a"], ["--case", "b"]],
acceptance="Predeclared quantitative criteria ...", inputs=[],
parent="root", rationale="Smallest justified change and why ...")
fresh = lab.run("validation.py", args=["--case", "a"],
outputs=["result.json"], commitment=plan["id"])
# Execute all committed cases, then review their receipts with claim=plan["id"].
New studies require evidence of active counterexample search for any supported
claim. The challenge identifies the strategy, submitted experiments and outcome;
the reviewer judges whether the tests actually challenge the claim. Boundary cases,
failure-prone regimes or exhaustive finite-domain testing may qualify. There is
no mandatory extra search phase or fixed number of tests.
A repair names its parent (root or an earlier commitment ID) and explains why
each changed assumption, scope or bound is necessary. This creates a durable
branching hypothesis tree. A repair’s review includes ancestor statements and the
accepted counterexamples’ actual source/results. Every ancestor must have an
accepted falsification before a supported descendant can close the study.
Minimality is judged scientifically, not by text length; scope restrictions must
explain failures rather than erase them. Experiment workspaces are immutable
snapshots, not separate Git worktrees for every hypothesis.
The service rejects changed committed source/arguments, retrospective relabelling of earlier runs and omission of committed cases. The reviewer still must judge whether the repair is meaningful: a fitted range tested on its own fitting data is not validated research.
Ordinary calculations do not need a separate instrument-claim hierarchy or an
approval before every calculation. Physical adequacy, controls and convergence
remain scientific obligations and are checked at review. A supported original
claim completes the study; under repair, a falsified original requires an
independently supported repair. Under answer, a reviewed negative answer can
complete it without that repair. Unresolved evidence and normal model exit do not complete it.
This is a cooperative same-account trust model. The native CLI agent is not adversarially isolated from host files; host-only Python methods are an interface boundary, not an OS security boundary. A hostile-worker deployment needs separate accounts or a separately authenticated service. Numerical execution retains its selected backend and recorded isolation limits. No existing campaign is migrated automatically.
Native-thread continuation prompts are short; full instructions remain in
research/RESEARCH_GUIDE.md. lab.status() includes remaining wall time and
receipt/workspace paths, with full metadata available through compact=False.
For long solvers prefer separately recorded cases, check a pilot’s output schema,
and reserve time for validation and synthesis.
Minimal is the new-study default by operator preference, not because the benchmark established superiority. The workflow is evaluated against plain, structured and frontier runs; see the measured results and benchmark plan.
Latest iteration: scientific-rule and default-mode tests.
Watching and controlling a study¶
A terminal launch prints live activity, backend/model, elapsed/remaining time and
experiment/review counts. Redirected output gets plain periodic status lines;
use --quiet to suppress them. Open simjecture web /path/to/study or run
simjecture status /path/to/study to inspect the same evidence and hypothesis tree.
Pause stops the agent at the supervisor boundary; already recorded numerical jobs may finish within their existing bounds. Resume retains the original wall deadline and mode. Cancel and deadline exhaustion terminate verified active numerical workers. Transient provider failures retry with backoff until the original deadline; authentication, permission and exhausted-quota failures pause with evidence intact; ordinary agent exit and inconclusive review do not establish completion. Provider usage is shown when the backend supplies completed-turn counters, with resumed cumulative counts deduplicated by native thread. Missing usage is not zero.