{"id":51141268,"url":"https://github.com/markmhendrickson/ateles","last_synced_at":"2026-06-25T23:30:22.548Z","repository":{"id":359576409,"uuid":"1246652570","full_name":"markmhendrickson/ateles","owner":"markmhendrickson","description":"Personal agent swarm infrastructure — attributed, capability-scoped, Neotoma-canonical","archived":false,"fork":false,"pushed_at":"2026-06-24T20:42:05.000Z","size":3642,"stargazers_count":2,"open_issues_count":24,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-24T22:12:02.663Z","etag":null,"topics":["aauth","agent-swarm","ai-agents","autonomous-agents","claude","llm","mcp","neotoma","reference-architecture"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/markmhendrickson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-22T12:11:06.000Z","updated_at":"2026-06-24T15:28:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/markmhendrickson/ateles","commit_stats":null,"previous_names":["markmhendrickson/ateles"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/markmhendrickson/ateles","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmhendrickson%2Fateles","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmhendrickson%2Fateles/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmhendrickson%2Fateles/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmhendrickson%2Fateles/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/markmhendrickson","download_url":"https://codeload.github.com/markmhendrickson/ateles/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markmhendrickson%2Fateles/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34796761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-25T02:00:05.521Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aauth","agent-swarm","ai-agents","autonomous-agents","claude","llm","mcp","neotoma","reference-architecture"],"created_at":"2026-06-25T23:30:20.072Z","updated_at":"2026-06-25T23:30:22.536Z","avatar_url":"https://github.com/markmhendrickson.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ateles\n\n**A single-operator AI agent swarm that runs a founder's company and personal life — every agent action\nattributed, capability-scoped, and queryable.**\n\nAteles is the reference architecture for running a *fleet* of AI agents as one person. It is two systems in\none repository:\n\n1. **A governed runtime substrate** — AAuth-signed agent identities, capability grants, an append-only\n   observation log, confidence × blast-radius execution gating, and workflow orchestration. This is what\n   makes a fleet *trustworthy*: you always know which agent did what, on whose authority, and within what\n   scope.\n2. **A working operations suite** — 18 background daemons and ~87 skills that already automate code review,\n   releases, issue triage, email, calendar, recurring payments (fiat + Bitcoin), meeting capture and recap,\n   health tracking, customer development, content and social, multi-jurisdiction tax prep, and CRM.\n\nEverything is built around [Neotoma](https://github.com/markmhendrickson/neotoma) as the canonical memory\nand state layer. T1 hosts, T2 resident agents, T3 daemons, and T4 invocable agents are all defined as\nNeotoma entities, dispatched through AAuth-signed identities, and audited through the same observation log\nthey write to. Open source. Local-first. MIT licensed.\n\n**Who it's for:** [docs/icp.md](docs/icp.md) · **Architecture:** [docs/architecture.md](docs/architecture.md)\n· **Taxonomy:** [docs/taxonomy.md](docs/taxonomy.md) · **Phases:** [docs/phases.md](docs/phases.md)\n\n\u003e **Not a package — a blueprint.** Ateles is a reference architecture you fork and adapt, not an installable\n\u003e product. It assumes one operator who owns the machine, the keypairs, and the Neotoma instance. See\n\u003e [Who this is for](docs/icp.md) for the precise profile and the explicit anti-profile.\n\n## Why this exists\n\nYou run AI agents across tools and tasks. Without a swarm infrastructure layer, *you* become the swarm:\n\n- Every agent operates from zero context — nothing it learns is shared across agents or sessions.\n- Identities collapse — a code-writing agent acts as you on GitHub, with no audit trail tying the AAuth\n  subject to the action.\n- Decisions execute without a reproducible trail — you can't trace why an agent did something or whether it\n  stayed in scope.\n- Orchestration is ad-hoc — kicking off a multi-agent workflow means manually opening chats and hoping they\n  don't conflict.\n\nThese are not hypothetical. They are what happens when one operator runs more than three agents in parallel\nacross more than two products. You compensate with bespoke scripts, redundant prompts, and manual sync.\nAteles removes that tax.\n\n## What the swarm actually does\n\nThe largest part of this repo is not abstract — it is concrete automation the operator runs every day. The\nfleet spans the operator's whole surface area, company and life alike:\n\n| Domain | What runs | Daemons / skills |\n| --- | --- | --- |\n| **Software delivery** | Implement issues, review and steward PRs, QA, cut releases, triage issues/PRs off GitHub webhooks | `cicada`, `vanellus`, `lanius`, `phoenicurus`, `struthio` skills; `formica`, `neotoma-agent`, `phoenicurus-release` daemons; `loxia` PR-review GHA |\n| **Email** | Triage inbox, draft replies, route operator replies back to run threads, daily digests | `turdus`, `riparia` daemons; `email-triage`, `email-triage-auto` skills |\n| **Calendar \u0026 scheduling** | 05:00 meeting-prep briefings, recurring-task ↔ calendar sync, slot-finding | `cotinga`, `sylvia` daemons; `remember-calendar`, `find-technician-slot` skills |\n| **Payments \u0026 finance** | Calendar-triggered recurring payments in fiat (Wise) and Bitcoin, portfolio/liquidity analysis, expense capture | `monedula` daemon; `fringilla`, `run-scorecard`, `extract-amazon-order`, `quarterly-portfolio-review` skills |\n| **Meetings** | Toggle recording, transcribe (with consent tracking), extract decisions/action items, draft recaps | `strix`, `tyto`, `piculet` daemons; `record_meeting`, `analyze-meeting`, `import-audio` skills |\n| **Health \u0026 fitness** | Log workouts, analyze progression, nudge on inactivity | `gorilla` daemon; `gorilla`, `scrape-chatgpt-workout` skills |\n| **Content \u0026 GTM** | Long-form and build-in-public writing, platform-adapted social, marketing/positioning, brand \u0026 UX | `corvus`, `write`, `write-blog-post`, `social`, `ciconia`, `manucode`, `aythya`, `accipiter` skills |\n| **Customer development** | ICP synthesis, feedback analysis, interview admin, contact intake | `hirundo`, `analyze-neotoma-feedback`, `process-feedback`, `interview-admin`, `intake-relationship` skills |\n| **Relationships / CRM** | Lifecycle management of investors, advisors, partners, customers | `sturnus` agent (CRM in Neotoma) |\n| **Tax \u0026 legal** | Multi-jurisdiction tax prep, contract/GDPR/IP review | `picus`, `buteo` skills |\n| **Operator briefing** | 05:30 digest in the operator's voice; pages only on real escalations | `morning-brief`, `aquila` daemons; `priority_rubric` filter |\n| **Mirror \u0026 sync** | Neotoma → git mirror of agent definitions, env/secret sync | `apus` daemon; `sync-env-from-1password`, `deploy-website` skills |\n\nUnderneath all of it, the **governance substrate** records, scopes, and gates every action — described next.\n\n## What makes the fleet trustworthy\n\nAteles is a single-operator agent swarm where:\n\n- **Agents are entities, not files.** Each `agent_definition` lives in Neotoma. Updating an agent's\n  behaviour is a `correct()` call, not a code commit. SKILL.md files on disk are generated mirror artifacts.\n- **Every action is attributed.** Agents authenticate via AAuth-signed JWTs (RFC 9421 HTTP message\n  signatures, ECDSA P-256). The `github_harness` MCP server records tool calls with both the AAuth subject\n  (who claimed to act) and the PAT attribution (who actually acted on GitHub).\n- **Capability is scoped.** `agent_grant` entities declare which agents may call which tools, against which\n  repos, with which parameter constraints. A `mcp_tool_grant_proxy` sits in front of every MCP server and\n  rejects out-of-scope calls before any side effect.\n- **Dangerous actions checkpoint.** A confidence × blast-radius gate runs low-blast work unattended and\n  parks high-blast actions (push, merge, payment, external comms) as a `checkpoint_brief` for operator\n  approval.\n- **Workflows are typed.** A `workflow_definition` declares phases, gates, owner agents, and skip\n  conditions. Anthus reads workflows from Neotoma and dispatches gates in order.\n- **State is canonical.** Participation records, grants, policies, and observations are all Neotoma\n  entities. The swarm has no other source of truth.\n\n### Four foundations\n\n| Foundation | What it means |\n| --- | --- |\n| **Attributed** | Every action records `agent_sub` (AAuth identity) and `pat_attribution` (GitHub identity). The trust boundary is visible at every call. |\n| **Capability-scoped** | Agents only have the powers their `agent_grant` declares. Out-of-scope calls return `wrong_capability` before any side effect, enforced by the MCP grant proxy. |\n| **Workflow-driven** | Phases, gates, and skip conditions live in `workflow_definition` entities. Anthus reads them and dispatches accordingly — no hardcoded sequencing. |\n| **Canonical-source-of-truth** | Agent definitions, grants, policies, and participation records all live in Neotoma. Disk artifacts are mirror outputs, never inputs. |\n\nFull design: [docs/architecture.md](docs/architecture.md).\n\n## Architecture\n\n```mermaid\ngraph TB\n  Operator[Operator] --\u003e|Telegram, email, terminal| Ateles\n  Ateles[Ateles T2 — primary interface] --\u003e|paged via priority_rubric| Operator\n  Anthus[Anthus T3 — swarm coordinator] --\u003e|notifies| Ateles\n  Apis[Apis T3 — task dispatcher] --\u003e|confidence × blast-radius gate| Workers\n  Anthus --\u003e|dispatch by workflow gate| Workers[T4 workers: Cicada · Vanellus · Pavo · …]\n  Workers --\u003e|every tool call| Harness[github_harness MCP + grant proxy]\n  Harness --\u003e|AAuth verify, PAT lookup, observation record| Neotoma[(Neotoma)]\n  Apus[Apus T3 — mirror webhook] --\u003e|regenerates SKILL.md from| Neotoma\n  Neotoma --\u003e|SSE events| Anthus \u0026 Apis \u0026 Formica\n  subgraph Ops daemons\n    Cotinga[Cotinga — briefings] \u0026 Monedula[Monedula — payments] \u0026 Turdus[Turdus — email] \u0026 Gorilla[Gorilla — health] \u0026 Tyto[Tyto/Piculet — capture] \u0026 Sylvia[Sylvia — recurring]\n  end\n  Ops_daemons --\u003e|read/write| Neotoma\n```\n\n- **AAuth-verified.** Every agent has a keypair. Every signed request carries an RFC 9421 signature the\n  harness verifies before acting.\n- **Capability-scoped.** `agent_grant` entities declare which agents can call which tools against which\n  repos. Wrong-capability calls fail with structured errors at the grant proxy.\n- **Observation-backed.** Harness and proxy calls write observation entities. Replay any agent's actions\n  over any time window from the log.\n- **Mirror-canonical.** Agent definitions live in Neotoma; Apus mirrors them to disk as SKILL.md files.\n  Direct disk edits are reverted on the next mirror pass.\n\n## Entities, not files\n\nEverything Ateles knows about itself is a Neotoma entity. The filesystem is a generated mirror — useful for\nIDE tooling, but never the source of truth.\n\n| Concept | Lives as | Mirrored to | Direction |\n| --- | --- | --- | --- |\n| Agent prompt | `agent_definition` | `.claude/skills/\u003cagent\u003e/SKILL.md` and `docs/agents/\u003cagent\u003e.md` | Neotoma → disk |\n| Agent capability | `agent_grant` | (none — read live by the harness + grant proxy) | Neotoma only |\n| Workflow phases | `workflow_definition` | (none — read live by Anthus) | Neotoma only |\n| Gate state | `participation_record` | (none — written by the coordinator) | Neotoma only |\n| Every tool call | observation entity | (none — append-only log) | Neotoma only |\n| Operating rules | `agent_policy` | (none — enforced at dispatch) | Neotoma only |\n| Strategy posture | `business_strategy` / `domain_strategy` / `agent_strategy` | (none) | Neotoma only |\n\n**What this means in practice:**\n\n- **Behaviour changes are corrections, not commits.** Updating an agent's prompt is a `correct()` on its\n  `agent_definition`. Apus regenerates the SKILL.md mirror on the next webhook. Direct edits to\n  `.claude/skills/\u003cagent\u003e/SKILL.md` are reverted.\n- **Capability changes are entities, not configs.** Granting an agent access to a new repo is a `correct()`\n  on the `agent_grant`. The next harness call sees the new scope on the next pre-check; no daemon restart.\n- **Workflow changes are entities, not code.** Adding a phase to a workflow is a `correct()` on the\n  `workflow_definition`. Anthus picks it up from the SSE event stream.\n- **Audit is a query, not a grep.** \"What did this agent do last Tuesday?\" is a `retrieve_entities` against\n  the observation log. Git logs only show committed code; observations cover every harness call.\n\nThe filesystem layout matters for the runtime substrate — daemons need code on disk, Claude Code needs\nSKILL.md on disk — but it is downstream of the entity model, not the other way around.\n\n## Agent taxonomy\n\nFour tiers, named after bird and animal genera. **35 agent definitions** live in Neotoma today —\n**16 active, 18 planned, 1 proposed** — split **2 T2 · 14 T3 · 19 T4**. (Status is tracked in the generated\ntable and drifts from runtime reality faster than the daemons do — see [docs/taxonomy.md](docs/taxonomy.md)\nfor the canonical list and [Current status](#current-status) for what is actually running.)\n\n| Tier | Role | Examples |\n| --- | --- | --- |\n| **T1** | Hosts (a process that owns a channel) | OpenClaw / Claude Code (terminal), launchd (daemon scheduling), aiohttp Bot API |\n| **T2** | Resident agents (always-on, conversational) | Ateles (primary operator interface), Menura (public-facing representative) |\n| **T3** | Daemons (event-driven or scheduled, persona-light) | Anthus · Apis · Apus · Aquila · Cotinga · Formica · Monedula · Sturnus · Sylvia · Turdus · Tyto · neotoma-agent · … |\n| **T4** | Invocable agents (stateless, spawned per task) | Cicada · Vanellus · Pavo · Waxwing · Phoenicurus · Fringilla · Gorilla · Picus · Corvus · Hirundo · … |\n\nFull agent table with tiers, genera, and status: [docs/taxonomy.md](docs/taxonomy.md) and\n[docs/agents/](docs/agents/).\n\n## Daemons\n\n18 daemons live under `execution/daemons/`. They split into **event-driven** (subscribe to the Neotoma SSE\nstream or an HTTP webhook) and **scheduled** (run under a launchd calendar interval or poll on a timer).\n\n| Daemon | Role | Trigger | Notes |\n| --- | --- | --- | --- |\n| **anthus** | Swarm coordinator — workflow gate dispatch, escalation surfacing | SSE (task/issue/PR/escalation) | Coordination + escalation complete; full gate orchestration phasing in |\n| **apis** | Universal task dispatcher — routing, readiness + execution gates, A2A + GitHub gateway | SSE + HTTP (:8742) | Feature-complete core; several run-thread features flag-gated |\n| **apus** | Neotoma → git mirror webhook receiver (HMAC-verified) | HTTP (:8741) | Complete |\n| **aquila** | Monthly cofounder/strategy report | launchd (monthly) | Thin scheduler; reasoning in the `aquila` skill |\n| **cotinga** | 05:00 meeting-prep briefings (calendar + contacts + research) | launchd (daily) | Phase 1 complete; deep-prep agents fire-and-forget |\n| **cyphorhinus** | Telegram reply router | Telegram long-poll | **Deprecated** — superseded by `riparia` (email) |\n| **formica** | GitHub issue/PR triage → dispatch Cicada/Vanellus (ateles repo) | SSE | Dispatch complete; full automation phasing in |\n| **gorilla** | Weekly fitness summaries + inactivity nudges | poll | Complete; read-only |\n| **monedula** | Daily recurring payments (Wise + Bitcoin) with operator approval | launchd (daily) | Calendar→preview→approve→execute flow solid |\n| **morning-brief** | 05:30 operator digest in Ateles voice | launchd (daily) | Depends on Cotinga briefs; fallbacks present |\n| **neotoma-agent** | neotoma-repo automation + task due-date hygiene | SSE | Dispatch works; hygiene flag-gated |\n| **phoenicurus-release** | Mon–Thu release-candidate preparation | launchd (weekdays) | Preflight gate complete; release logic in `/release` skill |\n| **piculet** | Voice Memos + meeting-recording import \u0026 transcription | poll (~60s) | Fully fleshed import pipeline |\n| **riparia** | Email reply router (operator replies → run threads) | poll (~60s) | E3 transport, succeeding Cyphorhinus |\n| **strix** | macOS menu-bar recording toggle | click handler | Minimal but functional |\n| **sylvia** | Recurring-task lifecycle + calendar sync | launchd (daily) | Core scan present; recurrence logic phasing in |\n| **turdus** | Email triage → email_message entities + tasks | poll (~5m) | Keyword classification; LLM triage deferred |\n| **tyto** | Screenshot watcher + recording transcription (consent-stamped) | poll (~10s) | Watch + dispatch; OCR/analysis deferred |\n\nScheduling is `launchd` on macOS (plist templates in-repo for several daemons) or `docker-compose` on a\nsmall cloud host — see [deploy/cloud/](deploy/cloud/) and [docs/cloud_hosting.md](docs/cloud_hosting.md).\n\n## Runtime substrate\n\nThe shared library under `lib/daemon_runtime/` is the engineered core, with **44 test files** across the\ncodebase. Every module is fully implemented and used by at least one daemon; pure decision logic is kept\nseparate from I/O and fails open on network errors.\n\n| Module | What it implements |\n| --- | --- |\n| `aauth_httpsig.py` / `aauth_signer.py` / `neotoma_signed.py` | RFC 9421 ECDSA P-256 HTTP message signing; per-agent keypair loading (JWK/PEM); signed Neotoma requests |\n| `grant_checker.py` | Loads `agent_grant`, normalizes capabilities, enforces tool allowlists + parameter constraints (table allowlists, `max_amount_sats`, etc.) |\n| `gating.py` | Confidence × blast-radius execution gate; writes `checkpoint_brief` to block on operator approval |\n| `readiness.py` | Pre-dispatch task readiness scoring; parks under-specified tasks and emails the operator for the missing pieces |\n| `task_lifecycle.py` | Task status state machine (PENDING → … → DONE/FAILED/BLOCKED) with retry policy |\n| `generalizer.py` / `drift.py` | Cluster `strategy_drift_signal` evidence into agent-local `agent_policy` entities; contradiction handling |\n| `sse_client.py` | Async Neotoma SSE subscription with exponential-backoff reconnect |\n| `session_finalize.py` / `run_email.py` | End-of-run capture (conversation + turns); deterministic email threading for run conversations |\n| `notify/notifier.py` | Apprise-backed priority routing (Telegram + email), silence windows, digest collapse |\n\nMCP servers live under `execution/mcp/`: **`github_harness`** (AAuth-verified GitHub operations, per-repo\nPAT loading, observation recording) and **`mcp_tool_grant_proxy`** (a chokepoint that enforces `agent_grant`\non every `tools/call` and records a `tool_call_observation`, plus an observe-only session-integrity\ninvariant).\n\n## Skills\n\n`.claude/skills/` holds **87 skills** in two kinds:\n\n- **~39 agent-persona mirrors** generated from Neotoma `agent_definition` entities (do not edit — corrections\n  go through Neotoma). These are how a harness loads an agent's prompt.\n- **~48 hand-authored skills** the operator invokes directly — engineering workflow (`commit`, `push`,\n  `pull`, `debug`, `fix-feature-bug`, `create-release`, `final-review`), personal ops (`record_meeting`,\n  `email-triage`, `find-technician-slot`, `run-scorecard`, `language`, `scrape-chatgpt-workout`), content\n  (`write`, `write-blog-post`, `social`, `deploy-website`), and Neotoma/meta (`update-plan`, `update-tasks`,\n  `store-neotoma`, `intake`, `learn`).\n\n## Quick start\n\nAteles is a reference architecture, not an installable package. The fastest way to evaluate whether to adopt\nthe pattern is to read the architecture doc and inspect a working daemon and the runtime substrate.\n\n```bash\ngit clone https://github.com/markmhendrickson/ateles.git\ncd ateles\nless docs/architecture.md\nless execution/daemons/apus/apus.py          # a complete event-driven daemon\nless execution/daemons/monedula/monedula.py  # a complete scheduled daemon\nless lib/daemon_runtime/gating.py            # the execution-gating core\n```\n\nRunning any daemon locally requires Neotoma running (see\n[neotoma installation](https://github.com/markmhendrickson/neotoma#quick-start)), AAuth keypairs (or the\ndocumented operator-token fallback), and `agent_grant` entities for each daemon. The full setup walkthrough\nlives in [docs/setup.md](docs/setup.md).\n\n### Roadmap that shapes adoption\n\n- **Installability.** Adopt-by-forking works today; install-by-package does not yet exist — identity\n  provisioning UX, an operator config schema, keypair-format unification, plist generation, and a\n  multi-operator path are the gating work. Tracked on the\n  [issues board](https://github.com/markmhendrickson/ateles/issues).\n- **Input attribution.** The swarm records *who acted* and *what they produced*, but not yet the full set\n  of Neotoma entities each agent *read* before deciding. Closing that loop enables reverse impact analysis\n  and precedent graphs.\n\n## Example: a dispatch traced through the entity layer\n\nA product-decision dispatch. The CLI invocation is one step among ten; the rest happens in Neotoma.\n\n1. **Operator files an issue.** The body is the task body for the owning agent.\n2. **`formica` (T3) ingests the issue.** It reads the GitHub webhook event, stores the `issue` entity on\n   Neotoma, and emits a triage observation.\n3. **`anthus` (T3) reads the SSE event stream.** It matches the new `issue` against `workflow_definition`\n   entities and picks the matching workflow.\n4. **Anthus opens a `participation_record`** — one per gate. The first gate has `owner_agent`,\n   `status: dispatched`, `dispatched_at: now()`.\n5. **Anthus reads the owner's `agent_definition`** from Neotoma — `prompt_markdown`,\n   `context_entity_types`, `operational_entity_types`, `allowed_tools`.\n6. **Anthus spawns `claude --print`** with the agent's SKILL.md as `--append-system-prompt` and the issue\n   body as the user prompt. The agent's AAuth keypair is loaded from `ateles-private/keys/`.\n7. **The agent reads context entities** through `mcpsrv_neotoma` — whatever its `context_entity_types`\n   lists.\n8. **The agent writes its decision** as a new entity, attributed to its AAuth subject, and emits a single\n   bracketed artifact-header line as its final stdout.\n9. **Anthus parses the artifact header** and updates the `participation_record` to `status: satisfied`,\n   `satisfied_at: now()`, `artifact_ref: ent_…`.\n10. **Anthus advances the workflow** — opens the next `participation_record` for the next gate, and the loop\n    repeats.\n\nEverything after step 1 is driven by entities. The operator can replay the full sequence later from the\nobservation log and `participation_record` history. No grep, no git log.\n\n## Structure\n\nThe filesystem is the runtime substrate that supports the entity layer — the mirror, not the source.\n\n```\nateles/\n├── .claude/\n│   ├── skills/             # 87 skills: agent-definition mirrors + hand-authored operator/dev skills\n│   └── hooks/              # session-integrity hooks (session_start, user_prompt_submit, stop_finalizer)\n├── docs/                   # architecture, taxonomy, phases, ICP, runbooks, design notes (see docs/README.md)\n│   └── agents/             # canonical harness-neutral agent_definition mirrors\n├── execution/\n│   ├── daemons/            # 18 T3 daemon implementations (see Daemons table)\n│   ├── mcp/                # github_harness MCP + mcp_tool_grant_proxy\n│   ├── scripts/            # domain scripts (transcription, grants, PR review, releases, sweeps)\n│   └── lib/telegram/       # Telegram send helpers\n├── lib/\n│   ├── daemon_runtime/     # AAuth signer, SSE client, grant checker, gating, readiness, lifecycle, …\n│   ├── notify/             # Apprise-backed priority notification routing\n│   ├── activity/           # observation/activity helpers\n│   └── issue_labels.py     # frozen GitHub label enums shared by daemons + GHA\n├── scripts/                # linters, git hooks, setup, secrets tooling\n├── deploy/cloud/           # Docker + docker-compose + bootstrap for a cloud host (SOPS+age, Tailscale)\n└── .github/workflows/      # CI: secret/PII scan, Loxia PR review, Lanius stale-issue sweep\n```\n\n## State guarantees 🔒\n\nThe swarm makes specific, code-backed commitments about what is verifiable.\n\n| Property | Without swarm infra | Ad-hoc agents | Ateles |\n| --- | --- | --- | --- |\n| 🪪 Agent identity verifiable | ❌ | ⚠️ partial (PAT only) | ✅ AAuth-signed (RFC 9421) |\n| 🔍 Trust boundary visible (sub ≠ pat) | ❌ | ❌ | ✅ both recorded |\n| 🚧 Capability scope enforced | ❌ | ⚠️ via PAT scopes only | ✅ `agent_grant` pre-check + MCP grant proxy |\n| 📋 Per-action audit trail | ❌ | ⚠️ git commits only | ✅ observation log |\n| 🚦 High-blast actions gated | ❌ | ❌ | ✅ confidence × blast-radius checkpoint |\n| 🔄 Workflow phase ordering | ⚠️ manual | ⚠️ manual | ✅ `workflow_definition` + Anthus |\n| ⏪ Replayable orchestration | ❌ | ❌ | ✅ `participation_record` log |\n| 📜 Agent definitions versioned | ❌ | ⚠️ git history | ✅ Neotoma observation history |\n| 🔔 Operator paged only on real escalations | ❌ | ⚠️ notification spam | ✅ `priority_rubric` filter |\n| 🧠 Inputs to a decision recorded | ❌ | ❌ | ⚠️ in flight (input attribution) |\n\nOutput attribution (who acted, against which capability, producing what) is solved and tested. Input\nattribution — recording the entities each agent consulted before deciding — is the open frontier.\n\n## Interfaces\n\nThe swarm exposes operational surfaces that all converge on Neotoma as source of truth.\n\n| Interface | Description |\n| --- | --- |\n| **Telegram (Ateles)** | Operator paging surface. Receives BLOCKER / OPERATOR_DECISION pages; the operator replies inline. |\n| **Email (swarm mailbox)** | Run-thread transport: Apis emails run kickoff/outcome; Riparia routes operator replies back into the run conversation. |\n| **`claude --print`** | Agent dispatch surface for both operator and coordinator. Each invocation passes `--append-system-prompt \"$(cat SKILL.md)\"`. |\n| **github_harness MCP** | Every code-touching agent's call surface — AAuth-verified, capability-scoped, observation-logged. |\n| **Neotoma SSE** | The substrate. Daemons subscribe by entity type; issues, PRs, tasks, escalations, and reports flow through this stream. |\n\n## Agent entity types\n\nEvery swarm-defining record is a typed Neotoma entity. The canonical `entity_type` values Ateles reads and\nwrites:\n\n| `entity_type` | What it stores |\n| --- | --- |\n| `agent_definition` | Identity, prompt, triggers, context types, operational types, allowed tools |\n| `agent_grant` | Capability scope — Neotoma entity-op allowlist + MCP tool allowlist + parameter constraints |\n| `agent_action_observation` / `tool_call_observation` | One row per tool call — AAuth sub, PAT attribution, tool, owner/repo, result |\n| `agent_policy` | Operating rules (mandatory / recommended / prohibited) with scope |\n| `workflow_definition` | Phases, gates, owner agents, skip conditions, preconditions |\n| `participation_record` | Per-gate dispatch + satisfaction history |\n| `checkpoint_brief` | A high-blast action parked for operator approval |\n| `business_strategy` / `domain_strategy` / `agent_strategy` | Hierarchical strategy DAG — root + per-area + per-agent posture |\n| `strategy_drift_signal` | Agent-emitted observation when work contradicts current operating assumptions |\n\nFull type catalog: [docs/data_types.md](docs/data_types.md).\n\n## Current status\n\n**Phase:** Reference architecture in daily autonomous + operator-driven use. **Operator:** one (Mark\nHendrickson). **License:** MIT.\n\n**What is solid (implemented and tested):**\n\n- The **runtime substrate** — AAuth RFC 9421 signing, grant checking with parameter constraints, execution\n  gating, readiness scoring, task lifecycle, drift-driven generalization, SSE subscription, notification\n  routing — backed by 44 test files.\n- **MCP enforcement** — the grant proxy rejects out-of-scope tool calls before side effects and records\n  observations; the session-integrity invariant rides the same chokepoint (observe-only).\n- **Complete daemons** — Apus (mirror webhook), Monedula (payments), Piculet (audio import), Gorilla\n  (fitness), and the Apis dispatch core.\n- **Session-integrity hooks** — `.claude/hooks/` mechanically check plan binding and turn storage at Stop\n  (WARN by default, BLOCK behind a flag).\n- **Operational tooling** — 8 linters, git hooks, three GitHub Actions (secret/PII scan, Loxia PR review,\n  Lanius stale-issue sweep), and a SOPS+age cloud-deploy path.\n\n**What is in flight (skeletons, flags, or phasing-in):**\n\n- Full workflow-gate orchestration in Anthus; LLM-based email triage in Turdus; recurrence logic in Sylvia;\n  several Apis run-thread features behind feature flags; the Cyphorhinus → Riparia transport migration.\n- **18 of 35** agent definitions are marked `planned`/`proposed`; the active set is the daily-use core.\n\n**What is not guaranteed yet:**\n\n- A stable `workflow_definition` schema across versions.\n- Consolidated schemas (feedback / UI / release types still overlap).\n- Backward compatibility — corrections may invalidate prior gate outputs.\n- A packaged install path (adopt-by-forking only).\n\nSee [docs/swarm_smoke_test_plan.md](docs/swarm_smoke_test_plan.md) for the phased rollout cadence.\n\n## Security defaults\n\nAteles is single-operator infrastructure. Defaults assume the operator owns the machine, the keypairs, and\nthe Neotoma instance.\n\n- **Authentication:** AAuth keypairs per agent, signed requests verified against published JWKS. An operator\n  token is the documented fallback for daemons without their own minted key.\n- **Authorization:** `agent_grant` entities pre-check every tool call at the MCP grant proxy. Wrong-capability\n  returns a structured error before any side effect.\n- **Sensitive material:** GitHub PATs live in `.env` only, loaded per-repo by the harness PAT loader. Agents\n  never see PATs. Operator secrets ride a SOPS+age snapshot decrypted offline (never committed to this\n  public repo).\n- **Audit:** Every harness/proxy call writes an observation. Replay over any time window.\n- **Public-repo hygiene:** A structural PII gitleaks config + a `check_hardcoded_config` linter keep prompts\n  PII-free and operator config env/Neotoma-sourced, so any operator can fork.\n- **Tunnel:** The Apus webhook receiver listens on `localhost:8741` only; a Cloudflare tunnel surfaces it to\n  Neotoma's prod webhook deliveries.\n\nSee [docs/secrets_management.md](docs/secrets_management.md) and [docs/aauth.md](docs/aauth.md).\n\n## Development\n\nDaemons run from disk under launchd (or Docker); the IDE reads SKILL.md mirrors from disk. Both are runtime\nconveniences. The only artifact that defines swarm behaviour is an entity in Neotoma.\n\n**Daemon iteration:**\n\n```bash\n# venv at .venv/ with httpx, apprise, cryptography, PyJWT, etc.\n.venv/bin/python3 execution/daemons/anthus/anthus.py    # foreground test\nlaunchctl unload ~/Library/LaunchAgents/com.ateles.anthus.plist\nlaunchctl load   ~/Library/LaunchAgents/com.ateles.anthus.plist\ntail -f /tmp/com.ateles.anthus.err.log\n```\n\n**Updating an agent's prompt (the canonical path):**\n\n```bash\n# Never edit .claude/skills/\u003cagent\u003e/SKILL.md directly — Apus reverts on the next mirror.\nneotoma correct --entity-id ent_… --field prompt_markdown --value \"$(cat new_prompt.md)\"\n# The Apus webhook fires; SKILL.md regenerates from the canonical entity.\n```\n\n**Updating an agent's capability scope:**\n\n```bash\n# agent_grant is also an entity. Add a repo to an agent's harness:write scope:\nneotoma correct --entity-id \u003cgrant-id\u003e --field repos --append neotoma-docs\n# The next harness call sees the new scope on the next pre-check; no daemon restart.\n```\n\n**Running the linters:**\n\n```bash\nscripts/lint.sh            # ruff, yamllint, shellcheck + 6 custom linters\n```\n\n**Prerequisites:** Python 3.13+ (`.venv/`), Node v22+ via NVM (for the `claude` CLI), Neotoma running on its\nprod URL, the `op` CLI for `.env` loading, and the `gh` and `gws` CLIs.\n\n## Using with AI tools\n\nAteles operates through the `claude` CLI and MCP servers. The MCP layer connects each agent to the Neotoma\nstate layer and the GitHub harness.\n\n| Tool | How Ateles uses it |\n| --- | --- |\n| **Claude Code** | Operator-driven sessions. Skills under `.claude/skills/` invoke agents by trigger word. |\n| **`claude --print`** | Headless agent dispatch (operator and coordinator). `--append-system-prompt` loads the agent's SKILL.md. |\n| **mcpsrv_neotoma** | Every agent reads/writes Neotoma state via this MCP. Schema-aware tool surface. |\n| **github_harness MCP** | AAuth-verified GitHub operations — issues, PRs, comments, branches, commits, reviews — all observation-logged. |\n| **typefully MCP** | Corvus's social-post scheduling surface. |\n| **parquet MCP** | Bulk-data query surface for finance, transcription, and messaging parquet stores. |\n\n**Agent dispatch contract:** Agents emit a single bracketed artifact-header line as their final response\n(`[\u003cagent\u003e] \u003cartifact_kind\u003e: \u003cbody\u003e` or `BLOCKED — \u003creason\u003e`). The coordinator parses this to mark workflow\ngates satisfied. Agents optionally append a second line, `[\u003cagent\u003e] strategy_drift_signal: \u003cobservation\u003e`,\nwhen their work surfaces evidence contradicting their current `agent_strategy`. See\n[docs/swarm_orchestration.md](docs/swarm_orchestration.md) for the full contract.\n\n## Common questions\n\n**Why a reference architecture instead of a packaged framework?**\nA single-operator agent swarm is too tightly coupled to the operator's tooling, repos, identities, and\ngrants to package generically. Ateles is the design and a working example — fork it, adapt the daemons to\nyour infrastructure, keep the contract (AAuth identity, observation recording, `workflow_definition`, mirror\npipeline).\n\n**How does this compare to LangGraph / CrewAI / AutoGen?**\nThose frameworks orchestrate multi-step LLM calls inside one process. Ateles orchestrates long-running\nbackground daemons that spawn `claude` subprocesses, each with its own AAuth identity, writing to a canonical\nstate store. Different problem — agent fleets across days, not chains across seconds.\n\n**Why launchd instead of Docker / k8s?**\nSingle operator, one machine. launchd is the lowest-overhead scheduler that survives reboots. The same\ndaemons also run under `docker-compose` on a cloud host; they don't care about the scheduler.\n\n**Is this production-ready?**\nThe substrate routes, scopes, gates, and executes low-blast tasks end-to-end unattended; high-blast actions\ncheckpoint for operator approval. A dozen-plus daemons run daily. Full autonomous gate orchestration is still\nin validation, and many T4 agents are still `planned`. See\n[docs/swarm_smoke_test_plan.md](docs/swarm_smoke_test_plan.md).\n\n**What if I want to add a new agent?**\nFile an `agent_definition` entity in Neotoma. Mint an AAuth keypair. File an `agent_grant` with the\ncapabilities it needs. Apus mirrors the SKILL.md to disk. The coordinator picks it up on the next workflow\nthat references its trigger. The whole loop is in [docs/swarm_orchestration.md](docs/swarm_orchestration.md).\n\n## Related posts\n\n- [Your agent fleet now signs its writes](https://markmhendrickson.com/posts/your-agent-fleet-now-signs-its-writes)\n- [Your agent's memory is a markdown file](https://markmhendrickson.com/posts/your-agents-memory-is-a-markdown-file)\n- [Building a truth layer for persistent agent memory](https://markmhendrickson.com/posts/truth-layer-agent-memory)\n- [Agent command centers need one source of truth](https://markmhendrickson.com/posts/agent-command-centers-source-of-truth)\n- [Six agentic trends I'm betting on](https://markmhendrickson.com/posts/six-agentic-trends-betting-on)\n\n## Documentation\n\nFull documentation lives in `docs/` — index at [docs/README.md](docs/README.md). Start here:\n\n**Orientation:** [Who it's for (ICP)](docs/icp.md) · [Architecture](docs/architecture.md) ·\n[Taxonomy](docs/taxonomy.md) · [Phases](docs/phases.md) ·\n[Neotoma vs. alternatives](docs/neotoma_vs_alternatives.md)\n\n**Operating:** [Swarm orchestration](docs/swarm_orchestration.md) ·\n[Agent execution runbook](docs/agent_execution_runbook.md) ·\n[Task execution loop](docs/task_execution_loop.md) · [Setup](docs/setup.md) ·\n[Smoke-test plan](docs/swarm_smoke_test_plan.md)\n\n**Reference:** [Data types](docs/data_types.md) · [AAuth](docs/aauth.md) ·\n[Secrets management](docs/secrets_management.md) · [PR review routing](docs/pr_review_routing.md) ·\n[Session integrity](docs/session_integrity.md)\n\n**Deploying \u0026 operating:** [Cloud hosting](docs/cloud_hosting.md) ·\n[Daemon RC autodeploy](docs/daemon_rc_autodeploy.md) · [Linting guide](docs/linting-guide.md) ·\n[Test setup](docs/test-setup-guide.md)\n\n**Planning:** [Documentation plan \u0026 reconciliation](docs/documentation_plan.md)\n\n## Contributing\n\nAteles is in active development by one operator. Issues and discussions welcome — open one at\n[github.com/markmhendrickson/ateles/issues](https://github.com/markmhendrickson/ateles/issues). Pull requests\nfor the reference architecture (daemon hardening, AAuth improvements, harness extensions) are reviewed. Pull\nrequests that bundle in operator-specific configuration are not — fork instead.\n\n**License:** [MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkmhendrickson%2Fateles","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarkmhendrickson%2Fateles","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkmhendrickson%2Fateles/lists"}