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
In this repository21 other files it gives its agents.
- adr-governanceSkill
- credential-operationsSkill
- documentation-experienceSkill
- engineering-loopSkill
- governance-doctorSkill
- homebrew-tap-mergeSkill
- jira-deliverySkill
- product-validationSkill
- public-release-reconcileSkill
- release-assuranceSkill
- release-docs-syncSkill
- release-evidence-finalizeSkill
- release-qa-gateSkill
- release-security-gateSkill
- release-tag-cutSkill
- release-validate-channelsSkill
- repo-bootstrapSkill
- repo-scaffoldSkill
- rust-developmentSkill
- shell-developmentSkill
- terraform-developmentSkill
The file
Files
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:
- SDK layer (in-process) — language SDKs call a thin Rust shim (
aa-ffi-*in the SDK repos) overaa-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-clientis not an enforcement point here, and denied before execution depends on the out-of-repo shim honouring the answer. Advisory only — see ADR 0002. - 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 honourHTTP_PROXY/HTTPS_PROXYand trust the CA (on macOS attempted at proxy start viasecurity add-trusted-certunlessAA_PROXY_SYSTEM_TRUST_INSTALL=never(AAASM-5978 — set for a managed launch with process-scoped trust, e.g. Claude Code'sNODE_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 Linuxsudo aasm proxy install-ca,aa-cli/src/commands/proxy/ca.rs:150-188; Windows unsupported). HTTP/1.1 only on MitM'd hosts, andllm_onlydefaults totrue, so only the built-in LLM hosts are decrypted. - 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 nocfg(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.mdfor the evidence anddocs/src/devtools/limitations.mdfor 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/)
| Crate | Role |
aa-core | Wire types (aa_core::types), storage traits (aa_core::storage), conformance harnesses |
aa-proto | Protobuf/tonic definitions (committed generated code) |
aa-gateway / aa-api | Gateway brain + HTTP/OpenAPI surface |
aa-runtime | Authoritative chokepoint: policy gate (handle_policy_query) + scan/redact stage (RuntimeScanner) |
aa-sdk-client | FFI-agnostic client the SDK shims pin by git SHA |
aa-security | Credential scanner + redaction (leaf crate) |
aa-proxy / aa-ebpf* / aa-sandbox | Interception mechanisms: transport mediation, Linux host-level, WASM tool sandbox |
aa-cache / aa-storage* | L1 cache + storage drivers |
aa-cli | aasm 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.jsonallow-list). - eBPF crates (
aa-ebpf*) use target-specific toolchains;cargo check -p aa-ebpfsuffices on non-Linux. aa-clismoke-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 alwaysmain; body follows the repo PR template; ≥1 Pioneer-team approval.
Repo-specific gotchas
- Push remote is
remote(→ai-agent-assembly/agent-assembly, canonical), notorigin(a personal fork). Scope changes againstremote/main, which is often far ahead of a fork checkout. - Pre-push
cargo docis filtered to Rust-affecting diffs (AAASM-5695): thepre-push.commands.docentry inlefthook.tomlcarries afilescommand (git diff --name-only --merge-base @{u} HEAD, falling back throughremote/mainthenorigin/mainmerge-bases before the full tree — AAASM-5838, so a worktree branch's first push before@{u}resolves still scopes correctly) plusglob = ["*.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 notHEAD(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 thelefthook.tomlcomment 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_DIRconvention, duplicating CI's own requiredclippyjob synchronously on every commit). Runscripts/clippy-changed-crates.shexplicitly 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.ymlhas a two-layer model — workflowon.paths(whether CI runs) + adorny/paths-filterchangesrouter (which jobs). Every router area filter needs a matchingon.*.pathsentry 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 nativecomponentsfield, notcustomfield_10041(which is null; per the.githubregistryjirasection / Core ADR 0014); Team (customfield_10001) = Pioneer. For feature work: Epic → Story → Subtask (one Subtask ≈ one commit) + aVerify …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-specrepo (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 (
///onpubfn/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 insiderun()so both paths share it", "fail-closed on oversized input"). - Inline
//why-comments: for workarounds, perf-sensitive code, security rationale, and version pins (theCargo.tomlpin 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/anddesign/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.
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
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.

