loomcycle 1.0 is here. Substrate complete. What's next.
Two months ago I was running my agents for JobEmber.ai (an AI job-search SaaS) on a VPS, first with claude --print in a loop, then with the Claude Agent SDK. Three to five agents in parallel and the VPS was out of memory. My minimum plan needed 100 in parallel, per user.
So I started writing a small Go sidecar to take the loop off the application. One Go binary, ~50 MB, alongside whatever your application is written in. That was supposed to be it.
Today loomcycle 1.0 ships.
The substrate is feature-complete. The hardening pass cleared an 8-hour stability soak. The runtime survives slow local hardware (a 133-minute autonomous run on Qwen3.6:27b through Ollama, multiple auto-compactions, zero false-timeout deaths). The companion repos are real and shipping. And the post-v1.0 design queue has a new entry that the substrate now genuinely needs: Filesystem Volumes (RFC AH, Phase 1 already shipped in PR #510), the multi-ensemble workspace-isolation primitive.
Below: what's in v1.0, what's next.
What's in v1.0
v1.0 is the feature-complete-substrate tag. No new primitives between here and v1.x; everything is hardening, distribution, and the polish work shipped across v0.34.3 → v0.37.0.
The substrate primitives
- Six LLM providers behind one interface: Anthropic, OpenAI, DeepSeek, Gemini, Ollama (cloud + local). Plus a deterministic
code-jsprovider for operator-authored agents that run in goja with no LLM call. - 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.
- Content-addressed substrate: Agent, Skill, MCPServer, Schedule, Webhook, MemoryBackend, A2A. Forkable, lineage-tracked, content-identifying.
- MCP on both sides. loomcycle is reachable as an MCP server (37 meta-tools the wire surface exposes), and loomcycle agents call external MCP servers as a first-class tool kind.
- A2A on both sides. loomcycle publishes an AgentCard at
/.well-known/agent-card.jsonwith three protocol bindings (REST, JSON-RPC, gRPC); external A2A peers from Microsoft Agent Framework, Google ADK, and LangGraph deployments call loomcycle agents as remote skills. - Multi-tenant authorization (RFC L). Per-principal bearer tokens (
lct_…) each bound to authoritative(tenant, subject, scopes). Same-tenant subjects collaborate; cross-tenant reads return opaque "not found." No existence oracle. - Multi-replica HA on Postgres LISTEN/NOTIFY (no Redis dep). Cross-replica cancel, pause/resume, runstate fanout, quota notifications, advisory-locked singleton sweepers. SQLite refuses cluster mode at boot.
- Pause / snapshot / resume even mid-run and across instances (RFC X both phases). A paused run snapshotted on instance A restores on instance B and re-dispatches autonomously. The breeder in exp6.5 finishes its work on a fresh machine after a DB wipe.
- Context compaction (RFC Z's host work). Manual, auto, self. The agent can call
Context op=compacton itself after looking at its ownused_pct. - Context-transform plugins (RFC Z Phase 1a). The
redactplugin scrubs operator-declared secrets and built-in heuristic patterns (Authorization,sk-,ghp_, AWS, Slack,key=value) from outbound LLM requests every iteration. The model never sees the literal token. - Per-run credentials (RFC F). The substrate substitutes resolved secrets at the MCP transport boundary, never in the agent's view of its credentials map. Agents see credential names; the wire sees values; persisted state sees redacted placeholders.
- Scheduled autonomous runs (RFC E). Cron +
on_completehooks +max_firesself-retire. The substrate has a clock (Context op=time). - Signed inbound webhooks (RFC H). HMAC-SHA256 over the raw body, two-layer idempotency (in-memory + durable), strict JSONPath payload projection.
- External MCP fan-out (RFC Y, v0.33.0). One MCP call (
spawn_runs, modejoin, ≤32 concurrent) fans N agents and returns an index-aligned envelope. The shape exp7 used to drive 10 reviewers from one Claude Code call.
Production-grade validation
Two numbers ground the v1.0 tag.
8-hour stability soak: 1.27M circuits, 3.8M agent runs, 100% completion across 468 waves, zero leaks (RSS, goroutines, connections, quotas). Per-replica load split to 0.14%. The substrate doesn't drift under sustained load.
133-minute autonomous run on Qwen3.6:27b through ollama-local (the slow-local-model robustness pass that landed v0.34.3 → v0.37.0). Multiple auto-compactions fired correctly, the tail-cap kept post-compaction requests under the 131k window, the heartbeat ticker kept the run alive through every long prefill. The runtime is honest about local inference now, not just cloud APIs.
Writeups: the 8-hour soak and the 133-minute local-Qwen saga.
The Claude Code surface
Claude Code stays the human's conversation surface. loomcycle is the side runtime where the delegated multi-agent work runs. Two integration paths:
loomcycle import claude-codelifts.claude/agents/*.md+.claude/skills/*/SKILL.mdinto the loomcycle substrate without rewriting. AgentDef + SkillDef synthesized from YAML frontmatter + markdown bodies; tools mapped toallowed_tools; skills bundled into the system prompt at config-load.- The
claude-code-plugin-loomcyclecompanion plugin (Claude Code marketplace, Apache-2.0) gives Claude Code a one-keystroke surface to drive loomcycle. Slash commands, skills, opt-in hooks. Uses loomcycle's MCP server with no loomcycle-side code changes.
The cost-shape that matters: Claude Code burns Claude tokens for the conversation. loomcycle can run the delegated agents on DeepSeek, Ollama, local Mistral, or any other cheaper provider the structured-loop work doesn't need Claude for. Same MCP wire surface; the model swap is one AgentDef field. exp7's 10 reviewers ran on Claude OAuth, but the topology is provider-neutral.
The reproducible experiments
Seven self-contained reproducers under loomcycle/examples. Each is a directory with its own loomcycle.yaml, run.sh, .env.local.example, and a reproducible README. Clone, cd, run.
- exp1+2 - tool access and interruption. writeup →
- exp3 - the multi-agent refine loop with channels, evaluation, and interruption. writeup →
- exp4 - Gitea + Telegram + the day the reviewer agent inlined a token (and the substrate redactor caught it). writeup →
- exp5 - scheduler-driven agent ensembles (RFC S,
Channel.awaitfan-in). writeup → - exp6 / exp6.5 / exp6.8 - self-evolving agents over forkable AgentDefs, plus the mid-run snapshot/resume demo, plus the local-Ollama rerun. writeup →
- exp7 - Claude Code orchestrates, loomcycle executes (10-agent code review through one MCP call). writeup →
What conversations with neighbouring projects surfaced
The runtime stays useful only if it integrates with what real teams are building today. Conversations during launch week with the maintainer of Paca (the AI-native, Apache-2.0, self-hosted Scrum / Trello / ClickUp alternative — 954 stars, active development, AI agents as first-class teammates) didn't land an integration this time around. Paca's agent shape is one isolated agent per feature (OpenHands' Docker-Sandbox-per-conversation model); loomcycle's shape is a team of specialised agents collaborating on a feature (architect → planner → code-guru fleet → reviewer → QA). The maintainer is bound to the single-agent model and is still working through how the multi-agent ensemble shape fits Paca's primitives. Integration work on his side is on hold while he thinks it through.
The productive output of those conversations is something else: a new substrate primitive — Filesystem Volumes (RFC AH).
Volumes solve the multi-ensemble interference problem. Today every agent in a loomcycle instance shares one global filesystem jail (LOOMCYCLE_READ_ROOT / WRITE_ROOT / BASH_CWD). Two ensembles working in the same runtime can read and write into each other's working tree with no operator control. The only workaround was per-ensemble Docker containers — which throws away exactly the "one long-lived runtime hosting many agents cheaply" benefit loomcycle exists to provide.
Volumes are {name, path, mode: ro|rw} — named, per-agent ro/rw filesystem roots for Read / Write / Edit / Glob / Grep / Bash. An AgentDef binds to N volumes; the file tools resolve paths relative to that volume's root. Spawn-narrow-only: a sub-agent's volume set ⊆ its parent's. Mirrors the network-side allowed_hosts plumbing exactly. Phase 2 adds a dynamic VolumeDef substrate with ephemeral run-scoped volumes — clone a repo into temp storage, the agent team works on it, delete on run completion.
Phase 1 already shipped in PR #510. The former global jail becomes the default Volume; existing deployments are byte-identical. Phase 2 (dynamic VolumeDef + ephemeral run-scoped) is the next implementation slice.
The conversation with Paca didn't produce the integration we discussed, but it produced something more durable: a primitive the substrate genuinely needed and that any multi-ensemble loomcycle deployment now wants. The integration conversation isn't dead — paused while the maintainer absorbs the ensemble model. When and if it resumes, the substrate is in a stronger shape to support it.
The companion-projects roster
Today, three companion projects ship alongside loomcycle:
loomcycle- the runtime itself (this release).n8n-nodes-loomcycle- the n8n community node package (Slim + Full editions, 20 / 24 nodes, npm-published). Drop loomcycle in front of an n8n workflow without writing custom HTTP nodes.claude-code-plugin-loomcycle- the Claude Code marketplace plugin (Apache-2.0). Slash commands, skills, opt-in hooks. Pairs withloomcycle import claude-codefor the round-trip.
What's next: four named post-v1.0 design RFCs
v1.0 is the feature-complete-substrate gate. The next thing is not "more features bolted on." It is four named design lines, drafted, scoped, and queued behind the v1.0 hardening pass clearing. The Filesystem Volumes work (above) is one of them, with Phase 1 already shipped — the other three are still in the design queue.
Context-compress plugin (RFC Z Phase 2)
Phase 1a of the contextplugin chain shipped in v0.34.0 with the redact plugin. Phase 2 is a context-compress plugin: LLMLingua-style content compression at the per-turn boundary, composing with redact in the same chain, transforming a copy of the outbound request, leaving the canonical history and the persisted transcript untouched. The seam is the same one auto-compaction already uses; the new dependency is a tokenizer.
The research is done. A separate research RFC scored LLMLingua / LLMLingua-2 / LongLLMLingua / Selective Context / soft-prompt family / abstractive / pure-Go against loomcycle's constraints (black-box providers, single Go binary, deterministic byte-stable, no local model required). The recommendation: a pure-Go structural pre-pass (cheap, deterministic, no external dep), and optionally LLMLingua-2 as the model-based method (sidecar / embedded ONNX / pure-Go-only - the deployment choice is the design crux).
Status: in preparation.
SQL Memory (RFC AA)
A second facet of the Memory primitive. Per-scope SQL databases the runtime owns, isolated from the main loomcycle store, that sandboxed agents query with arbitrary SQL. Two new Memory ops (sql_query, sql_exec); durable per-(tenant, scope, scope_id) plus an ephemeral per-run scratch DB; default-deny sql_scopes ACL; statement timeouts; byte quotas; full audit. sqlite tier first (one file per scope, hardened authorizer + statement allowlist), postgres tier (one schema per scope in a separate aux DB) is Phase 2.
Closes the "agents that need structured tables today need Bash + sqlite3" gap. The Bash escape hatch is restricted-not-isolated; SQL Memory is bounded at the SQL layer, audited, and never touches the main store.
Capability-based memory interface + mem0 backend (RFC K)
Generalize the v0.15.0 memory.Backend contract with an optional MemoryLayer capability so LLM-extract memory products (mem0, Mem9 in smart mode, Zep-style) work natively (add(messages) → recall(query)) rather than degraded into a KV store.
mem0 (57k stars, Apache-2.0, daily commits, funded company, published LoCoMo 91.6 / LongMemEval 94.8 numbers) lands as the first MemoryLayer backend. The flat Backend stays canonical; an external memory-layer backend declines Backend and serves MemoryLayer only. The substrate stops pretending an LLM-extract product is a KV store.
How to actually run it
Three install paths, three commands each, same single binary.
# Homebrew (macOS + Linux)
brew install denn-gubsky/loomcycle/loomcycle
loomcycle init --with-token
loomcycle doctor && loomcycle
# Docker (v0.11.2+; amd64 + arm64 incl. Apple Silicon)
docker pull denngubsky/loomcycle:latest
docker run --rm -p 8787:8787 \
-e ANTHROPIC_API_KEY=sk-... \
-e LOOMCYCLE_AUTH_TOKEN=$(openssl rand -hex 32) \
denngubsky/loomcycle:latest
# Direct tarball (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 && ./loomcycle doctor && ./loomcycle
Then open http://127.0.0.1:8787/ui, paste the token from ~/.config/loomcycle/auth.env, and the Web UI is yours. Already using Claude Code? loomcycle import claude-code --from=.claude --write --skills-dest=$PWD/skills lifts your existing agents and skills into the substrate.
Why v1.0 was the right gate
I could have tagged 1.0 a month ago and skipped the hardening pass. I didn't, for two reasons.
First: the substrate has to survive contact with production. The 8-hour soak was the answer to "does this thing drift under sustained load." The 133-minute local-Qwen run was the answer to "is the runtime honest about hardware that isn't an Anthropic data center." Both numbers gate the tag. Without them, "production-ready" is a marketing word.
Second: the post-v1.0 plans only make sense if the substrate underneath is stable. A context-compress plugin landing on a runtime that drifts under load would be debugging the wrong layer for weeks. SQL Memory landing on a runtime whose pause/snapshot is unreliable would be cleaning up half-written rows from crashed snapshots forever. Filesystem Volumes — the multi-ensemble workspace primitive that just shipped in Phase 1 — only makes sense after the global-jail behaviour has been load-bearing for months and the runtime knows precisely which invariants need preserving as the new primitive lands.
v1.0 is the first portable, durable, hardened version of the substrate. Everything from here is composition.
What I'd like to hear about
If you're running loomcycle on hardware I haven't tested, file an issue. If you're integrating loomcycle into a product, drop a line — every integration conversation so far has surfaced at least one substrate primitive worth adding (Volumes is the latest), and I'd like the next ones to keep that pattern going.
If you've been watching JobEmber.ai-shaped problems (per-user agent runs, scheduled background jobs, signed webhook ingress, secrets that should never reach an LLM) and waiting for a runtime to land them on: loomcycle is what I built. v1.0 is the first version that's not labeled "early adopter, here be dragons." Apache-2.0, self-hostable on a small VPS or a multi-replica cluster, no enterprise tier required for multi-tenancy (that lives in OSS, not paywalled).
Production teams inform the design; integration-shape ideas are the things that get RFCs written.
Companion reading: the substrate-shaped journey - exp1+2 · exp3 · exp4 · exp5 · exp6 + 6.5 + 6.8 · exp7. The hardening pass: 8-hour soak · 133 minutes on a local Qwen.