Skip to Content
ExamplesExecution Walkthrough — ACT-2604-001

Execution Walkthrough — ACT-2604-001

Activity: Content Brief: AI-Powered Marketing Agencies Agent: content-brief-writer Ref: ACT-2604-001 Date: 2026-03-31 (created) → 2026-04-02 (due)

This document traces the complete lifecycle of a single activity from the moment the Activity Planner creates it to the moment the approved brief releases the next downstream agent (ACT-2604-002). Every table write, queue operation, Claude invocation, tool call, and human review step is shown in order.


Pipeline Overview

[Activity Planner] │ creates activity + enqueues job [PostgreSQL: activities] [BullMQ: agent__content-brief-writer] │ worker picks up job [Worker: context assembly] ├── tenant settings (PostgreSQL: tenant_settings) ├── agent config (PostgreSQL: agent_configs) ├── skills (MongoDB: skills collection) └── RAG pre-fetch (Qdrant: ds_{datasetId}) [buildActivityPrompt() → full prompt string] [Claude Code CLI subprocess] claude -p "..." --add-dir /tmp/skills-{uuid}/ \ --output-format stream-json \ --model claude-sonnet-4-6 │ NDJSON events on stdout │ ├── tool_use: rag_search (×2) │ ├── tool_use: web_search (×1) │ └── tool_use: web_fetch (×3) [ContentBriefWriterOutput JSON] │ stored in PostgreSQL + MongoDB [HITL: approvals record created] [DM Portal: reviewer reads, edits, approves] [BullMQ: agent__research-note-writer] ← ACT-2604-002 released

Phase 1 — Activity Planner Creates the Activity

When: 2026-03-31, during the monthly Q2 Growth campaign decomposition run.

The Activity Planner agent has already completed the Keyword Researcher step for the “AI marketing agency tools” cluster. The keyword cluster passed HITL review (keyword approval gate). The Strategist now creates the downstream activity.

1.1 — PostgreSQL write: activities

INSERT INTO activities ( id, tenant_id, campaign_id, ref, title, description, channel, deliverable_type, assigned_agent, assigned_to_type, due_date, priority, status, created_by, created_at, input_payload ) VALUES ( 'act_01jwx9abc123', 'tenant_leadmetrics', 'camp_q2_2026', 'ACT-2604-001', 'Content Brief: AI-Powered Marketing Agencies', 'Generate SEO content brief for primary keyword cluster "AI marketing agency tools". Target: informational, 1,800 words. Includes keyword research, angle, H2 outline, internal link targets.', 'website', 'blog_post', 'content-brief-writer', 'agent', '2026-04-02', 'normal', 'pending', 'agent:activity-planner', NOW(), -- input_payload JSONB — the ContentBriefWriterInput '{ "tenantId": "tenant_leadmetrics", "keywordCluster": { "primaryKeyword": { "keyword": "AI marketing agency tools", "volume": 2900, "difficulty": 38, "intent": "informational", "cpc": 4.20 }, "secondaryKeywords": [ { "keyword": "AI tools for marketing agencies", "volume": 1600, "difficulty": 34, "intent": "informational" }, { "keyword": "marketing automation AI", "volume": 5400, "difficulty": 52, "intent": "commercial" }, { "keyword": "AI copywriting agency", "volume": 880, "difficulty": 28, "intent": "commercial" } ], "lsiTerms": ["machine learning marketing", "content automation", "programmatic advertising", "predictive analytics"], "contentGapOpportunity": "No ranking page covers the full workflow from brief to published blog using AI agents end-to-end", "serpFeatures": ["featured snippet (paragraph)", "people also ask", "top stories"] }, "contentGoal": "new_blog_post", "wordCountTarget": 1800, "campaignId": "camp_q2_2026" }' );

Status after write: pending

1.2 — BullMQ job enqueued

The Activity Planner calls the control plane’s internal queue API to enqueue the job. The queue name is namespaced to the tenant.

// control-plane/src/queue.ts await activityQueue.add( 'content-brief-writer', { activityId: 'act_01jwx9abc123', tenantId: 'tenant_leadmetrics', agentRole: 'content-brief-writer', wakeReason: 'new_task', dependsOnRuns: [], // no upstream dependency for this first job }, { jobId: 'act_01jwx9abc123', delay: 0, attempts: 3, backoff: { type: 'exponential', delay: 30_000 }, } );

Queue: agent__content-brief-writer Activity status updated to: assigned


Phase 2 — Worker Picks Up the Job

A BullMQ worker process subscribed to agent__content-brief-writer picks up the job.

Concurrency for this queue: 4 (up to 4 concurrent content-brief-writer runs across the platform).

2.1 — Activity status update

UPDATE activities SET status = 'in_progress', started_at = NOW() WHERE id = 'act_01jwx9abc123';

2.2 — activity_runs record created

INSERT INTO activity_runs ( id, activity_id, tenant_id, agent_role, status, started_at, wake_reason ) VALUES ( 'run_01jwx9def456', 'act_01jwx9abc123', 'tenant_leadmetrics', 'content-brief-writer', 'running', NOW(), 'new_task' );

Phase 3 — Context Assembly

Before spawning Claude, the worker fetches all context required to assemble the prompt.

3.1 — Tenant settings (PostgreSQL)

SELECT ts.industry, ts.target_audience, ts.connected_channels, ts.plan, ts.brand_voice, ts.language FROM tenant_settings ts WHERE ts.tenant_id = 'tenant_leadmetrics';

Result used to populate {{TENANT_SETTINGS}} placeholder:

Industry: SaaS / AI Marketing Target Audience: Digital marketing managers, agency owners, SMB marketing teams Plan: Pro Brand Voice: Confident, data-driven, conversational but not casual. Avoid jargon. Language: English (Australian)

3.2 — Agent config (PostgreSQL)

SELECT ac.adapter_config, ac.system_prompt_template, ac.skills, ac.rag_datasets FROM agent_configs ac WHERE ac.tenant_id = 'tenant_leadmetrics' AND ac.agent_role = 'content-brief-writer' AND ac.is_active = true;

Key fields retrieved:

  • adapter_config.model: claude-sonnet-4-6
  • adapter_config.timeoutSec: 360 (6 min)
  • adapter_config.maxTurnsPerRun: 15
  • skills: ['client-context-file', 'seo-content-brief-standards']
  • rag_datasets: ['website-content', 'published-content']

3.3 — Client context file (MongoDB)

The client-context-file skill is a tenant-specific Markdown document stored in MongoDB’s skills collection.

MongoDB: skills Query: { tenantId: 'tenant_leadmetrics', slug: 'client-context-file' }

Document returned (excerpt):

# Leadmetrics — Client Context **Company:** Leadmetrics — AI-powered marketing platform for SMB agencies **Website:** https://leadmetrics.io **Primary audience:** Agency owners, marketing managers at companies with 10–200 employees **Tone:** Confident, practical, data-driven. Australian English. Avoid "leverage" and "synergy". **Competitors:** HubSpot, Semrush, Jasper, Copy.ai, Surfer SEO **USP:** End-to-end AI agent pipeline from brief to published — the only platform that handles the full content workflow, not just generation. **Key pages:** /features, /pricing, /blog, /case-studies, /integrations **Do not mention:** Pending litigation with former partner (as of 2026-Q1)

3.4 — SEO standards skill (MongoDB)

MongoDB: skills Query: { tenantId: null, slug: 'seo-content-brief-standards' }

Global skill (not tenant-scoped). Returns the full seo-content-brief-standards.md content — title rules, meta rules, outline depth requirements, word count strategy, internal link criteria, competitor gap analysis standards.

3.5 — Skills written to temp directory

Both skill files are written to a temp directory for --add-dir injection:

/tmp/skills-a7f3b2c1/ ├── client-context-file.md (4,200 chars) └── seo-content-brief-standards.md (2,800 chars)

Claude reads these files on demand via --add-dir — they are not sent in the prompt upfront.

3.6 — RAG pre-fetch

Two Qdrant queries run before Claude is invoked. Results are injected into the {{RAG_CONTEXT}} placeholder to seed Claude before it calls rag_search itself.

Query 1 — Internal link candidates

Dataset: website-content (collection: ds_wc_leadmetrics) Query: "AI marketing agency tools content pages internal links" Top K: 8 Results: - /blog/what-is-product-led-growth (score: 0.82) - /features/ai-content-agent (score: 0.79) - /blog/reduce-ad-spend-ai (score: 0.74) - /pricing (score: 0.71) - /case-studies/acme-plumbing (score: 0.68)

Query 2 — Duplicate content check

Dataset: published-content (collection: ds_pc_leadmetrics) Query: "AI marketing agency tools blog post published articles" Top K: 5 Results: - "5 AI Tools Every Marketing Team Needs in 2025" (score: 0.61 — below 0.70 threshold ✓) - "How to Choose a Marketing Agency" (score: 0.44 — no overlap ✓)

No published article exceeds the 0.70 similarity threshold. No duplication risk.


Phase 4 — Prompt Assembly

4.1 — System prompt with placeholder substitution

The system prompt template from agent_configs has three placeholders. buildActivityPrompt() substitutes them with the assembled context.

// packages/agent-engine/src/prompt-builder.ts const systemPrompt = agentConfig.systemPromptTemplate .replace('{{CLIENT_CONTEXT}}', clientContextFileContent) .replace('{{TENANT_SETTINGS}}', formatTenantSettings(tenantSettings)) .replace('{{RAG_CONTEXT}}', formatRagContext(ragResults));

The final system prompt sent to Claude:

You are an SEO content strategist at a digital marketing agency. Your job is to write a complete, production-ready SEO content brief that a writer can follow without ambiguity. CLIENT CONTEXT: [...client-context-file.md content — company, brand voice, audience, competitors...] TENANT SETTINGS: Industry: SaaS / AI Marketing Target Audience: Digital marketing managers, agency owners, SMB marketing teams Plan: Pro Brand Voice: Confident, data-driven, conversational but not casual. Language: English (Australian) KNOWLEDGE BASE CONTEXT: ## Internal Link Candidates - /blog/what-is-product-led-growth — "What Is Product-Led Growth?" - /features/ai-content-agent — "AI Content Agent — Leadmetrics Features" - /blog/reduce-ad-spend-ai — "5 Ways to Reduce Ad Spend Waste with AI" - /pricing — "Leadmetrics Pricing" - /case-studies/acme-plumbing — "Case Study: Acme Plumbing" ## Recently Published — Duplication Check - "5 AI Tools Every Marketing Team Needs in 2025" (similarity: 0.61 — safe to proceed) - "How to Choose a Marketing Agency" (similarity: 0.44 — no overlap) [...full system prompt rules and output schema instructions...] Output valid JSON matching the ContentBriefWriterOutput schema.

4.2 — Task prompt

TASK: Generate an SEO content brief for the following keyword cluster. Keyword Cluster: { "primaryKeyword": { "keyword": "AI marketing agency tools", "volume": 2900, "difficulty": 38, "intent": "informational" }, "secondaryKeywords": [ { "keyword": "AI tools for marketing agencies", "volume": 1600 }, { "keyword": "marketing automation AI", "volume": 5400 }, { "keyword": "AI copywriting agency", "volume": 880 } ], "lsiTerms": ["machine learning marketing", "content automation", "programmatic advertising"], "contentGapOpportunity": "No ranking page covers the full AI agent workflow end-to-end", "serpFeatures": ["featured snippet (paragraph)", "people also ask"] } Content goal: new_blog_post Target word count: 1,800 Campaign: camp_q2_2026

Phase 5 — Claude Code CLI Subprocess

5.1 — Process spawn

const args = [ '--output-format', 'stream-json', '--model', 'claude-sonnet-4-6', '--add-dir', '/tmp/skills-a7f3b2c1/', '--max-turns', '15', '-p', `${systemPrompt}\n\nTASK:\n${taskPrompt}`, ]; const child = spawn('claude', args, { cwd: '/app/agent-workdir/tenant_leadmetrics/content-brief-writer', env: { ...process.env, ANTHROPIC_API_KEY: '<resolved>' }, stdio: ['ignore', 'pipe', 'pipe'], });

5.2 — NDJSON event stream

The adapter reads child.stdout line by line. Here is the complete annotated event sequence for this run:

// ── INIT ────────────────────────────────────────────────────────────────────── { "type": "system", "subtype": "init", "session_id": "sess_5xk9m2p", "model": "claude-sonnet-4-6" } // Adapter stores session_id → sessions table immediately // ── TURN 1: Claude reads skills files via --add-dir ─────────────────────────── // (Claude internally reads /tmp/skills-a7f3b2c1/ — not visible as tool_use events // in the stream; Claude Code's file access layer handles it transparently) // ── TURN 2: RAG search — internal link refinement ──────────────────────────── { "type": "tool_use", "id": "tu_001", "name": "rag_search", "input": { "query": "AI marketing platform features blog posts internal links", "dataset": "website-content", "topK": 10 } } { "type": "tool_result", "tool_use_id": "tu_001", "content": "...8 website pages with titles and URLs..." } // ── TURN 3: RAG search — duplicate check (deeper query) ────────────────────── { "type": "tool_use", "id": "tu_002", "name": "rag_search", "input": { "query": "AI agency automation marketing published blog 2025 2026", "dataset": "published-content", "topK": 5 } } { "type": "tool_result", "tool_use_id": "tu_002", "content": "...2 articles, max similarity 0.61..." } // ── TURN 4: Web search — SERP top 10 ───────────────────────────────────────── { "type": "tool_use", "id": "tu_003", "name": "web_search", "input": { "query": "AI marketing agency tools 2026" } } { "type": "tool_result", "tool_use_id": "tu_003", "content": "...10 SERP results with titles, URLs, snippets..." } // ── TURN 5: web_fetch — competitor 1 ───────────────────────────────────────── { "type": "tool_use", "id": "tu_004", "name": "web_fetch", "input": { "url": "https://agencyanalytics.com/blog/ai-marketing-tools" } } { "type": "tool_result", "tool_use_id": "tu_004", "content": "...DOM text, ~2,400 words, 6 H2 headings extracted..." } // ── TURN 6: web_fetch — competitor 2 ───────────────────────────────────────── { "type": "tool_use", "id": "tu_005", "name": "web_fetch", "input": { "url": "https://sproutsocial.com/insights/ai-marketing-tools/" } } { "type": "tool_result", "tool_use_id": "tu_005", "content": "...DOM text, ~3,100 words, 8 H2 headings extracted..." } // ── TURN 7: web_fetch — competitor 3 ───────────────────────────────────────── { "type": "tool_use", "id": "tu_006", "name": "web_fetch", "input": { "url": "https://buffer.com/resources/ai-marketing/" } } { "type": "tool_result", "tool_use_id": "tu_006", "content": "...DOM text, ~1,900 words, 5 H2 headings extracted..." } // ── FINAL OUTPUT: Claude writes the ContentBriefWriterOutput JSON ───────────── { "type": "assistant", "message": { "content": [{ "type": "text", "text": "{" }] } } { "type": "assistant", "message": { "content": [{ "type": "text", "text": "\n \"tenantId\": \"tenant_leadmetrics\"," }] } } // ... (streaming JSON tokens, ~2,000 output tokens total) ... // ── RESULT ──────────────────────────────────────────────────────────────────── { "type": "result", "subtype": "success", "result": "{ ...full ContentBriefWriterOutput JSON... }", "usage": { "input_tokens": 7480, "output_tokens": 2020 }, "session_id": "sess_5xk9m2p" }

Total tool calls: 6 (2× rag_search, 1× web_search, 3× web_fetch) Total turns: 7 Wall clock time: ~3 min 40 sec Estimated cost: $0.45 (7,480 × $0.003 + 2,020 × $0.015 per 1k tokens)


Phase 6 — Output Validation and Storage

6.1 — Post-generation guardrail checks

The worker runs the following validation rules before storing the result:

CheckRuleResult
Title length50–65 chars"How AI is Transforming Digital Marketing Agencies in 2026" — 57 chars ✓
Meta description150–160 chars154 chars ✓
Outline sections5–8 H2 sections7 sections ✓
Key points per H2≥ 3 per sectionMin 3, max 5 ✓
Internal link URLsMust exist in RAG results4 links — all validated against RAG page list ✓
Duplication checkSimilarity < 0.70 with publishedMax 0.61 ✓

All checks pass. No retry needed.

6.2 — MongoDB write: content document

The full ContentBriefWriterOutput JSON is stored as a document in MongoDB.

// MongoDB: content collection db.content.insertOne({ _id: 'content_01jwx9ghi789', tenantId: 'tenant_leadmetrics', activityId: 'act_01jwx9abc123', activityRef: 'ACT-2604-001', type: 'content_brief', agentRole: 'content-brief-writer', generatedAt: new Date('2026-04-01T09:42:17Z'), content: { title: 'How AI is Transforming Digital Marketing Agencies in 2026', metaDescription: 'Discover how AI marketing agency tools are cutting content creation time by 80% — from brief to published blog, fully automated. (154 chars)', h1: 'How AI is Transforming Digital Marketing Agencies in 2026', targetWordCount: 2050, wordCountRationale: 'Top 3 competitors average 2,467 words. Setting 2,050 as the floor with room to expand to 2,400 during writing.', primaryKeyword: 'AI marketing agency tools', secondaryKeywords: ['AI tools for marketing agencies', 'marketing automation AI', 'AI copywriting agency'], searchIntent: 'informational', tone: 'Confident, practical, data-driven. Australian English. Lead with stats. Avoid jargon.', outline: [ { h2: 'What Are AI Marketing Agency Tools (and Why Agencies Are Adopting Them Fast)', keyPoints: [ 'Define AI marketing tools vs. traditional martech', 'Stat: 68% of agencies report time savings > 50% after adopting AI tools (source: to be added by writer)', 'Shift from task automation to agent pipelines — the key distinction', ], internalLinkOpportunity: { anchorText: 'AI content agent', targetUrl: '/features/ai-content-agent', targetTitle: 'AI Content Agent — Leadmetrics Features', rationale: 'Introduce the concept, then link to the product feature page for conversion' }, wordCountTarget: 280 }, // ... 6 more H2 sections ... ], competitorUrls: [ { url: 'https://agencyanalytics.com/blog/ai-marketing-tools', wordCount: 2400, mainAngle: 'Tool category overview — one paragraph per tool, no workflow depth', gapWeCanFill: 'None cover the full agent pipeline workflow; focus on end-to-end automation narrative' }, { url: 'https://sproutsocial.com/insights/ai-marketing-tools/', wordCount: 3100, mainAngle: 'Social-media-focused; heavy on scheduling and listening tools', gapWeCanFill: 'Missing SEO and content brief automation — our primary differentiator' }, { url: 'https://buffer.com/resources/ai-marketing/', wordCount: 1900, mainAngle: 'Lightweight intro, mostly Buffer product placement', gapWeCanFill: 'Thin on concrete workflow — case study or step-by-step process section would outrank' } ], featuredSnippetOpportunity: { format: 'paragraph', targetSection: 'What Are AI Marketing Agency Tools', recommendedLength: 280 }, internalLinkTargets: [ { anchorText: 'AI content agent', targetUrl: '/features/ai-content-agent', targetTitle: 'AI Content Agent', rationale: 'Feature page — conversion intent' }, { anchorText: 'reduce ad spend waste with AI', targetUrl: '/blog/reduce-ad-spend-ai', targetTitle: '5 Ways to Reduce Ad Spend Waste', rationale: 'Related blog — topical authority' }, { anchorText: 'product-led growth', targetUrl: '/blog/what-is-product-led-growth', targetTitle: 'What Is Product-Led Growth?', rationale: 'Audience segment overlap' }, { anchorText: 'Leadmetrics pricing', targetUrl: '/pricing', targetTitle: 'Leadmetrics Pricing', rationale: 'CTA linkout at article close' } ], existingContentToAvoid: [] }, version: 1 });

6.3 — PostgreSQL write: activity_runs result

UPDATE activity_runs SET status = 'completed', completed_at = NOW(), output_ref = 'content_01jwx9ghi789', -- MongoDB doc ID input_tokens = 7480, output_tokens = 2020, cost_usd = 0.0526, duration_ms = 220140 -- ~3 min 40 sec WHERE id = 'run_01jwx9def456';

6.4 — PostgreSQL write: llm_calls

INSERT INTO llm_calls ( id, tenant_id, activity_run_id, provider, model, input_tokens, output_tokens, cost_usd, started_at, completed_at ) VALUES ( 'llm_01jwx9jkl012', 'tenant_leadmetrics', 'run_01jwx9def456', 'claude', 'claude-sonnet-4-6', 7480, 2020, 0.0526, '2026-04-01T09:38:37Z', '2026-04-01T09:42:17Z' );

Phase 7 — HITL Approval Gate

The content brief always goes to a human reviewer before the Blog Writer is dispatched (risk_level: low, trigger: always).

7.1 — Approvals record created

INSERT INTO approvals ( id, tenant_id, activity_id, activity_run_id, type, risk_level, status, content_ref, reviewer_id, created_at, expires_at ) VALUES ( 'appr_01jwx9mno345', 'tenant_leadmetrics', 'act_01jwx9abc123', 'run_01jwx9def456', 'content_brief_review', 'low', 'pending', 'content_01jwx9ghi789', -- MongoDB doc ID pointing to the brief 'user_dm_reviewer_01', NOW(), NOW() + INTERVAL '48 hours' );

7.2 — Activity status update

UPDATE activities SET status = 'awaiting_approval' WHERE id = 'act_01jwx9abc123';

7.3 — Notification sent

An in-app notification is created for the assigned DM reviewer:

INSERT INTO notifications ( tenant_id, user_id, type, ref_id, ref_type, message, created_at ) VALUES ( 'tenant_leadmetrics', 'user_dm_reviewer_01', 'approval_required', 'appr_01jwx9mno345', 'approval', 'Content brief ready for review: "AI-Powered Marketing Agencies"', NOW() );

Phase 8 — DM Reviewer Action (DM Portal)

8.1 — Reviewer opens the approval

API call from DM Portal:

GET /api/dm/approvals/appr_01jwx9mno345 Authorization: Bearer <dm-reviewer-jwt>

Response includes the full content brief from MongoDB (content_ref: content_01jwx9ghi789), the keyword cluster input, activity metadata, and the approval record.

8.2 — Reviewer reads the brief

The DM Portal renders the brief in a structured editor. The reviewer can:

  • Read the full H2 outline with key points
  • See competitor insights table
  • Review internal link targets
  • Check word count rationale
  • Edit any section inline

8.3 — Reviewer adds a note and approves

The reviewer adds a section note: “Add a mention of the Acme Plumbing case study in the social proof H2 — we got 42% lead growth, great stat for this audience.”

API call from DM Portal:

PATCH /api/dm/approvals/appr_01jwx9mno345 Authorization: Bearer <dm-reviewer-jwt> { "action": "approve", "notes": "Add Acme Plumbing case study mention in social proof section (42% lead growth).", "editedContentRef": "content_01jwx9ghi789" }

8.4 — Approval record updated

UPDATE approvals SET status = 'approved', reviewer_id = 'user_dm_reviewer_01', resolved_at = NOW(), reviewer_notes = 'Add Acme Plumbing case study mention in social proof section (42% lead growth).' WHERE id = 'appr_01jwx9mno345'; UPDATE activities SET status = 'approved' WHERE id = 'act_01jwx9abc123';

Phase 9 — Downstream Release: ACT-2604-002

Approval triggers release of the next activity in the pipeline.

9.1 — ACT-2604-002 created and enqueued

The control plane creates the Research Note Writer activity with the approved brief as its input payload:

INSERT INTO activities ( id, tenant_id, campaign_id, ref, title, assigned_agent, status, priority, due_date, created_at, input_payload ) VALUES ( 'act_01jwx9pqr678', 'tenant_leadmetrics', 'camp_q2_2026', 'ACT-2604-002', 'Research Notes: AI Marketing Agencies', 'research-note-writer', 'pending', 'normal', '2026-04-03', NOW(), '{ "tenantId": "tenant_leadmetrics", "briefRef": "content_01jwx9ghi789", "primaryKeyword": "AI marketing agency tools", "reviewerNotes": "Add Acme Plumbing case study mention in social proof section (42% lead growth).", "campaignId": "camp_q2_2026" }' );
await activityQueue.add( 'research-note-writer', { activityId: 'act_01jwx9pqr678', tenantId: 'tenant_leadmetrics', agentRole: 'research-note-writer', wakeReason: 'review_approved', dependsOnRuns: ['run_01jwx9def456'], // brief run ID threaded into context } );

9.2 — ACT-2604-001 marked complete

UPDATE activities SET status = 'completed', completed_at = NOW() WHERE id = 'act_01jwx9abc123';

Summary — Tables and APIs Touched

PostgreSQL tables written

TableOperationPhase
activitiesINSERT1.1
activitiesUPDATE status = 'assigned'1.2
activitiesUPDATE status = 'in_progress'2.1
activity_runsINSERT2.2
activity_runsUPDATE (result + cost)6.3
llm_callsINSERT6.4
approvalsINSERT7.1
activitiesUPDATE status = 'awaiting_approval'7.2
notificationsINSERT7.3
approvalsUPDATE (resolved)8.4
activitiesUPDATE status = 'approved'8.4
activitiesINSERT (ACT-2604-002)9.1
activitiesUPDATE status = 'completed'9.2

PostgreSQL tables read

TablePurposePhase
tenant_settingsBrand voice, industry, plan3.1
agent_configsAdapter config, skills list, RAG datasets3.2

MongoDB collections

CollectionOperationPhase
skillsREAD — client-context-file3.3
skillsREAD — seo-content-brief-standards3.4
contentINSERT — full ContentBriefWriterOutput6.2

Qdrant queries

CollectionQueryPhase
ds_wc_leadmetricsInternal link candidates3.6
ds_pc_leadmetricsDuplicate content check3.6

API endpoints called (DM Portal → Control Plane)

MethodEndpointPhase
GET/api/dm/approvals/appr_01jwx9mno3458.1
PATCH/api/dm/approvals/appr_01jwx9mno3458.3

Timeline

2026-03-31 18:00 Activity Planner creates ACT-2604-001, job enqueued 2026-04-01 09:38 Worker picks up job (next available slot) 2026-04-01 09:38 Context assembly: tenant settings, agent config, skills, RAG pre-fetch (~8 sec) 2026-04-01 09:38 Claude subprocess spawned 2026-04-01 09:38 Claude reads skill files via --add-dir 2026-04-01 09:39 rag_search (internal links) + rag_search (duplicate check) — 2 tool calls 2026-04-01 09:40 web_search (SERP top 10) 2026-04-01 09:40 web_fetch competitor 1 (agencyanalytics.com) 2026-04-01 09:41 web_fetch competitor 2 (sproutsocial.com) 2026-04-01 09:41 web_fetch competitor 3 (buffer.com) 2026-04-01 09:42 Claude writes ContentBriefWriterOutput JSON (~2,000 tokens) 2026-04-01 09:42 Output validation — all guardrail checks pass 2026-04-01 09:42 MongoDB write (content doc), PostgreSQL writes (activity_runs, llm_calls) 2026-04-01 09:42 Approval record created, notification sent to DM reviewer 2026-04-01 14:15 DM reviewer opens brief in portal 2026-04-01 14:22 Reviewer approves with note (7 min review) 2026-04-01 14:22 ACT-2604-002 (Research Note Writer) enqueued 2026-04-01 14:22 ACT-2604-001 marked completed

Total elapsed (creation to completion): ~20 hours (mostly reviewer availability; agent run itself ~4 min) Agent run time: 3 min 42 sec Agent cost: $0.0526


© 2026 Leadmetrics — Internal use only