tribunal-kit 2.4.6 → 3.1.0

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 (250) hide show
  1. package/.agent/ARCHITECTURE.md +99 -99
  2. package/.agent/GEMINI.md +52 -52
  3. package/.agent/agents/accessibility-reviewer.md +139 -86
  4. package/.agent/agents/ai-code-reviewer.md +160 -90
  5. package/.agent/agents/backend-specialist.md +164 -127
  6. package/.agent/agents/code-archaeologist.md +115 -73
  7. package/.agent/agents/database-architect.md +130 -110
  8. package/.agent/agents/debugger.md +137 -97
  9. package/.agent/agents/dependency-reviewer.md +78 -30
  10. package/.agent/agents/devops-engineer.md +161 -118
  11. package/.agent/agents/documentation-writer.md +151 -87
  12. package/.agent/agents/explorer-agent.md +117 -99
  13. package/.agent/agents/frontend-reviewer.md +127 -47
  14. package/.agent/agents/frontend-specialist.md +169 -109
  15. package/.agent/agents/game-developer.md +28 -164
  16. package/.agent/agents/logic-reviewer.md +87 -49
  17. package/.agent/agents/mobile-developer.md +151 -103
  18. package/.agent/agents/mobile-reviewer.md +133 -50
  19. package/.agent/agents/orchestrator.md +121 -110
  20. package/.agent/agents/penetration-tester.md +103 -77
  21. package/.agent/agents/performance-optimizer.md +136 -92
  22. package/.agent/agents/performance-reviewer.md +139 -69
  23. package/.agent/agents/product-manager.md +104 -70
  24. package/.agent/agents/product-owner.md +6 -25
  25. package/.agent/agents/project-planner.md +95 -95
  26. package/.agent/agents/qa-automation-engineer.md +174 -87
  27. package/.agent/agents/security-auditor.md +133 -129
  28. package/.agent/agents/seo-specialist.md +160 -99
  29. package/.agent/agents/sql-reviewer.md +132 -44
  30. package/.agent/agents/supervisor-agent.md +137 -109
  31. package/.agent/agents/swarm-worker-contracts.md +17 -17
  32. package/.agent/agents/swarm-worker-registry.md +46 -46
  33. package/.agent/agents/test-coverage-reviewer.md +132 -53
  34. package/.agent/agents/test-engineer.md +0 -21
  35. package/.agent/agents/type-safety-reviewer.md +143 -33
  36. package/.agent/patterns/generator.md +9 -9
  37. package/.agent/patterns/inversion.md +12 -12
  38. package/.agent/patterns/pipeline.md +9 -9
  39. package/.agent/patterns/reviewer.md +13 -13
  40. package/.agent/patterns/tool-wrapper.md +9 -9
  41. package/.agent/rules/GEMINI.md +63 -63
  42. package/.agent/scripts/__pycache__/auto_preview.cpython-311.pyc +0 -0
  43. package/.agent/scripts/__pycache__/bundle_analyzer.cpython-311.pyc +0 -0
  44. package/.agent/scripts/__pycache__/checklist.cpython-311.pyc +0 -0
  45. package/.agent/scripts/__pycache__/dependency_analyzer.cpython-311.pyc +0 -0
  46. package/.agent/scripts/__pycache__/security_scan.cpython-311.pyc +0 -0
  47. package/.agent/scripts/__pycache__/session_manager.cpython-311.pyc +0 -0
  48. package/.agent/scripts/__pycache__/skill_integrator.cpython-311.pyc +0 -0
  49. package/.agent/scripts/__pycache__/swarm_dispatcher.cpython-311.pyc +0 -0
  50. package/.agent/scripts/__pycache__/test_runner.cpython-311.pyc +0 -0
  51. package/.agent/scripts/__pycache__/verify_all.cpython-311.pyc +0 -0
  52. package/.agent/scripts/compress_skills.py +167 -0
  53. package/.agent/scripts/consolidate_skills.py +173 -0
  54. package/.agent/scripts/deep_compress.py +202 -0
  55. package/.agent/scripts/minify_context.py +80 -0
  56. package/.agent/scripts/security_scan.py +1 -1
  57. package/.agent/scripts/strip_tribunal.py +41 -0
  58. package/.agent/skills/agent-organizer/SKILL.md +60 -100
  59. package/.agent/skills/agentic-patterns/SKILL.md +0 -70
  60. package/.agent/skills/ai-prompt-injection-defense/SKILL.md +108 -53
  61. package/.agent/skills/api-patterns/SKILL.md +197 -257
  62. package/.agent/skills/api-security-auditor/SKILL.md +125 -57
  63. package/.agent/skills/app-builder/SKILL.md +326 -50
  64. package/.agent/skills/app-builder/templates/SKILL.md +13 -15
  65. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +16 -16
  66. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +22 -22
  67. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +18 -18
  68. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +20 -20
  69. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +17 -17
  70. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +18 -18
  71. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +21 -21
  72. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +19 -19
  73. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +26 -26
  74. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +26 -26
  75. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +19 -19
  76. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +18 -18
  77. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +20 -20
  78. package/.agent/skills/appflow-wireframe/SKILL.md +71 -98
  79. package/.agent/skills/architecture/SKILL.md +161 -200
  80. package/.agent/skills/authentication-best-practices/SKILL.md +121 -54
  81. package/.agent/skills/bash-linux/SKILL.md +71 -166
  82. package/.agent/skills/behavioral-modes/SKILL.md +8 -69
  83. package/.agent/skills/brainstorming/SKILL.md +345 -127
  84. package/.agent/skills/building-native-ui/SKILL.md +125 -57
  85. package/.agent/skills/clean-code/SKILL.md +266 -149
  86. package/.agent/skills/code-review-checklist/SKILL.md +0 -62
  87. package/.agent/skills/config-validator/SKILL.md +73 -131
  88. package/.agent/skills/csharp-developer/SKILL.md +434 -73
  89. package/.agent/skills/database-design/SKILL.md +190 -275
  90. package/.agent/skills/deployment-procedures/SKILL.md +81 -158
  91. package/.agent/skills/devops-engineer/SKILL.md +255 -94
  92. package/.agent/skills/devops-incident-responder/SKILL.md +50 -69
  93. package/.agent/skills/doc.md +5 -5
  94. package/.agent/skills/documentation-templates/SKILL.md +19 -63
  95. package/.agent/skills/edge-computing/SKILL.md +75 -165
  96. package/.agent/skills/extract-design-system/SKILL.md +84 -58
  97. package/.agent/skills/framer-motion-expert/SKILL.md +195 -0
  98. package/.agent/skills/frontend-design/SKILL.md +151 -499
  99. package/.agent/skills/game-design-expert/SKILL.md +71 -0
  100. package/.agent/skills/game-engineering-expert/SKILL.md +88 -0
  101. package/.agent/skills/geo-fundamentals/SKILL.md +52 -178
  102. package/.agent/skills/github-operations/SKILL.md +197 -272
  103. package/.agent/skills/gsap-expert/SKILL.md +194 -0
  104. package/.agent/skills/i18n-localization/SKILL.md +60 -172
  105. package/.agent/skills/intelligent-routing/SKILL.md +123 -103
  106. package/.agent/skills/lint-and-validate/SKILL.md +8 -52
  107. package/.agent/skills/llm-engineering/SKILL.md +281 -195
  108. package/.agent/skills/local-first/SKILL.md +76 -159
  109. package/.agent/skills/mcp-builder/SKILL.md +48 -188
  110. package/.agent/skills/mobile-design/SKILL.md +213 -219
  111. package/.agent/skills/motion-engineering/SKILL.md +184 -0
  112. package/.agent/skills/nextjs-react-expert/SKILL.md +184 -203
  113. package/.agent/skills/nodejs-best-practices/SKILL.md +403 -185
  114. package/.agent/skills/observability/SKILL.md +211 -203
  115. package/.agent/skills/parallel-agents/SKILL.md +53 -146
  116. package/.agent/skills/performance-profiling/SKILL.md +171 -151
  117. package/.agent/skills/plan-writing/SKILL.md +49 -153
  118. package/.agent/skills/platform-engineer/SKILL.md +57 -103
  119. package/.agent/skills/playwright-best-practices/SKILL.md +110 -63
  120. package/.agent/skills/powershell-windows/SKILL.md +61 -179
  121. package/.agent/skills/python-patterns/SKILL.md +7 -35
  122. package/.agent/skills/python-pro/SKILL.md +273 -114
  123. package/.agent/skills/react-specialist/SKILL.md +227 -108
  124. package/.agent/skills/readme-builder/SKILL.md +15 -85
  125. package/.agent/skills/realtime-patterns/SKILL.md +216 -243
  126. package/.agent/skills/red-team-tactics/SKILL.md +10 -51
  127. package/.agent/skills/rust-pro/SKILL.md +525 -142
  128. package/.agent/skills/seo-fundamentals/SKILL.md +92 -153
  129. package/.agent/skills/server-management/SKILL.md +110 -166
  130. package/.agent/skills/shadcn-ui-expert/SKILL.md +154 -55
  131. package/.agent/skills/skill-creator/SKILL.md +18 -58
  132. package/.agent/skills/sql-pro/SKILL.md +543 -68
  133. package/.agent/skills/supabase-postgres-best-practices/SKILL.md +28 -68
  134. package/.agent/skills/swiftui-expert/SKILL.md +124 -57
  135. package/.agent/skills/systematic-debugging/SKILL.md +49 -151
  136. package/.agent/skills/tailwind-patterns/SKILL.md +433 -149
  137. package/.agent/skills/tdd-workflow/SKILL.md +63 -169
  138. package/.agent/skills/test-result-analyzer/SKILL.md +33 -73
  139. package/.agent/skills/testing-patterns/SKILL.md +437 -130
  140. package/.agent/skills/trend-researcher/SKILL.md +30 -71
  141. package/.agent/skills/ui-ux-pro-max/SKILL.md +0 -41
  142. package/.agent/skills/ui-ux-researcher/SKILL.md +51 -91
  143. package/.agent/skills/vue-expert/SKILL.md +225 -119
  144. package/.agent/skills/vulnerability-scanner/SKILL.md +264 -226
  145. package/.agent/skills/web-accessibility-auditor/SKILL.md +141 -58
  146. package/.agent/skills/web-design-guidelines/SKILL.md +17 -61
  147. package/.agent/skills/webapp-testing/SKILL.md +71 -196
  148. package/.agent/skills/whimsy-injector/SKILL.md +58 -132
  149. package/.agent/skills/workflow-optimizer/SKILL.md +28 -68
  150. package/.agent/workflows/api-tester.md +96 -224
  151. package/.agent/workflows/audit.md +81 -122
  152. package/.agent/workflows/brainstorm.md +69 -105
  153. package/.agent/workflows/changelog.md +65 -97
  154. package/.agent/workflows/create.md +73 -88
  155. package/.agent/workflows/debug.md +80 -111
  156. package/.agent/workflows/deploy.md +119 -92
  157. package/.agent/workflows/enhance.md +80 -91
  158. package/.agent/workflows/fix.md +68 -97
  159. package/.agent/workflows/generate.md +165 -164
  160. package/.agent/workflows/migrate.md +106 -109
  161. package/.agent/workflows/orchestrate.md +103 -86
  162. package/.agent/workflows/performance-benchmarker.md +77 -268
  163. package/.agent/workflows/plan.md +120 -98
  164. package/.agent/workflows/preview.md +39 -96
  165. package/.agent/workflows/refactor.md +105 -97
  166. package/.agent/workflows/review-ai.md +63 -102
  167. package/.agent/workflows/review.md +71 -110
  168. package/.agent/workflows/session.md +53 -113
  169. package/.agent/workflows/status.md +42 -88
  170. package/.agent/workflows/strengthen-skills.md +90 -51
  171. package/.agent/workflows/swarm.md +114 -129
  172. package/.agent/workflows/test.md +125 -102
  173. package/.agent/workflows/tribunal-backend.md +60 -78
  174. package/.agent/workflows/tribunal-database.md +62 -100
  175. package/.agent/workflows/tribunal-frontend.md +62 -82
  176. package/.agent/workflows/tribunal-full.md +56 -100
  177. package/.agent/workflows/tribunal-mobile.md +65 -94
  178. package/.agent/workflows/tribunal-performance.md +62 -105
  179. package/.agent/workflows/ui-ux-pro-max.md +72 -121
  180. package/README.md +11 -15
  181. package/package.json +1 -1
  182. package/.agent/skills/api-patterns/api-style.md +0 -42
  183. package/.agent/skills/api-patterns/auth.md +0 -24
  184. package/.agent/skills/api-patterns/documentation.md +0 -26
  185. package/.agent/skills/api-patterns/graphql.md +0 -41
  186. package/.agent/skills/api-patterns/rate-limiting.md +0 -31
  187. package/.agent/skills/api-patterns/response.md +0 -37
  188. package/.agent/skills/api-patterns/rest.md +0 -40
  189. package/.agent/skills/api-patterns/security-testing.md +0 -122
  190. package/.agent/skills/api-patterns/trpc.md +0 -41
  191. package/.agent/skills/api-patterns/versioning.md +0 -22
  192. package/.agent/skills/app-builder/agent-coordination.md +0 -71
  193. package/.agent/skills/app-builder/feature-building.md +0 -53
  194. package/.agent/skills/app-builder/project-detection.md +0 -34
  195. package/.agent/skills/app-builder/scaffolding.md +0 -118
  196. package/.agent/skills/app-builder/tech-stack.md +0 -40
  197. package/.agent/skills/architecture/context-discovery.md +0 -43
  198. package/.agent/skills/architecture/examples.md +0 -94
  199. package/.agent/skills/architecture/pattern-selection.md +0 -68
  200. package/.agent/skills/architecture/patterns-reference.md +0 -50
  201. package/.agent/skills/architecture/trade-off-analysis.md +0 -77
  202. package/.agent/skills/brainstorming/dynamic-questioning.md +0 -360
  203. package/.agent/skills/database-design/database-selection.md +0 -43
  204. package/.agent/skills/database-design/indexing.md +0 -39
  205. package/.agent/skills/database-design/migrations.md +0 -48
  206. package/.agent/skills/database-design/optimization.md +0 -36
  207. package/.agent/skills/database-design/orm-selection.md +0 -30
  208. package/.agent/skills/database-design/schema-design.md +0 -56
  209. package/.agent/skills/dotnet-core-expert/SKILL.md +0 -103
  210. package/.agent/skills/framer-motion-animations/SKILL.md +0 -74
  211. package/.agent/skills/frontend-design/animation-guide.md +0 -331
  212. package/.agent/skills/frontend-design/color-system.md +0 -329
  213. package/.agent/skills/frontend-design/decision-trees.md +0 -418
  214. package/.agent/skills/frontend-design/motion-graphics.md +0 -306
  215. package/.agent/skills/frontend-design/typography-system.md +0 -363
  216. package/.agent/skills/frontend-design/ux-psychology.md +0 -1116
  217. package/.agent/skills/frontend-design/visual-effects.md +0 -383
  218. package/.agent/skills/game-development/2d-games/SKILL.md +0 -119
  219. package/.agent/skills/game-development/3d-games/SKILL.md +0 -135
  220. package/.agent/skills/game-development/SKILL.md +0 -236
  221. package/.agent/skills/game-development/game-art/SKILL.md +0 -185
  222. package/.agent/skills/game-development/game-audio/SKILL.md +0 -190
  223. package/.agent/skills/game-development/game-design/SKILL.md +0 -129
  224. package/.agent/skills/game-development/mobile-games/SKILL.md +0 -108
  225. package/.agent/skills/game-development/multiplayer/SKILL.md +0 -132
  226. package/.agent/skills/game-development/pc-games/SKILL.md +0 -144
  227. package/.agent/skills/game-development/vr-ar/SKILL.md +0 -123
  228. package/.agent/skills/game-development/web-games/SKILL.md +0 -150
  229. package/.agent/skills/intelligent-routing/router-manifest.md +0 -65
  230. package/.agent/skills/mobile-design/decision-trees.md +0 -516
  231. package/.agent/skills/mobile-design/mobile-backend.md +0 -491
  232. package/.agent/skills/mobile-design/mobile-color-system.md +0 -420
  233. package/.agent/skills/mobile-design/mobile-debugging.md +0 -122
  234. package/.agent/skills/mobile-design/mobile-design-thinking.md +0 -357
  235. package/.agent/skills/mobile-design/mobile-navigation.md +0 -458
  236. package/.agent/skills/mobile-design/mobile-performance.md +0 -767
  237. package/.agent/skills/mobile-design/mobile-testing.md +0 -356
  238. package/.agent/skills/mobile-design/mobile-typography.md +0 -433
  239. package/.agent/skills/mobile-design/platform-android.md +0 -666
  240. package/.agent/skills/mobile-design/platform-ios.md +0 -561
  241. package/.agent/skills/mobile-design/touch-psychology.md +0 -537
  242. package/.agent/skills/nextjs-react-expert/1-async-eliminating-waterfalls.md +0 -312
  243. package/.agent/skills/nextjs-react-expert/2-bundle-bundle-size-optimization.md +0 -240
  244. package/.agent/skills/nextjs-react-expert/3-server-server-side-performance.md +0 -490
  245. package/.agent/skills/nextjs-react-expert/4-client-client-side-data-fetching.md +0 -264
  246. package/.agent/skills/nextjs-react-expert/5-rerender-re-render-optimization.md +0 -581
  247. package/.agent/skills/nextjs-react-expert/6-rendering-rendering-performance.md +0 -432
  248. package/.agent/skills/nextjs-react-expert/7-js-javascript-performance.md +0 -684
  249. package/.agent/skills/nextjs-react-expert/8-advanced-advanced-patterns.md +0 -150
  250. package/.agent/skills/vulnerability-scanner/checklists.md +0 -121
@@ -1,72 +1,293 @@
1
1
  ---
2
2
  name: rust-pro
3
- description: Master Rust 1.75+ with modern async patterns, advanced type system features, and production-ready systems programming. Expert in the latest Rust ecosystem including Tokio, axum, and cutting-edge crates. Use PROACTIVELY for Rust development, performance optimization, or systems programming.
3
+ description: Master Rust 1.75+ with modern async patterns, ownership/borrowing, lifetimes, traits, error handling with thiserror/anyhow, async Tokio runtime, axum web framework, serde serialization, and systems programming. Use when building Rust services, CLI tools, WebAssembly, or performance-critical systems.
4
4
  allowed-tools: Read, Write, Edit, Glob, Grep
5
- version: 1.0.0
6
- last-updated: 2026-03-12
5
+ version: 2.0.0
6
+ last-updated: 2026-03-30
7
7
  applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
8
8
  ---
9
9
 
10
- # Rust DevelopmentProduction Principles
11
-
12
- > Rust's compiler is not your enemy. It is the most thorough code reviewer you will ever have.
13
- > Learn to read its errors as design feedback, not roadblocks.
10
+ # Rust ProRust 1.75+ Systems Mastery
14
11
 
15
12
  ---
16
13
 
17
- ## Ownership in Practice
14
+ ## Ownership & Borrowing
18
15
 
19
- The borrow checker enforces rules that prevent entire categories of bugs:
16
+ ### The Three Rules
20
17
 
21
18
  ```rust
22
- // Rule 1: Each value has exactly one owner
19
+ // Rule 1: Each value has exactly ONE owner
23
20
  let s1 = String::from("hello");
24
- let s2 = s1; // s1 is moved — no longer valid
25
- // println!("{}", s1); // ❌ compile error: value used after move
21
+ let s2 = s1; // s1 is MOVED to s2 s1 is no longer valid
22
+ // println!("{s1}"); // ❌ compile error: value borrowed after move
23
+
24
+ // Rule 2: You can have EITHER one mutable reference OR any number of immutable references
25
+ let mut data = vec![1, 2, 3];
26
+ let r1 = &data; // ✅ immutable borrow
27
+ let r2 = &data; // ✅ second immutable borrow — fine
28
+ // let r3 = &mut data; // ❌ compile error: cannot borrow as mutable while immutable borrows exist
29
+ println!("{r1:?} {r2:?}");
30
+ // r1 and r2 go out of scope here (NLL — Non-Lexical Lifetimes)
31
+ let r3 = &mut data; // ✅ now fine — no immutable borrows active
32
+ r3.push(4);
33
+
34
+ // Rule 3: References must always be valid (no dangling pointers)
35
+ // fn dangling() -> &String { // ❌ compile error
36
+ // let s = String::from("hello");
37
+ // &s // s is dropped at end of function — reference would dangle
38
+ // }
39
+ fn not_dangling() -> String {
40
+ String::from("hello") // ✅ return owned value
41
+ }
42
+ ```
43
+
44
+ ### Common Ownership Patterns
45
+
46
+ ```rust
47
+ // Clone when you need independent copies (has a cost — measure)
48
+ let original = vec![1, 2, 3];
49
+ let copy = original.clone(); // deep copy — both are independent
50
+
51
+ // Rc<T> — shared ownership (single-threaded)
52
+ use std::rc::Rc;
53
+ let shared = Rc::new(vec![1, 2, 3]);
54
+ let also_shared = Rc::clone(&shared); // cheap reference count increment
55
+ // Both shared and also_shared point to the same data
56
+
57
+ // Arc<T> — shared ownership (thread-safe)
58
+ use std::sync::Arc;
59
+ let thread_safe = Arc::new(vec![1, 2, 3]);
60
+ let for_thread = Arc::clone(&thread_safe);
61
+ std::thread::spawn(move || {
62
+ println!("{for_thread:?}");
63
+ });
64
+
65
+ // Cow<T> — Clone on Write (zero-copy when not modified)
66
+ use std::borrow::Cow;
67
+ fn process(input: &str) -> Cow<'_, str> {
68
+ if input.contains("bad") {
69
+ Cow::Owned(input.replace("bad", "good")) // allocated only if needed
70
+ } else {
71
+ Cow::Borrowed(input) // zero-copy
72
+ }
73
+ }
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Lifetimes
79
+
80
+ ```rust
81
+ // Lifetime annotations tell the compiler how long references are valid
82
+ // They DON'T change how long values live — they DESCRIBE existing relationships
83
+
84
+ // ✅ Explicit lifetime: return value lives as long as the input
85
+ fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
86
+ if x.len() > y.len() { x } else { y }
87
+ }
26
88
 
27
- // Rule 2: Borrowing multiple readers OR one writer
28
- let s = String::from("hello");
29
- let r1 = &s; // immutable borrow — fine
30
- let r2 = &s; // second immutable borrow — fine
31
- // let r3 = &mut s; // ❌ can't borrow mutably while immutably borrowed
32
- println!("{} {}", r1, r2);
33
- let r3 = &mut s.clone(); // ✅ clone to get a new owned value
89
+ // Struct with references (requires lifetime annotation)
90
+ struct Config<'a> {
91
+ name: &'a str,
92
+ version: &'a str,
93
+ }
94
+
95
+ impl<'a> Config<'a> {
96
+ fn display(&self) -> String {
97
+ format!("{} v{}", self.name, self.version)
98
+ }
99
+ }
100
+
101
+ // 'static lifetime — lives for the entire program
102
+ let s: &'static str = "I live forever"; // string literals are 'static
103
+ // Owned types satisfy 'static (they own their data)
104
+ fn takes_static(s: String) { /* String is 'static because it owns its data */ }
105
+
106
+ // ❌ HALLUCINATION TRAP: Lifetime elision rules handle most cases
107
+ // Don't add lifetimes unless the compiler asks for them
108
+ // The compiler tells you exactly which annotations are needed
34
109
  ```
35
110
 
36
111
  ---
37
112
 
38
113
  ## Error Handling
39
114
 
40
- Rust has no exceptions. Errors are values. Design for them explicitly.
115
+ ### The `?` Operator & Result
41
116
 
42
117
  ```rust
118
+ use std::fs;
43
119
  use std::io;
120
+
121
+ // ✅ Propagate errors with ?
122
+ fn read_config(path: &str) -> Result<Config, io::Error> {
123
+ let content = fs::read_to_string(path)?; // returns early on error
124
+ let config: Config = serde_json::from_str(&content)?;
125
+ Ok(config)
126
+ }
127
+
128
+ // ❌ HALLUCINATION TRAP: NEVER use .unwrap() in production code
129
+ // .unwrap() panics on error — crashes the entire program
130
+ // ❌ let file = File::open("config.json").unwrap();
131
+ // ✅ let file = File::open("config.json")?;
132
+ // ✅ let file = File::open("config.json").unwrap_or_default();
133
+ // ✅ let file = File::open("config.json").map_err(|e| AppError::Io(e))?;
134
+ ```
135
+
136
+ ### thiserror (Library Errors)
137
+
138
+ ```rust
139
+ // thiserror — for library code (structured error types)
44
140
  use thiserror::Error;
45
141
 
46
- // Define domain errors with thiserror
47
- #[derive(Error, Debug)]
142
+ #[derive(Debug, Error)]
48
143
  pub enum AppError {
49
- #[error("User {0} not found")]
50
- UserNotFound(String),
51
-
52
144
  #[error("Database error: {0}")]
53
145
  Database(#[from] sqlx::Error),
54
-
146
+
147
+ #[error("Validation error: {field} — {message}")]
148
+ Validation { field: String, message: String },
149
+
150
+ #[error("Not found: {0}")]
151
+ NotFound(String),
152
+
153
+ #[error("Unauthorized")]
154
+ Unauthorized,
155
+
55
156
  #[error("IO error: {0}")]
56
- Io(#[from] io::Error),
157
+ Io(#[from] std::io::Error),
158
+
159
+ #[error("JSON error: {0}")]
160
+ Json(#[from] serde_json::Error),
57
161
  }
58
162
 
59
- // Return Result in every function that can fail
60
- async fn get_user(id: &str) -> Result<User, AppError> {
61
- let user = db.find_user(id).await?; // the `?` operator propagates errors
62
- user.ok_or_else(|| AppError::UserNotFound(id.to_string()))
163
+ // #[from] auto-implements From<sqlx::Error> for AppError
164
+ // So sqlx errors can be propagated with ? automatically
165
+ ```
166
+
167
+ ### anyhow (Application Errors)
168
+
169
+ ```rust
170
+ // anyhow — for application code (quick error propagation)
171
+ use anyhow::{Context, Result, bail, ensure};
172
+
173
+ fn load_config(path: &str) -> Result<Config> {
174
+ let content = fs::read_to_string(path)
175
+ .context(format!("Failed to read config from {path}"))?;
176
+
177
+ let config: Config = serde_json::from_str(&content)
178
+ .context("Invalid JSON in config file")?;
179
+
180
+ ensure!(config.port > 0, "Port must be positive, got {}", config.port);
181
+
182
+ if config.name.is_empty() {
183
+ bail!("Config name cannot be empty");
184
+ }
185
+
186
+ Ok(config)
187
+ }
188
+
189
+ // Use thiserror for libraries, anyhow for applications
190
+ // ❌ HALLUCINATION TRAP: Don't use anyhow in library crates
191
+ // Libraries should expose structured error types (thiserror)
192
+ // anyhow erases type information — callers can't match on specific errors
193
+ ```
194
+
195
+ ---
196
+
197
+ ## Traits
198
+
199
+ ### Defining & Implementing
200
+
201
+ ```rust
202
+ trait Summarizable {
203
+ fn summary(&self) -> String;
204
+
205
+ // Default implementation
206
+ fn preview(&self) -> String {
207
+ let s = self.summary();
208
+ if s.len() > 50 {
209
+ format!("{}...", &s[..50])
210
+ } else {
211
+ s
212
+ }
213
+ }
63
214
  }
64
215
 
65
- // In main or handlers: match on the error
66
- match get_user("123").await {
67
- Ok(user) => println!("Found: {}", user.name),
68
- Err(AppError::UserNotFound(id)) => eprintln!("No user: {}", id),
69
- Err(e) => eprintln!("Unexpected error: {}", e),
216
+ struct Article {
217
+ title: String,
218
+ body: String,
219
+ author: String,
220
+ }
221
+
222
+ impl Summarizable for Article {
223
+ fn summary(&self) -> String {
224
+ format!("{} by {} — {}", self.title, self.author, &self.body[..100.min(self.body.len())])
225
+ }
226
+ }
227
+
228
+ // Trait bounds
229
+ fn notify(item: &impl Summarizable) {
230
+ println!("Breaking: {}", item.summary());
231
+ }
232
+
233
+ // Equivalent with generics (more flexible)
234
+ fn notify_generic<T: Summarizable + std::fmt::Display>(item: &T) {
235
+ println!("Breaking: {}", item.summary());
236
+ }
237
+
238
+ // where clause (cleaner for complex bounds)
239
+ fn process<T, U>(t: &T, u: &U) -> String
240
+ where
241
+ T: Summarizable + Clone,
242
+ U: std::fmt::Debug + Send,
243
+ {
244
+ format!("{} — {:?}", t.summary(), u)
245
+ }
246
+
247
+ // Return impl Trait (hide concrete type)
248
+ fn make_summarizer() -> impl Summarizable {
249
+ Article { title: "News".into(), body: "Content".into(), author: "Author".into() }
250
+ }
251
+ ```
252
+
253
+ ### Common Standard Traits
254
+
255
+ ```rust
256
+ // Derive common traits
257
+ #[derive(Debug, Clone, PartialEq, Eq, Hash)]
258
+ struct Point {
259
+ x: i32,
260
+ y: i32,
261
+ }
262
+
263
+ // Display — for user-facing output
264
+ use std::fmt;
265
+ impl fmt::Display for Point {
266
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
267
+ write!(f, "({}, {})", self.x, self.y)
268
+ }
269
+ }
270
+
271
+ // From/Into — type conversion
272
+ impl From<(i32, i32)> for Point {
273
+ fn from((x, y): (i32, i32)) -> Self {
274
+ Point { x, y }
275
+ }
276
+ }
277
+ let p: Point = (10, 20).into(); // uses From automatically
278
+
279
+ // Iterator
280
+ struct Counter { count: u32, max: u32 }
281
+ impl Iterator for Counter {
282
+ type Item = u32;
283
+ fn next(&mut self) -> Option<Self::Item> {
284
+ if self.count < self.max {
285
+ self.count += 1;
286
+ Some(self.count)
287
+ } else {
288
+ None
289
+ }
290
+ }
70
291
  }
71
292
  ```
72
293
 
@@ -74,167 +295,329 @@ match get_user("123").await {
74
295
 
75
296
  ## Async with Tokio
76
297
 
298
+ ### Runtime Setup
299
+
77
300
  ```rust
78
- use tokio;
301
+ // Cargo.toml
302
+ // [dependencies]
303
+ // tokio = { version = "1", features = ["full"] }
79
304
 
80
305
  #[tokio::main]
81
306
  async fn main() {
82
- // Concurrent tasks — run independently
83
- let (result_a, result_b) = tokio::join!(
84
- fetch_user(1),
85
- fetch_products()
307
+ let result = fetch_data("https://api.example.com/data").await;
308
+ println!("{result:?}");
309
+ }
310
+
311
+ // For library code — don't use #[tokio::main], let the caller choose the runtime
312
+ pub async fn fetch_data(url: &str) -> Result<String> {
313
+ let response = reqwest::get(url).await?;
314
+ let body = response.text().await?;
315
+ Ok(body)
316
+ }
317
+ ```
318
+
319
+ ### Concurrent Tasks
320
+
321
+ ```rust
322
+ use tokio::task;
323
+
324
+ // Spawn concurrent tasks
325
+ async fn parallel_fetch() -> Result<(Users, Posts)> {
326
+ let users_handle = task::spawn(async { fetch_users().await });
327
+ let posts_handle = task::spawn(async { fetch_posts().await });
328
+
329
+ let users = users_handle.await??; // first ? for JoinError, second for app error
330
+ let posts = posts_handle.await??;
331
+
332
+ Ok((users, posts))
333
+ }
334
+
335
+ // tokio::join! — run concurrently, wait for all
336
+ async fn fetch_all() -> Result<(Users, Posts, Analytics)> {
337
+ let (users, posts, analytics) = tokio::join!(
338
+ fetch_users(),
339
+ fetch_posts(),
340
+ fetch_analytics(),
86
341
  );
342
+ Ok((users?, posts?, analytics?))
343
+ }
344
+
345
+ // tokio::select! — race multiple futures, take first to complete
346
+ async fn fetch_with_timeout(url: &str) -> Result<String> {
347
+ tokio::select! {
348
+ result = fetch_data(url) => result,
349
+ _ = tokio::time::sleep(Duration::from_secs(5)) => {
350
+ Err(anyhow!("Request timed out after 5s"))
351
+ }
352
+ }
353
+ }
354
+
355
+ // ❌ HALLUCINATION TRAP: tokio::spawn requires 'static + Send
356
+ // You cannot spawn a task referencing local variables without Arc/clone
357
+ // ❌ let data = &local_data;
358
+ // tokio::spawn(async { process(data) }); // ❌ data doesn't live long enough
359
+ // ✅ let data = Arc::new(local_data);
360
+ // let data_clone = Arc::clone(&data);
361
+ // tokio::spawn(async move { process(&data_clone) });
362
+ ```
363
+
364
+ ### Channels
365
+
366
+ ```rust
367
+ use tokio::sync::{mpsc, oneshot, broadcast};
87
368
 
88
- // Spawn a background task
89
- let handle = tokio::spawn(async {
90
- background_work().await
369
+ // mpsc Multiple Producer, Single Consumer
370
+ async fn worker_pattern() {
371
+ let (tx, mut rx) = mpsc::channel::<String>(32); // buffer size
372
+
373
+ tokio::spawn(async move {
374
+ tx.send("hello".to_string()).await.unwrap();
375
+ tx.send("world".to_string()).await.unwrap();
91
376
  });
92
377
 
93
- // With timeout
94
- use tokio::time::{timeout, Duration};
95
- let result = timeout(Duration::from_secs(5), slow_operation()).await;
96
- match result {
97
- Ok(Ok(val)) => println!("Got: {}", val),
98
- Ok(Err(e)) => eprintln!("Operation failed: {}", e),
99
- Err(_) => eprintln!("Timed out"),
378
+ while let Some(msg) = rx.recv().await {
379
+ println!("Got: {msg}");
100
380
  }
101
381
  }
382
+
383
+ // oneshot — single response (request/response pattern)
384
+ async fn request_response() {
385
+ let (tx, rx) = oneshot::channel::<String>();
386
+
387
+ tokio::spawn(async move {
388
+ let result = expensive_computation().await;
389
+ tx.send(result).unwrap();
390
+ });
391
+
392
+ let response = rx.await.unwrap();
393
+ }
394
+
395
+ // Mutex (async-safe)
396
+ use tokio::sync::Mutex;
397
+ let shared_state = Arc::new(Mutex::new(Vec::new()));
398
+
399
+ let state = Arc::clone(&shared_state);
400
+ tokio::spawn(async move {
401
+ let mut guard = state.lock().await;
402
+ guard.push("item");
403
+ }); // lock released when guard is dropped
102
404
  ```
103
405
 
104
406
  ---
105
407
 
106
- ## HTTP Server with axum
408
+ ## Axum Web Framework
409
+
410
+ ### Basic Server
107
411
 
108
412
  ```rust
109
- use axum::{Router, routing::get, routing::post, Json, extract::State};
110
- use std::sync::Arc;
413
+ use axum::{
414
+ extract::{Path, Query, State, Json},
415
+ http::StatusCode,
416
+ response::IntoResponse,
417
+ routing::{get, post, delete},
418
+ Router,
419
+ };
420
+ use serde::{Deserialize, Serialize};
111
421
 
112
422
  #[derive(Clone)]
113
423
  struct AppState {
114
- db: Arc<Database>,
424
+ db: sqlx::PgPool,
115
425
  }
116
426
 
117
427
  #[tokio::main]
118
428
  async fn main() {
119
- let state = AppState { db: Arc::new(Database::connect().await.unwrap()) };
429
+ let pool = sqlx::PgPool::connect("postgres://localhost/mydb").await.unwrap();
430
+ let state = AppState { db: pool };
120
431
 
121
432
  let app = Router::new()
122
433
  .route("/users", get(list_users).post(create_user))
123
- .route("/users/:id", get(get_user))
434
+ .route("/users/{id}", get(get_user).delete(delete_user))
124
435
  .with_state(state);
125
436
 
126
- axum::serve(
127
- tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap(),
128
- app,
129
- ).await.unwrap();
437
+ let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
438
+ axum::serve(listener, app).await.unwrap();
130
439
  }
131
440
 
132
- async fn get_user(
133
- State(state): State<AppState>,
134
- axum::extract::Path(id): axum::extract::Path<String>,
135
- ) -> Result<Json<User>, StatusCode> {
136
- state.db.find_user(&id).await
137
- .map(Json)
138
- .map_err(|_| StatusCode::NOT_FOUND)
139
- }
441
+ // HALLUCINATION TRAP: axum 0.7+ uses {id} not :id for path params
442
+ // ❌ .route("/users/:id", ...) old syntax
443
+ // ✅ .route("/users/{id}", ...) axum 0.7+
140
444
  ```
141
445
 
142
- ---
446
+ ### Handlers
143
447
 
144
- ## Common Pitfalls
448
+ ```rust
449
+ #[derive(Deserialize)]
450
+ struct ListParams {
451
+ page: Option<u32>,
452
+ limit: Option<u32>,
453
+ }
145
454
 
146
- | Pitfall | What Happens | Fix |
147
- |---|---|---|
148
- | `.clone()` everywhere | Hides ownership problems, creates heap allocations | Use references `&T` where ownership isn't needed |
149
- | `unwrap()` in production | Panics on None/Err — crashes the process | Use `?` or match and return proper errors |
150
- | Blocking in async | `std::thread::sleep` blocks the Tokio runtime | Use `tokio::time::sleep().await` |
151
- | `Arc<Mutex<T>>` contention | Mutex held across await points causes deadlocks | Hold locks for minimum duration, never across `.await` |
455
+ async fn list_users(
456
+ State(state): State<AppState>,
457
+ Query(params): Query<ListParams>,
458
+ ) -> Result<Json<Vec<User>>, AppError> {
459
+ let page = params.page.unwrap_or(1);
460
+ let limit = params.limit.unwrap_or(20).min(100);
461
+ let offset = (page - 1) * limit;
462
+
463
+ let users = sqlx::query_as!(
464
+ User,
465
+ "SELECT id, name, email FROM users ORDER BY id LIMIT $1 OFFSET $2",
466
+ limit as i64,
467
+ offset as i64,
468
+ )
469
+ .fetch_all(&state.db)
470
+ .await?;
471
+
472
+ Ok(Json(users))
473
+ }
152
474
 
153
- ---
475
+ #[derive(Deserialize)]
476
+ struct CreateUserPayload {
477
+ name: String,
478
+ email: String,
479
+ }
154
480
 
155
- ## Project Structure
481
+ async fn create_user(
482
+ State(state): State<AppState>,
483
+ Json(payload): Json<CreateUserPayload>,
484
+ ) -> Result<(StatusCode, Json<User>), AppError> {
485
+ let user = sqlx::query_as!(
486
+ User,
487
+ "INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id, name, email",
488
+ payload.name,
489
+ payload.email,
490
+ )
491
+ .fetch_one(&state.db)
492
+ .await?;
493
+
494
+ Ok((StatusCode::CREATED, Json(user)))
495
+ }
156
496
 
497
+ async fn get_user(
498
+ State(state): State<AppState>,
499
+ Path(id): Path<i32>,
500
+ ) -> Result<Json<User>, AppError> {
501
+ let user = sqlx::query_as!(User, "SELECT id, name, email FROM users WHERE id = $1", id)
502
+ .fetch_optional(&state.db)
503
+ .await?
504
+ .ok_or(AppError::NotFound(format!("User {id}")))?;
505
+
506
+ Ok(Json(user))
507
+ }
157
508
  ```
158
- src/
159
- main.rs Entry point — thin, just wires up the server
160
- lib.rs Re-exports for library usage
161
- handlers/ HTTP request handlers (thin — parse, call service, return response)
162
- services/ Business logic (no HTTP awareness)
163
- repositories/ Database queries
164
- models/ Data structures and validation
165
- errors.rs Unified error type
166
- config.rs Settings loaded from environment
167
509
 
168
- Cargo.toml Dependencies
169
- ```
510
+ ### Error Handling in Axum
170
511
 
171
- ---
512
+ ```rust
513
+ use axum::response::{IntoResponse, Response};
172
514
 
173
- ## Essential Crates
515
+ #[derive(Debug, thiserror::Error)]
516
+ pub enum AppError {
517
+ #[error("Not found: {0}")]
518
+ NotFound(String),
519
+ #[error("Validation: {0}")]
520
+ Validation(String),
521
+ #[error("Database: {0}")]
522
+ Database(#[from] sqlx::Error),
523
+ #[error("Internal: {0}")]
524
+ Internal(#[from] anyhow::Error),
525
+ }
174
526
 
175
- | Crate | Purpose |
176
- |---|---|
177
- | `tokio` | Async runtime |
178
- | `axum` | Web framework |
179
- | `sqlx` | Async SQL with compile-time query checking |
180
- | `serde` + `serde_json` | Serialization |
181
- | `thiserror` | Ergonomic error definitions |
182
- | `anyhow` | Error handling in binaries/scripts (not libraries) |
183
- | `tracing` | Structured async-aware logging |
184
- | `config` | Hierarchical configuration from env/files |
527
+ impl IntoResponse for AppError {
528
+ fn into_response(self) -> Response {
529
+ let (status, message) = match &self {
530
+ AppError::NotFound(msg) => (StatusCode::NOT_FOUND, msg.clone()),
531
+ AppError::Validation(msg) => (StatusCode::BAD_REQUEST, msg.clone()),
532
+ AppError::Database(e) => {
533
+ tracing::error!("DB error: {e}"); // log internal details
534
+ (StatusCode::INTERNAL_SERVER_ERROR, "Database error".to_string())
535
+ }
536
+ AppError::Internal(e) => {
537
+ tracing::error!("Internal error: {e}");
538
+ (StatusCode::INTERNAL_SERVER_ERROR, "Internal error".to_string())
539
+ }
540
+ };
541
+
542
+ (status, Json(serde_json::json!({ "error": message }))).into_response()
543
+ }
544
+ }
545
+ ```
185
546
 
186
547
  ---
187
548
 
188
- ## Output Format
189
-
190
- When this skill produces or reviews code, structure your output as follows:
549
+ ## Serde (Serialization)
191
550
 
192
- ```
193
- ━━━ Rust Pro Report ━━━━━━━━━━━━━━━━━━━━━━━━
194
- Skill: Rust Pro
195
- Language: [detected language / framework]
196
- Scope: [N files · N functions]
197
- ─────────────────────────────────────────────────
198
- ✅ Passed: [checks that passed, or "All clean"]
199
- ⚠️ Warnings: [non-blocking issues, or "None"]
200
- ❌ Blocked: [blocking issues requiring fix, or "None"]
201
- ─────────────────────────────────────────────────
202
- VBC status: PENDING → VERIFIED
203
- Evidence: [test output / lint pass / compile success]
204
- ```
551
+ ```rust
552
+ use serde::{Deserialize, Serialize};
205
553
 
206
- **VBC (Verification-Before-Completion) is mandatory.**
207
- Do not mark status as VERIFIED until concrete terminal evidence is provided.
554
+ #[derive(Debug, Serialize, Deserialize)]
555
+ #[serde(rename_all = "camelCase")] // JSON uses camelCase
556
+ struct UserResponse {
557
+ user_id: i32, // serialized as "userId"
558
+ full_name: String, // serialized as "fullName"
559
+ email: String,
208
560
 
561
+ #[serde(skip_serializing_if = "Option::is_none")]
562
+ phone: Option<String>, // omitted from JSON if None
209
563
 
210
- ---
564
+ #[serde(default)] // defaults to 0 if missing in input
565
+ login_count: u32,
211
566
 
212
- ## 🏛️ Tribunal Integration (Anti-Hallucination)
567
+ #[serde(rename = "type")] // rename for reserved keywords
568
+ user_type: String,
213
569
 
214
- **Slash command: `/tribunal-backend`**
215
- **Active reviewers: `logic` · `security` · `memory` · `type-safety`**
570
+ #[serde(skip)] // never serialized/deserialized
571
+ internal_token: String,
572
+ }
216
573
 
217
- ### Forbidden AI Tropes in Rust
574
+ // Enum serialization
575
+ #[derive(Serialize, Deserialize)]
576
+ #[serde(tag = "type", content = "data")] // adjacently tagged
577
+ enum Event {
578
+ #[serde(rename = "user_created")]
579
+ UserCreated { id: i32, name: String },
580
+ #[serde(rename = "user_deleted")]
581
+ UserDeleted { id: i32 },
582
+ }
583
+ // Serializes as: {"type": "user_created", "data": {"id": 1, "name": "Alice"}}
584
+ ```
218
585
 
219
- 1. **`unwrap()`/`expect()` in production code** — hiding errors instead of propagating them with `?`.
220
- 2. **`.clone()` everywhere** — blindly copying data instead of reasoning about lifetimes and borrows.
221
- 3. **`Arc<Mutex<T>>` overuse** — wrapping everything in locks instead of passing ownership or using channels.
222
- 4. **Blocking the Tokio runtime** — using `std::thread::sleep` or sync I/O inside an `async` function.
223
- 5. **Over-complex trait bounds** — creating massive generic trait puzzles instead of concrete types when generics aren't needed.
586
+ ---
224
587
 
225
- ### Pre-Flight Self-Audit
588
+ ## Iterator Patterns
226
589
 
227
- Review these questions before generating Rust code:
228
- ```
229
- ✅ Did I properly propagate errors using `Result` and the `?` operator?
230
- Is the Tokio runtime safe from being blocked by my code?
231
- Did I avoid unnecessary `.clone()` calls by borrowing (`&T`) appropriately?
232
- Are my error types properly implemented (e.g., using `thiserror`)?
233
- Did I keep the lock durations on Mutexes as short as possible and never across `.await` points?
590
+ ```rust
591
+ let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
592
+
593
+ // Chain operations (lazy no allocation until collect)
594
+ let result: Vec<i32> = numbers.iter()
595
+ .filter(|&&n| n % 2 == 0) // keep even
596
+ .map(|&n| n * n) // square
597
+ .take(3) // first 3
598
+ .collect(); // [4, 16, 36]
599
+
600
+ // fold (reduce)
601
+ let sum: i32 = numbers.iter().fold(0, |acc, &n| acc + n);
602
+
603
+ // find / position
604
+ let first_even = numbers.iter().find(|&&n| n % 2 == 0); // Some(&2)
605
+ let pos = numbers.iter().position(|&n| n > 5); // Some(5)
606
+
607
+ // chunk / window
608
+ let chunks: Vec<&[i32]> = numbers.chunks(3).collect();
609
+ // [[1,2,3], [4,5,6], [7,8,9], [10]]
610
+
611
+ let windows: Vec<&[i32]> = numbers.windows(3).collect();
612
+ // [[1,2,3], [2,3,4], [3,4,5], ...]
613
+
614
+ // Collecting into HashMap
615
+ use std::collections::HashMap;
616
+ let word_counts: HashMap<&str, usize> = words.iter()
617
+ .fold(HashMap::new(), |mut map, word| {
618
+ *map.entry(word.as_str()).or_insert(0) += 1;
619
+ map
620
+ });
234
621
  ```
235
622
 
236
- ### 🛑 Verification-Before-Completion (VBC) Protocol
237
623
 
238
- **CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
239
- - ❌ **Forbidden:** Concluding your work because the logic seems sound or assuming `cargo check` is enough for complex runtime logic.
240
- - ✅ **Required:** You are explicitly forbidden from completing your Rust task without providing **concrete terminal evidence** that `cargo test` passes or the binary runs successfully (`cargo run`) without panics. The Borrow Checker passing is step one; runtime verification is mandatory before completion.