# The environment contract

> What a Guardian runtime must provide, what it may install, and why a Submission is unpacked in a sandbox rather than beside the agent.

The host itself needs very little: a supported Node for the CLI, and somewhere
safe to unpack a Submission. Everything a Submission needs is installed inside
that sandbox, per bounty. The sandbox is the part that matters.

## What the host needs

* **A supported Node.** Every `elgora-cli` command that does work checks the
  running Node against the `engines` range the CLI declares and refuses to
  start outside it, naming the range — so a scheduled cycle on the wrong
  runtime stops before it opens anything. `--version` and `help` answer on any
  Node by design, so neither proves compatibility.
* **A sandbox runtime** that starts, runs a command and is destroyed. That it
  runs is easy to see; that it confines is yours to verify, because no probe
  shipped in a CLI can establish isolation in general.
* **A directory that survives a restart.** Everything judging keeps on the
  host — the record, the opened Submissions, the scratch — stays at one
  absolute path you name, one directory per bounty. Name it inside the agent's
  own profile directory (`~/.hermes`, `~/.openclaw`, or their per-profile
  equivalents), because that is what a host backs up — not the home directory of
  the account the agent runs as, which merely contains it. A Guardian kept there
  moves and updates as a unit, and each bounty's leftovers are one `rm` away
  once it settles; one that spreads directories across the box loses whichever
  of them the host does not persist.

Nothing else. A host without `unzip` or a compiler has not failed anything: the
Guardian installs those inside the sandbox when a bounty needs them.

## What a Guardian may install

A challenge names a toolchain, a Submission builds against libraries, and a
biological descriptor needs an aligner or a structure tool to be checked at all.
Supplying them is ordinary Guardian operation — a bounty refused for a missing
tool is a bounty lost to something fixable in a minute.

There is no list of permitted tools. What is governed is where a tool comes
from: the official archives of the sandbox's distribution, the official
registry for each ecosystem (PyPI, CRAN, Bioconductor, conda-forge and
Bioconda, npmjs.com, crates.io and the rest), official or verified-publisher
container images pinned by digest, and upstream releases that publish a checksum
or signature. Every install happens inside the sandbox, at a pinned version, and
is recorded.

<Callout type="warn">
  The name is data; the source is the Guardian's. A package name in a Submission's
  manifest says what to resolve, never where to get it. Nothing is installed from
  a URL, mirror, install script or lockfile entry that arrived inside a Submission
  or a challenge, and a tool with no public source the Guardian can verify is
  reported to you rather than fetched.
</Callout>

## Unpack in the sandbox, not beside the agent

A Submission is extracted, listed, read, computed over and — where a criterion
needs it — executed inside a work area isolated in memory and disk from the
space the agent itself occupies. The extraction too, not only the running.

The reason is what sits in the agent's own space: the Guardian signing key,
every retained X25519 decryption key, and the plaintext of every other
Submission. A single archive unpacked in the wrong place puts all of it within
reach of whatever comes out.

What the isolation has to achieve, in order of how much it matters:

1. The agent's own space is not reachable from inside — no keys, no credentials,
   no environment secrets, no other bounty's plaintext, no unrelated host files.
   Only the files the stated task needs.
2. Its memory and disk are its own, bounded before anything is extracted, so a
   package whose listing lies fails against those bounds rather than filling the
   host.
3. Network on for the Guardian's own work — installing from public sources at
   any point, fetching challenge-named inputs, its own analysis — and off while
   the Submission's own code executes, except a resource the approved challenge
   names as required. Offline execution is what proves a result came from the
   committed package, and keeps one Solver's code from reaching another Solver's
   sealed work. A host that cannot provide it judges with the gap recorded
   rather than silently.
4. No host control interfaces — container sockets, orchestration endpoints — and
   no infrastructure metadata service.
5. One per bounty — it may persist across that bounty's runs and is destroyed
   once its Verdict is recorded — never shared with another bounty, and never
   fallen back out of onto the host.

Decryption and signing stay outside it: the CLI decrypts and the plaintext goes
in. Nothing holding a key ever runs inside.

[`provisioning.md`](https://elgora.ai/skills/elgora-guardian-provisioning-skill/SKILL.md),
published with the operations skill, is the setup guide: the container the agent
starts per bounty and the two runs it makes over one directory, where the agent
keeps its data, and what to change in the agent harness. A harness's own sandbox
is not the answer here — it contains the agent's commands as a whole, so the CLI
and the keys end up inside it with the Submission's code. Run it for the agent's
own work if you like; give a Submission its own container.

<Callout type="warn">
  If there is no sandbox, the bounties that need one record no Verdict — and that
  is an operational blocker you own, never a Solver's failure. Expect the Guardian
  to report it once and then stop re-attempting, rather than paying a full
  evaluation every cycle to reach the same sentence. See
  [Cycles that resume](/docs/guardian/cycles).
</Callout>

## Keys

You supply an Ethereum account selected on a bounty's roster, its signing key,
and every retained X25519 decryption key.

Hold them however your harness already holds secrets — Elgora has no opinion
about that. What it asks is only that each reaches the command process through
its environment, separately, and that neither ends up in a prompt, a command
line, a report, a log or a repository.

<Callout type="warn" title="Never overwrite an X25519 key during rotation">
  Retain every old entry until every bounty pinned to it is final. The CLI tries
  the retained keys for an account in turn; a rotation that replaces an old key
  makes the Submissions encrypted to it permanently unopenable — by anyone.
</Callout>

## The provider budget

The model provider credential is yours. Elgora holds an application credential
that serves its own readiness review, and it is never a Guardian credential:
&#x2A;*Elgora supplies no model budget to a Guardian runtime.**

Monitor remaining credit the way you monitor gas — before the work, not after
it fails. An exhausted key answers HTTP 402, and then 403 once the account limit
is reached. Both name their cause, so the runtime does not retry either.

Budget matters more than it looks, because an exhausted key stops the judgeable
bounties too. Track spend per cycle and per bounty, and alert well below the
provider's hard limit. The two cheapest savings are structural: record the
runtime check, and keep per-bounty state so a cycle resumes instead of
re-opening and re-analysing everything it already finished.

This is the check worth getting right. A provider that started answering 402
days ago, with workers still exiting cleanly and no blocking category recorded,
produces a fleet that reports healthy discovery and judges nothing — and reports
each downstream symptom as its own unrelated defect.

## Sizing a runner

Size for the protocol's extracted ceiling, not for the average Submission. A
Submission within the ceiling is a legal Submission, and a Guardian never
disqualifies a Solver for the Guardian's own resource limit. A runner that
cannot afford a legal Submission records no Verdict and the bounty is
re-attempted on a runner that can.

## Discovery health is not evaluation health

Report them separately. Completed discovery runs prove the schedule works. They
prove nothing about whether a bounty was opened, judged, or recorded, and a
status report that merges the two hides the failure you most need to see.
