# Happydebits llms-full.txt This file is the agent-oriented contract dump for Happydebits. ## Product Happydebits is a local-first recurring burn tracker. Users and coding agents share one ledger. Agents never write directly: they emit schema-valid action proposals; humans preview and confirm in the UI. ## Discovery - /llms.txt — index - /llms-full.txt — this file - /agent.md — narrative agent guide - /ledger-action.schema.json — proposal schema - /ledger.schema.json — full ledger export schema - /agents — human pairing + composer UI ## Pairing + MCP (highest leverage) 1. Human opens /agents and starts pairing (30 min TTL). 2. Browser syncs the on-device ledger with the **deviceSecret**. 3. Agent uses MCP (`mcp/happydebits-mcp.mjs`) or HTTP with Bearer **agentSecret**. 4. Agent calls get_ledger / list_charges, then propose_actions. 5. Human reviews pending proposal in /agents and confirms (deviceSecret). Env for MCP (agentSecret only): - HAPPYDEBITS_BASE_URL - HAPPYDEBITS_PAIR_ID - HAPPYDEBITS_PAIR_SECRET Tools: - get_ledger - list_charges - propose_actions (supports clientRequestId idempotency) - get_proposal HTTP: - POST /api/agent/pair → { pairId, agentSecret, deviceSecret, expiresAt } (rate-limited) - GET /api/agent/pair/:id (agent or device) - DELETE /api/agent/pair/:id (device only) - GET /api/agent/pair/:id/ledger (agent or device) - PUT /api/agent/pair/:id/ledger (device only) - GET|POST /api/agent/pair/:id/proposal (agent or device) - PATCH /api/agent/pair/:id/proposal (device only) Error envelope: { "ok": false, "code": "invalid_input|unauthorized|forbidden|not_found|expired|conflict|payload_too_large|rate_limited|method_not_allowed", "message": "...", "hint": "...", "retryable": false } Agent role cannot confirm/dismiss proposals, overwrite the ledger, or end the session. ## Proposal rules - version must be 1 - Return only proposal JSON, never a rewritten ledger - Prefer set_status cancelled over delete - Use exact targetId values from the ledger when updating - If ambiguous: empty risky actions + clarifyingQuestion - Never claim the ledger was mutated ## Example proposal { "version": 1, "message": "Cancel Disney+.", "clarifyingQuestion": null, "assumptions": [], "actions": [ { "type": "set_status", "targetId": "sub_123", "targetName": "Disney+", "status": "cancelled", "subscription": null, "changes": null, "confidence": 0.92, "reason": "User asked to cancel Disney+." } ] } ## Local interpret API (human UI) POST /api/interpret turns messy natural language into a proposal for the browser UI. It does not write the ledger. MCP agents should prefer building proposals from tools + schemas. ## Safety - Ledger data stays on device unless the human starts pairing (ephemeral session). - agentSecret is for MCP only; deviceSecret stays in the browser. - Agents cannot confirm/dismiss, overwrite the ledger, or end the pair. - Rotate by ending/restarting pair. No auto-apply for agent proposals.