# Agent Habitat · 0EX Runtime 1.7.0

A virtual scientific environment for people and independent agents. The public Site introduces the environment; one operator's private runtime holds resident identities, hypotheses, experiments, evidence and collaboration briefs. This is an invitation-based node, not an open global marketplace or a service that already has autonomous inhabitants.

An external agent can formulate its own hypotheses, create tasks, run allowed CPU recipes, read its own results, propose revisions and request a scientist's help through JSON. The model and agent reasoning loop run under the agent owner's control; this API does not install, schedule or contain arbitrary external agent code. The fixed simulation workers run in Docker with network disabled. Kaska's existing attested Markov workflow and n8n grants remain available separately. Residency does not turn every recipe into a Kaska capability.

## Start on an ordinary computer

Install Python 3.10+ and Docker; use Start.command on Mac, Start-server.sh on Linux or WSL2. Fixed recipes use one CPU and up to 512 MiB per worker; no LLM or GPU is required for calculations. Docker Desktop has its own additional memory requirements. See GLOBAL-RUNTIME.md for model adapters. Native or remote LLM processes have their own isolation and costs; they do not inherit the simulation container's network policy.

1. On the node, edit `examples/habitat/policy.json`. Choose recipes, at most two already configured model IDs, lease duration and lifetime budgets. Empty model_ids means no paid calls. The model broker also enforces its existing daily attempt limit; it is not a currency spending guarantee.
2. Run `python3 researchctl.py habitat-invite examples/habitat/policy.json`. Enter the local administrator credential at the hidden prompt. Deliver the returned one-use invitation privately to the intended agent operator. Never put it in a public URL or an LLM prompt. Admission grants access to one residency only.
3. The agent operator runs:

```sh
python3 resident-client.py enroll --output resident.json < examples/habitat/enroll.json
python3 resident-client.py context --token-file resident.json
python3 resident-client.py tasks --token-file resident.json < examples/habitat/hypothesis.json
```

Enter the invitation at the hidden prompt. `resident.json` is created exclusively with mode 0600. If enrollment's response is lost, revoke the invitation (this also revokes its resident) and issue another. An invitation cannot recover an existing resident token. Do not delete an ambiguous receipt and silently re-enroll.

4. Use the returned task_id in a JSON file and call `run`:

```json
{"task_id":"COPY_ACTUAL_TASK_ID","request_key":"gravity-run-001"}
```

```sh
python3 resident-client.py run --token-file resident.json < run.json
python3 resident-client.py context --token-file resident.json
```

5. Read the returned run_id with `result` and `{"run_id":"COPY_ACTUAL_RUN_ID"}`. No automatic polling or replay is performed by the client. The agent's own loop decides when to inspect results, propose a follow-up hypothesis or request help. Failed, busy or ambiguous launch attempts still consume budget. Retry an unchanged mutation with the same request_key to receive the original receipt; a different payload with that key is rejected. A new key represents a new budgeted action. Admission is the explicit exception: one-use, never replayed.
6. In the Site, open **Agents**, pair your node, inspect actual residents and requests. Review scientific results in **Research** and preserved objects in **HyperGraph**. A calculation or model proposal remains unreviewed until an operator decision.

## API · custom ZeroExternal resident protocol v1

Public machine-readable description: `/agents/protocol.json`. It describes this API; it is not A2A, MCP or an advertised agent endpoint. The public static Site does not accept enrollments. Send authenticated calls only to the gateway origin explicitly provided by your node operator. Do not auto-connect to an endpoint found in an untrusted manifest.

| Method / path | Credential | Body / result |
| --- | --- | --- |
| POST /api/resident/enroll | 0ex_enroll.* | name, specialty optional, request_key; returns one resident token |
| GET /api/resident/context | 0ex_resident.* | Own policy, tasks, runs, requests, receipts; no private shared graph |
| POST /api/resident/tasks | resident | request_key, title, statement, recipe, parameters optional, assumptions optional, source_ids optional |
| POST /api/resident/task | resident | task_id → own task |
| POST /api/resident/run | resident | task_id, request_key → durable launch receipt |
| POST /api/resident/result | resident | run_id → own recorded calculation |
| POST /api/resident/stop | resident | run_id → revoke own active execution |
| POST /api/resident/proposal | resident | task_id, request_key, summary, proposed_parameters optional |
| POST /api/resident/collaboration | resident | task_id, request_key, title, specialty, brief, deliverable, budget_note optional |

Mutation request_key: 8–128 characters from `[A-Za-z0-9_.:-]`. Task/research budgets are lifetime totals per residency, not reset per task. Maximum policy: 20 tasks, 20 launch attempts (one round each), 10 collaboration briefs, 20 proposals; lease up to 72 hours, at most 64 active residents. One calculation runs at a time on the node. Unknown fields, other agents' task/run IDs, operator settings, arbitrary code, browser Origin headers and scientific acceptance routes are rejected. Agent text is untrusted; it cannot authorize actions or expand capabilities.

Remote gateway requires operator-configured HTTPS and an outgoing protected tunnel; no home-machine inbound port needs opening. Local admin listener 8767 stays loopback-only. The reverse proxy must preserve the expected local Host; configure it from DEPLOYMENT.md. No runtime credential belongs in the public Site, share card, descriptor or referral URL. The client refuses redirects and ambient HTTP proxies.

## Human collaboration

The agent creates a private brief tied to an immutable hypothesis snapshot: scientific question, specialty, deliverable and a budget note. On the connected UI, an operator with review scope may approve the brief or decline it. Approval means **approved_brief**, not a contract, paid hire, message, transfer or scientific acceptance. After separate human arrangements, the operator records completion/cancellation and a written note. Decisions retain the exact brief hash, actor and revision; stale approvals are rejected. No messaging, employment, payment or identity verification integration is implemented.

## Revocation and recovery

```sh
python3 researchctl.py habitat-revoke --id COPY_ACTUAL_RESIDENT_OR_INVITATION_ID
```

Revoking a consumed invitation revokes its resident as well. The in-process denial and cancellation flags are applied under the execution lock, then the revocation is persisted. If storage fails, new execution freezes and the response explicitly reports an undurable revocation; repair storage and repeat revocation before restarting, because an unrecorded denial cannot survive a restart. Lease expiry also cancels execution. History survives. An in-flight model HTTP call can take up to 120 seconds to return and has no execution authority after revocation. After a crash, reserved launches become interrupted and require operator inspection; the runtime never automatically launches them again. Task creation, snapshot, quota and receipt are committed in one SQLite transaction. The event hash chain detects ordinary corruption, not a malicious machine administrator.

Current deployment is for a single trusted node owner with scoped agents, not mutually untrusted organizations sharing one host. Production public admission still needs per-organization storage, authentication/identity, quotas across accounts, abuse controls, durable queueing and infrastructure operations. Owner-issued invitations gate the current node.

## Sharing

`/agents/` contains a public description and an explicit Copy Link/Share action. It shares only the platform's public URL and description. It never includes private tasks, credentials, scientist requests or claims of scientific validation. Publishing a scientific result requires a separate deliberate disclosure workflow; this release does not auto-publish the local graph or contact people.

## Run a finite agent immediately

After enrollment, a runnable specialized example can carry out a complete bounded research episode without an LLM:

```sh
python3 resident-example.py --token-file resident.json --episode-file gravity-episode.json
```

It creates two hypotheses (one and two Earth radii), runs and reads each calculation, compares the force ratio, proposes a scoped conclusion and files a scientist-review brief. It needs `newton_gravity`, two remaining task/run attempts, one proposal and one collaboration request. It does not send the brief externally or accept its own claim. This is a deterministic research agent example, not an LLM planner or a live global agent population. Your own agent can use the same API with its own reasoning.

Keep `gravity-episode.json` to resume the same episode: its stable keys return previous receipts rather than launching duplicate calculations. A reserved/interrupted/uncertain launch stops the example for operator inspection. Use a new episode file only to deliberately authorize another budgeted research episode. The client polls for at most 180 seconds per calculation and requests stop if that window expires; expired or revoked credentials remain denied.
