100xprism 2.3.1

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 (207) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +196 -0
  3. package/VERSION +1 -0
  4. package/adapters/antigravity.sh +14 -0
  5. package/adapters/claude-code.sh +160 -0
  6. package/adapters/codex.sh +13 -0
  7. package/adapters/copilot.sh +13 -0
  8. package/adapters/cursor.sh +13 -0
  9. package/adapters/gemini.sh +13 -0
  10. package/adapters/lib/__pycache__/modules.cpython-312.pyc +0 -0
  11. package/adapters/lib/modules.py +592 -0
  12. package/adapters/lib/shared.sh +83 -0
  13. package/adapters/lib/sync_plugins.py +113 -0
  14. package/adapters/windsurf.sh +15 -0
  15. package/bin/100xprism.js +29 -0
  16. package/get.sh +24 -0
  17. package/install-project.sh +82 -0
  18. package/install.sh +281 -0
  19. package/lib/adapters/windows.js +429 -0
  20. package/lib/bootstrap.js +33 -0
  21. package/lib/init.js +19 -0
  22. package/lib/install.js +18 -0
  23. package/lib/migrate.js +52 -0
  24. package/lib/platform.js +22 -0
  25. package/lib/update.js +29 -0
  26. package/modules/_lib/reference.md +77 -0
  27. package/modules/a11y-auditor/SKILL.md +151 -0
  28. package/modules/ab-test-setup/SKILL.md +266 -0
  29. package/modules/ab-test-setup/evals/evals.json +105 -0
  30. package/modules/ab-test-setup/references/sample-size-guide.md +263 -0
  31. package/modules/ab-test-setup/references/test-templates.md +277 -0
  32. package/modules/ad-creative/SKILL.md +362 -0
  33. package/modules/ad-creative/evals/evals.json +90 -0
  34. package/modules/ad-creative/references/generative-tools.md +637 -0
  35. package/modules/ad-creative/references/platform-specs.md +213 -0
  36. package/modules/ai-seo/SKILL.md +398 -0
  37. package/modules/ai-seo/evals/evals.json +90 -0
  38. package/modules/ai-seo/references/content-patterns.md +285 -0
  39. package/modules/ai-seo/references/platform-ranking-factors.md +152 -0
  40. package/modules/analytics-tracking/SKILL.md +309 -0
  41. package/modules/analytics-tracking/evals/evals.json +90 -0
  42. package/modules/analytics-tracking/references/event-library.md +260 -0
  43. package/modules/analytics-tracking/references/ga4-implementation.md +300 -0
  44. package/modules/analytics-tracking/references/gtm-implementation.md +390 -0
  45. package/modules/architect/SKILL.md +282 -0
  46. package/modules/branch/SKILL.md +105 -0
  47. package/modules/churn-prevention/SKILL.md +424 -0
  48. package/modules/churn-prevention/evals/evals.json +93 -0
  49. package/modules/churn-prevention/references/cancel-flow-patterns.md +316 -0
  50. package/modules/churn-prevention/references/dunning-playbook.md +408 -0
  51. package/modules/cloud-security/SKILL.md +240 -0
  52. package/modules/cold-email/SKILL.md +178 -0
  53. package/modules/cold-email/evals/evals.json +94 -0
  54. package/modules/cold-email/references/benchmarks.md +83 -0
  55. package/modules/cold-email/references/follow-up-sequences.md +81 -0
  56. package/modules/cold-email/references/frameworks.md +90 -0
  57. package/modules/cold-email/references/personalization.md +79 -0
  58. package/modules/cold-email/references/subject-lines.md +53 -0
  59. package/modules/commit/SKILL.md +195 -0
  60. package/modules/competitor-alternatives/SKILL.md +256 -0
  61. package/modules/competitor-alternatives/evals/evals.json +93 -0
  62. package/modules/competitor-alternatives/references/content-architecture.md +271 -0
  63. package/modules/competitor-alternatives/references/templates.md +223 -0
  64. package/modules/connect/SKILL.md +894 -0
  65. package/modules/content-strategy/SKILL.md +359 -0
  66. package/modules/content-strategy/evals/evals.json +90 -0
  67. package/modules/context-dump/SKILL.md +67 -0
  68. package/modules/copy-editing/SKILL.md +447 -0
  69. package/modules/copy-editing/evals/evals.json +89 -0
  70. package/modules/copy-editing/references/plain-english-alternatives.md +394 -0
  71. package/modules/copywriting/SKILL.md +271 -0
  72. package/modules/copywriting/evals/evals.json +111 -0
  73. package/modules/copywriting/references/cold-email-benchmarks.md +83 -0
  74. package/modules/copywriting/references/cold-email-follow-ups.md +81 -0
  75. package/modules/copywriting/references/cold-email-frameworks.md +90 -0
  76. package/modules/copywriting/references/cold-email-personalization.md +79 -0
  77. package/modules/copywriting/references/cold-email-subject-lines.md +53 -0
  78. package/modules/copywriting/references/copy-frameworks.md +344 -0
  79. package/modules/copywriting/references/email-copy-guidelines.md +113 -0
  80. package/modules/copywriting/references/email-types.md +515 -0
  81. package/modules/copywriting/references/natural-transitions.md +272 -0
  82. package/modules/copywriting/references/sequence-templates.md +168 -0
  83. package/modules/data-query/SKILL.md +58 -0
  84. package/modules/data-viz/SKILL.md +225 -0
  85. package/modules/db/SKILL.md +205 -0
  86. package/modules/db/db-engines/_router.md +24 -0
  87. package/modules/db/db-engines/athena.md +16 -0
  88. package/modules/db/db-engines/cloud-sql.md +16 -0
  89. package/modules/db/db-engines/databricks.md +14 -0
  90. package/modules/db/db-engines/oracle.md +14 -0
  91. package/modules/db/db-engines/postgres.md +15 -0
  92. package/modules/db/db-engines/presto.md +14 -0
  93. package/modules/db/db-engines/snowflake.md +14 -0
  94. package/modules/docs/SKILL.md +100 -0
  95. package/modules/email-sequence/SKILL.md +309 -0
  96. package/modules/email-sequence/evals/evals.json +93 -0
  97. package/modules/email-sequence/references/copy-guidelines.md +113 -0
  98. package/modules/email-sequence/references/email-types.md +515 -0
  99. package/modules/email-sequence/references/sequence-templates.md +168 -0
  100. package/modules/enterprise-design/SKILL.md +75 -0
  101. package/modules/eval/SKILL.md +105 -0
  102. package/modules/figma-translator/SKILL.md +49 -0
  103. package/modules/fix-bugs/SKILL.md +104 -0
  104. package/modules/form-cro/SKILL.md +429 -0
  105. package/modules/form-cro/evals/evals.json +90 -0
  106. package/modules/free-tool-strategy/SKILL.md +178 -0
  107. package/modules/free-tool-strategy/evals/evals.json +90 -0
  108. package/modules/free-tool-strategy/references/tool-types.md +217 -0
  109. package/modules/gate/SKILL.md +232 -0
  110. package/modules/grill-me/SKILL.md +59 -0
  111. package/modules/interaction-engineer/SKILL.md +49 -0
  112. package/modules/issue/SKILL.md +272 -0
  113. package/modules/launch/SKILL.md +345 -0
  114. package/modules/launch-strategy/SKILL.md +353 -0
  115. package/modules/launch-strategy/evals/evals.json +91 -0
  116. package/modules/lint/SKILL.md +126 -0
  117. package/modules/marketing-ideas/SKILL.md +167 -0
  118. package/modules/marketing-ideas/evals/evals.json +90 -0
  119. package/modules/marketing-ideas/references/ideas-by-category.md +366 -0
  120. package/modules/marketing-psychology/SKILL.md +455 -0
  121. package/modules/marketing-psychology/evals/evals.json +88 -0
  122. package/modules/motion-designer/SKILL.md +214 -0
  123. package/modules/onboarding-cro/SKILL.md +220 -0
  124. package/modules/onboarding-cro/evals/evals.json +92 -0
  125. package/modules/onboarding-cro/references/experiments.md +258 -0
  126. package/modules/orchestrate/SKILL.md +77 -0
  127. package/modules/page-cro/SKILL.md +182 -0
  128. package/modules/page-cro/evals/evals.json +111 -0
  129. package/modules/page-cro/references/experiments.md +248 -0
  130. package/modules/page-cro/references/paywall-experiments.md +164 -0
  131. package/modules/paid-ads/SKILL.md +315 -0
  132. package/modules/paid-ads/evals/evals.json +90 -0
  133. package/modules/paid-ads/references/ad-copy-templates.md +207 -0
  134. package/modules/paid-ads/references/audience-targeting.md +243 -0
  135. package/modules/paid-ads/references/platform-setup-checklists.md +277 -0
  136. package/modules/paywall-upgrade-cro/SKILL.md +227 -0
  137. package/modules/paywall-upgrade-cro/evals/evals.json +93 -0
  138. package/modules/paywall-upgrade-cro/references/experiments.md +164 -0
  139. package/modules/popup-cro/SKILL.md +453 -0
  140. package/modules/popup-cro/evals/evals.json +94 -0
  141. package/modules/pr/SKILL.md +203 -0
  142. package/modules/pricing-strategy/SKILL.md +231 -0
  143. package/modules/pricing-strategy/evals/evals.json +90 -0
  144. package/modules/pricing-strategy/references/research-methods.md +152 -0
  145. package/modules/pricing-strategy/references/tier-structure.md +232 -0
  146. package/modules/product-marketing-context/SKILL.md +241 -0
  147. package/modules/product-marketing-context/evals/evals.json +85 -0
  148. package/modules/programmatic-seo/SKILL.md +238 -0
  149. package/modules/programmatic-seo/evals/evals.json +94 -0
  150. package/modules/programmatic-seo/references/playbooks.md +308 -0
  151. package/modules/push/SKILL.md +202 -0
  152. package/modules/referral-program/SKILL.md +255 -0
  153. package/modules/referral-program/evals/evals.json +89 -0
  154. package/modules/referral-program/references/affiliate-programs.md +164 -0
  155. package/modules/referral-program/references/program-examples.md +143 -0
  156. package/modules/release/SKILL.md +293 -0
  157. package/modules/revops/SKILL.md +343 -0
  158. package/modules/revops/evals/evals.json +91 -0
  159. package/modules/revops/references/automation-playbooks.md +290 -0
  160. package/modules/revops/references/lifecycle-definitions.md +278 -0
  161. package/modules/revops/references/routing-rules.md +203 -0
  162. package/modules/revops/references/scoring-models.md +247 -0
  163. package/modules/sales-enablement/SKILL.md +349 -0
  164. package/modules/sales-enablement/evals/evals.json +91 -0
  165. package/modules/sales-enablement/references/deck-frameworks.md +263 -0
  166. package/modules/sales-enablement/references/demo-scripts.md +355 -0
  167. package/modules/sales-enablement/references/objection-library.md +270 -0
  168. package/modules/sales-enablement/references/one-pager-templates.md +208 -0
  169. package/modules/schema-markup/SKILL.md +179 -0
  170. package/modules/schema-markup/evals/evals.json +87 -0
  171. package/modules/schema-markup/references/schema-examples.md +398 -0
  172. package/modules/security/SKILL.md +138 -0
  173. package/modules/seo-audit/SKILL.md +412 -0
  174. package/modules/seo-audit/evals/evals.json +136 -0
  175. package/modules/seo-audit/references/ai-writing-detection.md +200 -0
  176. package/modules/seo-audit/references/content-patterns.md +285 -0
  177. package/modules/seo-audit/references/platform-ranking-factors.md +152 -0
  178. package/modules/signup-flow-cro/SKILL.md +359 -0
  179. package/modules/signup-flow-cro/evals/evals.json +88 -0
  180. package/modules/site-architecture/SKILL.md +357 -0
  181. package/modules/site-architecture/evals/evals.json +88 -0
  182. package/modules/site-architecture/references/mermaid-templates.md +216 -0
  183. package/modules/site-architecture/references/navigation-patterns.md +305 -0
  184. package/modules/site-architecture/references/site-type-templates.md +293 -0
  185. package/modules/social-content/SKILL.md +278 -0
  186. package/modules/social-content/evals/evals.json +92 -0
  187. package/modules/social-content/references/platforms.md +170 -0
  188. package/modules/social-content/references/post-templates.md +177 -0
  189. package/modules/social-content/references/reverse-engineering.md +195 -0
  190. package/modules/spec/SKILL.md +81 -0
  191. package/modules/subagents/SKILL.md +123 -0
  192. package/modules/techdebt/SKILL.md +71 -0
  193. package/modules/terminal-setup/SKILL.md +49 -0
  194. package/modules/test/SKILL.md +493 -0
  195. package/modules/test/references/e2e-patterns.md +294 -0
  196. package/modules/update-claude-md/SKILL.md +52 -0
  197. package/modules/visual-system-architect/SKILL.md +53 -0
  198. package/package.json +44 -0
  199. package/plugins/plugins.json +43 -0
  200. package/shell/aliases.sh +24 -0
  201. package/shell/check-update.sh +212 -0
  202. package/templates/.env.example +199 -0
  203. package/templates/docker-compose.md +46 -0
  204. package/templates/node-frontend.md +56 -0
  205. package/templates/node-fullstack.md +59 -0
  206. package/templates/python-api.md +57 -0
  207. package/update.sh +231 -0
@@ -0,0 +1,408 @@
1
+ # Dunning Playbook
2
+
3
+ Complete guide to recovering failed payments and reducing involuntary churn.
4
+
5
+ ---
6
+
7
+ ## Why Dunning Matters
8
+
9
+ - Failed payments cause 30-50% of all subscription churn
10
+ - Most failed payments are recoverable with the right strategy
11
+ - Subscription businesses lose an estimated $129 billion annually to involuntary churn
12
+ - Effective dunning recovers 50-60% of failed payments
13
+
14
+ ---
15
+
16
+ ## The Dunning Timeline
17
+
18
+ ```
19
+ Day -30 to -7: Pre-dunning (prevent failures)
20
+ Day 0: Payment fails → Smart retry #1 + Email #1
21
+ Day 1-3: Smart retry #2 + Email #2
22
+ Day 3-5: Smart retry #3
23
+ Day 5-7: Smart retry #4 + Email #3
24
+ Day 7-10: Final retry + Email #4 (final warning)
25
+ Day 10-14: Grace period ends → Account paused/cancelled
26
+ Day 14+: Win-back sequence begins
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Pre-Dunning: Prevent Failures Before They Happen
32
+
33
+ ### Card Expiry Management
34
+
35
+ | Timing | Action |
36
+ |--------|--------|
37
+ | 30 days before expiry | Email: "Your card ending in 4242 expires next month" |
38
+ | 15 days before expiry | Email: "Update your payment method to avoid interruption" |
39
+ | 7 days before expiry | Email: "Your card expires in 7 days — update now" |
40
+ | 3 days before expiry | In-app banner: "Payment method expiring soon" |
41
+
42
+ **Email template — Card expiring:**
43
+ ```
44
+ Subject: Your card ending in 4242 expires soon
45
+
46
+ Hi [Name],
47
+
48
+ The card on file for your [Product] subscription expires on [date].
49
+
50
+ Update your payment method now to avoid any interruption:
51
+
52
+ [Update Payment Method →]
53
+
54
+ This takes less than 30 seconds.
55
+
56
+ — [Product] Team
57
+ ```
58
+
59
+ ### Card Updater Services
60
+
61
+ Major card networks offer automatic card update programs:
62
+
63
+ | Service | Network | What It Does |
64
+ |---------|---------|--------------|
65
+ | Visa Account Updater (VAU) | Visa | Auto-updates stored card numbers and expiry dates |
66
+ | Mastercard Automatic Billing Updater (ABU) | Mastercard | Same for Mastercard |
67
+ | Amex Cardrefresher | American Express | Same for Amex |
68
+
69
+ **Impact:** Reduces hard declines from expired/replaced cards by 30-50%.
70
+
71
+ **How to enable:**
72
+ - **Stripe**: Automatic — enabled by default
73
+ - **Chargebee**: Enabled through gateway settings
74
+ - **Recurly**: Built-in, enabled by default
75
+ - **Braintree**: Contact processor to enable
76
+
77
+ ### Backup Payment Methods
78
+
79
+ Prompt for a second payment method:
80
+ - During signup: "Add a backup payment method" (low conversion)
81
+ - After first successful payment: "Protect your account with a backup card" (better timing)
82
+ - After a failed payment is recovered: "Add a backup to prevent future interruptions" (best timing — they felt the pain)
83
+
84
+ ### Pre-Billing Notifications
85
+
86
+ For annual plans or high-value subscriptions:
87
+ - Email 7 days before renewal with amount and date
88
+ - Include link to update payment method
89
+ - Show what's included in the renewal
90
+ - Required by some regulations for auto-renewals
91
+
92
+ ---
93
+
94
+ ## Smart Retry Strategy
95
+
96
+ ### Decline Type Classification
97
+
98
+ | Code | Type | Meaning | Retry? |
99
+ |------|------|---------|--------|
100
+ | `insufficient_funds` | Soft | Temporarily low balance | Yes — retry in 2-3 days |
101
+ | `card_declined` (generic) | Soft | Various temporary reasons | Yes — retry 3-4 times |
102
+ | `processing_error` | Soft | Gateway/network issue | Yes — retry within 24h |
103
+ | `expired_card` | Hard | Card is expired | No — request new card |
104
+ | `stolen_card` | Hard | Card reported stolen | No — request new card |
105
+ | `do_not_honor` | Soft/Hard | Bank refused (ambiguous) | Try once more, then ask for new card |
106
+ | `authentication_required` | Auth | SCA/3DS needed | Send customer to authenticate |
107
+
108
+ ### Retry Schedule by Provider
109
+
110
+ **Stripe (Smart Retries — recommended):**
111
+ - Enable "Smart Retries" in Stripe Dashboard → Billing → Settings
112
+ - Stripe's ML model picks optimal retry timing based on billions of transactions
113
+ - Typically 4-8 retry attempts over 3-4 weeks
114
+ - Recovers ~15% more than fixed-schedule retries
115
+
116
+ **Manual retry schedule (if no smart retries):**
117
+
118
+ | Retry | Timing | Best Day/Time |
119
+ |-------|--------|--------------|
120
+ | 1 | Day 1 (24h after failure) | Morning, same day of week as original |
121
+ | 2 | Day 3 | Try a different time of day |
122
+ | 3 | Day 5 | After typical payday (1st, 15th) |
123
+ | 4 | Day 7 | Morning of the next business day |
124
+ | 5 (final) | Day 10 | Last attempt before grace period ends |
125
+
126
+ **Retry timing insights:**
127
+ - Retry on the same day of month the original payment succeeded
128
+ - Retry after common paydays (1st and 15th of the month)
129
+ - Avoid retrying on weekends (lower approval rates)
130
+ - Morning retries (8-10am local time) perform slightly better
131
+
132
+ ---
133
+
134
+ ## Dunning Email Sequence
135
+
136
+ ### Email 1: Payment Failed (Day 0)
137
+
138
+ **Tone:** Friendly, matter-of-fact. No alarm.
139
+
140
+ ```
141
+ Subject: Action needed — your payment didn't go through
142
+
143
+ Hi [Name],
144
+
145
+ We tried to charge your [card type] ending in [last 4] for your
146
+ [Product] subscription ($[amount]), but it didn't go through.
147
+
148
+ This happens sometimes — usually a quick card update fixes it.
149
+
150
+ [Update Payment Method →]
151
+
152
+ Your access isn't affected yet. We'll retry automatically, but
153
+ updating your card is the fastest fix.
154
+
155
+ Need help? Just reply to this email.
156
+
157
+ — [Product] Team
158
+ ```
159
+
160
+ ### Email 2: Reminder (Day 3)
161
+
162
+ **Tone:** Helpful, slightly more urgent.
163
+
164
+ ```
165
+ Subject: Quick reminder — update your payment for [Product]
166
+
167
+ Hi [Name],
168
+
169
+ Just a heads-up — we still haven't been able to process your
170
+ $[amount] payment for [Product].
171
+
172
+ [Update Payment Method →]
173
+
174
+ Takes less than 30 seconds. Your [data/projects/team access]
175
+ is safe, but we'll need a valid payment method to keep your
176
+ account active.
177
+
178
+ Questions? Reply here and we'll help.
179
+
180
+ — [Product] Team
181
+ ```
182
+
183
+ ### Email 3: Urgency (Day 7)
184
+
185
+ **Tone:** Direct, clear consequences.
186
+
187
+ ```
188
+ Subject: Your [Product] account will be paused in 3 days
189
+
190
+ Hi [Name],
191
+
192
+ We've tried to process your payment several times, but your
193
+ [card type] ending in [last 4] keeps getting declined.
194
+
195
+ If we don't receive payment by [date], your account will be
196
+ paused and you'll lose access to:
197
+
198
+ • [Key feature/data they use]
199
+ • [Their projects/workspace]
200
+ • [Team access for X members]
201
+
202
+ [Update Payment Method Now →]
203
+
204
+ Your data won't be deleted — you can reactivate anytime by
205
+ updating your payment method.
206
+
207
+ — [Product] Team
208
+ ```
209
+
210
+ ### Email 4: Final Warning (Day 10)
211
+
212
+ **Tone:** Final, clear, no guilt.
213
+
214
+ ```
215
+ Subject: Last chance to keep your [Product] account active
216
+
217
+ Hi [Name],
218
+
219
+ This is our last reminder. Your payment of $[amount] is past
220
+ due, and your account will be paused tomorrow ([date]).
221
+
222
+ [Update Payment Method →]
223
+
224
+ After pausing:
225
+ • Your data is saved for [90 days]
226
+ • You can reactivate anytime
227
+ • Just update your card to restore access
228
+
229
+ If you intended to cancel, no action needed — your account
230
+ will be paused automatically.
231
+
232
+ — [Product] Team
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Grace Period Management
238
+
239
+ ### What Happens During Grace Period
240
+
241
+ | Setting | Recommendation |
242
+ |---------|---------------|
243
+ | Duration | 7-14 days after final retry |
244
+ | Access | Degraded (read-only) or full access |
245
+ | Visibility | In-app banner: "Payment past due — update to continue" |
246
+ | Retry | Continue background retries during grace |
247
+ | Communication | Dunning emails continue |
248
+
249
+ ### Access Degradation Options
250
+
251
+ **Option A: Full access during grace (recommended for B2B)**
252
+ - Lower friction, customer feels respected
253
+ - Higher recovery rate (they still see value)
254
+ - Risk: some customers exploit the grace period
255
+
256
+ **Option B: Read-only access (recommended for B2C)**
257
+ - Can view but not create/edit
258
+ - Creates urgency without data loss fear
259
+ - Clear message: "Update payment to resume full access"
260
+
261
+ **Option C: Immediate lockout (not recommended)**
262
+ - Aggressive, damages relationship
263
+ - Lower recovery rate
264
+ - Only appropriate for very low-cost plans
265
+
266
+ ### Post-Grace Period
267
+
268
+ | Timing | Action |
269
+ |--------|--------|
270
+ | Grace period ends | Pause account (not delete) |
271
+ | Day 1 post-pause | "Your account has been paused" email |
272
+ | Day 7 post-pause | "Your data is still here" reminder |
273
+ | Day 30 post-pause | Win-back attempt with new offer |
274
+ | Day 60 post-pause | Final win-back |
275
+ | Day 90 post-pause | Data deletion warning (if applicable) |
276
+
277
+ ---
278
+
279
+ ## Provider-Specific Setup
280
+
281
+ ### Stripe
282
+
283
+ **Enable Smart Retries:**
284
+ 1. Dashboard → Settings → Billing → Subscriptions and emails
285
+ 2. Enable "Smart Retries" under retry rules
286
+ 3. Set failed payment emails in Dashboard → Settings → Emails
287
+
288
+ **Custom retry rules (if not using Smart Retries):**
289
+ ```
290
+ Retry 1: 3 days after failure
291
+ Retry 2: 5 days after failure
292
+ Retry 3: 7 days after failure
293
+ Final: Mark subscription as unpaid after last retry
294
+ ```
295
+
296
+ **Webhook events to handle:**
297
+ - `invoice.payment_failed` — trigger dunning
298
+ - `invoice.paid` — cancel dunning, restore access
299
+ - `customer.subscription.updated` — status changes
300
+ - `customer.subscription.deleted` — final cancellation
301
+
302
+ ### Chargebee
303
+
304
+ **Built-in dunning:**
305
+ 1. Settings → Configure Chargebee → Retry Settings
306
+ 2. Configure retry attempts and intervals
307
+ 3. Settings → Configure Chargebee → Email Notifications → Dunning
308
+
309
+ **Dunning options:**
310
+ - Automatic retries with configurable schedule
311
+ - Built-in dunning emails (customizable templates)
312
+ - Grace period configuration per plan
313
+
314
+ ### Paddle
315
+
316
+ **Managed dunning:**
317
+ - Paddle handles retries and dunning automatically
318
+ - Limited customization (Paddle manages the relationship)
319
+ - Webhook: `subscription.payment_failed`, `subscription.cancelled`
320
+ - Best for hands-off approach
321
+
322
+ ### Recurly
323
+
324
+ **Revenue Recovery:**
325
+ 1. Configuration → Dunning Management
326
+ 2. Set retry schedule per plan
327
+ 3. Configure grace period and final action (pause vs cancel)
328
+
329
+ **Advanced features:**
330
+ - Machine-learning retry optimization
331
+ - Per-plan dunning schedules
332
+ - Built-in Account Updater
333
+
334
+ ---
335
+
336
+ ## In-App Dunning
337
+
338
+ Don't rely on email alone. Show payment failures in the app:
339
+
340
+ ### Banner Pattern
341
+ ```
342
+ ┌──────────────────────────────────────────────────────┐
343
+ │ ⚠ Your payment of $29 failed. Update your card to │
344
+ │ avoid losing access. [Update Payment →] [Dismiss] │
345
+ └──────────────────────────────────────────────────────┘
346
+ ```
347
+
348
+ **Rules:**
349
+ - Show on every page load during dunning period
350
+ - Allow dismiss (but show again next session)
351
+ - Direct link to payment update (fewest clicks possible)
352
+ - Don't block the product — let them continue using it
353
+
354
+ ### Modal Pattern (for final warning)
355
+ ```
356
+ ┌─────────────────────────────────────┐
357
+ │ │
358
+ │ Your account will be paused │
359
+ │ on [date] │
360
+ │ │
361
+ │ Update your payment method to │
362
+ │ keep access to your [X] projects │
363
+ │ and [Y] team members. │
364
+ │ │
365
+ │ [Update Payment Method] │
366
+ │ [Remind Me Later] │
367
+ │ │
368
+ └─────────────────────────────────────┘
369
+ ```
370
+
371
+ ---
372
+
373
+ ## Measuring Dunning Performance
374
+
375
+ ### Key Metrics
376
+
377
+ | Metric | How to Calculate | Target |
378
+ |--------|-----------------|--------|
379
+ | Recovery rate | Recovered payments / Total failed | 50-60% |
380
+ | Recovery rate by decline type | Recovered / Failed per type | Soft: 70%+, Hard: 40%+ |
381
+ | Time to recovery | Days from failure to successful payment | <5 days |
382
+ | Pre-dunning prevention rate | Prevented failures / Expected failures | 20-30% |
383
+ | Dunning email open rate | Opens / Sent per email | 60%+ |
384
+ | Dunning email click rate | Clicks / Opens per email | 30%+ |
385
+ | Revenue recovered (monthly) | Sum of recovered payment amounts | Track trend |
386
+ | Revenue lost to involuntary churn | Sum of failed + unrecovered amounts | Track trend |
387
+
388
+ ### Benchmarking
389
+
390
+ **By company stage:**
391
+
392
+ | Stage | Typical Involuntary Churn | Target After Optimization |
393
+ |-------|--------------------------|--------------------------|
394
+ | Early (< $1M ARR) | 3-5% of MRR/month | 1-2% |
395
+ | Growth ($1-10M ARR) | 2-4% of MRR/month | 0.5-1.5% |
396
+ | Scale ($10M+ ARR) | 1-3% of MRR/month | 0.3-0.8% |
397
+
398
+ ### ROI Calculation
399
+
400
+ ```
401
+ Monthly failed payment MRR: $10,000
402
+ Current recovery rate: 30% ($3,000 recovered)
403
+ Target recovery rate: 60% ($6,000 recovered)
404
+ Monthly improvement: $3,000/month
405
+ Annual improvement: $36,000/year
406
+ Cost of dunning optimization: ~$200-500/month (tooling)
407
+ ROI: 6-15x
408
+ ```
@@ -0,0 +1,240 @@
1
+ ---
2
+ name: cloud-security
3
+ description: Rigorous security and data privacy scan for cloud deployments. Covers GCP infrastructure hardening, data privacy (PII/GDPR/CCPA), API security, container security, and compliance.
4
+ category: quality
5
+ tier: on-demand
6
+ slash_command: /cloud-security
7
+ ---
8
+
9
+ # Cloud Security — Cloud Security & Data Privacy Scan
10
+
11
+ Rigorous security and data privacy scan for cloud deployments. Covers GCP infrastructure hardening, data privacy (PII/GDPR/CCPA), API security, container security, and compliance.
12
+
13
+ ## Do NOT ask for permission — scan everything, fix what you can, report the rest.
14
+
15
+ ---
16
+
17
+ ## Step 0 — Detect cloud config
18
+
19
+ ```bash
20
+ PROJECT_ROOT=$(git rev-parse --show-toplevel)
21
+ INSTRUCTION_FILE=$(for f in CLAUDE.md AGENTS.md .cursorrules .windsurfrules; do [ -f "$PROJECT_ROOT/$f" ] && echo "$PROJECT_ROOT/$f" && break; done)
22
+ GCP_PROJECTS=$(grep -rh "GCP_PROJECT\|GOOGLE_CLOUD_PROJECT\|gcloud.*--project" ${INSTRUCTION_FILE:-/dev/null} .env.example terraform/ 2>/dev/null | grep -oE '[a-z][a-z0-9-]{4,28}' | sort -u | grep -v "^--" || true)
23
+ HAS_DOCKER=$(ls Dockerfile docker-compose.yml 2>/dev/null | head -1 || true)
24
+ HAS_TERRAFORM=$(ls terraform/*.tf infra/*.tf 2>/dev/null | head -1 || true)
25
+ ```
26
+
27
+ ---
28
+
29
+ ## Section 1 — GCP IAM & Access Control
30
+
31
+ For each GCP project detected:
32
+
33
+ ```bash
34
+ for PROJECT in $GCP_PROJECTS; do
35
+ echo "=== IAM: $PROJECT ==="
36
+ gcloud projects get-iam-policy "$PROJECT" --format=json 2>/dev/null \
37
+ | python3 -c "
38
+ import sys,json
39
+ p=json.load(sys.stdin)
40
+ bad=['roles/editor','roles/owner','roles/iam.securityAdmin','roles/storage.admin']
41
+ [print('[HIGH]',b['role'],m) for b in p.get('bindings',[]) for m in b['members'] if b['role'] in bad and ('serviceAccount' in m or 'allUsers' in m)]"
42
+ gcloud iam service-accounts list --project="$PROJECT" --format="value(email)" 2>/dev/null \
43
+ | while read SA; do
44
+ n=$(gcloud iam service-accounts keys list --iam-account="$SA" --filter="keyType=USER_MANAGED" --format="value(KEY_ID)" 2>/dev/null | wc -l)
45
+ [ "$n" -gt 0 ] && echo "[HIGH] $SA: $n user-managed key(s) — use Workload Identity instead"
46
+ done
47
+ gcloud projects get-iam-policy "$PROJECT" --format=json 2>/dev/null | grep -E "allUsers|allAuthenticatedUsers" && echo "[CRITICAL] Public IAM binding found" || true
48
+ done
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Section 2 — GCP Network & Firewall
54
+
55
+ ```bash
56
+ for PROJECT in $GCP_PROJECTS; do
57
+ echo "=== Network: $PROJECT ==="
58
+ gcloud compute firewall-rules list --project="$PROJECT" --format=json 2>/dev/null \
59
+ | python3 -c "
60
+ import sys,json
61
+ sp={'22','3389','5432','6379','3306','27017','6443'}
62
+ [print('[CRITICAL] Firewall',r['name'],'port',p,'open to 0.0.0.0/0') for r in json.load(sys.stdin) if '0.0.0.0/0' in r.get('sourceRanges',[]) or '::/0' in r.get('sourceRanges',[]) for a in r.get('allowed',[]) for p in a.get('ports',[]) if str(p) in sp]"
63
+ gcloud sql instances list --project="$PROJECT" --format=json 2>/dev/null \
64
+ | python3 -c "
65
+ import sys,json
66
+ for i in json.load(sys.stdin):
67
+ n,ip=i['name'],i.get('settings',{}).get('ipConfiguration',{})
68
+ [print('[CRITICAL] Cloud SQL',n,'public IP open to',net['value']) if net.get('value') in ('0.0.0.0/0','::/0') else print('[MEDIUM] Cloud SQL',n,'public IP enabled') for net in ip.get('authorizedNetworks',[])] if ip.get('ipv4Enabled') else None
69
+ print('[HIGH] Cloud SQL',n,'SSL not required') if not ip.get('requireSsl') and ip.get('sslMode','')!='ENCRYPTED_ONLY' else print('[PASS] Cloud SQL',n,'SSL enforced')
70
+ print('[HIGH] Cloud SQL',n,'backups disabled') if not i.get('settings',{}).get('backupConfiguration',{}).get('enabled') else None"
71
+ done
72
+ ```
73
+
74
+ ---
75
+
76
+ ## Section 3 — GCP Data Storage (GCS Buckets)
77
+
78
+ ```bash
79
+ for PROJECT in $GCP_PROJECTS; do
80
+ echo "=== Storage: $PROJECT ==="
81
+ gcloud storage buckets list --project="$PROJECT" --format="value(name)" 2>/dev/null | while read BUCKET; do
82
+ gcloud storage buckets get-iam-policy "gs://$BUCKET" --format=json 2>/dev/null \
83
+ | grep -qE "allUsers|allAuthenticatedUsers" && echo "[CRITICAL] Bucket gs://$BUCKET is public" || true
84
+ [ "$(gcloud storage buckets describe "gs://$BUCKET" --format="value(iamConfiguration.uniformBucketLevelAccess.enabled)" 2>/dev/null)" != "True" ] \
85
+ && echo "[MEDIUM] Bucket gs://$BUCKET: uniform access not enabled" || true
86
+ [ "$(gcloud storage buckets describe "gs://$BUCKET" --format="value(versioning.enabled)" 2>/dev/null)" != "True" ] \
87
+ && echo "[LOW] Bucket gs://$BUCKET: versioning not enabled" || true
88
+ done
89
+ done
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Section 4 — GCP Cloud Run Security
95
+
96
+ ```bash
97
+ for PROJECT in $GCP_PROJECTS; do
98
+ echo "=== Cloud Run: $PROJECT ==="
99
+ gcloud run services list --project="$PROJECT" --format=json --region=us-central1 2>/dev/null \
100
+ | python3 -c "
101
+ import sys,json
102
+ [print('[HIGH] Cloud Run',s['metadata']['name'],'env',e['name'],'may contain hardcoded secret') for s in json.load(sys.stdin) for c in s.get('spec',{}).get('template',{}).get('spec',{}).get('containers',[]) for e in c.get('env',[]) if len(e.get('value',''))>20 and not e.get('value','').startswith('\$(') and 'secretKeyRef' not in str(e)]" 2>/dev/null || true
103
+ gcloud run services list --project="$PROJECT" --region=us-central1 --format="value(SERVICE)" 2>/dev/null \
104
+ | while read SVC; do
105
+ gcloud run services get-iam-policy "$SVC" --project="$PROJECT" --region=us-central1 --format=json 2>/dev/null \
106
+ | grep -q "allUsers" && echo "[INFO] Cloud Run $SVC: public — verify app-level auth" || true
107
+ done
108
+ done
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Section 5 — GCP Audit Logging
114
+
115
+ ```bash
116
+ for PROJECT in $GCP_PROJECTS; do
117
+ echo "=== Audit Logging: $PROJECT ==="
118
+ gcloud projects get-iam-policy "$PROJECT" --format=json 2>/dev/null \
119
+ | python3 -c "
120
+ import sys,json
121
+ p=json.load(sys.stdin)
122
+ svcs={c['service'] for c in p.get('auditConfigs',[]) for l in c.get('auditLogConfigs',[]) if l.get('logType') in ('DATA_READ','DATA_WRITE')}
123
+ [print('[PASS] Audit logging:',s) if s in svcs else print('[MEDIUM] Audit logging not enabled:',s) for s in ['cloudsql.googleapis.com','storage.googleapis.com','secretmanager.googleapis.com']]"
124
+ done
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Section 6 — Secret Manager Hygiene
130
+
131
+ ```bash
132
+ for PROJECT in $GCP_PROJECTS; do
133
+ echo "=== Secrets: $PROJECT ==="
134
+ gcloud secrets list --project="$PROJECT" --format=json 2>/dev/null \
135
+ | python3 -c "
136
+ import sys,json
137
+ [print('[LOW] Secret',s['name'].split('/')[-1],'no rotation policy') for s in json.load(sys.stdin) if not s.get('rotation')]"
138
+ done
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Section 7 — Container Security (if Dockerfile present)
144
+
145
+ ```bash
146
+ if [ -n "$HAS_DOCKER" ]; then
147
+ echo "=== Container Security ==="
148
+ grep -rq "^USER root\|USER 0" Dockerfile 2>/dev/null && echo "[HIGH] Dockerfile: runs as root" || \
149
+ { grep -q "^USER" Dockerfile 2>/dev/null && echo "[PASS] non-root USER set" || echo "[HIGH] Dockerfile: no USER directive (defaults to root)"; }
150
+ grep -qE "^(ARG|ENV)\s+\w+(KEY|SECRET|PASSWORD|TOKEN|PASS)=\S+" Dockerfile 2>/dev/null \
151
+ && echo "[CRITICAL] Dockerfile: hardcoded secret in ARG/ENV" || echo "[PASS] No hardcoded secrets"
152
+ grep "^FROM" Dockerfile 2>/dev/null | head -1 | grep -q ":latest" \
153
+ && echo "[MEDIUM] Dockerfile: base image uses :latest — pin version" || echo "[PASS] Base image pinned"
154
+ grep -q "^RUN chown" Dockerfile 2>/dev/null && echo "[LOW] Dockerfile: use COPY --chown instead of RUN chown" || true
155
+ fi
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Section 8 — Data Privacy: PII in Source Code
161
+
162
+ Scan for PII patterns that should never appear in source code or logs.
163
+
164
+ ```bash
165
+ echo "=== PII in Source Code ==="
166
+ EXCL="--exclude-dir=node_modules --exclude-dir=venv --exclude-dir=dist"
167
+ # Hardcoded emails (non-test/example)
168
+ grep -rn $EXCL '[a-zA-Z0-9._%+-]\+@[a-zA-Z0-9.-]\+\.[a-zA-Z]\{2,\}' --include="*.ts" --include="*.tsx" --include="*.py" --include="*.js" . 2>/dev/null \
169
+ | grep -v "example\.com\|test\|mock\|\.spec\.\|\.test\.\|noreply@\|support@\|hello@\|admin@" | head -5 \
170
+ | grep -q . && echo "[HIGH] Real email addresses found in source" || true
171
+ # SSN / credit card patterns
172
+ grep -rn $EXCL '[0-9]\{3\}-[0-9]\{2\}-[0-9]\{4\}' --include="*.ts" --include="*.py" . 2>/dev/null | head -5 | grep -q . && echo "[CRITICAL] SSN pattern in source" || true
173
+ grep -rn $EXCL '[0-9]\{4\}[- ][0-9]\{4\}[- ][0-9]\{4\}[- ][0-9]\{4\}' --include="*.ts" --include="*.py" . 2>/dev/null | head -5 | grep -q . && echo "[CRITICAL] Credit card pattern in source" || true
174
+ # PII in logs / error responses
175
+ grep -rn $EXCL "console\.log\|logger\." --include="*.ts" --include="*.py" --exclude="*.test.*" . 2>/dev/null \
176
+ | grep -iE "email|password|ssn|credit.card|phone|dob|social.security" | head -5 \
177
+ | grep -q . && echo "[HIGH] PII field names in log statements" || echo "[PASS] No PII in log statements"
178
+ grep -rn $EXCL "res\.json\|res\.send\|return.*error" --include="*.ts" --exclude="*.test.*" . 2>/dev/null \
179
+ | grep -iE "email|password|user\." | grep -v "error\.message\|//\|generic" | head -5 \
180
+ | grep -q . && echo "[MEDIUM] Possible PII in API error responses — verify generic" || true
181
+ ```
182
+
183
+ ---
184
+
185
+ ## Section 9 — Data Privacy Compliance Checklist
186
+
187
+ Review manually. Report gaps.
188
+
189
+ GDPR/CCPA: □ Privacy Policy □ Data Inventory □ Consent □ Right to Delete □ Right to Export □ Data Retention □ Third-party DPAs □ Breach Response □ Data Minimization □ Encryption at Rest □ Encryption Transit □ Audit Trail
190
+
191
+ ```bash
192
+ grep -rn "DELETE.*user\|deleteUser\|deactivate" api/ src/ 2>/dev/null | head -3 || echo "[GAP] No delete user endpoint found"
193
+ grep -rn "export.*user\|userExport\|data.*export" api/ src/ 2>/dev/null | head -3 || echo "[GAP] No export user endpoint found"
194
+ grep -rn "retention\|expires\|cleanup\|purge" api/ 2>/dev/null | head -3 || echo "[GAP] No retention policy found"
195
+ ```
196
+
197
+ ---
198
+
199
+ ## Section 10 — API Security Hygiene
200
+
201
+ ```bash
202
+ echo "=== API Security ==="
203
+ X="--exclude-dir=node_modules"
204
+ grep -rn $X "helmet\|Content-Security-Policy\|Strict-Transport" --include="*.ts" --include="*.py" . 2>/dev/null | grep -q . \
205
+ && echo "[PASS] Security headers configured" || echo "[HIGH] No security headers (helmet/CSP) found"
206
+ grep -rn $X "rateLimit\|rate.limit\|RateLimiter\|throttle" --include="*.ts" --include="*.py" . 2>/dev/null | grep -q . \
207
+ && echo "[PASS] Rate limiting configured" || echo "[MEDIUM] No rate limiting found"
208
+ grep -rn $X "origin.*['\"]\\*['\"]" --include="*.ts" --include="*.py" . 2>/dev/null | grep -q . \
209
+ && echo "[HIGH] CORS wildcard (*) origin found" || echo "[PASS] No CORS wildcard"
210
+ grep -rn $X --exclude="*.test.*" "query.*\`.*\${" --include="*.ts" --include="*.py" . 2>/dev/null | grep -v '\$\${' | grep -q . \
211
+ && echo "[CRITICAL] SQL injection risk — string interpolation in queries" || echo "[PASS] No SQL injection patterns"
212
+ grep -rn $X --exclude="*.test.*" "eval[(]" --include="*.ts" --include="*.tsx" --include="*.js" . 2>/dev/null | grep -q . \
213
+ && echo "[HIGH] unsafe-eval usage found" || echo "[PASS] No unsafe-eval usage"
214
+ ```
215
+
216
+ ---
217
+
218
+ ## Section 11 — Terraform / IaC Security (if present)
219
+
220
+ ```bash
221
+ if [ -n "$HAS_TERRAFORM" ]; then
222
+ echo "=== Terraform Security ==="
223
+ grep -rn "roles/editor\|roles/owner\|storage\.admin\|secretmanager\.admin" terraform/ infra/ 2>/dev/null \
224
+ | grep -v "^#\|\.terraform" | grep -q . && echo "[HIGH] Overly broad IAM role in Terraform" || echo "[PASS] No overly broad IAM roles"
225
+ grep -rn "CHANGE_ME\|password.*default\|default.*password" terraform/ infra/ 2>/dev/null \
226
+ | grep -v "^#" | grep -q . && echo "[CRITICAL] Default/placeholder password in Terraform" || true
227
+ grep -rn "0\.0\.0\.0/0\|all_traffic\|allUsers" terraform/ infra/ 2>/dev/null \
228
+ | grep -v "^#\|egress" | grep -q . && echo "[HIGH] Possible public resource in Terraform" || true
229
+ fi
230
+ ```
231
+
232
+ ---
233
+
234
+ ## Final report
235
+
236
+ Summarize results per section: S1 IAM | S2 Network | S3 Storage | S4 Cloud Run | S5 Audit | S6 Secrets | S7 Container | S8 PII | S9 Privacy | S10 API | S11 Terraform
237
+
238
+ Report totals: CRITICAL: N HIGH: N MEDIUM: N LOW: N
239
+
240
+ **Gate 5:** BLOCKED if any CRITICAL or HIGH. PASSED if zero critical + zero high.