aws-durable-execution-sdk-rust
AGENTS.md14 starsChanged 7 days agoApache-2.0View on GitHub
This repository contains the AWS Durable Execution SDK for Rust, the aws-durable-execution-sdk crate, used to author AWS Lambda durable functions. Do not rely on this file for method signatures, builder options, or code examples. The API reference for this SDK is the README and the rustdoc comments in src/. To read the rustdoc in a browser, run cargo doc --no-deps --all-features --open. The AWS Durable Execution SDK Developer Guide explains the concepts that all the durable execution SDKs share. Its…
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,542 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
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
13 rules. About 0 are common, 4 are distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 9
Do not rely on this file for method signatures, builder options, or code examples.
- Very specific: line 70
Side effects outside steps repeat on every replay: Put side effects in steps.
- Very specific: line 81
Use the SDK's combinators, not
tokio::select!: Use ctx.race or ctx.select_ok over durable futures, so the SDK records which branch won. - Very specific: line 87
Do not rely on
Dropbetween operations: When an execution suspends, the SDK drops the handler future. - Distinctive: line 104
Do not add an error path for a case that cannot happen: No test can reach such a path, so it breaks rule 4 of the rules for every change.
- Very specific: line 107
When a type forces you to handle the case, call .expect("...") under #[expect(clippy::expect_used)], with a comment that states why the …
- Very specific: line 132
All changes MUST include related tests.
- Distinctive: line 140
Do NOT add or modify conformance tests without coordinating with the team.
- Distinctive: line 146
If a change warrants a new conformance test, note it in the PR description or open an issue in that repository.
- Very specific: line 155
Read CONTRIBUTING.md before making changes, and follow its rules for every change.
- Very specific: line 157
Run make check before you push.
- Very specific: line 165
Run every make target under timeout, for example timeout 3600 make ci.
- Distinctive: line 173
When the README, the rustdoc, and the source disagree, trust the source in this repository and report the discrepancy.
≈ “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
AWS Durable Execution SDK for Rust - Agent Guide
This repository contains the AWS Durable Execution SDK for Rust, the
aws-durable-execution-sdk crate, used to author AWS Lambda durable
functions.
Use the README and rustdoc, not this file, for APIs
Do not rely on this file for method signatures, builder options, or code
examples. The API reference for this SDK is the README and the
rustdoc comments in src/. To read the rustdoc in a browser, run
cargo doc --no-deps --all-features --open.
The AWS Durable Execution SDK Developer Guide explains the concepts that all the durable execution SDKs share. Its code examples cover other languages, not Rust. Use it for what each operation does, and the README and rustdoc for how to call it in Rust. Key sections:
For Lambda service topics such as deployment, infrastructure as code, invocation, IAM permissions, and quotas, see the Lambda durable functions guide.
Critical rules: the replay model
Durable functions use checkpoint and replay. After a wait, failure, or resume, code re-runs from the beginning. Completed steps return their checkpointed results without re-executing, and code outside steps runs again on every replay. This implies four rules:
- Code outside steps must be deterministic. Wrap clock reads, random
values, ID generation, calls to other services, and any other
non-deterministic work in a step. The SDK assigns each operation its ID
in the order the handler creates operations. So the handler must create
the same operations in the same order on every replay. Do not create
operations while iterating a
HashMaporHashSet, because their iteration order changes between runs. Sort into aVecfirst, or use aBTreeMaporBTreeSet. - Never call durable operations inside a step.
StepContext, the argument of a step body, has no operation methods. ADurableContextclone moved into the step closure still compiles. Do not do that. On replay the step body does not run, so every later operation would get a different ID than in the first invocation. So the SDK fails the execution on the first invocation with a context usage error when an operation is called inside a step body or await_for_conditioncheck. It does the same when an operation is called on the wrong context, such as a parent context used inside a child body. Usectx.run_in_child_contextto group operations, and call operations on the context passed to the closure. - Mutations inside steps are lost on replay. A step closure is
'static, so it cannot borrow a local variable. The body can still change shared state through anArc<Mutex<_>>or an atomic. That change happens only in the invocation that runs the body, not on replay. Return values from steps instead. - Side effects outside steps repeat on every replay. Put side effects
in steps. Logging is a side effect too: a
tracingevent between operations is emitted again on every replay, unless the subscriber suppresses replayed records. Install the subscriber withdurable::init_default_subscriber(), and each record between operations is written once per execution. A custom subscriber keeps that by addingReplayFilterLayeras the filter of itsfmtlayer.
Three more rules are specific to Rust. The crate documentation lists them
under "Determinism contract" in src/lib.rs.
- Use the SDK's combinators, not
tokio::select!. Usectx.raceorctx.select_okover durable futures, so the SDK records which branch won. - Use
.spawn()on an operation's builder, nottokio::spawn. A durable operation created on a task that the SDK did not start fails with an error. - Do not rely on
Dropbetween operations. When an execution suspends, the SDK drops the handler future. So a guard'sDropruns at the suspension, not after the wait completes. Release resources in a step.
See Determinism and Replay for worked examples in other languages.
Rules for SDK code
These rules apply to the SDK code in src/.
- Do not panic. A panic in the SDK fails the customer's Lambda
invocation. So clippy denies
unwrap,expect,panic!, and slice indexing. Return an error, and useget()instead of an index. Tests may panic:src/lib.rsallowsunwrapandexpectin unit tests, and other test code states its exemption with#[expect(...)]. - Do not add an error path for a case that cannot happen. No test can
reach such a path, so it breaks
rule 4 of the rules for every change.
When a type forces you to handle the case, call
.expect("...")under#[expect(clippy::expect_used)], with a comment that states why the case cannot happen. - Suppress a lint with
#[expect], not#[allow]. Give the reason in a comment. An#[expect]that no longer matches a lint failsmake check, so a stale suppression cannot stay in the code. The unit-test exemption insrc/lib.rsis the oneallow. - Do not call
tokio::spawn. The SDK's task-ownership checks and suspension accounting do not cover a task thattokio::spawnstarts.clippy.tomldisallows the call, and alsoJoinSet::spawnandspawn_blocking. Start every task through the task gateway insrc/task.rs. - Do not call
tokio::task::yield_nowin SDK code outside#[cfg(test)]code. The invocation coordinator suspends the invocation when no SDK work holds a permit and an operation waits. A yield releases the task's permit until the task is polled again, so a yield between operations can suspend the invocation. - Do not add a production dependency as part of another change.
scripts/check-direct-deps.shfails on a direct dependency outside its allowlist. Adding one needs its own pull request. See Dependency policy. Dev-dependencies need no approval.
Testing requirements
All changes MUST include related tests. At minimum, include unit tests
in a #[cfg(test)] mod tests block in the module under test. Add an
integration test under tests/ when the change spans several
operations, affects the public API, or needs to observe replay. These tests
drive a whole handler through LocalRunner (feature test-util). For an
isolated bug fix that a unit test covers, an integration test is not
required.
Do NOT add or modify conformance tests without coordinating with the
team. The runner and most requirements live in a separate repository
(aws-durable-execution-conformance-tests).
This repository holds the Rust handlers under conformance/. It also holds
the requirements of three suites that started in this SDK (history,
nondeterminism, and combinator), under conformance/conformance_ext/.
If a change warrants a new conformance test, note it in the PR description
or open an issue
in that repository.
Working in this repository
- The repository holds three independent cargo workspaces: the SDK crate at
the root (
src/andtests/), the conformance handlers (conformance/), and the deployable examples (examples/). - Read CONTRIBUTING.md before making changes, and
follow its rules for every change.
Run
make checkbefore you push. It is the single quality gate, and CONTRIBUTING.md lists what it runs. make checkcovers only the root workspace.make ciruns everyci.ymljob with CI's flags, including theconformance/andexamples/checks, which check the formatting, build Cargo's default members and lint every workspace member; run it after a public API change.make conformanceandmake cloud-testsrun the AWS suites. CONTRIBUTING.md gives their inputs.- Run every
maketarget undertimeout, for exampletimeout 3600 make ci. A change to suspension or concurrency code can make a test wait forever, and nothing else stops it. - Build a deployable binary with cargo-lambda, not with
cargo build. Thebuild_examples.shscripts inconformance/andexamples/call it.cargo buildlinks against the build host's glibc. A binary linked against a newer glibc than theprovided.al2023runtime's fails to start there. - When the README, the rustdoc, and the source disagree, trust the source in this repository and report the discrepancy.
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.

