Derive Copy Cross-Agent Ripple: Adding Copy to a Shared Type Breaks Downstream Clippy
Derive Copy Cross-Agent Ripple
Problem
When an agent adds #[derive(Copy)] to a shared type, callers in files outside that agent’s ownership get
clone_on_copy clippy warnings. Each agent’s own clippy passes (they only check their crate), but the workspace-wide
clippy at the wave gate fails.
Symptoms:
- Agent reports “clippy clean” for its crate
- Wave gate
cargo clippy --workspace -- -D warningsfails - Errors are in files no agent owns (e.g., framework layer calling an application layer type)
Root Cause
Adding Copy to a type is a widening change — it’s backward compatible at the type level, but clippy treats
.clone() on a Copy type as a lint error (clone_on_copy). The agent making the change only removes .clone() calls
in files it owns, missing callers in other crates/layers.
In this case:
- Agent 1 (application layer) added
CopytoSyncStatusand removed.clone()insync_engine.rs - Framework layer files
sync.rsandcommands/sync.rsalso called.status().clone()— not owned by any agent - Both agents passed their own
cargo clippy -p <crate>, but workspace clippy failed
Solution
At the Wave Gate
Fix the downstream .clone() → *dereference calls in the leader context:
// Before: clippy error after Copy was addedlet prev_status = engine.lock().await.status().clone();
// After: dereference instead of clonelet prev_status = *engine.lock().await.status();Prevention: Plan for Cross-Crate Ripple
When planning a derive(Copy) addition in an agent’s scope:
- Grep for
.clone()on the type across the workspace before assigning the task - Assign all affected files to the same agent, OR
- Document the expected wave-gate fixup in the plan so the leader knows to handle it
- Alternative: Have the agent run
cargo clippy --workspaceinstead of per-crate clippy
Checklist for Derive Changes
| Derive | Ripple Risk | What to Check |
|---|---|---|
Copy | High — clone_on_copy | grep -r "\.clone()" on the type |
PartialEq | Low | Usually additive |
Default | Medium | Callers using Type { field: val, ..Default::default() } |
Serialize/Deserialize | Low | Usually additive |
Implementation Notes
- The fix is always trivial (
.clone()→*dereference), but finding all locations requires workspace-wide search - This is a special case of the general pattern: trait/derive changes in shared types have workspace-wide blast radius
- Per-crate clippy (
cargo clippy -p <crate>) does NOT catch cross-crate lint issues
First Encountered
2026-02-22 — Code audit remediation. Agent “foundation-traits” added Copy to SyncStatus (P3-1). Wave 1 gate clippy
failed with 3 clone_on_copy errors in apps/desktop/src-tauri/src/sync.rs and commands/sync.rs. Fixed in leader
context (commit 4ee114c).
Agent Team Orchestration at Scale: Wave-Based Execution with File Ownership Next
lint-staged Pre-Commit Failure Drops Previously Staged Files
Was this page helpful?
Thanks for your feedback!