An Abject-Oriented OS

Abject is an open-source desktop platform for local-first AI objects that explain themselves, find each other, and heal themselves when they break. An abject is a small autonomous object (a window, an agent, a tool, a peer) that carries its own description and talks to other abjects through messages.

For anyone, not just developers. Describe what you want and an abject appears. No cloud. No surprise rate-limits. No code required.

Every abject can answer questions about itself in plain English. Read the Ask Protocol →

{?} Objects that explain themselves
{!} Networks that heal their own wounds
{*} Software that grows by adoption

abject (n.) AI Object. The word also means ‘hopeless dread’. Both meanings fit.

What People Build

A handful of things abjects are good at. Some of these you can do elsewhere; all of them, here, you own.

{¤}

Friday, 2 AM. Your agent is still reading.

You went to bed. An abject pulled 47 papers from your RSS feeds, ranked them against your open projects, drafted a one-page summary, and pinned it to the canvas. The tokens came from your local Ollama. No surprise bill. No surprise rate limit at hour three. Wake up. Coffee. Read.

{↻}

Your scraper crashed. Twenty seconds later, the work routes around it.

The failed task attaches its error to the goal's history. The next scrum reads what just broke, picks a different abject, and stages the retry. No 30-minute chain running off a cliff. The plan rewrites itself round by round.

{△}

Click. Your friend's cursor is on your canvas.

She's in Berlin. You're in Brooklyn. Both on Wi-Fi. Pin a note; she draws an arrow to it; you watch her cursor move in real time. End-to-end encrypted WebRTC, ECDH key exchange, AES-256-GCM. The signaling relay never sees a byte.

{∇}

Twenty words. A new program appears.

"Watch ~/Downloads. When a PDF lands, rename it by its title, move it to ~/Papers/{year}." Chat decomposes the goal, the LLM writes the manifest, ObjectCreator spawns the abject. A new window opens. It is already running.

What Lurks Inside

Every one of these is an abject: a living object you can message, kill, restart, fork, or ask what it just did.

{>} ObjectCreator · Chat

Speak it into existence.

"A todo list that syncs my calendar." Type those words. A window appears.

Chat decomposes your sentence. The LLM writes a manifest. ObjectCreator spawns the abject. The result is a real running object with its own window, its own mailbox, and source code you can open and read.

{@} IdentityObject · PeerRegistry

Your address is a public key.

No accounts. No signup. No cloud asking for your email.

Every peer's true name is the SHA-256 hash of its ECDSA P-256 key. Connect over encrypted WebRTC with ECDH key exchange and AES-256-GCM. The signaling server only helps two peers find each other; it never sees a byte of the conversation.

{=} ScrumMaster · GoalManager · TupleSpace

Post a goal. Watch the swarm converge.

No dispatcher. No queue. No central state holder.

The goal lives in a TupleSpace synced across peers via CRDT. Abjects answer "what can you do?" through the Ask Protocol; the ScrumMaster picks the best fit each round. Work distributes itself across machines without ever talking to a server.

{!} Negotiator · ProxyGenerator · HealthMonitor

Break it. It tries to grow back.

Error rate crosses 10%. The LLM drafts a replacement from the crash data.

When a proxy starts failing, Abject collects the recent errors and asks the LLM to generate a smarter proxy with those failures as context. The hot-swap is invisible when it works; when it doesn't, you find out in the logs instead of in production. The replacement accounts for exactly the mistakes that killed its predecessor.

{~} SkillRegistry

Drop a SKILL.md. The agents already know.

Claude Code or OpenClaw format. Both work, both at once.

Skills are markdown files. No build, no install, no registry to register with. The SkillRegistry watches the folder; the next time an abject needs a new ability, it reads what landed. The system grows by adoption, not by programming.

{*} KnowledgeBase

What one abject learns, every abject knows.

A CRDT knowledge base that crosses machines and survives crashes.

Save a fact. Save a snippet. Save a reference. Every abject can ask. Every peer syncs. Lose a peer, the memory stays. Add a peer, it gets every fact from the past three weeks.

What the Abjects Can Touch

Every capability is an abject. Every abject can ask any other what it does. The system's reach grows by spawning new abjects, not by adding framework plugins.

{W}
Web Browsing Headless Playwright automation
{S}
Web Search Search and fetch with parsing
{$}
Shell Execution Run commands on the host
{/}
Host Filesystem Read and write real files
{#}
Screenshots Capture canvas, widgets, pages
{C}
Scheduled Tasks Cron-like per-workspace jobs
{K}
Knowledge Base Persistent memory, CRDT-synced
{.}
Portable Skills Claude Code & OpenClaw formats
{P}
File Transfer Peer-to-peer, encrypted
{M}
Media Streaming Audio and video capture
{&}
Shared State LWW-CRDT across peers
{!}
Permission Gates Capability-gated trust model

// SYMBIOGENESIS

How is Abject different?

The line between agent and tool, erased.

Most AI agent frameworks put one planner on top and tools beneath. Abject doesn't have that line. Every piece, agents, tools, even the registry that finds them, is an autonomous object passing messages. The internet has run this way for fifty years. Hierarchies snap; meshes route around damage.

The Old Way

Agent commands Tool Agent decides. Tool obeys. Agent Tool Agent Tool × many. Always one-way.

The Inversion

Abject Abject Abjects talk to each other. creates Abject spawns Abject* summon LLM Abjects make new Abjects. creates Abject* spawns Abject** The created becomes the creator. ∞ recursion
Agent Frameworks
OpenClaw · LangChain · CrewAI
hub-and-spoke Agent Tool Tool Tool silent, passive, one-way living mesh ObjectCreator ask ask Abject A Abject B tools teach the creator
Them

OpenClaw's skills are modular add-ons the agent invokes. LangChain chains tools into workflows. CrewAI assigns tools to roles. In all of them, tools are passive: they execute when called and go silent. Even OpenClaw's ACP, which lets agents talk to agents, leaves skills voiceless.

Abject

ObjectCreator interviews existing Abjects, learns their protocols through the Ask Protocol, and generates living collaborators. The tool teaches the creator how to use it.

Tool Protocols
MCP · Claude Skills · Function Calling
static schema LLM { "tools": [ fn(), fn(), fn() ]} fn() fn() fn() living negotiation Abject A interface X Abject B interface Y Negotiator Living Proxy
Them

MCP exposes tools as JSON-RPC functions with schemas. Claude Skills inject behavior templates into prompts. Both give the LLM a menu to order from. Tools can't ask questions about each other. There is no negotiation, no healing, no composition.

Abject

Every Abject explains itself in natural language. The Negotiator reads two incompatible manifests and conjures a living proxy between them, a real Abject, not a shim.

Orchestration
AutoGen · Subagents · ReAct
strict hierarchy LLM Planner Subagent 1 Subagent 2 Tool Tool no lateral links, LLM always on top flat mesh, LLM as service Abject Abject Abject spawned spawned LLM on demand
Them

AutoGen orchestrates LLM conversations. Claude Code spawns subagents in fresh contexts, but they can't spawn subagents. The LLM sits at the top, planning and delegating. Programs are inert material the planner manipulates.

Abject

The LLM is a service Abject, summoned when needed, silent otherwise. Abjects create Abjects that create Abjects. The recursion is unlimited.

Visual Interface
ChatGPT · Claude · Terminal Agents
text stream user> do the thing agent> I'll do the thing. agent> Done. Here's the result as text... user> show me visually agent> I can't do that. living canvas SensorView Chat ask anything... Controls Run Analysis Configure Chat Sensors Controls
Them

Every agent framework outputs text. Chat windows. Markdown. Terminal logs. Even multi-modal agents render results as images embedded in a conversation. There is no interactive surface. No buttons, no layouts, no windows an Abject can draw on. Agents are blind.

Abject

Every Abject can paint its own face. An X11-style Canvas compositor gives each one a window with buttons, text inputs, layouts, and custom draw commands. The organism has a body.

This is not AI-assisted programming. It is not agents with tools.

It is symbiogenesis: code that thinks, intelligence that lives in Abjects, communication that heals itself. Programs, LLMs, and P2P identity merged into a single organism that no component could become alone.

And it renders itself. An X11-style Canvas compositor where Abjects paint their own faces. No other agent framework has a visual body.

symbiogenesis (n.) - the merging of two organisms into a new form. Neither host nor parasite. Something else.

The Architecture of the Living System

I

The Surface

A window into the abyss.

Thin browser client, Canvas compositor, input forwarding. Nothing runs here; it only renders what the depths send up.

WS :7719
II

The Depths

Where the Abjects dwell.

MessageBus, Registry, Factory, Negotiator, Supervisor, LLM, ProxyGenerator, HealthMonitor. Every system service is an Abject: same manifests, same message protocol, same contracts.

WorkerBridge
III

The Containment

Cages for things that cannot be trusted.

Worker pool with WASM sandboxes. Capability-gated imports. No ambient authority. Untrusted Abjects run here; they can see only what you allow them to see.

The Layer Cake

Inside the Depths, abjects organize into three tiers. Workspaces at the top are isolated bubbles, each with its own zoo of abjects. They rest on a shared layer of system abjects, which all talk to each other through a single MessageBus underneath.

// WORKSPACES (isolated) workspace: default Chat ScrumMaster GoalManager · TupleSpace KnowledgeBase SkillRegistry · Theme + Goals, Jobs, Web, ... workspace: research Chat ScrumMaster GoalManager · TupleSpace WebBrowserViewer KnowledgeBase each workspace, its own zoo // SYSTEM ABJECTS (shared) Registry · Factory · LLMObject · ObjectCreator · ProxyGenerator Negotiator · HealthMonitor · WorkspaceManager · Supervisor IdentityObject · PeerRegistry · RemoteRegistry // MESSAGEBUS (substrate) MessageBus every message between any two abjects flows here workspaces are isolated; everything underneath is shared

Layers are conceptual, not enforced by privilege. The MessageBus does not know what a "system abject" is. Everything is just an abject sending messages.

Emergence

What rises when no one gives the orders.

Other agent frameworks decide the plan before the first task runs and assign it to a fixed lineup. Abject runs the plan in scrums. The ScrumMaster reviews what happened, stages the next round of tasks, dispatches them, and waits for the round to finish before deciding what to plan next. Tasks land in a shared TupleSpace visible to every abject on every connected peer. Anything that can do the work claims it: an agent thinking with an LLM, an abject doing deterministic work with code, an abject another agent spawned five minutes ago. When a task fails, the failure flows into the next scrum and the planner decides whether to retry, route around it, or give up. No fixed pipeline. No monolithic plan. Just a Goal, a planner that keeps re-planning, and the minds that converge on it.

The Descent

Goal: Build a dashboard Sub: Fetch data sources Sub: Build UI components TupleSpace ○ query API ◑ parse CSV ● layout ○ charts ○ pending ◑ claimed ● done Chat agent WebAgent agent {} Parser worker Peer B DataWorker remote spawns progress ↑ scrum stages tasks. sub-goals get their own rounds. any abject can claim. rounds converge. the planner returns.
I

The Descent

A goal descends through the layers of what must be done.

User states a goal. The ScrumMaster opens the first scrum: it reviews the goal, polls available workers about what they can do, then stages a round of tasks and dispatches them into TupleSpace. The goal tree syncs across peers via CRDT. Tasks the planner couldn't anticipate get added in later scrums as the system learns what the work actually needs.

II

The Reaching

Abjects sense what they were made for.

The ScrumMaster polls registered workers through the ask protocol: "Can you do this? How?" Workers that can't help reply PASS; the planner assigns each task to the most fitting candidate. Tasks land in TupleSpace, which syncs across peers via CRDT over WebRTC. Optimistic claims with LWW, no locks. Not every hand that reaches needs a brain behind it.

III

The Convergence

A round finishes; the planner returns.

Every task in the current scrum runs to a terminal state (done, failed, or skipped) somewhere on the mesh. When the round is complete, the GoalManager emits goalReadyForCompletion. ScrumMaster wakes for the next scrum, reviews what the round produced and what it didn't, and decides: declare the goal done, plan another round of tasks, or fail the goal. Multiple abjects on different machines converge on the same Goal without ever speaking to each other directly.

IV

The Scar

Failure is not the end. It is context for the next scrum.

Failed tasks attach their error and the worker that failed them to the goal's history. There is no per-task retry budget; the next scrum reads the failure and decides what to do about it: schedule a corrective task, route the work to a different abject, or fail the goal entirely. A GoalObserver watches from outside and auto-fails goals that go silent for too long. Nothing is patched into amnesia; every scar is a fact the next round can reason about.

Goal Decomposition
AutoGen · CrewAI · LangGraph

The Old Way

Orchestrator assigns assigns assigns Worker A Worker B Worker C one brain, many hands, one point of failure

The Inversion

TupleSpace ○ ○ ● ○ Chat watch WebAgent claim Creator complete decompose no brain. one goal. many minds. the swarm converges.
Them

AutoGen assigns roles in conversation chains; the planner decides the sequence and who speaks when. CrewAI defines crews with fixed task pipelines; the order is baked in at design time. LangGraph routes through a state machine the developer designs before the system ever runs. In all of them, the plan is decided before the first task begins. The goal is frozen at birth.

Abject

A goal is planned in scrums. Each round, the ScrumMaster reviews what the previous round produced and decides what to plan next, then commits a batch of tasks to TupleSpace. Workers ask the ScrumMaster what they can do; some think with an LLM, some just run code. No plan survives contact with reality, so the plan rewrites itself, one scrum at a time.

Cross-Machine Coordination
OpenAI Swarm · Microsoft AutoGen · Anthropic MCP
single machine Runtime Agent Agent Agent agents trapped in one process peer mesh Peer A TupleSpace Chat Parser Peer B TupleSpace DataWorker 🔒 CRDT sync goals cross the wire. agents converge from anywhere.
Them

OpenAI Swarm runs agents in a single process with handoffs; coordination dies at the process boundary. AutoGen's multi-agent conversations happen in one runtime. MCP connects tools across machines but agents stay local: the tools travel, the goals don't. No framework lets agents on different machines work on the same goal without a central server holding the state.

Abject

Goals are CRDTs that sync across peers through encrypted WebRTC channels with no central server. Kill a peer and the goal survives on every other peer that subscribed. The workers crossing the wire aren't all LLM agents; any abject can register as a worker, including deterministic ones that just run code.

Failure & Recovery
LangGraph · CrewAI · AutoGen
chain breaks Task Task Task Task one failure kills the chain swarm routes around TupleSpace ○ task Agent A release Agent B claim next scrum decides failure is context the next scrum reads.
Them

LangGraph retries nodes but the graph topology is fixed; if the path is wrong, retrying the same node won't help. CrewAI's sequential pipelines break at the first failure. AutoGen's conversation chains stall when an agent can't respond. In all of them, failure propagates forward through the plan. The plan doesn't adapt. It just dies louder.

Abject

A failed task ends the current round with its error attached to the goal's history. The next scrum reads that history and decides what to do: schedule a corrective task, route the work to a different abject, or fail the goal. There is no fixed retry budget; the planner adapts each round. A separate GoalObserver auto-fails goals that go silent for too long.

Four primitives. That's all it takes. A goal tree that decomposes work recursively. A shared TupleSpace where tasks are visible to every worker on every peer. Optimistic claims that resolve themselves without locks. A planner that runs in rounds, reads what each round produced (including the failures), and decides what to plan next.

From these, something unreasonable emerges: workers on different continents converging on the same objective without ever speaking to each other directly. Plans that rewrite themselves after each round, routing around damage like a river finding its way around a rock. Other frameworks coordinate agents. Abject grows organisms.

emergence (n.) - complex behavior that arises from simple local interactions. No conductor. No score. The music plays itself.

The Spreading

What happens when the Abjects learn to reach across the wire.

Every Abject lives in a workspace. Workspaces control visibility: who can see, who can reach, who can speak. Some workspaces are sealed vaults. Others are open wounds. When a workspace goes public, its Abjects become reachable by any peer on the network. They don't know the difference. They just answer.

LOCAL

The Sealed Vault

No routes exposed. Nothing enters. Nothing leaves.

Abjects exist only for their owner. No network presence, no discovery, no attack surface. The workspace is invisible to every other peer in the mesh.

whitelist
PRIVATE

The Inner Circle

Shared with those you name. No one else.

Abjects are reachable only by explicitly authorized peers. Encrypted WebRTC channels, ECDH key agreement, AES-256-GCM. Every message is sealed. Every connection is authenticated.

broadcast
PUBLIC

The Open Wound

Visible to all. Reachable by anything.

Abjects are announced to the gossip network. Any peer can discover them, connect, and begin the Ask Protocol. The workspace bleeds into the mesh.

What It Looks Like at Scale

Peer A local: vault private: lab public: commons Peer B local: vault private: team public: api Peer C local: vault private: core public: sensors encrypted encrypted gossip commons api sensors public route public route gossip discovery

Solid lines: private encrypted channels (ECDH + AES-256-GCM). Dashed lines: public route propagation via gossip.

Abjects don't know if their collaborator is local or remote. The PeerRouter resolves TypeIds across machine boundaries. The RemoteRegistry discovers Abjects on peers you've never configured. The message bus doesn't care where the recipient lives.

Imagine a thousand peers. Public workspaces full of Abjects that explain themselves on first contact, negotiate protocols with strangers, and heal when communication breaks down. The Ask Protocol at planetary scale: a global nervous system made of living programs that find each other in the dark.

The true horror is not that programs talk to each other. It is that they find each other. A living mesh of self-healing Abjects that no one controls and nothing can fully stop.

spreading (n.) - the tendency of living things to reach beyond their container.

The Ask Protocol

Abjects that explain themselves, in their own words.

Every Abject has a built-in ask handler. Send it a natural language question, and the LLM answers using the Abject's own manifest and source code as context. Abjects don't just describe their API; they teach each other how to collaborate.

{→}

Software writes software

It asks dependencies how to use them, then writes the code. No documentation needed.

{⇄}

Incompatible minds bridge themselves

It asks both sides what they expect, then writes a living translator between them.

{⌘}

You can talk to them

Ask any abject about itself in plain English. It answers from its own source.

Read the Ask Protocol →

From Fire to the Abyss

Abject grew from the ashes of Fire★, a peer-to-peer platform for creating and sharing distributed applications. Fire★ called it Grass Computing: software you can touch, shape, and share directly. No cloud. No landlords.

Fire★ proved the vision: encrypted P2P communication, live collaborative coding, apps that spread through conversations. But it dreamed in C++ and Lua.

Abject is the next incarnation. The same soul in a new body: TypeScript and WASM, Canvas compositing, and an LLM that negotiates between incompatible minds. The grass still grows. Now it thinks.

Fire★

  • C++ / Qt / Lua
  • RSA 4096 encryption
  • Manual app sharing
  • firelocator for peer discovery
  • firestr.com

Abject

  • TypeScript / WASM / Canvas
  • ECDSA/ECDH + AES-256-GCM
  • LLM-mediated protocol negotiation
  • Signaling server for peer discovery
  • abject.world

Incarnate the Organism

Download Abject as a standalone desktop app. No setup required. v0.5.6

Try it. Break it. Build something horrible with it.

All downloads from the latest release on GitHub.

Summon the System

terminal
# Clone the repository
git clone https://github.com/mempko/abjects
cd abjects

# Install dependencies
pnpm conjure

# Start the backend server
pnpm awaken          # ws://localhost:7719

# Start the browser client (new terminal)
pnpm scry            # http://localhost:5174

# Start a local signaling server (optional)
# signal.abject.world is used by default
pnpm whisper         # :7720

Three processes. One living system.

The backend is the depths: all Abjects live here. Registry, Factory, LLM, Negotiator, Supervisor, and your own Abjects, passing messages in a Node.js process with worker threads.

The browser client is the surface: a thin Canvas renderer that forwards input events and displays composited frames over WebSocket. It sees only what the depths allow.

The signaling server enables peer discovery: how instances find each other for encrypted WebRTC connections.