> ## Documentation Index
> Fetch the complete documentation index at: https://docs.phyi.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Contract & Artifacts

> The agent entrypoint, the task context, inference, limits, and the artifact layout per track.

A Phylax agent is the code a miner builds and submits. It is a self-contained
program that analyses one artifact class and produces a verdict with evidence.
Miners submit **code only**; validators execute it inside their own hardened
sandbox image, so untrusted code runs in a trusted runtime, the environment is
reproducible by every validator, and the same task yields comparable runs
everywhere.

## Entrypoint

```python theme={"system"}
def agent_main(context: dict) -> dict:
    # 1. read the artifact from context["artifact_dir"]
    # 2. detonate it (or, for repositories, audit it statically)
    # 3. thread the probe from context["probe"] through the run
    # 4. return the attestation body: verdict, evidence, findings
    return attestation
```

* The function name defaults to `agent_main`. Override it with the `entrypoint`
  field when you submit the agent.
* It runs inside the validator's hardened sandbox image, network-jailed. The only
  endpoint it can reach is the inference proxy at `context["inference"]["api"]`.
* It must return the attestation body as a `dict`. A crash, a timeout, or a
  malformed return is a failed run and scores 0 for that task.

## The task context

Every run receives a single `context` dict from the validator's orchestrator:

```json theme={"system"}
{
  "artifact_dir": "/task/artifact",
  "track": "skills | mcp_servers | packages | repositories",
  "nonce": "…",
  "probe": { "file_path": "…", "file_content": "…", "dns_host": "…",
             "process_echo": "…", "canary": "…" },
  "inference": { "api": "<proxy url>", "api_key": "…", "provider": "…", "model": "…" },
  "sandbox": { "image": "…", "digest": "sha256:…" }
}
```

| Field          | What it is                                                                                                                                |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `artifact_dir` | Directory holding the unpacked artifact to analyse, mounted read-only.                                                                    |
| `track`        | The track this task belongs to. Always your registered track.                                                                             |
| `nonce`        | The task's fresh value, derived from the round seed.                                                                                      |
| `probe`        | The effects your agent must perform during detonation so the validator observes them. See [Proof of Execution](/core/proof-of-execution). |
| `inference`    | The metered proxy URL and your key. Call the LLM only through this.                                                                       |
| `sandbox`      | The image and digest the run is happening in (the validator's hardened image).                                                            |

## Calling inference

Direct egress is blocked, so the only way to reach a model is the metered proxy.
Point your client at `context["inference"]["api"]` and authenticate with
`context["inference"]["api_key"]`:

```python theme={"system"}
inf = context["inference"]
resp = http_post(
    f"{inf['api']}/v1/chat/completions",
    headers={"Authorization": f"Bearer {inf['api_key']}"},
    json={"model": inf.get("model") or "…", "messages": [...]},
)
```

The validator spends your key through this proxy when it runs your agent, which
is why the key is part of the submission: you fund the inference cost of your own
agent. Any attempt to reach a non-proxy host fails inside the jail.

<Note>
  A language model may never decide a verdict, author a finding category, or
  generate a policy. Model-assisted enrichment is confined to explaining a finding
  the deterministic analysis already produced. Every verdict must remain grounded
  in observed behavior.
</Note>

## Limits

Your agent runs under hard limits enforced by the sandbox:

| Limit              | Notes                                                                      |
| ------------------ | -------------------------------------------------------------------------- |
| Wall-clock time    | The per-task timeout `D`, set per track (8 s skills to 120 s repositories) |
| Memory, CPUs, PIDs | Hard caps per run                                                          |
| Network            | No egress except the metered inference proxy                               |

Exceeding the timeout or being killed by a limit records the task as a failure,
which scores 0 and drags your round average down. Budget inference calls and
detonation time accordingly.

## Per-track responsibilities

* **skills**: detonate, thread the probe, and produce dual-plane evidence
  (canonical capabilities on the action plane, injected instructions on the
  context plane). Decide ALLOW / WARN / BLOCK.
* **mcp\_servers**: the same, plus component-centric analysis: exposed tools,
  declared-vs-observed schema, tool poisoning, manifest integrity, and
  cross-component influence.
* **packages**: capture `install_time` and `import_time` behaviour, the
  `action_plane`, and a `supply_chain` block (SBOM, CVEs, typosquat, dependency
  confusion).
* **repositories**: no probe. Statically audit the source on two layers and return
  an `audit` block with both: a `vulnerabilities` list of exploitable code defects
  (CWE, file, line, severity, remediation), and a supply-chain scan of the repo's
  own dependencies — a `supply_chain` block (dependencies, typosquat, dependency
  confusion, install scripts) plus a `secrets` list of leaked credentials.

## Artifact layout the agent sees

| Track          | Typical contents of `artifact_dir`             |
| -------------- | ---------------------------------------------- |
| `skills`       | `SKILL.md` + helper scripts (`scripts/*.py`)   |
| `mcp_servers`  | `manifest.json` + `server.py`                  |
| `packages`     | `setup.py` / `pyproject.toml` + `src/<pkg>/…`  |
| `repositories` | a source tree (`src/…`, `requirements.txt`, …) |

Do not assume a fixed entry filename. Discover the surface from the manifest or
by scanning the tree. A malicious artifact will not label its payload for you.

## Output

Return the attestation body: `verdict`, `evidence`, and `findings` (see the
[SSSA Schema](/core/sssa-schema)). The validator that executed the run assembles
the full SSSA, adds the proof-of-execution material it observed, and signs it.
Report **canonical capability names** (see [Scoring](/core/scoring)); fabricated
or off-track names are dropped and lower your evidence quality.

The reference implementation is `phylax/harness/reference_agent.py`, a unified
agent that already dispatches all four tracks by `context["track"]`. Copy it and
iterate. See [Iterating on Your Agent](/guides/evolve) for the versioning flow.
