{"id":51298846,"url":"https://github.com/pulseengine/agora","last_synced_at":"2026-06-30T17:02:34.638Z","repository":{"id":367062422,"uuid":"1278426749","full_name":"pulseengine/agora","owner":"pulseengine","description":"Real-time agent-coordination substrate — named agents coordinate on channels, every message a typed/signed/traceable fact. Augments the issue loop. WCM + NATS.","archived":false,"fork":false,"pushed_at":"2026-06-24T10:55:52.000Z","size":291,"stargazers_count":0,"open_issues_count":10,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-24T12:22:38.719Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/pulseengine.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-06-23T19:26:39.000Z","updated_at":"2026-06-23T19:29:31.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pulseengine/agora","commit_stats":null,"previous_names":["pulseengine/agora"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/pulseengine/agora","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulseengine%2Fagora","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulseengine%2Fagora/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulseengine%2Fagora/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulseengine%2Fagora/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pulseengine","download_url":"https://codeload.github.com/pulseengine/agora/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pulseengine%2Fagora/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34975672,"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-30T02:00:05.919Z","response_time":92,"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":[],"created_at":"2026-06-30T17:02:34.018Z","updated_at":"2026-06-30T17:02:34.632Z","avatar_url":"https://github.com/pulseengine.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# agora\n\nReal-time agent-coordination substrate for PulseEngine — named agents subscribe to\nchannels and coordinate/agree, with every message a typed, signed, traceable fact.\n**Augments** (does not replace) the GitHub-issue coordination loop.\n\n\u003e Status: **spike**. This proves the architecture + the cross-talk controls run on\n\u003e the lighter (NATS-core + wasmtime + WAC) path, with NATS and sigil stubbed at\n\u003e their seams. It is the input to the lighter-vs-wasmCloud decision.\n\n## Architecture (five layers)\n\n| Layer | What | Built with |\n|---|---|---|\n| Named agents | each agent = a capability-isolated wasm component | wasm component, A2A-style identity |\n| Coordination logic | type / sign / shape / decide | wasm components, WAC-composed |\n| Protocol contract | channel · message · speech-acts | a WIT world (`agora:agent`) |\n| Durable spine *(native TCB)* | named channels, durable fan-out, replay | **NATS/JetStream** (self-hosted) |\n| Record | every message → signed fact | **rivet** + **sigil** (Rekor-style) |\n| Human window | watch live + inject + **out-of-band kill** | **thrum** |\n\nThe durable transport is deliberately **native** (NATS), not wasm: `wasi:messaging`\ndisclaims persistence/ack/delivery, so reimplementing it in wasm is gold-plating.\n\"WCM to the extreme\" is spent where it pays off — the **logic**, **capability\nisolation**, and **verification** (witness/scry/sigil) — not the transport.\n\n## What the spike demonstrates (runnable)\n\n`agent/` is a real wasm **component** (pure coordination logic, no ambient\nauthority). `host/` is the transport + capability layer (where NATS and sigil swap\nin) that runs it on wasmtime and enforces the cross-talk controls the research\nvalidated against the **Hermes infinite-ack-loop postmortem**\n(`NousResearch/hermes-agent#32791`):\n\n- **capability channel-scoping** (structural) — agents hold no handle to\n  `secret-ops`, so it is *never delivered* to them. 8 deliveries blocked.\n- **unconditional self-echo filter** (Hermes rule #1) — `sender == me` dropped on\n  every channel, never per-channel overridable. 12 echoes dropped.\n- **hop-count / TTL** — the deliberately chatty agent *would* loop forever (the\n  Hermes failure); the hop budget bounds it (3→2→1→0) and it converges.\n- **idempotency** — each (agent, message-id) processed once.\n- **signed identity + speech acts + rivet record** — every message carries a\n  (stubbed) sigil signature, a FIPA-style `act`, and is mirrored to\n  `facts/coordination.yaml` as a typed rivet fact.\n\n```sh\n# Canonical: hermetic component build via the PulseEngine ruleset (Bazel) —\n# native wasm32-wasip2 through wasi-sdk 29 (= WASI 0.2.6).\nbazel build //agent:agent\n\n# Quick path (same native-p2 component, no preview1 adapter):\ncd agent \u0026\u0026 cargo component build --release --target wasm32-wasip2\n\n# Run the host (loads the p2 component, enforces the cross-talk controls):\ncd host \u0026\u0026 cargo run --release   # `cargo test` asserts the controls (8/12/converge/6)\n```\n\n## Stubbed seams (the swap-in points)\n\n- **NATS/JetStream** — the host's in-memory `bus` Vec stands in for the durable\n  log. Real JetStream gives the global sequence (ordering), durable consumers\n  (= the watermark/pending_gates replay), and `Nats-Msg-Id` dedup.\n- **sigil** — `sig` is an FNV stub; real `wsc sign --keyless` swaps in (blocked on\n  `pulseengine/sigil#164`, the wasip2 parser).\n- **rivet** — facts are written as YAML; real `rivet` (0.17 present) ingests them.\n- **out-of-band human kill** — Hermes rule #2: thrum must hold a privileged kill at\n  the gateway, not an in-channel \"stop\". Not in this spike.\n\n## Lighter-vs-wasmCloud — what the spike surfaced\n\nThe lighter path **works and is fully functional**. Friction encountered (the real\ndecision input):\n\n- `cargo component` still defaults its *core* target to the legacy `wasm32-wasip1`\n  (preview1 + adapter), and honors neither `.cargo/config.toml` `build.target` nor a\n  metadata key — so the build pins `--target wasm32-wasip2` explicitly. That yields a\n  native component-model component (imports `wasi:io`/`wasi:cli@0.2.x`, no preview1\n  adapter); the host's `wasmtime_wasi::p2` linker satisfies it.\n- `from` is a reserved WIT keyword (→ `sender`).\n- `std` pulls WASI imports, so the host needs a `wasmtime-wasi` linker + the\n  version-specific `WasiView`/`WasiCtxView` boilerplate (had to read the crate\n  source to get the 41.x API right). **This host-embedding plumbing is exactly what\n  wasmCloud would absorb** — at the cost of running wasmCloud as a system and its\n  transport providers being native anyway.\n\nRead: for a small team building one substrate, the lighter path is viable; the\nfriction is one-time host plumbing. wasmCloud is the graduation path if the lattice\nfeatures (wadm, multi-host, provider ecosystem) start paying for themselves.\n\n## WASI: on p2 now, p3 is the direction\n\n**WASI 0.3.0 (Preview 3) was ratified 2026-06-11** — it rebases WASI onto the\nComponent Model's *native async* primitives (`async func`, `stream\u003cT\u003e`, `future\u003cT\u003e`).\nThis spike deliberately builds on stable **wasm32-wasip2** today, not preview1 and not\np3, because:\n\n- The agent is **pure coordination logic** — its only WASI surface is what `std`\n  pulls in; it gains nothing concrete from p3's async streams.\n- The Rust **`wasm32-wasip3` target is still tier-3** (\"does not yet build\" without a\n  `libc` `[patch]`; needs nightly + `-Z build-std` + `wasi-sdk ≥22`), and its `std`\n  **still emits p2 imports** during the transition — so a p3 build today would add\n  major toolchain friction (contradicting the lighter-path thesis above) for p2\n  imports anyway.\n- p3 host support lands in **wasmtime 43+**; this host is on 41.\n\n**Where p3 actually pays off for agora — and the adoption path when we take it:**\n\n1. **The transport seam (the real win).** p3's `stream\u003cT\u003e`/`future\u003cT\u003e` map cleanly\n   onto JetStream consumers — backpressure, ordering, and async delivery become\n   first-class in the WIT contract instead of host plumbing. This is the layer that's\n   stubbed today (the in-mem `bus`), so it's the right place to adopt p3.\n2. **Host:** bump `wasmtime`/`wasmtime-wasi` 41 → 43+ and switch\n   `wasmtime_wasi::p2::add_to_linker_sync` → `p3::add_to_linker_async` (async linker,\n   async `call_coordinate`).\n3. **Agent:** move to `wasm32-wasip3` once it reaches tier-2 and `std` migrates off p2\n   imports — then the gap closes with no `build-std`/wasi-sdk friction.\n\nSee: [wasi.dev/roadmap](https://wasi.dev/roadmap),\n[rustc — wasm32-wasip3](https://doc.rust-lang.org/beta/rustc/platform-support/wasm32-wasip3.html),\n[Async Components on wasmCloud with WASI P3](https://wasmcloud.com/blog/wasi-p3-on-wasmcloud/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpulseengine%2Fagora","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpulseengine%2Fagora","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpulseengine%2Fagora/lists"}