Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when building or extending a Rust service - axum on tokio (or the repository's actix-web / rocket), typed errors with IntoResponse, serde at the boundary, sqlx queries and migrations, never blocking the runtime, tracing, clippy
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Rust moves a class of bugs to compile time, and leaves two to you: panics on a request path and blocking the async runtime. Most of the rules below are about those two.
Core principle: the repository's framework, error crates, database crate and workspace layout win. Handlers stay thin; the domain is plain Rust that compiles without the web framework.
| Layer | Responsibility | axum surface |
|---|---|---|
| Router / handler | Extract and validate input, call one service, map the result | Router::new().route(...), extractors (State, Path, Json), impl IntoResponse |
| Service | Use-case orchestration and business rules | a struct holding its ports, async fn methods |
| Domain | Types and invariants: newtypes whose constructors validate | plain structs and enums, thiserror error enum |
| Adapter | Database, outbound HTTP, queues | a type implementing the port trait (sqlx, reqwest) |
In a workspace the domain is often its own crate; a crate that does not depend on axum cannot leak it.
rust-toolchain.toml when present; edition from Cargo.toml (2024 for a new crate). Commit Cargo.lock for a binary. Add crates with cargo add, the version from crates.io, not memory.unwrap(), expect(), indexing that can go out of bounds, or as casts that truncate on input-derived values. Use ? with a typed error. expect is for startup invariants with a message that says why it cannot fail.thiserror; an application error that implements IntoResponse and maps each variant to 400/404/409 in the repository's problem shape, logging the source of a 500 and never returning it. anyhow belongs in main and scripts, not in a library or a handler's signature.#[derive(Deserialize)] (with #[serde(deny_unknown_fields)] where the contract is strict), converted into domain newtypes (TaskTitle::try_from(String)) whose constructors enforce the invariant. A malformed JSON body is already a 4xx through Json's rejection — keep that rejection in the same error shape.AppState (Clone, cheap: Arcs and pools inside) passed with .with_state(state) and taken by State<AppState>; no global mutable statics.tokio::task::spawn_blocking; no std::thread::sleep in async code (tokio::time::sleep); never hold a std::sync::Mutex guard across .await — restructure, or use tokio::sync::Mutex when the lock must span an await.tower_http layers — TimeoutLayer, RequestBodyLimitLayer, TraceLayer, CorsLayer configured, not permissive() in production. Outbound reqwest clients built once with a timeout and shared.query! / query_as! checked at compile time; keep the offline .sqlx data committed with cargo sqlx prepare when the repository uses offline mode) or the repository's diesel / sea-orm. Never format! a SQL string with input. Migrations with sqlx migrate add <name> (reversible when the repository's are) applied by sqlx::migrate!() or the deploy step; postgres-migrations covers safe DDL.tracing with structured fields and #[tracing::instrument(skip(state, body))] on handlers and service methods — skip anything secret or large; JSON output from tracing-subscriber where the repository logs JSON.axum::serve(listener, app).with_graceful_shutdown(signal) on SIGTERM / Ctrl-C.unsafe: none in a feature task. If a dependency forces it, say so in a task comment; the security agent reviews every unsafe block.POST /tasks:
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
pub struct CreateTask { title: String }
pub async fn create_task(
State(state): State<AppState>,
user: AuthUser,
Json(body): Json<CreateTask>,
) -> Result<(StatusCode, Json<TaskResponse>), AppError> {
let title = TaskTitle::try_from(body.title)?; // 400 through AppError on a bad title
let task = state.tasks.create(user.id, title).await?; // the service owns the rule set
Ok((StatusCode::CREATED, Json(TaskResponse::from(task))))
}
TaskTitle::try_from trims and rejects empty or over-200-character titles, so no Task with an invalid title can exist anywhere in the program.
The repository's commands first (list_component_checks, the Makefile, CI). Otherwise: cargo fmt --check, cargo clippy --all-targets --all-features -- -D warnings, cargo test. For the runtime check build once — cargo build --release (or the workspace's -p <api>) — and start target/release/<api> in the background with its port and DATABASE_URL set, rather than cargo run, whose child a terminal timeout can orphan.
.unwrap() on a parse of user input — one bad request takes the connection down with a panic.std::fs or a synchronous client inside an async fn handler.Arc would do — or the reverse, wrapping everything in Arc<Mutex<_>>.#[allow(clippy::...)] added to get the build green.format!("SELECT ... {}", input) anywhere.MutexGuard alive across an .await.unsafe in a diff with no comment explaining the invariant it relies on.tokio::spawn with the JoinHandle dropped and no error handling inside the task.まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
日本語の概要は準備中です。原文の説明を表示しています。
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
日本語の概要は準備中です。原文の説明を表示しています。
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
日本語の概要は準備中です。原文の説明を表示しています。
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
日本語の概要は準備中です。原文の説明を表示しています。
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
日本語の概要は準備中です。原文の説明を表示しています。
Use when deciding whether a request needs an analiz task before implementation - the conditions that require the architect's analysis versus going straight to implementation
日本語の概要は準備中です。原文の説明を表示しています。