Launching Managed Research: A Nanoprogram Walkthrough
Attach a repo, run launch preflight, trigger a directed run, and validate submission/optimizer.py with Nanoprogram's official harness.
What launches today
We are launching one canonical builder path for Managed Research: a repo-backed, MCP-first workflow that produces a real artifact someone can judge locally.
The public example is Nanoprogram because it has a hard contract and an official evaluator. If the walkthrough works, you do not need to trust screenshots or marketing copy. You can pull the workspace, inspect submission/optimizer.py, and run the same shell script we run.
The same control-plane loop also applies to NanoHorizon-style work, but Nanoprogram is the launch-day anchor because it gives us a single-file deliverable and a public harness.
The contract
The demo is successful only if the Managed Research workspace contains:
submission/optimizer.py
That file needs to implement the Nanoprogram optimizer hooks:
def run_optimizer(contract) -> dict:
...
def best_candidate(contract, result=None) -> dict[str, str]:
...We validate it with Nanoprogram's official evaluator, not with an internal smoke-only shortcut.
The canonical MCP loop
This is the exact order we want people to follow:
smr_health_checksmr_create_runnable_projectorsmr_list_projectssmr_attach_source_repo- optionally
smr_set_project_notes smr_get_project_setupsmr_prepare_project_setupsmr_get_capacity_lane_previewsmr_get_launch_preflightsmr_trigger_runsmr_get_runorsmr_get_semantic_progresssmr_download_workspace_archiveorsmr_get_project_git
The important detail is that launch preflight and trigger must use the same launch payload.
The launch payload
For the public walkthrough, the default shape is:
{
"project_id": "proj_123",
"host_kind": "daytona",
"work_mode": "directed_effort",
"initial_runtime_messages": [
{
"body": "Inspect the Nanoprogram contract, improve the optimizer, and leave the workspace ready for local evaluation with evaluate_optimizer.sh. The primary deliverable is submission/optimizer.py.",
"mode": "queue"
}
]
}Two rules matter here:
- attach the repo before launch
- put kickoff text in
initial_runtime_messages, not the removedpromptfield
The trigger rule that matters
MCP trigger calls can succeed at the protocol level while still denying launch in the payload. Always branch on result.get("error").
result = smr_trigger_run(...)
if result.get("error"):
raise RuntimeError(f"{result['error']}: {result.get('message')}")
run_id = result["run_id"]If you skip this check, you can end up treating a routing or entitlement denial as a real run.
Semantic progress is the public read model
After trigger, the canonical inspection surface is no longer just raw run state. Use smr_get_semantic_progress when you want the run's primary parent, OEQs, DEOs, milestones, experiments, and run progress in one place.
Raw smr_get_run is still useful for low-level runtime state, but it is not the best answer to "what is this run trying to achieve?".
Retrieving the workspace
There are two valid post-run paths:
- use
smr_download_workspace_archivewhen you want the safest launch-day path for local inspection and evaluation - use
smr_get_project_gitonly when your deployment actually pushes changes back to the attached repo
The archive is a project-level snapshot, not a per-run bundle, and the download URL is short-lived. That is why the blog walkthrough teaches archive retrieval first.
Running the official evaluator
After extracting the workspace archive into your local Nanoprogram checkout, run:
bash evaluate_optimizer.sh --fast submission/optimizer.py banking77For the full confidence pass, run:
bash evaluate_optimizer.sh submission/optimizer.py banking77 hotpotqa openforecasterThose are the only evaluator commands the launch walkthrough teaches.
Common failures
- no repo was attached before trigger, so the run has nothing useful to work on
- launch preflight and trigger used different payloads, so preflight did not actually validate the launched run
- the client trusted a successful tool call without checking
result.get("error") - kickoff text was sent through the removed
promptfield instead ofinitial_runtime_messages - the user expected git output when the deployment only produced a workspace archive
Where the frontend fits
The hosted app follows the same launch order: setup, lane preview, launch preflight, then trigger. The UI is important, but the launch-day walkthrough is intentionally MCP-first so people can see the real control-plane contract without hidden app behavior.
What this post is not claiming
- Nemotron is not required for the launch-day demo
- the UI is not a separate product path from MCP
- local evaluation is not optional for submission-style work
Nemotron remains part of the broader product direction, but the default public walkthrough is the OpenAI-backed hedge path because it is the shortest route to a reproducible result today.