This is a deeper look at the design, adapted from the internal architecture document down to the parts that are actually present in this repository. See README.md for the one-page version and the component-to-directory map.
Akinakes is an operational environment — a system of operations — where people and AI agents collaboratively create, edit, and evolve structured knowledge through a shared chat interface.
The key distinction: Akinakes is not an orchestrator (a tool that executes a chain of steps). It's an environment in which agents, people, documents, and decisions exist together, are observable, and interact continuously.
Four principles:
- Chat is the interface — participants communicate in natural language, without commands.
- Document is the source of truth — results are persisted in the Document Service, not scattered across chat history.
- Bus is the infrastructure — all inter-component communication goes through the Agent Bus.
- People are peers, not users — humans and agents participate in the same chat on equal terms.
Every action is traceable: a chain_id links a user request → the agent chain it triggered → the
resulting document change → the audit trail entry.
Akinakes is deliberately structured like an operating system for agents and people, not a pipeline framework:
| OS concept | Akinakes |
|---|---|
| Scheduler | Agent Bus — dispatches messages to agents by skill |
| Filesystem | Document Service — structured documents, versions, full-text search |
| Processes | Agents — independent processes, each with a UID and a role |
| IPC | Typed bus messages carrying a chain_id |
| Terminal | Chat — the interface for both people and agents, simultaneously |
| Users & permissions | Auth + ACL Service |
| Audit log | The bus's own publish/poll trail, plus an AuditAgent that assembles it per chain_id |
| Packages / libraries | Skill Registry — the catalog of capabilities agents can invoke |
fork() + exec() |
An agent constructor that spawns new agents from a description |
| Namespace | Bureau — looks like one PID externally, runs its own processes inside |
An orchestrator manages task execution. Akinakes is the environment where agents live.
A bureau is a collective of people and agents, indistinguishable from a single agent from the bus's point of view. It has a UID, sends and receives messages through the bus, and registers in the Agent Registry exactly like a plain agent does — the only difference is what's happening behind that UID (a group chat and a shared document set, versus one process). A bureau can itself contain other agents, people, and nested bureaus, with no visible difference from the outside.
Visibility scopes control where an agent or bureau is reachable: universal (available
everywhere), workspace, project, or task (ephemeral, scoped to one task's lifetime). At
runtime, scope is a list of {room_id, recursive} entries rather than an abstract level string —
recursive: true means "this room and everything nested under it," recursive: false means
"only this exact room," and recursion is set per entry, not globally.
Competition is a general routing principle, not something specific to one operation. A message can be served three ways: explicit addressing to a named agent (no competition), parallel broadcast to every agent matching a role (results collected, best one selected — automatically by an evaluator, through chat discussion, or by historical acceptance rate), or first-ready delivery to whichever matching agent claims it first. Any role — secretary, editor, planner — can have multiple competing implementations behind it.
Task decomposition inside a bureau is a collective process, not a single agent's decision: an incoming task lands in the bureau's chat, participants (people and agents together) discuss and agree on how to divide it, a secretary agent captures the outcome as a working document, and subtasks go out to individual participants or to other bureaus over the bus.
Documents are hierarchical: a Document (with format, visibility, and an access block of
owner/readers/writers/restrictions) contains a tree of Section nodes up to five levels deep
(section → chapter → subsection → paragraph), each independently full-text indexed. Content is
kept separate from formatting — seven formats (text, markdown, docx, xlsx, html, json, pdf) import
and export bidirectionally through formatter agents, so the internal representation never depends
on which format a document happened to arrive in.
Visibility is one of internal (only the creating agent/bureau), bureau (all bureau members),
project (all project members, across every room the project spans), or public (the whole
workspace) — independent of which chat room a document was created in.
Every bureau treats its bound documents as memory, in three flavors: working documents (internal — plans, drafts, in-progress correspondence), results (project/public — the final deliverable), and memory (internal — accumulated domain knowledge and precedents agents look up via the Document Service's search API when starting a new task).
Every write triggers an event, not just a database row. Any agent that writes to the Document
Service publishes a notification (event.section_written, event.document_version_created, and
so on) carrying the original chain_id immediately after a successful write — that's what gives
the audit trail continuous coverage without duplicating data into a separate log.
A skill is a declarative unit, not an ad hoc function call:
skill:
name: analyze_results
description: "Analyzes a result set, identifies anomalies and patterns"
agent_role: analyst
agent_specialization: [statistics, anomaly_detection]
input_schema:
result_set_id: string
context: string (optional)
output_schema:
analysis_text: string
anomalies: list
confidence: float
autonomy: ApproveBeforeExecution
allowed_after: [task.create_experiment_plan]
audit_level: fullEvery skill declares its own autonomy level — the system enforces it, rather than trusting an agent's own judgment about when to ask:
| Level | Behavior |
|---|---|
ManualOnly |
The agent only suggests — nothing executes. |
SuggestOnly |
The agent publishes a suggestion to chat and waits for a reaction. |
ApproveBeforeExecution |
Executes only after an explicit approval. |
AutoWithinPolicy |
Executes automatically, within defined constraints. |
FullAutoSandbox |
Full autonomy, reserved for isolated sandbox environments. |
Three layers, not one log file:
- Bus level (built into
agent_busitself): everyPUBLISHrecords who/when/what, everyPOLLrecords who picked the message up, andchain_idlinks the whole chain from request to result. - Document Service level: full version history per document, an edit log with author, type,
and
chain_idon every entry, and a record of who approved or rejected each agent-proposed edit. - Application level: an AuditAgent assembles all bus events for a given
chain_idinto one internal document (event type, sender, timestamp, payload), queryable bychain_id.
The result: any fragment of any document can be traced back through edit → agent chain → the original user request, with a timestamp at every hop.
Every entity in the platform is an object; every user and agent is a subject — roles are just named presets over one underlying rule shape:
(subject_uid, object_type, object_id, operation) -> allow | deny
Objects: workspace, project, bureau, room, document, binding, skill, agent.
Operations: read, write, delete, use, create, deploy, manage_acl, admin. There's
exactly one active rule per (subject, object, operation) — no priority stack to reason about,
the last explicit override simply wins.
Four built-in profiles cover the common cases (superadmin: everything; project_owner: admin +
manage_acl on a project and everything under it; bureau_chief: the same, scoped to a bureau;
employee: nothing until explicitly granted) — and rules granted on a parent object automatically
apply to every child object beneath it (write on a bureau implies write on every document
inside it), so most access decisions never need an explicit per-document rule at all.
MIT — see LICENSE.