docs: agent platform design v2 — the agent algebra (agreed 2026-07-21)
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Unified redesign: two axioms (everything that can receive work is an Agent with a Card and availability function; one verb submit(task, target)) from which the v1 rules follow as theorems — per-model queues (scarcity), quota parking (a(t)=0), reflect-as-task, backbone swap as constraint edit, the Claude Code loop as an ordinary consumer, human-as-agent (KB waiting column = his inbox). Adds what v1 lacked: trust classes (vault=trusted only), prompt-injection taint boundary, always-ask escalation, global budget governor, per-task workspace-lease sandboxing with PR-only merges, KB-literal fabric decision, LiteLLM Auto Router v2 for sync routing, thin KB-polling workers as the executor, Langfuse kept as observability, real A2A protocol adoption. Includes decision log from alvis. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014t8Qg9gi7H7HtT8MncoXAB
This commit is contained in:
@@ -1,170 +1,253 @@
|
||||
# DESIGN — Agap Agent Platform (A2A, model queues, agents)
|
||||
# DESIGN — Agap Agent Platform v2: the agent algebra
|
||||
|
||||
Status: **draft for review** · Owner: alvis · Drafted 2026-07-21
|
||||
Status: **v2, agreed with alvis 2026-07-21** (supersedes v1 draft `2499218c`)
|
||||
Owner: alvis · Written with Claude
|
||||
|
||||
This is the overall design for turning the Agap homelab from "one Adolf carrying every
|
||||
tool + a few background LLM calls" into a **multi-agent platform**: agents as
|
||||
personas, models as queued compute, and A2A as the way work moves between them.
|
||||
One design, two axioms, one verb. Everything alvis asked for — per-model queues,
|
||||
quota parking, Hindsight reflect as an async task, the Claude Code loop as a task
|
||||
puller, semantic/tier/direct routing — falls out as a special case rather than a
|
||||
rule. This document is the reference; the Kanboard A2A tasks implement it.
|
||||
|
||||
---
|
||||
|
||||
## 0. Glossary
|
||||
|
||||
- **Task plane / "the fabric"** — the task-passing substrate connecting all
|
||||
agents: **Kanboard** (the durable task store and queue — for humans *and*
|
||||
agents) + **A2A protocol semantics** (submit/status/result, Agent Cards,
|
||||
context-by-reference) + the **conventions** on top (claim/lease, priorities,
|
||||
parking, trust-class routing). Not a deployable component; the collective name,
|
||||
the way "the network" names cables + IP + routing.
|
||||
- **Card** — an agent's self-description: capabilities, tier, cost class, trust
|
||||
class, availability. Maps 1:1 to an A2A Agent Card.
|
||||
- **Backbone** — the concrete LLM an agent currently uses for reasoning.
|
||||
- **Context ref** — a pointer (Hindsight bank id, git ref, KB task id, file
|
||||
path) passed *instead of* pasted content.
|
||||
|
||||
## 1. Why
|
||||
|
||||
Current pain, all observed on the live stack:
|
||||
Observed on the live stack:
|
||||
|
||||
- **Duplicated LLM spend.** Every Adolf turn costs two Kimi calls: the reply
|
||||
(~32.8K tokens in) and a *separate* background Hindsight retain/extraction
|
||||
(~22.8K). Only ~425 tokens of that is the actual conversation.
|
||||
- **Tool bloat.** One Adolf carries ~84 MCP tool schemas (~12K tokens) + ~26
|
||||
built-in Kimi tools (~10K) on **every** turn, whether relevant or not.
|
||||
- **Quota cliffs.** Kimi is a flat, window-limited subscription (~60 messages per
|
||||
5h, ~300/week measured). When the window is spent, Adolf goes dark. There is no
|
||||
graceful degradation and no way to park work until the window resets.
|
||||
- **Background work is hardcoded to a model.** Hindsight's reflect/consolidate
|
||||
call a fixed LLM directly. There is no scheduling, no priority, no quota
|
||||
awareness, no way to say "do this on the big model when it's free".
|
||||
- **No room to grow.** The ambition is autonomous research agents, remote llama
|
||||
nodes, more GPUs, more agents. None of that fits a single hardcoded assistant.
|
||||
- **Duplicated LLM spend** — an Adolf turn costs a ~32.8K-token reply call plus a
|
||||
~22.8K-token background Hindsight extraction; ~425 tokens are the conversation.
|
||||
- **Tool bloat** — one Adolf carries ~84 MCP tool schemas + ~26 built-in tools
|
||||
every turn (~22K tokens), relevant or not.
|
||||
- **Quota cliffs** — Kimi's flat window (~60 msgs/5h, ~300/wk measured) makes
|
||||
Adolf go dark with no degradation path and no way to park work.
|
||||
- **Hardcoded background cognition** — Hindsight reflect/consolidation call a
|
||||
fixed model directly: no scheduling, no priority, no quota awareness.
|
||||
- **No growth path** — the ambition is autonomous research agents, remote llama
|
||||
nodes, more GPUs, more agents.
|
||||
|
||||
## 2. Core concepts (and the distinctions that matter)
|
||||
## 2. The algebra
|
||||
|
||||
The central insight: **an agent is not a queue, and a model is not an agent.**
|
||||
### Axiom 1 — everything that can receive work is an Agent
|
||||
|
||||
### Task
|
||||
The unit of work. Durable, addressable, and **context-by-reference**: a task
|
||||
carries *pointers* (memory bank id, git ref, board task id, file path), never
|
||||
pasted context. Fields: id, intent, required capability/tier, target model queue,
|
||||
priority, status, context refs, result ref, submitter, deadline.
|
||||
An agent is `(identity, Card, Policy, State)`. The Card advertises capabilities,
|
||||
**tier** (model strength it offers or needs), **cost class**, **trust class**
|
||||
(§5), and an **availability function a(t)**. Special cases:
|
||||
|
||||
### Model (backbone) — the scarce resource
|
||||
A concrete LLM endpoint reached through the LiteLLM gateway. Examples today:
|
||||
`kimi` (flat quota), `claude-haiku` (paid, already wired), local ollama
|
||||
(`qwen3.5:4b`, `qwen3:8b`, `gemma3:4b`), later a remote llama box or a second GPU.
|
||||
| Agent | Persona | Memory | Card highlights |
|
||||
|---|---|---|---|
|
||||
| LLM endpoint (`kimi`, `gemma3:4b`, …) | trivial (identity) | none | tier, cost, quota-shaped a(t) |
|
||||
| **Adolf** | proactive auditor (SOUL.md) | Hindsight bank `adolf` | trusted; scoped core tools |
|
||||
| **claude-coder** (Claude Code loop) | implementer | session + repo | trusted; pulls complex coding tasks |
|
||||
| **Torgash** | marketplace analyst | own bank | sandboxed; marketplace tools only |
|
||||
| **researcher** | autonomous researcher | own bank | sandboxed/untrusted inputs; own KB project |
|
||||
| router | delegator | none | resolves constraints → agents |
|
||||
| **alvis (the human)** | — | — | trust=human; a(t)=waking hours; **inbox = KB "waiting-on-me"** |
|
||||
|
||||
**Each model has its own queue and its own worker**, because the model is what is
|
||||
actually scarce (quota, VRAM, cost, rate limit).
|
||||
The human being an agent is not a metaphor: approval gates, escalations and
|
||||
decisions are ordinary tasks submitted to his inbox. The KB column he already
|
||||
processes *is* that inbox.
|
||||
|
||||
### Agent — the persona
|
||||
An agent is a **combination of personality + system prompt + memory + tool scope**
|
||||
(e.g. Adolf the proactive auditor; Torgash the marketplace analyst; a research
|
||||
agent; the Claude coding loop). An agent is a *configuration*, not a runtime
|
||||
resource. Critically:
|
||||
|
||||
> **An agent may change its backbone LLM.** Adolf on Kimi today, on a local model
|
||||
> tomorrow, on Claude for a hard task. Therefore **queues are keyed by model, not
|
||||
> by agent.** An agent *submits into* and *consumes from* model queues.
|
||||
|
||||
### Queue — per model, async, with a lifecycle
|
||||
Queues are asynchronous by design and differ in how they drain:
|
||||
|
||||
| Lifecycle | Behaviour | Example |
|
||||
|---|---|---|
|
||||
| **always-on** | worker drains continuously in the background | local ollama models |
|
||||
| **quota-gated** | drains until the window is exhausted, then parks and resumes on reset | Kimi |
|
||||
| **cost-gated** | drains under a budget ceiling; stops/falls back when spent | paid Haiku/Flash |
|
||||
| **on-demand** | node is woken/attached when work exists | future remote llama / extra GPU |
|
||||
|
||||
A task parked on a quota-gated queue is not lost — it waits for the window, or is
|
||||
re-routed if it is urgent and another queue can satisfy the required capability.
|
||||
|
||||
## 3. Architecture
|
||||
|
||||
Four planes. Keeping them separate is the whole point.
|
||||
### Axiom 2 — one verb
|
||||
|
||||
```
|
||||
┌─ Coordination plane ──────────────────────────────────────────┐
|
||||
│ Task registry + lifecycle (Kanboard as blackboard today) │
|
||||
│ context-by-reference; claim/status; audit trail │
|
||||
└───────────────────────────────────────────────────────────────┘
|
||||
┌─ Agent plane ─────────────────────────────────────────────────┐
|
||||
│ Agent registry: persona + system prompt + memory bank + │
|
||||
│ tool scope + preferred capability tier │
|
||||
│ (Adolf, Torgash, research-agent, claude-coder, …) │
|
||||
└───────────────────────────────────────────────────────────────┘
|
||||
┌─ Scheduling plane ────────────────────────────────────────────┐
|
||||
│ Per-MODEL queues + workers; lifecycle policy (always-on / │
|
||||
│ quota-gated / cost-gated / on-demand); priority; claiming │
|
||||
└───────────────────────────────────────────────────────────────┘
|
||||
┌─ Model plane ─────────────────────────────────────────────────┐
|
||||
│ LiteLLM gateway: kimi | claude-haiku | local ollama | remote │
|
||||
│ routing, fallback on 429/quota, per-agent virtual keys+budget │
|
||||
└───────────────────────────────────────────────────────────────┘
|
||||
submit(task, target) -> taskRef # await(taskRef) optional => sync
|
||||
task = (intent, context-refs, constraints, priority, deadline, provenance)
|
||||
target ∈ { agent-id # direct: “this backbone / this specialist”
|
||||
| constraint-set # tier/capability: “any large model with tools”
|
||||
| auto } # router decides by availability/quota/complexity
|
||||
```
|
||||
|
||||
**Shared context stores** (what task references point at): Hindsight (memory
|
||||
banks), git/gitea (code + docs), Kanboard (task context), files.
|
||||
Context travels **by reference, never by value** — the single most important
|
||||
efficiency rule for inter-agent communication (A2A context-passing practice).
|
||||
`sync` vs `async` is not a second mechanism: sync = submit + await.
|
||||
|
||||
### A2A on top
|
||||
A2A gives the vocabulary we otherwise have to invent: **agent cards**
|
||||
(capability advertisement), **task lifecycle states**, structured task
|
||||
submission/tracking, and — most importantly — the **context-by-reference**
|
||||
pattern (send a `contextId`, let the worker read the shared store). We adopt the
|
||||
*patterns* first; the wire protocol can follow once more than one runtime needs
|
||||
to interoperate.
|
||||
### Theorems — the old rules become consequences
|
||||
|
||||
## 4. Worked examples (the required minimal set)
|
||||
1. **"Queues are per model, not per agent."** Every agent has an inbox, but
|
||||
queues *accumulate* only where a(t) or throughput binds — at scarce agents:
|
||||
model-agents and the human. Persona agents transform-and-delegate, so their
|
||||
inboxes stay near-empty. The v1 rule is the scarcity special case.
|
||||
2. **Quota lifecycles are shapes of a(t).** always-on: a(t)=1. quota-gated
|
||||
(Kimi): a(t)=0 when the window is spent — the queue **parks**, nothing fails,
|
||||
drains on reset. cost-gated: a(t)=0 past budget. on-demand (remote llama):
|
||||
a(t)=0 until woken. Four lifecycles, one function.
|
||||
3. **Hindsight reflect is just a submit** — `{intent: reflect, refs: bank+query,
|
||||
constraints: tier≥large}`, async. Same for consolidation (low priority).
|
||||
4. **Backbone swap is a constraint edit.** Persona agents name constraints, not
|
||||
endpoints; the backbone resolves per-submit. Adolf-on-Kimi today,
|
||||
Adolf-on-local tomorrow — no code change.
|
||||
5. **The Claude Code loop is an ordinary consumer** — an agent whose policy is
|
||||
"pull complex coding tasks from the fabric". It was never special.
|
||||
6. **For free:** escalation = re-submit with wider constraints (gated by policy,
|
||||
§5); approval = submit(…, target=alvis); proactivity/cron = delayed
|
||||
self-submission; the researcher = a low-priority self-submitting loop.
|
||||
|
||||
**(1) Hindsight `reflect` becomes an A2A task.** Reflect is async by design.
|
||||
Instead of Hindsight calling a fixed LLM inline, it **submits a task** — intent
|
||||
`reflect`, context ref = bank + query, required tier = *large* — onto the
|
||||
large-model queue. A worker runs it when that model has capacity/quota; the
|
||||
result is written back to the bank. Same for consolidation. This removes the
|
||||
hardcoded background call and makes memory work schedulable, priced, and
|
||||
quota-aware. (See also the "in-loop extraction" option, which is the cheaper
|
||||
counterpart for the *retain* path.)
|
||||
### Granularity rule
|
||||
|
||||
**(2) The Claude Code CLI loop is just an agent.** `claude-coder` = an agent
|
||||
whose persona is "implementer", whose backbone is a Claude model, and whose
|
||||
consumption rule is *pull complex/coding tasks*. It is a **special case of a
|
||||
queue consumer**, not a privileged component. This is why it already works:
|
||||
Adolf files tasks, the Claude loop pulls them. We are formalising what exists.
|
||||
A **Task** is a durable work item with a lifecycle worth auditing. A single LLM
|
||||
completion inside an agent's turn is **not** a Task — it is an implementation
|
||||
detail, observable in Langfuse, invisible to Kanboard. This keeps the KB-literal
|
||||
fabric free of micro-churn by construction.
|
||||
|
||||
**(3) Model queues ≠ agent queues.** Adolf may run on Kimi now and something else
|
||||
later; Torgash may be cheap-tier normally and escalate to a large model for a
|
||||
tricky comparison. So a task is queued against **the capability/model it needs**,
|
||||
and the agent identity travels *with the task* (persona + memory refs), not with
|
||||
the queue.
|
||||
## 3. Planes
|
||||
|
||||
**(4) Queues drain differently.** The local queue works all night; the Kimi queue
|
||||
stops at 100% of the 5h window and resumes after reset; a paid queue stops at its
|
||||
budget. Submitters therefore must state urgency, and the router must be able to
|
||||
re-route or park.
|
||||
```
|
||||
┌─ Task plane (“the fabric”) ─────────────────────────────────────────┐
|
||||
│ Kanboard = the queue + audit + human inboxes (KB-LITERAL: no │
|
||||
│ separate store). A2A semantics; claim/lease; priorities; parking. │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
┌─ Agent plane ───────────────────────────────────────────────────────┐
|
||||
│ Registry of Cards (persona, memory bank, tool scope, trust class, │
|
||||
│ preferred tier, current backbone). Runtimes: OpenClaw (Adolf + │
|
||||
│ specialists), Claude Code CLI, thin workers. │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
┌─ Model plane ───────────────────────────────────────────────────────┐
|
||||
│ LiteLLM gateway (:4000). Auto Router v2 (2026-07-14) does the SYNC │
|
||||
│ routing natively: pinned model | tier pools | complexity/semantic │
|
||||
│ auto-routing (SIMPLE<MEDIUM<COMPLEX<REASONING), plus virtual keys, │
|
||||
│ budgets, 429-fallback. alvis's three routing modes map 1:1: │
|
||||
│ specific backbone → pinned model_name │
|
||||
│ “tier” routing → tier pool │
|
||||
│ automatic router → auto_router/complexity_router │
|
||||
│ The fabric owns everything LiteLLM cannot: ASYNC queueing, parking │
|
||||
│ across quota windows, leases, cross-agent budget arbitration. │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
┌─ Context stores ────────────────────────────────────────────────────┐
|
||||
│ Hindsight banks (per-agent memory) · gitea (code, docs, this file) │
|
||||
│ · KB task bodies · files. Tasks point here; payloads never inline. │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 5. Growing the lab
|
||||
## 4. A2A: the protocol, adopted now
|
||||
|
||||
- **More GPUs / remote llama** → new model entries + their own queues and
|
||||
workers; `on-demand` lifecycle for nodes that are not always up. Nothing else
|
||||
changes.
|
||||
- **More agents** (research, finance, home) → new agent registry entries with
|
||||
scoped tools + their own memory banks. They inherit queues and A2A for free.
|
||||
- **Autonomous research agents** → long-running, low-priority tasks on always-on
|
||||
local queues, escalating to the large model only for synthesis. This is exactly
|
||||
what per-model queues + priorities make affordable.
|
||||
The algebra maps 1:1 onto A2A v1.0 (Jan 2026), which is why we implement the
|
||||
real protocol immediately rather than "patterns first":
|
||||
|
||||
## 6. Migration (phased, smallest useful step first)
|
||||
| Algebra | A2A |
|
||||
|---|---|
|
||||
| Card | Agent Card (`/.well-known/agent.json`) |
|
||||
| submit / await | `message/send` (sync-ish) / `tasks/get` (async) |
|
||||
| task lifecycle | submitted → working → input-required → completed/failed/canceled |
|
||||
| notify | push notifications |
|
||||
|
||||
1. **Registries + schemas** — model registry (endpoint, capability, lifecycle,
|
||||
quota), agent registry (persona/prompt/memory/tools), task schema.
|
||||
2. **One queue + one worker** — always-on local model, end-to-end.
|
||||
3. **Quota-aware worker** — Kimi: park on exhaustion, resume on reset.
|
||||
4. **A2A submission/tracking** with context-by-reference.
|
||||
5. **Cut over the examples** — Hindsight reflect → queue; Claude loop → declared
|
||||
agent/consumer; Adolf → declared agent with scoped tools.
|
||||
6. **Scale** — remote/extra models, more agents.
|
||||
Implementation: JSON-RPC 2.0 over HTTP on the LAN; each runtime (OpenClaw,
|
||||
Claude loop, workers) exposes/consumes A2A; Kanboard remains the durable state
|
||||
behind the endpoints. Scalability/extensibility later (remote nodes, third-party
|
||||
agents) then needs zero redesign.
|
||||
|
||||
## 7. Open questions
|
||||
## 5. Trust & sandboxing
|
||||
|
||||
- Is Kanboard the queue itself, or does it stay the *human-facing* board while
|
||||
workers use a dedicated queue store (and the two are synced)?
|
||||
- Where does the routing decision live — submitter picks the tier, or a central
|
||||
policy re-routes based on live quota/budget?
|
||||
- How much A2A do we actually implement (patterns only vs the real protocol)?
|
||||
- Claim/lease semantics: what happens to a task whose worker dies mid-run?
|
||||
- Does an agent's memory bank follow it across backbones (yes, by design) — and
|
||||
what does that mean for extraction quality when the backbone is weak?
|
||||
**Trust classes** (on every Card):
|
||||
|
||||
## 8. Related
|
||||
```
|
||||
human > trusted > sandboxed > untrusted
|
||||
```
|
||||
|
||||
- Kanboard epic: architecture + LiteLLM gateway + multi-agent framework.
|
||||
- Hindsight in-loop extraction (the cheap counterpart to queued reflect).
|
||||
- Per-agent tool scoping (why Adolf stops carrying every tool).
|
||||
- **trusted** (Adolf, claude-coder): vault access **yes**; outward actions per
|
||||
existing ask-first rules.
|
||||
- **sandboxed** (Torgash, researcher): **no vault**, no outward sends; scoped
|
||||
MCP allowlist; KB access **project-scoped** (researcher gets its own KB
|
||||
project(s)).
|
||||
- **untrusted** = anything ingesting the open web: its *outputs* are tainted.
|
||||
|
||||
**Taint / prompt-injection boundary:** tainted output may be written only to the
|
||||
agent's own bank/notes/project. Promotion into a trusted agent's memory or into
|
||||
any action requires a gate (initially: a task to alvis's inbox; later possibly a
|
||||
reviewer-agent).
|
||||
|
||||
**Escalation policy (initial): always-ask.** A task that fails on its tier is
|
||||
not silently retried on a bigger model; it becomes a decision task in alvis's
|
||||
inbox. Revisit once behavior is observed (debugging phase by design).
|
||||
|
||||
**Sandboxed coding — workspace lease:** per **task**, not per agent:
|
||||
`workspaces/<agent>/<task-id>/` = ephemeral gitea clone + branch; execution
|
||||
inside a container (no vault creds by default, network allowlist, resource
|
||||
caps); merge **only via PR** to gitea; autonomous agents never push to main.
|
||||
Reviewer = human, or later a reviewer-agent (just another persona).
|
||||
|
||||
**Global budget governor:** near the end of a quota window, interactive agents
|
||||
(Adolf) outrank background ones (researcher, consolidation) — arbitration lives
|
||||
in the fabric (priorities + a small governor rule), not in LiteLLM.
|
||||
|
||||
## 6. Executor — thin KB-polling workers
|
||||
|
||||
No Temporal/Hatchet: at homelab scale (dozens of tasks/day) a durable-execution
|
||||
platform would duplicate Kanboard as a second source of truth. Instead, one
|
||||
small worker daemon per model-queue (compose services, ~200 lines, shared lib):
|
||||
|
||||
```
|
||||
loop:
|
||||
a(t) check # quota/budget/health probe; if 0 → park (sleep, re-probe)
|
||||
poll KB view # filtered: my queue, status=queued, by priority
|
||||
claim # atomic: assign-to-self + column move + lease timestamp
|
||||
resolve refs # fetch context by reference
|
||||
execute # via LiteLLM (model-agents) / agent runtime (persona)
|
||||
write result ref # to the shared store; never inline
|
||||
update status # done | failed(retry policy) | input-required(→ inbox)
|
||||
```
|
||||
|
||||
Leases + heartbeats make dead workers safe: an expired lease returns the task to
|
||||
queued. Two workers on one queue never double-run a task (claim is atomic).
|
||||
Idempotency keys on submission prevent duplicate proactive tasks. OpenClaw cron
|
||||
is the proactive *submitter* (Adolf's schedule); workers are the *drainers*.
|
||||
|
||||
## 7. Observability — Langfuse (kept), wired for real
|
||||
|
||||
Decision: keep **Langfuse** (already deployed; best-in-class self-hosted:
|
||||
traces + per-token cost + prompt management + evals, MIT). Grafana rejected for
|
||||
this role — generic metrics with no LLM semantics (the source of past
|
||||
dissatisfaction); Zabbix keeps infra monitoring. To do (it currently receives
|
||||
nothing): LiteLLM success/failure callbacks → Langfuse; tag every trace with
|
||||
`agent`, `task-id`, `queue`; per-agent cost dashboards; upgrade v2→v3. Every
|
||||
completion is traced here — this is where sub-Task granularity lives.
|
||||
|
||||
## 8. Growing the lab
|
||||
|
||||
- **More GPUs / remote llama** → new model-agent Cards with `on-demand` a(t)
|
||||
(health probe, wake hook, graceful absence). Routing skips absent nodes.
|
||||
- **More specialists** → new Cards + scoped tools + own banks. The fabric and
|
||||
A2A don't change.
|
||||
- **Autonomous research agents** → low-priority loops on always-on local queues,
|
||||
escalating (via always-ask, initially) for large-model synthesis; own KB
|
||||
project; tainted outputs until promoted.
|
||||
|
||||
## 9. Migration order
|
||||
|
||||
1. Registries: model Cards + agent Cards (schema + populate).
|
||||
2. First thin worker end-to-end on an always-on local queue.
|
||||
3. Quota-gated worker (Kimi park/resume). Claim/lease semantics.
|
||||
4. A2A protocol surface (JSON-RPC + Agent Cards) over the fabric.
|
||||
5. Cutovers: Hindsight reflect → fabric; consolidation → fabric (low prio);
|
||||
claude-coder + Adolf declared as registry agents (Adolf's tools shrink to
|
||||
scoped core).
|
||||
6. Trust enforcement: capability grants (virtual keys + MCP allowlists), taint
|
||||
gate, budget governor, langfuse wiring.
|
||||
7. Scale: Torgash, researcher (own KB project), on-demand nodes.
|
||||
|
||||
## 10. Decision log (2026-07-21, alvis)
|
||||
|
||||
1. Single completions are not Tasks (langfuse-only) → no micro-churn.
|
||||
2. **KB-literal**: Kanboard is the queue, humans included; no separate store.
|
||||
3. Trust classes as §5; vault = trusted only.
|
||||
4. Escalation = always-ask initially.
|
||||
5. Researcher: KB access allowed, own project(s), scope-limited.
|
||||
6. Real A2A protocol now (JSON-RPC + Agent Cards).
|
||||
7. Proactive schedules: OpenClaw cron → fabric.
|
||||
8. Langfuse kept as the observability layer; Grafana rejected; Zabbix = infra.
|
||||
9. Executor = thin KB-polling workers; no Hatchet/Temporal at this scale.
|
||||
10. Sync routing = LiteLLM Auto Router v2; fabric owns async/parking.
|
||||
11. Sandbox = per-task workspace lease + container + PR-only merges.
|
||||
|
||||
Reference in New Issue
Block a user