CLAUDE.md — Auctor
Auctor is a bounded-autonomy content operator: it runs the content lifecycle for Consul (consul.so) from research through publishing, with human approval gates at every major transition. Single operator, database-first, policy-governed.
1Research → Strategy → Plan Items → Briefs → Drafts → Review → Validate → PublishMental Model
Three execution surfaces: Web UI (Next.js, port 3000), Desktop (Electron + native Claude Code binary), MCP tools (17 tools proxied through Next.js).
Monoagent pattern. One agent (auctor) handles all tasks, loading domain-specific skills on demand. Legacy role IDs (competitive-intelligence, search-landscape, content-strategy, content-brief, writer, editor, final-cleanup, publishing, seo-autofix) exist for backward compatibility in workflow steps — they map to skill hints via agentIdToSkills, not separate agents.
Database-first. Postgres/Supabase is canonical truth. Four schemas: auctor (control plane — pipeline, competitors, keywords, config), consul (publish destination — posts, categories), generative (legacy, migrating to auctor), mastra (framework state — do not modify directly).
Skills as editable doctrine. Expertise lives in versioned Markdown files, not hardcoded prompts. 9 default skill domains managed by frontend/src/content-engine/skills/catalog.ts.
Commands
Package managers: pnpm (workspace root, frontend, desktop, packages), uv (Python backend).
1pnpm dev # Frontend dev server (port 3000)
2pnpm dev:backend # Backend (uvicorn, port 8000)
3pnpm dev:all # Both concurrently
4pnpm dev:all-desktop # All three + Electron
5
6pnpm build # Production build (frontend)
7pnpm lint # ESLint
8pnpm test:frontend # Vitest
9
10cd backend && uv sync --extra dev # Python deps
11cd backend && uv run pytest # All backend tests
12cd backend && uv run pytest tests/test_extract.py::test_health -v # Single testEnvironment
Managed with dotenv-vault. Commit .env.vault; keep .env out of version control.
1npx dotenv-vault@latest pull # Pull latest
2npx dotenv-vault@latest push # Push changesRequired: ANTHROPIC_API_KEY, DATABASE_URL, NEXT_PUBLIC_SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY. See .env.example for all variables including optional ones (DataForSEO, Firecrawl, GSC, GA4, model overrides).
Database
Supabase projects: Consul Agent (wsagglvhelbkpalingjk, us-west-2) and Generative, Inc. (lmwnjkhdhrsruedgqsza, us-east-2). Use these IDs with Supabase MCP tools.
| Client | Constructor | Use |
|---|---|---|
| Service-role | getServiceSupabase() | Server-side R/W across auctor/consul/generative (bypasses RLS) |
| Publishable-key | getSupabase() | Client-side reads against consul (RLS-protected) |
| Mastra PostgresStore | via DATABASE_URL | mastra schema only — do not modify directly |
Client singletons: frontend/src/content-engine/db/supabase.ts. Row types: frontend/src/content-engine/db/schema.ts (camelCase, converted from Postgres snake_case via mapRow()/mapRows()). Repository pattern: batchedIn() for large IN queries (100-item chunks for PostgREST URL limits).
For full schema documentation (tables, columns, relationships): see docs/database-schema.md
Content Pipeline
Plan items → briefs → drafts → publish (to consul.posts)
| Stage | Status Flow | Human Gate |
|---|---|---|
| Plan items | pending_review → approved → scheduled → in_progress → completed | Calendar review |
| Briefs | draft → pending_review → approved (or changes_requested) | Brief approval |
| Drafts | draft → in_revision → pending_human_review → approved → ready_to_publish → published | Draft review |
Four Mastra workflows (suspend/resume at human gates): strategy-planning, brief-generation, draft-production, page-extraction. Defined in frontend/src/mastra/workflows/content-engine-workflows.ts.
Draft patching: frontend/src/content-engine/services/draft-patches.ts (section-level edits with undo).
MCP Tools (17)
| Tool | Scope | Mutation | Purpose |
|---|---|---|---|
auctor_context | context | read | Strategy directives, landscape, pipeline dashboard, parameter schemas |
auctor_strategy_workspace | strategy | read | Filtered strategy workspace snapshot |
auctor_intel | intelligence | read | Deep-dive on competitor/keyword/SERP/page/cluster |
auctor_discover | intelligence | execute | Live web search or keyword metrics (costs money, use sparingly) |
auctor_list_content | content | read | List content at any pipeline stage |
auctor_get_content | content | read | Full details for a content item by ID |
auctor_manage_plan | content | write | Create/update plan items |
auctor_run_workflow | content | execute | Start/resume strategy, brief, or draft workflows |
auctor_publish | content | execute | Validate (dry_run=true first!) and publish drafts |
auctor_read_draft | content | read | Active editor draft, section map, patch history |
auctor_apply_draft_patch | content | write | Section-level edits to active draft |
auctor_undo_draft_patch | content | write | Undo latest structured draft edit |
auctor_list_library_assets | library | read | List uploaded reference assets |
auctor_search_library_assets | library | read | Search library assets |
auctor_get_library_asset | library | read | Get specific asset with extracted text |
auctor_list_skills | skills | read | List published skill snapshots |
auctor_load_skill | skills | read | Load a skill's SKILL.md body |
Tool contracts: packages/auctor-mcp/src/contracts.ts. Implementations: frontend/src/mastra/tools/content-engine-tools.ts.
MCP workflow: Orient (auctor_context) → Research (auctor_intel, then auctor_discover only if needed) → Plan (auctor_manage_plan) → Produce (auctor_run_workflow) → Publish (auctor_publish with dry_run=true first).
MCP rules: Never chain >3 tools without returning findings. Always dry_run=true before publishing. Don't use auctor_discover for data already indexed — use auctor_intel. Load skills explicitly instead of improvising methodology.
.mcp.json registers 4 servers: auctor (content tools), next-devtools, supabase, mastra (docs).
Web App
Stack: Next.js 16 (App Router), React 19, TypeScript 5.7, Tailwind CSS v4, shadcn/ui (new-york), Supabase JS, Mastra AI. Path alias @/* → frontend root.
All pages use the (app) route group (shell layout: sidebar + header + context panel + agent dock). Routes are in frontend/app/(app)/. Navigation: frontend/lib/app-navigation.ts.
Header system: The header is an action bar, NOT a title display. Pages inject controls via useHeaderSlot(). Never render page titles in the header.
Data fetching: Server components call repositories directly. Client mutations go through /api/content-engine/ routes. Agent chat uses useChat() from @ai-sdk/react.
Desktop
Electron app spawns the native Claude Code binary (Mach-O at ~/.local/bin/claude) via child_process.spawn() with stdin/stdout JSON lines.
Tool policy: Read tools auto-allow. Write/edit tools allow if inside workspace. Safe git auto-allow. Destructive git and MCP publish require approval.
Key files: desktop/src/claude/runtime-manager.ts (session lifecycle), resolve-binary.ts (Mach-O validation), env-assembly.ts (8-layer env), tool-policy.ts (approval rules).
Activity Log
auctor.activity_log is the single observability stream. Every meaningful action must write to it.
Categories: agent, workflow, content, competitor, seo, job, config, automation, chat. Sources: system, agent, user, scheduler, mcp. Use recordActivityWithContext() — fire-and-forget, never block. Dot-notation actions: category.verb (e.g., content.draft_published, job.started). Always pass costUsd/tokenCount/durationMs for LLM calls. Link entities via entityType/entityId/workflowRunId.
Rules
- NEVER use
@anthropic-ai/claude-codenpm SDK for desktop runtime — crashes on Node 25+. Use native binary only. process.execPathin Electron returns the Electron binary. Useenv.NODE ?? 'node'for child processes.- Always log activity for new background processes, agent steps, workflows, jobs, user-facing mutations.
- Never block on logging — fire-and-forget only.
- Keep type parity between
frontend/lib/types.tsandbackend/app/models.pyfor extraction types. - Flat layouts — no Card wrappers. Use flat sections with spacing and borders.
- shadcn/ui components in
components/ui/are generated — avoid manual edits. next.config.mjsignores TS build errors and disables image optimization.batchedIn()for large.in()queries (100-item PostgREST limit).- Always
dry_run=truebeforeauctor_publish.
Key References
For detailed documentation beyond this file:
- Database schema (all tables, columns, relationships):
docs/database-schema.md - Pipeline testing and fixtures:
docs/pipeline-testing.md - System whitepaper and thesis:
docs/auctor-agent-whitepaper.md - Workflow details:
frontend/src/mastra/workflows/content-engine-workflows.ts - MCP contracts and operating spec:
packages/auctor-mcp/src/contracts.ts,operating-spec.ts - Agent metadata and role mappings:
frontend/src/mastra/agents/agent-metadata.ts - Extraction presets:
frontend/lib/pipeline-configs.ts,frontend/lib/presets.ts