TabMind v1.0.0 — Service Level Objectives (SLOs)

Status: Live as of v1.0.0 (2026-07-31)

Owner: operations@seele.agency

Review cadence: Monthly, with quarterly commitment review

Last revised: 2026-07-31


1. Why this document exists

TabMind move from "shipping captures" to "running a public service" at v1.0.0. The

questions we owe our users aren't "how fast is it?" — they're:

This document is the contract. We pick targets, we publish error budgets, we

publish the on-call handbook, and we publish the burn-rate policy. If we breach

an SLO, we tell users. If we keep hitting it, we tighten it.

2. Service definitions

The public surface of TabMind v1.0.0 is six services. Each has its own SLO

because each has different failure modes.

Service Path / Identity What it does
xkg-server https://seele.agency/api/* Public API (capture, search, sync, release)
xkg-cluster-hub https://hub.seele.agency/* KG linker, sync state, device registry
static-frontends https://seele.agency/* Marketing, docs, downloads, dashboard
mobile-cdn https://cdn.seele.agency/xkg-mobile/* APK/IP/AAB/IPA distribution
license-server https://license.seele.agency/v1/check Pro tier validation (with grace)
cf-worker-fresh https://seele.agency/* (cache layer) Edge cache + cache-bust

Standalone (not user-facing or offline-first): xkg-core Rust crate, TabMind

browser extension, xkg-desktop Tauri app. These do not have user SLOs.

3. SLO targets

Targets are availability unless noted. Availability = `successful requests /

total requests` over the rolling window, with a 4xx hand-wave rate ≤ 5% of

total (so error budgets are tight on 5xx, sloppy on 4xx).

Service Indicator Target Window
xkg-server API 5xx rate 99.9% successful (≤ 0.1% error budget) 30 d rolling
xkg-server p95 latency for /api/capture < 800 ms 7 d rolling
xkg-server p99 latency for /api/search < 1.5 s 7 d rolling
xkg-cluster-hub API 5xx rate 99.9% successful 30 d rolling
xkg-cluster-hub /api/sync/health p95 < 250 ms 7 d rolling
static-frontends HTTP 200 rate 99.95% (cf-fronted) 30 d rolling
static-frontends p95 TTFB < 200 ms 7 d rolling
mobile-cdn HTTP 200 rate on asset path 99.5% 30 d rolling
mobile-cdn APK download p95 (50 MB) < 8 s on 25 Mbps 7 d rolling
license-server HTTP 200 rate 99.0% (grace covers gaps) 30 d rolling
license-server p95 /v1/check latency < 400 ms 7 d rolling
cf-worker-fresh Edge cache hit ratio ≥ 90% 7 d rolling

Why these numbers:

achievable for a single-tenant service on Cloudflare + a small DO droplet.

should cache the file. The 0.5% error budget is for new release day.

clients fail-open on offline / timeout. Hard outage is invisible to users.

4. Error budget policy

4.1 Budget math

For xkg-server at 99.9% over 30 days:

At ~10 RPS sustained, that's 0.1% × 10 × 60 × 24 × 30 ≈ **2,592 failed

requests / 30 d** before we burn the budget.

4.2 Burn rate

We compute burn rate at 1h and 6h windows. Alerts fire at:

Burn rate Window Severity Action
14.4× 1h Page Wake on-call, suspect incident
6h Page Wake on-call, runbook: hunt regression
24h Ticket Office hours, file follow-up
30d Dashboard Quarterly review, tighten SLO

Source: Google SRE Workbook, multi-window burn-rate alerts.

4.3 Budget exhaustion

If we burn 50% of budget before day 15:

If we burn 100% before day 30:

If we hit 0% budget remaining with headroom on the calendar, SRE can

voluntarily tighten the SLO at the next quarterly review.

4.4 What is NOT counted against the budget

5. On-call runbook

5.1 Roster

5.2 Pager triage (first 5 minutes)

  1. Acknowledge. Ack within 5 min. If you can't, escalate.
  2. Read the alert. Severity, service, burn rate, window.
  3. Open the dashboard. https://grafana.seele.agency/d/tabmind-slo
  4. Check the change log. git log --since="2 hours ago" --oneline

across the implicated service.

  1. Open status page. https://status.seele.agency — confirm whether

other alerts are co-firing.

  1. Decide. Is this a real outage (5xx spike) or a noisy alert (rate-limit

traffic, known deploy)?

5.3 Severity classification

Sev Definition Response time Action
SEV-1 > 50% of users cannot use core flow 5 min Page all of engineering, public status update
SEV-2 > 10% of users experience degraded core flow 15 min Page on-call, status within 30 min
SEV-3 < 10% of users, or non-core path 1 hour Ticket, status next business day
SEV-4 No user impact, internal only Next business day File ticket, no page

5.4 Common playbooks

#### "xkg-server 5xx spike"

  1. curl -sS https://seele.agency/api/health → check 200
  2. tail -n 200 /var/log/xkg-server/error.log → look for stack traces
  3. ps aux | grep xkg-server → confirm process alive
  4. If crashed: systemctl restart xkg-server (no DB touch needed,

schema is idempotent on startup)

  1. If alive but erroring: check conversations.db is locked, check disk

space (df -h /home/x2/.cluster-hub)

  1. If disk full: journalctl --vacuum-size=200M (logs), then `du -sh

/home/x2/.cluster-hub/*` to find the offender

  1. Post in #incidents: cause, ETA, mitigation

#### "xkg-cluster-hub 5xx spike"

  1. curl -sS https://hub.seele.agency/api/health → check 200
  2. pgrep -af cluster-hub-server.py → confirm alive
  3. tail -n 200 /home/x2/.cluster-hub/hub.log → look for migration

errors (means DB schema issue)

  1. If migration error: do NOT restart without manual review. Open

ticket and consult db-migrate.py logs.

  1. If alive but slow: check conversations.db size; if > 1 GB, run

python3 scripts/db-prune.py --older-than 365d (artifacts only)

  1. If sync only failing: check /api/sync/health — device count, last

envelope timestamp; if a single device is flooding, ban its ID.

#### "Static frontends down (Cloudflare cache miss)"

  1. curl -sSI https://seele.agency/index.html → cf-cache-status
  2. If EXPIRED or MISS, push deploy: bash /home/x2/github/seele-agency-site/deploy.sh
  3. If BYPASS, check CF Worker logs (wrangler tail if installed)
  4. If CF is hot, but our origin is down, fallback to griptoad26.github.io

by updating CNAME temporarily (manual)

#### "license-server 5xx"

  1. Default action: do nothing. License failures are designed to

fail-open with a 30-day grace window. Users will not notice a 10-min

outage.

  1. Only page if the outage is > 1 hour AND a release is within the

grace window.

  1. license-server.py is runnable from any stdlib Python 3.11+ host.

Backup: bash /home/x2/.openclaw/agents/ocmi-orchestrator/scripts/start-license-stub.sh

5.5 Communication

https://seele.agency/postmortem/.html

5.6 Post-mortem template

Every SEV-1 and SEV-2 requires a post-mortem. Template:


# <date> — <short title>

## Summary
2-3 sentences. What happened, who was affected, how long.

## Timeline (PT)
- HH:MM — first alert
- HH:MM — ack
- HH:MM — mitigation
- HH:MM — resolution

## Root cause
One paragraph. The actual cause, not the symptom.

## Resolution
One paragraph. What we did to fix it.

## Recovery
One paragraph. What we did to prevent recurrence.

## SLO impact
% of monthly budget consumed by this incident.

## Lessons
Numbered list. What we learned, what we'll change.

6. Measurement

6.1 What we measure

against /api/health of each service.

latency, error rate, by endpoint.

6.2 What we ignore

6.3 Sources

7. SLO compliance dashboard

Public, anonymous, scrubbed:


https://seele.agency/status/slo.html

Renders last 90 days with:

This page is itself under SLO (99.95%). If the dashboard is down, it

counts against static-frontends.

8. Exceptions and revisions

This document is owned by the SRE function. To revise, attach the diff

to a PR and CC engineering-leadership@seele.agency. Quarterly review at

the v1.0.0 / v1.1.0 / v1.2.0 boundary.

We revise targets when we've held them for 90 days. We don't revise

to look generous; we revise when the floor proves too low.

9. Acknowledgments

Published: 2026-07-31

This SLO document is the result of:

If you find a bug in this document, file at https://github.com/griptoad26/seele-agency-site/issues

with the slo label.


TL;DR for non-SREs: