feat: deepened M7+M8, download page, healthcheck endpoint, analytics stub

This commit is contained in:
artale 2026-06-12 09:45:04 +02:00
parent c6364452f3
commit 716ab89a7d
64 changed files with 574 additions and 308 deletions

View File

@ -54,6 +54,13 @@ const server = http.createServer(async (req, res) => {
res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS')
res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
// Healthcheck endpoint
if (req.url === '/health' && req.method === 'GET') {
res.writeHead(200, { 'Content-Type': 'application/json' })
res.end(JSON.stringify({ status: 'ok', uptime: process.uptime() }))
return
}
if (req.method === 'OPTIONS') {
res.writeHead(204)
res.end()

View File

@ -18,6 +18,8 @@ export default defineConfig({
['link', { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' }],
['link', { href: 'https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,700;9..40,800&family=DM+Mono:wght@400;500&display=swap', rel: 'stylesheet' }],
['link', { href: 'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0,0', rel: 'stylesheet' }],
// Analytics — uncomment and configure when ready
// ['script', { src: 'https://analytics.example.com/script.js', 'data-domain': 'git.fdsa.agency', defer: '' }],
],
appearance: true,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,60 +0,0 @@
import{c as a,Q as i,j as e,m as t}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"Module 7: Advanced Topics","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m7-advanced.md","filePath":"modules/m7-advanced.md","lastUpdated":1780491906000}'),n={name:"modules/m7-advanced.md"};function l(h,s,p,r,o,d){return i(),e("div",null,[...s[0]||(s[0]=[t(`<h1 id="module-7-advanced-topics" tabindex="-1">Module 7: Advanced Topics <a class="header-anchor" href="#module-7-advanced-topics" aria-label="Permalink to &quot;Module 7: Advanced Topics&quot;"></a></h1><h2 id="lesson-7-1-autoresearch" tabindex="-1">Lesson 7.1: Autoresearch <a class="header-anchor" href="#lesson-7-1-autoresearch" aria-label="Permalink to &quot;Lesson 7.1: Autoresearch&quot;"></a></h2><h3 id="the-core-loop" tabindex="-1">The Core Loop <a class="header-anchor" href="#the-core-loop" aria-label="Permalink to &quot;The Core Loop&quot;"></a></h3><p>Agents that improve themselves. The experiment loop:</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>1. Run: Execute the agent with current configuration</span></span>
<span class="line"><span>2. Measure: Collect metrics (latency, cost, success rate)</span></span>
<span class="line"><span>3. Log: Record experiment results to JSONL</span></span>
<span class="line"><span>4. Decide: Keep if improvement, discard if regression</span></span>
<span class="line"><span>5. Repeat: Try next experiment</span></span></code></pre></div><h3 id="brand-monitor-example" tabindex="-1">Brand Monitor Example <a class="header-anchor" href="#brand-monitor-example" aria-label="Permalink to &quot;Brand Monitor Example&quot;"></a></h3><p>From your own autoresearch system:</p><div class="language-json vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">json</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;run&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;metric&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;name&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;home_ms&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;value&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">52</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;description&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;Baseline&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">{</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;run&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;metric&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: {</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;name&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;home_ms&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;value&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">46</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;deltaPct&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">-11.5</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">&quot;description&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;Remove N+1 count queries&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span></code></pre></div><hr><h2 id="lesson-7-2-the-experiment-loop--integrity" tabindex="-1">Lesson 7.2: The Experiment Loop Integrity <a class="header-anchor" href="#lesson-7-2-the-experiment-loop--integrity" aria-label="Permalink to &quot;Lesson 7.2: The Experiment Loop Integrity&quot;"></a></h2><h3 id="three-threats-to-integrity" tabindex="-1">Three Threats to Integrity <a class="header-anchor" href="#three-threats-to-integrity" aria-label="Permalink to &quot;Three Threats to Integrity&quot;"></a></h3><ol><li><p><strong>Reward hacking</strong> Model moves computation outside the timing function. The &quot;timed call&quot; becomes a lookup. (Found in Mythos paper.)</p></li><li><p><strong>Grinding</strong> Running identical code 160 times hoping for a lucky outlier. (Found in Mythos paper &quot;Pure grind same code, lucky measurement.&quot;)</p></li><li><p><strong>Test set leakage</strong> Finding the test set and training on it. (Found in Mythos paper time series agent found the test set and directly trained on it.)</p></li></ol><h3 id="integrity-guards" tabindex="-1">Integrity Guards <a class="header-anchor" href="#integrity-guards" aria-label="Permalink to &quot;Integrity Guards&quot;"></a></h3><div class="language-python vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">python</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Code hash detect grind runs</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">code_hash </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> hash</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">open</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;agent.py&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">).read())</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> last_run_code_hash </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">==</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> code_hash:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> flag_grind_run()</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Compare against median, not best</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">scores </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> [</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">52</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">48</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">47</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">46</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">46</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">51</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">53</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">median </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> sorted</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(scores)[</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">len</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(scores)</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">//</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">2</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">] </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># 48</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">best </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> max</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(scores) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># 46 (outlier)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Verify test data wasn&#39;t modified</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">test_data_hash_before </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> hash</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">open</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;benchmark_data.json&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">).read())</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># ... run experiment ...</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">test_data_hash_after </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> hash</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">open</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;benchmark_data.json&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">).read())</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">assert</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> test_data_hash_before </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">==</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> test_data_hash_after</span></span></code></pre></div><hr><h2 id="lesson-7-3-meta-agents--agents-that-build-agents" tabindex="-1">Lesson 7.3: Meta-Agents Agents That Build Agents <a class="header-anchor" href="#lesson-7-3-meta-agents--agents-that-build-agents" aria-label="Permalink to &quot;Lesson 7.3: Meta-Agents Agents That Build Agents&quot;"></a></h2><h3 id="the-pattern" tabindex="-1">The Pattern <a class="header-anchor" href="#the-pattern" aria-label="Permalink to &quot;The Pattern&quot;"></a></h3><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>User: &quot;I need an agent that monitors our API uptime&quot;</span></span>
<span class="line"><span>Meta-agent:</span></span>
<span class="line"><span> 1. Researches API monitoring patterns (parallel experts)</span></span>
<span class="line"><span> 2. Generates agent persona/system prompt</span></span>
<span class="line"><span> 3. Creates tool definitions</span></span>
<span class="line"><span> 4. Writes skill files</span></span>
<span class="line"><span> 5. Validates the generated agent works</span></span></code></pre></div><h3 id="pi-pi-meta-agent" tabindex="-1">Pi-Pi Meta-Agent <a class="header-anchor" href="#pi-pi-meta-agent" aria-label="Permalink to &quot;Pi-Pi Meta-Agent&quot;"></a></h3><p>From pi-vs-claude-code: a meta-agent that builds Pi agents using parallel research experts:</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>pi-pi agent dispatches to:</span></span>
<span class="line"><span> ext-expert (extension documentation)</span></span>
<span class="line"><span> theme-expert (theming conventions)</span></span>
<span class="line"><span> skill-expert (skill system)</span></span>
<span class="line"><span> config-expert (configuration)</span></span>
<span class="line"><span> tui-expert (TUI components)</span></span>
<span class="line"><span></span></span>
<span class="line"><span>Each expert:</span></span>
<span class="line"><span> 1. Fetches latest documentation (firecrawl + curl fallback)</span></span>
<span class="line"><span> 2. Synthesizes patterns</span></span>
<span class="line"><span> 3. Returns structured guidance</span></span>
<span class="line"><span></span></span>
<span class="line"><span>pi-pi generates complete extension code</span></span></code></pre></div><hr><h2 id="lesson-7-4-beyond-mcp--the-context-cost-trade-off" tabindex="-1">Lesson 7.4: Beyond MCP The Context Cost Trade-off <a class="header-anchor" href="#lesson-7-4-beyond-mcp--the-context-cost-trade-off" aria-label="Permalink to &quot;Lesson 7.4: Beyond MCP The Context Cost Trade-off&quot;"></a></h2><h3 id="the-matrix" tabindex="-1">The Matrix <a class="header-anchor" href="#the-matrix" aria-label="Permalink to &quot;The Matrix&quot;"></a></h3><table tabindex="0"><thead><tr><th>Approach</th><th>Context Cost</th><th>Portability</th><th>Agent-Invoked?</th><th>Best For</th></tr></thead><tbody><tr><td>MCP Server</td><td>HIGH (full context per call)</td><td>HIGH</td><td>Yes</td><td>Multi-client, standardized tools</td></tr><tr><td>CLI</td><td>MEDIUM</td><td>HIGH</td><td>No</td><td>80% of new tools</td></tr><tr><td>File Scripts</td><td>LOW (progressive disclosure)</td><td>MEDIUM</td><td>No</td><td>Context-sensitive tools</td></tr><tr><td>Skills</td><td>LOW</td><td>MEDIUM</td><td>Yes (auto-detect)</td><td>Agent-native behavior</td></tr></tbody></table><h3 id="the-insight" tabindex="-1">The Insight <a class="header-anchor" href="#the-insight" aria-label="Permalink to &quot;The Insight&quot;"></a></h3><p>MCP is not always the answer. For tools used by 1-2 agents, CLI + prime prompt is faster, cheaper on context, and easier to debug. MCP shines for tools used by many agents across many clients.</p><hr><h2 id="lesson-7-5-the-mac-mini-agent--physical-sandbox" tabindex="-1">Lesson 7.5: The Mac Mini Agent Physical Sandbox <a class="header-anchor" href="#lesson-7-5-the-mac-mini-agent--physical-sandbox" aria-label="Permalink to &quot;Lesson 7.5: The Mac Mini Agent Physical Sandbox&quot;"></a></h2><h3 id="architecture" tabindex="-1">Architecture <a class="header-anchor" href="#architecture" aria-label="Permalink to &quot;Architecture&quot;"></a></h3><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>Mac Mini (Agent Sandbox)</span></span>
<span class="line"><span> Steer (GUI automation) Swift, 14 commands</span></span>
<span class="line"><span> see, click, type, hotkey, ocr, find, wait</span></span>
<span class="line"><span> Drive (Terminal control) Python, 6 commands</span></span>
<span class="line"><span> session, run, send, poll, fanout</span></span>
<span class="line"><span> Listen (Job server) Python/FastAPI</span></span>
<span class="line"><span> POST /job, GET /job/{id}</span></span>
<span class="line"><span></span></span>
<span class="line"><span>Primary Machine (Dev)</span></span>
<span class="line"><span> Direct CLI client</span></span>
<span class="line"><span> start, get, list, latest, stop</span></span></code></pre></div><h3 id="sentinel-pattern" tabindex="-1">Sentinel Pattern <a class="header-anchor" href="#sentinel-pattern" aria-label="Permalink to &quot;Sentinel Pattern&quot;"></a></h3><p>Makes async terminal work deterministic:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Agent runs command, appends sentinel</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">long_running_task</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">; </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">echo</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;__DONE_abc123:</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">$?</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Agent polls for sentinel pattern</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">poll</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> logs</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> for</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;__DONE_abc123&quot;</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Extract exit code from sentinel</span></span></code></pre></div><hr><h2 id="lesson-7-6-always-on-agents" tabindex="-1">Lesson 7.6: Always-On Agents <a class="header-anchor" href="#lesson-7-6-always-on-agents" aria-label="Permalink to &quot;Lesson 7.6: Always-On Agents&quot;"></a></h2><h3 id="voice-to-command-bridge" tabindex="-1">Voice-to-Command Bridge <a class="header-anchor" href="#voice-to-command-bridge" aria-label="Permalink to &quot;Voice-to-Command Bridge&quot;"></a></h3><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>User speaks STT (faster-whisper) LLM transcribes to command Execute TTS response</span></span></code></pre></div><h3 id="job-server-pattern" tabindex="-1">Job Server Pattern <a class="header-anchor" href="#job-server-pattern" aria-label="Permalink to &quot;Job Server Pattern&quot;"></a></h3><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>Submit Queue Worker picks up Claude Code executes Result stored Check later</span></span></code></pre></div><h3 id="heartbeat-execution-from-paperclip" tabindex="-1">Heartbeat Execution (from Paperclip) <a class="header-anchor" href="#heartbeat-execution-from-paperclip" aria-label="Permalink to &quot;Heartbeat Execution (from Paperclip)&quot;"></a></h3><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>Timer fires Check for queued work Wake agent Agent executes Agent sleeps</span></span></code></pre></div><p>No continuous running. Agents wake, work, and sleep on a schedule.</p><h3 id="scheduling-strategies" tabindex="-1">Scheduling Strategies <a class="header-anchor" href="#scheduling-strategies" aria-label="Permalink to &quot;Scheduling Strategies&quot;"></a></h3><table tabindex="0"><thead><tr><th>Strategy</th><th>Pattern</th><th>Use Case</th></tr></thead><tbody><tr><td>Fixed interval</td><td>Every N minutes/hours/days</td><td>Brand monitoring, price tracking</td></tr><tr><td>Event-triggered</td><td>Webhook wake agent</td><td>CI/CD pipelines, PR reviews</td></tr><tr><td>Predictive</td><td>Learn optimal check times</td><td>Traffic monitoring, anomaly detection</td></tr><tr><td>Cascade</td><td>Agent A finishes Agent B starts</td><td>Data pipeline, ETL workflows</td></tr></tbody></table><h3 id="openclaw-the-always-on-employee" tabindex="-1">OpenClaw: The Always-On Employee <a class="header-anchor" href="#openclaw-the-always-on-employee" aria-label="Permalink to &quot;OpenClaw: The Always-On Employee&quot;"></a></h3><p>OpenClaw is a daemon-style agent that runs as a background service:</p><div class="language-yaml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">yaml</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># openclaw-config.yaml</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">agent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;brand-monitor&quot;</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> heartbeat</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">300</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # every 5 minutes</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> max_sessions</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">1</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> wake_command</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;claude -p &#39;Check brand mentions since last run&#39;&quot;</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> sleep_command</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;pkill -f &#39;claude.*brand-monitor&#39;&quot;</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> log_path</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;/var/log/openclaw/brand-monitor.log&quot;</span></span></code></pre></div><p>It starts, checks for work, executes if needed, then goes back to sleep. No continuous billing, no context window overflow, no runaway loops. This is the pattern for production always-on agents.</p><h3 id="when-not-to-use-always-on" tabindex="-1">When NOT to Use Always-On <a class="header-anchor" href="#when-not-to-use-always-on" aria-label="Permalink to &quot;When NOT to Use Always-On&quot;"></a></h3><p>Always-on adds complexity. Before building one, verify you actually need it:</p><ul><li><strong>Batch jobs</strong> Cron is simpler and cheaper</li><li><strong>Real-time</strong> Event-driven architectures (webhooks, Kafka) outperform polling agents</li><li><strong>One-off</strong> Just run the agent once</li></ul><p>Always-on makes sense when you need adaptive scheduling, dynamic task generation, or autonomous decision-making about what to work on next.</p><hr><h2 id="lab-7-7-build-an-autoresearch-loop" tabindex="-1">Lab 7.7: Build an Autoresearch Loop <a class="header-anchor" href="#lab-7-7-build-an-autoresearch-loop" aria-label="Permalink to &quot;Lab 7.7: Build an Autoresearch Loop&quot;"></a></h2><p><strong>Objective</strong>: Agent runs experiment, measures result, logs it, decides keep/discard.</p><p><strong>Starter</strong>: <code>course/labs/L7-autoresearch/starter.py</code></p><p><strong>Checkpoints</strong>:</p><ol><li>Run code, measure baseline metric</li><li>Modify code (agent makes change)</li><li>Re-measure, compare, log</li><li>Discard if regression, keep if improvement</li><li>Include integrity guard (code hashing)</li></ol><h2 id="lab-7-8-meta-agent" tabindex="-1">Lab 7.8: Meta-Agent <a class="header-anchor" href="#lab-7-8-meta-agent" aria-label="Permalink to &quot;Lab 7.8: Meta-Agent&quot;"></a></h2><p><strong>Objective</strong>: Agent generates a new agent persona from documentation.</p><p><strong>Starter</strong>: <code>course/labs/L7-meta-agent/starter.py</code></p>`,62)])])}const g=a(n,[["render",l]]);export{c as __pageData,g as default};

View File

@ -1 +0,0 @@
import{c as a,Q as i,j as e,m as t}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"Module 7: Advanced Topics","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m7-advanced.md","filePath":"modules/m7-advanced.md","lastUpdated":1780491906000}'),n={name:"modules/m7-advanced.md"};function l(h,s,p,r,o,d){return i(),e("div",null,[...s[0]||(s[0]=[t("",62)])])}const g=a(n,[["render",l]]);export{c as __pageData,g as default};

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
import{c as t,Q as a,j as i,m as s}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"Module 8: Capstone — Production Multi-Agent System","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m8-capstone.md","filePath":"modules/m8-capstone.md","lastUpdated":1780488246000}'),n={name:"modules/m8-capstone.md"};function r(l,e,o,d,h,p){return a(),i("div",null,[...e[0]||(e[0]=[s("",54)])])}const g=t(n,[["render",r]]);export{u as __pageData,g as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"404.md":"BiCvjdaY","api-keys.md":"D2Kyj8T3","blog_index.md":"B5nL9faf","blog_posts_cascade-routing.md":"DvBM3TSf","blog_posts_choosing-security-level.md":"BYXRZEDN","blog_posts_mental-models.md":"BRY80gtq","blog_posts_repo-is-spec.md":"BxY1cXc_","blog_posts_security-ladder.md":"DQaqn6Yt","blog_posts_three-x-rule.md":"BHO6bhvz","blog_posts_verifier-pattern.md":"Gha_L_u5","blog_posts_vibe-vs-agentic.md":"7mduPfz1","blog_posts_what-is-an-agent.md":"BU2wUq_Y","blog_posts_why-multi-agent.md":"BVRIN2vH","buy.md":"qEifz7WE","certificate.md":"0V0n-TLl","checkout.md":"Ccj6L__h","checkout_cancel.md":"DwL5mulX","checkout_success.md":"CYTg6xhL","free-preview.md":"C5BtRucn","getting-started.md":"Boo_V9xC","index.md":"BNS2TR1g","labs_index.md":"sAzXzfkI","labs_l1-first-agent.md":"BwU9yf-G","labs_l2-context.md":"BexGm8_s","labs_l2-multi-tool.md":"Bj3Mb-oj","labs_l3-verifier.md":"xilrGGap","labs_l3-whitelist-hook.md":"DJtbL66Y","labs_l4-agent-chain.md":"D89P8dwJ","labs_l4-multi-team.md":"DmSK8e2P","labs_l5-cicd.md":"Dz1Jl78z","labs_l5-observability.md":"BDpqVYjT","labs_l6-cost-optimization.md":"CabFK4GB","labs_l6-eval-harness.md":"CBwH6xOR","labs_l7-autoresearch.md":"BYlzPLYo","labs_l7-meta-agent.md":"iTswbOPg","modules_competitive-analysis.md":"BHMHacei","modules_curriculum.md":"D7UeKRfo","modules_debate.md":"DWctKMlA","modules_feynman.md":"DBw5sPBP","modules_field-manual.md":"hmt_NLf1","modules_m1-foundations.md":"DHFyTzWj","modules_m2-architecture.md":"DVowtmf9","modules_m3-safety.md":"RiQQ_HWX","modules_m4-orchestration.md":"DFLcAKBv","modules_m5-production.md":"DTkLIrwQ","modules_m6-economics.md":"HihVEOPb","modules_m7-advanced.md":"FtCudlFk","modules_m8-capstone.md":"D1AXKCqv","modules_non-technical.md":"BnvuUCRo","modules_reference-stack.md":"D9FXitvn","modules_software-factory.md":"C5Yf8Zwe","modules_tool-reference.md":"B40mlgZJ","public_certificate_template.md":"Cg1kPB1b","resources.md":"DcUu1NrK","skills.md":"BX3RBeCK","troubleshooting.md":"B6difx2I","verify.md":"Cl5ZMWNd"}
{"404.md":"BiCvjdaY","api-keys.md":"D2Kyj8T3","blog_index.md":"B5nL9faf","blog_posts_cascade-routing.md":"DvBM3TSf","blog_posts_choosing-security-level.md":"BYXRZEDN","blog_posts_mental-models.md":"BRY80gtq","blog_posts_repo-is-spec.md":"BxY1cXc_","blog_posts_security-ladder.md":"DQaqn6Yt","blog_posts_three-x-rule.md":"BHO6bhvz","blog_posts_verifier-pattern.md":"Gha_L_u5","blog_posts_vibe-vs-agentic.md":"7mduPfz1","blog_posts_what-is-an-agent.md":"BU2wUq_Y","blog_posts_why-multi-agent.md":"BVRIN2vH","buy.md":"qEifz7WE","certificate.md":"0V0n-TLl","checkout.md":"Ccj6L__h","checkout_cancel.md":"DwL5mulX","checkout_success.md":"CYTg6xhL","downloads.md":"BkgENRDR","free-preview.md":"C5BtRucn","getting-started.md":"Boo_V9xC","index.md":"BNS2TR1g","labs_index.md":"sAzXzfkI","labs_l1-first-agent.md":"BwU9yf-G","labs_l2-context.md":"BexGm8_s","labs_l2-multi-tool.md":"Bj3Mb-oj","labs_l3-verifier.md":"xilrGGap","labs_l3-whitelist-hook.md":"DJtbL66Y","labs_l4-agent-chain.md":"D89P8dwJ","labs_l4-multi-team.md":"DmSK8e2P","labs_l5-cicd.md":"Dz1Jl78z","labs_l5-observability.md":"BDpqVYjT","labs_l6-cost-optimization.md":"CabFK4GB","labs_l6-eval-harness.md":"CBwH6xOR","labs_l7-autoresearch.md":"BYlzPLYo","labs_l7-meta-agent.md":"iTswbOPg","modules_competitive-analysis.md":"BHMHacei","modules_curriculum.md":"D7UeKRfo","modules_debate.md":"DWctKMlA","modules_feynman.md":"DBw5sPBP","modules_field-manual.md":"hmt_NLf1","modules_m1-foundations.md":"DHFyTzWj","modules_m2-architecture.md":"DVowtmf9","modules_m3-safety.md":"RiQQ_HWX","modules_m4-orchestration.md":"DFLcAKBv","modules_m5-production.md":"DTkLIrwQ","modules_m6-economics.md":"HihVEOPb","modules_m7-advanced.md":"B8r6DZG5","modules_m8-capstone.md":"CTcrNOvN","modules_non-technical.md":"BnvuUCRo","modules_reference-stack.md":"D9FXitvn","modules_software-factory.md":"C5Yf8Zwe","modules_tool-reference.md":"B40mlgZJ","public_certificate_template.md":"Cg1kPB1b","resources.md":"DcUu1NrK","skills.md":"BX3RBeCK","troubleshooting.md":"B6difx2I","verify.md":"Cl5ZMWNd"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

128
site/downloads.md Normal file
View File

@ -0,0 +1,128 @@
---
title: Downloads - Agentic Engineering the Hard Way
---
# Course Downloads
Welcome! Your purchase gives you access to all course materials below. Each package is a ZIP file — extract and start learning.
<div class="download-grid">
<div class="dl-card">
<span class="dl-icon material-symbols-outlined">package_2</span>
<h3>Full Course Package</h3>
<p class="dl-size">147 MB · 415 files</p>
<ul>
<li>8 modules (markdown + code examples)</li>
<li>13 labs (starter + solution files)</li>
<li>20 skill kits (7 categories)</li>
<li>Install scripts (PowerShell + bash)</li>
</ul>
<a href="/dist/course-only.zip" class="btn-p btn-primary">Download Course</a>
</div>
<div class="dl-card">
<span class="dl-icon material-symbols-outlined">workspace_premium</span>
<h3>Enterprise Bundle</h3>
<p class="dl-size">191 MB · all course + extras</p>
<ul>
<li>Everything in Full Course Package</li>
<li>Capstone reference implementation</li>
<li>Brand Monitor full source</li>
<li>All 7 skill kits as standalone ZIPs</li>
</ul>
<a href="/dist/enterprise.zip" class="btn-p btn-primary">Download Enterprise</a>
</div>
</div>
## Individual Skill Kits
| Kit | Size | Download |
|-----|------|----------|
| Security Foundation | 9 KB | [Download](/dist/security-foundation.zip) |
| Multi-Agent Orchestration | 7 KB | [Download](/dist/multi-agent-orch.zip) |
| Verifier Pro | 4 KB | [Download](/dist/verifier-pro.zip) |
| Task Discipline | 2 KB | [Download](/dist/task-discipline.zip) |
| Autoresearch | 3 KB | [Download](/dist/autoresearch.zip) |
| Observability | 2 KB | [Download](/dist/observability.zip) |
| CEO Board | 3 KB | [Download](/dist/ceo-board.zip) |
## Getting Started
```bash
# 1. Extract the course package
unzip course-only.zip -d agentic-engineering
cd agentic-engineering
# 2. Install dependencies
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install anthropic openai
# 3. Start with Lab 1
cd course/labs/L1-first-agent/
python starter.py test.txt "What is this file about?"
```
## Support
Questions? Email [artale@fdsa.agency](mailto:artale@fdsa.agency)
<style>
.download-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 24px;
margin: 32px 0;
}
.dl-card {
background: var(--vp-c-bg-soft);
border: 1px solid var(--vp-c-border);
border-radius: 12px;
padding: 28px;
}
.dl-icon {
font-size: 32px;
color: var(--vp-c-brand-1);
margin-bottom: 12px;
display: block;
}
.dl-card h3 {
font-size: 18px;
margin-bottom: 4px;
}
.dl-size {
font-size: 12px;
color: var(--vp-c-text-3);
margin-bottom: 16px;
}
.dl-card ul {
list-style: none;
padding: 0;
margin-bottom: 20px;
}
.dl-card li {
padding: 4px 0;
font-size: 13px;
color: var(--vp-c-text-2);
}
.dl-card li::before {
content: "→";
color: var(--vp-c-brand-1);
margin-right: 8px;
}
.btn-p {
display: inline-block;
padding: 12px 24px;
background: var(--vp-c-brand-1);
color: #fff;
text-decoration: none;
border-radius: 8px;
font-weight: 600;
font-size: 14px;
}
.btn-p:hover {
background: var(--vp-c-brand-3);
}
</style>

View File

@ -141,6 +141,81 @@ poll logs for "__DONE_abc123"
# Extract exit code from sentinel
```
### Why Physical Sandbox Matters
Cloud agents are ephemeral. A Mac Mini agent is persistent — it has files, databases, browser sessions, and GPU state that survive agent restarts. This matters for:
- **Long-running experiments** that take hours or days
- **Browser automation** with persistent login sessions
- **Local model inference** where GPU memory is precious
- **Legacy system access** that can't be moved to cloud
The physical sandbox pattern works with any mini PC — Mac Mini, Intel NUC, Raspberry Pi 5, or repurposed laptop. The key is a dedicated machine that the agent can control without affecting your primary workstation.
---
## Lesson 7.6: Multi-Model Strategies
### Why One Model Isn't Enough
No single model is best at everything. Frontier models (Claude Opus, GPT-4o) excel at reasoning but cost 10-100x more than small models (Haiku, Flash, Nano). The strategy: use the right model for each subtask.
### Model Heterogeneity in Practice
```
Task: "Analyze this codebase for security vulnerabilities"
Step 1: File Discovery (Haiku — $0.0003/run)
→ List all files, grep for patterns
→ Cheap, fast, 100% accuracy needed
Step 2: Vulnerability Analysis (Sonnet — $0.008/run)
→ Read each suspicious file, classify vulnerability
→ Needs reasoning, but not frontier-level
Step 3: Report Generation (Opus — $0.03/run)
→ Synthesize findings into executive report
→ Needs highest quality output
```
Total cost: ~$0.04 instead of ~$0.30 if done entirely with Opus. **87% savings** with no quality loss on the critical path.
### The 3-Tier Cascade Pattern
```python
TIERS = {
"cheap": {"model": "claude-haiku", "max_tokens": 4000, "cost_per_k": 0.00025},
"mid": {"model": "claude-sonnet", "max_tokens": 8000, "cost_per_k": 0.003},
"premium": {"model": "claude-opus", "max_tokens": 16000, "cost_per_k": 0.015},
}
def cascade(prompt, complexity="mid"):
"""Route to appropriate tier based on task complexity."""
if complexity == "low":
return call_model(TIERS["cheap"], prompt)
elif complexity == "high":
return call_model(TIERS["premium"], prompt)
else:
return call_model(TIERS["mid"], prompt)
```
### Model Selection Decision Tree
```
Is the task deterministic? (grep, sort, count)
→ Use cheap model (Haiku/Flash)
Does the task need reasoning? (analyze, explain)
→ Use mid model (Sonnet/4o-mini)
Is the output customer-facing? (report, email, memo)
→ Use premium model (Opus/4o)
Will this code be deployed to production?
→ Run through ALL three tiers in sequence (cascade)
→ Cheap for bulk work, mid for analysis, premium for final review
```
---
## Lesson 7.6: Always-On Agents

View File

@ -145,6 +145,59 @@ Apply security layer:
```
[ ] Architecture document (one page, with diagram)
[ ] All agent source code with system prompts
[ ] Agent configuration files (YAML/JSON)
[ ] Tool definitions with reasoning parameters
[ ] Security hooks configuration (L3+)
[ ] Golden dataset (10+ test cases with expected outputs)
[ ] Test script showing all agents respond correctly
[ ] Cost analysis per session
[ ] README with setup instructions
[ ] Self-assessment against rubric
---
## Production Readiness Checklist
Before submitting, verify your system meets these production standards:
### Reliability
- [ ] All tools include error handling (FileNotFoundError, API timeout, etc.)
- [ ] MAX_ITERATIONS set on every agent loop (no infinite loops)
- [ ] Retry logic with exponential backoff for API calls
- [ ] Agent gracefully handles tool failures instead of crashing
### Security
- [ ] Minimum L3 blacklist hook installed on bash access
- [ ] Domain locking prevents agents from accessing files outside their scope
- [ ] Verifier agent has read-only tools only (no edit/bash)
- [ ] Damage-control rules prevent rm -rf, DROP TABLE, etc.
### Observability
- [ ] Every tool call logged to file (JSONL format)
- [ ] Cost tracked per session
- [ ] Agent loop depth monitored
- [ ] Errors logged with stack traces
### Economics
- [ ] Cost estimate per session documented
- [ ] Cascade routing implemented where appropriate
- [ ] Iteration limits set to minimize token waste
- [ ] Model selection justified (why this model for this agent?)
---
## Graduation Criteria
Your capstone passes if it meets ALL of these:
1. **Three or more agents** that communicate and coordinate
2. **Security at L3+** (blacklist or whitelist hook)
3. **Working test script** that demonstrates all agents responding
4. **Documented cost estimate** per session
5. **Observability** — at least one trace log from a complete run
6. **Self-assessment** against the rubric with honest notes on what you'd improve
The capstone is not about perfection. It's about demonstrating you understand the full stack — from tool design to security to economics. A passing capstone with honest self-assessment is worth more than a perfect one with no reflection.
[ ] Mental model files for each agent
[ ] Security configuration (damage-control rules)
[ ] Verifier agent (if applicable)