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

FlagDefaultEffect
DRY_RUNtrueNo external posts, no GitHub issues. Drafts only
ALLOW_WRITESfalseBlocks POST/PUT/DELETE to RevenueCat API
DEMO_MODEfalseUses mock API responses and local fixture data for testing

Autonomy Model

Runs AutonomouslyOperator-Gated
  • Documentation ingestion and indexing
  • Hybrid search (BM25 + semantic vectors)
  • Content drafting with citations
  • Content verification (link checks, hash matching)
  • Product feedback generation from doc analysis
  • Growth experiment execution
  • Site builds
  • Ledger recording and chain verification
  • Publishing content to the live site (DRY_RUN)
  • Posting tweets (DRY_RUN + critic gate)
  • API write operations (ALLOW_WRITES)
  • Deployment to GitHub Pages (explicit deploy command)
  • GitHub issue creation (DRY_RUN)

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.

ProducerSourceTTLWhat it detects
GitHub Issues6 RC repos (purchases-ios, android, flutter, unity, kmp, js)72hNew issues in last 72 hours
Reddit6 subreddits (iOSProgramming, androiddev, FlutterDev, etc.)48hQuality-gated: requires minimum engagement (score ≥ 3 or comments ≥ 2) AND actionable content (question, problem, comparison)
Dev.to StatsPublished articles72hEngagement spikes (1.5x+ growth) and stalled articles
Doc ChangesCached doc pages72hSHA256 changes between ingestion runs
ScheduledInternal timers48hContent 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:

  1. Issue labeled agent-task → workflow triggers immediately
  2. Task injected as a signal, claimed directly by ID — no producer ingestion, no scoring queue
  3. Supervisor decides the action (including submit_form for browser-based tasks) and executes it
  4. Ledger entry recorded
  5. 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.

CapabilityHow it works
Signal enrichmentBefore acting on a signal, the browser fetches the page content to give the agent full context
Form submissionLLM interprets page DOM + operator-provided fields → generates click/type sequences via MCP
Domain allowlist11 whitelisted domains: revenuecat.com (+ docs, www, community subdomains), github.com, dev.to, reddit.com (+ www, old), stackoverflow.com, jobs.ashbyhq.com
DRY_RUN gatingForm 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.

SourceTargetsWhat it does
GitHubpurchases-ios, purchases-android, purchases-flutter, purchases-unity, purchases-kmp, purchases-jsScans issues, drafts doc-grounded responses
RedditiOSProgramming, androiddev, FlutterDev, gamedev, IndieDev, RevenueCatScans posts mentioning subscriptions or RevenueCat, drafts helpful replies
TwitterRevenueCat developer communityDrafts 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:

PolicyRule
RecencyKeep all lessons from last 90 days regardless of confidence
Quality gateOlder lessons survive only if confidence ≥ 0.7
Per-key capMax 20 lessons per (lesson_type, key) combo — keeps the newest
DeduplicationExact 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:

LayerGateBlocks
1. ConfigDRY_RUN / ALLOW_WRITESAll external writes, API mutations, social posts
2. SafetySafetyError exceptionPOST/PUT/DELETE to RC API, write-capable MCP tools
3. Publish GateBanned phrase + citation checkDeployment if letter contains overclaims or too few citations
4. Tweet CriticProgrammatic + LLM reviewTweets 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:

ActionDaily Limit
Write content2/day
Draft tweets3/day
Draft community responses5/day
Generate feedback2/day
Rebuild site3/day

Eval Gates (Post-Production)

Quality thresholds checked after content is produced. Failures trigger rollback:

GateThresholdOn Failure
Content≥ 3 citations, ≥ 500 words, 0 unverified claims, Sources section requiredQuarantine (hidden from site)
Tweet≤ 280 chars, critic must approve, max 3 rewrite attemptsDiscard (never posted)
FeedbackMust have repro steps and proposed fixHeld in draft

Failure Categories and Retry Strategy

Failure TypeExampleStrategy
Transient API429 rate limit, 502 gatewayExponential backoff, 3 retries with jitter
Auth failure401 expired tokenFail fast, log to ledger, surface to operator
Content qualityPublish gate rejects letterRegen loop: up to N attempts with gate feedback injected into prompt
Tweet qualityCritic rejects draftRewrite loop: up to 3 rewrites with critic feedback
Doc fetchPage 404 or changedSkip page, log changed SHA256, continue ingest
LLM refusalClaude declines generationLog refusal reason, mark run as failed, no retry

Rollback Criteria

  • Ledger chain break: If verify-ledger reports breaks, the site build includes a red "BROKEN" badge. Deployment proceeds but the break is visible to reviewers.
  • Publish gate failure: submit command 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 RunEntry with 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-site renders locally for inspection. deploy is a separate, explicit command. The submit pipeline 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:

ActionConditionContract
Dev.to stats syncconditional(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 warningalwaysIf 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 rebuildalwaysRuns via build-site in the weekly CI workflow after the agent cycle completes.
Ledger verificationalwaysRuns via verify-ledger in CI. If the hash chain is broken, the site shows a red badge.
Memory pruningalwaysRemoves 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

CommandDescription
ingest-docsDownload RC docs, fetch .md mirrors, build search index
write-content --topic "..." --type tutorialGenerate content with citations and verification
run-experiment --name programmatic-seoStart a growth experiment
generate-feedback --count 3Generate product feedback from doc analysis
tweet --topic "..."Draft tweets (DRY_RUN gated)
scan-githubScan RC repos for issues, draft responses
scan-redditScan subreddits, draft responses
analyze-docsDocumentation quality analysis
repro-testAPI/MCP repro scenarios
weekly-reportWeekly activity summary
build-siteBuild static site
deploy --repo owner/nameDeploy to GitHub Pages
chatInteractive doc-grounded chat
serveHTTP API server
mcp-serveMCP server for other agents
auto --interval 6hScheduled task loop (content, experiments, feedback, site build)
superviseRun supervisor cycle (signal-driven OODA loop)
supervise --daemon --interval 21600Continuous supervisor (6-hour cycles)
agent --goal "..."Autonomous agent with a specific goal
scan-github --limit 10Scan 6 RC repos for issues, draft responses
scan-reddit --limit 10Scan 6 subreddits, draft responses
publish-devtoPublish content to Dev.to
devto-statsSync Dev.to engagement stats back to DB
prune-memoryPrune stale/duplicate agent memory entries
verify-ledgerVerify hash chain integrity
publish-gateRun publish gate checks on content
submitFull submit pipeline: gate check → build → deploy
deployDeploy to GitHub Pages
skillsList all Claude Code skills
demo-runFull 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)

ToolDescription
search_docsHybrid RAG search over ingested doc pages
ask_questionDoc-grounded Q&A with citations
suggest_topicsSuggest content topics based on doc coverage
generate_contentContent pipeline: outline → draft (no auto-verify)
generate_feedback_mcpDoc analysis → structured feedback
run_experiment_mcpStart a growth experiment (hypothesis + artifacts)
verify_ledgerHash chain integrity check
get_agent_statsSystem statistics and counts
get_architectureFull architecture and tech stack
list_contentAll generated content pieces
list_experimentsExperiment registry and results
list_feedbackFiled product feedback
get_content_bodyFull article markdown by slug
get_experiment_detailsExperiment hypothesis, inputs, results
get_feedback_detailsFeedback repro steps and evidence
get_ledger_entriesRecent ledger entries with hashes
get_weekly_reportWeekly activity summary
read_source_fileRead source files in the agent's codebase (sensitive files blocked)
list_source_filesBrowse the agent's source tree
list_skillsList available developer skills with capabilities and scopes
run_skillPrepare a skill's context, prompt, and scoped tools for the caller to drive
run_skill_chainChain 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"