agentleFS
ai-agent-assemblyai-agent-assembly/agent-assembly/.claude/CLAUDE.md

agent-assembly

CLAUDE.md4 starsChanged 3 months agoApache-2.0View on GitHub

Guidance for Claude Code (and humans) working in this repository. This file holds repo-specific context only; general engineering policy lives in the global config. When a fact here duplicates CONTRIBUTING.md, the Makefile, or Cargo.toml, treat those as the source of truth and update them, not just this file. The core Rust monorepo for AI Agent Assembly — the product that evaluates what an AI agent does against policy and records the outcome. It contains the gateway ("the brain"), the policy…

  • Commits and pushes

The file

Files
CLAUDE.md

CLAUDE.md — agent-assembly

Guidance for Claude Code (and humans) working in this repository. This file holds repo-specific context only; general engineering policy lives in the global config. When a fact here duplicates CONTRIBUTING.md, the Makefile, or Cargo.toml, treat those as the source of truth and update them, not just this file.

What this repo is

The core Rust monorepo for AI Agent Assembly — the product that evaluates what an AI agent does against policy and records the outcome. It contains the gateway ("the brain"), the policy engine, the interception mechanisms, the FFI shims the language SDKs bind to, and the operator CLI. The language SDKs (python-sdk, node-sdk, go-sdk) and the cloud control plane live in separate repos; this one is the source of truth for the protocol, policy semantics, and the shared aa-* crates they pin.

Architecture: the interception mechanisms

Governance is assembled from independently-deployable mechanisms, and a deployment runs whichever subset it installs. They are not a fallback chain and not a ranking: each reaches a different ADR 0033 §6 claim level, and an absent one is reported as absent rather than picked up by the next. Listed lowest-latency first:

  1. SDK layer (in-process) — language SDKs call a thin Rust shim (aa-ffi-* in the SDK repos) over aa-sdk-client, which emits events and asks the runtime for a decision on a wrapped framework tool call. Fastest path; requires SDK adoption and an explicit initializer call and a reachable runtime. In this repo it reaches Evaluated (advisory) — aa-sdk-client is not an enforcement point here, and denied before execution depends on the out-of-repo shim honouring the answer. Advisory only — see ADR 0002.
  2. Sidecar proxy (aa-proxy) — MitM of outbound HTTPS using per-host certificates minted from a local root CA; refuses or redacts a request before it leaves the machine, without changing the agent's own code. Requires the process to honour HTTP_PROXY/HTTPS_PROXY and trust the CA (on macOS attempted at proxy start via security add-trusted-cert unless AA_PROXY_SYSTEM_TRUST_INSTALL=never (AAASM-5978 — set for a managed launch with process-scoped trust, e.g. Claude Code's NODE_EXTRA_CA_CERTS); on the unopted-out path it needs admin authorization — a refused prompt fails proxy startup, aa-proxy/src/lib.rs:80-91 + tls/keychain.rs:16; on Linux sudo aasm proxy install-ca, aa-cli/src/commands/proxy/ca.rs:150-188; Windows unsupported). HTTP/1.1 only on MitM'd hosts, and llm_only defaults to true, so only the built-in LLM hosts are decrypted.
  3. eBPF (aa-ebpf*) — kernel uprobes on OpenSSL + exec/file syscall hooks. Observe-only: the probes emit telemetry and return no verdict, so this layer detects, it does not block. Linux only; there is no cfg(target_arch) gate — TLS uprobes and exec tracepoints work on x86_64 and aarch64, but the file-I/O kprobes are x86_64-only (hardcoded __x64_sys_*). It fails open if it cannot attach. It is one possible host mechanism, not a general enforcement layer.
<!-- truth-exempt: negative-example - the AAASM-5528 wording, quoted to show what is prohibited -->

Do not restate these as absolutes. Public copy derived from this file was the source of the AAASM-5528 truthfulness bug ("catches everything, including bypass attempts"). Every claim above must name its boundary; see verification-reports/AAASM-5528-public-claim-inventory.md for the evidence and docs/src/devtools/limitations.md for the measured limits.

<!-- /truth-exempt -->

The gateway (aa-gateway) is the brain: agent registry, policy engine (src/policy/), per-team budgets (src/budget/), gRPC for SDKs + HTTP/OpenAPI (via aa-api) for the dashboard. The runtime (aa-runtime) is the authoritative chokepoint, but split the two things it does: the allow/deny/pending gate is handle_policy_query (aa-runtime/src/pipeline/mod.rs:407), while RuntimeScanner (aa-runtime/src/pipeline/enforcement.rs:182) is the scan/redact/normalize stage — authoritative versus the untrusted SDK's own scan, not the policy gate. The CLI (aa-cli) ships the aasm binary (aasm topology / policy / dashboard).

Crate map (flat at repo root, not under crates/)

CrateRole
aa-coreWire types (aa_core::types), storage traits (aa_core::storage), conformance harnesses
aa-protoProtobuf/tonic definitions (committed generated code)
aa-gateway / aa-apiGateway brain + HTTP/OpenAPI surface
aa-runtimeAuthoritative chokepoint: policy gate (handle_policy_query) + scan/redact stage (RuntimeScanner)
aa-sdk-clientFFI-agnostic client the SDK shims pin by git SHA
aa-securityCredential scanner + redaction (leaf crate)
aa-proxy / aa-ebpf* / aa-sandboxInterception mechanisms: transport mediation, Linux host-level, WASM tool sandbox
aa-cache / aa-storage*L1 cache + storage drivers
aa-cliaasm operator binary
aa-devtool*Per-tool governance adapters (claude-code, codex, copilot, windsurf, saas)
dashboard/React/Vite operator UI (token-driven theming)

Build, test, lint

See CONTRIBUTING.md and the Makefile for the full list. For the fast-edit vs. targeted-test vs. multi-agent/worktree vs. full-QA distinction, sccache guidance, and the target-dir lifecycle tool (scripts/rust-target-lifecycle.sh), see docs/bench-5992/rust-dev-performance-policy.md (AAASM-5991) — read it before running an unscoped cargo nextest run --workspace/-p <pkg> or assuming disk pressure needs a manual cargo clean. Common commands:

lefthook install                       # one-time: fmt/deny on commit, doc on push
scripts/clippy-changed-crates.sh       # scoped clippy for your diff — run before opening a PR (AAASM-5838)
cargo build --workspace
cargo nextest run --workspace          # full suite
cargo nextest run -p aa-core           # one crate
cargo nextest run -p aa-gateway budget::types::tests::provider_variants_are_distinct  # one test
cargo fmt --all
cargo clippy --all-targets -- -D warnings
cargo deny check
cargo doc --workspace --no-deps        # checked on push by hooks, Rust-affecting diffs only
  • Some setups need RUSTUP_TOOLCHAIN=stable + an explicit toolchain path (normal on this machine; see .claude/settings.local.json allow-list).
  • eBPF crates (aa-ebpf*) use target-specific toolchains; cargo check -p aa-ebpf suffices on non-Linux.
  • aa-cli smoke-test: ./target/debug/aasm <subcommand>.

Conventions (see CONTRIBUTING.md — don't duplicate)

  • Commits: <emoji> (<scope>): <imperative summary> (gitmoji.dev). One logical unit per commit; bisectable. Utils/mocks/tests are separate preceding commits.
  • Branch: <release-or-phase>/<ticket>/<type>/<short_summary> (<type> = feat/fix/refactor/test/docs/config/deps/remove/lint; e.g. v0.0.1/AAASM-42/feat/add_agent_registry).
  • PR title: [<ticket>] <emoji> (<scope>): <summary>; base branch always main; body follows the repo PR template; ≥1 Pioneer-team approval.

Repo-specific gotchas

  • Push remote is remote (→ ai-agent-assembly/agent-assembly, canonical), not origin (a personal fork). Scope changes against remote/main, which is often far ahead of a fork checkout.
  • Pre-push cargo doc is filtered to Rust-affecting diffs (AAASM-5695): the pre-push.commands.doc entry in lefthook.toml carries a files command (git diff --name-only --merge-base @{u} HEAD, falling back through remote/main then origin/main merge-bases before the full tree — AAASM-5838, so a worktree branch's first push before @{u} resolves still scopes correctly) plus glob = ["*.rs", "*Cargo.toml", "*Cargo.lock"], so a Markdown/.claude-only push skips the build in seconds instead of costing the 3046 s (50m46s) full-workspace rustdoc build it used to. Two gaps are tracked, not covered: pushing a ref that is not HEAD (git push remote <branch> from elsewhere, git push --all) computes an empty file set and skips (AAASM-5726), and .proto-only or deletion-only diffs skip here with no workspace rustdoc gate anywhere in CI. The measurements behind both live in the lefthook.toml comment block — read it before changing that command. Never --no-verify; never force-push; don't route commits around the hook by other means either.
  • Pre-commit no longer runs a full-workspace cargo clippy (AAASM-5838 — it routinely blocked a single-crate commit 50+ minutes on this repo's shared-CARGO_TARGET_DIR convention, duplicating CI's own required clippy job synchronously on every commit). Run scripts/clippy-changed-crates.sh explicitly before opening a PR for a fast, scoped local check; CI remains the authoritative full-workspace gate.
  • Org GitHub Actions is billing-blocked on private repos and intermittently org-wide — jobs abort in ~2–11s with a payments message. Check run annotations before triaging as a code bug; validate locally instead of waiting on CI.
  • CI router: ci.yml has a two-layer model — workflow on.paths (whether CI runs) + a dorny/paths-filter changes router (which jobs). Every router area filter needs a matching on.*.paths entry or it's a dead trigger.

Project policy

  • JIRA: project AAASM; set the native Components field to the repo (ai-agent-assembly/agent-assembly) — it is the native components field, not customfield_10041 (which is null; per the .github registry jira section / Core ADR 0014); Team (customfield_10001) = Pioneer. For feature work: Epic → Story → Subtask (one Subtask ≈ one commit) + a Verify … subtask per Story. For a dedicated QA / verification Epic (e.g. AAASM-4522 user-smoke, AAASM-5020 design-QA): one verification item = one Story directly under the Epic (the [Journey NN] style) — no middle "checklist" Task, no Subtasks. Each such Story is verified by operating the live product as a real user (real running server, live API, real browser through the real login flow); CI / unit tests / mocked e2e (page.route, injected tokens) never substitute for real-user verification, even when they already cover the case. File a Bug only after reproducing through the genuine end-to-end path.
  • Self-hosted deployment is out of scope product-wide — don't propose Helm/Terraform/air-gapped/migration work even if the spec mentions it.
  • The Protocol Specification stays in this monorepo — do not move spec work to a separate agent-assembly-spec repo (that repo is archived by design).

Documentation conventions — document the WHY, not the WHAT

Comments and docstrings exist to capture intent that the code cannot: rationale, constraints, invariants, and non-obvious decisions. Restating what the code already says is noise that rots out of sync — avoid it.

  • Crate / module (//!): yes — its role in the architecture, key invariants, and which ADR 0033 element it implements. Do not write the superseded three-layer model into a new //!; forbidden design 1 names code comments explicitly.
  • Public items (/// on pub fn/struct/trait): yes — the contract: behavior, errors returned, units, side effects, and any threading/async/unsafe/ordering constraints. Especially the surprising ones (e.g. "built inside run() so both paths share it", "fail-closed on oversized input").
  • Inline // why-comments: for workarounds, perf-sensitive code, security rationale, and version pins (the Cargo.toml pin comments are the gold standard — e.g. why a crate is pinned, not just that it is).
  • Skip: private trivial helpers, getters, type-restating, and anything a reader infers from the signature. No per-variable docstrings.
  • Big architectural decisions → ADRs, not scattered docstrings. Link code to the ADR. Design specs already live in .ai/spec/ and design/vN/ — reference them.

Net: a new contributor (human or LLM) should be able to read a module's //! and a public item's /// and understand why it is the way it is without reverse- engineering it. If a comment only says what, delete it.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.