"Git for Agent Sessions"
Design Spec — March 30, 2026 — v1
The cloud service is a new provider adapter for the existing sync engine. Same YAML format, same .recallignore, same secret scanning. The cloud adapter translates push/pull into HTTP REST calls.
/recall sync init --github → user's GitHub repo (free, actual git) /recall sync init --gitlab → user's GitLab repo (free, actual git) /recall sync init --bitbucket → user's Bitbucket repo (free, actual git) /recall sync init --cloud → our managed R2 backend ($1.50/quarter)
┌─ Sync Engine (existing) ───────────────────────────────┐
│ │
│ Provider adapters: │
│ ├── git (GitHub, GitLab, BB) → git push/pull │
│ └── cloud (NEW) → HTTP REST to Worker │
│ │
└────────────────────┬───────────────────────┘
│ HTTPS
▼
┌─ Cloudflare Worker ────────────────────────────┐
│ │
│ Auth → Rate Limiter → Route Handler │
│ (API key) (KV) (PUT/GET/LIST/DELETE) │
│ │
│ Stripe Webhook (/webhook/stripe) │
│ │
│ ┌───────────┐ ┌────────────────────────┐ │
│ │ KV Store │ │ R2 (versioning enabled) │ │
│ │ api keys │ │ /{user_id}/ │ │
│ │ rate ctrs │ │ restarts/*.yaml │ │
│ │ usage │ │ learnings/*.yaml │ │
│ │ tier info │ │ adm/*.yaml │ │
│ └───────────┘ │ sops/*.yaml │ │
│ │ sessions/*.yaml │ │
│ │ agent-configs/*.yaml │ │
│ └────────────────────────┘ │
└────────────────────────────────────────────────┘
| Cloudflare Worker + R2 | AWS ECS Fargate + S3 | |
|---|---|---|
| Baseline | $0 | ~$23/mo |
| Egress | $0 | $0.09/GB |
| Profitable from | User #1 | ~User #200 |
| Deploy | wrangler deploy | Container + ALB + IAM + ECR |
No git server. No commits. No refs. R2's built-in object versioning provides automatic version history, restore any previous version, list all versions, and soft delete with retention. Each file is a complete, self-contained YAML document. No diffs, no deltas, no changelogs.
PUT /v1/files/{path} Store a file (R2 auto-versions)
GET /v1/files/{path} Get latest version
GET /v1/files/{path}?version={n} Get specific version
GET /v1/files/{path}/versions List all versions of a file
GET /v1/files/?after={timestamp} List files changed since
DELETE /v1/files/{path} Soft delete (versions retained)
DELETE /v1/files/{path}/versions Trim old versions (keep=N)
GET /v1/status Storage, rate limits, billing
GET /v1/export Signed R2 URL for full download
POST /v1/auth/rotate Rotate API key
POST /v1/webhook/stripe Stripe billing events
| Local command | Cloud call | What happens |
|---|---|---|
/recall sync push | PUT /v1/files/* | Upload changed files since last push |
/recall sync pull | GET /v1/files/?after={ts} | Download files changed since last pull |
/recall sync status | GET /v1/status | Show storage, limits, billing |
/recall cloud export | GET /v1/export | Download everything as tarball |
Push (fast-forward only): Sync engine gathers changed files → secret scan locally → .recallignore filter → PUT each file → R2 auto-versions → record timestamp.
Pull: GET files changed since last pull timestamp → download each → write to local directories → regenerate index.
No merge. No conflict resolution. Two machines create different files with unique timestamps. Latest write wins; versions are retained so nothing is lost.
| Tier | What syncs | Size per session |
|---|---|---|
| Lite (default) | Distilled restarts + index metadata | ~2-5KB |
| Standard | Lite + raw JSONL (expires 30 days) | ~1-10MB |
| Full | Everything, against 10GB cap | ~1-10MB, persists |
sync:
provider: cloud
tier: lite
include:
adm: true
restarts: true
learnings: true
sops: true
session_metadata: true
agent_configs: true
transcripts: false
10GB cap per user (includes R2 version history). When full: 507 Insufficient Storage. Version cleanup via DELETE /v1/files/{path}/versions?keep=3.
| Window | Max requests | Max IN | Max OUT | Why |
|---|---|---|---|---|
| Session (5hr) | 50 | 20MB | 50MB | Matches agent session |
| Hourly | 30 | 10MB | 30MB | Burst prevention |
| Daily | 200 | 50MB | 100MB | ~4 sessions/day |
| Weekly | 800 | 200MB | 500MB | Heavy dev week |
| Monthly | 2,000 | 500MB | 1GB | Full billing period |
Enforcement: Request → Auth → Check all 5 windows → Process or 429. Counters stored in KV with TTL-based auto-cleanup.
Export exemption: GET /v1/export always works regardless of rate limits. Your data is your data. Limited to 1/day to prevent CDN abuse.
| Item | Cost/user/quarter |
|---|---|
| Stripe fee (2.9% + $0.30) | $0.34 |
| R2 storage (10GB, 3mo) | ~$0.45 |
| Worker compute | ~$0.01 |
| Total cost | ~$0.80 |
| Revenue | $1.50 |
| Profit | ~$0.70 |
User visits cloud.html
→ Stripe Checkout ($1.50/quarter)
→ Webhook: checkout.session.completed
→ Generate API key (32-byte hex)
→ Store SHA-256(key + salt) in KV
→ Show key once on post-checkout page
→ echo "sk_recall_..." > ~/.env/agent-recall/api-key
→ /recall sync init --cloud
On invoice.upcoming webhook: check if any API requests in last 60 days. If no → cancel subscription, retain data for 30 days grace, then 7 more days export-only, then delete.
| State | Push/Pull | Export | Data retained |
|---|---|---|---|
| Active | Yes | Yes | Yes |
| Inactive | No | Yes | 30 days |
| Expired | No | Yes | 7 more days |
| Deleted | No | No | No |
A new sync category for AGENTS.md / CLAUDE.md files. Snapshots taken on session start, stored as versioned documents.
# agent-configs/CLAUDE.md/2026-03-30T08:01:00.yaml file: CLAUDE.md project: myapp snapshot_date: 2026-03-30T08:01:00 session_id: abc123 changed_by: agent:claude-opus-4-6 diff_summary: "Added 3 rules about ArangoDB env vars" content: | # full file content at this point in time
/recall configs # list tracked config files /recall configs diff # changes since last session /recall configs rollback 2 # restore from 2 snapshots ago
/{user_id}/ — hard isolationraw_key = crypto.randomBytes(32).hex() → shown once key_hash = SHA-256(raw_key + SALT) → stored in KV
Raw key never stored. Salt is a Worker secret. Rotation via POST /v1/auth/rotate.
docs/ ├── index.html ← existing recall microsite ├── cloud.html ← NEW: service + Stripe checkout └── self-host.html ← NEW: deploy-your-own guide
One paragraph, pricing ($0.50/mo billed $1.50/quarter), Stripe Checkout button, post-payment API key display, link to self-host guide.
1. Fork the repo 2. Create Cloudflare account (free) 3. Create R2 bucket (versioning) + KV namespace 4. Create Stripe account + product 5. wrangler secret put STRIPE_SECRET_KEY wrangler secret put STRIPE_WEBHOOK_SECRET wrangler secret put API_KEY_SALT 6. wrangler deploy 7. Configure Stripe webhook URL 8. Done — selling under your own brand
Open source safety: No credentials in code, ever. All secrets via wrangler secret put.
# ~/.config/agent-recall/sync.yaml sync: provider: cloud endpoint: https://recall-api.agent-recall.workers.dev api_key_file: ~/.env/agent-recall/api-key tier: lite auto_sync: true
| Command | What it does |
|---|---|
/recall cloud setup | Prompt for API key, write config, test |
/recall cloud status | Storage, rate limits, billing |
/recall cloud export | Download full data tarball |
| Command | Cloud behavior |
|---|---|
/recall sync push | PUT changed files to R2 |
/recall sync pull | GET files since last pull |
/recall sync push --dry-run | Show what would push |
/recall sync --verify | Confirm all data pushed |
/recall sync pause/resume | Toggle auto-sync |
Local always works. Cloud is additive. Sync failures never block the user.
agent-recall/ ├── worker/ # NEW: Cloudflare Worker │ ├── src/ │ │ ├── index.ts # Entrypoint, router │ │ ├── auth.ts # API key validation │ │ ├── rate-limiter.ts # 5-window rate limiting │ │ ├── files.ts # R2 CRUD │ │ ├── stripe.ts # Webhook handler │ │ └── export.ts # Signed URL generation │ ├── wrangler.toml # R2 + KV bindings │ ├── package.json │ └── tsconfig.json ├── lib/ │ ├── sync_cloud.py # NEW: cloud adapter │ └── sync.py # MOD: register cloud ├── docs/ │ ├── cloud.html # NEW: service page │ └── self-host.html # NEW: deploy guide └── wrangler.toml # existing (microsite)
| Users | Est. req/day | Action |
|---|---|---|
| 0 – 500 | <10k | Free tier, no action |
| 500 – 2,000 | 10k – 50k | Workers paid plan ($5/mo) |
| 2,000 – 5,000 | 50k – 100k | Monitor, approaching limit |
| 5,000+ | >100k | Split read/write Workers |
At 5,000 users: $10,000/quarter revenue. Infra: ~$50/month. Comfortable margin.
/recall cloud setup, status, export commands