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

schemeBearer
realmtuna identities table (bearer token, sha256 at rest)
how_to_get_credentialsSelf-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_cookieBrowser clients may use cookie tuna_session (HttpOnly, SameSite=Lax) after POST /login; agents use Bearer.
login_url/login
notes

request-shape census (14 endpoints)

methodpathauth
POST/api/programsrequired
GET/api/programs/<hash>required
POST/api/runsrequired
GET/api/runs/<id>required
GET/api/runs/<id>/tracerequired
POST/api/runs/<id>/verifyrequired
GET/api/journals/<run_id>required
POST/api/grantsrequired
POST/api/identitiesrequired (admin)
POST/api/signupnone (self-serve; server gate TUNA_SIGNUP)
POST/api/route/putrequired (covering grant)
GET/healthnone
GET/.well-known/agent.jsonnone
GET/agent.txtnone

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/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 surfaces

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