Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
eee41a7
capture: dialect-agnostic token capture for agent rollouts
adithya-s-k Aug 2, 2026
5976ac9
harbor: run Harbor tasks as an OpenEnv environment
adithya-s-k Aug 2, 2026
f1ae0e4
cli: openenv harbor info / rollout / serve / push
adithya-s-k Aug 2, 2026
341eebe
harbor_env: deployment packaging for a Space
adithya-s-k Aug 2, 2026
1b9b324
tests: port ownership, request normalisation, hosted serving
adithya-s-k Aug 2, 2026
d44f42c
docs: add the harbor_env stub and link it
adithya-s-k Aug 2, 2026
c684348
tests: cover the graph, rewards, seams, discovery and rendering
adithya-s-k Aug 2, 2026
af14859
harbor: fix the process-env lock breaking all concurrent rollouts
adithya-s-k Aug 2, 2026
17e080c
harbor: a FATAL capture finding must make the rollout unusable
adithya-s-k Aug 2, 2026
173acd8
harbor: cross-check pi against its own session log
adithya-s-k Aug 3, 2026
49dbdfa
harbor: recover the ATIF trajectory for hermes and openclaw
adithya-s-k Aug 3, 2026
559b30d
capture: name the upstream project in the dialect provenance
adithya-s-k Aug 3, 2026
33516cd
docs: rewrite the harbor_env guide, and make its example importable
adithya-s-k Aug 3, 2026
af2459e
docs: lead on multi-harness training, and document the CLI properly
adithya-s-k Aug 3, 2026
0d5c1de
harbor: stop calling asyncio.run on server-reachable paths
adithya-s-k Aug 3, 2026
24e7bcc
capture: fix the cloudflare forwarder, which never worked
adithya-s-k Aug 3, 2026
6ef13b5
capture: set the served-model marker before transforming, not after
adithya-s-k Aug 3, 2026
f924b40
capture: export every agent root, not only the first
adithya-s-k Aug 3, 2026
ecfb90a
harbor: restore the process env after a rollout, and fix the install …
adithya-s-k Aug 3, 2026
eb6d09e
harbor: give every turn its own prompt ids, and stop deriving turn bo…
adithya-s-k Aug 3, 2026
a18b592
capture: leave the caller's messages alone, and accept an engine URL …
adithya-s-k Aug 3, 2026
628059d
harbor: export a forked prefix once, and never leave a capture server…
adithya-s-k Aug 3, 2026
b592acc
harbor: sort imports the way usort does
adithya-s-k Aug 3, 2026
b2145d3
capture: accept SGLang as an engine, not just vLLM
adithya-s-k Aug 4, 2026
ad059f5
harbor: stop the tool-output box from eating the page scroll
adithya-s-k Aug 4, 2026
902699f
capture: authenticate to the upstream, and negotiate what it accepts
adithya-s-k Aug 5, 2026
84ac60c
capture: probe what an endpoint returns, instead of demanding token ids
adithya-s-k Aug 5, 2026
bde46be
capture: an eval rollout keeps its trace, and never a training contract
adithya-s-k Aug 5, 2026
59a09f5
harbor: carry the key and the capture level through a rollout
adithya-s-k Aug 5, 2026
125288b
harbor: fix the harnesses a compatibility matrix caught
adithya-s-k Aug 5, 2026
4d10afd
harbor ui: an API key field, and say plainly what you are about to get
adithya-s-k Aug 5, 2026
67597d8
tests: cover the negotiation, the eval path, and whether the logprobs…
adithya-s-k Aug 5, 2026
1a5014c
docs: two kinds of rollout, and what each endpoint gives you
adithya-s-k Aug 5, 2026
95ceb5c
Merge remote-tracking branch 'upstream/main' into harbor-integration
adithya-s-k Aug 6, 2026
e69e935
capture: link turns symmetrically, and catch retries of the first call
adithya-s-k Aug 6, 2026
846d805
capture: refuse to present an untrainable turn as a trainable one
adithya-s-k Aug 6, 2026
1a15811
harbor: keep a bad reward or a bad sequence from reaching the trainer
adithya-s-k Aug 6, 2026
14fc268
capture: gate the session routes, and survive odd upstream replies
adithya-s-k Aug 6, 2026
9838206
capture: dialect and transport fixes from review
adithya-s-k Aug 6, 2026
77bcd15
harbor: assume the weaker capture tier until the probe says otherwise
adithya-s-k Aug 6, 2026
7f0e26a
tests: cover the review findings
adithya-s-k Aug 6, 2026
3357767
harbor: one upstream rename should degrade one agent, not eight
adithya-s-k Aug 6, 2026
31d0939
capture: record the sampling parameters each turn was drawn with
adithya-s-k Aug 6, 2026
ad14f55
harbor: mask the aux node's own tokens, not its neighbours'
adithya-s-k Aug 6, 2026
3c71f5e
capture: count tokens in Google's request shape too
adithya-s-k Aug 6, 2026
1c8479c
harbor: don't strand the capture proxy when the tunnel fails
adithya-s-k Aug 6, 2026
4b857b6
capture: sample from the policy when the rollout is trainable
adithya-s-k Aug 6, 2026
5986b79
scripts: measure the top_p truncation bias in logprob_parity
adithya-s-k Aug 6, 2026
d2fc5f5
capture: the engine belongs to the rollout, not to the server
adithya-s-k Aug 20, 2026
5e82fe2
harbor: name the engine per rollout, alongside the harness and the sa…
adithya-s-k Aug 20, 2026
7a2056a
harbor: carry each turn's request on the wire
adithya-s-k Aug 20, 2026
9c209af
harbor: serve datasets without an engine, and cap agent output budgets
adithya-s-k Aug 20, 2026
1483c5d
Merge remote-tracking branch 'upstream/main' into harbor-integration
adithya-s-k Aug 20, 2026
9dcde4b
harbor: a served deployment does not need an engine to be useful
adithya-s-k Aug 20, 2026
c8535e5
capture: rewrite the outgoing model from the session's engine, not th…
adithya-s-k Aug 20, 2026
3924da8
capture: formatting (usort + ruff), as CI runs it
adithya-s-k Aug 20, 2026
c03e50e
harbor: let the caller bound a rollout
adithya-s-k Aug 20, 2026
33b57cc
harbor_env: loop-owning sessions, so a stock TRL worker can train on …
adithya-s-k Aug 20, 2026
e5d15fb
harbor_env: four review findings on the session factory
adithya-s-k Aug 20, 2026
6c0ad30
core: close() on an MCP client must actually close it
adithya-s-k Aug 24, 2026
33e2df1
harbor: n_trainable_tokens must agree with the turns beside it
adithya-s-k Aug 24, 2026
c2dac3b
harbor ui: run against the endpoint the user validated
adithya-s-k Aug 24, 2026
770ea8d
harbor: compute the token total after the turns exist, and let Run re…
adithya-s-k Aug 24, 2026
acd3c78
harbor_env: measure_prompt_skew has to decode tool-call arguments, li…
adithya-s-k Aug 24, 2026
b8b90e9
harbor: remove hermes support
adithya-s-k Aug 24, 2026
7e4688e
harbor harness: one client per rollout, not one per factory
adithya-s-k Aug 24, 2026
50e21cb
harbor: release both halves on teardown, and do not leak the proc-env…
adithya-s-k Aug 24, 2026
2854581
harbor tests: drop the asyncio import the hermes deletion orphaned
adithya-s-k Aug 24, 2026
ef11f95
harbor: let a caller bound how many steps an agent takes
adithya-s-k Aug 24, 2026
0ef184a
harbor harness: say when a rollout's packed row is big enough to OOM …
adithya-s-k Aug 24, 2026
5be8cb1
harbor harness: refuse an empty indices list instead of silently sele…
adithya-s-k Aug 24, 2026
9bf5e7f
harbor: one E2B template per distinct environment, not per task
adithya-s-k Aug 25, 2026
ca4d2e5
harbor: stop credential-by-env harnesses serialising, with context-lo…
adithya-s-k Aug 25, 2026
0308ac0
Merge upstream/main into harbor-integration
adithya-s-k Aug 27, 2026
77e6920
harbor: run the repo's own usort+ruff pipeline over three stragglers
adithya-s-k Sep 2, 2026
962ffcb
harbor: attribute a re-rendered system prompt to its parent, and let …
adithya-s-k Sep 2, 2026
c8bc449
harbor: 10 validated harnesses, and say why the other five are not
adithya-s-k Sep 2, 2026
664a93c
Merge upstream/main into harbor-integration (brings the RFC 008 rever…
adithya-s-k Sep 2, 2026
a116185
Merge upstream/main into harbor-integration (Task API docs, #1094)
adithya-s-k Sep 8, 2026
b6eaa72
harness: own the loop-owning contract, and serve TraceEntry over HTTP
adithya-s-k Sep 8, 2026
b341d3e
capture: a saturated logprob distribution is "unknown", not "raw"
adithya-s-k Sep 9, 2026
b63f56a
capture: run the proxy in-process from anywhere, and bound a rollout'…
adithya-s-k Sep 12, 2026
de7d535
capture: stop telling consumers to re-render, and say who can fill in…
adithya-s-k Sep 12, 2026
5f4ef18
capture: the budget stop must answer in the caller's dialect, and say…
adithya-s-k Sep 12, 2026
afade4f
capture: apply usort + ruff format
adithya-s-k Sep 13, 2026
4db07b9
Merge remote-tracking branch 'upstream/main' into local-integration
adithya-s-k Sep 13, 2026
a7634ce
harbor: make run_rollout an async MCP tool — the server was capped at…
adithya-s-k Sep 13, 2026
781bfc9
harbor: coerce verifier rewards PER KEY, so one unusable key cannot d…
adithya-s-k Sep 13, 2026
e098cc4
Merge remote-tracking branch 'upstream/main' into codex/pr1036-merge-…
adithya-s-k Sep 16, 2026
2ce2fa7
Harden Harbor provider capture and isolate live rollout UI
adithya-s-k Sep 16, 2026
ede5057
List Harbor in the environment documentation catalog
adithya-s-k Sep 16, 2026
606ccc1
Skip Harbor installer checks when optional runtime is unavailable
adithya-s-k Sep 16, 2026
5f7d917
Merge remote-tracking branch 'upstream/main' into codex/pr1036-merge-…
adithya-s-k Sep 16, 2026
7377273
Match MCP cleanup regression to upstream websocket detach order
adithya-s-k Sep 16, 2026
39b36a5
Format MCP cleanup regression assertion
adithya-s-k Sep 16, 2026
eceb50f
Merge remote-tracking branch 'upstream/main' into codex/pr1036-merge-…
adithya-s-k Sep 16, 2026
b13aeb9
Preserve default Harbor client compatibility with deployed services
adithya-s-k Sep 16, 2026
27e803e
Retain verifier diagnostics and clarify agent timeout scope
adithya-s-k Sep 16, 2026
6172e98
Merge remote-tracking branch 'upstream/main' into codex/pr1036-merge-…
adithya-s-k Sep 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .claude/docs/REPO_WALKTHROUGH.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ src/
│ │ ├── client_types.py # Client-side type definitions
│ │ ├── utils.py # Shared utilities
│ │ │
│ │ ├── harness/ # Agent protocols and captured trace collection
│ │ │ └── capture/ # Dialect adapters, session routing, exact tokens, SSE replay
│ │ │
│ │ ├── env_server/ # Server-side components
│ │ │ ├── interfaces.py # Environment abstract base class
│ │ │ ├── http_server.py # HTTPEnvServer (FastAPI + WebSocket)
Expand All @@ -58,6 +61,8 @@ src/
│ │ ├── local_python_executor.py # Python code execution
│ │ └── git_server_client.py # Git operations
│ │
│ ├── harbor/ # Harbor tasks, harness seams, provider qualification, live UI
│ │
│ ├── discovery/ # RFC 011 metadata-only repository catalogs
│ │ ├── models.py # Declaration profile and identity invariants
│ │ ├── repository.py # Bounded reads from one committed Git tree
Expand Down Expand Up @@ -111,6 +116,7 @@ envs/
│ ├── echo_environment.py # Environment implementation
│ └── Dockerfile # Container definition
├── harbor_env/ # Thin Harbor package and trainer session factory
├── thinkingbox_env/ # Stateful MCP business-workflow benchmark adapter
├── coding_env/ # Python code execution environment
├── chat_env/ # Conversational environment
Expand Down Expand Up @@ -273,3 +279,9 @@ ThinkingBox examples: `example_usage.py` is a public-client smoke test, while `e
| `envs/echo_env/` | Reference implementation - start here |
| `rfcs/001-abstractions.md` | Core architectural decisions |
| `.claude/docs/INVARIANTS.md` | Rules that must never be broken |

## Harbor integration

`src/openenv/core/harness/capture/` records inference calls independently of a trainer or tokenizer. `src/openenv/harbor/` runs Harbor tasks, reconciles their trajectories, and exposes the shared training contract through clients and the Gradio playground. `envs/harbor_env/` is the installable environment wrapper. `examples/harbor/nemo_shell_profile/` provides the explicitly qualified NeMo shell workflow.

See `docs/source/guides/harbor-provider-qualification.md` for provider and adapter evidence, `rfcs/012-harbor-capture-providers.md` for explicit evaluation/training and session ownership, and `tests/envs/test_harbor*.py` / `test_capture*.py` for deterministic capture regressions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,9 @@ docs/source/_env_assets/
# Sphinx-gallery generated output
docs/source/auto_getting_started/
docs/source/sg_execution_times.rst

# Gradio UI build artifacts
.gradio/

# Local preservation archives and isolated preparation worktrees
/temp/
4 changes: 4 additions & 0 deletions docs/source/_toctree.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
title: Catalog Discovery
- local: guides/rl-integration
title: RL Training
- local: guides/harbor-provider-qualification
title: Harbor Provider Qualification
- local: guides/rewards
title: Rewards
- local: guides/concepts
Expand Down Expand Up @@ -77,6 +79,8 @@
title: Terminus
- local: environments/coding_tools
title: Coding Tools
- local: environments/harbor
title: Harbor
- local: environments/chat
title: Chat
- local: environments/atari
Expand Down
7 changes: 7 additions & 0 deletions docs/source/environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,5 +320,12 @@ The OpenEnv community has built a catalog of ready-to-run environments that cove
<a href="https://huggingface.co/spaces/reasoning-core/reasoning-core-openenv" class="!no-underline border dark:border-gray-700 px-3 py-1 rounded text-sm hover:shadow">🤗 HF</a>
</div>
</div>
<div class="border dark:border-gray-700 p-5 rounded-lg shadow">
<div class="font-bold mb-2">Harbor</div>
<p class="text-sm">Serve Harbor tasks across agent harnesses and sandboxes, with captured traces for evaluation and exact-token training.</p>
<div class="flex gap-2 mt-3">
<a href="environments/harbor" class="!no-underline border dark:border-gray-700 px-3 py-1 rounded text-sm hover:shadow">📄 Docs</a>
</div>
</div>
</div>
</div>
557 changes: 557 additions & 0 deletions docs/source/environments/harbor.md

Large diffs are not rendered by default.

99 changes: 99 additions & 0 deletions docs/source/guides/harbor-provider-qualification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Harbor provider qualification

An installed adapter is not evidence that a harness works with a particular model provider. Qualify the actual harness version, model route, sandbox, capture implementation, and task set together.

## Evaluation and training capture

Use explicit `purpose="eval"` for evaluation. Hosted OpenAI, native Anthropic, and Hugging Face routes can produce graded evaluation traces without engine token IDs. An eval trace must not export a training contract, even when its endpoint happens to provide token IDs.

Use `purpose="train"` only with a verified token-capable endpoint. Training export preserves engine prompt IDs, sampled completion IDs, processed log probabilities, and loss masks. `openenv.harbor.contract.to_trace_entries` rejects evaluation traces and fatal capture findings. Do not reconstruct token IDs by tokenizing rendered conversation text or fill missing log probabilities with zeros.

A prompt rewrite may create several training rows from one rollout. That does not by itself make the sampled tokens invalid. Report rows per rollout, repeated context, retained supervision, and downstream weighting separately. Capture correctness does not establish an efficient training configuration.

Native Anthropic requests retain their original signed blocks and supported native metadata. Translation to another harness protocol rejects output semantics that cannot be preserved. The native streaming bridge buffers the upstream response and replays SDK-compatible events; it does not provide upstream first-token streaming latency.

## Evidence and support tiers

A qualification report has one cell per harness/provider pair. The provider names are `openai`, `anthropic`, `hf`, and `vllm`. Keep capture artifacts and attempt configuration alongside the report, including exact model routes, available revision pins, harness versions, task identities, sampling, and source hashes.

The report distinguishes:

- `eval_pass`: a completed, graded rollout with captured calls, no fatal capture findings, and no training export. A task score of zero is still a valid evaluation; an infrastructure failure or missing grade is not a benchmark zero.
- `capture_and_reader_pass`: exact capture passed validation and the real training reader retained the expected supervision.
- `optimizer_pass`: the current capture artifacts were consumed by a real optimizer diagnostic. Record model revision, input fingerprints, consumed rows, finite losses, and finite nonzero gradients. Explicitly state whether this was diagnostic replay and whether weight synchronization was tested.
- `failed`, `blocked`, `in_progress`, and `not_run`: retain these outcomes rather than replacing them with a passing result from a different configuration.

`harness_maturity_rows` derives support tiers from validated report cells. Stable requires all three eval profiles and a current-capture optimizer pass on vLLM. Partial or pending support is experimental. Four failed or blocked profiles are unstable for the tested matrix. None of these labels claim universal compatibility or production-scale reliability beyond the recorded coverage.

Set `OPENENV_HARBOR_QUALIFICATION_REPORT` to the report JSON path to display evidence in Gradio. The UI defaults to stable harnesses, provides an experimental opt-in, and excludes unstable harnesses. With no report, adapters are unqualified and require the experimental opt-in. Changing the filter invalidates the prior selection. Recorded results do not certify a newly entered endpoint or automatically pin its harness installation. For profile-specific evidence, the UI passes the recorded profile to the rollout: ACP supports `opencode-1.18.30`; NeMo supports `shell-1.9.0` when the example workflow package is available in the checkout. The selected profile is displayed in the agent label. Profile selection creates a local seam copy and does not mutate the global adapter registry. Programmatic callers can pass `harness_profile=` to `run_rollout` or `build_trial_config`; unknown profiles fail explicitly.

## Recorded qualification: 15 September 2026

The completed qualification attempted all 29 adapters on four provider profiles, with two fixed tasks per pair (116 pairs). Results are compatibility smoke tests, not benchmark pass@1 scores. “Stable” means passing this recorded coverage; it does not certify arbitrary models, harness upgrades, or production-scale reliability.

| Provider profile | Model | Passing adapters |
|---|---|---:|
| OpenAI evaluation | `gpt-5.4-mini-2026-03-17` | 21/29 |
| Native Anthropic evaluation | `claude-sonnet-4-5-20250929` | 20/29 |
| Hugging Face evaluation | `Qwen/Qwen3.5-9B:together` | 19/29 |
| vLLM training capture and optimizer diagnostic | `Qwen/Qwen3.5-4B` | 21/29 |

The HF route is pinned, but its hosted weights are not an immutable revision. The vLLM model revision is `851bf6e806efd8d0a36b00ddf55e13ccb7b8cd0a`. That profile used vLLM 0.25.1, TP=1, DP=1, BF16, a 131072-token context, processed log probabilities, engine token IDs, Qwen3 XML tool parsing, Qwen3 reasoning parsing with thinking disabled, and no image/video inputs.

There are **14 stable, 9 experimental, and 6 unstable adapters**. A failed pair means the two-task qualification did not pass; it does not necessarily mean both tasks failed or that the adapter can never support that provider.

| Adapter | Tier | OpenAI | Anthropic | HF | vLLM |
|---|---|---|---|---|---|
| acp | experimental | failed | eval_pass | eval_pass | optimizer_pass |
| antigravity-cli | experimental | failed | failed | eval_pass | optimizer_pass |
| antigravity-sdk | unstable | failed | failed | failed | failed |
| claude-code | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| cline-cli | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| codex | experimental | eval_pass | eval_pass | failed | optimizer_pass |
| computer-1 | unstable | failed | failed | failed | failed |
| copilot-cli | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| cursor-cli | unstable | failed | failed | failed | failed |
| devin | unstable | failed | failed | failed | failed |
| eve | unstable | failed | failed | failed | failed |
| gemini-cli | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| goose | experimental | eval_pass | eval_pass | failed | optimizer_pass |
| grok-build | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| kimi-cli | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| mimo | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| mini-swe-agent | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| nemo-agent | experimental | eval_pass | eval_pass | failed | optimizer_pass |
| openclaw | experimental | eval_pass | eval_pass | failed | failed |
| opencode | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| openhands | experimental | eval_pass | eval_pass | eval_pass | failed |
| openhands-sdk | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| pi | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| qwen-coder | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| rovodev-cli | unstable | failed | failed | failed | failed |
| swe-agent | experimental | eval_pass | failed | eval_pass | optimizer_pass |
| terminus-2 | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |
| trae-agent | experimental | eval_pass | failed | eval_pass | optimizer_pass |
| vibe | stable | eval_pass | eval_pass | eval_pass | optimizer_pass |

### Scope and known limitations

The optimizer diagnostics consumed 99 current capture rows across 21 adapters using the real `AsyncGRPOTrainer`, with finite losses and finite nonzero gradients. They used a diagnostic advantage of +1 and did not synchronize weights. This establishes capture consumption by the trainer, not reward-normalized learning, long-run stability, or correct weighting when a rollout produces multiple rows. Claude Code and other prompt-rewriting harnesses still need row-budget and weighting checks for a particular training configuration.

ACP qualification applies only to the `opencode-1.18.30` profile, and NeMo qualification only to `shell-1.9.0`. ACP has partial native usage evidence; NeMo lacks independent native token counts. Engine capture remains authoritative, and these results do not qualify arbitrary ACP agents or NeMo workflows.

Codex, Goose, and NeMo retain HF failures. Antigravity CLI retains OpenAI and Anthropic failures. SWE-agent timed out on Anthropic; Trae-agent captured no Anthropic calls. OpenClaw and OpenHands retain training trajectory reconciliation failures. Antigravity SDK also failed strict reconciliation despite executing tools. Missing vendor credentials or application prerequisites prevented qualification of Cursor, Devin, Rovo Dev, and Eve. Computer-1 needs a separate desktop/vision qualification. Keep these failures visible; do not relax token checks to promote an adapter.

The final combined regression run passed 567 tests with two skips; native Anthropic SDK streaming replay was also checked separately. Live qualification and optimizer replay used separate services and source snapshots. Updating this documentation or a qualification report does not restart training, change an existing training snapshot, or deploy the adapter changes. A running process continues to use its configured source and services.

## Regression and live validation

Run the deterministic Harbor tests from the repository root:

```bash
PYTHONPATH=src:envs python -m pytest tests/envs/test_harbor*.py -q
```

These tests cover provider conversion, capture graphs, export masks, reconciliation, routing, lifecycle behavior, and evidence gates. They are not a replacement for live harness execution.

For live qualification, use isolated services and immutable source snapshots. Fix the task set and versions before launch; bound sandbox concurrency; save each result before proceeding. Resume by scheduling only missing cases into a new attempt directory, preserving prior failures and provenance. Reusing a capture in optimizer evidence requires its exact source hash and row fingerprint to match; a newer retry must not inherit an older optimizer pass.

Some adapters require a separately supplied application, workflow, vision input, or vendor account. Report the missing prerequisite or restriction. Do not substitute a different agent, silently remove observations, relax token checks, or claim success merely because an endpoint is reachable.
Loading
Loading