incitaciones 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (318) hide show
  1. package/LICENSE +395 -0
  2. package/README.md +410 -0
  3. package/content/distilled/abstraction-miner.md +32 -0
  4. package/content/distilled/adversarial-stakeholder-evaluation.md +121 -0
  5. package/content/distilled/anti-slop-prose.md +46 -0
  6. package/content/distilled/bias-audit.md +39 -0
  7. package/content/distilled/code-review/SKILL.md +53 -0
  8. package/content/distilled/code-review/references/criteria.md +50 -0
  9. package/content/distilled/code-review/references/templates.md +75 -0
  10. package/content/distilled/code-review/references/variants.md +32 -0
  11. package/content/distilled/commit/SKILL.md +41 -0
  12. package/content/distilled/commit/references/criteria.md +21 -0
  13. package/content/distilled/commit/references/templates.md +46 -0
  14. package/content/distilled/composability-diagnostician.md +67 -0
  15. package/content/distilled/context-guardian.md +20 -0
  16. package/content/distilled/create-handoff/SKILL.md +16 -0
  17. package/content/distilled/create-handoff/references/handoff-template.md +65 -0
  18. package/content/distilled/create-handoff/references/naming.md +7 -0
  19. package/content/distilled/create-issues/SKILL.md +72 -0
  20. package/content/distilled/create-issues/references/criteria.md +44 -0
  21. package/content/distilled/create-issues/references/templates.md +75 -0
  22. package/content/distilled/create-plan/SKILL.md +19 -0
  23. package/content/distilled/create-plan/references/plan-template.md +87 -0
  24. package/content/distilled/create-plan/references/scenarios.md +19 -0
  25. package/content/distilled/debug/SKILL.md +42 -0
  26. package/content/distilled/debug/references/criteria.md +27 -0
  27. package/content/distilled/debug/references/templates.md +39 -0
  28. package/content/distilled/describe-pr/SKILL.md +17 -0
  29. package/content/distilled/describe-pr/references/pr-template.md +62 -0
  30. package/content/distilled/design-practice.md +213 -0
  31. package/content/distilled/design-review/SKILL.md +29 -0
  32. package/content/distilled/design-review/references/combined-review.md +27 -0
  33. package/content/distilled/design-review/references/decision-matrix.md +122 -0
  34. package/content/distilled/design-review/references/problem-statement.md +141 -0
  35. package/content/distilled/design-review/references/report-template.md +36 -0
  36. package/content/distilled/design-review/references/scope-document.md +51 -0
  37. package/content/distilled/distill-prompt/SKILL.md +41 -0
  38. package/content/distilled/distill-prompt/references/criteria.md +26 -0
  39. package/content/distilled/distill-prompt/references/templates.md +30 -0
  40. package/content/distilled/doc-link-verifier/SKILL.md +212 -0
  41. package/content/distilled/doc-link-verifier/scripts/check_links.py +453 -0
  42. package/content/distilled/doc-link-verifier/scripts/extract_links.py +521 -0
  43. package/content/distilled/edge-case-discovery.md +123 -0
  44. package/content/distilled/error-handling-diagnostician.md +90 -0
  45. package/content/distilled/extract-prompt.md +220 -0
  46. package/content/distilled/formal-verification-evaluator.md +158 -0
  47. package/content/distilled/grill-me.md +24 -0
  48. package/content/distilled/guided-review.md +68 -0
  49. package/content/distilled/implement-documentation.md +68 -0
  50. package/content/distilled/implement-plan/SKILL.md +23 -0
  51. package/content/distilled/implement-plan/references/common-situations.md +36 -0
  52. package/content/distilled/implement-plan/references/verification-template.md +18 -0
  53. package/content/distilled/invalid-states-diagnostician.md +63 -0
  54. package/content/distilled/issue-review/SKILL.md +37 -0
  55. package/content/distilled/issue-review/references/convergence.md +19 -0
  56. package/content/distilled/issue-review/references/final-report.md +60 -0
  57. package/content/distilled/issue-review/references/pass-1-clarity.md +28 -0
  58. package/content/distilled/issue-review/references/pass-2-scope.md +22 -0
  59. package/content/distilled/issue-review/references/pass-3-dependencies.md +23 -0
  60. package/content/distilled/issue-review/references/pass-4-alignment.md +17 -0
  61. package/content/distilled/issue-review/references/pass-5-executability.md +17 -0
  62. package/content/distilled/issue-review/references/setup.md +25 -0
  63. package/content/distilled/iterate-plan/SKILL.md +24 -0
  64. package/content/distilled/iterate-plan/references/change-template.md +15 -0
  65. package/content/distilled/iterate-plan/references/common-scenarios.md +14 -0
  66. package/content/distilled/julia-performance-diagnostician.md +71 -0
  67. package/content/distilled/modularity-diagnostician.md +68 -0
  68. package/content/distilled/multi-agent-review.md +196 -0
  69. package/content/distilled/mutability-diagnostician.md +63 -0
  70. package/content/distilled/narrative-article.md +60 -0
  71. package/content/distilled/optionality-review.md +190 -0
  72. package/content/distilled/parallel-review/SKILL.md +49 -0
  73. package/content/distilled/parallel-review/references/criteria.md +34 -0
  74. package/content/distilled/parallel-review/references/templates.md +59 -0
  75. package/content/distilled/plan-review/SKILL.md +42 -0
  76. package/content/distilled/plan-review/references/criteria.md +51 -0
  77. package/content/distilled/plan-review/references/templates.md +67 -0
  78. package/content/distilled/pre-mortem.md +10 -0
  79. package/content/distilled/project-status-report.md +124 -0
  80. package/content/distilled/pwa-accessibility-review.md +81 -0
  81. package/content/distilled/rca-diagnostician/SKILL.md +30 -0
  82. package/content/distilled/rca-diagnostician/references/action-hierarchy.md +77 -0
  83. package/content/distilled/rca-diagnostician/references/bias-countermeasures.md +64 -0
  84. package/content/distilled/rca-diagnostician/references/evidence-timeline.md +49 -0
  85. package/content/distilled/rca-diagnostician/references/hypothesis-methods.md +53 -0
  86. package/content/distilled/rca-diagnostician/references/problem-definition.md +34 -0
  87. package/content/distilled/rca-diagnostician/references/report-template.md +75 -0
  88. package/content/distilled/rca-diagnostician/references/rigor-checklist.md +66 -0
  89. package/content/distilled/red-team-review.md +133 -0
  90. package/content/distilled/research-codebase/SKILL.md +22 -0
  91. package/content/distilled/research-codebase/references/report-template.md +75 -0
  92. package/content/distilled/research-codebase/references/search-patterns.md +27 -0
  93. package/content/distilled/research-documentation.md +79 -0
  94. package/content/distilled/research-review/SKILL.md +42 -0
  95. package/content/distilled/research-review/references/criteria.md +51 -0
  96. package/content/distilled/research-review/references/templates.md +73 -0
  97. package/content/distilled/resonant-refactor.md +45 -0
  98. package/content/distilled/resume-handoff/SKILL.md +19 -0
  99. package/content/distilled/resume-handoff/references/analysis-template.md +40 -0
  100. package/content/distilled/resume-handoff/references/locating.md +12 -0
  101. package/content/distilled/review-documentation.md +44 -0
  102. package/content/distilled/rigidity-diagnostician.md +70 -0
  103. package/content/distilled/rule-of-5-universal/SKILL.md +26 -0
  104. package/content/distilled/rule-of-5-universal/references/criteria.md +34 -0
  105. package/content/distilled/rule-of-5-universal/references/examples.md +69 -0
  106. package/content/distilled/rule-of-5-universal/references/templates.md +136 -0
  107. package/content/distilled/specification-evaluation-diagnostician.md +106 -0
  108. package/content/distilled/specification-review/SKILL.md +43 -0
  109. package/content/distilled/specification-review/references/criteria.md +51 -0
  110. package/content/distilled/specification-review/references/templates.md +67 -0
  111. package/content/distilled/systematic-housekeeping.md +27 -0
  112. package/content/distilled/tdd/SKILL.md +38 -0
  113. package/content/distilled/tdd/references/criteria.md +26 -0
  114. package/content/distilled/tdd/references/templates.md +53 -0
  115. package/content/distilled/test-abstraction-miner.md +43 -0
  116. package/content/distilled/test-friction.md +51 -0
  117. package/content/distilled/testability-implementability-evaluator.md +144 -0
  118. package/content/distilled/ui-align.md +32 -0
  119. package/content/distilled/ux-dx-evaluation-diagnostician/SKILL.md +21 -0
  120. package/content/distilled/ux-dx-evaluation-diagnostician/references/layer-1-product.md +20 -0
  121. package/content/distilled/ux-dx-evaluation-diagnostician/references/layer-2-engineering.md +20 -0
  122. package/content/distilled/ux-dx-evaluation-diagnostician/references/layer-3-interface.md +23 -0
  123. package/content/distilled/ux-dx-evaluation-diagnostician/references/layer-4-ecosystem.md +20 -0
  124. package/content/distilled/ux-dx-evaluation-diagnostician/references/layer-5-documentation.md +19 -0
  125. package/content/distilled/ux-dx-evaluation-diagnostician/references/report-template.md +36 -0
  126. package/content/distilled/verification-diagnostician.md +90 -0
  127. package/content/distilled/verify-prompt/SKILL.md +32 -0
  128. package/content/distilled/verify-prompt/references/criteria.md +21 -0
  129. package/content/manifest.json +3220 -0
  130. package/package.json +50 -0
  131. package/pi-package/README.md +9 -0
  132. package/pi-package/prompts/abstraction-miner.md +10 -0
  133. package/pi-package/prompts/adversarial-stakeholder-evaluation.md +10 -0
  134. package/pi-package/prompts/anti-slop-prose.md +10 -0
  135. package/pi-package/prompts/bias-audit.md +10 -0
  136. package/pi-package/prompts/code-review.md +10 -0
  137. package/pi-package/prompts/commit.md +10 -0
  138. package/pi-package/prompts/composability-diagnostician.md +10 -0
  139. package/pi-package/prompts/context-guardian.md +10 -0
  140. package/pi-package/prompts/create-handoff.md +10 -0
  141. package/pi-package/prompts/create-issues.md +10 -0
  142. package/pi-package/prompts/create-plan.md +10 -0
  143. package/pi-package/prompts/debug.md +10 -0
  144. package/pi-package/prompts/describe-pr.md +10 -0
  145. package/pi-package/prompts/design-practice.md +10 -0
  146. package/pi-package/prompts/design-review.md +10 -0
  147. package/pi-package/prompts/distill-prompt.md +10 -0
  148. package/pi-package/prompts/doc-link-verifier.md +10 -0
  149. package/pi-package/prompts/edge-case-discovery.md +10 -0
  150. package/pi-package/prompts/error-handling-diagnostician.md +10 -0
  151. package/pi-package/prompts/extract-prompt.md +10 -0
  152. package/pi-package/prompts/formal-verification-evaluator.md +10 -0
  153. package/pi-package/prompts/grill-me.md +10 -0
  154. package/pi-package/prompts/guided-review.md +10 -0
  155. package/pi-package/prompts/implement-documentation.md +10 -0
  156. package/pi-package/prompts/implement-plan.md +10 -0
  157. package/pi-package/prompts/invalid-states-diagnostician.md +10 -0
  158. package/pi-package/prompts/issue-review.md +10 -0
  159. package/pi-package/prompts/iterate-plan.md +10 -0
  160. package/pi-package/prompts/julia-performance-diagnostician.md +10 -0
  161. package/pi-package/prompts/modularity-diagnostician.md +10 -0
  162. package/pi-package/prompts/multi-agent-review.md +10 -0
  163. package/pi-package/prompts/mutability-diagnostician.md +10 -0
  164. package/pi-package/prompts/narrative-article.md +10 -0
  165. package/pi-package/prompts/optionality-review.md +10 -0
  166. package/pi-package/prompts/parallel-review.md +10 -0
  167. package/pi-package/prompts/plan-review.md +10 -0
  168. package/pi-package/prompts/pre-mortem.md +10 -0
  169. package/pi-package/prompts/project-status-report.md +10 -0
  170. package/pi-package/prompts/pwa-accessibility-review.md +10 -0
  171. package/pi-package/prompts/rca-diagnostician.md +10 -0
  172. package/pi-package/prompts/red-team-review.md +10 -0
  173. package/pi-package/prompts/research-codebase.md +10 -0
  174. package/pi-package/prompts/research-documentation.md +10 -0
  175. package/pi-package/prompts/research-review.md +10 -0
  176. package/pi-package/prompts/resonant-refactor.md +10 -0
  177. package/pi-package/prompts/resume-handoff.md +10 -0
  178. package/pi-package/prompts/review-documentation.md +10 -0
  179. package/pi-package/prompts/rigidity-diagnostician.md +10 -0
  180. package/pi-package/prompts/rule-of-5-universal.md +10 -0
  181. package/pi-package/prompts/specification-evaluation-diagnostician.md +10 -0
  182. package/pi-package/prompts/specification-review.md +10 -0
  183. package/pi-package/prompts/systematic-housekeeping.md +10 -0
  184. package/pi-package/prompts/tdd.md +10 -0
  185. package/pi-package/prompts/test-abstraction-miner.md +10 -0
  186. package/pi-package/prompts/test-friction.md +10 -0
  187. package/pi-package/prompts/testability-implementability-evaluator.md +10 -0
  188. package/pi-package/prompts/ui-align.md +10 -0
  189. package/pi-package/prompts/ux-dx-evaluation-diagnostician.md +10 -0
  190. package/pi-package/prompts/verification-diagnostician.md +10 -0
  191. package/pi-package/prompts/verify-prompt.md +10 -0
  192. package/pi-package/skills/abstraction-miner/SKILL.md +38 -0
  193. package/pi-package/skills/adversarial-stakeholder-evaluation/SKILL.md +127 -0
  194. package/pi-package/skills/anti-slop-prose/SKILL.md +52 -0
  195. package/pi-package/skills/bias-audit/SKILL.md +45 -0
  196. package/pi-package/skills/code-review/SKILL.md +59 -0
  197. package/pi-package/skills/code-review/references/criteria.md +50 -0
  198. package/pi-package/skills/code-review/references/templates.md +75 -0
  199. package/pi-package/skills/code-review/references/variants.md +32 -0
  200. package/pi-package/skills/commit/SKILL.md +47 -0
  201. package/pi-package/skills/commit/references/criteria.md +21 -0
  202. package/pi-package/skills/commit/references/templates.md +46 -0
  203. package/pi-package/skills/composability-diagnostician/SKILL.md +73 -0
  204. package/pi-package/skills/context-guardian/SKILL.md +26 -0
  205. package/pi-package/skills/create-handoff/SKILL.md +22 -0
  206. package/pi-package/skills/create-handoff/references/handoff-template.md +65 -0
  207. package/pi-package/skills/create-handoff/references/naming.md +7 -0
  208. package/pi-package/skills/create-issues/SKILL.md +78 -0
  209. package/pi-package/skills/create-issues/references/criteria.md +44 -0
  210. package/pi-package/skills/create-issues/references/templates.md +75 -0
  211. package/pi-package/skills/create-plan/SKILL.md +25 -0
  212. package/pi-package/skills/create-plan/references/plan-template.md +87 -0
  213. package/pi-package/skills/create-plan/references/scenarios.md +19 -0
  214. package/pi-package/skills/debug/SKILL.md +48 -0
  215. package/pi-package/skills/debug/references/criteria.md +27 -0
  216. package/pi-package/skills/debug/references/templates.md +39 -0
  217. package/pi-package/skills/describe-pr/SKILL.md +23 -0
  218. package/pi-package/skills/describe-pr/references/pr-template.md +62 -0
  219. package/pi-package/skills/design-practice/SKILL.md +219 -0
  220. package/pi-package/skills/design-review/SKILL.md +35 -0
  221. package/pi-package/skills/design-review/references/combined-review.md +27 -0
  222. package/pi-package/skills/design-review/references/decision-matrix.md +122 -0
  223. package/pi-package/skills/design-review/references/problem-statement.md +141 -0
  224. package/pi-package/skills/design-review/references/report-template.md +36 -0
  225. package/pi-package/skills/design-review/references/scope-document.md +51 -0
  226. package/pi-package/skills/distill-prompt/SKILL.md +47 -0
  227. package/pi-package/skills/distill-prompt/references/criteria.md +26 -0
  228. package/pi-package/skills/distill-prompt/references/templates.md +30 -0
  229. package/pi-package/skills/doc-link-verifier/SKILL.md +218 -0
  230. package/pi-package/skills/doc-link-verifier/scripts/check_links.py +453 -0
  231. package/pi-package/skills/doc-link-verifier/scripts/extract_links.py +521 -0
  232. package/pi-package/skills/edge-case-discovery/SKILL.md +129 -0
  233. package/pi-package/skills/error-handling-diagnostician/SKILL.md +96 -0
  234. package/pi-package/skills/extract-prompt/SKILL.md +226 -0
  235. package/pi-package/skills/formal-verification-evaluator/SKILL.md +164 -0
  236. package/pi-package/skills/grill-me/SKILL.md +30 -0
  237. package/pi-package/skills/guided-review/SKILL.md +74 -0
  238. package/pi-package/skills/implement-documentation/SKILL.md +74 -0
  239. package/pi-package/skills/implement-plan/SKILL.md +29 -0
  240. package/pi-package/skills/implement-plan/references/common-situations.md +36 -0
  241. package/pi-package/skills/implement-plan/references/verification-template.md +18 -0
  242. package/pi-package/skills/invalid-states-diagnostician/SKILL.md +69 -0
  243. package/pi-package/skills/issue-review/SKILL.md +43 -0
  244. package/pi-package/skills/issue-review/references/convergence.md +19 -0
  245. package/pi-package/skills/issue-review/references/final-report.md +60 -0
  246. package/pi-package/skills/issue-review/references/pass-1-clarity.md +28 -0
  247. package/pi-package/skills/issue-review/references/pass-2-scope.md +22 -0
  248. package/pi-package/skills/issue-review/references/pass-3-dependencies.md +23 -0
  249. package/pi-package/skills/issue-review/references/pass-4-alignment.md +17 -0
  250. package/pi-package/skills/issue-review/references/pass-5-executability.md +17 -0
  251. package/pi-package/skills/issue-review/references/setup.md +25 -0
  252. package/pi-package/skills/iterate-plan/SKILL.md +30 -0
  253. package/pi-package/skills/iterate-plan/references/change-template.md +15 -0
  254. package/pi-package/skills/iterate-plan/references/common-scenarios.md +14 -0
  255. package/pi-package/skills/julia-performance-diagnostician/SKILL.md +77 -0
  256. package/pi-package/skills/modularity-diagnostician/SKILL.md +74 -0
  257. package/pi-package/skills/multi-agent-review/SKILL.md +202 -0
  258. package/pi-package/skills/mutability-diagnostician/SKILL.md +69 -0
  259. package/pi-package/skills/narrative-article/SKILL.md +66 -0
  260. package/pi-package/skills/optionality-review/SKILL.md +196 -0
  261. package/pi-package/skills/parallel-review/SKILL.md +55 -0
  262. package/pi-package/skills/parallel-review/references/criteria.md +34 -0
  263. package/pi-package/skills/parallel-review/references/templates.md +59 -0
  264. package/pi-package/skills/plan-review/SKILL.md +48 -0
  265. package/pi-package/skills/plan-review/references/criteria.md +51 -0
  266. package/pi-package/skills/plan-review/references/templates.md +67 -0
  267. package/pi-package/skills/pre-mortem/SKILL.md +16 -0
  268. package/pi-package/skills/project-status-report/SKILL.md +130 -0
  269. package/pi-package/skills/pwa-accessibility-review/SKILL.md +87 -0
  270. package/pi-package/skills/rca-diagnostician/SKILL.md +36 -0
  271. package/pi-package/skills/rca-diagnostician/references/action-hierarchy.md +77 -0
  272. package/pi-package/skills/rca-diagnostician/references/bias-countermeasures.md +64 -0
  273. package/pi-package/skills/rca-diagnostician/references/evidence-timeline.md +49 -0
  274. package/pi-package/skills/rca-diagnostician/references/hypothesis-methods.md +53 -0
  275. package/pi-package/skills/rca-diagnostician/references/problem-definition.md +34 -0
  276. package/pi-package/skills/rca-diagnostician/references/report-template.md +75 -0
  277. package/pi-package/skills/rca-diagnostician/references/rigor-checklist.md +66 -0
  278. package/pi-package/skills/red-team-review/SKILL.md +139 -0
  279. package/pi-package/skills/research-codebase/SKILL.md +28 -0
  280. package/pi-package/skills/research-codebase/references/report-template.md +75 -0
  281. package/pi-package/skills/research-codebase/references/search-patterns.md +27 -0
  282. package/pi-package/skills/research-documentation/SKILL.md +85 -0
  283. package/pi-package/skills/research-review/SKILL.md +48 -0
  284. package/pi-package/skills/research-review/references/criteria.md +51 -0
  285. package/pi-package/skills/research-review/references/templates.md +73 -0
  286. package/pi-package/skills/resonant-refactor/SKILL.md +51 -0
  287. package/pi-package/skills/resume-handoff/SKILL.md +25 -0
  288. package/pi-package/skills/resume-handoff/references/analysis-template.md +40 -0
  289. package/pi-package/skills/resume-handoff/references/locating.md +12 -0
  290. package/pi-package/skills/review-documentation/SKILL.md +50 -0
  291. package/pi-package/skills/rigidity-diagnostician/SKILL.md +76 -0
  292. package/pi-package/skills/rule-of-5-universal/SKILL.md +32 -0
  293. package/pi-package/skills/rule-of-5-universal/references/criteria.md +34 -0
  294. package/pi-package/skills/rule-of-5-universal/references/examples.md +69 -0
  295. package/pi-package/skills/rule-of-5-universal/references/templates.md +136 -0
  296. package/pi-package/skills/specification-evaluation-diagnostician/SKILL.md +112 -0
  297. package/pi-package/skills/specification-review/SKILL.md +49 -0
  298. package/pi-package/skills/specification-review/references/criteria.md +51 -0
  299. package/pi-package/skills/specification-review/references/templates.md +67 -0
  300. package/pi-package/skills/systematic-housekeeping/SKILL.md +33 -0
  301. package/pi-package/skills/tdd/SKILL.md +44 -0
  302. package/pi-package/skills/tdd/references/criteria.md +26 -0
  303. package/pi-package/skills/tdd/references/templates.md +53 -0
  304. package/pi-package/skills/test-abstraction-miner/SKILL.md +49 -0
  305. package/pi-package/skills/test-friction/SKILL.md +57 -0
  306. package/pi-package/skills/testability-implementability-evaluator/SKILL.md +150 -0
  307. package/pi-package/skills/ui-align/SKILL.md +38 -0
  308. package/pi-package/skills/ux-dx-evaluation-diagnostician/SKILL.md +27 -0
  309. package/pi-package/skills/ux-dx-evaluation-diagnostician/references/layer-1-product.md +20 -0
  310. package/pi-package/skills/ux-dx-evaluation-diagnostician/references/layer-2-engineering.md +20 -0
  311. package/pi-package/skills/ux-dx-evaluation-diagnostician/references/layer-3-interface.md +23 -0
  312. package/pi-package/skills/ux-dx-evaluation-diagnostician/references/layer-4-ecosystem.md +20 -0
  313. package/pi-package/skills/ux-dx-evaluation-diagnostician/references/layer-5-documentation.md +19 -0
  314. package/pi-package/skills/ux-dx-evaluation-diagnostician/references/report-template.md +36 -0
  315. package/pi-package/skills/verification-diagnostician/SKILL.md +96 -0
  316. package/pi-package/skills/verify-prompt/SKILL.md +38 -0
  317. package/pi-package/skills/verify-prompt/references/criteria.md +21 -0
  318. package/scripts/cli.mjs +453 -0
@@ -0,0 +1,521 @@
1
+ #!/usr/bin/env python3
2
+ # /// script
3
+ # requires-python = ">=3.10"
4
+ # dependencies = []
5
+ # ///
6
+ """
7
+ Extract links from documentation files in a repository.
8
+
9
+ Walks a directory, finds documentation and source files, pulls out every link
10
+ (markdown inline, reference-style, autolinks, rST, bare URLs, code-comment URLs)
11
+ along with the surrounding context, the file path, and the line number.
12
+
13
+ Output: JSON array to stdout (or --out file), one entry per link occurrence.
14
+
15
+ Usage:
16
+ uv run extract_links.py <repo_path> [--out links.json] [--include-code]
17
+ [--extensions .md,.mdx,.rst] [--exclude node_modules,dist]
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import argparse
23
+ import json
24
+ import os
25
+ import re
26
+ import sys
27
+ from dataclasses import dataclass, asdict
28
+ from pathlib import Path
29
+ from typing import Iterable
30
+
31
+
32
+ # -------- File-type configuration --------
33
+
34
+ DOC_EXTS = {".md", ".mdx", ".markdown", ".rst", ".txt"}
35
+ CODE_EXTS = {
36
+ ".py", ".js", ".jsx", ".ts", ".tsx", ".mjs", ".cjs",
37
+ ".java", ".go", ".rs", ".rb", ".c", ".cc", ".cpp", ".h", ".hpp",
38
+ ".swift", ".kt", ".cs", ".php", ".sh",
39
+ }
40
+
41
+ DEFAULT_EXCLUDE = {
42
+ ".git", "node_modules", "dist", "build", "target", ".next", ".nuxt",
43
+ "__pycache__", ".venv", "venv", "env", ".tox", ".mypy_cache",
44
+ ".pytest_cache", "vendor", "coverage", ".idea", ".vscode",
45
+ }
46
+
47
+
48
+ # -------- Link patterns --------
49
+
50
+ # Markdown inline: [text](url "optional title")
51
+ MD_INLINE = re.compile(
52
+ r'(?<!\!)\[(?P<text>(?:[^\[\]]|\[[^\]]*\])*)\]\((?P<url><[^>]+>|[^\s\)]+)(?:\s+"[^"]*")?\)'
53
+ )
54
+
55
+ # Markdown image: ![alt](url) — separated so reports can flag images distinctly
56
+ MD_IMAGE = re.compile(
57
+ r'!\[(?P<text>[^\]]*)\]\((?P<url><[^>]+>|[^\s\)]+)(?:\s+"[^"]*")?\)'
58
+ )
59
+
60
+ # Reference-style usage: [text][label] or [text][] — we resolve labels later
61
+ MD_REF_USE = re.compile(r'(?<!\!)\[(?P<text>(?:[^\[\]]|\[[^\]]*\])*)\]\[(?P<label>[^\]]*)\]')
62
+
63
+ # Reference-style definition: [label]: url "optional title"
64
+ MD_REF_DEF = re.compile(
65
+ r'^\s*\[(?P<label>[^\]]+)\]:\s*<?(?P<url>\S+?)>?(?:\s+"[^"]*")?\s*$',
66
+ re.MULTILINE,
67
+ )
68
+
69
+ # Autolink: <https://...> or <user@host>
70
+ MD_AUTOLINK = re.compile(r'<(?P<url>(?:https?|ftp|mailto):[^>\s]+)>')
71
+
72
+ # rST external link with text: `text <url>`_
73
+ RST_LINK = re.compile(r'`(?P<text>[^`<]+)\s+<(?P<url>[^>]+)>`_')
74
+
75
+ # rST target definition: .. _label: url
76
+ RST_TARGET = re.compile(r'^\s*\.\.\s+_(?P<label>[^:]+):\s*(?P<url>\S+)\s*$', re.MULTILINE)
77
+
78
+ # Bare URL — conservative, used as a fallback for plain text + code comments.
79
+ # Matches http(s) and stops at whitespace or common sentence terminators.
80
+ # Allows parentheses inside the URL (Wikipedia etc.) — clean_bare_url strips unbalanced trailing ones.
81
+ BARE_URL = re.compile(
82
+ r'(?<![\w/\-\.])(?P<url>https?://[^\s<>"\']+?)(?=[\s<>"\'\}\,;:!?]|$)',
83
+ re.IGNORECASE,
84
+ )
85
+
86
+ # Trailing punctuation we should strip off bare URLs (since regex includes them sometimes)
87
+ TRAILING_PUNCT = '.,;:!?\'"}'
88
+
89
+
90
+ @dataclass
91
+ class Link:
92
+ url: str # the URL as written (after fence-stripping)
93
+ raw_url: str # the URL exactly as it appeared
94
+ text: str # link text / description, may be empty
95
+ file: str # path relative to repo root
96
+ line: int # 1-indexed line where link starts
97
+ col: int # 0-indexed column
98
+ context: str # surrounding text (typically the line + neighbors)
99
+ kind: str # md-inline | md-image | md-ref | md-autolink | rst-link | rst-target | bare | comment-url
100
+ link_type: str # external | relative | anchor | mailto | other
101
+
102
+ def to_dict(self) -> dict:
103
+ return asdict(self)
104
+
105
+
106
+ # -------- Classification helpers --------
107
+
108
+ def classify(url: str) -> str:
109
+ u = url.strip()
110
+ if u.startswith('#'):
111
+ return 'anchor'
112
+ if u.startswith(('http://', 'https://', 'ftp://')):
113
+ return 'external'
114
+ if u.startswith('mailto:'):
115
+ return 'mailto'
116
+ if u.startswith(('/', './', '../')) or not re.match(r'^[a-z]+:', u, re.IGNORECASE):
117
+ # No scheme — treat as a repo-relative path
118
+ return 'relative'
119
+ return 'other'
120
+
121
+
122
+ def strip_angle_brackets(url: str) -> str:
123
+ if url.startswith('<') and url.endswith('>'):
124
+ return url[1:-1]
125
+ return url
126
+
127
+
128
+ def clean_bare_url(url: str) -> str:
129
+ """Strip trailing sentence punctuation that got pulled in by the regex."""
130
+ # First strip simple trailing punctuation
131
+ while url and url[-1] in TRAILING_PUNCT:
132
+ url = url[:-1]
133
+ # Then strip unbalanced trailing brackets/parens
134
+ bracket_pairs = {')': '(', ']': '['}
135
+ while url and url[-1] in bracket_pairs:
136
+ opener = bracket_pairs[url[-1]]
137
+ if url.count(opener) >= url.count(url[-1]):
138
+ break # balanced — keep it
139
+ url = url[:-1]
140
+ # Strip any remaining trailing punctuation exposed by bracket removal
141
+ while url and url[-1] in TRAILING_PUNCT:
142
+ url = url[:-1]
143
+ return url
144
+
145
+
146
+ def context_window(lines: list[str], line_idx: int, before: int = 1, after: int = 1) -> str:
147
+ """Return a slice of lines around line_idx (0-indexed) as a single string."""
148
+ start = max(0, line_idx - before)
149
+ end = min(len(lines), line_idx + after + 1)
150
+ return '\n'.join(lines[start:end]).strip()
151
+
152
+
153
+ # -------- Comment extraction --------
154
+
155
+ # For code files we don't want to match URLs in code strings indiscriminately,
156
+ # so we extract comment regions first and then scan those for bare URLs.
157
+
158
+ COMMENT_PATTERNS = {
159
+ # line-comment prefixes per language family
160
+ 'hash': re.compile(r'#.*$', re.MULTILINE), # py, rb, sh, etc.
161
+ 'slashes': re.compile(r'//.*$', re.MULTILINE), # js, ts, java, go, rs, c, etc.
162
+ 'block_c': re.compile(r'/\*[\s\S]*?\*/'), # c-style block comments
163
+ 'triple_double': re.compile(r'"""[\s\S]*?"""'), # python docstrings
164
+ 'triple_single': re.compile(r"'''[\s\S]*?'''"), # python docstrings (single)
165
+ }
166
+
167
+ LANG_COMMENTS = {
168
+ '.py': ('hash', 'triple_double', 'triple_single'),
169
+ '.rb': ('hash',),
170
+ '.sh': ('hash',),
171
+ '.js': ('slashes', 'block_c'),
172
+ '.jsx': ('slashes', 'block_c'),
173
+ '.ts': ('slashes', 'block_c'),
174
+ '.tsx': ('slashes', 'block_c'),
175
+ '.mjs': ('slashes', 'block_c'),
176
+ '.cjs': ('slashes', 'block_c'),
177
+ '.java': ('slashes', 'block_c'),
178
+ '.go': ('slashes', 'block_c'),
179
+ '.rs': ('slashes', 'block_c'),
180
+ '.c': ('slashes', 'block_c'),
181
+ '.cc': ('slashes', 'block_c'),
182
+ '.cpp': ('slashes', 'block_c'),
183
+ '.h': ('slashes', 'block_c'),
184
+ '.hpp': ('slashes', 'block_c'),
185
+ '.swift': ('slashes', 'block_c'),
186
+ '.kt': ('slashes', 'block_c'),
187
+ '.cs': ('slashes', 'block_c'),
188
+ '.php': ('slashes', 'block_c', 'hash'),
189
+ }
190
+
191
+
192
+ def extract_comment_regions(content: str, ext: str) -> list[tuple[int, str]]:
193
+ """Return list of (offset, comment_text) for all comment regions in the file."""
194
+ patterns = LANG_COMMENTS.get(ext, ())
195
+ regions = []
196
+ for pkey in patterns:
197
+ for m in COMMENT_PATTERNS[pkey].finditer(content):
198
+ regions.append((m.start(), m.group(0)))
199
+ regions.sort()
200
+ return regions
201
+
202
+
203
+ def offset_to_line_col(content: str, offset: int) -> tuple[int, int]:
204
+ """Convert a byte offset into (1-indexed line, 0-indexed column)."""
205
+ prefix = content[:offset]
206
+ line = prefix.count('\n') + 1
207
+ col = offset - (prefix.rfind('\n') + 1) if '\n' in prefix else offset
208
+ return line, col
209
+
210
+
211
+ # -------- Main extractors --------
212
+
213
+ def extract_markdown(content: str, rel_path: str) -> list[Link]:
214
+ lines = content.splitlines()
215
+ links: list[Link] = []
216
+
217
+ # Collect reference definitions first
218
+ ref_defs: dict[str, str] = {}
219
+ for m in MD_REF_DEF.finditer(content):
220
+ ref_defs[m.group('label').lower()] = strip_angle_brackets(m.group('url'))
221
+
222
+ # Inline links (skip those inside code fences — simple heuristic)
223
+ fence_ranges = _code_fence_ranges(content)
224
+
225
+ def in_fence(offset: int) -> bool:
226
+ return any(s <= offset < e for s, e in fence_ranges)
227
+
228
+ consumed_ranges: list[tuple[int, int]] = []
229
+
230
+ def add_match(m: re.Match, kind: str, url: str, text: str) -> None:
231
+ consumed_ranges.append((m.start(), m.end()))
232
+ if in_fence(m.start()):
233
+ return
234
+ line, col = offset_to_line_col(content, m.start())
235
+ url_clean = strip_angle_brackets(url).strip()
236
+ links.append(Link(
237
+ url=url_clean,
238
+ raw_url=url,
239
+ text=text.strip(),
240
+ file=rel_path,
241
+ line=line,
242
+ col=col,
243
+ context=context_window(lines, line - 1),
244
+ kind=kind,
245
+ link_type=classify(url_clean),
246
+ ))
247
+
248
+ for m in MD_INLINE.finditer(content):
249
+ add_match(m, 'md-inline', m.group('url'), m.group('text'))
250
+
251
+ for m in MD_IMAGE.finditer(content):
252
+ add_match(m, 'md-image', m.group('url'), m.group('text'))
253
+
254
+ for m in MD_AUTOLINK.finditer(content):
255
+ add_match(m, 'md-autolink', m.group('url'), '')
256
+
257
+ # Reference-style usage: resolve via ref_defs
258
+
259
+ for m in MD_REF_USE.finditer(content):
260
+ if in_fence(m.start()):
261
+ continue
262
+ label = (m.group('label') or m.group('text')).strip().lower()
263
+ url = ref_defs.get(label)
264
+ if not url:
265
+ continue
266
+ line, col = offset_to_line_col(content, m.start())
267
+ links.append(Link(
268
+ url=url,
269
+ raw_url=url,
270
+ text=m.group('text').strip(),
271
+ file=rel_path,
272
+ line=line,
273
+ col=col,
274
+ context=context_window(lines, line - 1),
275
+ kind='md-ref',
276
+ link_type=classify(url),
277
+ ))
278
+
279
+ # Reference definitions also contain URLs worth checking
280
+ for m in MD_REF_DEF.finditer(content):
281
+ consumed_ranges.append((m.start(), m.end()))
282
+ url = strip_angle_brackets(m.group('url')).strip()
283
+ line, col = offset_to_line_col(content, m.start())
284
+ links.append(Link(
285
+ url=url, raw_url=url, text=m.group('label').strip(),
286
+ file=rel_path, line=line, col=col,
287
+ context=context_window(lines, line - 1),
288
+ kind='md-ref-def', link_type=classify(url),
289
+ ))
290
+
291
+ # Now scan for bare URLs in regions NOT already consumed (GFM auto-links these)
292
+ def in_consumed(offset: int) -> bool:
293
+ return any(s <= offset < e for s, e in consumed_ranges)
294
+
295
+ for m in BARE_URL.finditer(content):
296
+ if in_fence(m.start()) or in_consumed(m.start()):
297
+ continue
298
+ raw = m.group('url')
299
+ url = clean_bare_url(raw)
300
+ if not url:
301
+ continue
302
+ line, col = offset_to_line_col(content, m.start())
303
+ links.append(Link(
304
+ url=url, raw_url=raw, text='',
305
+ file=rel_path, line=line, col=col,
306
+ context=context_window(lines, line - 1),
307
+ kind='bare', link_type=classify(url),
308
+ ))
309
+
310
+ return links
311
+
312
+
313
+ def _code_fence_ranges(content: str) -> list[tuple[int, int]]:
314
+ """Find ``` ... ``` fenced code blocks so we skip links inside them."""
315
+ ranges = []
316
+ fence_re = re.compile(r'^( {0,3})(```+|~~~+)', re.MULTILINE)
317
+ open_start: int | None = None
318
+ open_char: str | None = None
319
+ open_count: int = 0
320
+ for m in fence_re.finditer(content):
321
+ char = m.group(2)[0] # '`' or '~'
322
+ count = len(m.group(2))
323
+ if open_start is None:
324
+ # Opening fence
325
+ open_start = m.start()
326
+ open_char = char
327
+ open_count = count
328
+ elif char == open_char and count >= open_count:
329
+ # Matching closing fence
330
+ ranges.append((open_start, m.end()))
331
+ open_start = None
332
+ open_char = None
333
+ open_count = 0
334
+ # else: different fence char or shorter count inside a block — skip
335
+ # If there's an unclosed fence, treat everything after it as fenced
336
+ if open_start is not None:
337
+ ranges.append((open_start, len(content)))
338
+ return ranges
339
+
340
+
341
+ def extract_rst(content: str, rel_path: str) -> list[Link]:
342
+ lines = content.splitlines()
343
+ links: list[Link] = []
344
+ consumed_ranges: list[tuple[int, int]] = []
345
+ for m in RST_LINK.finditer(content):
346
+ consumed_ranges.append((m.start(), m.end()))
347
+ line, col = offset_to_line_col(content, m.start())
348
+ url = m.group('url').strip()
349
+ links.append(Link(
350
+ url=url, raw_url=url, text=m.group('text').strip(),
351
+ file=rel_path, line=line, col=col,
352
+ context=context_window(lines, line - 1),
353
+ kind='rst-link', link_type=classify(url),
354
+ ))
355
+ for m in RST_TARGET.finditer(content):
356
+ consumed_ranges.append((m.start(), m.end()))
357
+ line, col = offset_to_line_col(content, m.start())
358
+ url = m.group('url').strip()
359
+ links.append(Link(
360
+ url=url, raw_url=url, text=m.group('label').strip(),
361
+ file=rel_path, line=line, col=col,
362
+ context=context_window(lines, line - 1),
363
+ kind='rst-target', link_type=classify(url),
364
+ ))
365
+ # Also pick up bare URLs in rST bodies NOT already consumed by link/target patterns
366
+ def in_consumed(offset: int) -> bool:
367
+ return any(s <= offset < e for s, e in consumed_ranges)
368
+
369
+ for m in BARE_URL.finditer(content):
370
+ if in_consumed(m.start()):
371
+ continue
372
+ raw = m.group('url')
373
+ url = clean_bare_url(raw)
374
+ if not url:
375
+ continue
376
+ line, col = offset_to_line_col(content, m.start())
377
+ links.append(Link(
378
+ url=url, raw_url=raw, text='',
379
+ file=rel_path, line=line, col=col,
380
+ context=context_window(lines, line - 1),
381
+ kind='bare', link_type=classify(url),
382
+ ))
383
+ return links
384
+
385
+
386
+ def extract_bare_urls(content: str, rel_path: str, kind: str = 'bare') -> list[Link]:
387
+ lines = content.splitlines()
388
+ out: list[Link] = []
389
+ for m in BARE_URL.finditer(content):
390
+ raw = m.group('url')
391
+ url = clean_bare_url(raw)
392
+ if not url:
393
+ continue
394
+ line, col = offset_to_line_col(content, m.start())
395
+ out.append(Link(
396
+ url=url, raw_url=raw, text='',
397
+ file=rel_path, line=line, col=col,
398
+ context=context_window(lines, line - 1),
399
+ kind=kind, link_type=classify(url),
400
+ ))
401
+ return out
402
+
403
+
404
+ def extract_code_comments(content: str, rel_path: str, ext: str) -> list[Link]:
405
+ """Pull bare URLs out of comment regions only."""
406
+ regions = extract_comment_regions(content, ext)
407
+ if not regions:
408
+ return []
409
+ lines = content.splitlines()
410
+ out: list[Link] = []
411
+ seen: set[tuple[int, int]] = set()
412
+ for base_offset, text in regions:
413
+ for m in BARE_URL.finditer(text):
414
+ absolute_offset = base_offset + m.start()
415
+ if absolute_offset in {s for s, _ in seen}:
416
+ continue
417
+ raw = m.group('url')
418
+ url = clean_bare_url(raw)
419
+ if not url:
420
+ continue
421
+ line, col = offset_to_line_col(content, absolute_offset)
422
+ key = (line, col)
423
+ if key in seen:
424
+ continue
425
+ seen.add(key)
426
+ out.append(Link(
427
+ url=url, raw_url=raw, text='',
428
+ file=rel_path, line=line, col=col,
429
+ context=context_window(lines, line - 1, before=2, after=1),
430
+ kind='comment-url', link_type=classify(url),
431
+ ))
432
+ return out
433
+
434
+
435
+ # -------- File walking --------
436
+
437
+ def should_skip_dir(name: str, extra_exclude: set[str]) -> bool:
438
+ return name in DEFAULT_EXCLUDE or name in extra_exclude
439
+
440
+
441
+ def walk_files(root: Path, extensions: set[str], include_code: bool,
442
+ extra_exclude: set[str]) -> Iterable[Path]:
443
+ allowed = set(extensions)
444
+ if include_code:
445
+ allowed |= CODE_EXTS
446
+ for dirpath, dirnames, filenames in os.walk(root):
447
+ dirnames[:] = [d for d in dirnames if not should_skip_dir(d, extra_exclude)]
448
+ for fn in filenames:
449
+ ext = Path(fn).suffix.lower()
450
+ if ext in allowed:
451
+ yield Path(dirpath) / fn
452
+
453
+
454
+ def extract_from_file(path: Path, rel_path: str, include_code: bool) -> list[Link]:
455
+ ext = path.suffix.lower()
456
+ try:
457
+ content = path.read_text(encoding='utf-8', errors='replace')
458
+ except Exception as e:
459
+ print(f"skip {rel_path}: {e}", file=sys.stderr)
460
+ return []
461
+
462
+ if ext in {'.md', '.mdx', '.markdown'}:
463
+ return extract_markdown(content, rel_path)
464
+ if ext == '.rst':
465
+ return extract_rst(content, rel_path)
466
+ if ext == '.txt':
467
+ return extract_bare_urls(content, rel_path)
468
+ if include_code and ext in CODE_EXTS:
469
+ return extract_code_comments(content, rel_path, ext)
470
+ return []
471
+
472
+
473
+ # -------- CLI --------
474
+
475
+ def main() -> int:
476
+ p = argparse.ArgumentParser(description=__doc__)
477
+ p.add_argument('repo', help='Path to repository root')
478
+ p.add_argument('--out', help='Write JSON here instead of stdout')
479
+ p.add_argument('--include-code', action='store_true',
480
+ help='Also scan URLs inside code comments')
481
+ p.add_argument('--extensions', default=','.join(sorted(DOC_EXTS)),
482
+ help='Comma-separated list of doc extensions')
483
+ p.add_argument('--exclude', default='',
484
+ help='Additional comma-separated directory names to skip')
485
+ args = p.parse_args()
486
+
487
+ root = Path(args.repo).resolve()
488
+ if not root.is_dir():
489
+ print(f"error: {root} is not a directory", file=sys.stderr)
490
+ return 2
491
+
492
+ extensions = {e if e.startswith('.') else '.' + e
493
+ for e in args.extensions.split(',') if e.strip()}
494
+ extra_exclude = {e.strip() for e in args.exclude.split(',') if e.strip()}
495
+
496
+ all_links: list[Link] = []
497
+ file_count = 0
498
+ for path in walk_files(root, extensions, args.include_code, extra_exclude):
499
+ rel = str(path.relative_to(root))
500
+ all_links.extend(extract_from_file(path, rel, args.include_code))
501
+ file_count += 1
502
+
503
+ result = {
504
+ 'repo': str(root),
505
+ 'file_count': file_count,
506
+ 'link_count': len(all_links),
507
+ 'links': [l.to_dict() for l in all_links],
508
+ }
509
+
510
+ out_text = json.dumps(result, indent=2, ensure_ascii=False)
511
+ if args.out:
512
+ Path(args.out).write_text(out_text, encoding='utf-8')
513
+ print(f"wrote {len(all_links)} links from {file_count} files to {args.out}",
514
+ file=sys.stderr)
515
+ else:
516
+ print(out_text)
517
+ return 0
518
+
519
+
520
+ if __name__ == '__main__':
521
+ sys.exit(main())
@@ -0,0 +1,123 @@
1
+ <!-- Full version: content/prompt-task-edge-case-discovery.md -->
2
+ You are a Specification Edge Case Analyst. Systematically discover edge cases, failure modes, and specification gaps *before* implementation using a six-boundary analytical framework. Do NOT modify the specification — produce structured gap analysis with concrete scenarios only.
3
+
4
+ **GUARD:** This is a probabilistic model. Treat output as structured triage, not ground truth. Critical and High findings must be verified by the specification author or domain expert. Do not apply to draft outlines, code review, or trivial single-function changes.
5
+
6
+ **INPUT**
7
+ - Specification to analyze: [PASTE OR SPECIFY FILE PATH]
8
+ - Risk profile (optional): [standard | security-sensitive | safety-critical | concurrent-distributed | regulatory | "infer"]
9
+ - Team capability (optional): [all | no-formal-methods | basic-only | "infer"]
10
+
11
+ **PROTOCOL (Six-Boundary Sequential Analysis)**
12
+
13
+ Apply boundaries in order. Each builds on prior findings. After Boundary 4, risk-gate Boundaries 5-6.
14
+
15
+ **Boundary 1 — HUMAN (UX Stress Cases & Extreme Personas):**
16
+ Identify gaps from the perspective of users under stress, constraint, or at the fringes. For non-user-facing specs (libraries, infrastructure, pipelines), reinterpret "users" as *consumers*: other services, operators, maintainers. Focus on operator stress (on-call at 3AM), consumer misuse (wrong config, unexpected input), and observability gaps.
17
+ - Extreme personas: accessibility needs, low digital literacy, malicious intent, emotional distress (or: sleep-deprived operator, misconfigured consumer, unfamiliar maintainer)
18
+ - Environmental stress: low bandwidth, failing hardware, interrupted sessions, screen readers
19
+ - Crisis context: rushed, panicking, cognitively overloaded users
20
+ - Recovery paths: when something fails, can the user recover or is it a dead end?
21
+ Expect 3-8 findings per major capability.
22
+ Format: `[HUM-NNN] [severity] — Persona/Scenario: ... Gap: ... Impact: ... Suggested Scenario: Given/When/Then`
23
+
24
+ **Boundary 2 — BUSINESS (Example Mapping & Scenario Catalog):**
25
+ Decompose each capability into rules, examples, and unresolved questions. Verify four-path coverage:
26
+ - Happy path (standard success)
27
+ - Error path (validation failures, user mistakes)
28
+ - Abuse path (business logic abuse — gaming limits, exploiting policies; defer technical/security abuse to Boundary 5)
29
+ - Hazard path (system failures, network outages, data corruption)
30
+ Flag unresolved questions where two reasonable people would disagree on behavior.
31
+ Expect 5-15 findings per major capability (typically the highest-yield boundary).
32
+ Format: `[BIZ-NNN] [severity] — Rule: ... Missing Path: ... Gap: ... Question: ... Suggested Scenario: Given/When/Then`
33
+
34
+ **Boundary 3 — MATHEMATICAL (BVA, EP, Decision Tables):**
35
+ Apply Equivalence Partitioning, Boundary Value Analysis, and Decision Tables.
36
+ - Input partitioning: valid and invalid classes for each input
37
+ - Boundary values: min, min-1, max, max+1, zero, empty, null — is behavior defined?
38
+ - Decision table: cross-product of multi-condition rules — unhandled combinations? impossible states?
39
+ - Data type boundaries: string lengths, numeric overflow, date ranges, array capacities, Unicode
40
+ Format: `[MATH-NNN] [severity] — Input/Condition: ... Boundary: ... Gap: ... Suggested Requirement: ...`
41
+
42
+ **Boundary 4 — ARCHITECTURAL (Design by Contract):**
43
+ Examine interfaces for missing contracts.
44
+ - Preconditions: what must be true before each operation? Are caller obligations explicit?
45
+ - Postconditions: what does the system guarantee after success? Are exit states defined?
46
+ - Invariants: what must always hold? ("balance never negative unless overdraft enabled")
47
+ - Forbidden states: what must never happen? Documented?
48
+ - Cascading failures: if a postcondition is violated, what breaks downstream?
49
+ Format: `[ARCH-NNN] [severity] — Interface: ... Contract Element: ... Gap: ... Suggested Contract: ...`
50
+
51
+ **RISK GATE** — Before Boundary 5, output:
52
+ ```
53
+ Risk Assessment: Safety/security [Y/N], Concurrency [Y/N], Regulatory [Y/N], Failure cost [L/M/H]
54
+ Boundary 5 (Failure): [APPLY|SKIP] — rationale
55
+ Boundary 6 (Formal): [APPLY|SKIP] — rationale
56
+ ```
57
+ If standard-risk with no concerns: skip Boundaries 5-6, proceed to Synthesis.
58
+
59
+ **Boundary 5 — FAILURE (FMEA + STRIDE Threat Modeling) — Risk-Gated:**
60
+ FMEA: enumerate failure modes per component. Assess qualitatively: Severity [Critical/High/Med/Low], Likelihood [Likely/Possible/Unlikely], Detectability [Easy/Hard/Hidden]. Rank risk by combination (e.g., Critical + Likely + Hidden = highest priority). Identify missing controls, diagnostics, graceful degradation.
61
+ STRIDE: Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege.
62
+ Format: `[FAIL-NNN] [severity] — Failure Mode/Threat: ... Category: ... Risk: [Sev/Likelihood/Detect] or [STRIDE category] ... Gap: ... Suggested Mitigation: ...`
63
+
64
+ **Boundary 6 — FORMAL (Invariant & State Analysis) — Risk-Gated:**
65
+ For concurrent, distributed, or authorization-intensive subsystems:
66
+ - State machine completeness: all states, transitions, terminal conditions defined?
67
+ - Concurrency: race conditions, deadlocks, livelocks, ordering dependencies
68
+ - Authorization: unintended permission paths? deny-by-default?
69
+ - Distributed consistency: network partitions, split-brain, eventual consistency windows
70
+ - Temporal: liveness (good things eventually happen) and safety (bad things never happen)
71
+ Format: `[FORM-NNN] [severity] — Subsystem: ... Property Type: ... Gap: ... Scenario: ... Suggested Property: ...`
72
+
73
+ **SYNTHESIS**
74
+
75
+ Produce a final report:
76
+ ```
77
+ # Edge Case Discovery Report
78
+ Specification: [title/path]
79
+ Risk Profile: [profile]
80
+ Boundaries Applied: [1-4 | 1-5 | 1-6]
81
+
82
+ ## Gap Summary
83
+ | Boundary | CRITICAL | HIGH | MEDIUM | LOW | Total |
84
+ (one row per applied boundary, plus TOTAL)
85
+
86
+ ## Top 5 Critical Gaps
87
+ [ID] - Description / Impact / Fix (specific addition to spec)
88
+
89
+ ## Scenario Catalog Summary
90
+ Happy/Error/Abuse/Hazard paths: defined vs missing counts
91
+ Boundary conditions: tested vs missing counts
92
+
93
+ ## Missing Contracts
94
+ Preconditions / Postconditions / Invariants not defined
95
+
96
+ ## Verdict
97
+ [NO_GAPS_FOUND | NEEDS_SCENARIOS | NEEDS_CONTRACTS | NEEDS_REWORK]
98
+ Rationale: what must be added before implementation
99
+ ```
100
+
101
+ **RULES**
102
+ 1. Do NOT modify the specification. Gap analysis only.
103
+ 2. Every gap MUST include a concrete suggested scenario (Given/When/Then) or contract statement.
104
+ 3. Build progressively — reference prior findings by ID in later boundaries.
105
+ 4. Respect the risk gate — do not apply Boundaries 5-6 to standard-risk specs unless analysis reveals safety/security/concurrency concerns.
106
+ 5. Acknowledge coverage limits: ML/data edge cases, brownfield architectural gaps, and domain-specific risks are outside this protocol's scope.
107
+ 6. If team lacks capability for a protocol (e.g., formal methods), recommend the lightweight alternative.
108
+
109
+ Severity: CRITICAL = spec gap that will cause implementation failure or security breach. HIGH = missing scenario or contract that creates significant ambiguity. MEDIUM = incomplete boundary or partial coverage. LOW = missing edge case with minimal impact.
110
+
111
+ **Example finding:**
112
+ ```
113
+ [BIZ-002] CRITICAL - Section 4.1 "Transfer Limits"
114
+ Rule: Daily transfer limit per account
115
+ Missing Path: abuse
116
+ Gap: No specification of behavior when limit is approached via multiple small transfers
117
+ Question: Should rate limiting apply per-recipient or per-account?
118
+ Suggested Scenario:
119
+ Given Alice has transferred $9,900 of a $10,000 daily limit
120
+ When Alice initiates a $200 transfer
121
+ Then the transfer is declined with reason "daily_limit_exceeded"
122
+ And the remaining limit ($100) is shown to the user
123
+ ```