agents-united 0.12.0 → 0.14.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 (252) hide show
  1. package/README.md +466 -411
  2. package/dist/cli.d.ts +26 -1
  3. package/dist/cli.js +3805 -891
  4. package/dist/cli.js.map +1 -1
  5. package/package.json +3 -3
  6. package/registry/agents/orchestrator-business.md +50 -16
  7. package/registry/agents/orchestrator-design.md +50 -12
  8. package/registry/agents/orchestrator-digital-agency.md +32 -27
  9. package/registry/agents/orchestrator-engineering.md +46 -20
  10. package/registry/agents/orchestrator-marketing.md +43 -13
  11. package/registry/agents/orchestrator-research.md +43 -17
  12. package/registry/agents/orchestrator-security.md +44 -16
  13. package/registry/agents/orchestrator-system-architecture.md +43 -11
  14. package/registry/agents/orchestrator-universal.md +43 -0
  15. package/registry/agents/subagent-accessibility-lead.md +57 -2
  16. package/registry/agents/subagent-ai-model-architect.md +55 -1
  17. package/registry/agents/subagent-android-architect.md +61 -2
  18. package/registry/agents/subagent-appsec-penetration-tester.md +34 -0
  19. package/registry/agents/subagent-backend-architect.md +78 -229
  20. package/registry/agents/subagent-business-panel-experts.md +13 -0
  21. package/registry/agents/subagent-cloud-infrastructure-architect.md +30 -0
  22. package/registry/agents/subagent-cloud-security-architect.md +14 -0
  23. package/registry/agents/subagent-code-reviewer.md +54 -11
  24. package/registry/agents/subagent-compliance-grc-specialist.md +22 -1
  25. package/registry/agents/subagent-cross-platform-specialist.md +62 -2
  26. package/registry/agents/subagent-data-engineer.md +61 -2
  27. package/registry/agents/subagent-database-administrator.md +14 -0
  28. package/registry/agents/subagent-deep-research.md +12 -0
  29. package/registry/agents/subagent-design-ops-lead.md +13 -0
  30. package/registry/agents/subagent-design-researcher.md +13 -0
  31. package/registry/agents/subagent-design-systems-architect.md +13 -0
  32. package/registry/agents/subagent-designer-toolkit-expert.md +12 -0
  33. package/registry/agents/subagent-devops-engineer.md +75 -287
  34. package/registry/agents/subagent-distributed-systems-architect.md +62 -2
  35. package/registry/agents/subagent-e2e-tester.md +59 -2
  36. package/registry/agents/subagent-financial-analyst.md +13 -0
  37. package/registry/agents/subagent-finops-cost-engineer.md +12 -0
  38. package/registry/agents/subagent-frontend-architect.md +73 -231
  39. package/registry/agents/subagent-interaction-designer.md +13 -0
  40. package/registry/agents/subagent-ios-architect.md +61 -2
  41. package/registry/agents/subagent-legal-contract-analyst.md +13 -0
  42. package/registry/agents/subagent-lifecycle-email-specialist.md +13 -0
  43. package/registry/agents/subagent-literature-patent-analyst.md +13 -0
  44. package/registry/agents/subagent-market-intelligence-analyst.md +13 -0
  45. package/registry/agents/subagent-marketing-campaign-specialist.md +21 -1
  46. package/registry/agents/subagent-marketing-content-strategist.md +21 -1
  47. package/registry/agents/subagent-marketing-conversion-specialist.md +21 -1
  48. package/registry/agents/subagent-marketing-creative-designer.md +21 -1
  49. package/registry/agents/subagent-marketing-growth-strategist.md +21 -1
  50. package/registry/agents/subagent-ml-platform-engineer.md +55 -1
  51. package/registry/agents/subagent-operations-strategist.md +13 -0
  52. package/registry/agents/subagent-paid-acquisition-specialist.md +13 -0
  53. package/registry/agents/subagent-plg-strategist.md +13 -0
  54. package/registry/agents/subagent-prototype-tester.md +12 -0
  55. package/registry/agents/subagent-qa-automation-lead.md +50 -78
  56. package/registry/agents/subagent-repo-index.md +44 -1
  57. package/registry/agents/subagent-security-engineer.md +45 -0
  58. package/registry/agents/subagent-seo-specialist.md +21 -2
  59. package/registry/agents/subagent-socratic-mentor.md +13 -0
  60. package/registry/agents/subagent-statistical-analyst.md +12 -0
  61. package/registry/agents/subagent-sysops-sre-lead.md +14 -0
  62. package/registry/agents/subagent-system-architect.md +14 -0
  63. package/registry/agents/subagent-ui-designer.md +13 -0
  64. package/registry/agents/subagent-ux-strategist.md +13 -0
  65. package/registry/bundles.json +364 -34
  66. package/registry/core/orchestrator-engineering.core.md +34 -0
  67. package/registry/core/subagent-backend-architect.core.md +71 -0
  68. package/registry/core/subagent-code-reviewer.core.md +84 -0
  69. package/registry/core/subagent-frontend-architect.core.md +57 -0
  70. package/registry/core/subagent-repo-index.core.md +74 -0
  71. package/registry/profiles/claude@2.1.271.json +48 -0
  72. package/registry/realizations/claude/orchestrator-engineering.json +14 -0
  73. package/registry/realizations/claude/subagent-backend-architect.json +16 -0
  74. package/registry/realizations/claude/subagent-code-reviewer.json +15 -0
  75. package/registry/realizations/claude/subagent-frontend-architect.json +15 -0
  76. package/registry/realizations/claude/subagent-repo-index.json +15 -0
  77. package/registry/skills/ai-prototype-refactoring/SKILL.md +24 -0
  78. package/registry/skills/ai-prototype-refactoring/references/backend-frontend-devops-exemplars.md +104 -0
  79. package/registry/skills/azure-infrastructure-bicep/SKILL.md +24 -0
  80. package/registry/skills/azure-infrastructure-bicep/references/backend-frontend-devops-exemplars.md +173 -0
  81. package/registry/skills/banner-design/SKILL.md +170 -0
  82. package/registry/skills/banner-design/references/banner-sizes-and-styles.md +66 -0
  83. package/registry/skills/brand-identity/SKILL.md +212 -0
  84. package/registry/skills/brand-identity/references/approval-checklist.md +17 -0
  85. package/registry/skills/brand-identity/references/asset-organization.md +30 -0
  86. package/registry/skills/brand-identity/references/brand-guideline-template.md +57 -0
  87. package/registry/skills/brand-identity/references/color-palette-management.md +37 -0
  88. package/registry/skills/brand-identity/references/consistency-checklist.md +26 -0
  89. package/registry/skills/brand-identity/references/logo-usage-rules.md +23 -0
  90. package/registry/skills/brand-identity/references/messaging-framework.md +22 -0
  91. package/registry/skills/brand-identity/references/typography-specifications.md +29 -0
  92. package/registry/skills/brand-identity/references/visual-identity.md +23 -0
  93. package/registry/skills/brand-identity/references/voice-framework.md +27 -0
  94. package/registry/skills/brand-identity/scripts/extract-colors.mjs +104 -0
  95. package/registry/skills/brand-identity/scripts/inject-brand-context.mjs +112 -0
  96. package/registry/skills/brand-identity/scripts/lib/confirm-gate.mjs +28 -0
  97. package/registry/skills/brand-identity/scripts/sync-brand-to-tokens.mjs +205 -0
  98. package/registry/skills/brand-identity/scripts/validate-asset.mjs +137 -0
  99. package/registry/skills/clickhouse-architecture-advisor/SKILL.md +202 -0
  100. package/registry/skills/codeql-scanning/LICENSE +427 -0
  101. package/registry/skills/codeql-scanning/NOTICE.md +31 -0
  102. package/registry/skills/codeql-scanning/SKILL.md +136 -0
  103. package/registry/skills/codeql-scanning/references/build-fixes.md +105 -0
  104. package/registry/skills/codeql-scanning/references/diagnostic-query-templates.md +325 -0
  105. package/registry/skills/codeql-scanning/references/extension-yaml-format.md +202 -0
  106. package/registry/skills/codeql-scanning/references/important-only-suite.md +119 -0
  107. package/registry/skills/codeql-scanning/references/language-details.md +220 -0
  108. package/registry/skills/codeql-scanning/references/macos-arm64e-workaround.md +201 -0
  109. package/registry/skills/codeql-scanning/references/performance-tuning.md +81 -0
  110. package/registry/skills/codeql-scanning/references/quality-assessment.md +197 -0
  111. package/registry/skills/codeql-scanning/references/ruleset-catalog.md +68 -0
  112. package/registry/skills/codeql-scanning/references/run-all-suite.md +106 -0
  113. package/registry/skills/codeql-scanning/references/sarif-processing.md +82 -0
  114. package/registry/skills/codeql-scanning/references/threat-models.md +36 -0
  115. package/registry/skills/codeql-scanning/references/upstream-method.md +288 -0
  116. package/registry/skills/codeql-scanning/references/workflow-build-database.md +338 -0
  117. package/registry/skills/codeql-scanning/references/workflow-create-data-extensions.md +275 -0
  118. package/registry/skills/codeql-scanning/references/workflow-run-analysis.md +327 -0
  119. package/registry/skills/codeql-scanning/scripts/build_log.py +91 -0
  120. package/registry/skills/codeql-scanning/scripts/check_db_quality.py +366 -0
  121. package/registry/skills/codeql-scanning/scripts/find_databases.py +90 -0
  122. package/registry/skills/codeql-scanning/scripts/generate_suite.py +101 -0
  123. package/registry/skills/codeql-scanning/scripts/verify_query_suite.py +86 -0
  124. package/registry/skills/edge-security-audit/SKILL.md +225 -0
  125. package/registry/skills/expo-cicd-workflows/SKILL.md +228 -0
  126. package/registry/skills/hf-managed-jobs/SKILL.md +198 -0
  127. package/registry/skills/hf-model-training/SKILL.md +204 -0
  128. package/registry/skills/mutation-testing/LICENSE +427 -0
  129. package/registry/skills/mutation-testing/NOTICE.md +31 -0
  130. package/registry/skills/mutation-testing/SKILL.md +122 -0
  131. package/registry/skills/mutation-testing/references/blockchain-patterns.md +103 -0
  132. package/registry/skills/mutation-testing/references/equivalent-mutants.md +101 -0
  133. package/registry/skills/mutation-testing/references/input-formats.md +84 -0
  134. package/registry/skills/mutation-testing/references/optimization-strategies.md +327 -0
  135. package/registry/skills/mutation-testing/references/report-template.md +140 -0
  136. package/registry/skills/mutation-testing/references/severity-classification.md +132 -0
  137. package/registry/skills/mutation-testing/references/upstream-method.md +105 -0
  138. package/registry/skills/mutation-testing/references/workflow-analyzing-results.md +123 -0
  139. package/registry/skills/mutation-testing/references/workflow-bug-hunter.md +139 -0
  140. package/registry/skills/mutation-testing/references/workflow-configuration.md +338 -0
  141. package/registry/skills/playwright-best-practices/SKILL.md +5 -0
  142. package/registry/skills/playwright-best-practices/references/conversion-funnel-test.md +79 -0
  143. package/registry/skills/postgres-best-practices/SKILL.md +205 -0
  144. package/registry/skills/property-based-testing/LICENSE +427 -0
  145. package/registry/skills/property-based-testing/NOTICE.md +31 -0
  146. package/registry/skills/property-based-testing/SKILL.md +119 -0
  147. package/registry/skills/property-based-testing/references/generating.md +82 -0
  148. package/registry/skills/property-based-testing/references/interpreting-failures.md +83 -0
  149. package/registry/skills/property-based-testing/references/libraries.md +80 -0
  150. package/registry/skills/property-based-testing/references/refactoring.md +123 -0
  151. package/registry/skills/property-based-testing/references/reviewing.md +81 -0
  152. package/registry/skills/property-based-testing/references/upstream-method.md +65 -0
  153. package/registry/skills/react-best-practices/SKILL.md +5 -0
  154. package/registry/skills/react-best-practices/references/nextjs-server-actions-and-isr.md +85 -0
  155. package/registry/skills/sarif-triage/LICENSE +427 -0
  156. package/registry/skills/sarif-triage/NOTICE.md +31 -0
  157. package/registry/skills/sarif-triage/SKILL.md +117 -0
  158. package/registry/skills/sarif-triage/references/jq-queries.md +210 -0
  159. package/registry/skills/sarif-triage/references/upstream-method.md +490 -0
  160. package/registry/skills/sarif-triage/scripts/sarif_helpers.py +400 -0
  161. package/registry/skills/security-best-practices/LICENSE +201 -0
  162. package/registry/skills/security-best-practices/NOTICE.md +30 -0
  163. package/registry/skills/security-best-practices/SKILL.md +116 -0
  164. package/registry/skills/security-best-practices/references/golang-general-backend-security.md +829 -0
  165. package/registry/skills/security-best-practices/references/javascript-express-web-server-security.md +1161 -0
  166. package/registry/skills/security-best-practices/references/javascript-general-web-frontend-security.md +750 -0
  167. package/registry/skills/security-best-practices/references/javascript-jquery-web-frontend-security.md +681 -0
  168. package/registry/skills/security-best-practices/references/javascript-typescript-nextjs-web-server-security.md +1147 -0
  169. package/registry/skills/security-best-practices/references/javascript-typescript-react-web-frontend-security.md +993 -0
  170. package/registry/skills/security-best-practices/references/javascript-typescript-vue-web-frontend-security.md +794 -0
  171. package/registry/skills/security-best-practices/references/python-django-web-server-security.md +885 -0
  172. package/registry/skills/security-best-practices/references/python-fastapi-web-server-security.md +1039 -0
  173. package/registry/skills/security-best-practices/references/python-flask-web-server-security.md +708 -0
  174. package/registry/skills/security-best-practices/references/upstream-method.md +86 -0
  175. package/registry/skills/security-diff-review/LICENSE +427 -0
  176. package/registry/skills/security-diff-review/NOTICE.md +31 -0
  177. package/registry/skills/security-diff-review/SKILL.md +125 -0
  178. package/registry/skills/security-diff-review/references/adversarial.md +206 -0
  179. package/registry/skills/security-diff-review/references/methodology.md +237 -0
  180. package/registry/skills/security-diff-review/references/patterns.md +303 -0
  181. package/registry/skills/security-diff-review/references/reporting.md +372 -0
  182. package/registry/skills/security-diff-review/references/upstream-method.md +222 -0
  183. package/registry/skills/semgrep-scanning/LICENSE +427 -0
  184. package/registry/skills/semgrep-scanning/NOTICE.md +31 -0
  185. package/registry/skills/semgrep-scanning/SKILL.md +139 -0
  186. package/registry/skills/semgrep-scanning/references/rulesets.md +165 -0
  187. package/registry/skills/semgrep-scanning/references/scan-modes.md +153 -0
  188. package/registry/skills/semgrep-scanning/references/upstream-method.md +262 -0
  189. package/registry/skills/semgrep-scanning/references/workflow-scan-workflow.md +467 -0
  190. package/registry/skills/semgrep-scanning/scripts/merge_sarif.py +339 -0
  191. package/registry/skills/semgrep-scanning/scripts/run_scans.py +482 -0
  192. package/registry/skills/sentry-incident-triage/SKILL.md +193 -0
  193. package/registry/skills/supabase-backend-architecture/SKILL.md +24 -0
  194. package/registry/skills/supabase-backend-architecture/references/backend-frontend-devops-exemplars.md +140 -0
  195. package/registry/skills/supply-chain-risk-audit/LICENSE +427 -0
  196. package/registry/skills/supply-chain-risk-audit/NOTICE.md +31 -0
  197. package/registry/skills/supply-chain-risk-audit/SKILL.md +119 -0
  198. package/registry/skills/supply-chain-risk-audit/references/upstream-method.md +123 -0
  199. package/registry/skills/supply-chain-risk-audit/scripts/collect.py +1568 -0
  200. package/registry/skills/supply-chain-risk-audit/scripts/model.py +402 -0
  201. package/registry/skills/supply-chain-risk-audit/scripts/pyproject.toml +20 -0
  202. package/registry/skills/supply-chain-risk-audit/scripts/render.py +809 -0
  203. package/registry/skills/supply-chain-risk-audit/scripts/sources.py +683 -0
  204. package/registry/skills/supply-chain-risk-audit/scripts/uv.lock +12 -0
  205. package/registry/skills/terraform-style-guide/LICENSE +373 -0
  206. package/registry/skills/terraform-style-guide/NOTICE.md +31 -0
  207. package/registry/skills/terraform-style-guide/SKILL.md +126 -0
  208. package/registry/skills/terraform-style-guide/references/security.md +167 -0
  209. package/registry/skills/terraform-style-guide/references/style-conventions.md +312 -0
  210. package/registry/skills/terraform-test-patterns/LICENSE +373 -0
  211. package/registry/skills/terraform-test-patterns/NOTICE.md +31 -0
  212. package/registry/skills/terraform-test-patterns/SKILL.md +133 -0
  213. package/registry/skills/terraform-test-patterns/references/ci-cd.md +83 -0
  214. package/registry/skills/terraform-test-patterns/references/examples.md +317 -0
  215. package/registry/skills/terraform-test-patterns/references/mock-providers.md +174 -0
  216. package/registry/skills/terraform-test-patterns/references/test-syntax.md +445 -0
  217. package/registry/skills/threat-modeling/LICENSE +201 -0
  218. package/registry/skills/threat-modeling/NOTICE.md +31 -0
  219. package/registry/skills/threat-modeling/SKILL.md +136 -0
  220. package/registry/skills/threat-modeling/references/prompt-template.md +258 -0
  221. package/registry/skills/threat-modeling/references/security-controls-and-assets.md +35 -0
  222. package/registry/skills/threat-modeling/references/upstream-method.md +81 -0
  223. package/registry/skills/turso-distributed-sqlite/SKILL.md +24 -0
  224. package/registry/skills/turso-distributed-sqlite/references/backend-frontend-devops-exemplars.md +92 -0
  225. package/registry/skills/ux-writing/SKILL.md +183 -0
  226. package/registry/skills/ux-writing/references/interface-patterns.md +41 -0
  227. package/registry/skills/ux-writing/references/localization-accessibility.md +31 -0
  228. package/registry/skills/ux-writing/references/research-measurement.md +27 -0
  229. package/registry/skills/ux-writing/references/source-runtime-workflow.md +31 -0
  230. package/registry/skills/ux-writing/references/voice-tone-terminology.md +26 -0
  231. package/registry/skills/variant-analysis/LICENSE +427 -0
  232. package/registry/skills/variant-analysis/NOTICE.md +31 -0
  233. package/registry/skills/variant-analysis/SKILL.md +119 -0
  234. package/registry/skills/variant-analysis/assets/codeql/cpp.ql +119 -0
  235. package/registry/skills/variant-analysis/assets/codeql/go.ql +69 -0
  236. package/registry/skills/variant-analysis/assets/codeql/java.ql +71 -0
  237. package/registry/skills/variant-analysis/assets/codeql/javascript.ql +63 -0
  238. package/registry/skills/variant-analysis/assets/codeql/python.ql +80 -0
  239. package/registry/skills/variant-analysis/assets/semgrep/cpp.yaml +98 -0
  240. package/registry/skills/variant-analysis/assets/semgrep/go.yaml +63 -0
  241. package/registry/skills/variant-analysis/assets/semgrep/java.yaml +61 -0
  242. package/registry/skills/variant-analysis/assets/semgrep/javascript.yaml +60 -0
  243. package/registry/skills/variant-analysis/assets/semgrep/python.yaml +72 -0
  244. package/registry/skills/variant-analysis/references/reporting.md +41 -0
  245. package/registry/skills/variant-analysis/references/root-cause.md +101 -0
  246. package/registry/skills/variant-analysis/references/searching.md +162 -0
  247. package/registry/skills/variant-analysis/references/triage.md +95 -0
  248. package/registry/skills/variant-analysis/references/upstream-method.md +74 -0
  249. package/registry/skills/variant-analysis/references/variant-report-template.md +78 -0
  250. package/registry/skills/vercel-deploy-best-practices/SKILL.md +24 -0
  251. package/registry/skills/vercel-deploy-best-practices/references/backend-frontend-devops-exemplars.md +109 -0
  252. package/registry/translation-ledger.json +69 -0
@@ -0,0 +1,72 @@
1
+ rules:
2
+ - id: variant-taint-analysis
3
+ message: >-
4
+ Potential variant: user-controlled data flows to dangerous sink.
5
+ Original bug: [DESCRIBE_ORIGINAL_BUG]
6
+ severity: ERROR
7
+ languages: [python]
8
+ mode: taint
9
+
10
+ pattern-sources:
11
+ # Flask
12
+ - pattern: request.args.get(...)
13
+ - pattern: request.args[...]
14
+ - pattern: request.form.get(...)
15
+ - pattern: request.form[...]
16
+ - pattern: request.json
17
+ - pattern: request.data
18
+ # Django (uncomment if needed)
19
+ # - pattern: request.GET.get(...)
20
+ # - pattern: request.POST.get(...)
21
+ # General
22
+ - pattern: os.environ.get(...)
23
+ - pattern: input(...)
24
+
25
+ pattern-sinks:
26
+ # Command injection
27
+ - pattern: os.system($SINK)
28
+ - pattern: os.popen($SINK)
29
+ - pattern: subprocess.call($SINK, ...)
30
+ - pattern: subprocess.run($SINK, ...)
31
+ - pattern: subprocess.Popen($SINK, ...)
32
+ # Code execution
33
+ - pattern: eval($SINK)
34
+ - pattern: exec($SINK)
35
+ # SQL (uncomment if needed)
36
+ # - pattern: $CURSOR.execute($SINK)
37
+ # Path traversal (uncomment if needed)
38
+ # - pattern: open($SINK, ...)
39
+
40
+ pattern-sanitizers:
41
+ - pattern: shlex.quote(...)
42
+ - pattern: os.path.basename(...)
43
+ - pattern: int(...)
44
+ - pattern: sanitize(...)
45
+ - pattern: escape(...)
46
+ - pattern: validate(...)
47
+
48
+ paths:
49
+ exclude:
50
+ - "*_test.py"
51
+ - "test_*.py"
52
+ - "tests/"
53
+ - "**/test/**"
54
+
55
+ metadata:
56
+ category: security
57
+ confidence: HIGH
58
+
59
+ # Simple pattern matching variant (non-taint)
60
+ - id: variant-pattern-match
61
+ message: "Suspicious pattern matching known vulnerability signature"
62
+ severity: WARNING
63
+ languages: [python]
64
+ patterns:
65
+ - pattern-either:
66
+ - pattern: dangerous_func($USER_DATA)
67
+ - pattern: risky_operation(..., $USER_DATA, ...)
68
+ - pattern-not: dangerous_func("...")
69
+ paths:
70
+ exclude:
71
+ - "tests/"
72
+ - "*_test.py"
@@ -0,0 +1,41 @@
1
+ <!-- Adapted for agents-united from https://github.com/trailofbits/skills/blob/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/variant-analysis/skills/variant-analysis/references/reporting.md
2
+ Licence: see ../LICENSE; changes: see ../NOTICE.md. -->
3
+
4
+ # Reporting a Variant Hunt
5
+
6
+ Advice for the final stage. The report is written for a security engineer that is reviewing vulnerability variants.
7
+
8
+ ## Structure
9
+
10
+ Fill `../resources/variant-report-template.md` — the path is relative to this file, so
11
+ from the skill root it is `resources/variant-report-template.md`. Every section earns its
12
+ place:
13
+
14
+ - **Summary** — original bug, date, codebase, count
15
+ - **Original vulnerability** — the root cause statement, the origin location, the code
16
+ - **Search methodology** — the patterns tried, at which level, with match and FP counts
17
+ - **Findings** — one block per confirmed variant, severity-ordered
18
+ - **False positive patterns** — grouped by reason, not one row per match
19
+ - **Recommendations** — immediate fixes, then preventive measures
20
+
21
+ ## The Methodology Table
22
+
23
+ | Version | Pattern | Tool | Matches | TP | FP |
24
+ |---------|---------|------|---------|----|----|
25
+ | v1 | exact | ripgrep | 1 | 1 | 0 |
26
+ | v2 | abstract | semgrep | N | N | N |
27
+
28
+ This table makes the hunt reproducible. It records which abstractions worked, which
29
+ produced noise, and where the search stopped.
30
+
31
+ Record the patterns that failed alongside those that worked.
32
+
33
+ ## Quote the Real Code
34
+
35
+ Read each confirmed location and quote what is actually there. A report that paraphrases
36
+ code loses the detail a reviewer needs to confirm the finding, and a wrong quote destroys
37
+ trust in every other finding in the document.
38
+
39
+ ## Leave a Regression Guard
40
+
41
+ End with a CI-ready rule derived from whichever pattern found the most variants.
@@ -0,0 +1,101 @@
1
+ <!-- Adapted for agents-united from https://github.com/trailofbits/skills/blob/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/variant-analysis/skills/variant-analysis/references/root-cause.md
2
+ Licence: see ../LICENSE; changes: see ../NOTICE.md. -->
3
+
4
+ # Root Cause and Expansion Axes
5
+
6
+ Strategy for the first stage of a variant hunt: turning one known bug into the set of
7
+ independent directions worth searching. Everything downstream is calibrated against what
8
+ you produce here, so a shallow root cause caps the quality of the entire hunt.
9
+
10
+ ## Why Variants Exist
11
+
12
+ Vulnerabilities cluster because developers make consistent mistakes:
13
+
14
+ 1. **Developer habits**: the same person writes similar code and makes similar errors
15
+ 2. **Copy-paste propagation**: boilerplate spreads a bug across the codebase
16
+ 3. **API misuse patterns**: complex APIs invite consistent misunderstandings
17
+ 4. **Framework idioms**: framework patterns create predictable vulnerability shapes
18
+ 5. **Incomplete fixes**: the original bug was fixed in one place and missed elsewhere
19
+
20
+ Understanding WHY a variant exists predicts WHERE to find it. A copy-paste bug clusters in
21
+ sibling files; an API misuse bug clusters at every call site of that API, anywhere.
22
+
23
+ ## Extracting the Root Cause
24
+
25
+ Ask these four questions before writing anything:
26
+
27
+ 1. **What operation is dangerous?** (`eval()`, `system()`, raw SQL, an authorization check)
28
+ 2. **What data makes it dangerous?** (user-controlled input, a null, an attacker-chosen size)
29
+ 3. **What's missing?** (sanitization, validation, a bounds check, a null guard)
30
+ 4. **What context enables it?** (authentication state, an error path, a specific caller)
31
+
32
+ Then formulate a statement:
33
+
34
+ > "This vulnerability exists because [UNTRUSTED DATA] reaches [DANGEROUS OPERATION]
35
+ > without [REQUIRED PROTECTION]."
36
+
37
+ Examples:
38
+ - "User input reaches `eval()` without sanitization"
39
+ - "Attacker-controlled size reaches `malloc()` without an overflow check"
40
+ - "Untrusted path reaches `open()` without canonicalization"
41
+
42
+ For logic bugs that have no data flow, state the violated invariant instead: "this function
43
+ must return False for unauthenticated callers, and it returns True when both IDs are null."
44
+
45
+ That statement IS the search pattern. Everything below expands it.
46
+
47
+ ## The Expansion Checklist
48
+
49
+ A single root cause manifests in several ways. Enumerate all of them before searching.
50
+
51
+ ### 1. Semantically related identifiers
52
+
53
+ If the bug involves one name, every name that plays the same role is in scope:
54
+
55
+ - `isAuthenticated`: also `isActive`, `isAdmin`, `isVerified`, `isLoggedIn`
56
+ - `userId`: also `ownerId`, `creatorId`, `authorId`
57
+
58
+ Ground these in the codebase. Grep for the names before claiming them: a list of plausible
59
+ identifiers that don't exist wastes an entire search axis.
60
+
61
+ ### 2. Other boolean-logic errors
62
+
63
+ The same mistake in a different shape:
64
+
65
+ - Inverted conditions (`if not x` where `if x` was meant)
66
+ - Wrong default return (`return True` on the fall-through path)
67
+ - Short-circuit evaluation errors (`or` where `and` was meant)
68
+
69
+ ### 3. Data-type edge cases
70
+
71
+ - Null/None/undefined comparisons, especially where *both* sides can be null
72
+ - Empty string vs null
73
+ - Zero vs null
74
+ - Empty arrays and collections
75
+
76
+ ### 4. Documentation/code mismatches
77
+
78
+ A function whose behavior contradicts its own name or docstring. Search for functions named
79
+ with `deny`, `restrict`, `block`, `forbid`, `check`, `validate` and confirm the return value
80
+ means what the name says.
81
+
82
+ ## What Makes a Good Axis
83
+
84
+ Each axis is handed to a separate agent that knows nothing about the others. So an axis must be:
85
+
86
+ - **Independently searchable** — it names concrete identifiers or code constructs to look for,
87
+ not a theme like "authorization problems"
88
+ - **Non-overlapping** — two axes that find the same code waste an agent
89
+ - **Grounded** — its leads exist in this codebase
90
+
91
+ ## Pitfalls at This Stage
92
+
93
+ **Pattern too specific.** Using only the exact attribute from the original bug misses
94
+ variants built on related constructs. Enumerate the whole family, not the one instance.
95
+
96
+ **Single vulnerability class.** Focusing on one manifestation misses the others. A
97
+ "returns allow when the condition is false" bug also hides as a null-equality bypass, a
98
+ docs/code mismatch, and an inverted conditional. List every manifestation before searching.
99
+
100
+ **Ungrounded axes.** Plausible-sounding identifiers that don't appear in the codebase
101
+ produce an agent that searches hard and finds nothing.
@@ -0,0 +1,162 @@
1
+ <!-- Adapted for agents-united from https://github.com/trailofbits/skills/blob/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/variant-analysis/skills/variant-analysis/references/searching.md
2
+ Licence: see ../LICENSE; changes: see ../NOTICE.md. -->
3
+
4
+ # Searching: The Abstraction Ladder
5
+
6
+ Strategy for the sweep stage. You have a root cause and one axis to search. The job is to
7
+ climb from a pattern that matches only the known bug to one that matches its variants,
8
+ without climbing so far that the results become noise.
9
+
10
+ ## Tool Selection
11
+
12
+ | Scenario | Tool | Why |
13
+ |----------|------|-----|
14
+ | Quick surface search | ripgrep | Fast, zero setup |
15
+ | Simple pattern matching | Semgrep | Easy syntax, no build needed |
16
+ | Data flow tracking | Semgrep taint / CodeQL | Follows values across functions |
17
+ | Cross-function analysis | CodeQL | Best interprocedural analysis |
18
+ | Non-building code | Semgrep | Works on incomplete code |
19
+
20
+ Use ripgrep for recon, Semgrep for iteration, CodeQL for precision. Tool loyalty is an
21
+ anti-pattern: "I only use CodeQL" costs you the fast passes that tell you where to aim it.
22
+
23
+ ## The Ladder
24
+
25
+ ### Level 0: Exact match
26
+
27
+ Match the literal vulnerable code.
28
+
29
+ ```python
30
+ # Original vulnerable code
31
+ query = "SELECT * FROM users WHERE id=" + request.args.get('id')
32
+ ```
33
+
34
+ ```bash
35
+ rg 'SELECT \* FROM users WHERE id=" \+ request\.args\.get'
36
+ ```
37
+
38
+ Matches 1, zero false positives. This is not a search, it is the calibration point that proves your understanding of the bug is correct.
39
+
40
+ ### Level 1: Variable abstraction
41
+
42
+ Replace variable names with metavariables.
43
+
44
+ ```yaml
45
+ pattern: $QUERY = "SELECT * FROM users WHERE id=" + $INPUT
46
+ ```
47
+
48
+ Matches 3-5, low FP. Finds copy-paste variants.
49
+
50
+ ### Level 2: Structural abstraction
51
+
52
+ Generalize the surrounding structure.
53
+
54
+ ```yaml
55
+ patterns:
56
+ - pattern: $Q = "..." + $INPUT
57
+ - pattern-inside: |
58
+ def $FUNC(...):
59
+ ...
60
+ cursor.execute($Q)
61
+ ```
62
+
63
+ Matches 10-30, medium FP. Finds pattern variants.
64
+
65
+ ### Level 3: Semantic abstraction
66
+
67
+ Abstract to the security property itself.
68
+
69
+ ```yaml
70
+ mode: taint
71
+ pattern-sources:
72
+ - pattern: request.args.get(...)
73
+ - pattern: request.form.get(...)
74
+ pattern-sinks:
75
+ - pattern: cursor.execute(...)
76
+ ```
77
+
78
+ Matches 50-100+, high FP. Comprehensive coverage, requires real triage.
79
+
80
+ ### Choosing your level
81
+
82
+ | Goal | Level |
83
+ |------|-------|
84
+ | Verify a specific fix | 0 |
85
+ | Find copy-paste bugs | 1 |
86
+ | Audit a component | 2 |
87
+ | Full security assessment | 3 |
88
+
89
+ ## One Change at a Time
90
+
91
+ Never generalize multiple elements at once.
92
+
93
+ ```
94
+ BAD: exact code -> fully abstract pattern
95
+ GOOD: exact code -> abstract var1 -> abstract var2 -> abstract operation
96
+ ```
97
+
98
+ Each step: make ONE change, run it, read ALL new matches, decide whether the FP rate is
99
+ still acceptable, then continue or revert. Jumping straight to Level 3 produces a pile of
100
+ results with no way to tell which abstraction introduced the noise.
101
+
102
+ ### Decision points
103
+
104
+ **Abstract this variable name?** Yes if different names could carry the same bug. No if the
105
+ name itself is the semantic constraint you are relying on.
106
+
107
+ **Abstract this literal?** Yes if any value triggers the bug. No if only specific values are
108
+ dangerous.
109
+
110
+ **Use `...` wildcards?** Yes if argument position doesn't matter. No if only a specific
111
+ position is a sink.
112
+
113
+ **Add taint tracking?** Yes if you need to prove data actually flows from source to sink. No
114
+ if the presence of the pattern is already sufficient evidence.
115
+
116
+ ## Search Scope
117
+
118
+ Run every search against the **entire codebase root**, not the directory the original bug
119
+ lived in. A bug found in `api/handlers/` with a variant in `utils/auth.py` is the normal
120
+ case, not the exotic one. Narrow scope is the single most common reason a hunt finds nothing.
121
+
122
+ ## False Positive Management
123
+
124
+ ### Acceptable rates by context
125
+
126
+ | Context | Acceptable FP rate |
127
+ |---------|-------------------|
128
+ | Automated CI blocking | <5% |
129
+ | Developer warning | <20% |
130
+ | Security audit triage | <50% |
131
+ | Research/exploration | <80% |
132
+
133
+ For a variant hunt, stop generalizing when more than roughly half the matches are noise.
134
+ That is the signal you climbed one level too far: revert and take a different abstraction
135
+ rather than pushing further up the same one.
136
+
137
+ ### Common FP sources and filters
138
+
139
+ **Test code** — exclude test trees:
140
+ ```bash
141
+ rg "pattern" --glob '!**/test*' --glob '!**/*_test.*'
142
+ ```
143
+
144
+ **Already sanitized** — subtract the safe form:
145
+ ```yaml
146
+ pattern-not: dangerous_func(sanitize($X))
147
+ ```
148
+
149
+ **Literal values** — not attacker-controlled:
150
+ ```yaml
151
+ pattern-not: dangerous_func("...")
152
+ ```
153
+
154
+ **Dead code** — add reachability constraints:
155
+ ```yaml
156
+ pattern-not-inside: |
157
+ if False:
158
+ ...
159
+ ```
160
+
161
+ Analyze false positives as you go rather than deferring them. They tell you which
162
+ abstraction was too aggressive, which is information you lose if you triage in a batch at the end.
@@ -0,0 +1,95 @@
1
+ <!-- Adapted for agents-united from https://github.com/trailofbits/skills/blob/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/variant-analysis/skills/variant-analysis/references/triage.md
2
+ Licence: see ../LICENSE; changes: see ../NOTICE.md. -->
3
+
4
+ # Triage: Deciding Whether a Candidate Is Real
5
+
6
+ Strategy for the verification stage. You have candidate locations that resemble a known
7
+ bug. The job is to determine which ones actually carry it, and to say so with a severity
8
+ attached.
9
+
10
+ ## Argue Against the Candidate
11
+
12
+ The snippet alone is never enough. Read the surrounding function, the callers, and the type
13
+ of every value involved, then look specifically for the thing that makes it safe:
14
+
15
+ - A guard earlier in the function or in a decorator/middleware
16
+ - A sanitizer, validator, or parameterized API between source and sink
17
+ - A type constraint that makes the dangerous value unreachable
18
+ - A caller set that never supplies attacker-controlled input
19
+
20
+ A candidate survives only if you looked for these and did not find them.
21
+
22
+ Note what is *not* on that list: having no callers. Code that nothing reaches today is
23
+ still unprotected code, and a variant hunt is exactly the search that finds it before a
24
+ caller arrives. Report it at lower severity — see Exploitability below — rather than
25
+ refuting it as dead.
26
+
27
+ ## Exploitability
28
+
29
+ For a surviving candidate, establish:
30
+
31
+ - **Reachable** — is there a path from an external entry point to this code?
32
+ - **Controllable** — can an attacker influence the value that makes it dangerous?
33
+ - **Unprotected** — is the protection named in the root cause genuinely absent here?
34
+
35
+ A candidate that is reachable and controllable but has a different protection in place is a
36
+ false positive worth recording, not a finding. A candidate that is unreachable *today* but
37
+ unprotected is a real finding at lower severity: say so explicitly, and say what would make
38
+ it reachable.
39
+
40
+ ## Edge Cases That Hide Real Bugs
41
+
42
+ Test every candidate against these if applicable, because normal-path reasoning misses them.
43
+
44
+ ### Null equality bypasses
45
+
46
+ A common authorization bypass. If both sides of a comparison can be null at the same time,
47
+ the comparison succeeds for the wrong reason:
48
+
49
+ ```python
50
+ # anonymous_user.id is None, guest_order.owner_id is None
51
+ # None == None is True, so the check passes for a user who owns nothing
52
+ if order.owner_id == current_user.id:
53
+ return True
54
+ ```
55
+
56
+ Ask: what values can each side hold? Can both be null simultaneously? Who can cause that?
57
+
58
+ ### Documentation/code mismatch
59
+
60
+ The function does the opposite of what its name or docstring claims:
61
+
62
+ ```python
63
+ def check_restricted_permission(user, perm):
64
+ """Returns True if access should be DENIED."""
65
+ if user.has_perm(perm):
66
+ return True # BUG: returns "deny" for users who DO have permission
67
+ return False
68
+ ```
69
+
70
+ Every caller of a function like this is a potential finding, even where the call site looks
71
+ correct. Verify the return semantics against the name before trusting any use of it.
72
+
73
+ ### Others worth testing
74
+
75
+ - Unauthenticated and anonymous callers
76
+ - Empty strings vs null, zero vs null
77
+ - Empty arrays and collections
78
+ - Boundary values at the limits of the type
79
+
80
+ ## Severity and Confidence
81
+
82
+ Attach a severity to **every** verdict, including informational ones. Do not suppress
83
+ findings you judge minor: filtering happens downstream, where the full set is visible, and a
84
+ finding you decline to mention is a finding nobody sees.
85
+
86
+ Separate the two axes:
87
+
88
+ - **Severity** — the impact if this is real
89
+ - **Confidence** — how sure you are that it is real
90
+
91
+ ## Recording False Positives
92
+
93
+ When a candidate is ruled out, record *why* it was safe. Grouped by reason, these become the
94
+ false-positive table in the report, and they are what lets the next stage refine the
95
+ pattern instead of re-triaging the same matches.
@@ -0,0 +1,74 @@
1
+ <!-- Adapted for agents-united from https://github.com/trailofbits/skills/blob/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/variant-analysis/skills/variant-analysis/SKILL.md
2
+ Licence: see ../LICENSE; changes: see ../NOTICE.md. -->
3
+
4
+ # Variant Analysis
5
+
6
+ Find the other instances of a bug you have already found. One root cause usually has several
7
+ manifestations, and they are rarely in the module where you found the first one.
8
+
9
+ ## When to Use
10
+
11
+ - A vulnerability has been found and you need to search for similar instances
12
+ - Building or refining CodeQL/Semgrep queries for security patterns
13
+ - Performing systematic code audits after an initial issue discovery
14
+ - Analyzing how a single root cause manifests in different code paths
15
+
16
+ ## When NOT to Use
17
+
18
+ - Initial vulnerability discovery — use audit-context-building or a domain-specific audit
19
+ - General code review with no known pattern to search for
20
+ - Writing fix recommendations — use issue-writer
21
+ - Understanding unfamiliar code — use audit-context-building first
22
+
23
+ ## The Five Steps
24
+
25
+ Read the reference for a step when you reach it.
26
+
27
+ **1. Understand the original issue.** Extract the root cause — why the code is wrong, not
28
+ what it does — and enumerate the directions a variant could hide in: related identifiers,
29
+ other manifestations of the same mistake, data-type edge cases.
30
+ → [references/root-cause.md](root-cause.md)
31
+
32
+ **2. Create an exact match.** Write a pattern matching ONLY the known instance and confirm
33
+ it hits. A pattern that matches nothing means you have misunderstood the bug, and every
34
+ search built on it is calibrated against the wrong code.
35
+
36
+ **3–4. Generalize one element at a time.** Climb from the exact match toward the pattern
37
+ family, running and reading all matches after each single change. Stop when more than half
38
+ the matches are noise.
39
+ → [references/searching.md](searching.md) — abstraction ladder, tool selection,
40
+ false-positive filters
41
+
42
+ **5. Triage.** Decide which candidates are real, and say so with a severity attached.
43
+ → [references/triage.md](triage.md)
44
+
45
+ **Then write it up**, including the patterns that failed and a CI rule to prevent regression.
46
+ → [references/reporting.md](reporting.md)
47
+
48
+ ## Running it as a Workflow
49
+
50
+ This plugin ships `/variant-analysis:variants`, which runs the five steps across parallel
51
+ subagents — one per expansion axis, looping until the sweep stops finding anything new.
52
+ Each stage reads the reference above that matches its job.
53
+
54
+ Use the workflow when the codebase is large or the root cause has many manifestations. Work
55
+ the steps directly when the search is narrow or you want a say in each generalization.
56
+
57
+ ## What Makes Hunts Fail
58
+
59
+ 1. **Narrow scope** — searching only the module the original bug was in
60
+ 2. **Pattern too specific** — searching one attribute and missing the family around it
61
+ 3. **One vulnerability class** — chasing a single manifestation of the root cause
62
+ 4. **Happy-path testing** — never trying the null, empty, and boundary cases
63
+ 5. **Generalizing too fast** — abstracting several elements at once, so noise cannot be
64
+ attributed to any one of them
65
+
66
+ The first three are covered in root-cause.md and searching.md, the fourth in triage.md.
67
+
68
+ ## Resources
69
+
70
+ **CodeQL** (`assets/codeql/`): `python.ql`, `javascript.ql`, `java.ql`, `go.ql`, `cpp.ql`
71
+
72
+ **Semgrep** (`assets/semgrep/`): `python.yaml`, `javascript.yaml`, `java.yaml`, `go.yaml`, `cpp.yaml`
73
+
74
+ **Report**: `resources/variant-report-template.md`
@@ -0,0 +1,78 @@
1
+ <!-- Adapted for agents-united from https://github.com/trailofbits/skills/blob/0cc1c73a5e96749ab32d7ea5e14892fafa6972ae/plugins/variant-analysis/skills/variant-analysis/resources/variant-report-template.md
2
+ Licence: see ../LICENSE; changes: see ../NOTICE.md. -->
3
+
4
+ # Variant Analysis Report
5
+
6
+ ## Summary
7
+
8
+ | Field | Value |
9
+ |-------|-------|
10
+ | **Original Bug** | [BUG_ID / CVE] |
11
+ | **Analysis Date** | [DATE] |
12
+ | **Codebase** | [REPO/PROJECT] |
13
+ | **Variants Found** | [COUNT] |
14
+
15
+ ## Original Vulnerability
16
+
17
+ **Root Cause:** [e.g., "User input reaches SQL query without parameterization"]
18
+
19
+ **Location:** `[path/to/file.py:LINE]` in `function_name()`
20
+
21
+ ```python
22
+ # Vulnerable code
23
+ ```
24
+
25
+ ## Search Methodology
26
+
27
+ | Version | Pattern | Tool | Matches | TP | FP |
28
+ |---------|---------|------|---------|----|----|
29
+ | v1 | [exact] | ripgrep | 1 | 1 | 0 |
30
+ | v2 | [abstract] | semgrep | N | N | N |
31
+
32
+ **Final Pattern:**
33
+ ```yaml
34
+ # Pattern used
35
+ ```
36
+
37
+ ## Findings
38
+
39
+ ### Variant #1: [BRIEF_TITLE]
40
+
41
+ | Severity | Confidence | Status |
42
+ |----------|------------|--------|
43
+ | High | High | Confirmed |
44
+
45
+ **Location:** `[path/to/file.py:LINE]`
46
+
47
+ ```python
48
+ # Vulnerable code
49
+ ```
50
+
51
+ **Analysis:** [Why this is a true/false positive]
52
+
53
+ **Exploitability:**
54
+ - [ ] Reachable from external input
55
+ - [ ] User-controlled data
56
+ - [ ] No sanitization
57
+
58
+ ---
59
+
60
+ <!-- Copy variant template above for additional findings -->
61
+
62
+ ## False Positive Patterns
63
+
64
+ | Pattern | Count | Reason |
65
+ |---------|-------|--------|
66
+ | [pattern] | N | [why safe] |
67
+
68
+ ## Recommendations
69
+
70
+ ### Immediate
71
+ 1. Fix variant in [location]
72
+
73
+ ### Preventive
74
+ 1. Add Semgrep rule to CI
75
+
76
+ ```yaml
77
+ # CI-ready rule
78
+ ```
@@ -16,6 +16,20 @@ disable-slash-command: true
16
16
  ## Overview & Purpose
17
17
  `vercel-deploy-best-practices` provides production deployment and configuration guidelines for Next.js, Remix, and static web applications hosted on Vercel.
18
18
 
19
+ ## Execution Triggers
20
+ - A specialist's Skill Consultation Map names this skill for a task touching Vercel Edge Functions/Middleware, preview deployments, ISR caching, or `vercel.json` configuration.
21
+ - A project's `bundles.json` addon (`frontend-engineering` or `devops-engineering`) is installed and a Vercel CLI command, GitHub Actions preview workflow, or Edge runtime route needs authoring.
22
+
23
+ ## Input/Output Requirements
24
+ - **Input**: the target runtime (Edge vs. Node serverless), the environment tier (Development/Preview/Production), and any existing `vercel.json` / GitHub Actions workflow.
25
+ - **Output**: a deploy command sequence or GitHub Actions workflow, an Edge Function/Middleware file, and/or `vercel.json` concurrency settings — plus which step (build, preview deploy, production deploy) actually ran.
26
+
27
+ ## Step-by-Step Runbook
28
+ 1. Confirm the runtime target (`edge` vs. default Node) before writing the route — Edge has no Node APIs.
29
+ 2. Build with `vercel build`, then deploy the prebuilt output (`vercel deploy --prebuilt`) to preview first, always.
30
+ 3. Wire environment variables per tier (`vercel env pull`) rather than hardcoding per-environment values.
31
+ 4. **Never run the `--prod` promotion yourself** — stop at a verified preview deploy and hand the production command to the orchestrator for explicit user approval (`references/backend-frontend-devops-exemplars.md`).
32
+
19
33
  ## Core Directives & Standards
20
34
  1. **Edge Middleware Routing** — Keep Edge Middleware execution < 25ms by avoiding heavy libraries or un-cached external network calls.
21
35
  2. **Incremental Static Regeneration (ISR)** — Configure `revalidate` intervals or on-demand revalidation (`revalidatePath`, `revalidateTag`) for dynamic content caching.
@@ -23,6 +37,16 @@ disable-slash-command: true
23
37
  4. **Vercel Web Analytics & Speed Insights** — Integrate `@vercel/analytics` and `@vercel/speed-insights` for real-user Core Web Vitals monitoring.
24
38
  5. **Serverless Function Concurrency** — Configure max duration limits and memory allocations in `vercel.json` to prevent billing surprises.
25
39
 
40
+ ## Code & Config Exemplars
41
+ - `references/backend-frontend-devops-exemplars.md` — Edge streaming API route (backend),
42
+ prebuilt deploy commands (frontend), and a full Vercel preview GitHub Actions workflow
43
+ (devops). Extracted per Plan 025 Objective 4.
44
+
45
+ ## Edge Cases & Error Recovery
46
+ - **Edge Function needs a Node-only API**: switch the route to the default Node runtime rather than polyfilling; Edge intentionally excludes the Node standard library.
47
+ - **Preview deploy succeeds but production promotion is requested**: refuse to run `--prod` directly; hand the exact command to the orchestrator and report that human approval is required.
48
+ - **Stale preview after an env var change**: preview deployments do not pick up new env vars automatically — trigger a fresh `vercel deploy --prebuilt` after updating them.
49
+
26
50
  ## Verification Checklist
27
51
  - [ ] Preview deployments generate isolated database branch previews when paired with Neon/Supabase.
28
52
  - [ ] Zero unhandled Server Action errors in production logs.