@mrciphersmith/keryx 0.3.3 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/dist/cli.js +996 -366
  2. package/docs/README.md +2 -0
  3. package/package.json +1 -1
  4. package/src/gdskills/bundled/install-manifest.json +520 -48
  5. package/src/gdskills/bundled/stacks/csharp-dotnet/agent-refs.json +4 -0
  6. package/src/gdskills/bundled/stacks/csharp-dotnet/governance/eval.json +1881 -0
  7. package/src/gdskills/bundled/stacks/csharp-dotnet/governance/scout.json +33 -0
  8. package/src/gdskills/bundled/stacks/csharp-dotnet/pack.json +38 -0
  9. package/src/gdskills/bundled/stacks/csharp-dotnet/rules/coding-style.mdc +100 -0
  10. package/src/gdskills/bundled/stacks/csharp-dotnet/rules/patterns.mdc +107 -0
  11. package/src/gdskills/bundled/stacks/csharp-dotnet/rules/security.mdc +86 -0
  12. package/src/gdskills/bundled/stacks/csharp-dotnet/rules/testing.mdc +89 -0
  13. package/src/gdskills/bundled/stacks/csharp-dotnet/skills/dotnet-build-fix/SKILL.md +143 -0
  14. package/src/gdskills/bundled/stacks/csharp-dotnet/skills/dotnet-build-fix/evals.json +77 -0
  15. package/src/gdskills/bundled/stacks/csharp-dotnet/skills/dotnet-code-review/SKILL.md +121 -0
  16. package/src/gdskills/bundled/stacks/csharp-dotnet/skills/dotnet-code-review/evals.json +77 -0
  17. package/src/gdskills/bundled/stacks/csharp-dotnet/skills/dotnet-implementation/SKILL.md +134 -0
  18. package/src/gdskills/bundled/stacks/csharp-dotnet/skills/dotnet-implementation/evals.json +76 -0
  19. package/src/gdskills/bundled/stacks/csharp-dotnet/skills/dotnet-testing/SKILL.md +130 -0
  20. package/src/gdskills/bundled/stacks/csharp-dotnet/skills/dotnet-testing/evals.json +77 -0
  21. package/src/gdskills/bundled/stacks/django/agent-refs.json +3 -0
  22. package/src/gdskills/bundled/stacks/django/governance/eval.json +1763 -0
  23. package/src/gdskills/bundled/stacks/django/governance/scout.json +40 -0
  24. package/src/gdskills/bundled/stacks/django/pack.json +43 -0
  25. package/src/gdskills/bundled/stacks/django/rules/coding-style.mdc +80 -0
  26. package/src/gdskills/bundled/stacks/django/rules/patterns.mdc +92 -0
  27. package/src/gdskills/bundled/stacks/django/rules/security.mdc +92 -0
  28. package/src/gdskills/bundled/stacks/django/rules/testing.mdc +89 -0
  29. package/src/gdskills/bundled/stacks/django/skills/django-build-fix/SKILL.md +149 -0
  30. package/src/gdskills/bundled/stacks/django/skills/django-build-fix/evals.json +49 -0
  31. package/src/gdskills/bundled/stacks/django/skills/django-code-review/SKILL.md +137 -0
  32. package/src/gdskills/bundled/stacks/django/skills/django-code-review/evals.json +48 -0
  33. package/src/gdskills/bundled/stacks/django/skills/django-implementation/SKILL.md +147 -0
  34. package/src/gdskills/bundled/stacks/django/skills/django-implementation/evals.json +75 -0
  35. package/src/gdskills/bundled/stacks/django/skills/django-migrate/SKILL.md +166 -0
  36. package/src/gdskills/bundled/stacks/django/skills/django-migrate/evals.json +49 -0
  37. package/src/gdskills/bundled/stacks/django/skills/django-testing/SKILL.md +130 -0
  38. package/src/gdskills/bundled/stacks/django/skills/django-testing/evals.json +48 -0
  39. package/src/gdskills/bundled/stacks/fastapi/agent-refs.json +3 -0
  40. package/src/gdskills/bundled/stacks/fastapi/governance/eval.json +1777 -0
  41. package/src/gdskills/bundled/stacks/fastapi/governance/scout.json +34 -0
  42. package/src/gdskills/bundled/stacks/fastapi/pack.json +43 -0
  43. package/src/gdskills/bundled/stacks/fastapi/rules/coding-style.mdc +68 -0
  44. package/src/gdskills/bundled/stacks/fastapi/rules/patterns.mdc +108 -0
  45. package/src/gdskills/bundled/stacks/fastapi/rules/security.mdc +99 -0
  46. package/src/gdskills/bundled/stacks/fastapi/rules/testing.mdc +85 -0
  47. package/src/gdskills/bundled/stacks/fastapi/skills/fastapi-build-fix/SKILL.md +157 -0
  48. package/src/gdskills/bundled/stacks/fastapi/skills/fastapi-build-fix/evals.json +76 -0
  49. package/src/gdskills/bundled/stacks/fastapi/skills/fastapi-code-review/SKILL.md +150 -0
  50. package/src/gdskills/bundled/stacks/fastapi/skills/fastapi-code-review/evals.json +74 -0
  51. package/src/gdskills/bundled/stacks/fastapi/skills/fastapi-implementation/SKILL.md +158 -0
  52. package/src/gdskills/bundled/stacks/fastapi/skills/fastapi-implementation/evals.json +75 -0
  53. package/src/gdskills/bundled/stacks/fastapi/skills/fastapi-testing/SKILL.md +146 -0
  54. package/src/gdskills/bundled/stacks/fastapi/skills/fastapi-testing/evals.json +74 -0
  55. package/src/gdskills/bundled/stacks/flutter-dart/agent-refs.json +4 -0
  56. package/src/gdskills/bundled/stacks/flutter-dart/governance/eval.json +1849 -0
  57. package/src/gdskills/bundled/stacks/flutter-dart/governance/scout.json +33 -0
  58. package/src/gdskills/bundled/stacks/flutter-dart/pack.json +41 -0
  59. package/src/gdskills/bundled/stacks/flutter-dart/rules/coding-style.mdc +98 -0
  60. package/src/gdskills/bundled/stacks/flutter-dart/rules/patterns.mdc +88 -0
  61. package/src/gdskills/bundled/stacks/flutter-dart/rules/security.mdc +91 -0
  62. package/src/gdskills/bundled/stacks/flutter-dart/rules/testing.mdc +101 -0
  63. package/src/gdskills/bundled/stacks/flutter-dart/skills/flutter-build-fix/SKILL.md +134 -0
  64. package/src/gdskills/bundled/stacks/flutter-dart/skills/flutter-build-fix/evals.json +79 -0
  65. package/src/gdskills/bundled/stacks/flutter-dart/skills/flutter-code-review/SKILL.md +124 -0
  66. package/src/gdskills/bundled/stacks/flutter-dart/skills/flutter-code-review/evals.json +74 -0
  67. package/src/gdskills/bundled/stacks/flutter-dart/skills/flutter-implementation/SKILL.md +139 -0
  68. package/src/gdskills/bundled/stacks/flutter-dart/skills/flutter-implementation/evals.json +77 -0
  69. package/src/gdskills/bundled/stacks/flutter-dart/skills/flutter-testing/SKILL.md +134 -0
  70. package/src/gdskills/bundled/stacks/flutter-dart/skills/flutter-testing/evals.json +74 -0
  71. package/src/gdskills/bundled/stacks/java-kotlin-spring/agent-refs.json +3 -0
  72. package/src/gdskills/bundled/stacks/java-kotlin-spring/governance/eval.json +2194 -0
  73. package/src/gdskills/bundled/stacks/java-kotlin-spring/governance/scout.json +39 -0
  74. package/src/gdskills/bundled/stacks/java-kotlin-spring/pack.json +40 -0
  75. package/src/gdskills/bundled/stacks/java-kotlin-spring/rules/coding-style.mdc +67 -0
  76. package/src/gdskills/bundled/stacks/java-kotlin-spring/rules/patterns.mdc +65 -0
  77. package/src/gdskills/bundled/stacks/java-kotlin-spring/rules/security.mdc +69 -0
  78. package/src/gdskills/bundled/stacks/java-kotlin-spring/rules/testing.mdc +80 -0
  79. package/src/gdskills/bundled/stacks/java-kotlin-spring/skills/java-kotlin-spring-build-fix/SKILL.md +144 -0
  80. package/src/gdskills/bundled/stacks/java-kotlin-spring/skills/java-kotlin-spring-build-fix/evals.json +74 -0
  81. package/src/gdskills/bundled/stacks/java-kotlin-spring/skills/java-kotlin-spring-code-review/SKILL.md +129 -0
  82. package/src/gdskills/bundled/stacks/java-kotlin-spring/skills/java-kotlin-spring-code-review/evals.json +74 -0
  83. package/src/gdskills/bundled/stacks/java-kotlin-spring/skills/java-kotlin-spring-implementation/SKILL.md +147 -0
  84. package/src/gdskills/bundled/stacks/java-kotlin-spring/skills/java-kotlin-spring-implementation/evals.json +75 -0
  85. package/src/gdskills/bundled/stacks/java-kotlin-spring/skills/java-kotlin-spring-migrate/SKILL.md +139 -0
  86. package/src/gdskills/bundled/stacks/java-kotlin-spring/skills/java-kotlin-spring-migrate/evals.json +74 -0
  87. package/src/gdskills/bundled/stacks/java-kotlin-spring/skills/java-kotlin-spring-testing/SKILL.md +128 -0
  88. package/src/gdskills/bundled/stacks/java-kotlin-spring/skills/java-kotlin-spring-testing/evals.json +73 -0
  89. package/src/gdskills/bundled/stacks/kotlin-android/agent-refs.json +4 -0
  90. package/src/gdskills/bundled/stacks/kotlin-android/governance/eval.json +1889 -0
  91. package/src/gdskills/bundled/stacks/kotlin-android/governance/scout.json +34 -0
  92. package/src/gdskills/bundled/stacks/kotlin-android/pack.json +38 -0
  93. package/src/gdskills/bundled/stacks/kotlin-android/rules/coding-style.mdc +89 -0
  94. package/src/gdskills/bundled/stacks/kotlin-android/rules/patterns.mdc +96 -0
  95. package/src/gdskills/bundled/stacks/kotlin-android/rules/security.mdc +90 -0
  96. package/src/gdskills/bundled/stacks/kotlin-android/rules/testing.mdc +89 -0
  97. package/src/gdskills/bundled/stacks/kotlin-android/skills/compose-implementation/SKILL.md +150 -0
  98. package/src/gdskills/bundled/stacks/kotlin-android/skills/compose-implementation/evals.json +77 -0
  99. package/src/gdskills/bundled/stacks/kotlin-android/skills/kotlin-android-build-fix/SKILL.md +151 -0
  100. package/src/gdskills/bundled/stacks/kotlin-android/skills/kotlin-android-build-fix/evals.json +76 -0
  101. package/src/gdskills/bundled/stacks/kotlin-android/skills/kotlin-android-code-review/SKILL.md +139 -0
  102. package/src/gdskills/bundled/stacks/kotlin-android/skills/kotlin-android-code-review/evals.json +78 -0
  103. package/src/gdskills/bundled/stacks/kotlin-android/skills/kotlin-android-testing/SKILL.md +131 -0
  104. package/src/gdskills/bundled/stacks/kotlin-android/skills/kotlin-android-testing/evals.json +77 -0
  105. package/src/gdskills/bundled/stacks/python/agent-refs.json +2 -1
  106. package/src/gdskills/bundled/stacks/python/pack.json +1 -1
  107. package/src/gdskills/bundled/stacks/rust/agent-refs.json +3 -0
  108. package/src/gdskills/bundled/stacks/rust/governance/eval.json +1823 -0
  109. package/src/gdskills/bundled/stacks/rust/governance/scout.json +32 -0
  110. package/src/gdskills/bundled/stacks/rust/pack.json +42 -0
  111. package/src/gdskills/bundled/stacks/rust/rules/coding-style.mdc +93 -0
  112. package/src/gdskills/bundled/stacks/rust/rules/patterns.mdc +85 -0
  113. package/src/gdskills/bundled/stacks/rust/rules/security.mdc +85 -0
  114. package/src/gdskills/bundled/stacks/rust/rules/testing.mdc +82 -0
  115. package/src/gdskills/bundled/stacks/rust/skills/rust-build-fix/SKILL.md +141 -0
  116. package/src/gdskills/bundled/stacks/rust/skills/rust-build-fix/evals.json +78 -0
  117. package/src/gdskills/bundled/stacks/rust/skills/rust-code-review/SKILL.md +127 -0
  118. package/src/gdskills/bundled/stacks/rust/skills/rust-code-review/evals.json +72 -0
  119. package/src/gdskills/bundled/stacks/rust/skills/rust-implementation/SKILL.md +133 -0
  120. package/src/gdskills/bundled/stacks/rust/skills/rust-implementation/evals.json +79 -0
  121. package/src/gdskills/bundled/stacks/rust/skills/rust-testing/SKILL.md +130 -0
  122. package/src/gdskills/bundled/stacks/rust/skills/rust-testing/evals.json +75 -0
  123. package/src/gdskills/bundled/stacks/swift-ios/agent-refs.json +4 -0
  124. package/src/gdskills/bundled/stacks/swift-ios/governance/eval.json +1803 -0
  125. package/src/gdskills/bundled/stacks/swift-ios/governance/scout.json +32 -0
  126. package/src/gdskills/bundled/stacks/swift-ios/pack.json +38 -0
  127. package/src/gdskills/bundled/stacks/swift-ios/rules/coding-style.mdc +92 -0
  128. package/src/gdskills/bundled/stacks/swift-ios/rules/patterns.mdc +112 -0
  129. package/src/gdskills/bundled/stacks/swift-ios/rules/security.mdc +78 -0
  130. package/src/gdskills/bundled/stacks/swift-ios/rules/testing.mdc +90 -0
  131. package/src/gdskills/bundled/stacks/swift-ios/skills/swift-build-fix/SKILL.md +144 -0
  132. package/src/gdskills/bundled/stacks/swift-ios/skills/swift-build-fix/evals.json +75 -0
  133. package/src/gdskills/bundled/stacks/swift-ios/skills/swift-code-review/SKILL.md +122 -0
  134. package/src/gdskills/bundled/stacks/swift-ios/skills/swift-code-review/evals.json +75 -0
  135. package/src/gdskills/bundled/stacks/swift-ios/skills/swift-testing/SKILL.md +131 -0
  136. package/src/gdskills/bundled/stacks/swift-ios/skills/swift-testing/evals.json +75 -0
  137. package/src/gdskills/bundled/stacks/swift-ios/skills/swiftui-implementation/SKILL.md +149 -0
  138. package/src/gdskills/bundled/stacks/swift-ios/skills/swiftui-implementation/evals.json +76 -0
  139. package/src/gdskills/bundled/agents/python-build-fixer.md +0 -52
  140. package/src/gdskills/bundled/agents/python-code-auditor.md +0 -49
@@ -0,0 +1,32 @@
1
+ [
2
+ {
3
+ "query": "Use when cargo build/cargo clippy fails, or Cargo.toml/Cargo.lock are out of sync -- resolves dependency/edition/MSRV mismatches, borrow-checker and lifetime errors, trait-bound errors, clippy failures, and a failing cargo test, with the smallest root-cause fix.",
4
+ "decision": "fork",
5
+ "topMatch": "go/go-build-fix",
6
+ "recordedAt": "2026-09-25T18:06:22.209Z",
7
+ "skillName": "rust-build-fix",
8
+ "justification": "top match go/go-build-fix is the same build-fix category but for a different language's own toolchain (go build/vet vs. cargo build/clippy/borrow-checker errors), not a substitute; a Rust-scoped fork is warranted since Go's build-fix has no visibility into Rust's own trait-bound/borrow-checker/cargo failure modes."
9
+ },
10
+ {
11
+ "query": "Use when reviewing a Rust change for ownership, panic, and safety risks -- unwrap/expect on fallible input, unnecessary clone as a borrow-checker workaround, unjustified or oversized unsafe blocks, blocking calls in async fn, unchecked arithmetic/indexing on untrusted data, and error types that lose their source. Read-only, no edits.",
12
+ "decision": "create",
13
+ "topMatch": "angular/angular-code-review",
14
+ "recordedAt": "2026-09-25T18:06:22.532Z",
15
+ "skillName": "rust-code-review"
16
+ },
17
+ {
18
+ "query": "Use when implementing or extending a feature in a Rust crate -- Cargo.toml/edition/workspace layout, ownership and borrowing, Result/Option error handling with the ? operator, thiserror/anyhow conventions, trait and generic design, and avoiding blocking calls in async fn.",
19
+ "decision": "create",
20
+ "topMatch": "rust/rust-build-fix",
21
+ "recordedAt": "2026-09-25T18:06:22.848Z",
22
+ "skillName": "rust-implementation"
23
+ },
24
+ {
25
+ "query": "Use when a Rust crate's own test suite needs writing, extending, or fixing with cargo test -- #[cfg(test)] unit tests, tests/ integration tests, multi-case assertions built as a Vec of structs, #[tokio::test] async tests joined properly, proptest/quickcheck property-based checks on a Rust struct or enum, and criterion benchmarks.",
26
+ "decision": "create",
27
+ "topMatch": "rust/rust-implementation",
28
+ "recordedAt": "2026-09-25T18:06:23.160Z",
29
+ "skillName": "rust-testing",
30
+ "justification": "top match go/go-testing is the same test-authoring category but for a different language's own idiom (table-driven Go subtests vs. Rust's #[cfg(test)] modules, proptest, criterion benchmarks), not a substitute; a Rust-scoped fork is warranted since Go's testing skill has no Rust-specific guidance."
31
+ }
32
+ ]
@@ -0,0 +1,42 @@
1
+ {
2
+ "id": "rust",
3
+ "family": "language",
4
+ "modules": ["rust-rules", "rust-skills"],
5
+ "detectionMarkers": ["rust"],
6
+ "provenance": {
7
+ "origin": "authored",
8
+ "sourceRef": "flow 335, Wave 4 batch 3"
9
+ },
10
+ "stability": "experimental",
11
+ "skills": {
12
+ "implement": ["rust-implementation"],
13
+ "test": ["rust-testing"],
14
+ "review": ["rust-code-review"],
15
+ "build-fix": ["rust-build-fix"],
16
+ "migrate": []
17
+ },
18
+ "agentProfile": {
19
+ "displayName": "Rust",
20
+ "auditFocus": [
21
+ "an .unwrap()/.expect() on a Result or Option built from untrusted or fallible external input (a network response, a file read, a parsed argument) instead of propagating with ?",
22
+ "an unsafe block with no # Safety doc comment stating the invariants the caller must uphold, or one wider than the specific operation that requires it",
23
+ "a borrow-checker conflict worked around with an unnecessary .clone() instead of restructuring ownership, splitting borrows, or using a reference",
24
+ "a blocking call (std::thread::sleep, a synchronous file/network read, a std::sync::Mutex held across an .await) inside an async fn instead of the async equivalent or spawn_blocking",
25
+ "an integer operation on untrusted input with no overflow/bounds check (raw arithmetic or indexing instead of checked_add/get/saturating_* where the value could be attacker-influenced)",
26
+ "a custom error type that loses the underlying cause instead of using #[source]/#[from] (thiserror) or .context() (anyhow) to preserve it"
27
+ ],
28
+ "buildCommands": [
29
+ "cargo build --all-targets",
30
+ "cargo clippy --all-targets -- -D warnings",
31
+ "cargo fmt --check",
32
+ "cargo test"
33
+ ],
34
+ "fixGuardrails": [
35
+ "Never silence a clippy finding with a blanket #[allow(clippy::all)] or a lint-level allow instead of fixing the root cause.",
36
+ "Never add .unwrap()/.expect() to make a type error or a Result mismatch disappear; propagate with ? or handle the error explicitly.",
37
+ "Never bump the edition or MSRV in Cargo.toml just to make an error disappear without understanding why it changed.",
38
+ "Never delete or skip a failing test to reach a green build.",
39
+ "Never widen an unsafe block or drop a # Safety comment to silence a compiler or clippy complaint about it."
40
+ ]
41
+ }
42
+ }
@@ -0,0 +1,93 @@
1
+ ---
2
+ extends: common
3
+ paths: ["**/*.rs"]
4
+ metadata:
5
+ origin: authored
6
+ ---
7
+
8
+ # Rust coding style
9
+
10
+ Narrows `core-common-rules`' stack-agnostic style rules to modern Rust
11
+ (2021/2024 edition) idiom. Applies only to `*.rs` files — everything not
12
+ Rust-specific still comes from the common rules this file `extends`.
13
+
14
+ ## Naming and structure
15
+
16
+ - `snake_case` for functions, methods, variables, and modules;
17
+ `UpperCamelCase` for types, traits, and enum variants; `SCREAMING_SNAKE_CASE`
18
+ for constants and statics — `rustfmt`/`rustc` will warn on a mismatch.
19
+ - A crate's public surface lives at the paths re-exported from `lib.rs`;
20
+ keep implementation details `pub(crate)` or private and re-export
21
+ deliberately, rather than making every module `pub` by default.
22
+ - An identifier's name shrinks with its scope: a short-lived closure
23
+ parameter can be `x`, a `pub` function gets a full descriptive name.
24
+
25
+ ## Ownership, borrowing, and errors
26
+
27
+ - Prefer borrowing (`&T`/`&mut T`) over taking ownership when the callee
28
+ does not need to keep the value; prefer `&str`/`&[T]` parameters over
29
+ `&String`/`&Vec<T>` so callers can pass either owned or borrowed data.
30
+ - Resolve a borrow-checker conflict by restructuring ownership, splitting
31
+ the borrow, or shortening a borrow's lifetime — reach for `.clone()`
32
+ only when the value genuinely needs to be duplicated, and say why in a
33
+ comment when the clone is non-obvious; an unnecessary `.clone()` used
34
+ purely to silence the borrow checker is a cost paid on every call.
35
+ - `Result<T, E>` for anything that can fail; propagate with the `?`
36
+ operator rather than a manual `match` that just re-returns `Err`.
37
+ `Option<T>` for genuine absence, not as a substitute for `Result` on an
38
+ operation that can fail for a reason worth naming.
39
+ - Never call `.unwrap()`/`.expect()` on a `Result`/`Option` built from
40
+ fallible or untrusted input (a parsed argument, a network response, a
41
+ file read, a map lookup on external data) in production code without a
42
+ stated invariant that makes it truly infallible; prefer `?`, a `match`,
43
+ or a combinator (`unwrap_or`, `unwrap_or_else`, `ok_or`) that handles the
44
+ failure path.
45
+ - Use `thiserror` to derive `std::error::Error` for a library's own error
46
+ enum (`#[error("...")]` per variant, `#[source]`/`#[from]` to preserve
47
+ the underlying cause); use `anyhow::Result`/`.context()`/`.with_context()`
48
+ in application/binary code that just needs to propagate and annotate
49
+ errors up to `main`, not to dictate a precise error type to its own
50
+ callers.
51
+
52
+ ## Traits and generics
53
+
54
+ - Accept the narrowest trait bound a function actually needs (`AsRef<str>`
55
+ over `&String`, `Iterator<Item = T>` over `Vec<T>`) so callers keep
56
+ flexibility in what they pass.
57
+ - Prefer returning a concrete type (`impl Trait` in return position) over
58
+ a boxed trait object (`Box<dyn Trait>`) unless runtime polymorphism
59
+ (a heterogeneous collection, a plugin-style callback list) is actually
60
+ needed — `impl Trait` avoids the allocation and indirection.
61
+ - Derive `Debug`, `Clone`, `PartialEq`, etc. instead of hand-writing them
62
+ when the type's fields support it; hand-write only when the derived
63
+ behavior would be wrong for the type's invariants.
64
+
65
+ ## Iterators and control flow
66
+
67
+ - Prefer an iterator chain (`.map`/`.filter`/`.fold`/`.collect`) over a
68
+ hand-rolled indexed loop when it expresses the transformation as clearly
69
+ — but do not force a chain that reads worse than a plain `for` loop just
70
+ to look idiomatic; readability wins over either style has priority.
71
+ - Use pattern matching (`match`, `if let`, `let else`) to handle every
72
+ variant of an enum explicitly; avoid a catch-all `_ =>` arm on a `match`
73
+ over your own enum where a new variant should force every call site to
74
+ be revisited.
75
+
76
+ ## Async conventions (when the crate uses async)
77
+
78
+ - `async fn` for I/O-bound work; never call a blocking operation
79
+ (`std::thread::sleep`, a synchronous file/socket read, a `std::sync`
80
+ primitive held across an `.await` point) inside an `async fn` running on
81
+ a multi-threaded executor — use the async equivalent (`tokio::time::sleep`,
82
+ `tokio::fs`, `tokio::sync::Mutex`) or `tokio::task::spawn_blocking` for
83
+ genuinely CPU-bound or blocking work.
84
+ - Keep a `Mutex` guard's scope as short as possible and never hold one
85
+ across an `.await`; prefer `tokio::sync::Mutex` when the lock itself
86
+ must be held across an await point, `std::sync::Mutex` when it never is.
87
+
88
+ ## Formatting and lints
89
+
90
+ - Format with `rustfmt` (`cargo fmt`) before finishing a change; do not
91
+ hand-format around a formatter that is already configured.
92
+ - Run `cargo clippy -- -D warnings` and fix findings at the root cause
93
+ rather than adding a blanket `#[allow(...)]`.
@@ -0,0 +1,85 @@
1
+ ---
2
+ extends: common
3
+ paths: ["**/*.rs"]
4
+ metadata:
5
+ origin: authored
6
+ ---
7
+
8
+ # Rust patterns
9
+
10
+ Narrows `core-common-rules`' stack-agnostic design guidance to idiomatic
11
+ Rust design and its common anti-patterns. Applies only to `*.rs` files.
12
+
13
+ ## Crate and module layout
14
+
15
+ - `src/lib.rs` (or `src/main.rs` for a binary) is the crate root; group
16
+ related functionality into modules under `src/`, each with a clear
17
+ single responsibility — a module that only holds shared types with no
18
+ behavior ("models", "types", "common") invites the same cross-module
19
+ coupling a Go "utils" package does.
20
+ - A workspace (`[workspace]` in the root `Cargo.toml`) splits genuinely
21
+ independent crates (a library plus a CLI that depends on it, or several
22
+ services sharing a core crate) — do not default to a workspace for a
23
+ single-binary project that has no reason to publish separate crates.
24
+ - Keep `pub` surface intentional: re-export the types callers need from
25
+ `lib.rs`, keep internal modules `pub(crate)` or private so the compiler
26
+ (not convention) enforces the boundary.
27
+
28
+ ## Error handling design
29
+
30
+ - A library crate defines its own error enum with `thiserror`, one
31
+ variant per failure mode, `#[source]`/`#[from]` on any variant that
32
+ wraps another error so `source()` and `?`-based conversion both work —
33
+ never collapse distinct failure modes into a single `Other(String)`
34
+ variant that erases the caller's ability to match on what happened.
35
+ - An application/binary crate uses `anyhow::Result` at its outer layers
36
+ and `.context("doing x")`/`.with_context(|| ...)` at each call to `?`
37
+ that crosses a meaningful boundary, so a failure's final error chain
38
+ reads as a story, not a single opaque message.
39
+ - Never use a `Result<T, String>`/`Result<T, Box<dyn Error>>` as a
40
+ permanent design in a library — `Box<dyn Error>` is a reasonable
41
+ quick-prototype return type but forces every caller to string-match or
42
+ downcast; graduate to a concrete `thiserror` enum once the error shapes
43
+ stabilize.
44
+
45
+ ## Ownership-driven API design
46
+
47
+ - Take `&self`/`&mut self`/`self` deliberately: `self` (by value) only
48
+ when the method consumes or transforms the value into something else
49
+ (a builder's terminal `.build()`), `&mut self` when it mutates in place,
50
+ `&self` otherwise.
51
+ - The typestate/builder pattern (a `FooBuilder` with chained `with_x`
52
+ methods returning `Self`, a terminal `.build() -> Result<Foo, ...>`) for
53
+ a constructor with many optional parameters, instead of a boolean-heavy
54
+ positional signature.
55
+ - Prefer newtypes (`struct UserId(u64);`) over a bare primitive when a
56
+ value has domain meaning distinct from its representation — the
57
+ compiler then rejects passing a `ProductId` where a `UserId` is
58
+ expected, which a bare `u64` parameter cannot.
59
+
60
+ ## Trait design
61
+
62
+ - Define a trait at the point of abstraction a consumer actually needs
63
+ (an `impl Trait` argument or a generic bound), sized to the methods that
64
+ consumer calls — a trait with every method the concrete type happens to
65
+ have is not an abstraction, it is a restatement of the type.
66
+ - Prefer generics (`fn process<T: Processor>(p: &T)`) for a hot path where
67
+ monomorphization's code-size cost is acceptable and static dispatch
68
+ matters; use `Box<dyn Trait>`/`&dyn Trait` when you need a heterogeneous
69
+ collection or a boundary (a plugin registry, a callback list) where the
70
+ concrete type varies at runtime.
71
+
72
+ ## Anti-patterns to flag
73
+
74
+ - A `.clone()` inserted to make the borrow checker pass without
75
+ considering whether restructuring ownership or borrowing differently
76
+ would avoid the copy — flag any clone in a hot path with no comment
77
+ explaining why it is necessary.
78
+ - Stringly-typed errors (`Err(format!("something went wrong: {e}"))`
79
+ returned as `Result<T, String>`) in a library crate instead of a
80
+ `thiserror`-derived enum a caller can match on.
81
+ - A "god module" (`utils`, `helpers`, `common`) accumulating unrelated
82
+ free functions — split by what the code actually does, the same
83
+ anti-pattern flagged in Go/Python's own pattern rules.
84
+ - `unwrap()`/`expect()` reached for as a shortcut past a type error during
85
+ development and never revisited before the change ships.
@@ -0,0 +1,85 @@
1
+ ---
2
+ extends: common
3
+ paths: ["**/*.rs"]
4
+ metadata:
5
+ origin: authored
6
+ ---
7
+
8
+ # Rust security
9
+
10
+ Narrows `core-common-rules`' stack-agnostic security rules to Rust-specific,
11
+ OWASP-relevant risks and the safe standard-library/ecosystem API to use
12
+ instead. `unsafe` and panic-on-untrusted-input risks can appear anywhere a
13
+ crate touches attacker-influenced data, so this file stays broad rather
14
+ than narrowing to a single subdirectory.
15
+
16
+ ## `unsafe` blocks
17
+
18
+ - Every `unsafe` block carries a `# Safety` doc comment (on the block or
19
+ the function containing it) stating the exact invariants the caller or
20
+ the block itself must uphold for the operation to be sound — not a
21
+ generic "this is safe" note, but the specific precondition (pointer
22
+ validity, alignment, lifetime, no concurrent mutation) that makes it so.
23
+ - Keep an `unsafe` block as small as possible — wrap only the operation
24
+ that actually requires it (a raw pointer deref, an FFI call, a
25
+ `mem::transmute`), not the surrounding safe code, so the audited surface
26
+ stays minimal.
27
+ - Never widen an `unsafe` block or drop its `# Safety` comment to silence
28
+ a compiler or clippy complaint; if the invariant cannot be stated, the
29
+ code is not actually sound and needs a different approach.
30
+
31
+ ## Panics on untrusted input
32
+
33
+ - Never call `.unwrap()`/`.expect()` on a `Result`/`Option` derived from
34
+ network input, file contents, CLI arguments, or any other
35
+ attacker-influenced source — a panic there is a denial-of-service vector
36
+ (the process/thread aborts) even when the underlying bug is minor.
37
+ Propagate with `?`, or handle explicitly.
38
+ - Guard array/slice indexing on untrusted-derived indices with `.get(i)`
39
+ (returns `Option`) instead of `arr[i]` (panics out of bounds); guard
40
+ integer arithmetic on untrusted values with `checked_add`/`checked_mul`/
41
+ `saturating_*`/`wrapping_*` as the operation's semantics require, instead
42
+ of a bare `+`/`*` that panics on overflow in debug builds and silently
43
+ wraps in release builds — both are wrong for a value an attacker
44
+ influences.
45
+
46
+ ## FFI boundaries
47
+
48
+ - Validate every value crossing an `extern "C"` boundary before trusting
49
+ it — a raw pointer from C is not guaranteed non-null, valid, or
50
+ correctly aligned; check before dereferencing, and document the
51
+ ownership/lifetime contract (who frees it, using what allocator) in the
52
+ function's `# Safety` comment.
53
+ - Never let a Rust panic unwind across an `extern "C"` boundary — undefined
54
+ behavior in most toolchains; catch it with `std::panic::catch_unwind` at
55
+ the FFI edge and convert it to an error code instead.
56
+
57
+ ## Dependency and supply-chain hygiene
58
+
59
+ - Run `cargo audit` (or the project's already-configured equivalent) when
60
+ introducing or updating a dependency, or when asked to check for known
61
+ vulnerabilities — it checks `Cargo.lock` against the RustSec advisory
62
+ database.
63
+ - Pin dependency versions deliberately in `Cargo.toml`; avoid a bare `*`
64
+ or an overly wide range that lets an unreviewed major/minor bump in.
65
+
66
+ ## Deserialization
67
+
68
+ - When deserializing untrusted input with `serde`, apply size/depth limits
69
+ appropriate to the format and deserializer (a bounded reader, a
70
+ recursion-depth guard, or the deserializer's own limit configuration
71
+ where it exposes one) — an unbounded deserialize of attacker-controlled
72
+ JSON/bincode/etc. is a memory-exhaustion or stack-overflow
73
+ (deeply-nested structures) vector.
74
+ - Never derive `Deserialize` for a type and then trust its field values
75
+ as pre-validated — validate ranges/formats/invariants after
76
+ deserializing, the same as any other externally-sourced value.
77
+
78
+ ## Randomness and secrets
79
+
80
+ - Use a CSPRNG (the `rand` crate's default `ThreadRng`/`OsRng`, or the
81
+ `getrandom`/`ring` crates) for anything security-sensitive — tokens,
82
+ session IDs, keys, nonces; a non-cryptographic PRNG seeded predictably
83
+ is unsuitable for secrets even when its API looks the same.
84
+ - Never hard-code a credential, API key, or signing secret in source; load
85
+ it from environment/secret storage the project already uses.
@@ -0,0 +1,82 @@
1
+ ---
2
+ extends: common
3
+ paths: ["**/*.rs"]
4
+ metadata:
5
+ origin: authored
6
+ ---
7
+
8
+ # Rust testing
9
+
10
+ Narrows `core-common-rules`' stack-agnostic testing rules to Rust's built-in
11
+ `#[test]` framework and its common extensions. Applies only to `*.rs` files.
12
+
13
+ ## Layout and naming
14
+
15
+ - Unit tests live in a `#[cfg(test)] mod tests { use super::*; ... }` block
16
+ at the bottom of the file they test, giving them access to private
17
+ items; integration tests (exercising only the crate's public API) live
18
+ under `tests/` at the crate root, one file per test binary.
19
+ - Name a test function for the behavior it verifies
20
+ (`rejects_negative_amount`, not `test1` or `test_validate`); group
21
+ related cases as separate `#[test]` functions or, for many similar
22
+ inputs, a parameterized loop/table within one function.
23
+ - Fixture/golden data a test reads lives under `tests/fixtures/` (or a
24
+ crate-local `testdata/` if the project already uses that convention) —
25
+ match whatever the crate already does rather than inventing a new one.
26
+
27
+ ## Test structure
28
+
29
+ - Prefer a small table of cases (a `Vec` of a local struct, or a slice of
30
+ tuples) iterated in one `#[test]` function over many near-duplicate test
31
+ functions, when the cases share the same assertion shape — mirrors the
32
+ table-driven convention from other stacks, adapted to Rust's lack of a
33
+ built-in subtest runner.
34
+ - Assert with `assert_eq!`/`assert!`/`assert_ne!` from `std`, or the
35
+ project's already-adopted assertion crate (`pretty_assertions`,
36
+ `assert_matches`) — do not introduce a new assertion library into a
37
+ crate that has not adopted one.
38
+ - For a `Result`-returning function, assert the specific error variant
39
+ (`assert!(matches!(err, MyError::NotFound { .. }))` or
40
+ `assert_eq!(err, MyError::NotFound)` when the error implements
41
+ `PartialEq`) rather than only `assert!(result.is_err())`, which passes
42
+ for the wrong failure just as readily as the right one.
43
+
44
+ ## Async tests
45
+
46
+ - `#[tokio::test]` (or the project's already-configured async test
47
+ attribute) for an `async fn` test body; never block a `#[test]`
48
+ function's thread on a future with a hand-rolled executor when the
49
+ project already depends on `tokio`.
50
+ - Join spawned tasks with `.await` on their `JoinHandle`, or a channel,
51
+ before asserting — never synchronize with `std::thread::sleep`/
52
+ `tokio::time::sleep` to "give a spawned task time to finish"; that is
53
+ non-deterministic under load and flakes in CI exactly like a Go test
54
+ that sleeps instead of joining a goroutine.
55
+
56
+ ## Property-based and fuzz testing
57
+
58
+ - Reach for `proptest` or `quickcheck` (whichever the crate already
59
+ depends on) for a function with a large, structured input space
60
+ (a parser, a serializer round-trip) instead of hand-writing dozens of
61
+ near-identical example-based cases.
62
+ - `cargo fuzz` (built on `libFuzzer`) for a parser or decoder that touches
63
+ untrusted input formats directly; note in the report that fuzzing runs
64
+ separately from `cargo test` and is not part of the default CI test run
65
+ unless the project has wired it in.
66
+
67
+ ## Benchmarks
68
+
69
+ - Use `criterion` (the de facto ecosystem standard) for a benchmark that
70
+ needs statistical rigor (warm-up, outlier detection, regression
71
+ comparison across runs) rather than the unstable built-in `#[bench]`
72
+ attribute, which requires nightly.
73
+
74
+ ## Running and determinism
75
+
76
+ - Run `cargo test` (add `--all-features`/`--workspace` when the project's
77
+ CI does) before reporting tests as passing; a test relying on wall-clock
78
+ timing, real network access, or shared global state is a flake risk —
79
+ prefer a fake clock, a mock boundary, or `#[serial]` (from the `serial_test`
80
+ crate) for tests that must not run concurrently.
81
+ - New behavior gets a new test in the same change; a bug fix gets a
82
+ regression test that fails before the fix and passes after.
@@ -0,0 +1,141 @@
1
+ ---
2
+ name: rust-build-fix
3
+ description: "Use when cargo build/cargo clippy fails, or Cargo.toml/Cargo.lock are out of sync -- resolves dependency/edition/MSRV mismatches, borrow-checker and lifetime errors, trait-bound errors, clippy failures, and a failing cargo test, with the smallest root-cause fix."
4
+ triggers:
5
+ - "cargo build is failing"
6
+ - "fix Cargo.toml Cargo.lock mismatch"
7
+ - "resolve this Rust borrow checker error"
8
+ - "cargo clippy is failing"
9
+ - "this Rust trait bound isn't satisfied"
10
+ - "cargo test is failing"
11
+ metadata:
12
+ origin: authored
13
+ category: build-fix
14
+ version: "1.0.0"
15
+ compatible_harnesses: "claude,codex,cursor,zed,opencode"
16
+ license: "MIT"
17
+ ---
18
+
19
+ # Rust build fix (2021/2024 edition)
20
+
21
+ Resolve a `cargo build`/`cargo clippy` failure, a `Cargo.toml`/`Cargo.lock`
22
+ mismatch, a borrow-checker/lifetime error, an unsatisfied trait bound, or a
23
+ failing `cargo test` — with the smallest change that fixes the actual root
24
+ cause. `rules/coding-style.mdc` and `rules/security.mdc` govern what a
25
+ "correct" fix looks like; this skill never reaches for a suppression
26
+ instead of a fix.
27
+
28
+ ## Workflow
29
+
30
+ ### Step 1: Reproduce and classify
31
+
32
+ ```bash
33
+ cargo build --all-targets
34
+ cargo clippy --all-targets -- -D warnings
35
+ ```
36
+
37
+ Read the exact error text (`rustc`'s diagnostics name the error code, e.g.
38
+ `E0502`, `E0308`) and classify it:
39
+
40
+ - **Compile error** (type mismatch, undefined item, wrong argument count).
41
+ - **Borrow checker / lifetime** (`E0502` conflicting borrows, `E0499`
42
+ multiple mutable borrows, a lifetime that doesn't live long enough).
43
+ - **Trait bound** (`the trait bound ... is not satisfied`, a missing
44
+ `impl` the code assumes exists).
45
+ - **Dependency/edition/MSRV** (`Cargo.lock` stale against `Cargo.toml`,
46
+ a version conflict, a feature used past the declared `edition`/
47
+ `rust-version`).
48
+ - **Clippy finding** (a lint from `cargo clippy`'s default set or the
49
+ project's configured groups).
50
+ - **Test failure** (`cargo test` reports a failing assertion or panic).
51
+
52
+ ### Step 2: Fix by category
53
+
54
+ **Dependency/edition/MSRV:** run `cargo update -p <crate>` for a targeted
55
+ bump, or `cargo update` for a full re-resolve, when `Cargo.lock` is simply
56
+ stale against `Cargo.toml`'s requirements. For a genuine version conflict,
57
+ check `cargo tree -i <crate>` (what depends on the conflicting version)
58
+ before bumping by hand. Only raise `edition`/`rust-version` in
59
+ `Cargo.toml` when the code genuinely needs a feature that edition/MSRV
60
+ introduces, and say so in the report — never to make an unrelated error
61
+ disappear.
62
+
63
+ **Borrow checker / lifetime:** read what the compiler's own suggestion
64
+ proposes first (`rustc` usually names the exact conflicting borrows or
65
+ missing lifetime). Prefer restructuring ownership, splitting a borrow, or
66
+ shortening a lifetime over reaching for `.clone()`; a clone is an
67
+ acceptable fix only when the value genuinely needs to be duplicated —
68
+ say so in the report either way (`rules/patterns.mdc`).
69
+
70
+ **Trait bound:** check whether the missing `impl` should exist on the
71
+ type in question (derive it, or implement it) versus whether the calling
72
+ code's generic bound is wider than it needs to be. Do not add a blanket
73
+ bound or an unnecessary `Box<dyn Trait>` conversion just to make the
74
+ compiler stop complaining without understanding which side is wrong.
75
+
76
+ **Clippy finding:** fix the underlying issue the lint names (an
77
+ unnecessary clone, a `.unwrap()` on fallible input, a needless
78
+ collect). Never add `#[allow(clippy::...)]` or a blanket
79
+ `#[allow(clippy::all)]` whose only purpose is to make the checker stop
80
+ complaining without addressing what it found.
81
+
82
+ **Test failure:** read the assertion output and the code path it
83
+ exercises; fix the actual bug the test caught. Never delete, skip
84
+ (`#[ignore]`), or loosen the assertion to reach a green build unless the
85
+ test itself is proven wrong (say so explicitly in the report).
86
+
87
+ ### Step 3: Verify
88
+
89
+ ```bash
90
+ cargo build --all-targets
91
+ cargo clippy --all-targets -- -D warnings
92
+ cargo fmt --check
93
+ cargo test
94
+ ```
95
+
96
+ All must exit 0 before reporting done.
97
+
98
+ ### Step 4: Report
99
+
100
+ ```
101
+ Fixed: Cargo.lock stale against a version bump in Cargo.toml (ran `cargo update -p tokio`)
102
+ - Root cause: Cargo.lock predated a minor version bump in Cargo.toml
103
+ - cargo build/clippy -D warnings/fmt --check/test all pass
104
+ ```
105
+
106
+ State the root cause in one sentence, not just "fixed the error."
107
+
108
+ ## Rules
109
+
110
+ - Find and fix the smallest change that addresses the actual root cause —
111
+ never widen a fix beyond what the failure requires.
112
+ - NEVER add `#[allow(clippy::...)]` (especially a blanket
113
+ `#[allow(clippy::all)]`) to silence a clippy finding instead of fixing
114
+ what it found.
115
+ - NEVER raise `edition`/`rust-version` in `Cargo.toml`, or bump a major
116
+ dependency version, just to make an error disappear without
117
+ understanding why it changed.
118
+ - NEVER reach for `.clone()`/`.unwrap()` purely to make the compiler stop
119
+ complaining without considering whether it addresses the actual error.
120
+ - NEVER delete, skip (`#[ignore]`), or loosen an assertion to reach a
121
+ green `cargo test`.
122
+
123
+ ## Red Flags
124
+
125
+ | Rationalization | Why it is wrong |
126
+ |---|---|
127
+ | "I'll add `#[allow(clippy::redundant_clone)]` here so the linter stops complaining" | Silences the finding without addressing whether the clone is actually needed; check the ownership shape instead. `redundant_clone` lives in clippy's `nursery` group (allow-by-default), so it only surfaces when that group is enabled -- but once it fires, suppressing it is the same mistake as suppressing any other clippy finding |
128
+ | "Bumping the edition to 2024 makes this compile" | Changes the crate's declared minimum edition for every consumer to dodge one error; understand why the code needs 2024 first, or fix the code to work at the declared edition |
129
+ | "This test is flaky, I'll add `#[ignore]` for now" | Hides a real bug or a real flake source instead of fixing the underlying issue; find the actual cause |
130
+ | "I'll just `.clone()` past this borrow error" | A reflexive clone can mask an ownership design issue the compiler is correctly catching; read the compiler's own suggestion first |
131
+
132
+ ## Verification
133
+
134
+ Do not report the fix done until all of the following hold:
135
+
136
+ - `cargo build --all-targets`, `cargo clippy --all-targets -- -D warnings`,
137
+ `cargo fmt --check`, and `cargo test` all exit 0.
138
+ - The change is the smallest one that addresses the stated root cause —
139
+ no unrelated files touched.
140
+ - The report states the root cause in one sentence, not just "build now
141
+ passes."
@@ -0,0 +1,78 @@
1
+ {
2
+ "triggers": {
3
+ "positive": [
4
+ "cargo build is failing with a trait bound not satisfied error",
5
+ "I bumped a dependency version and now cargo build complains the lockfile doesn't match Cargo.toml anymore, what do I do?",
6
+ "The compiler won't let me borrow `orders` as mutable twice at the same time in this function, how do I restructure it so it compiles?",
7
+ "cargo clippy is reporting a needless clone lint",
8
+ "This Rust code has a lifetime error that won't compile",
9
+ "cargo test is failing with a panic in the order crate, fix the build"
10
+ ],
11
+ "negative": [
12
+ "npm install is failing with a peer dependency conflict",
13
+ "go build is failing for this Go module",
14
+ "pip install is failing for this Python project",
15
+ "Implement a new Rust feature in the order crate",
16
+ "Review this Rust diff for unsafe blocks and unwrap panics",
17
+ "Write Rust tests for this function",
18
+ "Our CMake configure step is failing with a missing header error"
19
+ ]
20
+ },
21
+ "scenarios": [
22
+ {
23
+ "id": "lockfile-mismatch",
24
+ "prompt": "cargo build --locked fails saying Cargo.lock is out of date after I bumped a dependency version in Cargo.toml (this is the same command our CI runs). How do I fix it?",
25
+ "strictness": "high",
26
+ "expected_behavior": [
27
+ {
28
+ "grader": "judge",
29
+ "rubric": "A correct answer identifies that Cargo.lock is stale relative to Cargo.toml's requirements after the dependency bump and fixes it by running cargo update (or a targeted cargo update -p <crate>). For a genuine version conflict it checks cargo tree -i <crate> before bumping another dependency's version by hand, rather than routing around the error some other way.",
30
+ "pass_criteria": [
31
+ "Names `cargo update` or `cargo update -p <crate>`, run from the crate/workspace root, as the concrete command that resolves the stale Cargo.lock -- not merely 'sync the files' or 'run the tool that fixes this'.",
32
+ "States the root cause: Cargo.lock no longer matches what Cargo.toml now requires after the version bump, not just 'run this command' with no explanation.",
33
+ "Either names a concrete verification step afterward (`cargo build`/`cargo test`) or does not suggest skipping verification."
34
+ ],
35
+ "fail_criteria": [
36
+ "Recommends raising the `edition` or `rust-version` in Cargo.toml to make the error go away, or bumping another dependency's version by hand without checking what depends on it, as a substitute for running `cargo update`.",
37
+ "Recommends hand-editing the checksum/version lines in Cargo.lock directly instead of regenerating it with `cargo update`."
38
+ ]
39
+ }
40
+ ],
41
+ "calibration": {
42
+ "known_right": "This means Cargo.lock no longer matches what Cargo.toml now requires after you bumped the dependency version. The fix is `cargo update -p <crate-name>` (or a plain `cargo update` if you want everything re-resolved) run from the crate or workspace root -- it recomputes Cargo.lock against Cargo.toml's requirements, picking up the new version and resolving anything that needs to shift alongside it. If the bump pulls in a genuine version conflict rather than a simple stale-lock error, don't just bump another crate's version by hand -- run `cargo tree -i <conflicting-crate>` first to see what's actually pinning the conflicting version, so you understand the dependency shape before changing it. After `cargo update` finishes, re-run `cargo build` and `cargo test` to confirm everything is consistent again before considering this done. Avoid hand-editing the checksums or version lines in Cargo.lock directly; that file is generated and meant to be regenerated by tooling, not patched by hand.",
43
+ "known_wrong": "Honestly the fastest fix here is to bump the edition in Cargo.toml to \"2024\" -- that usually makes Cargo.lock errors like this go away without you needing to figure out what `cargo update` would even change. Just edit the `edition = \"2021\"` line and re-run the build; if it still complains, bump another dependency's version in Cargo.toml up a bit further too until the error clears. You don't really need to run `cargo tree` or dig into the dependency graph for a simple lockfile mismatch like this -- that's overkill for what's usually just a version string being out of date.",
44
+ "vague": "This is just a dependency sync issue -- make sure your Cargo files are consistent with each other again and the build should pass.",
45
+ "subtle_wrong": "Bump the dependency's version in Cargo.toml directly to match what your code now needs, then try `cargo build` again -- if Cargo.lock still complains about a missing checksum for that version, add the missing hash/version entry to Cargo.lock by hand so the two files line up. That gets you to a green build without having to run `cargo update` and re-resolve everything else it might touch."
46
+ }
47
+ },
48
+ {
49
+ "id": "no-clippy-allow-suppression",
50
+ "prompt": "cargo clippy (with the nursery group enabled) is flagging a redundant clone in my Rust code. How should I fix it?",
51
+ "strictness": "high",
52
+ "expected_behavior": [
53
+ {
54
+ "grader": "judge",
55
+ "rubric": "A correct answer fixes the actual redundant clone -- removes it and borrows instead, or restructures ownership so the clone isn't needed -- instead of suppressing the lint with #[allow(clippy::...)] (especially a blanket #[allow(clippy::all)]), and instead of keeping the clone with only a comment explaining it away when the lint indicates it is genuinely unnecessary.",
56
+ "pass_criteria": [
57
+ "Identifies that the clone is unnecessary and should be removed in favor of borrowing (a reference) or restructuring ownership, not kept.",
58
+ "Shows the concrete fix direction: pass a reference (e.g. `&value` or changing the parameter type to `&T`) instead of the owned clone, or an equivalent restructuring -- not merely a statement that the clone 'should be looked at'.",
59
+ "Does not rely on `#[allow(clippy::...)]` (or a blanket `#[allow(clippy::all)]`) as the fix for the flagged finding."
60
+ ],
61
+ "fail_criteria": [
62
+ "Recommends adding `#[allow(clippy::redundant_clone)]` or `#[allow(clippy::all)]` to silence the finding instead of removing the clone.",
63
+ "Keeps the clone unchanged and only adds a comment justifying it, when the lint's own message indicates the value can simply be borrowed instead."
64
+ ]
65
+ }
66
+ ],
67
+ "calibration": {
68
+ "known_right": "clippy's `redundant_clone` (part of the `nursery` group, allow-by-default, which is why it only shows up once that group is enabled) is telling you the value gets duplicated somewhere it could just be borrowed instead -- that usually means a function parameter or a call site is taking ownership (`T` or `.clone()`) where a reference (`&T`) would work just as well. Look at how the cloned value is used afterward: if the caller still needs its own copy and the callee only reads the value, change the callee's signature to accept `&T` and drop the `.clone()` at the call site. If the callee genuinely needs to own or mutate its own copy independent of the caller, the clone might be legitimate -- in that case leave it, but consider whether an owned move (transferring ownership instead of cloning) is possible if the caller doesn't need the value afterward either. Don't reach for `#[allow(clippy::redundant_clone)]` here -- that just tells the linter to stop looking, it doesn't address whether the clone was actually needed. Once you've fixed it, re-run `cargo clippy -- -D warnings` (with the nursery group enabled) to confirm the finding is actually resolved rather than merely hidden.",
69
+ "known_wrong": "The simplest fix is to just add `#[allow(clippy::redundant_clone)]` above the function -- that clone genuinely doesn't matter here for a value this small, and it stops clippy from flagging it every time CI runs. You don't need to touch the actual signature or figure out whether borrowing would work; the allow attribute is exactly what it's for. If clippy flags something similar nearby, you can add the same allow there too rather than working through each clone individually.",
70
+ "vague": "You should fix that clone properly instead of suppressing the finding -- make sure it's actually addressed before you call this done.",
71
+ "subtle_wrong": "That redundant_clone finding is easy to clear without touching the surrounding logic: leave the `.clone()` exactly where it is and add a comment above it explaining that it's there for simplicity, so future readers understand it's intentional. That way you're not silently ignoring clippy's feedback anymore, and you don't have to change the function's signature or verify that borrowing would actually work at every call site."
72
+ },
73
+ "anti_patterns": [
74
+ "#[allow(clippy"
75
+ ]
76
+ }
77
+ ]
78
+ }