{
  "id": "rust-service",
  "name": "Rust service: Axum + Tokio + PostgreSQL + SQLx",
  "use_cases": [
    "Native network services",
    "resource-sensitive APIs",
    "services sharing a Rust core"
  ],
  "choose_when": [
    "Memory/resource control or Rust library reuse is important",
    "Team accepts ownership/async complexity for compile-time guarantees"
  ],
  "avoid_when": [
    "Primary goal is conventional CRUD delivery with minimal framework assembly",
    "Team cannot maintain Rust async code",
    "A full product framework is needed immediately"
  ],
  "tools": [
    {
      "job": "HTTP server",
      "default": "Axum + Tokio + tower-http",
      "alternatives": [
        "Direct Hyper only for transport-specific needs"
      ],
      "reason": "Typed extractors/state and Tower middleware compose with Tokio networking.",
      "limits": "Configure limits, timeout/error mapping and graceful shutdown. Blocking work must not monopolize async workers.",
      "source_urls": [
        "https://docs.rs/axum/latest/axum/",
        "https://tokio.rs/"
      ]
    },
    {
      "job": "Database and migrations",
      "default": "PostgreSQL + SQLx; sqlx-cli migrations",
      "alternatives": [],
      "reason": "SQL-oriented async access with optional checked query macros and migration tooling.",
      "limits": "Select runtime/TLS/database features for the resolved release. Checked macros need a database or maintained offline metadata; runtime queries are not compile-time checked.",
      "source_urls": [
        "https://docs.rs/sqlx/latest/sqlx/",
        "https://github.com/transact-rs/sqlx/blob/main/sqlx-cli/README.md"
      ]
    },
    {
      "job": "Configuration",
      "default": "Serde-backed settings + config",
      "alternatives": [
        "std::env for a small fixed settings set"
      ],
      "reason": "Typed settings plus structured events/spans.",
      "limits": "Set precedence explicitly; validate semantics; install a tracing subscriber; never log secrets.",
      "source_urls": [
        "https://docs.rs/config/latest/config/",
        "https://doc.rust-lang.org/std/env/fn.var.html",
        "https://docs.rs/tracing/latest/tracing/"
      ]
    },
    {
      "job": "Application logging",
      "default": "tracing + configured subscriber",
      "alternatives": [],
      "reason": "Typed settings plus structured events/spans.",
      "limits": "Set precedence explicitly; validate semantics; install a tracing subscriber; never log secrets.",
      "source_urls": [
        "https://docs.rs/config/latest/config/",
        "https://doc.rust-lang.org/std/env/fn.var.html",
        "https://docs.rs/tracing/latest/tracing/"
      ]
    },
    {
      "job": "Tests and static checks",
      "default": "cargo test; rustfmt; Clippy; cargo audit",
      "alternatives": [],
      "reason": "Compiler, style, behavior and known-advisory checks complement each other.",
      "limits": "Audit coverage is advisory-driven; compile success does not establish behavior or security. Test supported feature combinations rather than blindly enabling incompatible features.",
      "source_urls": [
        "https://doc.rust-lang.org/cargo/commands/cargo-test.html",
        "https://github.com/rust-lang/rustfmt",
        "https://doc.rust-lang.org/clippy/usage.html",
        "https://rustsec.org/",
        "https://docs.rs/assert_cmd/latest/assert_cmd/"
      ]
    },
    {
      "job": "Durable work",
      "default": "None for request-only service; Restate Rust SDK when durable workflows are required",
      "alternatives": [],
      "reason": "Durable handlers and persisted workflow progress address work outliving a process.",
      "limits": "Requires a Restate service and adoption test. Journal external operations correctly; idempotency and business transactions remain explicit. Tokio tasks alone are not durable.",
      "source_urls": [
        "https://docs.rs/restate-sdk/latest/restate_sdk/"
      ]
    },
    {
      "job": "Deployment",
      "default": "cargo build --release --locked in a target-specific build pipeline",
      "alternatives": [
        "Container with explicit runtime libraries"
      ],
      "reason": "Reproducible dependency resolution from committed lockfile; native executable artifact.",
      "limits": "Not universally static: verify libc, TLS/native libraries, target support, certificates and container runtime needs.",
      "source_urls": [
        "https://doc.rust-lang.org/cargo/commands/cargo-build.html"
      ]
    },
    {
      "job": "API token verification",
      "default": "jsonwebtoken + selected identity provider contract",
      "alternatives": [
        "Preserve an existing compatible project choice"
      ],
      "reason": "Typed claims and signature checks fit JWT-bearing service APIs",
      "limits": "Configure accepted algorithms, issuer/audience, expiry and trusted key rotation; select required crypto features for resolved release. This is a verifier, not an OIDC login/session solution; opaque tokens need provider introspection.",
      "source_urls": [
        "https://docs.rs/jsonwebtoken/latest/jsonwebtoken/"
      ]
    },
    {
      "job": "Transactional email",
      "default": "lettre + project-selected SMTP provider",
      "alternatives": [
        "Preserve an existing compatible project choice"
      ],
      "reason": "Typed mail construction and SMTP transport support application messages",
      "limits": "Configure TLS, sender credentials and timeouts; send required mail through durable jobs with duplicate protection. Validate chosen async/runtime features in Rust; delivery receipts and bounces need provider handling.",
      "source_urls": [
        "https://docs.rs/lettre/latest/lettre/"
      ]
    },
    {
      "job": "Uploads and object storage",
      "default": "AWS SDK for Rust S3 client",
      "alternatives": [
        "Preserve an existing compatible project choice"
      ],
      "reason": "Durable object storage avoids dependence on service-local disk",
      "limits": "Configure runtime credentials, region and least-privilege bucket access; authorize object keys and uploads, bound size/concurrency and define retention. Test multipart cleanup and selected provider compatibility.",
      "source_urls": [
        "https://docs.aws.amazon.com/sdk-for-rust/latest/dg/rust_s3_code_examples.html"
      ]
    },
    {
      "job": "Realtime transport",
      "default": "Axum WebSocket extractor",
      "alternatives": [
        "Server-sent events for one-way feeds",
        "Polling for infrequent updates"
      ],
      "reason": "WebSocket support fits bidirectional connected clients",
      "limits": "Enable the documented module/feature; authorize handshake and every protected message, bound queues/message size and implement heartbeat/shutdown. Socket delivery is not durable history; define reconnect/resync.",
      "source_urls": [
        "https://docs.rs/axum/latest/axum/extract/ws/index.html"
      ]
    }
  ],
  "setup_steps": [
    "Create source in a local development workspace: cargo new service; enter service and commit the generated application Cargo.lock after dependency resolution.",
    "Run cargo add axum; cargo add tokio --features macros,rt-multi-thread; add required tower-http middleware after selecting compatible releases.",
    "Add SQLx selecting PostgreSQL, Tokio and a supported TLS configuration from that release; install matching sqlx-cli. Create config validation and tracing subscriber.",
    "Use a disposable database in DATABASE_URL. Create migrations with sqlx migrate add initial; write SQL and run sqlx migrate run.",
    "For checked query macros, run cargo sqlx prepare after schema/query changes and commit offline metadata. Implement HTTP, real-database and cancellation tests.",
    "Introduce Restate only after a separate restart/retry/idempotency proof. Pin toolchain and release targets. These instructions were not executed."
  ],
  "verification_commands": [
    "cargo fmt --all -- --check",
    "cargo clippy --workspace --all-targets --locked -- -D warnings",
    "cargo test --workspace --locked",
    "cargo audit",
    "sqlx migrate info",
    "cargo sqlx prepare --check",
    "cargo build --release --locked"
  ],
  "evidence_status": "documentation-reviewed",
  "sources": [
    {
      "url": "https://docs.rs/axum/latest/axum/",
      "title": "Axum",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://tokio.rs/",
      "title": "Tokio",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.rs/sqlx/latest/sqlx/",
      "title": "SQLx",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://github.com/transact-rs/sqlx/blob/main/sqlx-cli/README.md",
      "title": "SQLx CLI",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.rs/config/latest/config/",
      "title": "Rust config crate",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://doc.rust-lang.org/std/env/fn.var.html",
      "title": "Rust environment variables",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.rs/tracing/latest/tracing/",
      "title": "Rust tracing",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://doc.rust-lang.org/cargo/commands/cargo-test.html",
      "title": "Cargo test",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://github.com/rust-lang/rustfmt",
      "title": "rustfmt",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://doc.rust-lang.org/clippy/usage.html",
      "title": "Clippy usage",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://rustsec.org/",
      "title": "RustSec",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.rs/assert_cmd/latest/assert_cmd/",
      "title": "assert_cmd",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.rs/restate-sdk/latest/restate_sdk/",
      "title": "Restate Rust SDK",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://doc.rust-lang.org/cargo/commands/cargo-build.html",
      "title": "Cargo build",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.rs/jsonwebtoken/latest/jsonwebtoken/",
      "title": "jsonwebtoken API",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.rs/lettre/latest/lettre/",
      "title": "lettre documentation",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.aws.amazon.com/sdk-for-rust/latest/dg/rust_s3_code_examples.html",
      "title": "AWS Rust S3 examples",
      "checked_date": "2026-10-10"
    },
    {
      "url": "https://docs.rs/axum/latest/axum/extract/ws/index.html",
      "title": "Axum WebSocket extractor documentation",
      "checked_date": "2026-10-10"
    }
  ],
  "open_questions": [
    "Which API/token contract and trusted key-rotation mechanism apply?",
    "Which target/runtime/TLS and database configurations must ship?",
    "Does durable work justify a separate Restate service and its operation?",
    "Which workload, realtime capacity and restore objectives must be met?"
  ],
  "title": "Rust service",
  "language": "Rust",
  "group": "APIs & services",
  "kind": [
    "api"
  ],
  "ui": "none",
  "host": "binary",
  "summary": "Services where runtime control and explicit resource handling matter.",
  "shape": "Axum · Tokio · SQLx · PostgreSQL",
  "tradeoff": "Async runtime and type complexity add development work; measure the reason to choose them.",
  "research_file": "go-rust.json",
  "reviewed": "2026-10-10",
  "best_practices": [
    "Keep blocking work off async executor threads and apply timeouts and concurrency limits.",
    "Use typed configuration and tracing; preserve useful context when returning errors.",
    "Rehearse SQLx migrations and validate prepared query metadata against the intended schema.",
    "Build for the actual deployment target. Type checks do not replace authorization, retry and load tests."
  ],
  "research_freshness": {
    "core_guidance_checked_on": "2026-10-13",
    "sources": [
      "https://docs.rs/axum/latest/axum/"
    ],
    "scope": "Core framework roles, current setup/agent documentation and cited-source availability rechecked; not a reimplementation or exhaustive semantic audit of every third-party dependency."
  },
  "guide_url": "/stacks/rust-service/",
  "markdown_url": "/stacks/rust-service/guide.md",
  "json_url": "/stacks/rust-service/record.json",
  "architecture_and_migration": {
    "id": "rust-service",
    "version_scope": "Reviewed docs expose Axum 0.8.9, Tokio 1.53.2 and SQLx 0.9.0 on 11 October 2026; Rust std docs show 1.99.0. These are documentation scopes, not a qualified composition or an automatic upgrade recommendation. Record rust-toolchain.toml, Cargo.lock, enabled features, SQLx CLI compatibility and database version before implementation.",
    "operating_model": "Recommendation: Axum/Tower owns request extraction and middleware; domain functions return explicit errors; Tokio drives async I/O; SQLx pools and transactions own database access. Track child tasks and cancellation separately from persisted jobs. A Tokio channel coordinates tasks inside one live process and cannot recover accepted work after a crash.",
    "architecture": [
      "Recommendation: route through Axum extractors and typed State with cloneable pool/client handles. Keep domain logic independent of HTTP responses, and map business/infrastructure errors deliberately through IntoResponse.",
      "Recommendation: compose Tower limits and timeouts with explicit overload/error mapping. Use bounded channels/semaphores; a concurrency limit without an admission/queue policy does not bound every waiting request.",
      "Recommendation: use SQLx query macros where schema checking fits and dynamic queries where needed. Store reviewed migrations and offline metadata; runtime authorization and isolation remain separate from compile-time type checks.",
      "Recommendation: move sustained CPU work to a bounded blocking executor or dedicated worker process. Track async tasks with cancellation/termination coordination; a started spawn_blocking task cannot be forcibly aborted through Tokio."
    ],
    "developer_workflow": [
      "Recommendation: inspect Cargo.toml/Cargo.lock, rust-toolchain.toml and enabled dependency features. For a new project, cargo new service and cargo add axum can establish the package; select Tokio runtime and SQLx database/TLS features deliberately rather than copying a broad feature list.",
      "Recommendation: run cargo fmt --check, cargo clippy --all-targets -- -D warnings and cargo test --locked with the project-supported feature matrix. Compile and run protocol/cancellation fixtures; no integration was executed in this research.",
      "Recommendation: install a SQLx CLI version compatible with the selected crate; against a disposable database run cargo sqlx migrate run, then cargo sqlx prepare --workspace and commit .sqlx metadata. CI cargo sqlx prepare --check --workspace detects stale metadata; an offline build does not prove the live schema matches.",
      "Recommendation: cargo build --release --locked prepares a release for the selected target. Use tracing/request IDs, pool-wait metrics and representative load profiles before asserting latency, cost or capacity advantages."
    ],
    "avoid": [
      "Avoid Arc<Mutex<Connection>> for all queries; a shared pool permits independent requests without a global database serialization boundary.",
      "Avoid blocking SDK calls or heavy loops on async runtime workers. spawn_blocking needs its own capacity limits and cannot abort a running closure.",
      "Avoid using Tokio mpsc as a drop-in replacement for durable Redis jobs; accepted jobs disappear with memory unless independently persisted.",
      "Avoid confusing Rust memory safety with correct authorization, queue delivery or compatibility guarantees."
    ],
    "transitions": [
      {
        "capability": "data",
        "existing_contract": "Capture the old SQL schema, transactions, tenant filters, nullable values and database engine behavior.",
        "coexistence": "Recommendation: keep existing schema ownership and backward-compatible columns; run SQLx reads for a selected boundary before transferring its writer. Generate metadata against exactly the reviewed migration state.",
        "target": "Recommendation: SQLx pooled access with transaction-scoped domain changes; query! checks literals against a live build schema or checked-in .sqlx metadata. Keep database engine choice independent of the Rust rewrite.",
        "benefits": [
          {
            "benefit": "Compile-time query/type checks can expose SQL/API mismatches before deployment.",
            "prerequisites": "Query macros/features and metadata match the chosen engine and schema; nullable results and dynamic queries receive runtime checks.",
            "tradeoffs": "Dynamic SQL is outside macro checking; stale offline metadata can compile; schema ownership and deployment order still need controls."
          }
        ],
        "checks": [
          "Run an offline locked build with the reviewed metadata and a live prepare --check against the migrated fixture DB.",
          "Verify both runtimes read each other's writes, including null/time/ID mappings.",
          "Cancel during a transaction and confirm the intended committed/rolled-back state plus pool recovery."
        ],
        "rollback": "Recommendation: route writes back while retaining additive schema and a previous compatible binary. Delay destructive migrations; reconcile new-only persisted values before rollback.",
        "sources": [
          "https://docs.rs/sqlx/latest/sqlx/macro.query.html",
          "https://docs.rs/sqlx/latest/sqlx/struct.Pool.html",
          "https://github.com/transact-rs/sqlx/blob/main/sqlx-cli/README.md"
        ],
        "id": "data-1"
      },
      {
        "capability": "jobs",
        "existing_contract": "Preserve old broker serialization, acknowledgement, delayed/retry states, concurrency and effect IDs. Durable Redis workers cannot be replaced transparently by tokio::spawn.",
        "coexistence": "Recommendation: Rust commits an outbox intent in its domain transaction; a replay-safe relay submits to the retained queue/worker interface. Existing workers retain queue ownership while new job kinds are qualified. This outbox design is inferred, not a shipped Axum feature.",
        "target": "Recommendation: keep proven durable workers until a chosen Rust queue implementation is qualified for retries, scheduling, leases and crashes. River current Ruby docs describe a shared schema with Rust; that statement alone does not qualify a Rust worker API or migration.",
        "benefits": [
          {
            "benefit": "A retained worker boundary allows the HTTP layer to change without dropping backlog or broker guarantees.",
            "prerequisites": "Same-transaction outbox intent; stable relay/effect IDs; explicit payload translator; observed delivery and backlog ownership.",
            "tradeoffs": "Two runtimes and a relay add operations; delivery may repeat; a SQLx transaction alone does not atomically submit to Redis."
          }
        ],
        "checks": [
          "Crash after the domain commit but before relay delivery; an intent remains recoverable.",
          "Crash the relay after submission before marking sent; duplicate delivery produces one logical effect.",
          "Reconcile ready, scheduled, retry, failed and in-flight old jobs before any worker replacement."
        ],
        "rollback": "Recommendation: stop the new producer, let accepted outbox entries settle and retain the old worker. Roll back traffic only after ambiguous effects are reconciled; avoid consuming a queue with incompatible handlers.",
        "sources": [
          "https://tokio.rs/tokio/tutorial/channels",
          "https://docs.rs/sqlx/latest/sqlx/macro.query.html",
          "https://riverqueue.com/docs/ruby"
        ],
        "id": "jobs-1"
      },
      {
        "capability": "operations",
        "existing_contract": "Define HTTP admission/error behavior, task ownership, shutdown deadline and behavior for unavoidable CPU/blocking operations.",
        "coexistence": "Recommendation: retain old routing while introducing Tower admission bounds and CancellationToken/TaskTracker-based ownership for a coherent endpoint cohort. Benchmark equivalent resource limits and durability before attributing gains to Rust.",
        "target": "Recommendation: bounded async work, cooperative cancellation, explicit shutdown notification plus tracked task completion, and SQLx pool close. For untrusted/hard-deadline native work, isolate it in a process whose termination contract is tested.",
        "benefits": [
          {
            "benefit": "Tracked tasks and explicit admission limits make resource use and planned termination easier to reason about.",
            "prerequisites": "Every child task is tracked; limits include waiting work; cancellation-safe I/O and shutdown budget are verified.",
            "tradeoffs": "spawn_blocking closures may continue after timeout; killing a process still requires durable recovery and external-effect reconciliation."
          }
        ],
        "checks": [
          "Cancel an overloaded request and verify queue permits/resources are released.",
          "Send termination during async and blocking work; document tasks that drain and work that cannot be aborted.",
          "Force a crash after acceptance; verify recovery of persisted intents and honest failure of memory-only work."
        ],
        "rollback": "Recommendation: return the cohort to the previous service and reconcile persisted outcomes. Do not simply retry every cancelled request; its external effect may already have occurred.",
        "sources": [
          "https://docs.rs/tower/latest/tower/limit/index.html",
          "https://tokio.rs/tokio/topics/shutdown",
          "https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html",
          "https://docs.rs/sqlx/latest/sqlx/struct.Pool.html"
        ],
        "id": "operations-1"
      },
      {
        "capability": "realtime",
        "existing_contract": "Preserve subscriptions, authorization revocation, event versions, reconnect behavior and cross-instance fan-out.",
        "coexistence": "Recommendation: keep the existing shared broker while a Rust gateway serves entire room/tenant cohorts; adapters translate existing messages without dual-emitting user effects. Test cross-runtime publication in both directions.",
        "target": "Recommendation: Axum WebSocket transport and bounded per-client queues. Tokio broadcast is appropriate only for local ephemeral fan-out with explicit Lagged handling; use durable state/event history to resync clients when loss is unacceptable.",
        "benefits": [
          {
            "benefit": "Local bounded fan-out can prevent slow receivers from retaining unbounded memory.",
            "prerequisites": "Overflow/disconnect/resync policy exists; replica routing and shared fan-out remain covered; every broadcast error is handled.",
            "tradeoffs": "Tokio broadcast is process-local; old messages are evicted when capacity is exceeded; it is not a durable cross-node broker."
          }
        ],
        "checks": [
          "Force receiver lag and verify Lagged triggers resync or the documented disconnect policy.",
          "Publish from each runtime and confirm the opposite runtime's subscribers receive the intended event.",
          "Reconnect after deployment/crash and rebuild state without trusting missing ephemeral frames."
        ],
        "rollback": "Recommendation: route the whole cohort back and retain the shared broker/protocol. Resynchronize from authoritative durable records; local channel state cannot be restored from a previous binary.",
        "sources": [
          "https://docs.rs/axum/latest/axum/",
          "https://docs.rs/tokio/latest/tokio/sync/broadcast/index.html",
          "https://redis.io/docs/latest/develop/pubsub/"
        ],
        "id": "realtime-1"
      }
    ],
    "sources": [
      {
        "url": "https://docs.rs/axum/latest/axum/",
        "title": "Axum 0.8.9",
        "claim": "Typed extractors/State and Tower middleware form the HTTP composition."
      },
      {
        "url": "https://docs.rs/tower/latest/tower/limit/index.html",
        "title": "Tower limits",
        "claim": "Concurrency and rate-limit middleware exist; admission/error policy needs application design."
      },
      {
        "url": "https://tokio.rs/tokio/topics/shutdown",
        "title": "Tokio graceful shutdown",
        "claim": "CancellationToken and TaskTracker coordinate shutdown and task completion."
      },
      {
        "url": "https://tokio.rs/tokio/tutorial/channels",
        "title": "Tokio channels",
        "claim": "Bounded mpsc coordinates tasks; capacity/backpressure is explicit, not disk persistence."
      },
      {
        "url": "https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html",
        "title": "Tokio spawn_blocking",
        "claim": "CPU work needs a parallelism limit; started blocking tasks cannot be aborted."
      },
      {
        "url": "https://docs.rs/sqlx/latest/sqlx/macro.query.html",
        "title": "SQLx 0.9.0 query macro",
        "claim": "Literal queries need a matching database schema or offline metadata; engine binding and nullability have limits."
      },
      {
        "url": "https://docs.rs/sqlx/latest/sqlx/struct.Pool.html",
        "title": "SQLx pool",
        "claim": "A shared async pool supports reuse; a mutex around one connection creates serialization; close should be awaited."
      },
      {
        "url": "https://github.com/transact-rs/sqlx/blob/main/sqlx-cli/README.md",
        "title": "SQLx CLI README",
        "claim": "Migrations and prepare/prepare --check maintain offline query metadata."
      },
      {
        "url": "https://docs.rs/tokio/latest/tokio/sync/broadcast/index.html",
        "title": "Tokio broadcast",
        "claim": "A bounded local channel drops older values and reports lagging receivers."
      },
      {
        "url": "https://riverqueue.com/docs/ruby",
        "title": "River cross-language schema statement",
        "claim": "Current Ruby guide explicitly names Go, Rust and TypeScript sharing a schema; Rust API itself is unqualified here."
      },
      {
        "url": "https://redis.io/docs/latest/develop/pubsub/",
        "title": "Redis Pub/Sub",
        "claim": "Ephemeral shared fan-out remains at-most-once and needs a separate recovery path."
      }
    ],
    "reviewed_at": "2026-10-11",
    "evidence": "documentation-reviewed"
  },
  "rewrite_url": "/rewrite/guide.md",
  "migration_contracts_url": "/rewrite/contracts.json",
  "agent_workflow": [
    "Read README, dependency manifests, lockfiles, runtime pins and the maintained project workflow before changing anything. Preserve an existing stack unless reconsidering it is part of the request.",
    "Use this guide to select tools by requirement. Resolve compatible versions from official and installed-version documentation; record the actual lockfile and runtime versions.",
    "Create a plan for schema changes, identity, authorization, external effects and deployment. A library choice does not complete its integration.",
    "Run relevant checks after configuration. Exercise the real interface, failure paths and packaged artifact on the intended target. Report commands, versions, results and untested behavior.",
    "On failure, retain the command and diagnostic, fix the failing prerequisite and resume there. Do not regenerate over existing work or suppress failures to make a check green."
  ],
  "selection": {
    "native_ui": false,
    "static_hosting": false,
    "offline_client_candidate": false
  },
  "coverage_note": "Tools are curated starting points for this application role. Exact versions, integrations and offline behavior require project-specific qualification."
}
