# LoopKit Agent Instructions

Read telemetry as evidence for product improvement, not as an end in itself.

Default loop:
1. Read a bounded telemetry window.
2. Cluster repeated product pain.
3. Draft eval candidates and patch plans.
4. Stop before any external write. LoopKit prepares the work; posting issues or
   opening PRs happens outside LoopKit for now.
5. Verify the next telemetry window.

## Get a key (self-serve, no operator)

No key yet? Two options:

- POST /v1/provision — body { "project_name": string, "operator"?: string }
  → the signup shape PLUS { resumed, graduated }. RECOMMENDED for agents: one
  re-runnable call that converges to the SAME project for a given name.
  • First call (no auth): MINTS the project and returns fresh producer + agent keys,
    self-graduated to a permanent key. Rate-limited and race-guarded.
  • Re-run: send one of THAT project's keys as 'Authorization: Bearer <key>' to
    RESUME it. Resume is NON-ROTATING — it graduates the project in place and you
    keep the key you sent (no new key is returned, nothing is deleted). Resuming an
    existing project without its key is rejected (401/403): only the owner can.
  Scope a name with "operator" so two operators can each own the same project name
  in the shared sandbox tenant.
- POST /v1/signup (no auth) — body { "project_name"?: string }
  → { producer_key, agent_key, project_id, quota_spans, expires_at, ingest_url,
      diagnose_url, recovery_code, dashboard_url }
  Mints a fresh isolated sandbox project each call (non-idempotent).

Then ingest with the producer_key and diagnose with the agent_key. Sandbox
projects are isolated and span-capped; request a production tenant via
/contact.json when you outgrow it.

## Don't lose your keys (recovery)

Keys are shown ONCE and stored only as hashes — LoopKit cannot show them again. Save
the producer_key, agent_key, project_id, AND the recovery_code from the signup/provision
response. If you lose the keys, rotate fresh ones with the recovery_code:

- POST /v1/recover — body { "project_id": string, "recovery_code": string }
  → rotates fresh producer + agent keys, revokes the old ones, returns a dashboard_url.
  The recovery_code is HMAC-SHA256("recover:<project_id>") and does NOT change when keys
  rotate — keep it (and your project_id) safe. Humans can also recover in the browser at
  /dashboard via the "Lost your key?" form, and bookmark the long-lived dashboard_url.

If an operator gives you a signed upgrade code, POST /v1/signup/upgrade with the
agent_key bearer and body { "code": "<signed hex code>" }. The code is
HMAC-SHA256("signup-upgrade:sandbox:<project_id>") signed with the Worker secret
SIGNUP_UPGRADE_SECRET. Older sandbox projects that predate the token index can
include producer_key and agent_key in that body once.

## Surfaces

- GET /v1/dashboard — machine-readable program state (JSON). Authoritative technical surface.
- GET /v1/reports/latest.md — narrative report for agents.
- GET /v1/telemetry — recent normalized telemetry records.
- POST /v1/traces — OTLP JSON spans, normalized into stored telemetry records.
- POST /v1/runs/diagnose — cluster failures into an issue packet.
- POST /v1/provision — idempotent onboarding: public mint (race-guarded), authenticated non-rotating resume, auto-graduate.
- POST /v1/signup/upgrade — graduate sandbox keys to permanent-but-capped.
- POST /v1/recover — rotate lost keys with the recovery_code (returns fresh keys + a dashboard link).
- /agents.md, /llms.txt — operating instructions.

## Dashboard fields

- summary.regression_rate — derived share of measured changes that slipped back (null if none measured).
- value — derived plain-English momentum: { headline, momentum, held_count, slipped_count, open_pain_count, regression_rate, derived }.
- open_pains[] — product pains clustered from telemetry, each with signal_type, count, and evidence_count.
- wins[] / regressions_detail[] — measured improvements split by derived direction, each with change_percent.

## See also

- /quickstart.md for the ingest + diagnose flow.
- /openapi.json for the full HTTP surface.
- /schema/improvement-packet.json for diagnosis packet shape.
