Appearance
Stage 3c: Self-Sufficiency 🗂️
Agents have their own data. The filesystem IS the source of truth. Copy a folder, get an agent. Delete a folder, it's gone.
Status: ✅ Complete Tests: 74/74 passing Philosophy: Unix + Mac app installation applied to AI agents.
Two Big Shifts
1. Per-Agent Data Namespaces
Each agent owns its data. Collections are namespaced:
{namespace}__{collection}
attendance-manager__records ← owned by attendance-manager
contact-manager__contacts ← owned by contact-manager
shared__config ← shared, requires grant
system__agents ← framework, read-only for agentsAccess model:
- Agent's OWN namespace: full access (read/write)
sharednamespace: requires explicit grantsystemnamespace: read-only for all agents- Cross-agent namespaces: requires grant from Axiom
2. Filesystem as Source of Truth
The folder IS the agent. No registry, no database sync, no strings.
tenant/agents/<agent-name>/
├── dna.md ← inherited, universal genetic code
├── instruction.md ← behavior (second person: "You are...")
├── config.json ← { name, skills[], grants[], metadata }
└── skills/ ← agent-specific skill markdowns (optional)Operations are just filesystem operations:
✅ Copy folder in → agent exists immediately
✅ Delete folder → agent gone immediately
✅ Edit config.json → changes take effect on next wake
✅ Zip folder → share an agent
✅ Git tracked → version controlledNew Organ: DataService
src/memoria/data-service.ts
Generic namespaced CRUD with access enforcement:
typescript
data.insert("attendance-manager", "records", { name: "Arun", date: "..." }, "attendance-manager");
data.find("attendance-manager", "records", { date: "2026-04-05" });
data.update("attendance-manager", "records", recordId, { status: "present" });
data.delete("attendance-manager", "records", recordId);Invalid namespace/collection names are rejected. Every record gets automatic id, createdAt, updatedAt, createdBy fields.
New Organ: AgentLoader
src/genesis/agent-loader.ts
Scans the filesystem for agents. No database.
typescript
loader.list() // scan tenant/agents/ → return all configs
loader.read(name) // read one agent's config.json
loader.exists(name) // does folder exist?
loader.create({...}) // write folder + files
loader.addSkill(name, skill)
loader.addGrant(name, grant)
loader.remove(name) // delete folder
loader.resolveDir(name) // returns framework or tenant dirFramework agents (like Axiom) live in agents/. Tenant agents live in tenant/agents/. Tenant agents can be created, modified, removed. Framework agents cannot.
New Tools (Every Agent Gets These)
| Tool | What It Does |
|---|---|
store_data | Save record to own namespace (or granted) |
query_data | Read records with filter |
update_data | Update record by id |
delete_data | Delete record by id |
New Tools (Axiom/Structural)
| Tool | What It Does |
|---|---|
remove_agent | Delete a tenant agent folder |
grant_collection_access | Allow agent to access another namespace |
The Attendance Example (End-to-End)
USER: "Create an agent to track attendance, with data tools"
AXIOM:
add_agent(
name="attendance-manager",
instruction="You handle attendance marking and queries...",
initial_skills=["store_data", "query_data", "send_message"]
)
→ Creates tenant/agents/attendance-manager/
├── dna.md
├── instruction.md (your instruction)
├── config.json { skills: [...] }
└── skills/
USER: "Mark Arun present on 5th April"
AXIOM: delegate_to_agent(attendance-manager, ...)
↓
attendance-manager:
store_data(
collection="records",
data={ name: "Arun", date: "2026-04-05", status: "present" }
)
→ Saved to attendance-manager__records collection
USER: "Who was present on 5th April?"
AXIOM: delegate_to_agent(attendance-manager, ...)
↓
attendance-manager:
query_data(
collection="records",
filter={ date: "2026-04-05", status: "present" }
)
→ Returns all matching recordsSharing Data Between Agents
USER: "Create a reporter that reads attendance data"
AXIOM:
1. add_agent("reporter", instruction, [query_data, send_message])
2. grant_collection_access(
agent_name="reporter",
namespace="attendance-manager",
collection="*",
access="read"
)
Now reporter can:
query_data(
namespace="attendance-manager", ← cross-namespace
collection="records",
filter={...}
)The Shareable Organism
Because everything is in folders, you can share agents like Mac apps:
bash
# Export an agent
zip -r attendance-manager.zip tenant/agents/attendance-manager/
# Someone else imports it
unzip attendance-manager.zip -d tenant/agents/
# Done. Their organism has the same agent.Agent marketplace becomes trivial. Community-built agents, just download and drop in.
Data Persistence on Deletion
Delete an agent folder:
- Agent disappears from the organism
- Its MongoDB collections REMAIN
Recreate an agent with the same name:
- All previous data is there
This is a FEATURE. Drop folder to trash → agent paused.
Drag folder back → agent resurrected with full memory.Full cleanup (if you really want it) requires manual MongoDB collection drop.
Why This Architecture
| Traditional SaaS | Orbita Filesystem Model |
|---|---|
| DB is source of truth | Filesystem is source of truth |
| Admin panel to manage agents | Folders in a directory |
| Export/import via API | Zip a folder |
| Custom code per customer | Instruction markdown per customer |
| Opaque state | cat config.json |
| Complex registry sync | Scan directory |
The organism is transparent. Open any folder, read any file. Nothing hidden.
Code Changes
Removed:
✗ src/genesis/agent-registry.ts (MongoDB-backed registry)
Added:
✓ src/genesis/agent-loader.ts (filesystem scanner)
✓ src/memoria/data-service.ts (generic namespaced CRUD)
✓ src/tools/data-tools.ts (store/query/update/delete)
✓ src/tools/remove-agent.skill.ts
✓ agents/axiom/config.json (Axiom is just a folder too)The runtime (src/) is just the enabler. The organism is the folders.