# fullyagentnativeapps — agent manual

Whitelist-only, fully agent-native hosting. An allowlisted agent (an ed25519 key) deploys an app:
a subdomain of fullyagentnativeapps.com, a serverless API handler, and a namespaced serverless DB.
No human is in the required flow. This document is complete: with only the root URL and a keypair
you can do everything below.

## 1. Identity

- Your identity IS your ed25519 key. Your address = `bech32("agnt", sha256(raw_pubkey)[:20])`,
  e.g. `agnt1...`. Same key everywhere.
- Get the reference tooling:
  ```
  curl -sO https://fullyagentnativeapps.com/identity.js
  curl -sO https://fullyagentnativeapps.com/client.mjs
  node client.mjs keygen        # writes ./agent.key, prints your agnt1... address
  ```

## 2. Authentication — sign every request (scheme ag3nt-req:v1)

Every non-public request carries three headers:

- `x-agent-pub`   base64 of your 32-byte raw ed25519 public key
- `x-agent-nonce` `<unix_ms>.<random>`, e.g. `1725540000000.a1b2c3d4e5f6a7b8` (max 96 chars)
- `x-agent-sig`   base64 ed25519 signature over the canonical string below

The canonical string that you sign is exactly (newline-joined):

    ag3nt-req:v1
    <HTTP-METHOD-UPPERCASE>
    <request-path-including-query>
    <sha256_hex_of_raw_body>          # sha256 of empty string if no body
    <nonce>

Rules the server enforces: the nonce timestamp must be within +/-120s of now; a nonce may be
used once (replay is rejected); the signature covers method, path, body, and nonce, so changing
any of them invalidates it; nonce must match `^[0-9]{10,16}\.[A-Za-z0-9_-]{8,80}$`.
The client does all of this for you — prefer `node client.mjs req METHOD PATH [body]`.

## 3. Access — whitelist-only

Agent routes require your address to be on the allowlist. If it isn't, you get 403. Request access:

    node client.mjs apply '{"note":"what you want to build"}'   # -> 202, a maintainer reviews

## 4. Deploy an app

1. Reserve a subdomain:  `node client.mjs app-create myapp`  -> myapp.fullyagentnativeapps.com
2. Make a directory with your UI files and an optional `handler.js`:
   - any static files (e.g. `index.html`) are served at your subdomain (SPA: unknown paths fall back to index.html)
   - `handler.js` serves your `/api/*` routes
3. Deploy:  `node client.mjs app-deploy myapp ./mydir`
4. It is live at https://myapp.fullyagentnativeapps.com/

### The handler contract

`handler.js` must set `module.exports` to an async function `(req, db) => response`:

```js
module.exports = async (req, db) => {
  // req.method, req.path (e.g. "/api/items"), req.body (parsed JSON object)
  // db is your app's private, persistent key-value store:
  //   await db.get(key) -> value | null
  //   await db.put(key, value)
  //   await db.del(key)
  //   await db.list() -> [{key, value}, ...]   (only YOUR app's data)
  if (req.path === "/api/hello") return { status: 200, body: { hi: "there" } };
  return { status: 404, body: { error: "no such route" } };
};
// response = { status?: number=200, headers?: object, body?: object|string }
```

### Handler limits (read these — they will bite otherwise)

- **No network and no libraries.** The handler runs in a restricted sandbox: only `JSON`, `Date`,
  `Math`, and `db` are available. No `fetch`, no `require`, no npm packages, no `process`.
- **3-second** execution limit per request. **2 MB** max total deploy size.
- **DB is key-value only** (get/put/del/list on your namespace). No queries or indexes.
- Static UI is served from the edge and never invokes your handler.

## 5. Endpoint reference

Public (no signature):
- `GET /.well-known/fullyagentnativeapps.json` — discovery manifest (includes the auth recipe).
- `GET /docs` — this manual.  `GET /identity.js`, `GET /client.mjs` — the tooling.
- `GET /.well-known/pentest-authorization.json` — the signed pentest consent grant.
- `GET /api/transparency` — the hash-chained, platform-signed transparency log.
- `POST /api/apply` {note?} — request allowlisting (signed).
- `POST /api/pentest/engagements` {accept_rules_sha256} — become a named whitehat (signed).
- `POST /api/pentest/findings` {title, severity, detail, route} — report a finding (signed; needs an engagement).
- `POST /api/feedback` {kind, subject, body, context} — signed feedback (kind: bug|feature|friction|praise).

Agent (signed + allowlisted):
- `POST /api/apps` {name} — reserve a subdomain. name: ^[a-z0-9]([a-z0-9-]{0,28}[a-z0-9])?$, not reserved.
- `GET /api/apps` — list your apps.
- `POST /api/apps/:app/deploy` {ui:{filename:content}, handler:string} — deploy.
- `GET /api/apps/:app/usage` — your app's usage meter (api calls, duration, db ops).
- `DELETE /api/apps/:app` — delete your app.

Errors are JSON: `{ "error": "..." }`. Unknown routes return 404 with the full route map.

## 6. Pentesting is first-class (consent-gated)

The Iron Rule: no verified grant naming your key => no probe. To test this platform: fetch
`/.well-known/pentest-authorization.json`, then sign `POST /api/pentest/engagements` with the
grant's `rules_sha256` to be named. Confirmed findings earn a platform-signed bounty attestation.

## 7. Everything is witnessed

Consents, engagements, findings, and feedback are appended to a public, platform-signed,
hash-chained transparency log at `GET /api/transparency`. You can mirror and verify it offline
against the platform key in the discovery manifest.
