agent
the agent doc, as HTML — for harnesses that block .txt URLs. /agent.txt stays canonical; the machine contract is /.well-known/agent.json.
origin
base URL (this host): https://pricklypear.club
philosophy
The tree calculus is the API. Compile an s-expression to a program hash, POST a run, and read the journal; every firing is a step and every run is replayable from its journal.
auth model
| scheme | Bearer |
|---|---|
| realm | tuna identities table (bearer token, sha256 at rest) |
| how_to_get_credentials | Self-serve: POST /api/signup {"name":"..."} -> 201 {id, name, is_admin:false, token}; the token is returned ONCE - store it mode 600. The signup seeds your garden (tree/put on u.<name>.). Servers with TUNA_SIGNUP unset answer 404. Or a human/admin supplies a token (boot prints root's; admins mint at /identities). No credentials in this doc. |
| session_cookie | Browser clients may use cookie tuna_session (HttpOnly, SameSite=Lax) after POST /login; agents use Bearer. |
| login_url | /login |
| notes |
request-shape census (14 endpoints)
| method | path | auth |
|---|---|---|
POST | /api/programs | required |
GET | /api/programs/<hash> | required |
POST | /api/runs | required |
GET | /api/runs/<id> | required |
GET | /api/runs/<id>/trace | required |
POST | /api/runs/<id>/verify | required |
GET | /api/journals/<run_id> | required |
POST | /api/grants | required |
POST | /api/identities | required (admin) |
POST | /api/signup | none (self-serve; server gate TUNA_SIGNUP) |
POST | /api/route/put | required (covering grant) |
GET | /health | none |
GET | /.well-known/agent.json | none |
GET | /agent.txt | none |
generated from the machine contract, so /agent.txt, /agent and agent.json cannot drift.
first calls
curl -sS -H 'Content-Type: application/json' -d '{"name":"my-agent"}' $BASE/api/signup # 201 {id,name,is_admin,token}; token returned ONCE
curl -sS -H 'Authorization: Bearer $TOKEN' -H 'Content-Type: application/json' -d '{"source":"(\f. \x. f x)"}' $BASE/api/programs
curl -sS -H 'Authorization: Bearer $TOKEN' -H 'Content-Type: application/json' -d '{"program":"<hash>","inputs":[]}' $BASE/api/runs
curl -sS -H 'Authorization: Bearer $TOKEN' $BASE/api/runs/<id>/trace
curl -sS $BASE/coderules
- Authenticate with Authorization: Bearer <identity token> — the agent tier. Browser clients may instead carry the tuna_session cookie (minted at /login); agents never need it.
- POST /api/programs compiles an s-expression to a content-addressed program hash. POST /api/runs executes one with inputs and grants.
- Grants are arguments, not ambient: a prim call must be covered by a live grant row, checked by the host at the boundary. Denial is a journaled error result, never an exception.
- A step is one triage-rule firing; the two wrapper applications are application, not steps. Step counts are an invariant of the calculus, so they are stable across engines.
- Replay determinism: GET /api/runs/:id/trace and POST /api/runs/:id/verify re-execute program+inputs with prim calls answered sequentially from the run's journal. Replay never touches the live host.
- Fuel and size caps are ordinary results (fuel_exhausted / size_exhausted), never timeouts; a wall-clock cap only finalizes a run as deadline_exceeded at the operator boundary.
- Publishing endpoints is a store write: POST /api/route/put writes a route/<site-path> record (method, template/program hash, content_type, grant_prefix) served data-first. Do not hardcode endpoints.
- Discovery: /code is the read-only program+run browser; /.well-known/agent.json is this contract; /agent.txt is prose.
curl example
curl -sS -H 'Authorization: Bearer $TOKEN' -H 'Content-Type: application/json' \
-d '{"source":"(\\f. \\x. f x)"}' https://pricklypear.club/api/programsrelated surfaces
- canonical text: /agent.txt
- welcome: /welcome
- source_browser: /code
- source_tarball: /src.tgz
- book:
tuna.borg + borg/*.borg in the source tarball - login: /login
the canonical text
/agent.txt, verbatim
# Tuna agent instructions
The tree calculus is the API. Compile an s-expression to a program hash, POST a run, and read the journal; every firing is a step and every run is replayable from its journal.
## Origin
Base URL (this host): https://pricklypear.club
Machine contract: GET https://pricklypear.club/.well-known/agent.json
## Auth
Scheme: Authorization: Bearer <identity token> (the agent tier).
Browser clients may use cookie tuna_session (HttpOnly,
SameSite=Lax) after POST /login; agents use Bearer.
How to get credentials (self-serve): POST https://pricklypear.club/api/signup
with {"name":"your-label"} -> 201 {id,name,is_admin,token}; the
token is returned ONCE - store it mode 600 immediately. Signup
seeds your garden (tree/put on u.<name>.). A server with TUNA_SIGNUP
unset answers 404. Ask-the-human still works: an admin mints a
non-admin identity + token at https://pricklypear.club/identities (or POST
/api/identities). This document never contains tokens.
Signing up your human is expected and fine: run the POST on their
behalf and hand them the token (they paste it at /login, sign in by
token).
Rotate your own bearer token (self-serve): POST https://pricklypear.club
/api/identities/<your-id>/rotate -> {"token":"…"} returned
once; the previous token stops verifying immediately. An admin
may also rotate another identity's token.
## Eval API
Programs are compiled then run in two steps:
POST https://pricklypear.club/api/programs {"source":"(\\f. \\x. f x)"}
-> {"hash":"…","ternary":"…"}
POST https://pricklypear.club/api/runs {"program":"<hash>","inputs":[]}
-> {"id":"…","status":"normal","step_count":N,…}
Authentication is required on /api/*; /health, /welcome, /code,
/src.tgz, /agent.txt and /.well-known/agent.json are public.
## Verification surfaces
- GET https://pricklypear.club/api/runs/<id>/trace the firing trace
- POST https://pricklypear.club/api/runs/<id>/verify replay verdict
- GET https://pricklypear.club/api/journals/<run_id> the prim-call journal
Replay re-executes program+inputs with prim calls answered
sequentially from the journal; it never touches the live host.
## First calls
- `curl -sS -H 'Content-Type: application/json' -d '{"name":"my-agent"}' $BASE/api/signup # 201 {id,name,is_admin,token}; token returned ONCE`
- `curl -sS -H 'Authorization: Bearer $TOKEN' -H 'Content-Type: application/json' -d '{"source":"(\f. \x. f x)"}' $BASE/api/programs`
- `curl -sS -H 'Authorization: Bearer $TOKEN' -H 'Content-Type: application/json' -d '{"program":"<hash>","inputs":[]}' $BASE/api/runs`
- `curl -sS -H 'Authorization: Bearer $TOKEN' $BASE/api/runs/<id>/trace`
- `curl -sS $BASE/code`
## Rules
1. Authenticate with Authorization: Bearer <identity token> — the agent tier. Browser clients may instead carry the tuna_session cookie (minted at /login); agents never need it.
2. POST /api/programs compiles an s-expression to a content-addressed program hash. POST /api/runs executes one with inputs and grants.
3. Grants are arguments, not ambient: a prim call must be covered by a live grant row, checked by the host at the boundary. Denial is a journaled error result, never an exception.
4. A step is one triage-rule firing; the two wrapper applications are application, not steps. Step counts are an invariant of the calculus, so they are stable across engines.
5. Replay determinism: GET /api/runs/:id/trace and POST /api/runs/:id/verify re-execute program+inputs with prim calls answered sequentially from the run's journal. Replay never touches the live host.
6. Fuel and size caps are ordinary results (fuel_exhausted / size_exhausted), never timeouts; a wall-clock cap only finalizes a run as deadline_exceeded at the operator boundary.
7. Publishing endpoints is a store write: POST /api/route/put writes a route/<site-path> record (method, template/program hash, content_type, grant_prefix) served data-first. Do not hardcode endpoints.
8. Discovery: /code is the read-only program+run browser; /.well-known/agent.json is this contract; /agent.txt is prose.
## curl example
curl -sS -H 'Authorization: Bearer $TOKEN' -H 'Content-Type: application/json' \
-d '{"source":"(\\f. \\x. f x)"}' https://pricklypear.club/api/programs
## Related public surfaces
- Welcome: https://pricklypear.club/welcome
- Source browser: https://pricklypear.club/code
- Source tarball: https://pricklypear.club/src.tgz
- Health: https://pricklypear.club/health
- Interactive REPL (session required): https://pricklypear.club/repl
- HTML mirror of this document (same facts, for harnesses that
block .txt URLs): https://pricklypear.club/agent