agy-superpowers 5.2.2 → 5.2.4

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 (231) hide show
  1. package/README.md +47 -150
  2. package/package.json +1 -1
  3. package/template/agent/rules/CLAUDE.md +80 -0
  4. package/template/agent/rules/code-styles.md +31 -32
  5. package/template/agent/rules/debug-confirmation-policy.md +2 -0
  6. package/template/agent/rules/file-length-policy.md +2 -0
  7. package/template/agent/rules/git-policy.md +7 -0
  8. package/template/agent/rules/language-matching.md +2 -0
  9. package/template/agent/rules/scratch-scripts.md +39 -0
  10. package/template/agent/rules/superpowers.md +8 -51
  11. package/template/agent/skills/executing-plans/SKILL.md +17 -0
  12. package/template/agent/skills/systematic-debugging/SKILL.md +16 -0
  13. package/template/agent/skills/test-driven-development/SKILL.md +16 -0
  14. package/template/agent/skills/verification-before-completion/SKILL.md +22 -0
  15. package/template/agent/skills/writing-plans/SKILL.md +16 -0
  16. package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
  17. package/template/agent/skills/analytics-setup/SKILL.md +0 -51
  18. package/template/agent/skills/api-design/SKILL.md +0 -193
  19. package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
  20. package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
  21. package/template/agent/skills/backend-developer/SKILL.md +0 -148
  22. package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
  23. package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
  24. package/template/agent/skills/community-manager/SKILL.md +0 -115
  25. package/template/agent/skills/content-marketer/SKILL.md +0 -111
  26. package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
  27. package/template/agent/skills/cto-architect/SKILL.md +0 -133
  28. package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
  29. package/template/agent/skills/data-analyst/SKILL.md +0 -147
  30. package/template/agent/skills/devops-engineer/SKILL.md +0 -117
  31. package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
  32. package/template/agent/skills/game-design/SKILL.md +0 -194
  33. package/template/agent/skills/game-developer/SKILL.md +0 -175
  34. package/template/agent/skills/growth-hacker/SKILL.md +0 -122
  35. package/template/agent/skills/idea-validator/SKILL.md +0 -55
  36. package/template/agent/skills/indie-legal/SKILL.md +0 -53
  37. package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
  38. package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
  39. package/template/agent/skills/launch-strategist/SKILL.md +0 -62
  40. package/template/agent/skills/market-researcher/SKILL.md +0 -53
  41. package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
  42. package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
  43. package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
  44. package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
  45. package/template/agent/skills/real-time-features/SKILL.md +0 -194
  46. package/template/agent/skills/retention-specialist/SKILL.md +0 -123
  47. package/template/agent/skills/rust-developer/SKILL.md +0 -281
  48. package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
  49. package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
  50. package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
  51. package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
  52. package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
  53. package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
  54. package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
  55. package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
  56. package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
  57. package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
  58. package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
  59. package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
  60. package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
  61. package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
  62. package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
  63. package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
  64. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
  65. package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
  66. package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
  67. package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
  68. package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
  69. package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
  70. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
  71. package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
  72. package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
  73. package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
  74. package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
  75. package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
  76. package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
  77. package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
  78. package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
  79. package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
  80. package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
  81. package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
  82. package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
  83. package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
  84. package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
  85. package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
  86. package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
  87. package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
  88. package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
  89. package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
  90. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
  91. package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
  92. package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
  93. package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
  94. package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
  95. package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
  96. package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
  97. package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
  98. package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
  99. package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
  100. package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
  101. package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
  102. package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
  103. package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
  104. package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
  105. package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
  106. package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
  107. package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
  108. package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
  109. package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
  110. package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
  111. package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
  112. package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
  113. package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
  114. package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
  115. package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
  116. package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
  117. package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
  118. package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
  119. package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
  120. package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
  121. package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
  122. package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
  123. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
  124. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
  125. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
  126. package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
  127. package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
  128. package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
  129. package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
  130. package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
  131. package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
  132. package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
  133. package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
  134. package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
  135. package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
  136. package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
  137. package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
  138. package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
  139. package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
  140. package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
  141. package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
  142. package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
  143. package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
  144. package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
  145. package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
  146. package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
  147. package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
  148. package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
  149. package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
  150. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
  151. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
  152. package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
  153. package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
  154. package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
  155. package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
  156. package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
  157. package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
  158. package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
  159. package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
  160. package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
  161. package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
  162. package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
  163. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
  164. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
  165. package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
  166. package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
  167. package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
  168. package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
  169. package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
  170. package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
  171. package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
  172. package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
  173. package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
  174. package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
  175. package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
  176. package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
  177. package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
  178. package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
  179. package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
  180. package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
  181. package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
  182. package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
  183. package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
  184. package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
  185. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
  186. package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
  187. package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
  188. package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
  189. package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
  190. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
  191. package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
  192. package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
  193. package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
  194. package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
  195. package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
  196. package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
  197. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
  198. package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
  199. package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
  200. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
  201. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
  202. package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
  203. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
  204. package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
  205. package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
  206. package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
  207. package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
  208. package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
  209. package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
  210. package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
  211. package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
  212. package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
  213. package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
  214. package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
  215. package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
  216. package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
  217. package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
  218. package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
  219. package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
  220. package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
  221. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
  222. package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
  223. package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
  224. package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
  225. package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
  226. package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
  227. package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
  228. package/template/agent/skills/saas-architect/SKILL.md +0 -139
  229. package/template/agent/skills/security-engineer/SKILL.md +0 -133
  230. package/template/agent/skills/seo-specialist/SKILL.md +0 -130
  231. package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
@@ -1,188 +0,0 @@
1
- # type-phantom-marker
2
-
3
- > Use `PhantomData` to express type relationships without runtime cost
4
-
5
- ## Why It Matters
6
-
7
- Sometimes your type needs to be parameterized by a type that doesn't appear in any field—for variance, drop order, or semantic purposes. `PhantomData<T>` tells the compiler your type is "associated with" `T` without storing any `T` data. It has zero runtime cost.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Type parameter unused - compiler error
13
- struct Handle<T> {
14
- id: u64,
15
- // Error: parameter `T` is never used
16
- }
17
-
18
- // Workaround with unnecessary storage
19
- struct Handle<T> {
20
- id: u64,
21
- _type: Option<T>, // Wastes memory, requires T: Default
22
- }
23
- ```
24
-
25
- ## Good
26
-
27
- ```rust
28
- use std::marker::PhantomData;
29
-
30
- struct Handle<T> {
31
- id: u64,
32
- _marker: PhantomData<T>, // Zero-size, tells compiler about T
33
- }
34
-
35
- impl<T> Handle<T> {
36
- fn new(id: u64) -> Self {
37
- Handle {
38
- id,
39
- _marker: PhantomData,
40
- }
41
- }
42
- }
43
-
44
- // Different Handle types are incompatible
45
- struct User;
46
- struct Order;
47
-
48
- fn process_user(h: Handle<User>) { ... }
49
-
50
- let user_handle = Handle::<User>::new(1);
51
- let order_handle = Handle::<Order>::new(2);
52
-
53
- process_user(user_handle); // OK
54
- process_user(order_handle); // Error: expected Handle<User>, found Handle<Order>
55
- ```
56
-
57
- ## Expressing Ownership
58
-
59
- ```rust
60
- use std::marker::PhantomData;
61
-
62
- // Owns T conceptually (like Box<T>)
63
- struct Container<T> {
64
- ptr: *mut T,
65
- _marker: PhantomData<T>, // Acts like we own a T
66
- }
67
-
68
- // Drop will be called on T when Container drops
69
- impl<T> Drop for Container<T> {
70
- fn drop(&mut self) {
71
- unsafe {
72
- std::ptr::drop_in_place(self.ptr);
73
- }
74
- }
75
- }
76
- ```
77
-
78
- ## Expressing Borrowing
79
-
80
- ```rust
81
- use std::marker::PhantomData;
82
-
83
- // Borrows T for lifetime 'a
84
- struct Ref<'a, T> {
85
- ptr: *const T,
86
- _marker: PhantomData<&'a T>, // Acts like &'a T
87
- }
88
-
89
- // Compiler tracks lifetime correctly
90
- impl<'a, T> Ref<'a, T> {
91
- fn get(&self) -> &'a T {
92
- unsafe { &*self.ptr }
93
- }
94
- }
95
- ```
96
-
97
- ## Type-Level State Machine
98
-
99
- ```rust
100
- use std::marker::PhantomData;
101
-
102
- // States as zero-size types
103
- struct Unlocked;
104
- struct Locked;
105
-
106
- struct Door<State> {
107
- _state: PhantomData<State>,
108
- }
109
-
110
- impl Door<Unlocked> {
111
- fn lock(self) -> Door<Locked> {
112
- println!("Locking...");
113
- Door { _state: PhantomData }
114
- }
115
-
116
- fn open(&self) {
117
- println!("Opening...");
118
- }
119
- }
120
-
121
- impl Door<Locked> {
122
- fn unlock(self) -> Door<Unlocked> {
123
- println!("Unlocking...");
124
- Door { _state: PhantomData }
125
- }
126
-
127
- // Can't call open() on Locked door - method doesn't exist
128
- }
129
-
130
- fn example() {
131
- let door: Door<Unlocked> = Door { _state: PhantomData };
132
- door.open(); // OK
133
- let locked = door.lock();
134
- // locked.open(); // Error: no method `open` for Door<Locked>
135
- let unlocked = locked.unlock();
136
- unlocked.open(); // OK
137
- }
138
- ```
139
-
140
- ## Variance Control
141
-
142
- ```rust
143
- use std::marker::PhantomData;
144
-
145
- // Covariant in T (PhantomData<T>)
146
- struct Producer<T> {
147
- _marker: PhantomData<T>, // Covariant
148
- }
149
-
150
- // Contravariant in T (PhantomData<fn(T)>)
151
- struct Consumer<T> {
152
- _marker: PhantomData<fn(T)>, // Contravariant
153
- }
154
-
155
- // Invariant in T (PhantomData<fn(T) -> T>)
156
- struct Both<T> {
157
- _marker: PhantomData<fn(T) -> T>, // Invariant
158
- }
159
- ```
160
-
161
- ## Common Uses
162
-
163
- ```rust
164
- // 1. FFI handles with type safety
165
- struct FileHandle<T: FileType> {
166
- fd: i32,
167
- _marker: PhantomData<T>,
168
- }
169
-
170
- // 2. Generic iterators
171
- struct Iter<'a, T> {
172
- ptr: *const T,
173
- end: *const T,
174
- _marker: PhantomData<&'a T>,
175
- }
176
-
177
- // 3. Allocator-aware types
178
- struct Vec<T, A: Allocator = Global> {
179
- buf: RawVec<T, A>,
180
- len: usize,
181
- }
182
- ```
183
-
184
- ## See Also
185
-
186
- - [api-typestate](./api-typestate.md) - State machine pattern
187
- - [api-newtype-safety](./api-newtype-safety.md) - Type-safe wrappers
188
- - [type-newtype-ids](./type-newtype-ids.md) - ID types
@@ -1,143 +0,0 @@
1
- # type-repr-transparent
2
-
3
- > Use `#[repr(transparent)]` for newtypes in FFI contexts
4
-
5
- ## Why It Matters
6
-
7
- `#[repr(transparent)]` guarantees a newtype has the same memory layout as its inner type. This is essential for FFI where you need type safety in Rust but must match C ABI layouts. Without it, the compiler may add padding or change layout.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // No layout guarantee - might not match inner type in FFI
13
- struct Handle(u64);
14
-
15
- // Passing to C code might fail
16
- extern "C" {
17
- fn process_handle(h: Handle); // May not work correctly
18
- }
19
-
20
- // Wrapping C type without layout guarantee
21
- struct SafePointer(*mut c_void);
22
- ```
23
-
24
- ## Good
25
-
26
- ```rust
27
- // Guaranteed same layout as inner type
28
- #[repr(transparent)]
29
- struct Handle(u64);
30
-
31
- // Safe for FFI
32
- extern "C" {
33
- fn process_handle(h: Handle); // Works - same layout as u64
34
- }
35
-
36
- // FFI pointer wrapper
37
- #[repr(transparent)]
38
- struct SafePointer(*mut c_void);
39
-
40
- impl SafePointer {
41
- // Safe Rust API around raw pointer
42
- pub fn new(ptr: *mut c_void) -> Option<Self> {
43
- if ptr.is_null() {
44
- None
45
- } else {
46
- Some(SafePointer(ptr))
47
- }
48
- }
49
- }
50
- ```
51
-
52
- ## What repr(transparent) Guarantees
53
-
54
- ```rust
55
- use std::mem::{size_of, align_of};
56
-
57
- #[repr(transparent)]
58
- struct Meters(f64);
59
-
60
- // Same size
61
- assert_eq!(size_of::<Meters>(), size_of::<f64>());
62
-
63
- // Same alignment
64
- assert_eq!(align_of::<Meters>(), align_of::<f64>());
65
-
66
- // Same ABI - can pass where f64 expected
67
- extern "C" fn measure(distance: Meters) { ... }
68
- ```
69
-
70
- ## With PhantomData
71
-
72
- ```rust
73
- use std::marker::PhantomData;
74
-
75
- // PhantomData is zero-sized, doesn't affect layout
76
- #[repr(transparent)]
77
- struct TypedHandle<T> {
78
- raw: u64,
79
- _marker: PhantomData<T>, // Zero-sized, ignored for layout
80
- }
81
-
82
- // Still same layout as u64
83
- assert_eq!(size_of::<TypedHandle<String>>(), size_of::<u64>());
84
- ```
85
-
86
- ## NonZero Wrappers
87
-
88
- ```rust
89
- use std::num::NonZeroU64;
90
-
91
- #[repr(transparent)]
92
- struct NonZeroHandle(NonZeroU64);
93
-
94
- // Inherits null-pointer optimization
95
- assert_eq!(size_of::<Option<NonZeroHandle>>(), size_of::<u64>());
96
- ```
97
-
98
- ## FFI Pattern
99
-
100
- ```rust
101
- mod ffi {
102
- use std::os::raw::c_int;
103
-
104
- #[repr(transparent)]
105
- pub struct FileDescriptor(c_int);
106
-
107
- extern "C" {
108
- pub fn open(path: *const i8, flags: c_int) -> FileDescriptor;
109
- pub fn close(fd: FileDescriptor) -> c_int;
110
- pub fn read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isize;
111
- }
112
- }
113
-
114
- // Safe wrapper
115
- pub struct File {
116
- fd: ffi::FileDescriptor,
117
- }
118
-
119
- impl File {
120
- pub fn open(path: &str) -> std::io::Result<Self> {
121
- let c_path = std::ffi::CString::new(path)?;
122
- let fd = unsafe { ffi::open(c_path.as_ptr(), 0) };
123
- // ... error handling
124
- Ok(File { fd })
125
- }
126
- }
127
- ```
128
-
129
- ## When to Use
130
-
131
- | Scenario | Use `#[repr(transparent)]`? |
132
- |----------|----------------------------|
133
- | FFI newtype wrappers | Yes |
134
- | Type-safe handles | Yes |
135
- | NonZero optimization | Yes |
136
- | Pure Rust newtypes | Optional (doesn't hurt) |
137
- | Multi-field structs | N/A (only for single-field) |
138
-
139
- ## See Also
140
-
141
- - [type-newtype-ids](./type-newtype-ids.md) - Newtype pattern
142
- - [type-phantom-marker](./type-phantom-marker.md) - PhantomData usage
143
- - [api-newtype-safety](./api-newtype-safety.md) - Type-safe newtypes
@@ -1,131 +0,0 @@
1
- # type-result-fallible
2
-
3
- > Use `Result<T, E>` for operations that can fail
4
-
5
- ## Why It Matters
6
-
7
- `Result<T, E>` makes failure explicit in the type system. Callers must acknowledge and handle potential errors—they can't accidentally ignore failures. The `?` operator makes error propagation ergonomic while maintaining explicit error handling.
8
-
9
- ## Bad
10
-
11
- ```rust
12
- // Returning Option loses error context
13
- fn read_config(path: &str) -> Option<Config> {
14
- let content = std::fs::read_to_string(path).ok()?; // Why did it fail?
15
- toml::from_str(&content).ok() // Parse error lost
16
- }
17
-
18
- // Panicking on errors
19
- fn read_config(path: &str) -> Config {
20
- let content = std::fs::read_to_string(path).unwrap(); // Crashes
21
- toml::from_str(&content).unwrap() // Crashes
22
- }
23
-
24
- // Sentinel values
25
- fn divide(a: i32, b: i32) -> i32 {
26
- if b == 0 { return -1; } // Magic value, easy to miss
27
- a / b
28
- }
29
- ```
30
-
31
- ## Good
32
-
33
- ```rust
34
- // Result with clear error type
35
- fn read_config(path: &str) -> Result<Config, ConfigError> {
36
- let content = std::fs::read_to_string(path)
37
- .map_err(ConfigError::IoError)?;
38
- toml::from_str(&content)
39
- .map_err(ConfigError::ParseError)
40
- }
41
-
42
- fn divide(a: i32, b: i32) -> Result<i32, DivisionError> {
43
- if b == 0 {
44
- return Err(DivisionError::DivideByZero);
45
- }
46
- Ok(a / b)
47
- }
48
-
49
- // Caller must handle
50
- match divide(10, 0) {
51
- Ok(result) => println!("Result: {}", result),
52
- Err(e) => println!("Error: {}", e),
53
- }
54
- ```
55
-
56
- ## The ? Operator
57
-
58
- ```rust
59
- fn process_file(path: &str) -> Result<ProcessedData, Error> {
60
- let content = std::fs::read_to_string(path)?; // Propagates Err
61
- let parsed: RawData = serde_json::from_str(&content)?;
62
- let validated = validate(parsed)?;
63
- let processed = transform(validated)?;
64
- Ok(processed)
65
- }
66
-
67
- // Equivalent to:
68
- fn process_file(path: &str) -> Result<ProcessedData, Error> {
69
- let content = match std::fs::read_to_string(path) {
70
- Ok(c) => c,
71
- Err(e) => return Err(e.into()),
72
- };
73
- // ... etc
74
- }
75
- ```
76
-
77
- ## Result Combinators
78
-
79
- ```rust
80
- let result: Result<i32, Error> = Ok(42);
81
-
82
- // map: transform success value
83
- let doubled = result.map(|n| n * 2); // Ok(84)
84
-
85
- // map_err: transform error
86
- let with_context = result.map_err(|e| format!("Failed: {}", e));
87
-
88
- // and_then: chain fallible operations
89
- let processed = result.and_then(|n| {
90
- if n > 0 { Ok(n * 2) } else { Err(Error::Negative) }
91
- });
92
-
93
- // unwrap_or: provide default on error
94
- let value = result.unwrap_or(0);
95
-
96
- // ok(): convert to Option, discarding error
97
- let maybe_value: Option<i32> = result.ok();
98
- ```
99
-
100
- ## Defining Error Types
101
-
102
- ```rust
103
- use thiserror::Error;
104
-
105
- #[derive(Error, Debug)]
106
- pub enum ConfigError {
107
- #[error("failed to read file: {0}")]
108
- Io(#[from] std::io::Error),
109
-
110
- #[error("failed to parse config: {0}")]
111
- Parse(#[from] toml::de::Error),
112
-
113
- #[error("missing required field: {0}")]
114
- MissingField(String),
115
- }
116
-
117
- fn load_config(path: &str) -> Result<Config, ConfigError> {
118
- let content = std::fs::read_to_string(path)?; // Io error
119
- let config: Config = toml::from_str(&content)?; // Parse error
120
- if config.name.is_empty() {
121
- return Err(ConfigError::MissingField("name".into()));
122
- }
123
- Ok(config)
124
- }
125
- ```
126
-
127
- ## See Also
128
-
129
- - [err-thiserror-lib](./err-thiserror-lib.md) - Defining error types
130
- - [err-question-mark](./err-question-mark.md) - Using ? operator
131
- - [type-option-nullable](./type-option-nullable.md) - Option vs Result
@@ -1,139 +0,0 @@
1
- ---
2
- name: saas-architect
3
- description: Use when designing multi-tenant SaaS architecture, tenant isolation, data models, or making core infrastructure decisions for a SaaS product
4
- ---
5
-
6
- # SaaS Architect Lens
7
-
8
- > **Philosophy:** Multi-tenancy is not a feature — it's a fundamental architectural constraint.
9
- > Every design decision must answer: "Is this tenant-safe?"
10
-
11
- ---
12
-
13
- ## Core Instincts
14
-
15
- - **Tenant isolation first** — data leaking between tenants is an existential business risk
16
- - **Design for the tenant, not the user** — every entity in the data model has a `tenant_id`
17
- - **Shared infrastructure, isolated data** — the sweet spot for indie hackers
18
- - **Plan the upgrade path** — schema-per-tenant → RLS → shared schema: picking wrong is expensive to change
19
- - **Hard-delete rarely; soft-delete by default** — audit trails matter in B2B
20
-
21
- ---
22
-
23
- ## Tenancy Isolation Models
24
-
25
- | Model | Isolation | Cost | Complexity | Best for |
26
- |-------|-----------|------|------------|----------|
27
- | **Separate database per tenant** | ✅ Strongest | 💰 Highest | High | Enterprise, regulated industries |
28
- | **Schema per tenant** (PostgreSQL) | ✅ Strong | 💰 Medium | Medium | Mid-market SaaS |
29
- | **Row-level security (RLS)** | ✅ Good | 💰 Low | Medium | Indie hacker / SMB SaaS |
30
- | **Application-level filtering** | ⚠️ Weakest | 💰 Lowest | Low | Prototype only — never production |
31
-
32
- **Recommended for indie hackers:** Row-Level Security (RLS) on PostgreSQL (Supabase, Neon). Strong isolation at low cost.
33
-
34
- ---
35
-
36
- ## Tenant Data Model Pattern
37
-
38
- ```sql
39
- -- Every table must have tenant_id
40
- CREATE TABLE projects (
41
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
42
- tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
43
- name TEXT NOT NULL,
44
- created_at TIMESTAMPTZ DEFAULT now(),
45
- deleted_at TIMESTAMPTZ -- soft delete
46
- );
47
-
48
- -- RLS: tenant can only see their own rows
49
- ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
50
- CREATE POLICY tenant_isolation ON projects
51
- USING (tenant_id = current_setting('app.tenant_id')::UUID);
52
-
53
- -- Index tenant_id on EVERY tenant-scoped table
54
- CREATE INDEX ON projects(tenant_id);
55
- ```
56
-
57
- ---
58
-
59
- ## Tenant Routing Patterns
60
-
61
- ```
62
- Option 1: Subdomain routing
63
- acme.myapp.com → tenant lookup by subdomain → set tenant_id context
64
-
65
- Option 2: Path routing
66
- myapp.com/acme → extract slug from path → set tenant_id context
67
-
68
- Option 3: Custom domain
69
- app.acme.com → CNAME → myapp.com → DNS lookup → set tenant_id context
70
-
71
- Recommended for indie hackers: Start with subdomain routing; add custom domains when users ask.
72
- ```
73
-
74
- ---
75
-
76
- ## ❌ Anti-Patterns to Avoid
77
-
78
- | ❌ NEVER DO | Why | ✅ DO INSTEAD |
79
- |------------|-----|--------------|
80
- | Application-level tenant filtering only | One missing WHERE clause = data breach | RLS at DB level = defense in depth |
81
- | Tenant ID in JWT payload, enforced only in app | Bypassed by direct DB access | DB-level enforcement (RLS or schema) |
82
- | Hard-delete tenant data immediately | Chargebacks, disputes, legal holds | Soft-delete + 30-day retention before purge |
83
- | No tenant_id index | Full table scan at scale | `CREATE INDEX ON every_table(tenant_id)` |
84
- | Single shared sequence for IDs | Enumerable IDs expose tenant data volume | UUIDs (v4 or v7) always |
85
- | Storing cross-tenant references | Breaks isolation, schema nightmare | Denormalize data within tenant boundary |
86
-
87
- ---
88
-
89
- ## Tenant Lifecycle Management
90
-
91
- ```
92
- Sign up → Create tenant record → Create owner user → Provision trial subscription
93
-
94
- Active → Upgrade → Downgrade → Cancel → Grace period (30 days) → Purge
95
- ```
96
-
97
- **Required tenant states:** `trialing`, `active`, `past_due`, `canceled`, `suspended`
98
-
99
- ---
100
-
101
- ## Questions You Always Ask
102
-
103
- **When adding a new model:**
104
- - Does every record in this table belong to a tenant? → Add `tenant_id`
105
- - Is there an index on `tenant_id`?
106
- - Does the RLS policy cover this table?
107
- - What happens when the tenant is deleted/canceled?
108
-
109
- **When reviewing a query:**
110
- - Is `tenant_id` in the WHERE clause? (Even with RLS, explicit filtering = clarity)
111
- - Could this query return data from another tenant?
112
-
113
- ---
114
-
115
- ## Red Flags
116
-
117
- **Must fix:**
118
- - [ ] Tables with user data but no `tenant_id`
119
- - [ ] Application-level tenant filtering without DB-level enforcement
120
- - [ ] No index on `tenant_id` columns
121
- - [ ] Hard-delete on tenant cancellation (no retention period)
122
-
123
- **Should fix:**
124
- - [ ] No soft-delete strategy for tenant-scoped records
125
- - [ ] Cross-tenant foreign key references
126
- - [ ] Tenant ID stored as integer (enumerable — use UUID)
127
-
128
- ---
129
-
130
- ## Who to Pair With
131
- - `backend-developer` — for query patterns and migration execution
132
- - `auth-and-identity` — for tenant-scoped authentication
133
- - `security-engineer` — for data isolation audit
134
- - `devops-engineer` — for per-tenant resource provisioning
135
-
136
- ---
137
-
138
- ## Tools
139
- Supabase (RLS built-in) · Neon (branching per tenant possible) · PlanetScale (separate DBs) · Drizzle ORM / Prisma (schema management) · Zod (runtime tenant_id validation)