Show HN: Loomcycle – a sidecar runtime for AI agents (Go binary, Apache-2.0) Loomcycle, an open-source sidecar runtime for AI agents, has reached v1.0 under the Apache-2.0 license. The Go binary provides a hardened agent loop, MCP support on both sides, multi-replica high availability, and runs alongside existing applications without requiring code changes. The release marks a stable, distribution-ready milestone after extensive hardening and testing. The agentic runtime, in a sidecar. One Go binary alongside your application. Hardened agent loop, MCP on both sides, multi-replica HA. Apache-2.0. 🌐 loomcycle.dev https://loomcycle.dev Β· πŸ“ Engineering blog https://loomcycle.dev/blog/ Β· πŸ“ Architecture https://github.com/denn-gubsky/loomcycle/blob/main/docs/ARCHITECTURE.md 🌳 v1.0 is here.loomcycle1.0is released β€” the feature set is complete and the runtime is hardened and distribution-ready. The core primitives stabilised across the v0.8 β†’ v0.23 line multi-replica HA; the substrate Defs Agent/Skill/MCPServer/Schedule/Webhook/MemoryBackend/A2A; A2A interoperability; inbound webhooks; pluggable memory + a memory layer; the synthetic code-js provider; andOSS multi-tenant authorizationin v0.17.0 β€” per-principal bearer tokens + a role-aware Web UI . The v0.24 β†’ v0.37 line was a hardening + operability run: the interactive terminal, pause/resume/snapshot + cross-instance resume, the context-compaction subsystem, context-transform plugins, external fan-out on every transport, and slow-local-model robustness. 1.0 itself is a pure hardening + distribution milestone β€” no new primitives β€” wired to Homebrew, multi-arch Docker, and the Claude Code plugin. 8-hour stability soak: 1.27M circuits, 3.8M agent runs, 100% completion across 468 waves, zero leaks. Apache-2.0. We welcome bug reports, security disclosures, feature contributions, downstream consumers, and forks. See . CONTRIBUTING.md The agentic runtime, in a sidecar. loomcycle is one Go binary, ~50 MB. It runs alongside your application, not inside it. Your app calls loomcycle over HTTP, gRPC, MCP, the TypeScript adapter, or the Python adapter. The agent loop, multi-provider routing, memory and channel primitives, MCP server identity, OpenTelemetry traces, and multi-replica coordination all live in the binary. Your application stays in whatever language you wrote it in. The shape that's different. Today's agentic-systems market gives you three options. One: embed a Python or TypeScript library inside your application process. Two: rent a managed cloud service tied to one vendor's IAM. Three: proxy your model calls through a gateway that doesn't actually run agents. loomcycle is a fourth option. A lightweight self-hostable runtime that owns the loop and speaks every wire format your stack already uses. | Release | Highlights | |---|---| v0.4 β†’ v0.26.x foundation | Everything the runtime is built on, condensed. Seven inference modes: Anthropic, OpenAI, DeepSeek, Gemini, Ollama cloud + local , plus the synthetic provider and a mock provider. The hardened code-js model β†’ tool use β†’ tool result loop. 19 built-in tools with Claude Code parity Read, Write, Edit, Grep, Glob, NotebookEdit , plus HTTP, WebFetch, WebSearch, Bash, Agent, Skill, Memory, Channel, AgentDef, SkillDef, Evaluation, Interruption, Context. The content-addressed, runtime-mutable substrate Agent / Skill / MCPServer / Schedule / Webhook / MemoryBackend / A2A defs . Vector Memory sqlite-vec / pgvector on a pluggable MemoryBackend, with a memory layer above. MCP on both sides. The LLM Gateway + OpenAI-compatible shims. A2A interop. Input webhooks. Ensemble-sync primitives RFC S . OTEL + per-tenant fairness + Pause / Resume / Snapshot + multi-replica HA. Per-run named credentials + tool-use hooks. OSS multi-tenant authorization RFC L, v0.17.0 across both the state and definition planes. The embedded React Web UI + the interactive terminal. TS + Python + n8n adapters. Homebrew + Docker distribution. Per-version detail: REVISIONS.md | v0.27.0 | Interactive runs survive leaving the terminal. Background-goroutine execution under context.WithoutCancel , re-attach via GET /v1/runs/{run id}/stream replay-from- ?from seq + live-tail . Context op=self reports the resolved provider + model. | v0.28.0 | Per-agent LLM temperature / top p / top k / penalties / seed / stop, set via yaml or AgentDef overlay or per-run . And sampling : the loop parks at an iteration boundary and pause cooperative quiesce Pause waits for in-flight runs, so a mid-run snapshot is reliable. | v0.29.0 | Web UI + operability. Agent-editor sampling controls + a collapsible advanced JSON/YAML overlay, terminal message-echo + a context-size gauge, and soft reclaim of a retired agent name no new runtime primitives . | v0.30.0 | Cross-instance resume of a snapshotted mid-run RFC X Phase 2 . A paused run is re-dispatched by reconstructing its loop from the transcript, fired after a snapshot restore and at boot crash recovery, cluster-gated . | v0.31.0 | Park + resume a fan-out parent blocked in Agent.parallel spawn RFC X Phase 3 . Pause-watcher + a no-schema-change spawn ledger, gated behind LOOMCYCLE RESUME FANOUT . | v0.32.0 | Context-compaction subsystem. Replace older turns with a summary + keep-last-N verbatim clean user-turn boundary, non-destructive . Manual / auto / self triggers and a per-agent compaction block that flows down the spawn tree. | v0.33.0 | External fan-out and the run-mutation surface on every transport. POST /v1/runs:batch , a spawn runs MCP tool ≀32 server-concurrent , a SpawnRunBatch RPC. compact run / CompactRun . Per-run sampling + compaction on MCP/gRPC. @loomcycle/client 0.33.0. | v0.34.0 | Context-transform plugins RFC Z Phase 1a, with the redact outbound-secret-scrub plugin , an exp7 self-review hardening pass, and a cross-provider thinking-model fallback downgrade reasoner β†’ chat . | v0.34.1 | Hardening + branding no new features . A central tenant-scoping store accessor closing three live cross-tenant read gaps security review S2 , plus the new loomcycle brand logo and favicon in the Web UI. | v0.34.2 | Web UI design system + theming. A tokenized --lc- design system spacing / type / radius / shadow / fonts + semantic colors , light + dark themes OS default + a persistent topbar toggle , bundled brand fonts Outfit / Inter / JetBrains Mono , and the loom-wood accent. Plus a loop fix interactive runs unbounded by default; no more stop-at-16 and a 56c596 -race test de-flake. | v0.34.3 | Patch. Context op=self reports a fresh context footprint right after a compaction. It had kept showing the stale pre-compaction size e.g. 164k / 82% for one turn even though the wire request had already shrunk. The loop now refreshes lastCtxTokens at every compaction site. | v0.34.4 | Patch. Interactive-terminal UX + local-model fixes: a collapsible interactive-sessions switcher on the run page and interactive tags on the runs page , a flashing waiting indicator in the terminal, the Ollama context gauge backed by num ctx , generous 300s , relative ollama-local timeoutssandbox paths anchored to the root not the process cwd , and the static agent base re-surfaced in the Library when no dynamic version is active. | v0.34.5 | Patch. Ollama now reports the model's actual loaded context window read from /api/ps at the stream's done frame instead of only a pinned num ctx β€” so the gauge is truthful for local models loaded at the server's OLLAMA CONTEXT LENGTH ; plus docs the architecture diagram + ARCHITECTURE.md show the context-transform plugin layer; a README v1.0 voice refresh . | v0.35.0 | Model aliases in tier candidates. A models: alias e.g. local-gemma now resolves anywhere a tier candidate is accepted β€” per-agent models: , user tiers , and the library tiers: β€” not only in an agent pin, closing the "pin expands aliases but tier candidates don't" 503. A candidate can be written as a bare alias string - local-gemma ; config-load validation and the Web UI Library editor know aliases too. | v0.36.0 | Jailed agents can see their sandbox. The Read / Write / Edit / Bash path docs now instruct relative paths they wrongly said "Absolute file path," so agents passed host paths that resolve outside the jail , and reports the sandbox roots Context op=self read root / write root / bash cwd + the effective host allowlist. Plus a collapsible left column on the run page so the live terminal can use the full width. | v0.37.0 | Slow-local-model robustness. Two loop fixes that keep an interactive run on a slow local model alive for hours: a run-lifetime heartbeat a long prefill / retry no longer gets reaped as a crashed run and a compaction window cap auto-compaction always fits the model's window instead of "succeeding" yet still overflowing . Plus an aliases-first loomcycle.example.yaml , a "Local models Ollama " config guide + a loomcycle.local-interactive.example.yaml . Validated by a 133-min standalone local run. | v1.0.0 | 🌳 1.0 β€” feature-complete, hardened, distribution-ready. The milestone the roadmap pointed at: no new primitives, the culmination of the v0.8β†’v0.37 primitive + hardening line. Apache-2.0, wired to Homebrew / multi-arch Docker / the Claude Code plugin. Same codebase as v0.37.0, tagged as the stable 1.0. | Full per-version log: REVISIONS.md /denn-gubsky/loomcycle/blob/main/REVISIONS.md . Same Go binary, same config schema. Operator flips a few env vars to pick the posture. | Posture | Configuration shape | Use case | |---|---|---| True managed sandbox | LOOMCYCLE BASH ENABLED=0 , LOOMCYCLE READ ROOT / LOOMCYCLE WRITE ROOT unset, LOOMCYCLE HTTP HOST ALLOWLIST empty, LOOMCYCLE HTTP CALLER AUTHORITATIVE=1 . Every tool default-deny; agents can only reach what the caller's per-request allowed hosts says. | Shared-server deployments processing untrusted prompts. The runtime survives contact with adversarial input. | Agentic dev environment | Bash enabled, filesystem roots set to your workspace, broad allowed hosts , optional local Ollama for offline work. | Local development. Internal trusted operators. Single-user research workstation. | The trust boundary is operator / caller . The operator config is the floor; callers can narrow per-request but never widen. The bearer token LOOMCYCLE AUTH TOKEN is the authority. Treat anyone with the token as fully trusted to drive the runtime. For true isolation in the sandbox posture, run loomcycle inside a container or VM. Bash is restricted cwd, env scrub, output bounds, timeouts but it is not a kernel-level sandbox. Pick the path that fits. All four ship the same single static binary plus the v0.11.1 init / doctor first-run flow. Context.help installation covers each in detail. Homebrew macOS + Linux brew install denn-gubsky/loomcycle/loomcycle Docker v0.11.2+; pull works on amd64 + arm64 including Apple Silicon docker pull denngubsky/loomcycle:latest go install from source skips Web UI embedding β€” for dev only go install github.com/denn-gubsky/loomcycle/cmd/loomcycle@latest Direct tarball one of darwin-arm64 / darwin-amd64 / linux-arm64 / linux-amd64 curl -L https://github.com/denn-gubsky/loomcycle/releases/latest/download/loomcycle-darwin-arm64.tar.gz | tar xz loomcycle init --with-token writes config + mints a token to ~/.config/loomcycle/auth.env 0600 export ANTHROPIC API KEY=sk-... or OPENAI API KEY / DEEPSEEK API KEY β€” at least one provider key loomcycle doctor verify env + keys + storage + the just-minted token loomcycle starts on 127.0.0.1:8787 auto-loads auth.env β€” no shell-rc edit init --with-token prints the Web UI URL http://127.0.0.1:8787/ui . Open it, then paste the token from ~/.config/loomcycle/auth.env at the login prompt. The token is kept in the 0600 file and never embedded in a URL. A ?token= link would leak the bearer into browser history and into any fronting proxy's logs. loomcycle and loomcycle doctor both auto-load auth.env from the config dir; a real export LOOMCYCLE AUTH TOKEN=… always overrides it. Pick the tier that fits. Each is a superset of the one above. Auth is enforced only once something is configured , so Tier 1 needs no token at all. No token, no flags. Fastest way to kick the tires on 127.0.0.1 . loomcycle init config only β€” no secret written export ANTHROPIC API KEY=sk-... loomcycle open mode: /v1/ + /ui pass through unauthenticated logs a warning open http://127.0.0.1:8787/ui With no LOOMCYCLE AUTH TOKEN and no minted tokens, the runtime runs open on localhost. Every request is allowed, whoami returns a synthetic admin. Good for a 10-second smoke test. Never expose this off localhost. One bearer gates everything. init --with-token is the easy button above . Equivalent manual setup: loomcycle init export LOOMCYCLE AUTH TOKEN=$ openssl rand -hex 32 or: loomcycle init --with-token export ANTHROPIC API KEY=sk-... loomcycle open "http://127.0.0.1:8787/ui?token=$LOOMCYCLE AUTH TOKEN" sets the cookie once Treat anyone holding the token as fully trusted to drive the runtime. Mint a distinct bearer per developer / app, each bound to an authoritative tenant, subject, scopes . Migrate a Tier-2 deployment in place, no downtime: promote your existing shared token into the substrate, then mint scoped tokens loomcycle operator-token create --copy-from-env --name ops --tenant ops --scopes substrate:admin loomcycle operator-token create --name acme-app --tenant acme --subject alice --scopes runs:create The first admin OperatorTokenDef disables the legacy shared-token fallback. Per-route HTTP and per-RPC gRPC scopes. The Web UI becomes role-aware super-admin vs tenant . See Context.help operator-tokens and the v0.17.0 notes in REVISIONS.md /denn-gubsky/loomcycle/blob/main/REVISIONS.md . Smoke any tier: curl http://127.0.0.1:8787/healthz {"ok":true} Real call from another terminal : curl -N http://127.0.0.1:8787/v1/runs \ -H "Authorization: Bearer $LOOMCYCLE AUTH TOKEN" \ -H "Content-Type: application/json" \ -d '{"agent":"default","segments": {"role":"user","content": {"type":"trusted-text","text":"Hello"} } }' Build from a checkout for development : make build-all UI + binary in one shot; output β†’ ./bin/loomcycle ./bin/loomcycle --config loomcycle.example.yaml Multi-replica cluster demo v0.12.x . For a one-command docker compose up cluster 2 loomcycle replicas, Postgres, nginx LB with a verify script, see examples/cluster/README.md /denn-gubsky/loomcycle/blob/main/examples/cluster/README.md . Full operator runbook in . /denn-gubsky/loomcycle/blob/main/docs/MULTI-REPLICA.md docs/MULTI-REPLICA.md v1.0.0: feature-complete, hardened, distribution-ready. 🌳 The 1.0 milestone β€” the point the roadmap pointed at since the multi-tenant-auth capstone v0.17.0 and the substrate-completeness line v0.18–v0.23 . 1.0 adds no new primitives ; it's the stable tag on the runtime that stabilised across v0.8β†’v0.23 the providers, built-in tools, substrate Defs, triggers, multi-tenant authz, HA and was hardened across v0.24β†’v0.37 interactive terminal, pause/resume/snapshot + cross-instance resume, the context-compaction subsystem, context-transform plugins, external fan-out on every transport, slow-local-model robustness . Distribution is wired end-to-end: Homebrew + multi-arch Docker, init / doctor first-run, the Claude Code plugin, the TS @loomcycle/client + Python adapters, and the embedded Web UI. Apache-2.0. Code-identical to v0.37.0 β€” 1.0 is the stability stamp, not a feature delta. Beyond 1.0 unscheduled : a settings UI, an operator cookbook, Helm. v0.37.0: slow-local-model robustness + aliases-first docs. Two loop fixes from a slow-local-model stress test, plus a config/docs pass. 1 Heartbeat during a model call 502 β€” OnHeartbeat fired only at iteration start, so a single iteration that blocked far longer than the cadence a large-context prefill on a slow local model, or a same-provider retry let the heartbeat go stale and the stale-run sweeper reaped the live run as heartbeat timeout . A run-lifetime ticker now pulses every 30s while the run goroutine is alive; the HTTP timeouts remain the authority on a genuinely stuck call. 2 Compaction caps the kept tail to the window 503 β€” auto-compaction could "succeed" yet leave the context still over the window a tool-heavy agent's keep last n tail of huge file reads ; the loop now folds the oldest kept turns into the summary until the tail fits ~half the window, so compaction always relieves pressure. 3 Aliases-first config + local-model guide 504 β€” loomcycle.example.yaml restructured aliases-first, a new docs/CONFIGURATION.md Β§6b "Local models Ollama " the global num ctx knob, header/idle timeouts, compaction tuning , a new loomcycle.local-interactive.example.yaml , and a runs-page chip fix. Validated by a 133-minute standalone interactive code-reviewer run on a local GPU; the one edge it surfaced compaction can't reduce a single indivisible tool-chain is captured for a follow-up. Runtime + docs; no @loomcycle/client bump. v0.36.0: jailed agents can see their sandbox + a roomier run terminal. Two features. 1 Agents jailed to a filesystem sandbox kept addressing files with absolute host paths, which resolve outside the root and fail β€” because the Read / Write / Edit path params said "Absolute file path" what the model reads every turn even though the resolver anchors relative paths to the root. The descriptions now instruct relative paths, and Context op=self additionally reports the jail sandbox.read root / write root / bash cwd + the relative-path convention and the granted host allowlist network.allowed hosts + source , so an agent can introspect its sandbox instead of guessing. docs/TOOLS.md is corrected too it documented the old relative-to-process-cwd behaviour . 2 The run page's left column interactive-sessions switcher + run form is now collapsible to a thin strip showing the running-interactive count, so the live terminal can use the full width during a run. Runtime + Web UI + docs; op=self fields are additive; no @loomcycle/client bump 499, 500 . v0.35.0: model aliases work in tier candidates. A models: alias e.g. local-gemma β†’ {ollama-local, gemma4:max} now resolves anywhere a tier candidate is accepted β€” per-agent models: , user tiers. .tiers , and the library tiers: β€” not only in an agent pin. Previously a tier candidate naming an alias failed with 503 no provider available for requested tier because the resolver matched the model string literally. Expansion now happens at the two resolver-entry boundaries through one shared helper the same rule the pin path uses , covering HTTP, gRPC, and dynamic / Web-UI / MCP-authored agents. A candidate can also be written as a bare alias string - local-gemma , and both config-load validation and the Web UI Library editor understand aliases. Wire-shape-neutral; no @loomcycle/client bump 497 . v0.34.5 patch: Ollama reports the model's real loaded context window. Runtime + docs. The ollama / ollama-local context gauge previously showed a window only when LOOMCYCLE OLLAMA LOCAL NUM CTX was pinned β€” and that knob is also sent as options.num ctx , so it both caps and reports the context, overriding the ollama server's own setting. With it unset, loomcycle reported "unknown" even when ollama loaded the model at a larger window a 256K-trained model running at a real 128K . The driver now reads the actual loaded context length from ollama's /api/ps at the stream's done frame the model is in VRAM by then and stamps it on the usage event β€” so the gauge reflects what ollama actually allocated. An explicit num ctx still wins; a not-yet-loaded model reports 0 "unknown" ; per-model cached, best-effort gauge-only, never correctness . The loop prefers this per-call window over the static capability default 495 . Docs: the architecture diagram + ARCHITECTURE.md now show the context-transform plugin layer 493 , plus a README v1.0 voice refresh 494 . No @loomcycle/client bump. v0.34.4 patch: interactive-terminal UX, local-model fixes, two sandbox/Library fixes. Web UI + runtime; no new primitives. 1 Interactive-session switcher 491 . Leaving the /run terminal stranded an interactive run behind the runs-page "resume in terminal" link. The run page Single tab now has a collapsible Interactive sessions list in its left column. Each row is one of the operator's running interactive sessions, re-attaching in the terminal on click replay + live-tail , the current one marked open , collapsed shows "N interactive sessions". The runs page tree + detail gains an interactive tag. Backed by an additive interactive field on the GET /v1/users/{id}/agents row. 2 Terminal waiting indicator 488 . A flashing indicator with an adaptive label "running