From 5326368c5e6e0085b6a20b69d67ff9fad5746a81 Mon Sep 17 00:00:00 2001 From: "Carlos D. Escobar-Valbuena" Date: Sun, 4 Oct 2026 08:25:19 -0500 Subject: [PATCH 1/4] fix(ci): clippy::double_must_use on #[async_trait] traits + stop toolchain drift (BRO-2814) main went red with no code change: every CI job used `dtolnay/rust-toolchain@stable`, which floats to whatever is current stable on the day the job runs. Between the last green run (2026-09-28) and today, `stable` moved 1.93.0 -> 1.99.0 and clippy started treating the boxed `dyn Future` that `#[async_trait]` returns as already `#[must_use]`, so the `#[must_use]` the macro also stamps on the generated method is flagged as `clippy::double_must_use` -- 72 errors in aios-protocol alone, plus the same pattern in 44 more trait definitions across ergon, chronos, haima, life-runtime, etc. This is a known async-trait/clippy interaction, not a real bug in any of these traits, so each site gets a narrow `#[allow(clippy::double_must_use, reason = "...")]` rather than a blanket `-A` on the lint. Also, to close the drift loop itself (not just today's symptom): - Add rust-toolchain.toml pinning channel = "1.99.0" (the toolchain clippy was just made clean against) and switch the CI/harness jobs that used `@stable` to `@master`, which reads that file instead of floating. Bumping the toolchain is now a deliberate edit to this file instead of a silent drift. MSRV Check keeps its own explicit 1.93.0 pin, unchanged. - Add a weekly schedule trigger to ci.yml so main's CI runs even without a push (BRO-2806: main's latest CI must be under 7 days old) -- this is exactly how the drift went undetected for a week. - Group routine cargo minor/patch bumps into one Dependabot PR instead of ten (the ten open PRs #1797-#1806 all failed on this same latent issue, independent of what they bumped). Co-Authored-By: Claude Sonnet 5 --- .github/dependabot.yml | 8 +++ .github/workflows/ci.yml | 27 ++++---- .github/workflows/harness.yml | 2 +- crates/aios/aios-events/src/lib.rs | 4 ++ crates/aios/aios-policy/src/lib.rs | 4 ++ crates/aios/aios-protocol/src/budget.rs | 4 ++ crates/aios/aios-protocol/src/hypervisor.rs | 8 +++ .../aios-protocol/src/network_isolation.rs | 4 ++ crates/aios/aios-protocol/src/payment.rs | 4 ++ crates/aios/aios-protocol/src/ports.rs | 64 +++++++++++++++++++ crates/aios/aios-runtime/src/lib.rs | 12 ++++ crates/aios/aios-sandbox/src/lib.rs | 4 ++ crates/anima/anima-identity/src/rotation.rs | 4 ++ crates/arcan/arcan-aios-adapters/src/tools.rs | 4 ++ crates/arcan/arcan-ergon/src/registry.rs | 4 ++ crates/arcan/arcan-sandbox/src/provider.rs | 4 ++ crates/arcan/arcan-tui/src/client.rs | 4 ++ crates/chronos/chronos-core/src/agenda.rs | 4 ++ crates/chronos/chronos-core/src/dispatch.rs | 4 ++ crates/chronos/chronos-core/src/trigger.rs | 4 ++ crates/cli/life-cli/src/deploy/backend.rs | 4 ++ crates/ergon/ergon-anima-adapter/src/lib.rs | 4 ++ .../ergon/ergon-life-hooks/src/attestation.rs | 4 ++ crates/ergon/ergon-life-hooks/src/budget.rs | 4 ++ .../ergon/ergon-life-hooks/src/capability.rs | 4 ++ crates/ergon/ergon-life-hooks/src/score.rs | 4 ++ crates/ergon/ergon/src/agent.rs | 4 ++ crates/ergon/ergon/src/agent_registry.rs | 4 ++ crates/ergon/ergon/src/hook.rs | 4 ++ crates/ergon/ergon/src/runtime.rs | 8 +++ crates/ergon/ergon/src/step.rs | 4 ++ crates/ergon/ergon/src/stream.rs | 4 ++ crates/ergon/ergon/src/workflow.rs | 4 ++ crates/haima/haima-outcome/src/verifier.rs | 4 ++ crates/haima/haima-wallet/src/backend.rs | 4 ++ .../life-kernel-conformance/src/lib.rs | 4 ++ crates/life-perturb/src/injector.rs | 4 ++ crates/life-runtime/anima-proxy/src/client.rs | 4 ++ crates/life-runtime/arcan-proxy/src/client.rs | 4 ++ crates/life-runtime/haima-proxy/src/client.rs | 4 ++ crates/life-runtime/lago-proxy/src/client.rs | 4 ++ .../life-runtime/lifed-conformance/src/lib.rs | 4 ++ .../life-runtime/lifed/src/idempotency/mod.rs | 4 ++ crates/life-runtime/lifed/src/route/ergon.rs | 4 ++ crates/life-runtime/lifed/src/saga/driver.rs | 8 +++ .../lifegw/src/services/anthropic_messages.rs | 4 ++ crates/nous/nous-tools/src/lineage.rs | 4 ++ crates/relay/life-relayd/src/adapters/mod.rs | 4 ++ rust-toolchain.toml | 18 ++++++ 49 files changed, 303 insertions(+), 12 deletions(-) create mode 100644 rust-toolchain.toml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d813b01c..fff8499d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,6 +7,14 @@ updates: open-pull-requests-limit: 10 labels: - dependencies + # BRO-2814: one grouped PR for routine bumps instead of ten separate + # ones hitting the same CI gates in parallel. Major bumps (API breaks) + # stay ungrouped so they still get individual review. + groups: + cargo-patch-and-minor: + update-types: + - minor + - patch - package-ecosystem: github-actions directory: / schedule: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e23265ab..9da621c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,11 @@ on: - "docs/**" - "research/**" workflow_dispatch: + # BRO-2814/BRO-2806: main's latest CI run must be under 7 days old even + # with no pushes — toolchain drift (e.g. `stable` floating to a new + # rustc/clippy) otherwise surfaces only when someone happens to push. + schedule: + - cron: "0 6 * * 1" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -40,7 +45,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master with: components: rustfmt - run: cargo fmt --all -- --check @@ -53,7 +58,7 @@ jobs: - uses: actions/checkout@v7 - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master with: components: clippy - uses: Swatinem/rust-cache@v2 @@ -92,7 +97,7 @@ jobs: df -h / - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master - uses: Swatinem/rust-cache@v2 with: prefix-key: v1-rust @@ -121,7 +126,7 @@ jobs: - uses: actions/checkout@v7 - name: Install protoc run: brew install protobuf - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master - uses: Swatinem/rust-cache@v2 - run: cargo test --workspace @@ -157,7 +162,7 @@ jobs: continue-on-error: true steps: - uses: actions/checkout@v7 - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master - uses: Swatinem/rust-cache@v2 - run: cargo install cargo-deny --locked - run: cargo deny check @@ -170,7 +175,7 @@ jobs: - uses: actions/checkout@v7 - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master - uses: Swatinem/rust-cache@v2 - name: Run scripts/verify_dependencies_lifed.sh run: bash scripts/verify_dependencies_lifed.sh @@ -183,7 +188,7 @@ jobs: - uses: actions/checkout@v7 - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master - uses: Swatinem/rust-cache@v2 - name: Run scripts/verify_dependencies_lifegw.sh run: bash scripts/verify_dependencies_lifegw.sh @@ -196,7 +201,7 @@ jobs: - uses: actions/checkout@v7 - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master - uses: Swatinem/rust-cache@v2 - name: Run scripts/verify_dependencies_lifegw_anthropic_codec.sh run: bash scripts/verify_dependencies_lifegw_anthropic_codec.sh @@ -217,7 +222,7 @@ jobs: - uses: actions/checkout@v7 - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master - uses: Swatinem/rust-cache@v2 - name: Self-test (regression guard for FAIL-path detection) run: bash scripts/verify_dependencies_ergon.sh --self-test @@ -246,7 +251,7 @@ jobs: - uses: actions/checkout@v7 - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master with: components: rustfmt, clippy - uses: Swatinem/rust-cache@v2 @@ -346,7 +351,7 @@ jobs: - uses: actions/checkout@v7 - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master - uses: oven-sh/setup-bun@v2 with: bun-version: latest diff --git a/.github/workflows/harness.yml b/.github/workflows/harness.yml index cc356bfb..43163175 100644 --- a/.github/workflows/harness.yml +++ b/.github/workflows/harness.yml @@ -64,7 +64,7 @@ jobs: df -h / - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master with: components: rustfmt, clippy - uses: Swatinem/rust-cache@v2 diff --git a/crates/aios/aios-events/src/lib.rs b/crates/aios/aios-events/src/lib.rs index be348657..b00029e0 100644 --- a/crates/aios/aios-events/src/lib.rs +++ b/crates/aios/aios-events/src/lib.rs @@ -18,6 +18,10 @@ fn to_kernel_error(error: anyhow::Error) -> KernelError { KernelError::Runtime(error.to_string()) } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait EventStore: Send + Sync { async fn append(&self, event: &EventRecord) -> Result<()>; diff --git a/crates/aios/aios-policy/src/lib.rs b/crates/aios/aios-policy/src/lib.rs index c5a3e94f..37a5790f 100644 --- a/crates/aios/aios-policy/src/lib.rs +++ b/crates/aios/aios-policy/src/lib.rs @@ -42,6 +42,10 @@ pub struct ApprovalResolution { pub actor: String, } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait PolicyEngine: Send + Sync { async fn evaluate_capabilities( diff --git a/crates/aios/aios-protocol/src/budget.rs b/crates/aios/aios-protocol/src/budget.rs index 9779910a..a048fa0f 100644 --- a/crates/aios/aios-protocol/src/budget.rs +++ b/crates/aios/aios-protocol/src/budget.rs @@ -106,6 +106,10 @@ pub enum BudgetDecision { /// Implementations are expected to be cheap and pure (no I/O on the hot /// path). MVS default impl is `NoOpBudgetGate` (Phase 1, permits everything). /// `SessionBudgetGate` lands in Phase 4. `RcsLambdaBudgetGate` is Phase 6. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait BudgetGatePort: Send + Sync { /// Check whether a dispatch should proceed under `ctx` with the given diff --git a/crates/aios/aios-protocol/src/hypervisor.rs b/crates/aios/aios-protocol/src/hypervisor.rs index e93bff31..0af70945 100644 --- a/crates/aios/aios-protocol/src/hypervisor.rs +++ b/crates/aios/aios-protocol/src/hypervisor.rs @@ -395,6 +395,10 @@ pub enum BackendError { /// /// Uses `#[async_trait]` so the trait is dyn-compatible; callers typically /// hold `Arc` inside the kernel backend registry. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait HypervisorBackend: Send + Sync + 'static { /// Stable name used for routing + observability. Examples: `"local"`, `"cube"`, `"vercel"`. @@ -446,6 +450,10 @@ pub trait HypervisorBackend: Send + Sync + 'static { /// invoke a filesystem-dependent operation. Implementors MUST also advertise /// [`BackendCapabilitySet::FILESYSTEM_EXT`] from /// [`HypervisorBackend::capabilities`]. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait HypervisorFilesystemExt: HypervisorBackend { /// Write a batch of files into the VM's guest filesystem. diff --git a/crates/aios/aios-protocol/src/network_isolation.rs b/crates/aios/aios-protocol/src/network_isolation.rs index 78617a50..f9dfee78 100644 --- a/crates/aios/aios-protocol/src/network_isolation.rs +++ b/crates/aios/aios-protocol/src/network_isolation.rs @@ -55,6 +55,10 @@ pub enum EgressProtocol { /// MVS default impl is `NoOpNetworkIsolation` (Phase 1, logs but allows /// all). `AllowListNetworkIsolation` lands in Phase 4. /// `EbpfNetworkIsolation` (CubeVS pattern) is Phase 6. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait NetworkIsolationPort: Send + Sync { /// Apply a network policy to a VM. Typically called exactly once at VM diff --git a/crates/aios/aios-protocol/src/payment.rs b/crates/aios/aios-protocol/src/payment.rs index cdfcfa7e..1a107e4d 100644 --- a/crates/aios/aios-protocol/src/payment.rs +++ b/crates/aios/aios-protocol/src/payment.rs @@ -81,6 +81,10 @@ pub struct WalletBalanceInfo { /// Implementations: /// - `haima-x402`: x402 protocol (Coinbase/Cloudflare) /// - Future: MPP (Stripe/Tempo), direct fiat rails +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait PaymentPort: Send + Sync { /// Evaluate whether a payment should be authorized given current policy diff --git a/crates/aios/aios-protocol/src/ports.rs b/crates/aios/aios-protocol/src/ports.rs index 7c7b92c9..8a78494f 100644 --- a/crates/aios/aios-protocol/src/ports.rs +++ b/crates/aios/aios-protocol/src/ports.rs @@ -170,6 +170,10 @@ pub struct ApprovalResolution { pub resolved_at: DateTime, } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait EventStorePort: Send + Sync { async fn append(&self, event: EventRecord) -> KernelResult; @@ -189,16 +193,28 @@ pub trait EventStorePort: Send + Sync { ) -> KernelResult; } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait ModelProviderPort: Send + Sync { async fn complete(&self, request: ModelCompletionRequest) -> KernelResult; } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait ToolHarnessPort: Send + Sync { async fn execute(&self, request: ToolExecutionRequest) -> KernelResult; } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait PolicyGatePort: Send + Sync { async fn evaluate( @@ -216,6 +232,10 @@ pub trait PolicyGatePort: Send + Sync { } } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait ApprovalPort: Send + Sync { async fn enqueue(&self, request: ApprovalRequest) -> KernelResult; @@ -284,6 +304,10 @@ mod kernel_port { /// error), *not* the legacy [`crate::error::KernelResult`] used by /// the older ports (`EventStorePort`, `ModelProviderPort`, …). Those /// ports migrate in BRO-856. + #[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" + )] #[async_trait::async_trait] pub trait KernelPort: Send + Sync { /// Provision a new VM from `spec` under the attribution / budget @@ -347,6 +371,10 @@ use crate::session::{CreateSessionRequest, SessionFilter, SessionManifest, TickI /// Implementors provide create/get/list/tick/stream/close over the session tier. /// `arcand` is the reference implementation; `life-kernel-facade` consumes this /// trait through `Arc`. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait SessionPort: Send + Sync { async fn create(&self, req: CreateSessionRequest) -> KernelResult; @@ -383,6 +411,10 @@ use crate::memory::SoulProfile; /// Implementors provide soul-profile CRUD and belief-store access for an /// agent. `anima-core` is the reference implementation; `life-kernel-facade` /// consumes this trait through `Arc`. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait IdentityPort: Send + Sync { /// Fetch the current [`SoulProfile`] for `agent`. @@ -435,6 +467,10 @@ use crate::knowledge::{KnowledgeQuery, KnowledgeSearchResult, Note, NoteDraft, N /// Implementors provide full-text search, note CRUD, and graph traversal over /// the knowledge index. `lago-knowledge` is the reference implementation; /// `life-kernel-facade` consumes this trait through `Arc`. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait KnowledgePort: Send + Sync { async fn search(&self, query: KnowledgeQuery) -> KernelResult; @@ -448,6 +484,10 @@ pub trait KnowledgePort: Send + Sync { /// Implementors provide immutable put/get over SHA-256–addressed payloads. /// `lago-store` is the reference implementation; `life-kernel-facade` consumes /// this trait through `Arc`. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait BlobStorePort: Send + Sync { async fn put( @@ -463,6 +503,10 @@ pub trait BlobStorePort: Send + Sync { /// /// Implementors record usage events and synthesize invoices. `life-kernel-facade` /// consumes this trait through `Arc`. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait BillingPort: Send + Sync { async fn record_usage(&self, usage: UsageRecord) -> KernelResult<()>; @@ -496,6 +540,10 @@ use crate::homeostasis::{ /// /// Streaming projections are returned as a [`BoxStream`] so callers can /// consume them incrementally without holding a large in-memory buffer. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait HomeostasisPort: Send + Sync { /// Return the current three-pillar homeostatic snapshot for `session`. @@ -552,6 +600,10 @@ use crate::finance::{ /// `SettlementReceipt`. /// /// Authorization IDs correlate authorization ↔ receipt for audit. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait FinancePort: Send + Sync { /// Fetch the current wallet manifest (address, balance, policy) for `owner`. @@ -613,6 +665,10 @@ use crate::evaluation::{ /// Implementors provide rubric-based evaluation, heuristic scoring, and /// comparative judgement. `nousd` is the reference implementation; /// `life-kernel-facade` consumes this trait through `Arc`. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait EvaluationPort: Send + Sync { async fn evaluate(&self, req: EvaluationRequest) -> KernelResult; @@ -638,6 +694,10 @@ use crate::relay::{RelayFrame, RelayOpenRequest, RelaySession, RelayToken}; /// Implementors proxy web-based remote agent sessions from life-relayd. /// Facade implementations return `KernelError::Unimplemented` until v0.2 /// lights the proxies up (Phase 4). +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait RelayPort: Send + Sync { async fn open(&self, req: RelayOpenRequest) -> KernelResult; @@ -667,6 +727,10 @@ use crate::world::{WorldEvent, WorldId, WorldMutation, WorldSnapshot, WorldVersi /// Implementors provide snapshot queries, state mutations, and event streaming /// for a named world. `opsisd` is the reference implementation; /// `life-kernel-facade` consumes this trait through `Arc`. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait WorldPort: Send + Sync { /// Return the current state snapshot for `world`. diff --git a/crates/aios/aios-runtime/src/lib.rs b/crates/aios/aios-runtime/src/lib.rs index dcc3bbc3..c846f3b7 100644 --- a/crates/aios/aios-runtime/src/lib.rs +++ b/crates/aios/aios-runtime/src/lib.rs @@ -143,6 +143,10 @@ pub enum ToolCallGuardDecision { }, } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait ToolCallGuard: Send + Sync { async fn on_tool_call( @@ -152,6 +156,10 @@ pub trait ToolCallGuard: Send + Sync { ) -> Result; } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait TurnMiddleware: Send + Sync { async fn process(&self, ctx: &mut TurnContext, next: TurnNext<'_>) -> Result; @@ -380,6 +388,10 @@ pub struct WorkflowTickOutcome { /// by `arcan-ergon` (and any future workflow runtime) and registered /// on the [`KernelRuntime`] at construction time. See /// `core/life/docs/superpowers/specs/2026-05-08-bro-1001-ergon-tick-body.md`. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait WorkflowTickDispatcher: Send + Sync { /// Run a workflow as the body of a single tick. Errors propagate diff --git a/crates/aios/aios-sandbox/src/lib.rs b/crates/aios/aios-sandbox/src/lib.rs index b5bff24c..51cd2dce 100644 --- a/crates/aios/aios-sandbox/src/lib.rs +++ b/crates/aios/aios-sandbox/src/lib.rs @@ -46,6 +46,10 @@ pub struct SandboxExecution { pub timed_out: bool, } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait SandboxRunner: Send + Sync { async fn run(&self, request: SandboxRequest) -> Result; diff --git a/crates/anima/anima-identity/src/rotation.rs b/crates/anima/anima-identity/src/rotation.rs index 9e522526..54a176e1 100644 --- a/crates/anima/anima-identity/src/rotation.rs +++ b/crates/anima/anima-identity/src/rotation.rs @@ -67,6 +67,10 @@ pub struct RotationChainQuery<'a> { /// callers hold `&dyn JournalResolver` so the resolver can be swapped /// at runtime (e.g. between staging Vault-backed lago and a local /// fixture). +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait JournalResolver: Send + Sync { /// Return all `anima.identity_rotated` events that mention diff --git a/crates/arcan/arcan-aios-adapters/src/tools.rs b/crates/arcan/arcan-aios-adapters/src/tools.rs index 364f2102..90f16dba 100644 --- a/crates/arcan/arcan-aios-adapters/src/tools.rs +++ b/crates/arcan/arcan-aios-adapters/src/tools.rs @@ -28,6 +28,10 @@ pub struct RunCompletionContext { pub knowledge_top_relevance: Option, } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait ToolHarnessObserver: Send + Sync { async fn post_execute(&self, session_id: String, tool_name: String, is_error: bool); diff --git a/crates/arcan/arcan-ergon/src/registry.rs b/crates/arcan/arcan-ergon/src/registry.rs index 8000fc1c..e3f5b298 100644 --- a/crates/arcan/arcan-ergon/src/registry.rs +++ b/crates/arcan/arcan-ergon/src/registry.rs @@ -27,6 +27,10 @@ use std::sync::Arc; /// /// Implementers should not need to write this trait by hand — /// [`WorkflowRegistry::register`] wraps any `Workflow` automatically. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait BoxedWorkflowExecutor: Send + Sync { /// Stable workflow name (e.g. `"bookkeeping.promotion-judge"`). diff --git a/crates/arcan/arcan-sandbox/src/provider.rs b/crates/arcan/arcan-sandbox/src/provider.rs index e4de05e3..e0870aa8 100644 --- a/crates/arcan/arcan-sandbox/src/provider.rs +++ b/crates/arcan/arcan-sandbox/src/provider.rs @@ -55,6 +55,10 @@ use crate::types::{ since = "0.2.0", note = "use aios_protocol::HypervisorBackend — SandboxProvider is retained as a transitional alias" )] +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait SandboxProvider: Send + Sync + 'static { /// Stable, unique name used for config routing and observability labels. diff --git a/crates/arcan/arcan-tui/src/client.rs b/crates/arcan/arcan-tui/src/client.rs index 1826cb20..9e9b23c5 100644 --- a/crates/arcan/arcan-tui/src/client.rs +++ b/crates/arcan/arcan-tui/src/client.rs @@ -102,6 +102,10 @@ pub struct ProviderInfo { /// /// Implementations may use HTTP/SSE (daemon mode) or direct function calls /// (in-process mode). The TUI's `App` only sees this trait. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait AgentClientPort: Send + Sync + 'static { /// Submit a user message to start or continue a run. diff --git a/crates/chronos/chronos-core/src/agenda.rs b/crates/chronos/chronos-core/src/agenda.rs index c091dbbb..1ecd89e4 100644 --- a/crates/chronos/chronos-core/src/agenda.rs +++ b/crates/chronos/chronos-core/src/agenda.rs @@ -256,6 +256,10 @@ pub fn sort_for_dispatch(items: &mut [AgendaItem]) { /// across the daemon's HTTP handlers and wake loop. `#[async_trait]` boxes the returned futures /// for dyn-compatibility (the wake rate Chronos targets — ≤ 100/sec — makes the boxing cost /// negligible). +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait AgendaStore: Send + Sync { /// Add a new item to the agenda. Returns the freshly-minted id. diff --git a/crates/chronos/chronos-core/src/dispatch.rs b/crates/chronos/chronos-core/src/dispatch.rs index 2f0f4ed7..cc167648 100644 --- a/crates/chronos/chronos-core/src/dispatch.rs +++ b/crates/chronos/chronos-core/src/dispatch.rs @@ -50,6 +50,10 @@ impl DispatchOutcome { /// the session exists, builds a `TickInput { objective: intent, .. }`, calls /// `KernelRuntime::tick_on_branch(session, BranchId::main(), input)`, and folds the `TickOutput` /// into a [`DispatchOutcome`]. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait KernelDispatcher: Send + Sync { /// Run one agent tick for `session_id` driven by `intent` (the wake's objective). diff --git a/crates/chronos/chronos-core/src/trigger.rs b/crates/chronos/chronos-core/src/trigger.rs index 509a52d1..7ddc69df 100644 --- a/crates/chronos/chronos-core/src/trigger.rs +++ b/crates/chronos/chronos-core/src/trigger.rs @@ -16,6 +16,10 @@ use crate::WakeEvent; /// /// `#[async_trait::async_trait]` boxes the future, which makes `Box` work. /// The boxing overhead is negligible for the wake rate Chronos expects (≤ 100/sec system-wide). +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait::async_trait] pub trait WakeTrigger: Send { /// Pull the next wake event from this trigger. diff --git a/crates/cli/life-cli/src/deploy/backend.rs b/crates/cli/life-cli/src/deploy/backend.rs index 25cca053..be9f4396 100644 --- a/crates/cli/life-cli/src/deploy/backend.rs +++ b/crates/cli/life-cli/src/deploy/backend.rs @@ -34,6 +34,10 @@ pub struct DeploymentResult { /// /// Implementations handle the specifics of provisioning, monitoring, and /// tearing down agent stacks on different cloud providers. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait DeployBackend: Send + Sync { /// Deploy an agent template to the cloud target. diff --git a/crates/ergon/ergon-anima-adapter/src/lib.rs b/crates/ergon/ergon-anima-adapter/src/lib.rs index b2bc38ab..8e9b55bf 100644 --- a/crates/ergon/ergon-anima-adapter/src/lib.rs +++ b/crates/ergon/ergon-anima-adapter/src/lib.rs @@ -29,6 +29,10 @@ use serde_json::Value; /// (`SoulAttester`) to per-step receipts. The receipt body shape is /// canonical-JSON per ADR §4; the returned string is the compact JWS /// (`
..`) signed by the agent's custody key. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait AgentAttestationSigner: Send + Sync { /// Sign a step receipt. The receipt is opaque to this trait — the diff --git a/crates/ergon/ergon-life-hooks/src/attestation.rs b/crates/ergon/ergon-life-hooks/src/attestation.rs index 083c22f4..de3edae4 100644 --- a/crates/ergon/ergon-life-hooks/src/attestation.rs +++ b/crates/ergon/ergon-life-hooks/src/attestation.rs @@ -33,6 +33,10 @@ use std::sync::Arc; /// emits the signed event onto the lago journal. /// /// Errors are non-fatal — see module docs. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait SoulAttester: Send + Sync { /// Sign a `SessionStart`-equivalent event for the given session. diff --git a/crates/ergon/ergon-life-hooks/src/budget.rs b/crates/ergon/ergon-life-hooks/src/budget.rs index 98ee3883..46c95d8e 100644 --- a/crates/ergon/ergon-life-hooks/src/budget.rs +++ b/crates/ergon/ergon-life-hooks/src/budget.rs @@ -25,6 +25,10 @@ use std::sync::Arc; /// for example, downgrading `max_tokens` when the budget is tight, or /// stripping expensive tools — and return `Continue`. The hook re-checks /// after potential mutation. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait BudgetGate: Send + Sync { /// Decide whether the given inference call is allowed. diff --git a/crates/ergon/ergon-life-hooks/src/capability.rs b/crates/ergon/ergon-life-hooks/src/capability.rs index 6f0cd356..00b59cc6 100644 --- a/crates/ergon/ergon-life-hooks/src/capability.rs +++ b/crates/ergon/ergon-life-hooks/src/capability.rs @@ -21,6 +21,10 @@ use std::sync::Arc; /// The trait is **deliberately small** — one async method. Substrate /// integration (PolicySet evaluation, capability glob matching, etc.) /// happens behind this seam, not in this crate. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait CapabilityResolver: Send + Sync { /// Decide whether the given tool invocation is allowed. diff --git a/crates/ergon/ergon-life-hooks/src/score.rs b/crates/ergon/ergon-life-hooks/src/score.rs index 9e08641c..16e778d8 100644 --- a/crates/ergon/ergon-life-hooks/src/score.rs +++ b/crates/ergon/ergon-life-hooks/src/score.rs @@ -26,6 +26,10 @@ use std::sync::Arc; /// `nous_core::NousEvaluator`. The returned JSON value is the canonical /// score representation (e.g. `{"novelty": 2, "specificity": 3, /// "relevance": 3, "total": 8}`); ergon does not impose a schema. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait ResponseScorer: Send + Sync { /// Score the response. Errors are non-fatal; the hook records the diff --git a/crates/ergon/ergon/src/agent.rs b/crates/ergon/ergon/src/agent.rs index f2d58a2c..c7ee2e4e 100644 --- a/crates/ergon/ergon/src/agent.rs +++ b/crates/ergon/ergon/src/agent.rs @@ -264,6 +264,10 @@ impl AgentSpec { /// prefer `TypedAgent` for static cases or `AgentSpec` for dynamic /// cases. Implementing `Agent` directly is reserved for advanced /// patterns like recording wrappers, remote-dispatch shims, etc. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait Agent: Send + Sync { /// The (possibly-derived) spec for this agent. Cheap to call — diff --git a/crates/ergon/ergon/src/agent_registry.rs b/crates/ergon/ergon/src/agent_registry.rs index 2164e9de..225ad6e5 100644 --- a/crates/ergon/ergon/src/agent_registry.rs +++ b/crates/ergon/ergon/src/agent_registry.rs @@ -68,6 +68,10 @@ use crate::error::ErgonError; /// Hosts can compose multiple registries via [`ChainedAgentRegistry`]: /// authored MD files take precedence over experimental lago entries, /// or vice versa, depending on the deployment's policy. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait AgentRegistry: Send + Sync { /// Resolve an agent by name. Returns `None` if no agent is diff --git a/crates/ergon/ergon/src/hook.rs b/crates/ergon/ergon/src/hook.rs index ea6508a8..be7fa7c9 100644 --- a/crates/ergon/ergon/src/hook.rs +++ b/crates/ergon/ergon/src/hook.rs @@ -129,6 +129,10 @@ pub enum InferenceHookOutcome { /// returning [`HookOutcome::Continue`]. [`Self::on_post_tool_use`] receives /// `&mut ToolResult` so post-processing hooks can transform results before /// they reach the model. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait Hook: Send + Sync { /// Stable, human-readable name of this hook (used in error messages diff --git a/crates/ergon/ergon/src/runtime.rs b/crates/ergon/ergon/src/runtime.rs index e3ef0c34..667ee7bc 100644 --- a/crates/ergon/ergon/src/runtime.rs +++ b/crates/ergon/ergon/src/runtime.rs @@ -64,6 +64,10 @@ use std::sync::Arc; /// `arcan_provider::Provider` and translates its events to ergon's /// [`crate::StreamEvent`] taxonomy. In tests: see the mock impl in /// `step.rs` `tests` module. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait Provider: Send + Sync { /// Stable, human-readable name of the provider (used in tracing, @@ -106,6 +110,10 @@ pub trait Provider: Send + Sync { /// In production: a `PraxisToolRegistryAdapter` (BRO-1001) wraps /// `praxis_core::ToolRegistry` and bakes a `SandboxPolicy` in at /// construction. In tests: see the mock impl in `step.rs` `tests` module. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait ToolRegistry: Send + Sync { /// JSON-Schema-backed tool definitions advertised to the model. diff --git a/crates/ergon/ergon/src/step.rs b/crates/ergon/ergon/src/step.rs index e4f6dacc..1de13952 100644 --- a/crates/ergon/ergon/src/step.rs +++ b/crates/ergon/ergon/src/step.rs @@ -139,6 +139,10 @@ impl InferenceRequest { /// Step lifecycle hooks ([`crate::Hook::on_step_start`], /// [`crate::Hook::on_step_end`]) fire automatically when a step runs /// via [`StepCtx::step`]. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait Step: Send + Sync { /// Typed input. diff --git a/crates/ergon/ergon/src/stream.rs b/crates/ergon/ergon/src/stream.rs index f7ee7c31..bb92385a 100644 --- a/crates/ergon/ergon/src/stream.rs +++ b/crates/ergon/ergon/src/stream.rs @@ -151,6 +151,10 @@ pub enum StreamEvent { /// Sinks that buffer (mpsc-style) propagate backpressure by awaiting on /// their internal channel. The autonomous loop awaits each `emit` call /// in turn, so a slow sink throttles the upstream provider naturally. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait StreamSink: Send + Sync { /// Forward a single stream event. Returns an error if the sink can no diff --git a/crates/ergon/ergon/src/workflow.rs b/crates/ergon/ergon/src/workflow.rs index 32479909..1462becf 100644 --- a/crates/ergon/ergon/src/workflow.rs +++ b/crates/ergon/ergon/src/workflow.rs @@ -110,6 +110,10 @@ pub use praxis_skills_stub::{EmptySkillSet, SkillSet}; /// that consume skills override this. /// - The workflow does NOT supply tools, sandbox, or providers — those /// come from the [`StepCtx`] the host runtime hands to `execute`. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait Workflow: Send + Sync + 'static { /// Typed input. Must round-trip through JSON (the host runtime diff --git a/crates/haima/haima-outcome/src/verifier.rs b/crates/haima/haima-outcome/src/verifier.rs index 0c5301cb..77c7270d 100644 --- a/crates/haima/haima-outcome/src/verifier.rs +++ b/crates/haima/haima-outcome/src/verifier.rs @@ -17,6 +17,10 @@ use serde::{Deserialize, Serialize}; /// A pluggable verifier that checks whether a single success criterion has been met. /// /// Implementations must be `Send + Sync` so they can be used across async tasks. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait SuccessVerifier: Send + Sync { /// Human-readable name for this verifier (e.g., "`tests_passed`", "webhook"). diff --git a/crates/haima/haima-wallet/src/backend.rs b/crates/haima/haima-wallet/src/backend.rs index ca755385..86b7d457 100644 --- a/crates/haima/haima-wallet/src/backend.rs +++ b/crates/haima/haima-wallet/src/backend.rs @@ -8,6 +8,10 @@ use haima_core::{HaimaResult, WalletAddress}; /// Local wallets sign directly with a private key. /// MPC wallets delegate signing to a remote service (e.g., Coinbase CDP). /// This trait unifies both behind a single interface. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait WalletBackend: Send + Sync { /// Get the wallet's on-chain address. diff --git a/crates/life-kernel/life-kernel-conformance/src/lib.rs b/crates/life-kernel/life-kernel-conformance/src/lib.rs index 21afbb81..256f861d 100644 --- a/crates/life-kernel/life-kernel-conformance/src/lib.rs +++ b/crates/life-kernel/life-kernel-conformance/src/lib.rs @@ -66,6 +66,10 @@ pub trait CapturingEventStore: EventStorePort { /// trail without going through the `KernelPort` trait. Implementations /// are expected to return a *fresh* engine + store on every call — /// scenarios assume an empty journal at construction time. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait ConformanceHarness: Send + Sync { /// Build a fresh engine + capturing store pair. diff --git a/crates/life-perturb/src/injector.rs b/crates/life-perturb/src/injector.rs index 4c7268e5..ec061906 100644 --- a/crates/life-perturb/src/injector.rs +++ b/crates/life-perturb/src/injector.rs @@ -36,6 +36,10 @@ impl PerturbationHandle { /// One implementation per level. Concrete injectors live in this crate as /// stubs and will be filled in by the per-level workstreams (v0.1 → v1.0). +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait Injector: Send + Sync { /// The hierarchy level this injector targets. diff --git a/crates/life-runtime/anima-proxy/src/client.rs b/crates/life-runtime/anima-proxy/src/client.rs index c76b130a..c27af368 100644 --- a/crates/life-runtime/anima-proxy/src/client.rs +++ b/crates/life-runtime/anima-proxy/src/client.rs @@ -354,6 +354,10 @@ fn session_from_proto(s: anima_pb::SessionDescriptor) -> SessionDescriptor { } } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait AnimaCall: Send + Sync { async fn register_session(&self, sid: &str, user_id: &str) -> AnimaProxyResult<()>; diff --git a/crates/life-runtime/arcan-proxy/src/client.rs b/crates/life-runtime/arcan-proxy/src/client.rs index 13851c67..dcf96613 100644 --- a/crates/life-runtime/arcan-proxy/src/client.rs +++ b/crates/life-runtime/arcan-proxy/src/client.rs @@ -307,6 +307,10 @@ fn record_outcome(guard: Option, success_or_permanent: bool) { /// the event journal and filesystem manifest. HTTP-backed impls /// (`VercelAiGatewayArcan`, `AnthropicArcan`) have no branch concept on /// the raw provider wire and ignore it; mocks accept and ignore it. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait ArcanCall: Send + Sync { async fn create_agent(&self, sid: &str) -> ArcanProxyResult; diff --git a/crates/life-runtime/haima-proxy/src/client.rs b/crates/life-runtime/haima-proxy/src/client.rs index 4e324e7b..c6890ff2 100644 --- a/crates/life-runtime/haima-proxy/src/client.rs +++ b/crates/life-runtime/haima-proxy/src/client.rs @@ -408,6 +408,10 @@ fn record_outcome(guard: Option, success_or_permanent: bool) { } } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait HaimaCall: Send + Sync { async fn bind_wallet(&self, sid: &str, project_id: &str) -> HaimaProxyResult; diff --git a/crates/life-runtime/lago-proxy/src/client.rs b/crates/life-runtime/lago-proxy/src/client.rs index e29510b5..3b2d8377 100644 --- a/crates/life-runtime/lago-proxy/src/client.rs +++ b/crates/life-runtime/lago-proxy/src/client.rs @@ -261,6 +261,10 @@ fn record_outcome(guard: Option, status: &tonic::Status) { } } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait LagoCall: Send + Sync { async fn open_namespace(&self, sid: &str) -> LagoProxyResult; diff --git a/crates/life-runtime/lifed-conformance/src/lib.rs b/crates/life-runtime/lifed-conformance/src/lib.rs index 32192ce8..8261b78f 100644 --- a/crates/life-runtime/lifed-conformance/src/lib.rs +++ b/crates/life-runtime/lifed-conformance/src/lib.rs @@ -33,6 +33,10 @@ pub struct VerificationCase { pub should_pass: bool, } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait SubstrateUnderTest: Send + Sync { fn audience(&self) -> &'static str; diff --git a/crates/life-runtime/lifed/src/idempotency/mod.rs b/crates/life-runtime/lifed/src/idempotency/mod.rs index 0e1ece01..6569a68f 100644 --- a/crates/life-runtime/lifed/src/idempotency/mod.rs +++ b/crates/life-runtime/lifed/src/idempotency/mod.rs @@ -35,6 +35,10 @@ impl IdemKey { } } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait IdempotencyStore: Send + Sync { async fn lookup(&self, key: &IdemKey) -> Result>, tonic::Status>; diff --git a/crates/life-runtime/lifed/src/route/ergon.rs b/crates/life-runtime/lifed/src/route/ergon.rs index c8f36ca5..02f86511 100644 --- a/crates/life-runtime/lifed/src/route/ergon.rs +++ b/crates/life-runtime/lifed/src/route/ergon.rs @@ -149,6 +149,10 @@ pub struct StreamSessionRequest { /// The substrate-side implementation (in arcan-ergon, out of tree) wraps /// each concrete `ergon::Workflow` and returns the JSON-in / stream-out /// surface this trait exposes. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait ErgonWorkflowHandle: Send + Sync { /// Stable workflow name. Used in tracing spans + the diff --git a/crates/life-runtime/lifed/src/saga/driver.rs b/crates/life-runtime/lifed/src/saga/driver.rs index f68e4cfa..422b0a86 100644 --- a/crates/life-runtime/lifed/src/saga/driver.rs +++ b/crates/life-runtime/lifed/src/saga/driver.rs @@ -67,6 +67,10 @@ pub struct SagaCtx { pub claims: CapabilityClaims, } +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait SagaStep: Send + Sync { async fn forward(&self, ctx: &SagaCtx) -> Result<(), SagaError>; @@ -78,6 +82,10 @@ pub trait SagaStep: Send + Sync { /// requires every saga state transition lands in /// `system/lifed/saga/`. We expose a small trait so the saga /// driver doesn't take a hard dependency on `LagoCall`. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait SagaJournal: Send + Sync { /// Append one saga lifecycle event. Errors are logged by the caller diff --git a/crates/life-runtime/lifegw/src/services/anthropic_messages.rs b/crates/life-runtime/lifegw/src/services/anthropic_messages.rs index 0a5911ff..6bed40e8 100644 --- a/crates/life-runtime/lifegw/src/services/anthropic_messages.rs +++ b/crates/life-runtime/lifegw/src/services/anthropic_messages.rs @@ -180,6 +180,10 @@ const X402_AMOUNT_USD_DEFAULT: &str = "0.10"; /// /// `Send + Sync + 'static` so the trait is dyn-callable from inside /// the per-request handler. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait::async_trait] pub trait HaimaClient: Send + Sync + 'static { /// Pre-call gate. `estimated_cost_micros` is the worst-case spend diff --git a/crates/nous/nous-tools/src/lineage.rs b/crates/nous/nous-tools/src/lineage.rs index bf92e7d8..d0ba1d25 100644 --- a/crates/nous/nous-tools/src/lineage.rs +++ b/crates/nous/nous-tools/src/lineage.rs @@ -130,6 +130,10 @@ impl LineageFilter { /// /// Implementations must preserve insertion order on read — downstream /// promoters rely on chronological iteration to detect drift. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait] pub trait NousLineage: Send + Sync { /// Record a single scoring/judging event with its full provenance. diff --git a/crates/relay/life-relayd/src/adapters/mod.rs b/crates/relay/life-relayd/src/adapters/mod.rs index a886dd49..1b44bf26 100644 --- a/crates/relay/life-relayd/src/adapters/mod.rs +++ b/crates/relay/life-relayd/src/adapters/mod.rs @@ -11,6 +11,10 @@ use uuid::Uuid; /// /// Implementations manage a collection of live sessions internally. /// Output is streamed to the provided `event_tx` channel during `spawn`. +#[allow( + clippy::double_must_use, + reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" +)] #[async_trait::async_trait] pub trait SessionAdapter: Send + Sync { /// Spawn a new session. Returns session info. diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..f6efce51 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,18 @@ +# BRO-2814: pin the toolchain CI and local dev both resolve to. +# +# Before this file existed, every CI job used `dtolnay/rust-toolchain@stable`, +# which floats to whatever is current `stable` on the day the job runs. main +# went red with no code change in between: `stable` moved from rustc 1.93.0 +# to 1.99.0 and a new clippy lint pass started flagging every +# `#[async_trait]`-annotated trait as `clippy::double_must_use`. Pinning here +# makes that kind of drift a deliberate, reviewed bump (edit this file, see +# what breaks, fix it in the same PR) instead of a silent one that only shows +# up when Dependabot or a push happens to land that week. +# +# Bump deliberately: update `channel`, run `cargo fmt && cargo clippy +# --workspace -- -D warnings -A clippy::too_many_arguments && cargo test +# --workspace` locally, fix whatever the new toolchain flags, then commit +# both together. +[toolchain] +channel = "1.99.0" +components = ["rustfmt", "clippy"] From 268f25b1c9fda3365284a17c493e41b0820ff634 Mon Sep 17 00:00:00 2001 From: "Carlos D. Escobar-Valbuena" Date: Sun, 4 Oct 2026 08:36:09 -0500 Subject: [PATCH 2/4] fix(ci): pass explicit toolchain to dtolnay/rust-toolchain@master MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @master requires a `toolchain` input — it does not read rust-toolchain.toml on its own (confirmed by the PR's own CI: every job switched to @master in the previous commit failed in <20s with "'toolchain' is a required input"). Pass toolchain: "1.99.0" explicitly everywhere, matching rust-toolchain.toml's pin; MSRV Check keeps its own "1.93.0". Co-Authored-By: Claude Sonnet 5 --- .github/workflows/ci.yml | 19 +++++++++++++++++++ .github/workflows/harness.yml | 1 + 2 files changed, 20 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9da621c3..83e69410 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,7 @@ jobs: - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@master with: + toolchain: "1.99.0" components: rustfmt - run: cargo fmt --all -- --check @@ -60,6 +61,7 @@ jobs: run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - uses: dtolnay/rust-toolchain@master with: + toolchain: "1.99.0" components: clippy - uses: Swatinem/rust-cache@v2 - run: cargo clippy --workspace -- -D warnings -A clippy::too_many_arguments @@ -98,6 +100,8 @@ jobs: - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - uses: dtolnay/rust-toolchain@master + with: + toolchain: "1.99.0" - uses: Swatinem/rust-cache@v2 with: prefix-key: v1-rust @@ -127,6 +131,8 @@ jobs: - name: Install protoc run: brew install protobuf - uses: dtolnay/rust-toolchain@master + with: + toolchain: "1.99.0" - uses: Swatinem/rust-cache@v2 - run: cargo test --workspace @@ -163,6 +169,8 @@ jobs: steps: - uses: actions/checkout@v7 - uses: dtolnay/rust-toolchain@master + with: + toolchain: "1.99.0" - uses: Swatinem/rust-cache@v2 - run: cargo install cargo-deny --locked - run: cargo deny check @@ -176,6 +184,8 @@ jobs: - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - uses: dtolnay/rust-toolchain@master + with: + toolchain: "1.99.0" - uses: Swatinem/rust-cache@v2 - name: Run scripts/verify_dependencies_lifed.sh run: bash scripts/verify_dependencies_lifed.sh @@ -189,6 +199,8 @@ jobs: - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - uses: dtolnay/rust-toolchain@master + with: + toolchain: "1.99.0" - uses: Swatinem/rust-cache@v2 - name: Run scripts/verify_dependencies_lifegw.sh run: bash scripts/verify_dependencies_lifegw.sh @@ -202,6 +214,8 @@ jobs: - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - uses: dtolnay/rust-toolchain@master + with: + toolchain: "1.99.0" - uses: Swatinem/rust-cache@v2 - name: Run scripts/verify_dependencies_lifegw_anthropic_codec.sh run: bash scripts/verify_dependencies_lifegw_anthropic_codec.sh @@ -223,6 +237,8 @@ jobs: - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - uses: dtolnay/rust-toolchain@master + with: + toolchain: "1.99.0" - uses: Swatinem/rust-cache@v2 - name: Self-test (regression guard for FAIL-path detection) run: bash scripts/verify_dependencies_ergon.sh --self-test @@ -253,6 +269,7 @@ jobs: run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - uses: dtolnay/rust-toolchain@master with: + toolchain: "1.99.0" components: rustfmt, clippy - uses: Swatinem/rust-cache@v2 - name: Format check (ergon) @@ -352,6 +369,8 @@ jobs: - name: Install protoc run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - uses: dtolnay/rust-toolchain@master + with: + toolchain: "1.99.0" - uses: oven-sh/setup-bun@v2 with: bun-version: latest diff --git a/.github/workflows/harness.yml b/.github/workflows/harness.yml index 43163175..fb1dd0f0 100644 --- a/.github/workflows/harness.yml +++ b/.github/workflows/harness.yml @@ -66,6 +66,7 @@ jobs: run: sudo apt-get update && sudo apt-get install -y protobuf-compiler - uses: dtolnay/rust-toolchain@master with: + toolchain: "1.99.0" components: rustfmt, clippy - uses: Swatinem/rust-cache@v2 with: From 84b740663fe81cdd6a85a2a7ab99493d8fb2161d Mon Sep 17 00:00:00 2001 From: "Carlos D. Escobar-Valbuena" Date: Sun, 4 Oct 2026 08:42:25 -0500 Subject: [PATCH 3/4] fix(ci): allow clippy::all on two generated-proto modules missing the existing convention CI's Lint job still failed after the previous commit, this time in lago-ingest (3 more double_must_use errors, same async_trait-in- generated-tonic-code root cause as BRO-2814, just inside the include_proto! output this time instead of hand-written source). Every other tonic::include_proto! module in the workspace already carries `#[allow(unused_qualifications, clippy::all)]` (aios-proto, anima/haima/arcan-substrate-proto, life-kernel-proto, ...) specifically because generated code isn't something we hand-tune for clippy. lago-ingest and spaces-a2a were the two that never got it. Bringing them in line with the rest of the codebase, not inventing a new pattern. Co-Authored-By: Claude Sonnet 5 --- crates/lago/lago-ingest/src/lib.rs | 1 + crates/spaces-a2a/spaces-a2a/src/grpc.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/crates/lago/lago-ingest/src/lib.rs b/crates/lago/lago-ingest/src/lib.rs index 4b606e3f..23559314 100644 --- a/crates/lago/lago-ingest/src/lib.rs +++ b/crates/lago/lago-ingest/src/lib.rs @@ -3,6 +3,7 @@ pub mod codec; pub mod server; /// Generated protobuf types. +#[allow(unused_qualifications, clippy::all)] pub mod proto { tonic::include_proto!("lago.v1"); } diff --git a/crates/spaces-a2a/spaces-a2a/src/grpc.rs b/crates/spaces-a2a/spaces-a2a/src/grpc.rs index 9f77d3c8..c4956a59 100644 --- a/crates/spaces-a2a/spaces-a2a/src/grpc.rs +++ b/crates/spaces-a2a/spaces-a2a/src/grpc.rs @@ -8,6 +8,7 @@ use crate::types::{MessagePart, TaskMessage}; use std::sync::Arc; use tonic::{Request, Response, Status}; +#[allow(unused_qualifications, clippy::all)] pub mod pb { tonic::include_proto!("a2a.v1"); } From 6d0a16c3576113d0990719d6ad518e705f9bc6b5 Mon Sep 17 00:00:00 2001 From: "Carlos D. Escobar-Valbuena" Date: Sun, 4 Oct 2026 09:05:47 -0500 Subject: [PATCH 4/4] refactor(ci): hoist double_must_use allow to workspace.lints.clippy (BRO-2814) P20 review (strata B+C) on the previous commits flagged that hand-pasting the same #[allow(clippy::double_must_use, reason = "...")] onto 63 trait definitions across 43 files is a maintenance trap: the next #[async_trait] trait anyone adds won't carry it and will silently fail CI again. The repo already has the right mechanism for exactly this (`[workspace.lints.clippy] too_many_arguments = "allow"`, opted into by `[lints] workspace = true` in 41 of the 43 touched crates) -- one line there covers every current AND future #[async_trait] trait workspace-wide, so use it instead of 63 copies of the same 4 lines. arcan-tui and life-cli don't opt into workspace lints yet, so they keep their local #[allow(...)] (now the only two). Verified clean with the real pinned toolchain this time (rustup run 1.99.0 cargo clippy --workspace --all-targets -- -D warnings -A clippy::too_many_arguments), not just the stale local one. Co-Authored-By: Claude Sonnet 5 --- Cargo.toml | 8 +++ crates/aios/aios-events/src/lib.rs | 4 -- crates/aios/aios-policy/src/lib.rs | 4 -- crates/aios/aios-protocol/src/budget.rs | 4 -- crates/aios/aios-protocol/src/hypervisor.rs | 8 --- .../aios-protocol/src/network_isolation.rs | 4 -- crates/aios/aios-protocol/src/payment.rs | 4 -- crates/aios/aios-protocol/src/ports.rs | 64 ------------------- crates/aios/aios-runtime/src/lib.rs | 12 ---- crates/aios/aios-sandbox/src/lib.rs | 4 -- crates/anima/anima-identity/src/rotation.rs | 4 -- crates/arcan/arcan-aios-adapters/src/tools.rs | 4 -- crates/arcan/arcan-ergon/src/registry.rs | 4 -- crates/arcan/arcan-sandbox/src/provider.rs | 4 -- crates/chronos/chronos-core/src/agenda.rs | 4 -- crates/chronos/chronos-core/src/dispatch.rs | 4 -- crates/chronos/chronos-core/src/trigger.rs | 4 -- crates/ergon/ergon-anima-adapter/src/lib.rs | 4 -- .../ergon/ergon-life-hooks/src/attestation.rs | 4 -- crates/ergon/ergon-life-hooks/src/budget.rs | 4 -- .../ergon/ergon-life-hooks/src/capability.rs | 4 -- crates/ergon/ergon-life-hooks/src/score.rs | 4 -- crates/ergon/ergon/src/agent.rs | 4 -- crates/ergon/ergon/src/agent_registry.rs | 4 -- crates/ergon/ergon/src/hook.rs | 4 -- crates/ergon/ergon/src/runtime.rs | 8 --- crates/ergon/ergon/src/step.rs | 4 -- crates/ergon/ergon/src/stream.rs | 4 -- crates/ergon/ergon/src/workflow.rs | 4 -- crates/haima/haima-outcome/src/verifier.rs | 4 -- crates/haima/haima-wallet/src/backend.rs | 4 -- .../life-kernel-conformance/src/lib.rs | 4 -- crates/life-perturb/src/injector.rs | 4 -- crates/life-runtime/anima-proxy/src/client.rs | 4 -- crates/life-runtime/arcan-proxy/src/client.rs | 4 -- crates/life-runtime/haima-proxy/src/client.rs | 4 -- crates/life-runtime/lago-proxy/src/client.rs | 4 -- .../life-runtime/lifed-conformance/src/lib.rs | 4 -- .../life-runtime/lifed/src/idempotency/mod.rs | 4 -- crates/life-runtime/lifed/src/route/ergon.rs | 4 -- crates/life-runtime/lifed/src/saga/driver.rs | 8 --- .../lifegw/src/services/anthropic_messages.rs | 4 -- crates/nous/nous-tools/src/lineage.rs | 4 -- crates/relay/life-relayd/src/adapters/mod.rs | 4 -- 44 files changed, 8 insertions(+), 252 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d0e55b62..f8990fe4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -417,6 +417,14 @@ gray_matter = { version = "0.2", default-features = false, features = ["yaml"] } [workspace.lints.clippy] too_many_arguments = "allow" +# BRO-2814: async_trait's generated methods return a boxed `dyn Future`, +# which clippy (since the stable->1.99.0 bump) treats as already +# #[must_use]; the #[must_use] async_trait also stamps on top then reads +# as redundant. Not a bug in any of the ~60 `#[async_trait]` port traits +# this flags across the workspace — a known async-trait/clippy +# interaction. Two crates that predate `[lints] workspace = true` +# (arcan-tui, life-cli) carry a local #[allow(...)] instead. +double_must_use = "allow" [profile.release] lto = "thin" diff --git a/crates/aios/aios-events/src/lib.rs b/crates/aios/aios-events/src/lib.rs index b00029e0..be348657 100644 --- a/crates/aios/aios-events/src/lib.rs +++ b/crates/aios/aios-events/src/lib.rs @@ -18,10 +18,6 @@ fn to_kernel_error(error: anyhow::Error) -> KernelError { KernelError::Runtime(error.to_string()) } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait EventStore: Send + Sync { async fn append(&self, event: &EventRecord) -> Result<()>; diff --git a/crates/aios/aios-policy/src/lib.rs b/crates/aios/aios-policy/src/lib.rs index 37a5790f..c5a3e94f 100644 --- a/crates/aios/aios-policy/src/lib.rs +++ b/crates/aios/aios-policy/src/lib.rs @@ -42,10 +42,6 @@ pub struct ApprovalResolution { pub actor: String, } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait PolicyEngine: Send + Sync { async fn evaluate_capabilities( diff --git a/crates/aios/aios-protocol/src/budget.rs b/crates/aios/aios-protocol/src/budget.rs index a048fa0f..9779910a 100644 --- a/crates/aios/aios-protocol/src/budget.rs +++ b/crates/aios/aios-protocol/src/budget.rs @@ -106,10 +106,6 @@ pub enum BudgetDecision { /// Implementations are expected to be cheap and pure (no I/O on the hot /// path). MVS default impl is `NoOpBudgetGate` (Phase 1, permits everything). /// `SessionBudgetGate` lands in Phase 4. `RcsLambdaBudgetGate` is Phase 6. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait BudgetGatePort: Send + Sync { /// Check whether a dispatch should proceed under `ctx` with the given diff --git a/crates/aios/aios-protocol/src/hypervisor.rs b/crates/aios/aios-protocol/src/hypervisor.rs index 0af70945..e93bff31 100644 --- a/crates/aios/aios-protocol/src/hypervisor.rs +++ b/crates/aios/aios-protocol/src/hypervisor.rs @@ -395,10 +395,6 @@ pub enum BackendError { /// /// Uses `#[async_trait]` so the trait is dyn-compatible; callers typically /// hold `Arc` inside the kernel backend registry. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait HypervisorBackend: Send + Sync + 'static { /// Stable name used for routing + observability. Examples: `"local"`, `"cube"`, `"vercel"`. @@ -450,10 +446,6 @@ pub trait HypervisorBackend: Send + Sync + 'static { /// invoke a filesystem-dependent operation. Implementors MUST also advertise /// [`BackendCapabilitySet::FILESYSTEM_EXT`] from /// [`HypervisorBackend::capabilities`]. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait HypervisorFilesystemExt: HypervisorBackend { /// Write a batch of files into the VM's guest filesystem. diff --git a/crates/aios/aios-protocol/src/network_isolation.rs b/crates/aios/aios-protocol/src/network_isolation.rs index f9dfee78..78617a50 100644 --- a/crates/aios/aios-protocol/src/network_isolation.rs +++ b/crates/aios/aios-protocol/src/network_isolation.rs @@ -55,10 +55,6 @@ pub enum EgressProtocol { /// MVS default impl is `NoOpNetworkIsolation` (Phase 1, logs but allows /// all). `AllowListNetworkIsolation` lands in Phase 4. /// `EbpfNetworkIsolation` (CubeVS pattern) is Phase 6. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait NetworkIsolationPort: Send + Sync { /// Apply a network policy to a VM. Typically called exactly once at VM diff --git a/crates/aios/aios-protocol/src/payment.rs b/crates/aios/aios-protocol/src/payment.rs index 1a107e4d..cdfcfa7e 100644 --- a/crates/aios/aios-protocol/src/payment.rs +++ b/crates/aios/aios-protocol/src/payment.rs @@ -81,10 +81,6 @@ pub struct WalletBalanceInfo { /// Implementations: /// - `haima-x402`: x402 protocol (Coinbase/Cloudflare) /// - Future: MPP (Stripe/Tempo), direct fiat rails -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait PaymentPort: Send + Sync { /// Evaluate whether a payment should be authorized given current policy diff --git a/crates/aios/aios-protocol/src/ports.rs b/crates/aios/aios-protocol/src/ports.rs index 8a78494f..7c7b92c9 100644 --- a/crates/aios/aios-protocol/src/ports.rs +++ b/crates/aios/aios-protocol/src/ports.rs @@ -170,10 +170,6 @@ pub struct ApprovalResolution { pub resolved_at: DateTime, } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait EventStorePort: Send + Sync { async fn append(&self, event: EventRecord) -> KernelResult; @@ -193,28 +189,16 @@ pub trait EventStorePort: Send + Sync { ) -> KernelResult; } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait ModelProviderPort: Send + Sync { async fn complete(&self, request: ModelCompletionRequest) -> KernelResult; } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait ToolHarnessPort: Send + Sync { async fn execute(&self, request: ToolExecutionRequest) -> KernelResult; } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait PolicyGatePort: Send + Sync { async fn evaluate( @@ -232,10 +216,6 @@ pub trait PolicyGatePort: Send + Sync { } } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait ApprovalPort: Send + Sync { async fn enqueue(&self, request: ApprovalRequest) -> KernelResult; @@ -304,10 +284,6 @@ mod kernel_port { /// error), *not* the legacy [`crate::error::KernelResult`] used by /// the older ports (`EventStorePort`, `ModelProviderPort`, …). Those /// ports migrate in BRO-856. - #[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" - )] #[async_trait::async_trait] pub trait KernelPort: Send + Sync { /// Provision a new VM from `spec` under the attribution / budget @@ -371,10 +347,6 @@ use crate::session::{CreateSessionRequest, SessionFilter, SessionManifest, TickI /// Implementors provide create/get/list/tick/stream/close over the session tier. /// `arcand` is the reference implementation; `life-kernel-facade` consumes this /// trait through `Arc`. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait SessionPort: Send + Sync { async fn create(&self, req: CreateSessionRequest) -> KernelResult; @@ -411,10 +383,6 @@ use crate::memory::SoulProfile; /// Implementors provide soul-profile CRUD and belief-store access for an /// agent. `anima-core` is the reference implementation; `life-kernel-facade` /// consumes this trait through `Arc`. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait IdentityPort: Send + Sync { /// Fetch the current [`SoulProfile`] for `agent`. @@ -467,10 +435,6 @@ use crate::knowledge::{KnowledgeQuery, KnowledgeSearchResult, Note, NoteDraft, N /// Implementors provide full-text search, note CRUD, and graph traversal over /// the knowledge index. `lago-knowledge` is the reference implementation; /// `life-kernel-facade` consumes this trait through `Arc`. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait KnowledgePort: Send + Sync { async fn search(&self, query: KnowledgeQuery) -> KernelResult; @@ -484,10 +448,6 @@ pub trait KnowledgePort: Send + Sync { /// Implementors provide immutable put/get over SHA-256–addressed payloads. /// `lago-store` is the reference implementation; `life-kernel-facade` consumes /// this trait through `Arc`. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait BlobStorePort: Send + Sync { async fn put( @@ -503,10 +463,6 @@ pub trait BlobStorePort: Send + Sync { /// /// Implementors record usage events and synthesize invoices. `life-kernel-facade` /// consumes this trait through `Arc`. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait BillingPort: Send + Sync { async fn record_usage(&self, usage: UsageRecord) -> KernelResult<()>; @@ -540,10 +496,6 @@ use crate::homeostasis::{ /// /// Streaming projections are returned as a [`BoxStream`] so callers can /// consume them incrementally without holding a large in-memory buffer. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait HomeostasisPort: Send + Sync { /// Return the current three-pillar homeostatic snapshot for `session`. @@ -600,10 +552,6 @@ use crate::finance::{ /// `SettlementReceipt`. /// /// Authorization IDs correlate authorization ↔ receipt for audit. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait FinancePort: Send + Sync { /// Fetch the current wallet manifest (address, balance, policy) for `owner`. @@ -665,10 +613,6 @@ use crate::evaluation::{ /// Implementors provide rubric-based evaluation, heuristic scoring, and /// comparative judgement. `nousd` is the reference implementation; /// `life-kernel-facade` consumes this trait through `Arc`. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait EvaluationPort: Send + Sync { async fn evaluate(&self, req: EvaluationRequest) -> KernelResult; @@ -694,10 +638,6 @@ use crate::relay::{RelayFrame, RelayOpenRequest, RelaySession, RelayToken}; /// Implementors proxy web-based remote agent sessions from life-relayd. /// Facade implementations return `KernelError::Unimplemented` until v0.2 /// lights the proxies up (Phase 4). -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait RelayPort: Send + Sync { async fn open(&self, req: RelayOpenRequest) -> KernelResult; @@ -727,10 +667,6 @@ use crate::world::{WorldEvent, WorldId, WorldMutation, WorldSnapshot, WorldVersi /// Implementors provide snapshot queries, state mutations, and event streaming /// for a named world. `opsisd` is the reference implementation; /// `life-kernel-facade` consumes this trait through `Arc`. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait WorldPort: Send + Sync { /// Return the current state snapshot for `world`. diff --git a/crates/aios/aios-runtime/src/lib.rs b/crates/aios/aios-runtime/src/lib.rs index c846f3b7..dcc3bbc3 100644 --- a/crates/aios/aios-runtime/src/lib.rs +++ b/crates/aios/aios-runtime/src/lib.rs @@ -143,10 +143,6 @@ pub enum ToolCallGuardDecision { }, } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait ToolCallGuard: Send + Sync { async fn on_tool_call( @@ -156,10 +152,6 @@ pub trait ToolCallGuard: Send + Sync { ) -> Result; } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait TurnMiddleware: Send + Sync { async fn process(&self, ctx: &mut TurnContext, next: TurnNext<'_>) -> Result; @@ -388,10 +380,6 @@ pub struct WorkflowTickOutcome { /// by `arcan-ergon` (and any future workflow runtime) and registered /// on the [`KernelRuntime`] at construction time. See /// `core/life/docs/superpowers/specs/2026-05-08-bro-1001-ergon-tick-body.md`. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait WorkflowTickDispatcher: Send + Sync { /// Run a workflow as the body of a single tick. Errors propagate diff --git a/crates/aios/aios-sandbox/src/lib.rs b/crates/aios/aios-sandbox/src/lib.rs index 51cd2dce..b5bff24c 100644 --- a/crates/aios/aios-sandbox/src/lib.rs +++ b/crates/aios/aios-sandbox/src/lib.rs @@ -46,10 +46,6 @@ pub struct SandboxExecution { pub timed_out: bool, } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait SandboxRunner: Send + Sync { async fn run(&self, request: SandboxRequest) -> Result; diff --git a/crates/anima/anima-identity/src/rotation.rs b/crates/anima/anima-identity/src/rotation.rs index 54a176e1..9e522526 100644 --- a/crates/anima/anima-identity/src/rotation.rs +++ b/crates/anima/anima-identity/src/rotation.rs @@ -67,10 +67,6 @@ pub struct RotationChainQuery<'a> { /// callers hold `&dyn JournalResolver` so the resolver can be swapped /// at runtime (e.g. between staging Vault-backed lago and a local /// fixture). -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait JournalResolver: Send + Sync { /// Return all `anima.identity_rotated` events that mention diff --git a/crates/arcan/arcan-aios-adapters/src/tools.rs b/crates/arcan/arcan-aios-adapters/src/tools.rs index 90f16dba..364f2102 100644 --- a/crates/arcan/arcan-aios-adapters/src/tools.rs +++ b/crates/arcan/arcan-aios-adapters/src/tools.rs @@ -28,10 +28,6 @@ pub struct RunCompletionContext { pub knowledge_top_relevance: Option, } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait ToolHarnessObserver: Send + Sync { async fn post_execute(&self, session_id: String, tool_name: String, is_error: bool); diff --git a/crates/arcan/arcan-ergon/src/registry.rs b/crates/arcan/arcan-ergon/src/registry.rs index e3f5b298..8000fc1c 100644 --- a/crates/arcan/arcan-ergon/src/registry.rs +++ b/crates/arcan/arcan-ergon/src/registry.rs @@ -27,10 +27,6 @@ use std::sync::Arc; /// /// Implementers should not need to write this trait by hand — /// [`WorkflowRegistry::register`] wraps any `Workflow` automatically. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait BoxedWorkflowExecutor: Send + Sync { /// Stable workflow name (e.g. `"bookkeeping.promotion-judge"`). diff --git a/crates/arcan/arcan-sandbox/src/provider.rs b/crates/arcan/arcan-sandbox/src/provider.rs index e0870aa8..e4de05e3 100644 --- a/crates/arcan/arcan-sandbox/src/provider.rs +++ b/crates/arcan/arcan-sandbox/src/provider.rs @@ -55,10 +55,6 @@ use crate::types::{ since = "0.2.0", note = "use aios_protocol::HypervisorBackend — SandboxProvider is retained as a transitional alias" )] -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait SandboxProvider: Send + Sync + 'static { /// Stable, unique name used for config routing and observability labels. diff --git a/crates/chronos/chronos-core/src/agenda.rs b/crates/chronos/chronos-core/src/agenda.rs index 1ecd89e4..c091dbbb 100644 --- a/crates/chronos/chronos-core/src/agenda.rs +++ b/crates/chronos/chronos-core/src/agenda.rs @@ -256,10 +256,6 @@ pub fn sort_for_dispatch(items: &mut [AgendaItem]) { /// across the daemon's HTTP handlers and wake loop. `#[async_trait]` boxes the returned futures /// for dyn-compatibility (the wake rate Chronos targets — ≤ 100/sec — makes the boxing cost /// negligible). -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait AgendaStore: Send + Sync { /// Add a new item to the agenda. Returns the freshly-minted id. diff --git a/crates/chronos/chronos-core/src/dispatch.rs b/crates/chronos/chronos-core/src/dispatch.rs index cc167648..2f0f4ed7 100644 --- a/crates/chronos/chronos-core/src/dispatch.rs +++ b/crates/chronos/chronos-core/src/dispatch.rs @@ -50,10 +50,6 @@ impl DispatchOutcome { /// the session exists, builds a `TickInput { objective: intent, .. }`, calls /// `KernelRuntime::tick_on_branch(session, BranchId::main(), input)`, and folds the `TickOutput` /// into a [`DispatchOutcome`]. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait KernelDispatcher: Send + Sync { /// Run one agent tick for `session_id` driven by `intent` (the wake's objective). diff --git a/crates/chronos/chronos-core/src/trigger.rs b/crates/chronos/chronos-core/src/trigger.rs index 7ddc69df..509a52d1 100644 --- a/crates/chronos/chronos-core/src/trigger.rs +++ b/crates/chronos/chronos-core/src/trigger.rs @@ -16,10 +16,6 @@ use crate::WakeEvent; /// /// `#[async_trait::async_trait]` boxes the future, which makes `Box` work. /// The boxing overhead is negligible for the wake rate Chronos expects (≤ 100/sec system-wide). -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait::async_trait] pub trait WakeTrigger: Send { /// Pull the next wake event from this trigger. diff --git a/crates/ergon/ergon-anima-adapter/src/lib.rs b/crates/ergon/ergon-anima-adapter/src/lib.rs index 8e9b55bf..b2bc38ab 100644 --- a/crates/ergon/ergon-anima-adapter/src/lib.rs +++ b/crates/ergon/ergon-anima-adapter/src/lib.rs @@ -29,10 +29,6 @@ use serde_json::Value; /// (`SoulAttester`) to per-step receipts. The receipt body shape is /// canonical-JSON per ADR §4; the returned string is the compact JWS /// (`
..`) signed by the agent's custody key. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait AgentAttestationSigner: Send + Sync { /// Sign a step receipt. The receipt is opaque to this trait — the diff --git a/crates/ergon/ergon-life-hooks/src/attestation.rs b/crates/ergon/ergon-life-hooks/src/attestation.rs index de3edae4..083c22f4 100644 --- a/crates/ergon/ergon-life-hooks/src/attestation.rs +++ b/crates/ergon/ergon-life-hooks/src/attestation.rs @@ -33,10 +33,6 @@ use std::sync::Arc; /// emits the signed event onto the lago journal. /// /// Errors are non-fatal — see module docs. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait SoulAttester: Send + Sync { /// Sign a `SessionStart`-equivalent event for the given session. diff --git a/crates/ergon/ergon-life-hooks/src/budget.rs b/crates/ergon/ergon-life-hooks/src/budget.rs index 46c95d8e..98ee3883 100644 --- a/crates/ergon/ergon-life-hooks/src/budget.rs +++ b/crates/ergon/ergon-life-hooks/src/budget.rs @@ -25,10 +25,6 @@ use std::sync::Arc; /// for example, downgrading `max_tokens` when the budget is tight, or /// stripping expensive tools — and return `Continue`. The hook re-checks /// after potential mutation. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait BudgetGate: Send + Sync { /// Decide whether the given inference call is allowed. diff --git a/crates/ergon/ergon-life-hooks/src/capability.rs b/crates/ergon/ergon-life-hooks/src/capability.rs index 00b59cc6..6f0cd356 100644 --- a/crates/ergon/ergon-life-hooks/src/capability.rs +++ b/crates/ergon/ergon-life-hooks/src/capability.rs @@ -21,10 +21,6 @@ use std::sync::Arc; /// The trait is **deliberately small** — one async method. Substrate /// integration (PolicySet evaluation, capability glob matching, etc.) /// happens behind this seam, not in this crate. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait CapabilityResolver: Send + Sync { /// Decide whether the given tool invocation is allowed. diff --git a/crates/ergon/ergon-life-hooks/src/score.rs b/crates/ergon/ergon-life-hooks/src/score.rs index 16e778d8..9e08641c 100644 --- a/crates/ergon/ergon-life-hooks/src/score.rs +++ b/crates/ergon/ergon-life-hooks/src/score.rs @@ -26,10 +26,6 @@ use std::sync::Arc; /// `nous_core::NousEvaluator`. The returned JSON value is the canonical /// score representation (e.g. `{"novelty": 2, "specificity": 3, /// "relevance": 3, "total": 8}`); ergon does not impose a schema. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait ResponseScorer: Send + Sync { /// Score the response. Errors are non-fatal; the hook records the diff --git a/crates/ergon/ergon/src/agent.rs b/crates/ergon/ergon/src/agent.rs index c7ee2e4e..f2d58a2c 100644 --- a/crates/ergon/ergon/src/agent.rs +++ b/crates/ergon/ergon/src/agent.rs @@ -264,10 +264,6 @@ impl AgentSpec { /// prefer `TypedAgent` for static cases or `AgentSpec` for dynamic /// cases. Implementing `Agent` directly is reserved for advanced /// patterns like recording wrappers, remote-dispatch shims, etc. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait Agent: Send + Sync { /// The (possibly-derived) spec for this agent. Cheap to call — diff --git a/crates/ergon/ergon/src/agent_registry.rs b/crates/ergon/ergon/src/agent_registry.rs index 225ad6e5..2164e9de 100644 --- a/crates/ergon/ergon/src/agent_registry.rs +++ b/crates/ergon/ergon/src/agent_registry.rs @@ -68,10 +68,6 @@ use crate::error::ErgonError; /// Hosts can compose multiple registries via [`ChainedAgentRegistry`]: /// authored MD files take precedence over experimental lago entries, /// or vice versa, depending on the deployment's policy. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait AgentRegistry: Send + Sync { /// Resolve an agent by name. Returns `None` if no agent is diff --git a/crates/ergon/ergon/src/hook.rs b/crates/ergon/ergon/src/hook.rs index be7fa7c9..ea6508a8 100644 --- a/crates/ergon/ergon/src/hook.rs +++ b/crates/ergon/ergon/src/hook.rs @@ -129,10 +129,6 @@ pub enum InferenceHookOutcome { /// returning [`HookOutcome::Continue`]. [`Self::on_post_tool_use`] receives /// `&mut ToolResult` so post-processing hooks can transform results before /// they reach the model. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait Hook: Send + Sync { /// Stable, human-readable name of this hook (used in error messages diff --git a/crates/ergon/ergon/src/runtime.rs b/crates/ergon/ergon/src/runtime.rs index 667ee7bc..e3ef0c34 100644 --- a/crates/ergon/ergon/src/runtime.rs +++ b/crates/ergon/ergon/src/runtime.rs @@ -64,10 +64,6 @@ use std::sync::Arc; /// `arcan_provider::Provider` and translates its events to ergon's /// [`crate::StreamEvent`] taxonomy. In tests: see the mock impl in /// `step.rs` `tests` module. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait Provider: Send + Sync { /// Stable, human-readable name of the provider (used in tracing, @@ -110,10 +106,6 @@ pub trait Provider: Send + Sync { /// In production: a `PraxisToolRegistryAdapter` (BRO-1001) wraps /// `praxis_core::ToolRegistry` and bakes a `SandboxPolicy` in at /// construction. In tests: see the mock impl in `step.rs` `tests` module. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait ToolRegistry: Send + Sync { /// JSON-Schema-backed tool definitions advertised to the model. diff --git a/crates/ergon/ergon/src/step.rs b/crates/ergon/ergon/src/step.rs index 1de13952..e4f6dacc 100644 --- a/crates/ergon/ergon/src/step.rs +++ b/crates/ergon/ergon/src/step.rs @@ -139,10 +139,6 @@ impl InferenceRequest { /// Step lifecycle hooks ([`crate::Hook::on_step_start`], /// [`crate::Hook::on_step_end`]) fire automatically when a step runs /// via [`StepCtx::step`]. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait Step: Send + Sync { /// Typed input. diff --git a/crates/ergon/ergon/src/stream.rs b/crates/ergon/ergon/src/stream.rs index bb92385a..f7ee7c31 100644 --- a/crates/ergon/ergon/src/stream.rs +++ b/crates/ergon/ergon/src/stream.rs @@ -151,10 +151,6 @@ pub enum StreamEvent { /// Sinks that buffer (mpsc-style) propagate backpressure by awaiting on /// their internal channel. The autonomous loop awaits each `emit` call /// in turn, so a slow sink throttles the upstream provider naturally. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait StreamSink: Send + Sync { /// Forward a single stream event. Returns an error if the sink can no diff --git a/crates/ergon/ergon/src/workflow.rs b/crates/ergon/ergon/src/workflow.rs index 1462becf..32479909 100644 --- a/crates/ergon/ergon/src/workflow.rs +++ b/crates/ergon/ergon/src/workflow.rs @@ -110,10 +110,6 @@ pub use praxis_skills_stub::{EmptySkillSet, SkillSet}; /// that consume skills override this. /// - The workflow does NOT supply tools, sandbox, or providers — those /// come from the [`StepCtx`] the host runtime hands to `execute`. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait Workflow: Send + Sync + 'static { /// Typed input. Must round-trip through JSON (the host runtime diff --git a/crates/haima/haima-outcome/src/verifier.rs b/crates/haima/haima-outcome/src/verifier.rs index 77c7270d..0c5301cb 100644 --- a/crates/haima/haima-outcome/src/verifier.rs +++ b/crates/haima/haima-outcome/src/verifier.rs @@ -17,10 +17,6 @@ use serde::{Deserialize, Serialize}; /// A pluggable verifier that checks whether a single success criterion has been met. /// /// Implementations must be `Send + Sync` so they can be used across async tasks. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait SuccessVerifier: Send + Sync { /// Human-readable name for this verifier (e.g., "`tests_passed`", "webhook"). diff --git a/crates/haima/haima-wallet/src/backend.rs b/crates/haima/haima-wallet/src/backend.rs index 86b7d457..ca755385 100644 --- a/crates/haima/haima-wallet/src/backend.rs +++ b/crates/haima/haima-wallet/src/backend.rs @@ -8,10 +8,6 @@ use haima_core::{HaimaResult, WalletAddress}; /// Local wallets sign directly with a private key. /// MPC wallets delegate signing to a remote service (e.g., Coinbase CDP). /// This trait unifies both behind a single interface. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait WalletBackend: Send + Sync { /// Get the wallet's on-chain address. diff --git a/crates/life-kernel/life-kernel-conformance/src/lib.rs b/crates/life-kernel/life-kernel-conformance/src/lib.rs index 256f861d..21afbb81 100644 --- a/crates/life-kernel/life-kernel-conformance/src/lib.rs +++ b/crates/life-kernel/life-kernel-conformance/src/lib.rs @@ -66,10 +66,6 @@ pub trait CapturingEventStore: EventStorePort { /// trail without going through the `KernelPort` trait. Implementations /// are expected to return a *fresh* engine + store on every call — /// scenarios assume an empty journal at construction time. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait ConformanceHarness: Send + Sync { /// Build a fresh engine + capturing store pair. diff --git a/crates/life-perturb/src/injector.rs b/crates/life-perturb/src/injector.rs index ec061906..4c7268e5 100644 --- a/crates/life-perturb/src/injector.rs +++ b/crates/life-perturb/src/injector.rs @@ -36,10 +36,6 @@ impl PerturbationHandle { /// One implementation per level. Concrete injectors live in this crate as /// stubs and will be filled in by the per-level workstreams (v0.1 → v1.0). -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait Injector: Send + Sync { /// The hierarchy level this injector targets. diff --git a/crates/life-runtime/anima-proxy/src/client.rs b/crates/life-runtime/anima-proxy/src/client.rs index c27af368..c76b130a 100644 --- a/crates/life-runtime/anima-proxy/src/client.rs +++ b/crates/life-runtime/anima-proxy/src/client.rs @@ -354,10 +354,6 @@ fn session_from_proto(s: anima_pb::SessionDescriptor) -> SessionDescriptor { } } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait AnimaCall: Send + Sync { async fn register_session(&self, sid: &str, user_id: &str) -> AnimaProxyResult<()>; diff --git a/crates/life-runtime/arcan-proxy/src/client.rs b/crates/life-runtime/arcan-proxy/src/client.rs index dcf96613..13851c67 100644 --- a/crates/life-runtime/arcan-proxy/src/client.rs +++ b/crates/life-runtime/arcan-proxy/src/client.rs @@ -307,10 +307,6 @@ fn record_outcome(guard: Option, success_or_permanent: bool) { /// the event journal and filesystem manifest. HTTP-backed impls /// (`VercelAiGatewayArcan`, `AnthropicArcan`) have no branch concept on /// the raw provider wire and ignore it; mocks accept and ignore it. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait ArcanCall: Send + Sync { async fn create_agent(&self, sid: &str) -> ArcanProxyResult; diff --git a/crates/life-runtime/haima-proxy/src/client.rs b/crates/life-runtime/haima-proxy/src/client.rs index c6890ff2..4e324e7b 100644 --- a/crates/life-runtime/haima-proxy/src/client.rs +++ b/crates/life-runtime/haima-proxy/src/client.rs @@ -408,10 +408,6 @@ fn record_outcome(guard: Option, success_or_permanent: bool) { } } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait HaimaCall: Send + Sync { async fn bind_wallet(&self, sid: &str, project_id: &str) -> HaimaProxyResult; diff --git a/crates/life-runtime/lago-proxy/src/client.rs b/crates/life-runtime/lago-proxy/src/client.rs index 3b2d8377..e29510b5 100644 --- a/crates/life-runtime/lago-proxy/src/client.rs +++ b/crates/life-runtime/lago-proxy/src/client.rs @@ -261,10 +261,6 @@ fn record_outcome(guard: Option, status: &tonic::Status) { } } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait LagoCall: Send + Sync { async fn open_namespace(&self, sid: &str) -> LagoProxyResult; diff --git a/crates/life-runtime/lifed-conformance/src/lib.rs b/crates/life-runtime/lifed-conformance/src/lib.rs index 8261b78f..32192ce8 100644 --- a/crates/life-runtime/lifed-conformance/src/lib.rs +++ b/crates/life-runtime/lifed-conformance/src/lib.rs @@ -33,10 +33,6 @@ pub struct VerificationCase { pub should_pass: bool, } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait SubstrateUnderTest: Send + Sync { fn audience(&self) -> &'static str; diff --git a/crates/life-runtime/lifed/src/idempotency/mod.rs b/crates/life-runtime/lifed/src/idempotency/mod.rs index 6569a68f..0e1ece01 100644 --- a/crates/life-runtime/lifed/src/idempotency/mod.rs +++ b/crates/life-runtime/lifed/src/idempotency/mod.rs @@ -35,10 +35,6 @@ impl IdemKey { } } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait IdempotencyStore: Send + Sync { async fn lookup(&self, key: &IdemKey) -> Result>, tonic::Status>; diff --git a/crates/life-runtime/lifed/src/route/ergon.rs b/crates/life-runtime/lifed/src/route/ergon.rs index 02f86511..c8f36ca5 100644 --- a/crates/life-runtime/lifed/src/route/ergon.rs +++ b/crates/life-runtime/lifed/src/route/ergon.rs @@ -149,10 +149,6 @@ pub struct StreamSessionRequest { /// The substrate-side implementation (in arcan-ergon, out of tree) wraps /// each concrete `ergon::Workflow` and returns the JSON-in / stream-out /// surface this trait exposes. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait ErgonWorkflowHandle: Send + Sync { /// Stable workflow name. Used in tracing spans + the diff --git a/crates/life-runtime/lifed/src/saga/driver.rs b/crates/life-runtime/lifed/src/saga/driver.rs index 422b0a86..f68e4cfa 100644 --- a/crates/life-runtime/lifed/src/saga/driver.rs +++ b/crates/life-runtime/lifed/src/saga/driver.rs @@ -67,10 +67,6 @@ pub struct SagaCtx { pub claims: CapabilityClaims, } -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait SagaStep: Send + Sync { async fn forward(&self, ctx: &SagaCtx) -> Result<(), SagaError>; @@ -82,10 +78,6 @@ pub trait SagaStep: Send + Sync { /// requires every saga state transition lands in /// `system/lifed/saga/`. We expose a small trait so the saga /// driver doesn't take a hard dependency on `LagoCall`. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait SagaJournal: Send + Sync { /// Append one saga lifecycle event. Errors are logged by the caller diff --git a/crates/life-runtime/lifegw/src/services/anthropic_messages.rs b/crates/life-runtime/lifegw/src/services/anthropic_messages.rs index 6bed40e8..0a5911ff 100644 --- a/crates/life-runtime/lifegw/src/services/anthropic_messages.rs +++ b/crates/life-runtime/lifegw/src/services/anthropic_messages.rs @@ -180,10 +180,6 @@ const X402_AMOUNT_USD_DEFAULT: &str = "0.10"; /// /// `Send + Sync + 'static` so the trait is dyn-callable from inside /// the per-request handler. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait::async_trait] pub trait HaimaClient: Send + Sync + 'static { /// Pre-call gate. `estimated_cost_micros` is the worst-case spend diff --git a/crates/nous/nous-tools/src/lineage.rs b/crates/nous/nous-tools/src/lineage.rs index d0ba1d25..bf92e7d8 100644 --- a/crates/nous/nous-tools/src/lineage.rs +++ b/crates/nous/nous-tools/src/lineage.rs @@ -130,10 +130,6 @@ impl LineageFilter { /// /// Implementations must preserve insertion order on read — downstream /// promoters rely on chronological iteration to detect drift. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait] pub trait NousLineage: Send + Sync { /// Record a single scoring/judging event with its full provenance. diff --git a/crates/relay/life-relayd/src/adapters/mod.rs b/crates/relay/life-relayd/src/adapters/mod.rs index 1b44bf26..a886dd49 100644 --- a/crates/relay/life-relayd/src/adapters/mod.rs +++ b/crates/relay/life-relayd/src/adapters/mod.rs @@ -11,10 +11,6 @@ use uuid::Uuid; /// /// Implementations manage a collection of live sessions internally. /// Output is streamed to the provided `event_tx` channel during `spawn`. -#[allow( - clippy::double_must_use, - reason = "async_trait boxes the return in a Pin>, which clippy now treats as already #[must_use]; the attribute it generates on top is therefore redundant, not a real bug" -)] #[async_trait::async_trait] pub trait SessionAdapter: Send + Sync { /// Spawn a new session. Returns session info.