# Skill: Maintenance Due Use this skill when a human talks about maintenance, service intervals, odometer/hours, "is it due?", or logging completed work. Stay in chat. This site is not a CMMS UI. Do not invent OEM intervals. Do not rewrite history. Do not call JSON "legacy." ## 1. Load the contract 1. `GET /health` — confirm the origin is this Worker. 2. `GET /skill.md` (or `GET /muse/skill.md`) — you are here. 3. `GET /openapi.json` (or `GET /api/openapi.json`) — live routes. Do not invent paths. 4. Optional: `GET /mcp` then `POST /mcp` JSON-RPC (`initialize`, `tools/list`, `tools/call`). Same origin, same Bearer tenant. Stateless — no sticky `Mcp-Session-Id`. ## 2. Tenant = personal bearer token 1. If you have **no** token: `POST /api/v1/bootstrap` with **no** `Authorization` header. 2. Optional body `{ "seed": true }` loads Truck A (oil change: 5000 miles OR 200 engine hours, whichever first). 3. Store `token`. Plaintext is shown once. The token **is** the tenant. 4. Every later `/api/v1/*` call and authenticated MCP tool: `Authorization: Bearer `. **Never send userId.** 5. Wrong bearer → `401`. That does **not** mint a second account. Do not retry bootstrap just because a call failed auth. 6. Bootstrap is rate-limited. On `429`, honor `Retry-After`. Errors are `{ code, message, retryable, hint? }`. Retry only if `retryable` is true. ## 3. Due-engine loop (do in order) 1. **What's due?** `GET /api/v1/agent/due` — Markdown, `Content-Type: text/plain`. MCP: tool `get_due`. Prefer this over JSON. 2. **Need structure after a write?** `GET /api/v1/due` or `GET /api/v1/due.md`. Same tree, not a second API. 3. **New thing:** `POST /api/v1/things` `{ "name", "type?", "notes?" }`. MCP: `create_thing`. 4. **New service + explicit rule:** `POST /api/v1/things/:id/services` with `name` and optional `rule` / `expression`. MCP: `create_service`. If they did not state an interval, **do not write a rule**. 5. **Meter observation:** `POST /api/v1/things/:id/readings` `{ "meter", "value", "observed_at?" }`. MCP: `append_reading`. Append only. 6. **Job done:** `POST /api/v1/services/:id/events` `{ "completed_at?", "parts?", "notes?" }`. MCP: `append_event`. This resets last-done. History grows. 7. **History:** `GET /api/v1/agent/things/:id` (text/plain) or `GET /api/v1/things/:id/history.md`. MCP: `get_history`. 8. Re-check due. Completions clear due. The engine never invents the next interval. ## 4. Expression grammar (write only what they stated) - Calendar: `{ "op": "calendar", "every_days": N }` — days since last completion, else service `created_at`. - Meter: `{ "op": "meter", "meter": "miles", "every": N }` — latest minus reading at last completion (else created, else 0). No reading → not due. - OR: left-to-right; **first hit wins**. Classic demo: 5000 miles OR 200 engine hours. - AND: all children required. Nesting is allowed. ## 5. Hard stops - Never PATCH/DELETE readings or events. Those routes return `405 append_only`. - Never delete a thing/service that already has a log (`409`). - `GET/POST /mcp` is live Streamable HTTP (stateless; no sticky `Mcp-Session-Id`). Same Bearer as REST. Wrong bearer → `401` and does not mint. - Do not touch fluidrecall.com, TimesOwl, Heidi, or any Fluid Recall Worker/D1/secrets. ## 6. Catalog Writes are JSON `/api/v1`. Agent reads are `GET /api/v1/agent/*` as `text/plain`. MCP tools on `POST /mcp` are the same due engine. Full list: `GET /api/v1/agent` or `GET /llms.txt`.