Operator Runbook
Quick Start (Demo Mode)
git clone https://github.com/akshan-main/revcat-agent-advocate.git
cd revcat-agent-advocate
pip install -e .
export DEMO_MODE=true
export ANTHROPIC_API_KEY=sk-ant-...
revcat-advocate demo-run
python -m http.server -d site_output 8000
Quick Start (Real Mode)
git clone https://github.com/akshan-main/revcat-agent-advocate.git
cd revcat-agent-advocate
pip install -e .
export REVENUECAT_API_KEY=sk_your_key
export ANTHROPIC_API_KEY=sk-ant-...
export DEMO_MODE=false
revcat-advocate ingest-docs
revcat-advocate write-content --topic "Your Topic" --type tutorial
revcat-advocate build-site
Safety Gates
| Flag | Default | Effect |
|---|---|---|
DRY_RUN | true | No external posts, no GitHub issues. Drafts only |
ALLOW_WRITES | false | Blocks POST/PUT/DELETE to RevenueCat API |
DEMO_MODE | false | Uses mock API responses and local fixture data for testing |
Autonomy Model
| Runs Autonomously | Operator-Gated |
|---|---|
|
|
Signal Pipeline
The supervisor ingests signals from 5 producers, scores them, and acts on the highest-priority signal each cycle. Agent-task issues are handled by a separate event-driven workflow, not the signal pipeline.
| Producer | Source | TTL | What it detects |
|---|---|---|---|
| GitHub Issues | 6 RC repos (purchases-ios, android, flutter, unity, kmp, js) | 72h | New issues in last 72 hours |
| 6 subreddits (iOSProgramming, androiddev, FlutterDev, etc.) | 48h | Quality-gated: requires minimum engagement (score ≥ 3 or comments ≥ 2) AND actionable content (question, problem, comparison) | |
| Dev.to Stats | Published articles | 72h | Engagement spikes (1.5x+ growth) and stalled articles |
| Doc Changes | Cached doc pages | 72h | SHA256 changes between ingestion runs |
| Scheduled | Internal timers | 48h | Content due (5 days), tweet due (2 days), feedback due (7 days) |
Signal Scoring
Each signal is scored: score = impact × urgency × confidence × freshness. Freshness decays linearly from 1.0 to 0.05 over the signal's TTL. The highest-scoring unclaimed signal is acted on.
Deduplication & Expiry
Signals are deduped by (source, url) or title hash. Each signal has a TTL — expired signals are marked and excluded from scoring. This prevents the agent from re-processing stale information.
Agent Tasks (Event-Driven)
Agent tasks are not part of the signal pipeline. They have their own GitHub Actions workflow (agent-task.yml) that triggers when an issue is labeled agent-task:
- Issue labeled
agent-task→ workflow triggers immediately - Task injected as a signal, claimed directly by ID — no producer ingestion, no scoring queue
- Supervisor decides the action (including
submit_formfor browser-based tasks) and executes it - Ledger entry recorded
- Issue closed on success, left open on failure (CLI exits non-zero if task not acted on)
This separation ensures operator tasks get immediate execution without competing against scored signals in the supervisor queue, while retaining access to all supervisor actions including browser automation.
Browser Automation
The supervisor can browse the web via Playwright MCP (pinned to @playwright/mcp@0.0.28). Used for signal enrichment (fetching page content) and form submission.
| Capability | How it works |
|---|---|
| Signal enrichment | Before acting on a signal, the browser fetches the page content to give the agent full context |
| Form submission | LLM interprets page DOM + operator-provided fields → generates click/type sequences via MCP |
| Domain allowlist | 11 whitelisted domains: revenuecat.com (+ docs, www, community subdomains), github.com, dev.to, reddit.com (+ www, old), stackoverflow.com, jobs.ashbyhq.com |
| DRY_RUN gating | Form submissions blocked in dry-run mode |
Community Scanning
The agent monitors developer communities for RevenueCat questions and discussions. All responses stay in draft status — nothing is auto-posted.
| Source | Targets | What it does |
|---|---|---|
| GitHub | purchases-ios, purchases-android, purchases-flutter, purchases-unity, purchases-kmp, purchases-js | Scans issues, drafts doc-grounded responses |
| iOSProgramming, androiddev, FlutterDev, gamedev, IndieDev, RevenueCat | Scans posts mentioning subscriptions or RevenueCat, drafts helpful replies | |
| RevenueCat developer community | Drafts tweets with critic-agent quality gate (length, code detection, LLM review) |
Dev.to Closed Loop
Content published to Dev.to feeds engagement data back into the agent's decision-making:
write-content → publish-devto → Dev.to API
↓
devto-stats (pulls views, reactions, comments back to Turso)
↓
Bandit reward = max(views/500, reactions/20, comments/10)
↓
Thompson sampling updates Beta(alpha, beta) priors
↓
Next topic selection favors higher-engagement categories
The supervisor calls sync_rewards_from_devto to update bandit priors from Dev.to engagement stats. The autonomous agent core also enforces Dev.to stats sync as a post-cycle step (conditional on has_devto). This creates a self-improving content strategy based on real engagement data.
Memory Pruning
Agent memory grows over time as lessons are recorded each cycle. The pruning system keeps memory useful instead of noisy:
| Policy | Rule |
|---|---|
| Recency | Keep all lessons from last 90 days regardless of confidence |
| Quality gate | Older lessons survive only if confidence ≥ 0.7 |
| Per-key cap | Max 20 lessons per (lesson_type, key) combo — keeps the newest |
| Deduplication | Exact duplicates (same type + key + insight) are hard-deleted, keeping newest |
revcat-advocate prune-memory # apply default policies
revcat-advocate prune-memory --dry-run # preview what would be pruned
revcat-advocate prune-memory --max-age 60 # tighter window
revcat-advocate prune-memory --min-confidence 0.5 # stricter quality gate
Reliability Engineering
Pre-Execution Action Firewall
External actions are checked against applicable gates before execution:
| Layer | Gate | Blocks |
|---|---|---|
| 1. Config | DRY_RUN / ALLOW_WRITES | All external writes, API mutations, social posts |
| 2. Safety | SafetyError exception | POST/PUT/DELETE to RC API, write-capable MCP tools |
| 3. Publish Gate | Banned phrase + citation check | Deployment if letter contains overclaims or too few citations |
| 4. Tweet Critic | Programmatic + LLM review | Tweets that fail length, code detection, or quality checks |
External actions are gated by applicable layers. DRY_RUN/ALLOW_WRITES and the tweet critic are enforced in code; the YAML firewall provides additional configurable rules for actions routed through both the supervisor and the agent core.
Supervisor Rate Limits
Per-day limits enforced by the YAML firewall to prevent runaway autonomous actions:
| Action | Daily Limit |
|---|---|
| Write content | 2/day |
| Draft tweets | 3/day |
| Draft community responses | 5/day |
| Generate feedback | 2/day |
| Rebuild site | 3/day |
Eval Gates (Post-Production)
Quality thresholds checked after content is produced. Failures trigger rollback:
| Gate | Threshold | On Failure |
|---|---|---|
| Content | ≥ 3 citations, ≥ 500 words, 0 unverified claims, Sources section required | Quarantine (hidden from site) |
| Tweet | ≤ 280 chars, critic must approve, max 3 rewrite attempts | Discard (never posted) |
| Feedback | Must have repro steps and proposed fix | Held in draft |
Failure Categories and Retry Strategy
| Failure Type | Example | Strategy |
|---|---|---|
| Transient API | 429 rate limit, 502 gateway | Exponential backoff, 3 retries with jitter |
| Auth failure | 401 expired token | Fail fast, log to ledger, surface to operator |
| Content quality | Publish gate rejects letter | Regen loop: up to N attempts with gate feedback injected into prompt |
| Tweet quality | Critic rejects draft | Rewrite loop: up to 3 rewrites with critic feedback |
| Doc fetch | Page 404 or changed | Skip page, log changed SHA256, continue ingest |
| LLM refusal | Claude declines generation | Log refusal reason, mark run as failed, no retry |
Rollback Criteria
- Ledger chain break: If
verify-ledgerreports breaks, the site build includes a red "BROKEN" badge. Deployment proceeds but the break is visible to reviewers. - Publish gate failure:
submitcommand will not deploy if the letter fails gate checks after max regen attempts. The previous deployed version remains live. - Tweet rejection: If the critic agent rejects a tweet 3 times, it is logged as "skipped" and never posted. No partial posts.
- Failed run: Every failed run is logged to the ledger with
success=0. Failed runs are shown on the scorecard with timestamps for post-mortem.
Eval and Observability
- Hash-chained ledger: Key commands (content generation, experiments, feedback, tweets, agent cycles) produce a
RunEntrywith inputs, tool calls, sources, outputs, and SHA256 hash linking to the previous entry. Tamper detection is automatic. - Citation verification: Content verifier HEAD-checks every cited URL, matches quoted snippets against cached doc hashes, and validates code snippet syntax.
- Scorecard metrics: Success rate, word count, citation count, experiment outcomes, and failure log are computed live from the database on every site build.
- Staged rollout:
build-siterenders locally for inspection.deployis a separate, explicit command. Thesubmitpipeline gates deployment on publish-gate pass.
Post-Cycle Enforcement
After every autonomous agent cycle, the following actions run in code, not prompt — the agent cannot skip them:
| Action | Condition | Contract |
|---|---|---|
| Dev.to stats sync | conditional(has_devto) | Only runs when DEVTO_API_KEY is configured. Pulls views, reactions, comments for all published articles back to Turso. Skipped silently when no key is set. |
| Lesson recording warning | always | If the agent did not call record_lesson during the cycle, a warning is logged. The cycle still succeeds — but the gap is visible in the ledger. |
| Site rebuild | always | Runs via build-site in the weekly CI workflow after the agent cycle completes. |
| Ledger verification | always | Runs via verify-ledger in CI. If the hash chain is broken, the site shows a red badge. |
| Memory pruning | always | Removes duplicates, old low-confidence lessons, and excess per-key entries. Recent lessons (last 90 days) are never pruned by the per-key cap. |
This is a deliberate contract: post_cycle_devto_sync = conditional(has_devto). The agent decides what to create; the code decides what happens after.
Where the Receipts Are
- /content: Posts have a Sources section with cited doc URLs. SHA256 hashes shown when available.
- /experiments: Every experiment has hypothesis, metric, and results.
- /feedback: Feedback items include repro steps and evidence links where available.
Commands
| Command | Description |
|---|---|
ingest-docs | Download RC docs, fetch .md mirrors, build search index |
write-content --topic "..." --type tutorial | Generate content with citations and verification |
run-experiment --name programmatic-seo | Start a growth experiment |
generate-feedback --count 3 | Generate product feedback from doc analysis |
tweet --topic "..." | Draft tweets (DRY_RUN gated) |
scan-github | Scan RC repos for issues, draft responses |
scan-reddit | Scan subreddits, draft responses |
analyze-docs | Documentation quality analysis |
repro-test | API/MCP repro scenarios |
weekly-report | Weekly activity summary |
build-site | Build static site |
deploy --repo owner/name | Deploy to GitHub Pages |
chat | Interactive doc-grounded chat |
serve | HTTP API server |
mcp-serve | MCP server for other agents |
auto --interval 6h | Scheduled task loop (content, experiments, feedback, site build) |
supervise | Run supervisor cycle (signal-driven OODA loop) |
supervise --daemon --interval 21600 | Continuous supervisor (6-hour cycles) |
agent --goal "..." | Autonomous agent with a specific goal |
scan-github --limit 10 | Scan 6 RC repos for issues, draft responses |
scan-reddit --limit 10 | Scan 6 subreddits, draft responses |
publish-devto | Publish content to Dev.to |
devto-stats | Sync Dev.to engagement stats back to DB |
prune-memory | Prune stale/duplicate agent memory entries |
verify-ledger | Verify hash chain integrity |
publish-gate | Run publish gate checks on content |
submit | Full submit pipeline: gate check → build → deploy |
deploy | Deploy to GitHub Pages |
skills | List all Claude Code skills |
demo-run | Full pipeline end-to-end |
Reproduce a Post
revcat-advocate write-content --topic "Charts API for Agents" --type tutorial
# Output: site_output/content/charts-api-for-agents/index.md
# Includes: outline, citations, code snippets, verification results
Reproduce an Experiment
revcat-advocate run-experiment --name programmatic-seo
# Output: SEO pages in site_output/content/
# DB record in growth_experiments table
Architecture
RevenueCat Docs (LLM Index + .md mirrors)
-> Hybrid RAG (BM25 + ChromaDB vectors + Contextual AI reranker)
-> Content Engine (Claude + citation verification)
-> Growth Engine (experiments + SEO)
-> Feedback Engine (doc analysis)
-> Social (Dev.to + Twitter + GitHub/Reddit scanning)
-> Supervisor (signal-driven OODA loop, 6-hour cycles)
-> Signal Pipeline (5 producers: GitHub, Reddit, Dev.to, docs, schedule)
-> Thompson Sampling Bandit (10 topic categories, Beta priors)
-> Playwright MCP Browser (enrichment + form submission)
-> Action Firewall (YAML rules + rate limits + eval gates)
-> Turso (10-table cloud DB, all state)
-> Ledger (SHA256 hash chain + optional HMAC signing)
-> Agent Memory (lessons + pruning policies)
-> MCP Server (22 tools + 3 resources via FastMCP)
-> Static Site (GitHub Pages)
Claude Code Skills
Clone this repo into any project and get RevenueCat developer tools as Claude Code slash commands. These aren't wrappers. Each skill adds a new capability that combines the agent's ingested doc knowledge base with your actual codebase to solve real developer problems.
Try it
git clone https://github.com/akshan-main/revcat-agent-advocate.git
cd revcat-agent-advocate && pip install -e .
# In Claude Code, inside any project:
/review-rc # Review your RC integration against docs
/migrate # Generate migration plan from StoreKit/Stripe/Adapty
/paywall # Generate paywall UI code for your platform
/debug-webhook # Paste a webhook payload, get plain-English explanation
/rc-audit # Full integration audit with scored report
/pricing-strategy # Pricing optimization based on category benchmarks
/search-docs # Search ingested RC docs with hybrid RAG
/quiz # Product comprehension quiz on your code changes
MCP Server Integration
The agent also runs as an MCP server with 22 tools. MCP clients like Claude Desktop and Claude Code can connect and use the agent's capabilities.
Connect via stdio (local)
claude mcp add revcat-agent-advocate -- revcat-advocate mcp-serve
Connect via SSE (remote)
revcat-advocate mcp-serve --transport sse --port 8090
claude mcp add revcat-agent-advocate -t http -- http://localhost:8090/mcp
Available MCP Tools (22)
| Tool | Description |
|---|---|
search_docs | Hybrid RAG search over ingested doc pages |
ask_question | Doc-grounded Q&A with citations |
suggest_topics | Suggest content topics based on doc coverage |
generate_content | Content pipeline: outline → draft (no auto-verify) |
generate_feedback_mcp | Doc analysis → structured feedback |
run_experiment_mcp | Start a growth experiment (hypothesis + artifacts) |
verify_ledger | Hash chain integrity check |
get_agent_stats | System statistics and counts |
get_architecture | Full architecture and tech stack |
list_content | All generated content pieces |
list_experiments | Experiment registry and results |
list_feedback | Filed product feedback |
get_content_body | Full article markdown by slug |
get_experiment_details | Experiment hypothesis, inputs, results |
get_feedback_details | Feedback repro steps and evidence |
get_ledger_entries | Recent ledger entries with hashes |
get_weekly_report | Weekly activity summary |
read_source_file | Read source files in the agent's codebase (sensitive files blocked) |
list_source_files | Browse the agent's source tree |
list_skills | List available developer skills with capabilities and scopes |
run_skill | Prepare a skill's context, prompt, and scoped tools for the caller to drive |
run_skill_chain | Chain multiple skills in sequence, passing context forward |
RevenueCat MCP (upstream)
claude mcp add revenuecat -t http -- https://mcp.revenuecat.ai/mcp \
--header "Authorization: Bearer YOUR_API_KEY"