agentleFS
AWSKnown publisheraws/aws-durable-execution-sdk-rust/AGENTS.md

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
  1. Very specific:

    Do not rely on this file for method signatures, builder options, or code examples.

    line 9
  2. Very specific:

    Side effects outside steps repeat on every replay: Put side effects in steps.

    line 70
  3. Very specific:

    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.

    line 81
  4. Very specific:

    Do not rely on Drop between operations: When an execution suspends, the SDK drops the handler future.

    line 87
  5. Distinctive:

    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.

    line 104
  6. Very specific:

    When a type forces you to handle the case, call .expect("...") under #[expect(clippy::expect_used)], with a comment that states why the …

    line 107
  7. Very specific:

    All changes MUST include related tests.

    line 132
  8. Distinctive:

    Do NOT add or modify conformance tests without coordinating with the team.

    line 140
  9. Distinctive:

    If a change warrants a new conformance test, note it in the PR description or open an issue in that repository.

    line 146
  10. Very specific:

    Read CONTRIBUTING.md before making changes, and follow its rules for every change.

    line 155
  11. Very specific:

    Run make check before you push.

    line 157
  12. Very specific:

    Run every make target under timeout, for example timeout 3600 make ci.

    line 165
  13. Distinctive:

    When the README, the rustdoc, and the source disagree, trust the source in this repository and report the discrepancy.

    line 173

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
AGENTS.md

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:

  1. 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 HashMap or HashSet, because their iteration order changes between runs. Sort into a Vec first, or use a BTreeMap or BTreeSet.
  2. Never call durable operations inside a step. StepContext, the argument of a step body, has no operation methods. A DurableContext clone 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 a wait_for_condition check. It does the same when an operation is called on the wrong context, such as a parent context used inside a child body. Use ctx.run_in_child_context to group operations, and call operations on the context passed to the closure.
  3. 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 an Arc<Mutex<_>> or an atomic. That change happens only in the invocation that runs the body, not on replay. Return values from steps instead.
  4. Side effects outside steps repeat on every replay. Put side effects in steps. Logging is a side effect too: a tracing event between operations is emitted again on every replay, unless the subscriber suppresses replayed records. Install the subscriber with durable::init_default_subscriber(), and each record between operations is written once per execution. A custom subscriber keeps that by adding ReplayFilterLayer as the filter of its fmt layer.

Three more rules are specific to Rust. The crate documentation lists them under "Determinism contract" in src/lib.rs.

  1. 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.
  2. Use .spawn() on an operation's builder, not tokio::spawn. A durable operation created on a task that the SDK did not start fails with an error.
  3. Do not rely on Drop between operations. When an execution suspends, the SDK drops the handler future. So a guard's Drop runs 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 use get() instead of an index. Tests may panic: src/lib.rs allows unwrap and expect in 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 fails make check, so a stale suppression cannot stay in the code. The unit-test exemption in src/lib.rs is the one allow.
  • Do not call tokio::spawn. The SDK's task-ownership checks and suspension accounting do not cover a task that tokio::spawn starts. clippy.toml disallows the call, and also JoinSet::spawn and spawn_blocking. Start every task through the task gateway in src/task.rs.
  • Do not call tokio::task::yield_now in 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.sh fails 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/ and tests/), the conformance handlers (conformance/), and the deployable examples (examples/).
  • Read CONTRIBUTING.md before making changes, and follow its rules for every change. Run make check before you push. It is the single quality gate, and CONTRIBUTING.md lists what it runs.
  • make check covers only the root workspace. make ci runs every ci.yml job with CI's flags, including the conformance/ and examples/ checks, which check the formatting, build Cargo's default members and lint every workspace member; run it after a public API change. make conformance and make cloud-tests run the AWS suites. CONTRIBUTING.md gives their inputs.
  • Run every make target under timeout, for example timeout 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. The build_examples.sh scripts in conformance/ and examples/ call it. cargo build links against the build host's glibc. A binary linked against a newer glibc than the provided.al2023 runtime's fails to start there.
  • When the README, the rustdoc, and the source disagree, trust the source in this repository and report the discrepancy.

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.