---
title: "Cadence Over Volume — Orchestrating Multiple Projects with AI Agents"
description: "Concrete architecture for maintaining a steady cadence across parallel projects: automations.json, agent memory, and cross-project knowledge compounding."
created: 2026-05-11T23:00:00+02:00
updated: 2026-05-13T12:00:00+02:00
tags: ["AI", "KittyClaw", "Tooling", "Behind the scenes"]
image: /images/blog/cadence-agents-5-projets-cover.webp
card: /images/blog/cadence-agents-5-projets-card.webp
---

Running multiple projects in parallel with AI agents produces a counter-intuitive effect: without a compounding infrastructure, every run starts from zero. Memory stays local to the project, discovered patterns don't migrate, and cadence depends entirely on human availability. What follows describes the infrastructure that solves this problem — and why regularity is its primary condition.

## Anatomy of an Orchestrated Project

Each project hosts a `.agents/` directory with four elements:

```
.agents/
├── preamble.md          # context injected into every agent run
├── automations.json     # trigger pipelines
├── {agent}/
│   ├── SKILL.md         # stable domain instructions
│   └── memory.md        # accumulated learnings, run after run
```

**`preamble.md`** is the coherence vector. It contains shared rules — git workflow, commit conventions, API access — injected into every agent's context at startup. What lives in `preamble.md` doesn't need to be repeated in every `SKILL.md`.

**`automations.json`** defines the pipelines. The core automation, `assignee-dispatch`, runs three actions as soon as a ticket moves to Todo with an assignee:

```json
{
  "id": "assignee-dispatch",
  "trigger": { "type": "ticketInColumn", "columns": ["Todo"] },
  "conditions": [
    { "type": "assignedTo", "slugs": ["programmer", "content-writer", "qa-tester", "..."] },
    { "type": "ticketCountInColumn", "columns": ["InProgress"],
      "sameAssignee": true, "operator": "==", "value": 0 }
  ],
  "actions": [
    { "type": "moveTicketStatus", "to": "InProgress" },
    { "type": "runAgent", "agent": "{assignee}", "model": "claude-sonnet-4-6" },
    { "type": "commitAgentMemory", "agent": "{assignee}" }
  ]
}
```

The `ticketCountInColumn == 0` condition prevents uncontrolled parallelism: an agent won't start a new ticket while it has one in progress. The final action, `commitAgentMemory`, automatically persists the agent's memory after every run — this is the key to compounding.

## Memory as a Progression Tool

Where most AI agent setups remain stateless, `memory.md` introduces structured persistent state. Each agent maintains a file of lessons with a `[+N]` counter that tracks how many times each lesson has been reapplied:

```markdown
## API / tooling [+5]
- curl on Windows mangles UTF-8 in JSON bodies.
  Use python3 urllib.request instead. [+2]
- PR creation: gh not available;
  az repos pr create has permission errors. [+2]

## SVG inline in Markdown [+3]
- NEVER use <marker> + marker-end="url(#id)" in inline SVGs. [+3]
- Draw arrowheads as explicit <polygon> elements.
```

The counter serves two functions: it shows which lessons have value (they recur), and it guides consolidation — when an entry reaches `[5+]`, it migrates to `SKILL.md` as a stable rule. Entries at `[0]` are removed.

This distinction between `SKILL.md` (stable rules, rarely modified) and `memory.md` (active learnings, updated each run) is structural. It prevents memory from becoming a catch-all and enforces discipline about what is worth retaining.

## Cross-Project Compounding

Agents learn from their mistakes — once an agent hits a problem, `memory.md` ensures it never hits the same one again. But the real step change happens when projects start sharing entire capabilities.

### Shared image generation

A content-writer on Bloomii needs an illustration. A content-writer on Ekioo needs a cover. Neither knows how gpt-image-2 works, neither manages an API key, neither worries about rate limiting.

A single processor runs on a 10-minute cron in the central Workspace. Agents from any project submit a request via `image-enqueue.mjs`, get an ID back, and move on. The processor manages the queue, pauses when the quota is hit, resumes automatically. The agent gets notified when the image is ready.

```bash
node C:/IA/Workspace/.agents/tools/image-enqueue.mjs \
  --prompt "..." --output path/to/cover.webp \
  --project bloomii --ticket 189
```

One tool, one processor, N consumer projects. Adding a sixth project requires zero configuration — just a call to `image-enqueue.mjs`.

<svg viewBox="0 0 700 200" xmlns="http://www.w3.org/2000/svg" style="width:100%;max-width:700px;background:#0d1117;border-radius:8px;display:block;margin:2rem auto">
<defs>
<pattern id="cen-img-dots" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="1" fill="#1c2128"/>
</pattern>
<filter id="cen-img-gg" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="3" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="cen-img-gp" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="4" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
</defs>
<rect width="700" height="200" fill="#0d1117"/>
<rect width="700" height="200" fill="url(#cen-img-dots)"/>
<rect x="20" y="20" width="130" height="44" rx="6" fill="#0d2818" stroke="#3fb950" stroke-width="1.5" filter="url(#cen-img-gg)"/>
<rect x="20" y="20" width="4" height="44" rx="2" fill="#3fb950"/>
<text x="88" y="47" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="12">Bloomii</text>
<rect x="20" y="78" width="130" height="44" rx="6" fill="#0d2818" stroke="#3fb950" stroke-width="1.5" filter="url(#cen-img-gg)"/>
<rect x="20" y="78" width="4" height="44" rx="2" fill="#3fb950"/>
<text x="88" y="105" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="12">Ekioo</text>
<rect x="20" y="136" width="130" height="44" rx="6" fill="#0d2818" stroke="#3fb950" stroke-width="1.5" filter="url(#cen-img-gg)"/>
<rect x="20" y="136" width="4" height="44" rx="2" fill="#3fb950"/>
<text x="88" y="163" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="12">Kalceo</text>
<text x="88" y="13" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="10">agents</text>
<line x1="150" y1="42" x2="240" y2="80" stroke="#3fb950" stroke-width="1.5" opacity="0.6"/>
<polygon points="234,75 242,80 234,85" fill="#3fb950" opacity="0.6"/>
<line x1="150" y1="100" x2="240" y2="100" stroke="#3fb950" stroke-width="1.5" opacity="0.6"/>
<polygon points="234,96 242,100 234,104" fill="#3fb950" opacity="0.6"/>
<line x1="150" y1="158" x2="240" y2="120" stroke="#3fb950" stroke-width="1.5" opacity="0.6"/>
<polygon points="234,115 242,120 234,125" fill="#3fb950" opacity="0.6"/>
<rect x="244" y="60" width="160" height="80" rx="8" fill="#150d2a" stroke="#a371f7" stroke-width="2" filter="url(#cen-img-gp)"/>
<rect x="244" y="60" width="160" height="4" rx="2" fill="#a371f7"/>
<text x="324" y="90" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="13" font-weight="bold">image-queue.json</text>
<text x="324" y="110" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="10">single queue · cron /10min</text>
<text x="324" y="126" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="10">auto rate limit</text>
<line x1="404" y1="100" x2="470" y2="100" stroke="#a371f7" stroke-width="1.5" opacity="0.7"/>
<polygon points="464,96 472,100 464,104" fill="#a371f7" opacity="0.7"/>
<rect x="474" y="70" width="120" height="60" rx="8" fill="#1a1a0d" stroke="#d29922" stroke-width="1.5" filter="url(#cen-img-gg)"/>
<rect x="474" y="70" width="4" height="60" rx="2" fill="#d29922"/>
<text x="537" y="96" text-anchor="middle" fill="#d29922" font-family="monospace" font-size="12" font-weight="bold">gpt-image-2</text>
<text x="537" y="114" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="10">CDP processor</text>
<line x1="594" y1="100" x2="630" y2="100" stroke="#d29922" stroke-width="1.5" opacity="0.7"/>
<polygon points="624,96 632,100 624,104" fill="#d29922" opacity="0.7"/>
<text x="665" y="104" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="11">.webp</text>
</svg>

### Centralized mailbox — automatic dispatch

All projects share a single mailbox, exposed through VizMail (a local HTTP server with 40+ REST endpoints). When an email arrives — a Kalceo client reply, Bloomii reader feedback, an Ekioo contact form — it gets automatically dispatched to the relevant project as a KittyClaw ticket. The appropriate agent picks it up with no human intervention.

The result: one mailbox to monitor, zero manual sorting, and every project receives its relevant emails as actionable tasks for agents.

<svg viewBox="0 0 700 200" xmlns="http://www.w3.org/2000/svg" style="width:100%;max-width:700px;background:#0d1117;border-radius:8px;display:block;margin:2rem auto">
<defs>
<pattern id="cen-mail-dots" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="1" fill="#1c2128"/>
</pattern>
<filter id="cen-mail-gb" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="3" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="cen-mail-gp" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="4" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="cen-mail-gg" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="3" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
</defs>
<rect width="700" height="200" fill="#0d1117"/>
<rect width="700" height="200" fill="url(#cen-mail-dots)"/>
<rect x="20" y="60" width="120" height="80" rx="8" fill="#0d1a2a" stroke="#58a6ff" stroke-width="2" filter="url(#cen-mail-gb)"/>
<rect x="20" y="60" width="4" height="80" rx="2" fill="#58a6ff"/>
<text x="82" y="93" text-anchor="middle" fill="#58a6ff" font-family="monospace" font-size="13" font-weight="bold">IMAP</text>
<text x="82" y="113" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="10">single mailbox</text>
<text x="82" y="128" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="10">lain@ekioo.com</text>
<line x1="140" y1="100" x2="218" y2="100" stroke="#58a6ff" stroke-width="1.5" opacity="0.7"/>
<polygon points="212,96 220,100 212,104" fill="#58a6ff" opacity="0.7"/>
<rect x="222" y="50" width="190" height="100" rx="8" fill="#150d2a" stroke="#a371f7" stroke-width="2" filter="url(#cen-mail-gp)"/>
<rect x="222" y="50" width="190" height="4" rx="2" fill="#a371f7"/>
<text x="317" y="82" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="13" font-weight="bold">VizMail</text>
<text x="317" y="100" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="10">classify + dispatch</text>
<text x="317" y="118" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="10">→ KittyClaw ticket</text>
<text x="317" y="136" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="10">per project</text>
<line x1="412" y1="75" x2="490" y2="48" stroke="#3fb950" stroke-width="1.5" opacity="0.6"/>
<polygon points="484,43 492,48 484,53" fill="#3fb950" opacity="0.6"/>
<line x1="412" y1="100" x2="490" y2="100" stroke="#3fb950" stroke-width="1.5" opacity="0.6"/>
<polygon points="484,96 492,100 484,104" fill="#3fb950" opacity="0.6"/>
<line x1="412" y1="125" x2="490" y2="152" stroke="#3fb950" stroke-width="1.5" opacity="0.6"/>
<polygon points="484,147 492,152 484,157" fill="#3fb950" opacity="0.6"/>
<rect x="494" y="24" width="180" height="44" rx="6" fill="#0d2818" stroke="#3fb950" stroke-width="1.5" filter="url(#cen-mail-gg)"/>
<rect x="494" y="24" width="4" height="44" rx="2" fill="#3fb950"/>
<text x="587" y="42" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="11">Kalceo</text>
<text x="587" y="58" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="9">client reply → ticket</text>
<rect x="494" y="78" width="180" height="44" rx="6" fill="#0d2818" stroke="#3fb950" stroke-width="1.5" filter="url(#cen-mail-gg)"/>
<rect x="494" y="78" width="4" height="44" rx="2" fill="#3fb950"/>
<text x="587" y="96" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="11">Bloomii</text>
<text x="587" y="112" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="9">reader feedback → ticket</text>
<rect x="494" y="132" width="180" height="44" rx="6" fill="#0d2818" stroke="#3fb950" stroke-width="1.5" filter="url(#cen-mail-gg)"/>
<rect x="494" y="132" width="4" height="44" rx="2" fill="#3fb950"/>
<text x="587" y="150" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="11">Ekioo</text>
<text x="587" y="166" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="9">contact form → ticket</text>
</svg>

### Centralized X branding

Four projects feed a single X account (`@LainAgent_AI`). Each project has its own publishing tool (`x-post-tweet.mjs`), but the editorial strategy lives in a single file — `x-strategy.md` — in the central Workspace: content pillars, voice, engagement rules.

A community-manager drafts, lain approves. No audience fragmentation across four ghost accounts. A single account building authority, fed by four different content sources.

<svg viewBox="0 0 700 200" xmlns="http://www.w3.org/2000/svg" style="width:100%;max-width:700px;background:#0d1117;border-radius:8px;display:block;margin:2rem auto">
<defs>
<pattern id="cen-x-dots" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="1" fill="#1c2128"/>
</pattern>
<filter id="cen-x-gg" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="3" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="cen-x-gp" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="4" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
</defs>
<rect width="700" height="200" fill="#0d1117"/>
<rect width="700" height="200" fill="url(#cen-x-dots)"/>
<rect x="20" y="20" width="150" height="40" rx="6" fill="#0d2818" stroke="#3fb950" stroke-width="1.5" filter="url(#cen-x-gg)"/>
<rect x="20" y="20" width="4" height="40" rx="2" fill="#3fb950"/>
<text x="98" y="45" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="11">Ekioo · AI/Craft</text>
<rect x="20" y="70" width="150" height="40" rx="6" fill="#0d2818" stroke="#3fb950" stroke-width="1.5" filter="url(#cen-x-gg)"/>
<rect x="20" y="70" width="4" height="40" rx="2" fill="#3fb950"/>
<text x="98" y="95" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="11">Kalceo · BTP</text>
<rect x="20" y="120" width="150" height="40" rx="6" fill="#0d2818" stroke="#3fb950" stroke-width="1.5" filter="url(#cen-x-gg)"/>
<rect x="20" y="120" width="4" height="40" rx="2" fill="#3fb950"/>
<text x="98" y="145" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="11">Bloomii · Green</text>
<text x="98" y="13" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="10">content pillars</text>
<line x1="170" y1="40" x2="260" y2="86" stroke="#3fb950" stroke-width="1.5" opacity="0.6"/>
<polygon points="254,81 262,86 254,91" fill="#3fb950" opacity="0.6"/>
<line x1="170" y1="90" x2="260" y2="94" stroke="#3fb950" stroke-width="1.5" opacity="0.6"/>
<polygon points="254,90 262,94 254,98" fill="#3fb950" opacity="0.6"/>
<line x1="170" y1="140" x2="260" y2="104" stroke="#3fb950" stroke-width="1.5" opacity="0.6"/>
<polygon points="254,99 262,104 254,109" fill="#3fb950" opacity="0.6"/>
<rect x="264" y="60" width="180" height="80" rx="8" fill="#150d2a" stroke="#a371f7" stroke-width="2" filter="url(#cen-x-gp)"/>
<rect x="264" y="60" width="180" height="4" rx="2" fill="#a371f7"/>
<text x="354" y="90" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="12" font-weight="bold">x-strategy.md</text>
<text x="354" y="108" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="10">single voice · approval</text>
<text x="354" y="126" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="10">community-manager + lain</text>
<line x1="444" y1="100" x2="510" y2="100" stroke="#a371f7" stroke-width="1.5" opacity="0.7"/>
<polygon points="504,96 512,100 504,104" fill="#a371f7" opacity="0.7"/>
<rect x="514" y="66" width="166" height="68" rx="8" fill="#1a1a0d" stroke="#d29922" stroke-width="1.5" filter="url(#cen-x-gg)"/>
<rect x="514" y="66" width="4" height="68" rx="2" fill="#d29922"/>
<text x="600" y="94" text-anchor="middle" fill="#d29922" font-family="monospace" font-size="14" font-weight="bold">@LainAgent_AI</text>
<text x="600" y="114" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="10">single account · authority</text>
<rect x="20" y="170" width="150" height="22" rx="4" fill="#1c1c2a" stroke="#58a6ff" stroke-width="1" opacity="0.6"/>
<text x="98" y="185" text-anchor="middle" fill="#58a6ff" font-family="monospace" font-size="9">Vizmail · Tooling</text>
<line x1="170" y1="181" x2="260" y2="114" stroke="#58a6ff" stroke-width="1" opacity="0.4"/>
<polygon points="254,109 262,114 254,119" fill="#58a6ff" opacity="0.4"/>
</svg>

### Hub-and-spoke knowledge base

The central Workspace provides shared infrastructure: API documentation (KittyClaw, Brevo, Chrome CDP), centralized credentials, CLI tools. Each project maintains its own domain knowledge base — BTP regulation and artisan pain points for Kalceo, editorial research packs and distribution guides for Bloomii.

A Kalceo agent sending a newsletter and a Bloomii agent scheduling a LinkedIn post use the same Brevo token, the same documentation, the same call patterns — without knowing the other exists. Infrastructure knowledge is written once, consumed everywhere.

<svg viewBox="0 0 700 240" xmlns="http://www.w3.org/2000/svg" style="width:100%;max-width:700px;background:#0d1117;border-radius:8px;display:block;margin:2rem auto">
<defs>
<pattern id="cen-kb-dots" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="1" fill="#1c2128"/>
</pattern>
<filter id="cen-kb-gp" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="4" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="cen-kb-gg" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="3" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="cen-kb-gb" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="3" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
</defs>
<rect width="700" height="240" fill="#0d1117"/>
<rect width="700" height="240" fill="url(#cen-kb-dots)"/>
<text x="350" y="22" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="10">central hub — Workspace</text>
<rect x="200" y="32" width="300" height="80" rx="8" fill="#150d2a" stroke="#a371f7" stroke-width="2" filter="url(#cen-kb-gp)"/>
<rect x="200" y="32" width="300" height="4" rx="2" fill="#a371f7"/>
<text x="350" y="58" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="12" font-weight="bold">knowledge/ · tools/ · credentials</text>
<rect x="218" y="68" width="84" height="20" rx="10" fill="#1c1c2a" stroke="#a371f7" stroke-width="1"/>
<text x="260" y="82" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="9">KittyClaw API</text>
<rect x="308" y="68" width="84" height="20" rx="10" fill="#1c1c2a" stroke="#a371f7" stroke-width="1"/>
<text x="350" y="82" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="9">Brevo API</text>
<rect x="398" y="68" width="84" height="20" rx="10" fill="#1c1c2a" stroke="#a371f7" stroke-width="1"/>
<text x="440" y="82" text-anchor="middle" fill="#a371f7" font-family="monospace" font-size="9">Chrome CDP</text>
<line x1="280" y1="112" x2="140" y2="148" stroke="#a371f7" stroke-width="1.5" opacity="0.5"/>
<polygon points="134,143 142,148 134,153" fill="#a371f7" opacity="0.5"/>
<line x1="350" y1="112" x2="350" y2="148" stroke="#a371f7" stroke-width="1.5" opacity="0.5"/>
<polygon points="346,142 350,150 354,142" fill="#a371f7" opacity="0.5"/>
<line x1="420" y1="112" x2="560" y2="148" stroke="#a371f7" stroke-width="1.5" opacity="0.5"/>
<polygon points="554,143 562,148 554,153" fill="#a371f7" opacity="0.5"/>
<text x="350" y="140" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="10">spoke — project domain</text>
<rect x="20" y="152" width="200" height="70" rx="6" fill="#0d2818" stroke="#3fb950" stroke-width="1.5" filter="url(#cen-kb-gg)"/>
<rect x="20" y="152" width="4" height="70" rx="2" fill="#3fb950"/>
<text x="122" y="174" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="12" font-weight="bold">Kalceo</text>
<text x="122" y="192" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="9">BTP regulation</text>
<text x="122" y="206" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="9">artisan pain points · quotes</text>
<rect x="250" y="152" width="200" height="70" rx="6" fill="#0d2818" stroke="#3fb950" stroke-width="1.5" filter="url(#cen-kb-gg)"/>
<rect x="250" y="152" width="4" height="70" rx="2" fill="#3fb950"/>
<text x="352" y="174" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="12" font-weight="bold">Bloomii</text>
<text x="352" y="192" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="9">editorial pillars · sources</text>
<text x="352" y="206" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="9">distribution packs</text>
<rect x="480" y="152" width="200" height="70" rx="6" fill="#0d1a2a" stroke="#58a6ff" stroke-width="1.5" filter="url(#cen-kb-gb)"/>
<rect x="480" y="152" width="4" height="70" rx="2" fill="#58a6ff"/>
<text x="582" y="174" text-anchor="middle" fill="#e6edf3" font-family="monospace" font-size="12" font-weight="bold">Ekioo · Vizmail</text>
<text x="582" y="192" text-anchor="middle" fill="#8b949e" font-family="monospace" font-size="9">no domain KB</text>
<text x="582" y="206" text-anchor="middle" fill="#58a6ff" font-family="monospace" font-size="9">consume the hub</text>
</svg>

## Cadence as a Health Signal

Thirty to fifty tickets processed per week across all projects. That number isn't a productivity target — it's a system health indicator.

When a project's Todo column accumulates without draining, the signal is clear: the backlog is poorly prioritized, or the project lacks agents suited to the queued tasks. The weekly cadence makes this imbalance immediately visible.

The `evaluator` agent calculates scores after each closed ticket: first-pass success rate, feedback compliance, delivery quality. These metrics measure whether compounding is actually working — a rising first-pass success rate means agents are improving run after run. A stagnating rate signals a memory that's no longer being fed.

An agent that doesn't run regularly doesn't accumulate usable memory: it resets each time, repeats the same mistakes, asks the same clarifying questions. Regularity isn't a publishing discipline — it's the condition for the system to learn.

## Conclusion

The infrastructure fits in four files per agent: `preamble.md`, `automations.json`, `SKILL.md`, `memory.md`. What makes it effective is feeding discipline: commit memory after every run (the `commitAgentMemory` action handles this automatically), remove entries at `[0]`, promote lessons at `[5+]` to `SKILL.md`.

The only rule that matters: never miss two weeks in a row. One quiet week doesn't break the cadence. Two weeks break agent memory, project coherence, and the SEO signal.

Consistency first. Volume second.
