aws-emulator
AGENTS.md8.3k starsChanged 6 days agoCC0-1.0View on GitHub
Developer and agent guide for this EmulatorCore-generated emulator project for aws services. (The repository's README.md is the project's own, user-facing document; this file is the working guide for anyone — human or agent — editing the emulator.) This project uses the per-crate layout: every service is its own Cargo crate, so changing one service recompiles only that crate instead of the whole emulator. When .emulator/license-header exists, every new .rs file starts with its contents, copied exactly, followed by a blank…
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,439 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
The file
We split this AGENTS.md into the rules it gives an agent
3 rules. About 0 are common, 0 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 54
When .emulator/license-header exists, every new .rs file starts with its contents, copied exactly, followed by a blank line.
- Very specific: line 60
Leave every @auth/@optionalAuth trait in smithy-model/ as shipped, and never override auth_schemes() to return an empty list: an operation …
- Very specific: line 71
Create them with ctx.credential_store().create(&AWS_ACCESS_KEY) or &AWS_SESSION, return the id and secrets you get back, write none to a …
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Working in aws-emulator
Developer and agent guide for this EmulatorCore-generated emulator project for
aws services. (The repository's README.md is the project's own,
user-facing document; this file is the working guide for anyone — human or agent
— editing the emulator.)
Specification
- Type: Smithy
- SDK: aws
- Emulator Core: v0.1.0
- Layout: per-service crate (multi-service)
Project Structure
This project uses the per-crate layout: every service is its own Cargo crate, so changing one service recompiles only that crate instead of the whole emulator.
aws-emulator/
├── Cargo.toml # workspace: one member per service, plus router
├── services/service-<name>/ # ONE CRATE PER SERVICE — this is where you work
│ ├── Cargo.toml
│ ├── build.rs # calls emulator_core_build_support::generate(...)
│ ├── smithy-model/ # <name>.json — the Smithy model (drives the wire protocol)
│ └── src/
│ ├── lib.rs # #[smithy_service] decl (generated by build.rs)
│ ├── service.rs # impl Service — can_handle + routing/refusal overrides (yours to edit)
│ ├── state.rs # this service's in-memory state struct
│ ├── scaffolded.rs # the 501 channel, and `validation` to refuse a bad request
│ └── ops/ # ONE FILE PER OPERATION — add handlers here
├── core/router/ # binary: assembles every service into one emulator
│ ├── src/lib.rs # build_router: register_connector + ops::register_all per
│ │ # service. RE-RENDERED on every service add — do not edit
│ └── src/main.rs # the boot path; emitted once — do not edit
├── vendor/ # vendored, agent-immutable framework (path deps)
│ ├── engine/ # the SINGLE shared InMemoryEngine (do not fork)
│ └── build-support/ # shared build.rs codegen
└── issues/ # issue trackingWhich files do I edit?
| Want to... | Edit |
| Implement an operation | services/service-<name>/src/ops/<operation>.rs |
| Change which requests a service claims, or override its routing or refusal wording | services/service-<name>/src/service.rs |
| Add state for a service | services/service-<name>/src/state.rs |
| Add a service-level test | services/service-<name>/tests/all/<name>.rs, declared in that crate's tests/all.rs |
| Add a cross-service test | core/router/tests/all/<name>.rs, declared in core/router/tests/all.rs |
| Add a dependency | services/service-<name>/Cargo.toml (the root Cargo.toml is not editable) |
When .emulator/license-header exists, every new .rs file starts with its
contents, copied exactly, followed by a blank line.
An operation that executes user code or serves a native data-plane protocol follows
the contract in the module docs of vendor/engine/src/lib.rs.
Leave every @auth/@optionalAuth trait in smithy-model/ as shipped, and never override
auth_schemes() to return an empty list: an operation is unsigned only when the model makes it
so.
There are two kinds of credentials:
- The emulator's own (root) credentials,
ctx.callback().credentials()andctx.callback().aws_credentials_provider(), only sign this operation's in-process calls to other services. Never put them in a response or a log: anyone holding them can sign any request. They are not in the credential store. - Created credentials are what an operation returns to its caller (an access key, a session).
Create them with
ctx.credential_store().create(&AWS_ACCESS_KEY)or&AWS_SESSION, return the id and secrets you get back, write none to a file or log, and delete them withdelete(id); never construct an id or a secret yourself.
A URL an operation returns for the caller to fetch later must lead back to this emulator:
- A presigned URL (a download or upload location, a callback URL): sign it with
ctx.url_signer().sign(SignedUrlRequest::new(method, signing_name, path), expires_in), withpathdecoded as the model lays it out, and returnurl.as_str(). Returnexpires_at()andrequired_headers()as well when the output has members for them. Code without a context (state, a background task) is handed a clone ofctx.url_signer(). Never writeX-Amz-Signatureyourself or presign with an AWS SDK: that URL reaches the real service or fails verification. - An unsigned address (a queue URL, a resource endpoint):
ctx.endpoint()followed by the resource's path. Never build it from<service>.<region>.amazonaws.com.
The emulator verifies every request signature: a service never checks signatures itself.
Quick Start
Build
cargo build # whole workspace
cargo build -p service-<name> # ONE service (this is the fast path)Run the emulator
cargo run -p aws-emulator-routerThe router binds the emulator API and its GET /__admin/health readiness
endpoint on :9297 (self-signed HTTPS). Override with EMULATOR_DATA_PORT or -p.
Test one service in-process (no socket)
fn build_service() -> service_<name>::EmulatedService<engine::InMemoryEngine> {
let engine = std::sync::Arc::new(engine::InMemoryEngine::new());
service_<name>::EmulatedService::new(engine)
}EmulatedService::new(engine) constructs each operation from the single shared
engine (the engine-as-constructor seam); there is no builder and no per-operation
registration step. Each operation reaches the shared store through self.engine.
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.

