Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ buzz-core (zero I/O — types, verification, filter matching, kind registry)
└── buzz-relay (ties everything together — the server)

buzz-ifc (zero I/O — execution-domain derivation and IFC rules)
└── buzz-acp (relay/ACP adapter and worker routing)
├── buzz-acp (relay/ACP adapter and worker routing)
└── buzz-ifc-broker (stateful JSON-RPC policy process for non-Rust harnesses)
buzz-sdk (typed Nostr event builders — used by buzz-acp and buzz-cli)
buzz-media (Blossom/S3 media storage)
buzz-cli (agent-first CLI)
Expand Down Expand Up @@ -677,11 +678,11 @@ Buzz Relay ──WS──→ buzz-acp ──stdio (ACP/JSON-RPC)──→ Agent

---

### buzz-ifc — Shared Agent Policy
### buzz-ifc and buzz-ifc-broker — Shared Agent Policy

`buzz-ifc` is a zero-I/O policy crate. Given facts already verified by a trusted Buzz adapter, it derives the invocation's audience, retained-state context, membership epoch, and effective capabilities. It also evaluates reads, calls, publications, and process reuse while retaining a conservative label for each process.

`buzz-acp` links the crate directly. The surrounding adapter remains responsible for signed-event and membership verification, process lifecycle, credential mediation, and OS or VM confinement for confidential domains.
`buzz-acp` links the crate directly. Other harnesses can run `buzz-ifc-broker` and use its bounded JSON-RPC protocol over stdio. Despite the executable name, this is the policy process inside a larger trusted agent gateway, not the complete product broker. It retains policy state for workers on that connection. The surrounding adapter remains responsible for signed-event and membership verification, process lifecycle, credential mediation, and OS or VM confinement for confidential domains.

---

Expand Down
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ members = [
"crates/buzz-audit",
"crates/buzz-acp",
"crates/buzz-ifc",
"crates/buzz-ifc-broker",
"crates/buzz-agent",
"crates/sprig",
"crates/buzz-test-client",
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ A Rust workspace of focused crates. Single source of truth: the relay. See [ARCH

**Services** — `buzz-db` (Postgres) · `buzz-auth` (NIP-42/98 Schnorr auth, rate limiting) · `buzz-pubsub` (Redis, presence, typing) · `buzz-search` (Postgres FTS) · `buzz-audit` (hash-chain log). Multi-community mode scopes tenant-observable rows, cache keys, search documents, workflow state, media metadata, git repo pointers, and audit chains by the host-derived community; shared infrastructure is an implementation detail, not a user-visible global workspace.

**Agent surface** — `buzz-cli` (agent-first CLI, JSON in / JSON out) · `buzz-acp` (ACP harness for Goose/Codex/Claude Code) · `buzz-agent` (ACP agent — see [VISION_AGENT.md](VISION_AGENT.md)) · `buzz-dev-mcp` (shell + file-edit tools) · `buzz-ifc` (shared audience-scoped agent policy) · `buzz-workflow` (YAML automation) · `buzz-persona` (agent persona packs)
**Agent surface** — `buzz-cli` (agent-first CLI, JSON in / JSON out) · `buzz-acp` (ACP harness for Goose/Codex/Claude Code) · `buzz-agent` (ACP agent — see [VISION_AGENT.md](VISION_AGENT.md)) · `buzz-dev-mcp` (shell + file-edit tools) · `buzz-ifc` / `buzz-ifc-broker` (shared audience-scoped agent policy) · `buzz-workflow` (YAML automation) · `buzz-persona` (agent persona packs)

**Git & pairing** — `git-sign-nostr` / `git-credential-nostr` (nostr-signed git) · `buzz-pair-relay` / `buzz-pairing-cli` (relay pairing)

Expand Down
4 changes: 3 additions & 1 deletion crates/buzz-acp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ state. Its logs report those remaining gaps explicitly.
The deterministic label, domain, capability, reuse, and confinement rules live
in the runtime-independent `buzz-ifc` crate. `buzz-acp` supplies the trusted
Buzz-specific half: signed-event admission, relay-signed membership resolution,
and ACP worker replacement.
and ACP worker replacement. A non-Rust harness can use the same rules through
the bounded JSON-RPC interface provided by `buzz-ifc-broker`; see that crate's
README and conformance fixture for the wire contract.

### Parallel Agents & Heartbeat

Expand Down
22 changes: 22 additions & 0 deletions crates/buzz-ifc-broker/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "buzz-ifc-broker"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
description = "Language-neutral policy broker for audience-scoped Buzz agents"

[dependencies]
anyhow = { workspace = true }
buzz-ifc = { workspace = true }
clap = { version = "4", features = ["derive", "env"] }
futures-util = { workspace = true }
hex = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true, features = ["io-std"] }
tokio-util = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
uuid = { workspace = true }
77 changes: 77 additions & 0 deletions crates/buzz-ifc-broker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# buzz-ifc-broker

`buzz-ifc-broker` exposes the shared `buzz-ifc` policy over bounded JSON-RPC
2.0 on stdin/stdout. It exists for trusted agent harnesses that cannot link the
Rust crate directly, such as a Go kgoose integration.

The broker owns process-level IFC state. The caller supplies facts only after
it has verified the triggering event and authoritative Buzz membership. The
caller does not choose an audience or context: `buzz-ifc` derives both from the
verified conversation kind, roster, requesters, executing agent, and owner.

The agent runtime must not receive raw Buzz credentials or another route around
the trusted adapter. Despite its executable name, this is the policy process
inside the agent gateway, not the complete product broker. It does not launch,
sandbox, or terminate workers and cannot force its caller to obey a decision.

Every derived domain includes a compartment profile:

- `shared_public` may reuse the realm's normal public worker and public state.
- `domain_confined` requires a worker, writable state, and output paths dedicated
to that exact restricted or owner-private domain.

The trusted adapter implements that placement. A local sandbox, container, or VM
supplies the final confinement boundary for `domain_confined` work.

Run in compatibility mode:

```bash
buzz-ifc-broker --mode audit
```

Run when the trusted adapter will treat denied decisions as blocking:

```bash
buzz-ifc-broker --mode enforce
```

Each request and response is one JSON line. Start by binding a concrete worker
to the domain derived from verified invocation facts:

```json
{"jsonrpc":"2.0","id":1,"method":"worker/enter","params":{"worker_id":"kgoose-session-42","invocation":{"realm_url":"wss://buzz.example","channel_id":"00000000-0000-0000-0000-000000000001","conversation_kind":"restricted","epoch":"membership:<signed-event-id>","members":["<agent-pubkey>","<alice-pubkey>","<bob-pubkey>"],"executing_agent":"<agent-pubkey>","requesters":["<alice-pubkey>"],"owner":"<alice-pubkey>","bot_capabilities":["buzz.read.current","buzz.publish.current","email.read"],"conversation_capabilities":["buzz.read.current","buzz.publish.current"]}}}
```

The result includes the opaque `domain_id`; `details.replace_worker` tells the
adapter when the named process already contains another domain. The adapter
must retire that process before delivering the new request.

Call `worker/observe` before labeled data enters the process and `worker/call`
before invoking a mediated operation. If audit mode proceeds after a denied
call, its result must still be reported with `worker/observe`. Before Buzz signs
or sends a response, call `worker/publish` with the exact content digest and the
actual destination. Without a verified declassification grant, output is bound
to the source context. The current protocol intentionally exposes no
declassification method.

Supported methods:

- `broker/info`
- `domain/derive`
- `worker/enter`
- `worker/observe`
- `worker/call`
- `worker/publish`
- `worker/retire`

Logs are written to stderr. Stdout contains protocol frames only.

The broker connection is part of the worker lifecycle. `worker/retire` removes
policy state only after the adapter has terminated the corresponding process.
If the broker exits or the connection is replaced, the adapter must terminate
all workers tracked by that broker. A fresh broker has no evidence that an
existing process is safe to reuse.

`tests/fixtures/domain-golden.json` is the language-neutral conformance vector.
Adapters should replay it in their own test suite rather than duplicating the
domain hashing algorithm.
Loading
Loading