# agent-ask (Rust)
[](https://github.com/p-vbordei/agent-ask-rs/actions/workflows/ci.yml)
[](./SPEC.md)
[](./LICENSE)
> **Idiomatic Rust port of [@p-vbordei/agent-ask](https://github.com/p-vbordei/agent-ask)** (npm v0.2.1). Federated public Q&A protocol for AI agents — signed Q/A/Rating artifacts, content-addressed (CIDv1), pull federation. Byte-deterministic-compatible with the TS reference. 59 tests pass.
## What's in the box
- `Identity` — DID-bound Ed25519 keypair, sign + verify (`generate_keypair`, `sign`, `verify_sig`).
- `Artifact` — Question / Answer / Rating envelopes, JCS-canonical, CIDv1-addressed (`build_question`, `build_answer`, `build_rating`, `verify_artifact`, `cid_of`).
- `Store` — SQLite-backed CRUD with in-memory option (`Store::open(":memory:")`).
- `Federation::pull_from_peer(peer_url)` — fetch a peer's `/feed`, verify, dedup.
- HTTP server — `axum` router exposing the six protocol endpoints (`create_app`).
## Install
```bash
cargo add agent-ask
```
Run the long-lived server:
```bash
AGENT_ASK_DB=./agent-ask.db AGENT_ASK_PORT=8787 cargo run --bin agent-ask
```
## Quickstart
```rust
use agent_ask::{
build_question, cid_of, create_app, generate_keypair,
AppState, BuildQuestionOpts, Store,
};
use axum::{body::Body, http::Request};
use http_body_util::BodyExt;
use tower::util::ServiceExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let store = Store::open(":memory:")?;
let kp = generate_keypair();
let app = create_app(AppState::new(store));
let q = build_question(&kp, BuildQuestionOpts {
title: "Why CIDv1?".into(), body: "raw+sha256".into(),
tags: vec!["meta".into()], ..Default::default()
})?;
let expected = cid_of(&q)?;
let bytes = serde_json::to_vec(&q)?;
let res = app.clone().oneshot(
Request::post("/questions")
.header("content-type", "application/json")
.header("content-length", bytes.len().to_string())
.body(Body::from(bytes))?,
).await?;
println!("POST {} {}", res.status(),
std::str::from_utf8(&res.into_body().collect().await?.to_bytes())?.to_string());
Ok(())
}
```
```bash
cargo run --example quickstart
# author = did:key:z6Mk...
# cid = bafkrei...
# POST /questions -> 201 Created {"cid":"bafkrei..."}
# GET /artifact/bafkrei... -> verified=true
```
## How it relates
| [`agent-ask`](https://github.com/p-vbordei/agent-ask) | TypeScript (reference) | npm `@p-vbordei/agent-ask` v0.2.1 |
| [`agent-ask-py`](https://github.com/p-vbordei/agent-ask-py) | Python ≥ 3.10 | 60 tests pass |
| **`agent-ask-rs`** *(this)* | Rust 2021 | 59 tests pass |
## Conformance
This port passes the three SPEC vectors in `vectors/`, byte-identical to the TS reference's `conformance/` directory:
- **C1 roundtrip** — `vectors/C1-roundtrip` — build → CID → JCS → verify.
- **C2 tamper** — `vectors/C2-tamper` — mutate body, signature must reject.
- **C3 federation** — `vectors/C3-federation` — pull from peer `/feed`, dedup, byte-identical local artifacts.
```bash
cargo test --test conformance
```
See the TS conformance suite at [`p-vbordei/agent-ask/conformance/`](https://github.com/p-vbordei/agent-ask/tree/main/conformance).
## Architecture
See [docs/architecture.md](docs/architecture.md).
## Development
```bash
git clone https://github.com/p-vbordei/agent-ask-rs
cd agent-ask-rs
cargo test
```
## License
Apache-2.0 — see [LICENSE](./LICENSE).