← All work

Isosceles

A Discord collaborator agent with real, bounded tool agency

Last devlog: June 26, 2026

FAST CLOCK — DETERMINISTIC (GATEWAY LOOP) SLOW CLOCK — PROBABILISTIC (BETWEEN TURNS) ← LLM NEVER CROSSES THIS LINE → DiscordGatewaydeterministicFast Clock Coredispatch · execute · logRole Gateoperator onlyNormalizationvalidate outputContext Assemblydevlog index · server state · task listSignal BridgeAppend-only ledgeractions · feedback · tasksdeterministic · durableGated ExecutionPathoperator-approved onlyTOMA Surfacegoverned tool agencyecosystem toolsReasoning Layerlocal Qwen 3.5 9B — proposes, never executesprobabilistic · between turnsOperatordirects · approveseventslogproposeapproveexecutereversible toolsreason (async)proposetasks

Key boundary (two-clock): The Reasoning Layer (LLM) never runs inside the Discord Gateway loop. It reads a compact, pre-assembled context payload and proposes an action or response. The gateway is pure Rust. The LLM proposes; the fast clock disposes. An LLM in a real-time action loop is a latency bomb and a sovereignty solvent.

Key boundary (capability gate): Reversible actions (create, post, reorder, read) execute directly in the Fast Clock Core. Consequential actions (deploy, publish, send, spend) route through the Signal Bridge as proposals, then through the Gated Execution Path on operator approval. The gate is structural — the signal-bridge crate lacks the egress to take consequential actions directly. A prompt directive is a comment; the gate is code.

Key boundary (role gate): Only the operator role can direct the agent's actions. Non-operators can converse but the agent will not act on their behalf. The check is pure Rust, fast-clock, before the reasoning layer. A non-operator cannot talk the agent into taking actions — the action path checks the role, not the persuasiveness.

Isosceles is a Discord collaborator agent for the Decagon ecosystem. It lives in a private Discord server that the operator owns and that the agent itself scaffolds and tends. The agent collaborates with the operator (who directs) and with the other ecosystem agents (via TOMA). It scaffolds channels and roles, posts content, pulls ecosystem state, pushes server signals, and invokes sibling tools — all from a Discord cockpit.

The architecture is a two-clock system. A fast deterministic clock (pure Rust) owns the Discord gateway event loop — message receipt, dispatch, scaffolding execution, content posting, response posting. It never waits on a token. A slow probabilistic clock (the local Qwen 3.5 9B via vLLM) reasons only between message turns and before actions — drafting scaffolding plans, producing content, deciding which tool to invoke, interpreting operator directives. The LLM proposes; the fast clock disposes. The boundary is what makes the agent responsive and trustworthy — an LLM in a real-time action loop is a latency bomb and a sovereignty solvent.

Three structural boundaries make the agent's agency safe:

**The capability-separation gate.** The agent acts freely on reversible work — creating channels, posting content, reorganizing, reading state. Consequential actions — deploying, publishing, sending, spending, triggering sibling-agent actions — are structurally gated. The agent produces a proposal; the operator approves; a separate credential-holding path executes. The gate is structural, not instructional: the signal-bridge crate lacks the egress to take consequential actions directly. A prompt directive is a comment; the gate is code.

**The role gate.** Only the operator role can direct the agent's actions. Non-operators can converse (the agent responds, grounded and bounded) but the agent will not take any action on their behalf — no scaffolding, no content, no tools. The check is pure Rust, fast-clock, before the reasoning layer. A non-operator cannot talk the agent into taking actions, because the agent's action path checks the role, not the persuasiveness.

**The normalization layer.** Every LLM output is validated before execution — action-type validation, field validation (Discord naming rules, valid role IDs, valid tool names), an action cap, and rejection-with-log on failure. Pure Rust, no LLM. The last line of defense between probabilistic output and deterministic execution.

The thesis: a local LLM, behind a strict two-clock boundary, with real tool-backed agency via TOMA, can be a genuine collaborator — sovereign, local, bounded, and competent at something other than talking. V1 is private; the server-as-surface is eventual. The agent is the moat, demonstrated.

Devlog posts about Isosceles

The first breath: what surfaces when the loop runs live

The vertical slice ran live in a test server. The 9B model produced a grounded 4-action scaffolding plan, the role gate denied a non-operator, and the ledger captured everything. A category-nesting bug surfaced on the first run — the execution layer was passing stale server structure to subsequent actions. The bug was structural, not a parameter issue, and the fix was structural. Build-floor findings from the first honest breath of the loop.

The two clocks, applied to collaboration

The two-clock architecture — a deterministic fast clock that owns the gateway, a slow probabilistic clock that reasons between turns — proven in game loops and embodiment loops, applied here to a Discord collaborator surface. Why the chat-window-wearing-a-bot failure is the default, why inverting it is the discipline, and what the boundary looks like when the agent takes real actions in a real workspace.

Captured from day one, learned from later

A ledger that captures what happened doesn't capture whether it was good. The learning signal — four capture surfaces at different friction levels, all converging on a single ledger entry linked to the action — is specified and captured from the first action, even though the learner that consumes it is a future component. The methodology: design the signal capture before you need the learner, or you'll find the data insufficient when the learner is ready.