Guidance for AI coding agents working in this repository.
- Use English in repository files: code, comments, commit messages, PR titles, PR bodies, and technical docs.
- Add comments only when they explain non-obvious intent or constraints.
- Add tests when they verify real behavior or guard a regression; do not add placeholder tests.
- Do not change public APIs or behavior tests unless the task explicitly requires it.
The Rust workspace for OpenDAL core lives under core/. There is no root Cargo.toml; run core cargo commands from core/.
cd core
# Check and build
cargo check
cargo build --locked
cargo build --all-features --locked
# Lint, matching Core CI
cargo clippy --workspace --all-targets --all-features -- -D warnings
# Lint a focused service/layer feature set
cargo clippy --all-targets --features=services-s3 -- -D warnings
# Unit tests, matching Core CI
cargo nextest run --workspace --no-fail-fast --all-features
# Doc tests and docs
cargo test --workspace --doc --all-features
cargo doc --lib --no-deps --all-features
# Behavior tests
OPENDAL_TEST=s3 cargo test behavior --features tests,services-s3
# Format core workspace
cargo fmt --all
cargo fmt --all -- --checkRepository-wide format checks run from the repository root:
./scripts/workspace.py cargo fmt -- --check
taplo format --checkCode generation and release helpers also run from the repository root:
just generate python
just generate java
just update-version
just releaseOpenDAL's Rust core has been split into a facade crate plus smaller core, service, and layer crates.
core/Cargo.toml: Rust workspace root andopendalfacade package.core/src/lib.rs: facade crate that re-exportsopendal-core, wires optional service/layer crates, and registers enabled services forOperator::from_uri/Operator::via_iter.core/core/:opendal-core, containing public core types, raw traits, shared layers, HTTP utilities, docs, RFCs, and the always-available memory service.core/services/<service>/: standalone service crates namedopendal-service-*.core/layers/<layer>/: standalone layer crates namedopendal-layer-*.core/testkit/: behavior-test support.core/tests/behavior/: core behavior test entrypoint.integrations/: ecosystem integrations such asobject_store,parquet,dav-server,unftp-sbe, and Spring.bindings/: language bindings; each binding has its own build/test conventions.website/: documentation website.dev/: repository maintenance, code generation, and release tooling used byjust.
Important consequences of the split:
- Service and layer code no longer lives under
core/src/servicesorcore/src/layers. - Public API changes usually touch
core/core/src/...and the facade exports incore/src/lib.rs. - Optional user-facing features are declared in
core/Cargo.tomlasservices-*andlayers-*, and usually map to optionalopendal-service-*/opendal-layer-*dependencies. - The memory service is in
core/core/src/services/memory;services-memoryis a deprecated compatibility feature because memory is always enabled.
Most services follow this shape under core/services/<name>/:
src/lib.rs: crate docs, module declarations, public builder/config exports, and service registration function.src/backend.rs: builder andopendal_core::raw::Accessimplementation.src/config.rs: serializable config and builder conversion.src/core.rs: shared service client, request construction, and service-specific helpers.src/error.rs: service-specific error parsing.src/reader.rs,src/writer.rs,src/lister.rs,src/deleter.rs,src/copier.rs: operation implementations when the service needs them.src/docs.md: service docs included into rustdoc.
When adding or changing a service:
- Put implementation in
core/services/<service>/. - Implement
BuilderandAccessusingopendal_core. - Add or update the facade feature and optional dependency in
core/Cargo.toml. - Register the service in
core/src/lib.rswhen it should support URI/iterator construction. - Add or update behavior-test setup under
.github/services/<service>/when real backend testing is needed. - Run focused clippy/tests first, then broaden validation based on the blast radius.
Reusable layers live under core/layers/<layer>/ as opendal-layer-* crates. Core layers that are required by opendal-core itself live under core/core/src/layers/.
When adding or changing a public optional layer:
- Put reusable optional code in
core/layers/<layer>/. - Depend on
opendal-coreand implementLayer/LayeredAccessagainstopendal_core::raw. - Add or update the corresponding
layers-*feature and optional dependency incore/Cargo.toml. - Re-export it from the facade when users should access it through
opendal::layers.
- Use
cargo fmt --all -- --checkfor Rust formatting insidecore/; use./scripts/workspace.py cargo fmt -- --checkfor the repository-wide format check. - For core changes,
cargo clippy --workspace --all-targets --all-features -- -D warningsis the CI-level lint gate. - For behavior changes, run the narrow behavior test, for example
OPENDAL_TEST=s3 cargo test behavior --features tests,services-s3. - Behavior tests require backend credentials or fixture setup. Use
.env.example,fixtures/, and.github/services/<service>/as the source of truth for service-specific setup. - Integration crates under
integrations/have their own CI workflows and should be validated in their own directories when touched. - Binding changes should follow the binding's local README/build files and the matching
.github/workflows/ci_bindings_*.yml.
- Always use
.github/pull_request_template.mdwhen creating a PR. - Keep PR titles and descriptions factual and concise.
- Do not add AI-tool branding or co-author trailers.
- If public APIs or user-facing behavior change, update docs and call out the user-facing impact in the PR template.
- Minimum Rust version is 1.91, configured in
core/Cargo.tomland checked by CI. - Use
opendal_core::raw::Access,Layer, andLayeredAccessfor internal implementations. - Use
opendal_core::raw::oio::{ReadStream, Write, List, Delete}for operation bodies. - Use
Operatorandblocking::Operatoras the public API entry points. - Prefer existing helpers in
opendal-corebefore adding service-local utilities.
Security model: SECURITY.md
Agents that scan this repository should consult SECURITY.md and the threat
model it links (SECURITY-THREAT-MODEL.md) for the project's in-scope /
out-of-scope declarations, adversary model, and known non-findings before
reporting issues.