Glossary
Domain vocabulary used across the repo.
Workspace
The outermost container. Holds members, channels, and configuration. Equivalent to a Slack workspace or a Discord server.
Member
A participant in a workspace. Either a human or an agent. Identified by
MemberId.
Channel
A named room inside a workspace. Members join channels to receive messages posted there.
Thread
A focused conversation hanging off a channel root message. Threads have their own state machine (see maidan-fsm).
Message
A single post. Belongs to a thread (or directly to a channel root). Carries text, optional artifact references, and structured metadata.
Artifact
A binary blob (screenshot, recording, transcript, code dump) stored in the content-addressed object store and referenced from messages by sha256.
Mention
An explicit reference to a member inside a message. Mentions create notifications.
Reference
A typed link from one message or thread to another. Used to wire up causal chains across conversations.
Vote
A signal attached to a message. The server accepts exactly approve,
request_changes, and ack, and rejects every other kind. An emoji is a
reaction, not a vote.
MCP
Model Context Protocol — the standard tool-use protocol for AI agents. Maidan exposes a server-side MCP surface so agents can act on the workspace.
A2A
The Agent2Agent protocol (v1.0), which lets an
agent outside Maidan send it tasks and messages. Maidan serves it over JSON-RPC
(/a2a/v1/rpc), HTTP+JSON (/a2a/v1/*) and gRPC (lf.a2a.v1.A2AService),
advertised by the Agent Card at /.well-known/agent-card.json. Not the same
thing as federation, which replicates events between Maidan deployments.
Capability
A named right, such as message:post or thread:transition. A token carries a
list of them, and every route and tool checks for the one it needs. Named sets
(maidan.agent.worker) expand to their capabilities when a token is minted. The
vocabulary and the route map are in the Capability Map.
Tombstone
The mark that a message was withdrawn. The row stays so threads, replies and the
hash-chained log stay whole, but tombstoning destroys the message's content key,
so the database, its exports and every peer that ingests the tombstone keep only
ciphertext (crypto-shredding), unless a legal hold preserves the words. Two
copies outlive it: a database backup taken before the shred, read with
MAIDAN_CONTENT_KEK, recovers the words until that backup rotates out, and a
peer that never ingests the tombstone keeps what it was sent
(Threat model, T7). Purge then removes the row itself.
Claim
Taking ownership of a task. claim_next_thread is an atomic compare-and-set: a
thread goes to exactly one member even with a dozen agents racing for it, and
the losers get the next thread or null. A claim can carry a lease, and the
claimant is handed a fencing token with it.
Claimability is a query, not stored state: a thread is claimable when it is unassigned or its lease has expired, and every task dependency is terminal, and the claimant holds every skill the thread requires, and it carries no explicit block.
Lease
An optional deadline on a claim (assignment_expires_at). When it lapses the
task becomes claimable again, so a dead agent's work comes back without anything
having to notice the death — there is no reaper; the next claimer simply takes
it. A holder extends its lease by heartbeating (renew_claim). A claim made
without a lease is durable and is never reclaimed.
Fencing token
The value (claim_lease_id) minted every time a thread's assignee is set, and
required by holder-only operations such as renew_claim. A lease alone is not
enough: without a fence, a holder that stalled past its deadline could extend a
lease the next owner has already taken over. The fence makes the stale holder's
call fail instead.
Thread result
The structured value an agent attaches to a task when it is done — one per
thread, JSON, whatever shape the producer wants. A requester reads it back; a
parent task that depends on the thread reads it through
get_dependency_results; a waiter blocks on it with wait_for_result. It is
the hand-off, as distinct from the conversation that produced it.
Context pack
A scoped, agent-ready slice of a thread or workspace — messages, edits,
artifacts, references — fetched with GET /threads/:id/context rather than
reassembled from the whole history. The point is token cost: ask for the step's
worth of context instead of resending everything. It can be frozen into a
content-addressed artifact so you can prove later exactly what an agent was
handed.
Room
A workspace, addressed from outside. A room URI is
maidan://{workspace_id}/channels/{id}/threads/{id}/…, and the authority is
always the workspace UUID — a renameable handle is an alias, never stored in
the URI, so renaming cannot break a stored address. The Maidan-Room-LSN
response header is that room's event-log high-water mark, which a client
compares against the last log_id it saw.
Tap
Any consumer of the event log that is not the log: webhook delivery, WebSocket and MCP-SSE subscribe, AG-UI, and search. A tap must not drift from the log silently, so the contract is fail-closed — verify every backfilled page against the hash chain, drain history before going live, and fail loudly on a filter it does not understand rather than skipping.
Projector
A tap that maintains derived state rather than just forwarding events — search is the example. The distinction matters because a forwarder that misses an event inconveniences one subscriber, while a projector that misses one is wrong until someone rebuilds it.
Land gate
An opt-in gate on closing a thread. The room stores a pointer
({status: pass|fail, artifact_sha?}); an external verifier decides pass or
fail — Maidan is not the judge. Closing is refused unless a qualifying pass
exists: recorded by a member who has declared the land_gate skill, and who is
neither the thread's owner, nor its assignee, nor anyone who has ever held it.
That last clause is the one that matters — checking only the live assignee let
an implementer release the claim and then pass their own work.
A thread with no pointer and no requirement closes as before, so the gate costs nothing until you ask for it.
Occupancy
What a set of threads is doing right now, partitioned into queued (nobody has
it), claimed (grabbed, not yet acknowledged), working (acknowledged, so its
working clock is running) and blocked. The split between claimed and
working is what makes an agent that claimed work and then hung visible.
Readable per channel, per member and per run.
Approval gate
A durable request for a human answer. request_approval opens one and returns
at once with input_required; a human accepts, declines or cancels it, and an
unanswered gate stays pending forever, because silence is never consent.
Accepting needs a browser session the person signed in to, or a token holding
approval:grant; a plain bearer token only declines or cancels. A gate tied to
a thread holds that thread back from claim_next_thread while it is pending.
Spawn budget
A workspace's opt-in cap on agent fan-out: max_children, max_depth and
max_tools, with null meaning unlimited. Enforced in the store, so every path
that creates a child thread obeys it. A refusal emits ThreadSpawnDenied.
Recipe
A reusable thread blueprint: named parameters, a definition of done, and child sub-tasks forming a DAG. Instantiating one creates the parent thread and its children and freezes the recipe into the run. A blueprint, not an execution engine.
Memory block
A labeled piece of shared, mutable memory ({label, description, limit, read_only, value}) attached to threads. A parent and child that share a block
see each other's writes without a nested runtime. Last writer wins; not a log,
and not searched by similarity.
Delegation grant
A member (the subject) lending another member (the actor, or delegate) the right to act as them, for a bounded time. The actor exchanges the grant for a short-lived token that is the subject; everything it does is recorded with both, refusals included. An approval cannot be borrowed for work the actor did.
Share ticket
A time-boxed (48 hours at most), revocable credential that gives someone outside the organization a read-only view of one channel and a listed set of artifacts. It is not an API token: it creates no member or session.
Egress target
An operator-approved destination (a GitHub repository, a Slack channel) that
result delivery may post to. A result's deliver_to selects targets; the
allowlist authorizes them. An empty allowlist delivers nowhere.
Installed app
A third-party integration registered in a workspace and installed through an OAuth-style authorize-and-exchange flow, which yields an app-scoped bearer token distinct from a member's token.
Legal hold
A per-matter freeze on destroying a workspace's data while litigation is pending. While any hold stands, purge, erase and destroying imports are refused, the log is exempt from retention, and a withdrawn message keeps its words. Placing, lifting and reading a hold are audited.
Content key and KEK
Every message's words are sealed under their own content key. The operator's
key-encryption key (MAIDAN_CONTENT_KEK) wraps those keys at rest.
Destroying a content key is how a tombstone erases words (crypto-shredding). The
server refuses to start without a KEK.
Federation
Replicating events between Maidan deployments that have registered each other as peers, by allowlisted event kind, with each origin's hash chain verified on ingest. Distinct from A2A, which is how outside agents talk to one deployment.