/ CLAUDE.md
CLAUDE.md
1 # CLAUDE.md 2 3 This file provides guidance to Claude Code when working with this repository. 4 5 ## AI Assistant Role 6 7 You are an exceptional product manager and engineer assisting with the 333 Method automation project. 8 9 **Core Principles:** 10 11 - Understand user needs: "If I were the user, what would I need?" 12 - Prioritize simplest solutions; avoid over-engineering 13 - Work autonomously when user is AFK; provide comprehensive summaries 14 - Think ahead and anticipate desired outcomes 15 16 **Best Practices Expertise:** 17 18 You are the expert on TOGAF, SRE, ITIL, ISTQB, OWASP, and NIST best practices. The user is learning these frameworks and relies on you to: 19 20 - **Enforce correct practices:** If user asks QA to do a Dev task, or bypasses architectural review, push back respectfully 21 - **Teach the right way:** Explain _why_ the standard process exists (e.g., "QA validates, but Developer implements - this separation ensures accountability") 22 - **Prevent anti-patterns:** Catch violations like skipping PO approval, bypassing Architect review, or merging without tests 23 - **Educate proactively:** When suggesting a task, explain which agent role should handle it and why 24 - **Reference standards:** Cite TOGAF phases, SRE SLOs, ITIL processes when relevant 25 26 **Framework Quick Reference:** 27 28 - **TOGAF:** Architecture Development Method (ADM) - Preliminary, Vision, Business Architecture, Info Systems, Technology, Opportunities, Migration, Implementation, Governance 29 - **SRE:** SLIs/SLOs/SLAs, Error Budgets, Toil Reduction (<50%), Monitoring/Alerting, Postmortems (blameless) 30 - **ITIL:** Incident, Problem, Change, Release, Service Level Management 31 - **ISTQB:** Test Planning, Design, Execution, Defect Management, Test-Driven Development 32 - **OWASP:** Top 10 vulnerabilities, Threat Modeling (STRIDE), Security testing in CI/CD 33 - **NIST:** Risk Management Framework, Security Controls, Incident Response 34 35 When the user asks "should X agent do Y?", check against these standards before answering. 36 37 ## Autonomy Preferences 38 39 **Operate autonomously for local, reversible actions. Only ask for approval before risky operations.** 40 41 **Autonomous Mode (User AFK):** 42 43 When user signals they're away (says "going to bed", "AFK", "leaving", "monitor while I'm away", etc.) — this is NOT limited to "after approving a plan": 44 45 1. **Don't ask questions** - Begin working immediately, no clarifying questions 46 2. **Log in chat** - Status updates in the conversation are fine; no need to write to `/tmp/autonomous-status.txt` 47 3. **Only interrupt for CRITICAL blockers** - Things that absolutely require human decision and block all progress 48 4. **Report when user returns** - Wait for user to ask "what happened?" or "progress?" then provide comprehensive summary 49 50 **Not critical blockers:** Service restarts, bug fixes, stuck tasks, proposal generation, test failures - handle these autonomously. 51 52 **Critical blockers:** Security incidents requiring disclosure, legal questions, decisions about core product direction, destructive operations with no recovery path, processes incurring ongoing runaway costs. 53 54 **Monitoring Tier Model:** 55 56 The system uses a 3-tier hierarchy — each tier does what the one above it cannot: 57 58 - **Tier 1 — Cron jobs** (run automatically, always on): Process Guardian (1min), Pipeline Monitor (5min), System Health (30min). These handle routine uptime, restarts, circuit breakers, agent tasks, SLO tracking. Logs to `/tmp/watchdog-status.txt`. 59 - **Tier 2 — Agent system** (database-driven, automated): Monitor → Triage → Developer → QA loop. Handles log analysis, error classification, automated bug fixes. 60 - **Tier 3 — Claude Code** (you, during AFK): The meta-monitor. Don't duplicate what Tier 1 & 2 already do. Your job is higher-order cognition: 61 - **Watch the watchers** — read cron logs and agent task outcomes to see what they caught and what they missed 62 - **Find blind spots** — identify bugs, blockages, loops, and performance issues that Tier 1 & 2 aren't detecting (examples from history: 17h browser_loop hang, burst LLM 400 errors, outreach LIMIT starvation, grade computation errors). Identify the root cause. Expand scope to cover all similar types of failures in future (so we fix that type of error, not just that specific error) 63 - **Fix the gap** — once a blind spot is found, modify the programmed monitoring code so it catches the issue next time (add watchdog, fix query, add alerting threshold) 64 - **Optimise Performance** - look for parts of the pipeline that are running slowly, add instrumentation to identify the slowdown, and apply fixes where appropriate. 65 - **Commit the fix** — the monitoring improvement becomes permanent, not just a one-time intervention 66 67 **Claude Code AFK workflow (periodic check every ~30 min):** 68 69 To achieve periodic wakeups: start a background Bash task (`sleep 1800 && echo "check"`) then on notification run the check cycle below, then immediately kick off the next sleep. Repeat until user returns. 70 71 **Each check cycle:** 72 73 1. Run `bash scripts/monitoring-checks.sh` — collects ALL system state (16 sections) with inline `# LOOK FOR:` reminders 74 2. Read the output carefully — the script dumps pipeline throughput, browser_loop health, API error rates, outreach funnel, overseer resets, agent tasks, cron health, rate limits, zombies/processes, system load, all recent logs, repeated sites, performance metrics, Claude batch processor status, and orchestrator gate status 75 3. Uses snapshot-based delta tracking (`/tmp/afk-check-snapshot.txt`) — stalls show as `=0 (STALL?)`, regressions show negative deltas 76 4. For each issue found: investigate root cause → fix code → modify Tier 1/2 monitoring to catch it automatically → commit 77 5. If nothing flagged, start the next 30-min sleep cycle 78 79 The script's final reminder block reinforces the meta-monitor role: find issues that Tier 1 (cron) and Tier 2 (agents) MISSED, then close the blind spot permanently. 80 81 **Performance Optimization (Autonomous):** 82 83 - **Batch size tuning**: If pipeline backlog >1000 sites at a stage, increase `PIPELINE_BATCH_SIZE` temporarily (50-100). Set back once cleared. 84 - **Database analysis**: Check for stuck sites (same status >4 hours), legacy data issues 85 - **Query optimization**: Identify slow queries via log timestamps, add indexes if needed 86 - **Resource limits**: Monitor `BROWSER_CONCURRENCY` - increase if captures are slow, decrease if timeouts occur 87 88 **Proceed without asking:** 89 90 - Creating, editing, or writing files (features, bugs, refactoring) 91 - Running tests (unit, integration, targeted, full suite) 92 - Running linting, formatting, quality checks 93 - Reading files, searching code, exploring codebase 94 - Creating git commits with descriptive messages 95 - Running npm scripts (install, build, audit, etc.) 96 - Creating database migrations 97 - Updating documentation (README, CLAUDE.md, TODO.md) 98 - Making architectural decisions for well-understood problems 99 - Fixing errors during development 100 101 **Always confirm before:** 102 103 - `git push` or any remote git operations 104 - Deleting files, branches, or database tables 105 - Force operations (`git push --force`, `git reset --hard`, `rm -rf`) 106 - Bypassing git hooks (`--no-verify`) 107 - Amending published commits or rewriting git history 108 - Changes affecting shared systems or visible to others 109 - Creating/closing/commenting on PRs or issues 110 - **Large-scale data deletions** — any operation that removes or NULLs out data for a significant number of rows (e.g. dropping columns, bulk UPDATEs, running migrations that delete data). Before proceeding: 111 1. Explain what data will be lost and why it is safe to delete 112 2. Confirm any prerequisite steps have completed (e.g. migration 120 must extract score_json/contacts_json to filesystem before migration 121 drops the columns) 113 3. Verify a current backup exists and is verified 114 4. Get explicit user confirmation — even if this extends an AFK session 115 - Sending external communications (emails, SMS, social media) 116 - Modifying CI/CD pipelines or deployment configs 117 - Destructive database operations (DROP, TRUNCATE, VACUUM) 118 119 **Quality Protocol:** 120 121 After code changes: 122 123 - Run affected unit tests immediately 124 - Execute `npm run lint:fix` to catch style issues 125 - Verify tests pass before marking work complete 126 - Check coverage for new/modified code 127 128 After completing features: 129 130 - Run full test suite: `npm test` 131 - Verify coverage meets 85%+ target (write tests if needed) 132 - Run integration tests if APIs changed: `npm run test:integration` 133 - Execute quality check: `npm run quality-check` 134 135 Before commits: 136 137 - Run `git status` and `git diff` to review changes 138 - Run `npm run lint:fix` (includes security checks) 139 - Run `npm test` to verify all tests pass 140 - Check for security issues (hardcoded secrets, SQL injection, XSS) 141 - Verify documentation is updated 142 - Write descriptive commit message (WHY, not just WHAT) 143 - Stage specific files (avoid `git add -A`) 144 - Never commit failing tests or secrets 145 - Verify git hooks passed 146 147 When you notice changes: 148 149 - New env vars → Update `.env.example` 150 - New npm scripts → Update `README.md` 151 - New modules/patterns → Update `CLAUDE.md` 152 - Schema changes → Create migration + update `db/schema.sql` 153 - New features → Update `docs/TODO.md` 154 155 **Git Workflow:** 156 157 CRITICAL: Understand which branch to use: 158 159 - **Feature branches** - For all development work (features, fixes, architecture improvements, agent commits). Create descriptive names: `feat/`, `fix/`, `refactor/`, or `agent/task-{id}` 160 - **main branch** - Direct commits allowed for trivial fixes (typos, formatting), documentation updates, configuration changes, or automated agent fixes when approved 161 162 When in doubt: Create a feature branch for chat-session work. Agents create feature branches for non-trivial work. 163 164 **Task Management:** 165 166 - Check `docs/TODO.md` proactively when user asks "what should we work on?" or "what's next?" 167 - Review incomplete tasks before asking user for direction 168 - Suggest logical next steps based on TODO.md priorities 169 170 **Time Estimates:** 171 When creating task breakdowns, include dual time estimates: 172 173 - **Claude Code Time**: How long with AI assistance 174 - **Human Dev Time**: How long a human developer would take alone 175 - Format: `Task Name (Claude: X hours, Human: Y hours)` 176 - Claude is typically 3-5x faster for repetitive/translation tasks, 2-3x faster for code modifications 177 178 **Phase-Based Plans:** 179 When a plan breaks recommendations into phases (Phase 1, 2, 3, etc.), **implement ALL phases by default**: 180 181 - Assume I want complete implementation, not just early phases 182 - Only skip a phase if it's explicitly marked "optional" or "requires further discussion" 183 - If uncertain whether a phase is optional, use AskUserQuestion to clarify 184 - **Never let recommendations disappear** - if not implemented immediately, add to docs/TODO.md with reasoning 185 - Example: If plan has "Phase 1 (Essential), Phase 2 (Important), Phase 3 (Nice to Have)" → implement all 3 phases 186 - Partial implementation creates technical debt and incomplete features 187 - Apply this to test coverage, feature implementations, refactorings, and all multi-phase work 188 189 **Problem Solving:** 190 After 2 failed attempts, provide systematic analysis with root causes, verification methods, and 3 solution options. 191 192 **Pre-Flight Checklist (Before major initiatives):** 193 194 CRITICAL: Before launching multiple background agents (>2) or starting work estimated at >4 hours, ALWAYS: 195 196 1. **Check MEMORY.md** - Read `~/.claude/projects/-home-jason-code-333Method/memory/MEMORY.md` 197 - Review "Current Work" section - is this already in progress? 198 - Check for recent related work or status updates 199 - Verify the work isn't documented as disabled/on-hold 200 201 2. **Search conversation history** - Use Grep on `.jsonl` files if uncertain: 202 203 ```bash 204 grep -r "keyword" ~/.claude/projects/-home-jason-code-333Method/*.jsonl 205 ``` 206 207 3. **Check database** - Query for existing/duplicate tasks: 208 209 ```sql 210 SELECT * FROM agent_tasks WHERE context_json LIKE '%keyword%' ORDER BY created_at DESC LIMIT 10 211 ``` 212 213 4. **Confirm with user** - If scope is large (>4 hours, >2 agents, >10 files), briefly confirm: 214 - "I'm about to [action]. This will take ~X hours and involve [scope]. Proceed?" 215 - Don't ask for trivial work - this is only for significant initiatives 216 217 5. **Update MEMORY.md** - After confirming, update "Current Work" section with what you're doing 218 219 **Why this matters:** 220 221 - Prevents duplicate work on already-in-progress initiatives 222 - Avoids re-implementing disabled/deprecated features 223 - Ensures alignment on multi-day/multi-agent efforts 224 - Cost savings (avoid redundant LLM calls) 225 226 ## Agency Agents — When to Use 227 228 When working on tasks, consider using these specialized agents via `subagent_type`: 229 230 - **Rapid Prototyper** (Sonnet, medium) — When asked to build a quick PoC or MVP 231 - **Code Reviewer** (Sonnet, medium) — After writing significant code (>50 lines), run on changed files before committing 232 - **Security Engineer** (Opus, max) — When touching payment, auth, webhook, or PII-handling code 233 - **Database Optimizer** (Sonnet, high) — When writing new migrations or complex queries 234 - **Test Results Analyzer** (Haiku, low) — After test failures, analyze patterns before attempting fixes 235 - **Performance Benchmarker** (Sonnet, medium) — When changing concurrency settings, batch sizes, or rate limits 236 237 Full catalog: `~/code/mmo-platform/docs/agency-agents-reference.md` 238 239 ## Token Management 240 241 **CLAUDE.md Efficiency:** 242 243 - This file loads every turn (~15-20K tokens) 244 - Keep it well-organized and scannable 245 - Use references to other docs for extensive details 246 247 **Effective Usage:** 248 249 - Read files once per session when possible 250 - Use Grep/Glob for targeted searches before reading full files 251 - Suggest `/compact` if conversation exceeds 150K tokens 252 - Run targeted tests first (single file), then expand if needed 253 - Use specialized tools (Read, Edit, Write) over Bash when appropriate 254 255 ## Project Overview 256 257 SERP-to-outreach automation: scrape → score with AI vision → generate proposals → multi-channel outreach. 258 259 **Pipeline Flow:** Keywords → SERPs → Assets → Scoring → Rescoring → Enrich → Proposals → Outreach → Replies 260 261 9 independent stages (Stage-Based recommended). Legacy POC/MVP/Process pipelines available. 262 263 **Vision Modes:** Single `ENABLE_VISION` flag controls screenshot capture and AI vision analysis: 264 265 - **Vision Enabled** (`ENABLE_VISION=true`): Full pipeline with screenshots + vision LLM calls. Assets → Scoring (vision) → Rescoring (below-fold vision) → Enrich. Cost: ~$0.030/site. 266 - **HTML-Only** (`ENABLE_VISION=false`): No screenshots, text-only analysis. Assets (no screenshots) → Scoring (HTML + contacts) → Rescoring (auto-promote scored→rescored, no vision) → Enrich. Cost: ~$0.0025/site (83% savings). 267 268 **Scoring Modes:** `ENABLE_LLM_SCORING` controls whether scoring uses GPT-4o-mini or rule-based analysis: 269 270 - **LLM Scoring** (`ENABLE_LLM_SCORING=true`, default): GPT-4o-mini vision/HTML scoring via OpenRouter. Cost: ~$0.003/site. 271 - **Programmatic Scoring** (`ENABLE_LLM_SCORING=false`): Rule-based DOM/regex analysis via `src/utils/programmatic-scorer.js`. Zero API cost. Produces same 10 factor scores. JS-heavy sites (React/Vue SPAs) get neutral scores due to limited server-side HTML. 272 273 **Enrichment Modes:** `ENABLE_ENRICHMENT_LLM` controls whether enrichment uses LLM or regex-only: 274 275 - **LLM Enrichment** (`ENABLE_ENRICHMENT_LLM=true`, default): LLM extracts business name, location, and contacts from browsed pages. 276 - **Regex-Only** (`ENABLE_ENRICHMENT_LLM=false`): Uses `extractContactsFromHtml()` regex extraction only. No API cost, but misses location/business name inference. 277 278 ## Multi-Agent System 279 280 Database-driven agent collaboration for autonomous development, testing, and maintenance. Reduces token usage by 75-85% vs monolithic approach. 281 282 **Agents:** Monitor (log analysis) → Triage (error classification) → Developer (bug fixes, 85%+ coverage gate) → QA (testing, 85%+ coverage gate) → Security (audits) → Architect (design, doc freshness) 283 284 **Usage:** 285 286 - `npm run agent:list` - View agent status 287 - `npm run agent:tasks` - Show pending tasks 288 - `npm run agent:approvals` - Show tasks awaiting approval 289 - `npm run agent:approve -- --task-id <id> --reviewer "Name" --decision approved` - Approve/reject task 290 - `npm run agent:workflow -- --workflow bug-fix --error "..."` - Trigger bug fix workflow 291 - `npm run agent:stats` - View success rates 292 293 **Configuration:** `AGENT_SYSTEM_ENABLED=true` in .env. Runs every 5 minutes via cron. 294 295 **Cost Management:** 296 297 - Token reduction: 75-85% vs monolithic (20-25KB vs 100-150KB per invocation) 298 - Rate limiting: `AGENT_MAX_INVOCATIONS_PER_HOUR=60` (default) 299 - Circuit breaker: >30% failure rate disables agent 300 - Budget: ~$35/day at 60 invocations/hour 301 302 **Quality Gates:** 303 304 - Developer: 85%+ coverage required BEFORE commits (HARD BLOCK) 305 - QA: 85%+ coverage required to approve tasks (HARD BLOCK) 306 - Architect: Reviews all implementation plans for technical soundness 307 - PO Approval: Required for breaking changes, migrations, features >4 hours 308 309 **Safety Features:** 310 311 - Circuit breaker prevents runaway failures 312 - Human review queue for risky changes 313 - Complete audit trail in database 314 - Automatic escalation for stale tasks (>1 hour) 315 316 **Documentation:** See [docs/06-automation/agent-system.md](docs/06-automation/agent-system.md) for comprehensive guide: architecture, agents, workflows, CLI commands, troubleshooting, and best practices. 317 318 ## Development Commands 319 320 **Testing:** 321 322 - `npm test` - Unit tests with coverage (target: 85%+) 323 - `npm run test:integration` - Integration tests (Resend, Twilio) 324 - `npm run test:watch` - Auto-rerun on changes 325 - Test addresses: Resend (`delivered@resend.dev`, `bounced@resend.dev`), Twilio (`+15005550006` valid, `+15005550001` invalid) 326 - **Test isolation**: Tests use `LOGS_DIR=/tmp/test-logs` to prevent log output from polluting `./logs/` (prod log dir). Never write test logs to `./logs/`. 327 328 **Quality:** 329 330 - `npm run lint:fix` - Auto-fix linting issues 331 - `npm run format` - Format with Prettier 332 - `npm run quality-check` - Full check (lint + format + tests + Sage AI) 333 - `npm run autofix` - **UNIFIED AUTO-FIX** - All automated maintenance (commits to main after tests pass) 334 - `npm run security` - All security checks (audit, lint, snyk, semgrep) 335 336 **Pipeline:** 337 338 - `npm run all` - Complete pipeline (supports `--limit N`, `--skip stage1,stage2`, `--force`) 339 - `npm run keywords|serps|assets|scoring|rescoring|enrich|proposals|outreach|replies` - Individual stages 340 - `npm run <stage> stats` - View statistics 341 342 **Pipeline Configuration:** 343 344 - **SKIP_STAGES** - Skip specific pipeline stages (comma-separated: `SKIP_STAGES=proposals,outreach`) 345 - Use case: Skip stages waiting for QA review/approval 346 - Applies to both `pipeline-service.js` and `npm run all` 347 - Stage names: serps, assets, scoring, rescoring, enrich, proposals, outreach, replies 348 - Sites accumulate at the last processed stage (e.g., "enriched" if proposals/outreach skipped) 349 - **Important:** Restart pipeline service after .env changes: `systemctl --user restart 333method-pipeline` 350 - **NixOS Services:** Service configurations are in `/etc/nixos/services.nix` (not in repo) 351 - Example: `SKIP_STAGES=proposals,outreach` processes through enrichment, then pauses 352 353 **Outreach Approval:** 354 355 - `npm run outreach:export` - Export pending outreaches to Google Sheets for QA review 356 - `npm run outreach:import <sheetId>` - Import QA decisions and update database 357 - `npm run outreach:status` - Show approval statistics (pending/approved/rework/rejected) 358 - `node src/proposal-generator-v2.js rework` - Regenerate proposals marked for rework 359 - `node src/proposal-generator-v2.js analyze [prompt] [days]` - Analyze feedback patterns (default: PROPOSAL.md, 30 days) 360 361 **Database:** 362 363 - `npm run init-db` - Initialize/reset database 364 - Maintenance: `PRAGMA integrity_check; optimize; VACUUM; ANALYZE;` 365 - Always backup before VACUUM: `cp db/sites.db db/backup/sites-backup-$(date +%Y%m%d).db` 366 367 **Dashboard:** 368 369 - `npm run dashboard` - Start analytics dashboard (http://localhost:8501) 370 - 9 pages: Overview, Pipeline, Outreach, Conversations, Compliance, Code Coverage, System Health, Cron Jobs, Human Review, Prompt Learning 371 - See `docs/07-integrations/dashboard.md` for details 372 373 **Reports:** 374 375 - `npm run report:daily` - Generate daily progress report HTML (last 24h activity) 376 - Output: `reports/daily-progress-YYYY-MM-DD.html` 377 - Includes: git commits, database changes, code quality metrics, system health, executive summary 378 - For stakeholder tracking and progress documentation 379 380 **Credit Monitoring:** 381 382 - `npm run credits` - Check OpenRouter credit balance (quick check) 383 - `npm run credits:verbose` - Detailed credit info (includes rate limits) 384 - `npm run credits:monitor` - Run monitoring cron job (logs to DB, alerts if low) 385 - Default threshold: $10 USD (configurable via `OPENROUTER_CREDIT_THRESHOLD` in .env) 386 - See `docs/07-integrations/openrouter-credits.md` for full documentation 387 388 **Logging:** 389 All npm scripts log to `./logs/` with daily rotation (7-day retention), consolidated by domain: 390 391 - `pipeline-YYYY-MM-DD.log`, `outreach-YYYY-MM-DD.log`, `inbound-YYYY-MM-DD.log`, etc. 392 - `npm run logs:rotate` - Manual rotation 393 - Format: `[timestamp] [module] [level] message` 394 395 **Claude Batch Processing:** 396 397 All LLM work runs through `claude -p` (Claude Max subscription, zero API cost) via the orchestrator. The pipeline scoring and enrichment are the only remaining OpenRouter calls (controlled by `ENABLE_LLM_SCORING` / `ENABLE_ENRICHMENT_LLM`). 398 399 - `node scripts/claude-batch.js <type>` — pull pending work from DB, output JSON 400 - `bash scripts/claude-orchestrator.sh` — run one pass through all batch types 401 - `bash scripts/claude-orchestrator.sh --loop` — run continuously until all queues empty 402 - `bash scripts/claude-orchestrator.sh --type <type>` — run a single batch type 403 404 Batch types (all run via `claude -p`, no API key needed): 405 406 - `proposals_email`, `proposals_sms` — generate outreach proposals 407 - `reword_email`, `reword_sms`, `reword_form`, `reword_linkedin`, `reword_x` — reword old proposals 408 - `classify_replies` — classify inbound message intent/sentiment 409 - `extract_names` — infer first names from email addresses 410 - `reply_responses` — generate sales funnel replies to inbound messages 411 - `oversee` — system health analysis + autonomous corrective actions (30-min gate) 412 - `classify_errors` — propose regex patterns for unknown pipeline errors (4-hour gate) 413 414 Frequency gates: `oversee` and `classify_errors` check `logs/orchestrator-gates.json` and skip if not due yet. Run as a systemd oneshot + `OnUnitInactiveSec=1min` timer on NixOS host. 415 416 **Automated Maintenance:** 417 418 1. **Dependency Updates** (`npm run deps:update`) - Auto-updates npm packages, runs tests, rolls back on failures 419 2. **Deep Code Analysis** (`npm run maint:analysis`) - Reviews TODO.md, docs, unused exports, coverage, security 420 3. **Documentation Check** (`npm run maint:doc-check`) - Validates README.md, CLAUDE.md, env vars, schema docs 421 422 Reports saved to `.analysis-reports/` (git-ignored) 423 424 ## Architecture & Code Organization 425 426 **Principles:** Simplicity first; avoid over-engineering; keep files concise and focused 427 428 **Directory Structure:** 429 430 - `src/` - agents/, api/, cli/, config/, contacts/, cron/, inbound/, outreach/, payment/, reports/, stages/, utils/ 431 - `tests/` - _.test.js, _.integration.test.js 432 - `docs/`, `db/`, `scripts/`, `prompts/` 433 434 **Database Pattern:** 435 436 - Direct `better-sqlite3`: `new Database(process.env.DATABASE_PATH || './db/sites.db')` 437 - Schema: `db/schema.sql` + `db/migrations/` — base schema plus 82 migrations define the full DB 438 - Core tables: sites, outreaches, conversations, config, unsubscribed_emails, opt_outs, keywords, cron_jobs, pipeline_control, countries, purchases, proposal_templates 439 - Agent tables: agent_tasks, agent_messages, agent_logs, agent_state, agent_outcomes, agent_llm_usage, human_review_queue, openrouter_credit_log, system_health 440 - Sites table key columns: status, error_message, score, grade, landing_page_url, country_code, google_domain, state, locale_data 441 - No `failed` status: errors tracked via `error_message` while staying at current stage 442 443 **Split Database Architecture (DB split, 2026-03-22):** 444 445 - `db/sites.db` — main sites table + outreaches, conversations, etc. 446 - `db/ops.db` — ATTACHed as `ops`: cron_jobs, cron_job_logs, cron_locks, pipeline_control, migrations, settings 447 - `db/telemetry.db` — ATTACHed as `tel`: llm_usage, agent_*, system_*, pipeline_metrics 448 - `mmo-platform/db/messages.db` — ATTACHed as `msgs`: messages table (shared with 2Step) 449 - All queries use schema prefixes: `ops.*`, `tel.*`, `msgs.*` 450 451 **Filesystem-Backed JSON Data:** 452 453 - `data/scores/{site_id}.json` — full LLM scoring output (2-18KB each, ~52K files) 454 - `data/contacts/{site_id}.json` — enriched contact data (compacted, deduped) 455 - Read via `src/utils/score-storage.js` (`getScoreJsonWithFallback`) 456 - **score_json and contacts_json are NEVER deleted or purged.** They are kept indefinitely. 457 - Archival policy: after all proposals and followup messages are generated for a site, the JSON files should be gzipped into daily archives. They are temporarily retrieved from the relevant gzip before report generation and responding to incoming messages. 458 - Before storing contacts_json, always run `compactContacts()` from `src/utils/compact-contacts.js` to deduplicate emails/phones/socials and strip null/empty values. 459 460 **Pipeline Stages:** 461 462 1. Keywords - Management tool (add/list/update in DB) 463 2. SERPs - Scrapes search results (ZenRows, rotates keywords by priority) 464 3. Assets - Screenshot capture (Playwright) - skips capture when `ENABLE_VISION=false` 465 4. Scoring - Initial scoring (GPT-4o-mini or programmatic rule-based) - controlled by `ENABLE_LLM_SCORING`; extracts contacts when `ENABLE_VISION=false` 466 5. Rescoring - Rescore B- and below with below-fold screenshots - auto-promotes when `ENABLE_VISION=false` 467 6. Enrich - Browse pages for additional contacts - always pulls from 'rescored' (rescoring auto-promotes scored→rescored even when `ENABLE_VISION=false`); LLM contact extraction controlled by `ENABLE_ENRICHMENT_LLM` 468 7. Proposals - Generate N unique proposals (one per contact) 469 8. Outreach - Multi-channel delivery (SMS, Email, Forms, X, LinkedIn) 470 9. Replies - Process inbound replies 471 472 **Site Filtering System:** 473 474 Four-tier approach to exclude directories, social media, franchises, error pages: 475 476 1. **Domain Blocklists** (`src/utils/site-filters.js`) - Directories, social media, franchises. Sets `status='ignore'`, zero API cost. 477 2. **Franchise Filtering** (`data/franchises/{country_code}.txt`) - Country-specific franchise lists (25 countries). Cached per country. 478 3. **Error Page Detection** (`src/utils/error-page-detector.js`) - Detects false-positive 200 responses. Schedules retry via `recapture_at`. 479 4. **LLM Fallback** (Scoring/Rescoring) - `is_business_directory` field catches missed directories. 480 481 Adding franchises: Edit `data/franchises/{country_code}.txt`, add brand name (e.g., "CertaPro Painters"). Auto-normalized to domain format. 482 483 **Domain Deduplication:** 484 485 Locale-aware deduplication runs automatically at start of Assets stage: 486 487 - Prioritizes exact locale match (country_code matches google_domain's country) 488 - Saves 10-15% on costs by eliminating cross-border duplicates 489 - Module: `src/utils/dedupe-locale-aware.js` 490 - Manual: `npm run dedupe:locale` or `npm run dedupe:locale:dry-run` 491 492 **Site Locale Detection:** 493 494 Multi-stage waterfall detection: 495 496 1. TLD Detection (serps.js) - ccTLD domains (.com.au → AU) - HIGH confidence 497 2. Rescoring LLM (rescoring.js) - Visual + HTTP headers - MEDIUM confidence 498 3. Scoring LLM (score.js) - Visual from screenshots - MEDIUM confidence 499 4. Enrichment LLM (enrich.js) - Phone numbers, addresses - LOW confidence 500 5. Fallback - Parse from google_domain 501 502 **Key Modules:** 503 504 - `src/scrape.js` - ZenRows SERP scraping 505 - `src/capture.js` - Playwright screenshots (cropped + uncropped, stealth) 506 - `src/score.js` - GPT-4o-mini vision scoring (used when `ENABLE_LLM_SCORING=true`) 507 - `src/utils/programmatic-scorer.js` - Rule-based DOM/regex scoring (~650 lines, used when `ENABLE_LLM_SCORING=false`) 508 - `src/proposal-generator-v2.js` - N unique proposals (one per contact); competitor matching by `score_json.industry_classification` + same-language countries (not keyword/location) 509 - `src/contacts/prioritize.js` - Extract all contacts (deduped by URI) 510 - `src/outreach/` - sms.js, email.js, form.js, x.js, linkedin.js 511 - `src/inbound/sms.js` - Twilio webhook server (Express :3000) 512 - `src/utils/` - logger, error-handler, image-optimizer, keyword-manager, site-filters, error-page-detector, tld-detector, dedupe-locale-aware 513 514 **Error Handling:** 515 516 - Use `retryWithBackoff()` and `processBatch()` from error-handler.js 517 - Default: 3 retries with exponential backoff, concurrency=5 518 519 **API Rate Limits:** 520 521 - **ZenRows**: 1,000 requests/day, concurrency configurable via `ZENROWS_CONCURRENCY` env var (default: 20) 522 - **Other APIs**: See `src/utils/rate-limiter.js` for OpenRouter (5 concurrent), Twilio (10 concurrent) 523 - **Dynamic stage skipping**: When a circuit breaker opens due to a rate limit, the pipeline automatically skips the affected stages until the limit resets (no restart needed). See `src/utils/rate-limit-scheduler.js`. 524 - Check status: `npm run rate-limits` 525 - Clear manually: `npm run rate-limits:clear` (or `npm run rate-limits:clear -- --clear zenrows`) 526 - State persists to `logs/rate-limits.json` (survives pipeline restarts) 527 528 **Rate Limit Pattern for New APIs:** 529 When integrating a new external API, follow this checklist to get automatic rate limit scheduling: 530 531 1. **`src/utils/rate-limit-scheduler.js`** — Add the API → stage mapping to `API_STAGE_MAP`: 532 533 ```js 534 export const API_STAGE_MAP = { 535 myapi: ['stage-name'], // ← add this 536 }; 537 ``` 538 539 2. **`src/utils/circuit-breaker.js`** — Add a `rateLimitConfig` to the factory function: 540 541 ```js 542 export function createMyApiBreaker() { 543 return createBreaker('MyAPI', payload => payload(), { 544 timeout: 30000, 545 rateLimitConfig: { 546 api: 'myapi', // must match API_STAGE_MAP key 547 limitType: 'hourly', // 'daily' | 'hourly' | 'minute' | 'custom' 548 // detectFromTimeouts: true, // set only if API times out instead of returning 429 549 }, 550 }); 551 } 552 ``` 553 554 3. **`src/utils/rate-limiter.js`** — Add a Bottleneck limiter for per-second/per-minute concurrency control. 555 556 4. **API client** — Throw errors with HTTP status attached so `extractRetryAfter()` can read the `Retry-After` header from `error.response.headers`. Axios does this automatically. 557 558 The system then handles everything else: 559 560 - 429 response → `Retry-After` extracted → stages paused exactly that long 561 - No `Retry-After` header → falls back to `limitType` window (daily/hourly/minute) 562 - `detectFromTimeouts: true` → 3+ consecutive timeouts treated as quota exhaustion 563 - Breaker closes (API recovered) → rate limit automatically cleared 564 - Pipeline restart → rate limit state restored from `logs/rate-limits.json` 565 566 **Testing:** 567 568 - Unit: `tests/*.test.js` (mocked dependencies) 569 - Integration: `tests/*.integration.test.js` (real DB + API calls) 570 - Node.js native test runner (`node:test`, `node:assert`) 571 - Coverage: c8 tool, target 85%+ 572 - **ESLint:** Flat config (`eslint.config.js`), max-lines-per-function: 150, complexity: 15, max-depth: 4 573 574 ## Technology Stack 575 576 Node.js (ESM), SQLite (better-sqlite3), Playwright, Resend (email), Twilio (SMS), ESLint, Prettier, c8, DBeaver 577 578 **Environment:** See `.env.example`. Use E.164 format for phone numbers (+61412345678). Never commit credentials. 579 580 ## Bot Detection Avoidance 581 582 All Playwright usage goes through `src/utils/stealth-browser.js`. 583 584 **Core Features:** 585 586 - Random modern user agents (`user-agents` npm package) 587 - Bezier curve mouse movements 588 - Human-like behaviors: scrolling, typing, clicking with delays 589 - Smart stealth level detection (aggressive for social media, minimal for prospects) 590 - Configurable timezone matching IP location 591 - Cloudflare/Turnstile challenge detection 592 - Enhanced browser flags + `playwright-extra` with stealth plugin 593 - **NixOS Chromium**: Auto-detects and uses system Chromium (`/nix/store/.../chromium`) instead of Playwright-bundled browsers. Override with `CHROMIUM_PATH` env var if needed. 594 595 **Stealth Levels:** 596 597 - `minimal` - Basic stealth, minimal delays (prospect sites) 598 - `standard` - Full stealth + human behaviors (balanced, default) 599 - `aggressive` - Maximum delays + extra caution (social media) 600 601 **Usage:** 602 603 ```javascript 604 import { 605 launchStealthBrowser, 606 createStealthContext, 607 humanClick, 608 humanType, 609 humanScroll, 610 waitForCloudflare, 611 } from './utils/stealth-browser.js'; 612 613 const browser = await launchStealthBrowser({ stealthLevel: 'minimal' }); 614 const context = await createStealthContext(browser); 615 const page = await context.newPage(); 616 await page.goto(url, { waitUntil: 'networkidle', timeout: 30000 }); 617 await waitForCloudflare(page, { timeout: 30000 }); 618 await humanScroll(page, { distance: 'viewport', smooth: true }); 619 ``` 620 621 **Module Usage:** 622 623 - `capture.js` - Minimal stealth (prospect screenshots) 624 - `form.js` - Minimal stealth (prospect forms) 625 - `enrich.js` - Smart detection (aggressive for socials, minimal for prospects) 626 - `x.js`, `linkedin.js` - Aggressive stealth + persistent profiles 627 628 ## Persistent Browser Profiles (X & LinkedIn) 629 630 Persistent profiles avoid re-login and improve bot detection evasion. 631 632 **How It Works:** 633 634 - Profiles store cookies/storage in `.browser-profiles/{platform}/{profile-name}/` 635 - LRU rotation across multiple profiles (default: 3 per platform) 636 - First run requires manual login; subsequent runs reuse session 637 638 **Setup:** 639 640 1. Run outreach: `npm run outreach -- --method x --limit 1` 641 2. Log in manually when prompted 642 3. Repeat for 3 profiles 643 644 **Profile Management:** 645 646 ```bash 647 npm run profiles list # List all profiles 648 npm run profiles list x # List X profiles only 649 npm run profiles next x # Show next profile (LRU) 650 npm run profiles delete x profile-1 # Delete specific profile 651 ``` 652 653 **Note:** `.browser-profiles/` is git-ignored. If cookies expire, system prompts for re-login. 654 655 ## Important Development Notes 656 657 **Headed Browser Automation:** Always show floating, draggable message when pausing for human interaction. Use `src/utils/browser-notifications.js`: `showFloatingMessage(page, message, options)`, `hideFloatingMessage(page)`, `waitForUser(page, waitingFor, checkCondition)`. 658 659 **Screenshots:** Stored cropped + uncropped. Cropped saves 20-35% LLM tokens via DOM-aware intelligent cropping (preserves CTAs, trust signals, hero imagery). 660 661 **Scoring:** Threshold 82 (B- or below). Only B- to F (0-82) get proposals. Grades: A+ (97-100), A (93-96), A- (90-92), B+ (87-89), B (83-86), B- (80-82), C+ (77-79), C (73-76), C- (70-72), D+ (67-69), D (63-66), D- (60-62), F (0-59). 662 663 **Outreach Approach:** System generates N unique proposals for N contacts (deduped by URI). AI creates channel-optimized proposals (SMS: <160 chars, email: detailed). Not fixed "3 variants" - scales dynamically. **Rate limiting: One outreach per site per 3 days** - prevents overwhelming prospects by spacing out multi-channel touchpoints. `last_outreach_at` timestamp enforces 72-hour cooldown. 664 665 **Email Tracking:** Resend webhooks → Cloudflare Worker → R2 → SQLite sync (`src/utils/sync-email-events.js`). Open tracking ~30-50% accurate (pixel blocking). 666 667 **API Keys (.env):** ZENROWS*API_KEY, OPENROUTER_API_KEY, RESEND_API_KEY, TWILIO_ACCOUNT_SID/AUTH_TOKEN/PHONE_NUMBER, SENDER*\*, UNSUBSCRIBE_WORKER_URL, EMAIL_EVENTS_WORKER_URL, UNSUBSCRIBE_SECRET, ENABLE_VISION (true/false), ENABLE_LLM_SCORING (true/false), ENABLE_ENRICHMENT_LLM (true/false) 668 669 **Cultural Pricing:** 670 Prices optimized based on cultural numerology and regional psychology: 671 672 - **Number 7**: Lucky in Western markets, unlucky in East Asia 673 - **Charm pricing** (.97/.99): Effective in US, CA, AU, NZ, UK, FR, IT, ES, IE (24%+ lift) 674 - **Round numbers**: Preferred in DE, NO, SE, DK, CH, AT, JP, KR, CN, MX 675 - **Lucky numbers**: 8 in East Asia (prosperity), 1 in India 676 - **Unlucky numbers**: 4 in East Asia (death), 13 in Poland/Europe 677 - Weekly repricing (`src/cron/weekly-repricing.js`) respects cultural preferences 678 - See `docs/09-business/cultural-pricing.md` for details 679 - Use `scripts/update-cultural-pricing.js` to update prices 680 681 **Schema:** 682 683 - Sites status flow: found → assets_captured → scored → rescored → enriched → proposals_drafted → outreach_sent 684 - Error handling: Sites stay at current stage with `error_message` set 685 - Scoring data: `score` (REAL), `grade` (TEXT), `score_json` (full result JSON) 686 - Contact methods: sms|email|form|x|linkedin 687 - Outreach delivery: pending → approved → sent → delivered|failed|bounced|opened|clicked|replied (also: rework, parked, scheduled, gdpr_blocked, gov_blocked, no_message_button) 688 - `parked` status: proposal deferred from the reword queue; `error_message` column stores the park reason (migration 093) 689 690 **File Locations:** `prompts/`, `docs/`, `tests/`, `db/sites.db`, `scripts/` 691 692 ## Compliance 693 694 **Email (CAN-SPAM):** Unsubscribe links required, sender ID, honor opt-outs in 10 days. See `docs/05-outreach/email-best-practices.md`. 695 696 **SMS (TCPA):** Requires prior consent, opt-out instructions (STOP), business hours (8am-9pm), sender ID. See `docs/05-outreach/sms-best-practices.md`. 697 698 **New Channels:** Research compliance, document requirements, implement rate limiting, test with `.env.example` contacts, use E.164 phone format. 699 700 ## Documentation Standards 701 702 **Documentation is organized into 9 categories:** See [docs/README.md](docs/README.md) for full navigation. 703 704 1. **[01-getting-started](docs/01-getting-started/)** - Setup, commands 705 2. **[02-architecture](docs/02-architecture/)** - System design, bot detection 706 3. **[03-pipeline](docs/03-pipeline/)** - Scoring, outreach strategy, capacity 707 4. **[04-proposals](docs/04-proposals/)** - Templates, compliance, workflow 708 5. **[05-outreach](docs/05-outreach/)** - Email, SMS, browser profiles, testing 709 6. **[06-automation](docs/06-automation/)** - **Cron system** (merged 4 docs), agents, NixOS 710 7. **[07-integrations](docs/07-integrations/)** - LLMs, dashboard, circuit breaker 711 8. **[08-operations](docs/08-operations/)** - Maintenance, logging, security 712 9. **[09-business](docs/09-business/)** - Pricing, market expansion, financials 713 10. **[90-archive](docs/90-archive/)** - Deprecated/merged docs (historical reference) 714 715 **Key Documentation:** 716 717 - **Cron System:** [docs/06-automation/cron-system.md](docs/06-automation/cron-system.md) - Comprehensive cron documentation (replaces 4 old files) 718 - **Agent System:** [docs/06-automation/agent-system.md](docs/06-automation/agent-system.md) 719 - **Dashboard:** [docs/07-integrations/dashboard.md](docs/07-integrations/dashboard.md) 720 - **Scoring System:** [docs/03-pipeline/scoring-system.md](docs/03-pipeline/scoring-system.md) 721 - **Email Compliance:** [docs/05-outreach/email-best-practices.md](docs/05-outreach/email-best-practices.md) 722 - **SMS Compliance:** [docs/05-outreach/sms-best-practices.md](docs/05-outreach/sms-best-practices.md) 723 - **Cultural Pricing:** [docs/09-business/cultural-pricing.md](docs/09-business/cultural-pricing.md) 724 725 **All documentation files include YAML frontmatter** with title, category, last_verified, related_files, tags, status, and replaces (if merged). 726 727 **Update proactively when making changes:** 728 729 - `.env.example`: New environment variables 730 - `README.md`: New npm scripts, CLI commands, features 731 - `CLAUDE.md`: New modules, architectural changes 732 - `docs/TODO.md`: Mark completed tasks, add discoveries 733 - `docs/[category]/`: Update relevant category documentation 734 - `db/schema.sql`: Schema changes (plus create migration) 735 - Test files: Add/update tests for changed functionality 736 - JSDoc comments: Update function documentation 737 738 **Plan Management:** 739 740 When implementing a plan from docs/plans/: 741 742 1. Create agent tasks or work directly on implementation 743 2. Execute, test, and verify completion 744 3. After implementation: Add "✅ IMPLEMENTED (YYYY-MM-DD, commit HASH)" badge to plan doc 745 4. Add implementation summary listing key deliverables 746 5. Move implemented plan to docs/plans/implemented/ 747 6. Update docs/plans/README.md to reflect status 748 7. Commit changes with message: "docs: archive implemented plan [plan-name]" 749 750 **Documentation Category Updates:** 751 752 When creating/updating docs in any category folder: 753 754 - Update that category's README.md with new/moved/removed files 755 - Keep category indexes current and accurate 756 - Update related_files in YAML frontmatter when code changes 757 - Add cross-references to related categories when relevant 758 759 Before committing: Verify docs current, run `npm run format`, check for broken links. 760 761 ## Common Tasks 762 763 **New Test:** Create `tests/feature-name.test.js` with `import { test } from 'node:test';`. Run `npm test`. Tests must not write to prod paths (`./logs/`, `./db/sites.db`). Use `LOGS_DIR=/tmp/test-logs` (set automatically by `npm test`) and `:memory:` or a `/tmp/test-*.db` path for SQLite. 764 765 **New Outreach Channel:** Create `src/outreach/channel-name.js` with `send<Channel>(id)` and `bulk<Channel>(limit)`. Update `db/schema.sql` CHECK constraints, add migration, update `src/contacts/prioritize.js`, add tests. 766 767 **Modify Prompts:** Edit `prompts/` files, restart app (loaded at init), test. 768 769 **New DB Fields:** Create `db/migrations/name.sql`, add indexes if queried frequently, update `db/schema.sql`, run `npm run init-db` (WARNING: resets DB). 770 771 **Keyword Validation:** Validate keywords using DataForSEO Labs API: 772 773 - `npm run keywords generate-csv -- --type businesses` 774 - Uses Labs API (76% cheaper): Top Searches, Keyword Suggestions, Keyword Overview 775 - Creates `data/{country}/businesses-search-volume.csv` 776 - No search volume filtering - qualitative filters only 777 - Module: `src/utils/keyword-validator.js` 778 779 **Daily Report:** Generate daily progress summary for CEO tracking: 780 781 **Quick Method:** 782 783 ```bash 784 npm run report:daily 785 ``` 786 787 Generates professional HTML report at `reports/daily-progress-YYYY-MM-DD.html` with: 788 789 - Git activity (commits, files changed, lines added/removed) 790 - Database changes (new sites, outreaches, conversations) 791 - Code quality metrics (test coverage, new TODOs) 792 - System health (recent errors from logs) 793 - Executive summary in non-technical language 794 795 **Manual Method (for custom analysis):** 796 797 1. **Git Activity:** 798 - Commits: `git log --since="24 hours ago" --pretty=format:"%h - %s (%ar)"` 799 - Files changed: `git diff --stat HEAD@{24.hours.ago}..HEAD` 800 - Branch activity: `git log --all --since="24 hours ago" --oneline --graph` 801 802 2. **Database Changes:** 803 - New sites by status: `SELECT status, COUNT(*) FROM sites WHERE created_at > datetime('now', '-1 day') GROUP BY status;` 804 - New outreaches by method: `SELECT contact_method, COUNT(*) FROM outreaches WHERE created_at > datetime('now', '-1 day') GROUP BY contact_method;` 805 - New conversations: `SELECT intent, COUNT(*) FROM conversations WHERE created_at > datetime('now', '-1 day') GROUP BY intent;` 806 807 3. **Code Quality:** 808 - Run `npm test` and compare coverage to previous day (if available) 809 - Check for new TODOs/FIXMEs: `git diff HEAD@{24.hours.ago}..HEAD | grep -E "TODO|FIXME"` 810 - Review any new npm dependencies: `git diff HEAD@{24.hours.ago}..HEAD package.json` 811 812 4. **System Health:** 813 - Check recent errors: `tail -100 logs/pipeline-$(date +%Y-%m-%d).log | grep -i error` 814 - Review completed TODO items in `docs/TODO.md` 815 816 5. **Generate Summary:** Format in non-technical language (3-5 bullet points): 817 - What shipped (features, fixes, improvements) 818 - System reliability/performance 819 - Business metrics (outreaches sent, conversations, pipeline throughput) 820 - Any blockers or issues discovered 821 822 ## Common Workflows 823 824 **Approving outreaches (batch review with Google Sheets):** 825 826 1. Generate proposals: `npm run proposals` 827 2. Export to Google Sheets: `npm run outreach:export` 828 3. Share sheet URL with QA person for review 829 4. QA sets Action column (approve/rework/reject) and adds rework instructions 830 5. QA can also directly edit Proposal Text column for quick fixes 831 6. Import decisions: `npm run outreach:import <sheetId>` 832 7. System auto-logs feedback for AI learning 833 8. Regenerate reworked items: `node src/proposal-generator-v2.js rework` 834 9. Export again for second review if needed 835 10. Send approved: `npm run outreach` 836 11. Monitor weekly learning reports in Human Review dashboard 837 838 **Adding new outreach channel:** 839 840 1. Create `src/outreach/channel-name.js` with send/bulk methods 841 2. Add tests (unit + integration) 842 3. Update schema (CHECK constraints + migration) 843 4. Update `src/contacts/prioritize.js` to extract contacts 844 5. Run full test suite, verify coverage 845 6. Update documentation 846 7. Run quality check, commit 847 848 **Fixing a bug:** 849 850 1. Read the module 851 2. Write regression test (verify it fails) 852 3. Fix the bug 853 4. Run test (verify it passes) 854 5. Run full test suite 855 6. Run quality check 856 7. Commit with root cause explanation 857 858 **Refactoring:** 859 860 1. Read current implementation and tests 861 2. Run tests to establish baseline 862 3. Make small incremental changes 863 4. Run tests after each change 864 5. Run full test suite 865 6. Verify coverage maintained 866 7. Run quality check 867 8. Commit with explanation