agent-sdd 1.0.3

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 (304) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1028 -0
  3. package/README.ru.md +1046 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.js +867 -0
  6. package/dist/features/approve/adapters/inbound/CliApproveHandler.d.ts +17 -0
  7. package/dist/features/approve/adapters/inbound/CliApproveHandler.js +108 -0
  8. package/dist/features/approve/adapters/outbound/NodeApproveFileSystem.d.ts +8 -0
  9. package/dist/features/approve/adapters/outbound/NodeApproveFileSystem.js +147 -0
  10. package/dist/features/approve/adapters/outbound/NodePlanFileWriter.d.ts +6 -0
  11. package/dist/features/approve/adapters/outbound/NodePlanFileWriter.js +92 -0
  12. package/dist/features/approve/adapters/outbound/SystemApproveClock.d.ts +4 -0
  13. package/dist/features/approve/adapters/outbound/SystemApproveClock.js +5 -0
  14. package/dist/features/approve/application/ApplyApproval.d.ts +19 -0
  15. package/dist/features/approve/application/ApplyApproval.js +30 -0
  16. package/dist/features/approve/application/WriteAttestation.d.ts +19 -0
  17. package/dist/features/approve/application/WriteAttestation.js +23 -0
  18. package/dist/features/approve/domain/ApproveRequest.d.ts +24 -0
  19. package/dist/features/approve/domain/ApproveRequest.js +24 -0
  20. package/dist/features/approve/domain/Rewrite.d.ts +1 -0
  21. package/dist/features/approve/domain/Rewrite.js +6 -0
  22. package/dist/features/approve/ports/inbound/ApproveCommand.d.ts +10 -0
  23. package/dist/features/approve/ports/inbound/ApproveCommand.js +1 -0
  24. package/dist/features/approve/ports/outbound/ApproveClock.d.ts +3 -0
  25. package/dist/features/approve/ports/outbound/ApproveClock.js +1 -0
  26. package/dist/features/approve/ports/outbound/ApproveConfigPort.d.ts +4 -0
  27. package/dist/features/approve/ports/outbound/ApproveConfigPort.js +1 -0
  28. package/dist/features/approve/ports/outbound/ApproveFileSystem.d.ts +8 -0
  29. package/dist/features/approve/ports/outbound/ApproveFileSystem.js +1 -0
  30. package/dist/features/approve/ports/outbound/PlanFileWriter.d.ts +13 -0
  31. package/dist/features/approve/ports/outbound/PlanFileWriter.js +1 -0
  32. package/dist/features/check/adapters/inbound/CliCheckHandler.d.ts +8 -0
  33. package/dist/features/check/adapters/inbound/CliCheckHandler.js +62 -0
  34. package/dist/features/check/adapters/outbound/ChildProcessCheckGit.d.ts +8 -0
  35. package/dist/features/check/adapters/outbound/ChildProcessCheckGit.js +112 -0
  36. package/dist/features/check/adapters/outbound/NodeCheckFileReader.d.ts +7 -0
  37. package/dist/features/check/adapters/outbound/NodeCheckFileReader.js +44 -0
  38. package/dist/features/check/application/CheckBaseline.d.ts +28 -0
  39. package/dist/features/check/application/CheckBaseline.js +54 -0
  40. package/dist/features/check/domain/BaselineComparison.d.ts +1 -0
  41. package/dist/features/check/domain/BaselineComparison.js +2 -0
  42. package/dist/features/check/ports/inbound/CheckCommand.d.ts +4 -0
  43. package/dist/features/check/ports/inbound/CheckCommand.js +1 -0
  44. package/dist/features/check/ports/outbound/CheckConfigPort.d.ts +4 -0
  45. package/dist/features/check/ports/outbound/CheckConfigPort.js +1 -0
  46. package/dist/features/check/ports/outbound/CheckGitPort.d.ts +7 -0
  47. package/dist/features/check/ports/outbound/CheckGitPort.js +1 -0
  48. package/dist/features/check/ports/outbound/CheckSpecPort.d.ts +9 -0
  49. package/dist/features/check/ports/outbound/CheckSpecPort.js +1 -0
  50. package/dist/features/doctor/adapters/inbound/CliDoctorHandler.d.ts +8 -0
  51. package/dist/features/doctor/adapters/inbound/CliDoctorHandler.js +77 -0
  52. package/dist/features/doctor/adapters/outbound/NodeRegistryReader.d.ts +5 -0
  53. package/dist/features/doctor/adapters/outbound/NodeRegistryReader.js +40 -0
  54. package/dist/features/doctor/application/RunDoctor.d.ts +30 -0
  55. package/dist/features/doctor/application/RunDoctor.js +78 -0
  56. package/dist/features/doctor/domain/RegistryRow.d.ts +23 -0
  57. package/dist/features/doctor/domain/RegistryRow.js +114 -0
  58. package/dist/features/doctor/domain/SemverRange.d.ts +7 -0
  59. package/dist/features/doctor/domain/SemverRange.js +82 -0
  60. package/dist/features/doctor/ports/inbound/DoctorCommand.d.ts +8 -0
  61. package/dist/features/doctor/ports/inbound/DoctorCommand.js +1 -0
  62. package/dist/features/doctor/ports/outbound/RegistryReader.d.ts +12 -0
  63. package/dist/features/doctor/ports/outbound/RegistryReader.js +1 -0
  64. package/dist/features/finalize/adapters/inbound/CliFinalizeHandler.d.ts +8 -0
  65. package/dist/features/finalize/adapters/inbound/CliFinalizeHandler.js +80 -0
  66. package/dist/features/finalize/adapters/outbound/NodeFinalizeFileSystem.d.ts +11 -0
  67. package/dist/features/finalize/adapters/outbound/NodeFinalizeFileSystem.js +167 -0
  68. package/dist/features/finalize/adapters/outbound/NodePlanRepo.d.ts +7 -0
  69. package/dist/features/finalize/adapters/outbound/NodePlanRepo.js +82 -0
  70. package/dist/features/finalize/adapters/outbound/SystemFinalizeClock.d.ts +4 -0
  71. package/dist/features/finalize/adapters/outbound/SystemFinalizeClock.js +5 -0
  72. package/dist/features/finalize/application/RunFinalize.d.ts +34 -0
  73. package/dist/features/finalize/application/RunFinalize.js +98 -0
  74. package/dist/features/finalize/domain/ValidateFinalizeGraph.d.ts +9 -0
  75. package/dist/features/finalize/domain/ValidateFinalizeGraph.js +86 -0
  76. package/dist/features/finalize/ports/inbound/FinalizeCommand.d.ts +7 -0
  77. package/dist/features/finalize/ports/inbound/FinalizeCommand.js +1 -0
  78. package/dist/features/finalize/ports/outbound/FinalizeClock.d.ts +3 -0
  79. package/dist/features/finalize/ports/outbound/FinalizeClock.js +1 -0
  80. package/dist/features/finalize/ports/outbound/FinalizeConfigPort.d.ts +4 -0
  81. package/dist/features/finalize/ports/outbound/FinalizeConfigPort.js +1 -0
  82. package/dist/features/finalize/ports/outbound/FinalizeFileSystem.d.ts +14 -0
  83. package/dist/features/finalize/ports/outbound/FinalizeFileSystem.js +1 -0
  84. package/dist/features/finalize/ports/outbound/PlanRepo.d.ts +21 -0
  85. package/dist/features/finalize/ports/outbound/PlanRepo.js +1 -0
  86. package/dist/features/install/adapters/inbound/CliInstallHandler.d.ts +8 -0
  87. package/dist/features/install/adapters/inbound/CliInstallHandler.js +54 -0
  88. package/dist/features/install/adapters/outbound/NodeInstallSource.d.ts +7 -0
  89. package/dist/features/install/adapters/outbound/NodeInstallSource.js +24 -0
  90. package/dist/features/install/adapters/outbound/NodeInstallTargetFs.d.ts +7 -0
  91. package/dist/features/install/adapters/outbound/NodeInstallTargetFs.js +30 -0
  92. package/dist/features/install/application/InstallRules.d.ts +10 -0
  93. package/dist/features/install/application/InstallRules.js +73 -0
  94. package/dist/features/install/domain/InstallPlan.d.ts +27 -0
  95. package/dist/features/install/domain/InstallPlan.js +168 -0
  96. package/dist/features/install/domain/InstallResult.d.ts +23 -0
  97. package/dist/features/install/domain/InstallResult.js +1 -0
  98. package/dist/features/install/domain/InstallTarget.d.ts +6 -0
  99. package/dist/features/install/domain/InstallTarget.js +7 -0
  100. package/dist/features/install/domain/ManagedBlock.d.ts +3 -0
  101. package/dist/features/install/domain/ManagedBlock.js +20 -0
  102. package/dist/features/install/domain/RuleManifest.d.ts +17 -0
  103. package/dist/features/install/domain/RuleManifest.js +69 -0
  104. package/dist/features/install/domain/SettingsMerge.d.ts +5 -0
  105. package/dist/features/install/domain/SettingsMerge.js +43 -0
  106. package/dist/features/install/ports/inbound/InstallCommand.d.ts +10 -0
  107. package/dist/features/install/ports/inbound/InstallCommand.js +1 -0
  108. package/dist/features/install/ports/outbound/InstallSource.d.ts +4 -0
  109. package/dist/features/install/ports/outbound/InstallSource.js +1 -0
  110. package/dist/features/install/ports/outbound/InstallTargetFs.d.ts +6 -0
  111. package/dist/features/install/ports/outbound/InstallTargetFs.js +1 -0
  112. package/dist/features/lint/adapters/inbound/CliLintHandler.d.ts +8 -0
  113. package/dist/features/lint/adapters/inbound/CliLintHandler.js +61 -0
  114. package/dist/features/lint/adapters/outbound/NodeLintFileReader.d.ts +7 -0
  115. package/dist/features/lint/adapters/outbound/NodeLintFileReader.js +165 -0
  116. package/dist/features/lint/application/RunLint.d.ts +10 -0
  117. package/dist/features/lint/application/RunLint.js +100 -0
  118. package/dist/features/lint/domain/Diagnostic.d.ts +1 -0
  119. package/dist/features/lint/domain/Diagnostic.js +2 -0
  120. package/dist/features/lint/domain/Record.d.ts +1 -0
  121. package/dist/features/lint/domain/Record.js +5 -0
  122. package/dist/features/lint/domain/Rules.d.ts +1 -0
  123. package/dist/features/lint/domain/Rules.js +2 -0
  124. package/dist/features/lint/domain/SpecParser.d.ts +1 -0
  125. package/dist/features/lint/domain/SpecParser.js +2 -0
  126. package/dist/features/lint/ports/inbound/LintCommand.d.ts +4 -0
  127. package/dist/features/lint/ports/inbound/LintCommand.js +1 -0
  128. package/dist/features/lint/ports/outbound/LintConfigPort.d.ts +4 -0
  129. package/dist/features/lint/ports/outbound/LintConfigPort.js +1 -0
  130. package/dist/features/lint/ports/outbound/LintFileReader.d.ts +10 -0
  131. package/dist/features/lint/ports/outbound/LintFileReader.js +1 -0
  132. package/dist/features/plan/adapters/inbound/CliPlanShowHandler.d.ts +8 -0
  133. package/dist/features/plan/adapters/inbound/CliPlanShowHandler.js +73 -0
  134. package/dist/features/plan/adapters/outbound/NodePlanReader.d.ts +7 -0
  135. package/dist/features/plan/adapters/outbound/NodePlanReader.js +68 -0
  136. package/dist/features/plan/application/ShowPlan.d.ts +7 -0
  137. package/dist/features/plan/application/ShowPlan.js +4 -0
  138. package/dist/features/plan/ports/inbound/PlanShowCommand.d.ts +7 -0
  139. package/dist/features/plan/ports/inbound/PlanShowCommand.js +1 -0
  140. package/dist/features/plan/ports/outbound/PlanConfigPort.d.ts +4 -0
  141. package/dist/features/plan/ports/outbound/PlanConfigPort.js +1 -0
  142. package/dist/features/plan/ports/outbound/PlanReader.d.ts +19 -0
  143. package/dist/features/plan/ports/outbound/PlanReader.js +1 -0
  144. package/dist/features/ready/adapters/inbound/CliReadyHandler.d.ts +8 -0
  145. package/dist/features/ready/adapters/inbound/CliReadyHandler.js +79 -0
  146. package/dist/features/ready/adapters/outbound/ChildProcessReadyGit.d.ts +9 -0
  147. package/dist/features/ready/adapters/outbound/ChildProcessReadyGit.js +113 -0
  148. package/dist/features/ready/adapters/outbound/NodeReadyFileSystem.d.ts +8 -0
  149. package/dist/features/ready/adapters/outbound/NodeReadyFileSystem.js +159 -0
  150. package/dist/features/ready/application/RunReady.d.ts +16 -0
  151. package/dist/features/ready/application/RunReady.js +572 -0
  152. package/dist/features/ready/domain/AggregatedRules.d.ts +16 -0
  153. package/dist/features/ready/domain/AggregatedRules.js +42 -0
  154. package/dist/features/ready/domain/MarkerParser.d.ts +17 -0
  155. package/dist/features/ready/domain/MarkerParser.js +108 -0
  156. package/dist/features/ready/domain/PartitionResolver.d.ts +1 -0
  157. package/dist/features/ready/domain/PartitionResolver.js +5 -0
  158. package/dist/features/ready/domain/ReadyInput.d.ts +6 -0
  159. package/dist/features/ready/domain/ReadyInput.js +1 -0
  160. package/dist/features/ready/domain/ReadyViolation.d.ts +38 -0
  161. package/dist/features/ready/domain/ReadyViolation.js +19 -0
  162. package/dist/features/ready/domain/Rules.d.ts +22 -0
  163. package/dist/features/ready/domain/Rules.js +243 -0
  164. package/dist/features/ready/domain/SpecDiff.d.ts +33 -0
  165. package/dist/features/ready/domain/SpecDiff.js +321 -0
  166. package/dist/features/ready/ports/inbound/ReadyCommand.d.ts +4 -0
  167. package/dist/features/ready/ports/inbound/ReadyCommand.js +1 -0
  168. package/dist/features/ready/ports/outbound/ReadyConfigPort.d.ts +4 -0
  169. package/dist/features/ready/ports/outbound/ReadyConfigPort.js +1 -0
  170. package/dist/features/ready/ports/outbound/ReadyFileReader.d.ts +12 -0
  171. package/dist/features/ready/ports/outbound/ReadyFileReader.js +1 -0
  172. package/dist/features/ready/ports/outbound/ReadyGitPort.d.ts +10 -0
  173. package/dist/features/ready/ports/outbound/ReadyGitPort.js +5 -0
  174. package/dist/features/record/adapters/inbound/CliRecordHandler.d.ts +10 -0
  175. package/dist/features/record/adapters/inbound/CliRecordHandler.js +111 -0
  176. package/dist/features/record/adapters/outbound/NodeRecordFileSystem.d.ts +9 -0
  177. package/dist/features/record/adapters/outbound/NodeRecordFileSystem.js +152 -0
  178. package/dist/features/record/application/AddRecord.d.ts +11 -0
  179. package/dist/features/record/application/AddRecord.js +84 -0
  180. package/dist/features/record/application/GetRecord.d.ts +8 -0
  181. package/dist/features/record/application/GetRecord.js +22 -0
  182. package/dist/features/record/application/ListRecords.d.ts +9 -0
  183. package/dist/features/record/application/ListRecords.js +24 -0
  184. package/dist/features/record/application/SetRecord.d.ts +11 -0
  185. package/dist/features/record/application/SetRecord.js +68 -0
  186. package/dist/features/record/domain/RecordBody.d.ts +12 -0
  187. package/dist/features/record/domain/RecordBody.js +66 -0
  188. package/dist/features/record/domain/RecordPartition.d.ts +1 -0
  189. package/dist/features/record/domain/RecordPartition.js +7 -0
  190. package/dist/features/record/domain/RecordSlice.d.ts +7 -0
  191. package/dist/features/record/domain/RecordSlice.js +1 -0
  192. package/dist/features/record/domain/RecordSummary.d.ts +11 -0
  193. package/dist/features/record/domain/RecordSummary.js +13 -0
  194. package/dist/features/record/domain/RecordWrite.d.ts +14 -0
  195. package/dist/features/record/domain/RecordWrite.js +8 -0
  196. package/dist/features/record/ports/inbound/RecordCommand.d.ts +19 -0
  197. package/dist/features/record/ports/inbound/RecordCommand.js +1 -0
  198. package/dist/features/record/ports/outbound/RecordConfigPort.d.ts +4 -0
  199. package/dist/features/record/ports/outbound/RecordConfigPort.js +1 -0
  200. package/dist/features/record/ports/outbound/RecordFileReader.d.ts +10 -0
  201. package/dist/features/record/ports/outbound/RecordFileReader.js +1 -0
  202. package/dist/features/record/ports/outbound/RecordFileWriter.d.ts +6 -0
  203. package/dist/features/record/ports/outbound/RecordFileWriter.js +1 -0
  204. package/dist/features/refresh/adapters/inbound/CliRefreshHandler.d.ts +8 -0
  205. package/dist/features/refresh/adapters/inbound/CliRefreshHandler.js +24 -0
  206. package/dist/features/refresh/adapters/outbound/ChildProcessRefreshGit.d.ts +8 -0
  207. package/dist/features/refresh/adapters/outbound/ChildProcessRefreshGit.js +118 -0
  208. package/dist/features/refresh/adapters/outbound/NodeRefreshFileReader.d.ts +7 -0
  209. package/dist/features/refresh/adapters/outbound/NodeRefreshFileReader.js +44 -0
  210. package/dist/features/refresh/adapters/outbound/SystemRefreshClock.d.ts +4 -0
  211. package/dist/features/refresh/adapters/outbound/SystemRefreshClock.js +5 -0
  212. package/dist/features/refresh/application/BuildRefreshStubs.d.ts +25 -0
  213. package/dist/features/refresh/application/BuildRefreshStubs.js +43 -0
  214. package/dist/features/refresh/domain/DiffStubs.d.ts +24 -0
  215. package/dist/features/refresh/domain/DiffStubs.js +81 -0
  216. package/dist/features/refresh/domain/Footprint.d.ts +14 -0
  217. package/dist/features/refresh/domain/Footprint.js +45 -0
  218. package/dist/features/refresh/ports/inbound/RefreshCommand.d.ts +4 -0
  219. package/dist/features/refresh/ports/inbound/RefreshCommand.js +1 -0
  220. package/dist/features/refresh/ports/outbound/RefreshClockPort.d.ts +3 -0
  221. package/dist/features/refresh/ports/outbound/RefreshClockPort.js +1 -0
  222. package/dist/features/refresh/ports/outbound/RefreshConfigPort.d.ts +4 -0
  223. package/dist/features/refresh/ports/outbound/RefreshConfigPort.js +1 -0
  224. package/dist/features/refresh/ports/outbound/RefreshGitPort.d.ts +7 -0
  225. package/dist/features/refresh/ports/outbound/RefreshGitPort.js +1 -0
  226. package/dist/features/refresh/ports/outbound/RefreshSpecPort.d.ts +9 -0
  227. package/dist/features/refresh/ports/outbound/RefreshSpecPort.js +1 -0
  228. package/dist/features/report/adapters/inbound/CliReportHandler.d.ts +8 -0
  229. package/dist/features/report/adapters/inbound/CliReportHandler.js +35 -0
  230. package/dist/features/report/adapters/outbound/NodeReportFileSystem.d.ts +7 -0
  231. package/dist/features/report/adapters/outbound/NodeReportFileSystem.js +128 -0
  232. package/dist/features/report/application/RunReport.d.ts +19 -0
  233. package/dist/features/report/application/RunReport.js +161 -0
  234. package/dist/features/report/ports/inbound/ReportCommand.d.ts +8 -0
  235. package/dist/features/report/ports/inbound/ReportCommand.js +1 -0
  236. package/dist/features/report/ports/outbound/ReportConfigPort.d.ts +4 -0
  237. package/dist/features/report/ports/outbound/ReportConfigPort.js +1 -0
  238. package/dist/features/report/ports/outbound/ReportFileReader.d.ts +7 -0
  239. package/dist/features/report/ports/outbound/ReportFileReader.js +1 -0
  240. package/dist/features/token/adapters/inbound/CliTokenHandler.d.ts +8 -0
  241. package/dist/features/token/adapters/inbound/CliTokenHandler.js +53 -0
  242. package/dist/features/token/adapters/outbound/ChildProcessTokenGit.d.ts +8 -0
  243. package/dist/features/token/adapters/outbound/ChildProcessTokenGit.js +112 -0
  244. package/dist/features/token/adapters/outbound/NodeTokenConfigReader.d.ts +5 -0
  245. package/dist/features/token/adapters/outbound/NodeTokenConfigReader.js +41 -0
  246. package/dist/features/token/application/ComputeToken.d.ts +18 -0
  247. package/dist/features/token/application/ComputeToken.js +27 -0
  248. package/dist/features/token/ports/inbound/TokenCommand.d.ts +4 -0
  249. package/dist/features/token/ports/inbound/TokenCommand.js +1 -0
  250. package/dist/features/token/ports/outbound/TokenConfigPort.d.ts +4 -0
  251. package/dist/features/token/ports/outbound/TokenConfigPort.js +1 -0
  252. package/dist/features/token/ports/outbound/TokenGitPort.d.ts +7 -0
  253. package/dist/features/token/ports/outbound/TokenGitPort.js +1 -0
  254. package/dist/shared/domain/AgentBlocklist.d.ts +5 -0
  255. package/dist/shared/domain/AgentBlocklist.js +28 -0
  256. package/dist/shared/domain/BoundaryReachability.d.ts +5 -0
  257. package/dist/shared/domain/BoundaryReachability.js +71 -0
  258. package/dist/shared/domain/CheckOutcome.d.ts +10 -0
  259. package/dist/shared/domain/CheckOutcome.js +7 -0
  260. package/dist/shared/domain/CliOutput.d.ts +10 -0
  261. package/dist/shared/domain/CliOutput.js +29 -0
  262. package/dist/shared/domain/Config.d.ts +29 -0
  263. package/dist/shared/domain/Config.js +201 -0
  264. package/dist/shared/domain/DiagnosticRegistry.d.ts +8 -0
  265. package/dist/shared/domain/DiagnosticRegistry.js +71 -0
  266. package/dist/shared/domain/Errors.d.ts +12 -0
  267. package/dist/shared/domain/Errors.js +23 -0
  268. package/dist/shared/domain/GlobMatch.d.ts +2 -0
  269. package/dist/shared/domain/GlobMatch.js +58 -0
  270. package/dist/shared/domain/LintReport.d.ts +16 -0
  271. package/dist/shared/domain/LintReport.js +11 -0
  272. package/dist/shared/domain/LintRules.d.ts +67 -0
  273. package/dist/shared/domain/LintRules.js +956 -0
  274. package/dist/shared/domain/PartitionGrammar.d.ts +4 -0
  275. package/dist/shared/domain/PartitionGrammar.js +16 -0
  276. package/dist/shared/domain/PlanFile.d.ts +28 -0
  277. package/dist/shared/domain/PlanFile.js +112 -0
  278. package/dist/shared/domain/Scope.d.ts +1 -0
  279. package/dist/shared/domain/Scope.js +3 -0
  280. package/dist/shared/domain/SpecApprovalRewrite.d.ts +23 -0
  281. package/dist/shared/domain/SpecApprovalRewrite.js +254 -0
  282. package/dist/shared/domain/SpecBlocks.d.ts +12 -0
  283. package/dist/shared/domain/SpecBlocks.js +96 -0
  284. package/dist/shared/domain/SpecRecord.d.ts +17 -0
  285. package/dist/shared/domain/SpecRecord.js +208 -0
  286. package/dist/shared/domain/TemplateFieldMetadata.d.ts +2 -0
  287. package/dist/shared/domain/TemplateFieldMetadata.js +177 -0
  288. package/dist/shared/domain/Token.d.ts +2 -0
  289. package/dist/shared/domain/Token.js +5 -0
  290. package/dist/shared/domain/WeaselWords.d.ts +3 -0
  291. package/dist/shared/domain/WeaselWords.js +32 -0
  292. package/package.json +71 -0
  293. package/rules/enforcement_registry.md +126 -0
  294. package/rules/hooks/sdd-lint-reminder.sh +33 -0
  295. package/rules/hooks/sdd-spec-read-guard.sh +73 -0
  296. package/rules/manifest.json +15 -0
  297. package/rules/review-sdd.md +9 -0
  298. package/rules/sdd-cli-usage.md +91 -0
  299. package/rules/skills/spec-driven-development/SKILL.md +554 -0
  300. package/rules/skills/spec-driven-development/data/weasel-words.json +22 -0
  301. package/rules/spec-driven-development.md +69 -0
  302. package/rules/tdd-sdd.md +127 -0
  303. package/rules/workflow-sdd.md +56 -0
  304. package/schema/sdd.config.schema.json +104 -0
@@ -0,0 +1,108 @@
1
+ /*
2
+ * Two-stage scanner for `@covers <partition>:<id> [key=value]*` markers
3
+ * (CST-007). Pure: takes a string + filename, returns Marker[] with 1-based
4
+ * line numbers. Language-agnostic: byte/string scan, no AST.
5
+ */
6
+ import { ID_TAIL_RE_SRC, PARTITION_PREFIX_RE_SRC, } from "../../../shared/domain/PartitionGrammar.js";
7
+ export const ALLOWED_MARKER_KEYS = new Set([
8
+ "compatibility_action",
9
+ ]);
10
+ /*
11
+ * Tail stops at `@` so a second `@covers` on the same line is reachable. The
12
+ * `compatibility_action=…` whitelist tokens never contain `@`, so this is a
13
+ * safe boundary in practice. Partition + id grammar is shared with Config
14
+ * validation via `PartitionGrammar`.
15
+ */
16
+ const MARKER_RE = new RegExp(`@covers\\s+(${PARTITION_PREFIX_RE_SRC}:${ID_TAIL_RE_SRC})([^@\\n\\r]*)`, "g");
17
+ /*
18
+ * Loose recogniser for `@covers`-shaped tokens that end in a valid id tail
19
+ * (`<TYPE>-<num>`) but whose prefix violates the strict partition grammar
20
+ * (e.g. uppercase segment). Used to surface near-miss advisories (OQ-017).
21
+ */
22
+ const NEAR_MISS_RE = new RegExp(`@covers\\s+([A-Za-z0-9_:-]+:[A-Z]+-\\d+)`, "g");
23
+ const STRICT_TARGET_RE = new RegExp(`^${PARTITION_PREFIX_RE_SRC}:${ID_TAIL_RE_SRC}$`);
24
+ /** `@covers`-shaped tokens that look like a marker attempt (valid id tail) but
25
+ * fail the strict partition grammar. Strictly-valid markers are excluded. */
26
+ export function parseNearMisses(text, file) {
27
+ const out = [];
28
+ const lineStarts = lineStartOffsets(text);
29
+ NEAR_MISS_RE.lastIndex = 0;
30
+ let match;
31
+ while ((match = NEAR_MISS_RE.exec(text)) !== null) {
32
+ const target = match[1];
33
+ if (STRICT_TARGET_RE.test(target)) {
34
+ continue;
35
+ }
36
+ out.push({
37
+ text: target,
38
+ file,
39
+ line: lineNumberOf(lineStarts, match.index),
40
+ });
41
+ }
42
+ return out;
43
+ }
44
+ export function parseMarkers(text, file) {
45
+ const out = [];
46
+ const lineStarts = lineStartOffsets(text);
47
+ /* Reset regex state in case a stale lastIndex leaks across calls. */
48
+ MARKER_RE.lastIndex = 0;
49
+ let match;
50
+ while ((match = MARKER_RE.exec(text)) !== null) {
51
+ const target = match[1];
52
+ const rawTail = match[2] ?? "";
53
+ /*
54
+ * CST-007: split at the LAST `:` — the id tail has no `:`, so everything
55
+ * before the rightmost `:` is the partition prefix.
56
+ */
57
+ const colon = target.lastIndexOf(":");
58
+ const partition = target.slice(0, colon);
59
+ const id = target.slice(colon + 1);
60
+ const tail = parseTail(rawTail);
61
+ const offset = match.index;
62
+ const line = lineNumberOf(lineStarts, offset);
63
+ out.push({ partition, id, tail, file, line });
64
+ }
65
+ return out;
66
+ }
67
+ function parseTail(rawTail) {
68
+ const tail = {};
69
+ for (const token of rawTail.split(/\s+/)) {
70
+ if (token.length === 0) {
71
+ continue;
72
+ }
73
+ const eq = token.indexOf("=");
74
+ if (eq < 1) {
75
+ continue;
76
+ }
77
+ const key = token.slice(0, eq);
78
+ const value = token.slice(eq + 1);
79
+ if (!ALLOWED_MARKER_KEYS.has(key)) {
80
+ continue;
81
+ }
82
+ tail[key] = value;
83
+ }
84
+ return tail;
85
+ }
86
+ function lineStartOffsets(text) {
87
+ const starts = [0];
88
+ for (let i = 0; i < text.length; i++) {
89
+ if (text[i] === "\n") {
90
+ starts.push(i + 1);
91
+ }
92
+ }
93
+ return starts;
94
+ }
95
+ function lineNumberOf(lineStarts, offset) {
96
+ let lo = 0;
97
+ let hi = lineStarts.length - 1;
98
+ while (lo < hi) {
99
+ const mid = (lo + hi + 1) >>> 1;
100
+ if (lineStarts[mid] <= offset) {
101
+ lo = mid;
102
+ }
103
+ else {
104
+ hi = mid - 1;
105
+ }
106
+ }
107
+ return lo + 1;
108
+ }
@@ -0,0 +1 @@
1
+ export { matchesGlob, fileInGlobs } from "../../../shared/domain/GlobMatch.js";
@@ -0,0 +1,5 @@
1
+ /*
2
+ * Glob-matching primitives moved to the shared kernel (used by both ready and
3
+ * lint). Re-exported here for the ready feature's existing import sites.
4
+ */
5
+ export { matchesGlob, fileInGlobs } from "../../../shared/domain/GlobMatch.js";
@@ -0,0 +1,6 @@
1
+ export interface ReadyInput {
2
+ partitionFilter?: string;
3
+ /** When set, ready additionally runs the P2.3 semver-cascade diff against
4
+ * this git ref (e.g. "HEAD~5", a tag, or a commit SHA). Off by default. */
5
+ against?: string;
6
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,38 @@
1
+ import type { ReadyViolationKindId } from "../../../shared/domain/DiagnosticRegistry.js";
2
+ export type ReadyViolationKind = ReadyViolationKindId;
3
+ export type ReadyErrorKind = "spec_parse_failed" | "config_invalid" | "unreadable_test_paths" | "internal";
4
+ export interface ReadyViolation {
5
+ kind: ReadyViolationKind;
6
+ id?: string;
7
+ partition?: string;
8
+ status?: string;
9
+ file?: string;
10
+ line?: number;
11
+ expected?: string;
12
+ actual?: string;
13
+ remediation?: string;
14
+ source?: string;
15
+ }
16
+ export interface ReadyError {
17
+ kind: ReadyErrorKind;
18
+ message: string;
19
+ file?: string;
20
+ }
21
+ /** Non-blocking advisory (OQ-011/OQ-017): surfaced in the ready envelope but
22
+ * never affects exit code. */
23
+ export interface ReadyAdvisory {
24
+ kind: "covers_near_miss";
25
+ file: string;
26
+ line: number;
27
+ text: string;
28
+ remediation: string;
29
+ }
30
+ export interface ReadyEnvelope {
31
+ ok: boolean;
32
+ error: ReadyError | null;
33
+ violations: ReadyViolation[];
34
+ advisories: ReadyAdvisory[];
35
+ }
36
+ export declare function emptyEnvelope(): ReadyEnvelope;
37
+ export declare function envelopeFromError(error: ReadyError): ReadyEnvelope;
38
+ export declare function envelopeFromViolations(violations: ReadyViolation[]): ReadyEnvelope;
@@ -0,0 +1,19 @@
1
+ /*
2
+ * Discriminated union for sdd ready output. Encoded by CTR-014; the union is
3
+ * derived from src/shared/domain/DiagnosticRegistry.READY_VIOLATION_KINDS so
4
+ * that CTR-016 / SUR-009 / INV-010 stays the single source of truth.
5
+ */
6
+ export function emptyEnvelope() {
7
+ return { ok: true, error: null, violations: [], advisories: [] };
8
+ }
9
+ export function envelopeFromError(error) {
10
+ return { ok: false, error, violations: [], advisories: [] };
11
+ }
12
+ export function envelopeFromViolations(violations) {
13
+ return {
14
+ ok: violations.length === 0,
15
+ error: null,
16
+ violations,
17
+ advisories: [],
18
+ };
19
+ }
@@ -0,0 +1,22 @@
1
+ import type { Partition } from "../../../shared/domain/Config.js";
2
+ import type { LintRecord } from "../../../shared/domain/SpecRecord.js";
3
+ import type { Marker } from "./MarkerParser.js";
4
+ import type { ReadyViolation } from "./ReadyViolation.js";
5
+ export interface PartitionView {
6
+ partition: Partition;
7
+ records: LintRecord[];
8
+ recordsById: Map<string, LintRecord>;
9
+ creditedMarkersById: Map<string, Marker[]>;
10
+ }
11
+ export declare function ruleUnapproved(view: PartitionView): ReadyViolation[];
12
+ export declare function ruleUncovered(view: PartitionView): ReadyViolation[];
13
+ export declare function ruleRemovedNoCompatTest(view: PartitionView): ReadyViolation[];
14
+ export declare function ruleRemovedCompatActionMismatch(view: PartitionView): ReadyViolation[];
15
+ export declare function ruleSurfaceUnapprovedRef(view: PartitionView): ReadyViolation[];
16
+ export interface ScannedMarker {
17
+ marker: Marker;
18
+ isPartitionConfigured: boolean;
19
+ hasMatchingRecord: boolean;
20
+ }
21
+ export declare function ruleOrphanCovers(scanned: readonly ScannedMarker[]): ReadyViolation[];
22
+ export declare function ruleUnknownPartitionCovers(scanned: readonly ScannedMarker[]): ReadyViolation[];
@@ -0,0 +1,243 @@
1
+ import { fileInGlobs } from "./PartitionResolver.js";
2
+ const NORMATIVE = new Set([
3
+ "Behavior",
4
+ "Invariant",
5
+ "Contract",
6
+ "Scenario",
7
+ "NFR",
8
+ "Constraint",
9
+ "Policy",
10
+ "Migration",
11
+ "Delta",
12
+ "GeneratedArtifact",
13
+ "ExternalDependency",
14
+ "LocalizationContract",
15
+ "Surface",
16
+ ]);
17
+ /*
18
+ * Surface is normative but exempt from individual coverage requirements; its
19
+ * members carry the obligation. Matches lint's OBLIGATIONLESS_TEMPLATES.
20
+ */
21
+ const COVERAGE_EXEMPT_TEMPLATES = new Set(["Surface"]);
22
+ export function ruleUnapproved(view) {
23
+ const out = [];
24
+ for (const rec of view.records) {
25
+ if (!isNormative(rec)) {
26
+ continue;
27
+ }
28
+ const status = rec.lifecycleStatus;
29
+ if (status !== "draft" && status !== "proposed") {
30
+ continue;
31
+ }
32
+ if (fileInGlobs(rec.file, view.partition.sandboxPaths)) {
33
+ continue;
34
+ }
35
+ out.push({
36
+ kind: "unapproved",
37
+ id: rec.id,
38
+ partition: view.partition.name,
39
+ status,
40
+ file: rec.file,
41
+ line: rec.line,
42
+ remediation: "promote via `sdd approve` or move into sandbox_paths",
43
+ });
44
+ }
45
+ return out;
46
+ }
47
+ export function ruleUncovered(view) {
48
+ const out = [];
49
+ for (const rec of view.records) {
50
+ if (!isNormative(rec)) {
51
+ continue;
52
+ }
53
+ if (rec.template !== null && COVERAGE_EXEMPT_TEMPLATES.has(rec.template)) {
54
+ continue;
55
+ }
56
+ if (rec.lifecycleStatus !== "approved" &&
57
+ rec.lifecycleStatus !== "deprecated") {
58
+ continue;
59
+ }
60
+ if (isNotApplicableTestObligation(rec)) {
61
+ continue;
62
+ }
63
+ if ((view.creditedMarkersById.get(rec.id) ?? []).length > 0) {
64
+ continue;
65
+ }
66
+ out.push({
67
+ kind: "uncovered",
68
+ id: rec.id,
69
+ partition: view.partition.name,
70
+ status: rec.lifecycleStatus,
71
+ file: rec.file,
72
+ line: rec.line,
73
+ remediation: "add `@covers " +
74
+ rec.id +
75
+ "` next to a test for this ID, or set `Test obligation: not_applicable + reason`",
76
+ });
77
+ }
78
+ return out;
79
+ }
80
+ export function ruleRemovedNoCompatTest(view) {
81
+ const out = [];
82
+ for (const rec of view.records) {
83
+ if (!isNormative(rec)) {
84
+ continue;
85
+ }
86
+ if (rec.lifecycleStatus !== "removed") {
87
+ continue;
88
+ }
89
+ const markers = view.creditedMarkersById.get(rec.id) ?? [];
90
+ const haveCompat = markers.some((m) => typeof m.tail.compatibility_action === "string");
91
+ if (haveCompat) {
92
+ continue;
93
+ }
94
+ out.push({
95
+ kind: "removed_no_compat_test",
96
+ id: rec.id,
97
+ partition: view.partition.name,
98
+ status: rec.lifecycleStatus,
99
+ file: rec.file,
100
+ line: rec.line,
101
+ remediation: "add a test with `@covers " +
102
+ rec.id +
103
+ " compatibility_action=<action>`",
104
+ });
105
+ }
106
+ return out;
107
+ }
108
+ export function ruleRemovedCompatActionMismatch(view) {
109
+ const out = [];
110
+ for (const rec of view.records) {
111
+ if (!isNormative(rec)) {
112
+ continue;
113
+ }
114
+ if (rec.lifecycleStatus !== "removed") {
115
+ continue;
116
+ }
117
+ const expected = readCompatibilityAction(rec);
118
+ if (expected === null) {
119
+ continue;
120
+ }
121
+ const markers = view.creditedMarkersById.get(rec.id) ?? [];
122
+ for (const m of markers) {
123
+ const actual = m.tail.compatibility_action;
124
+ if (typeof actual !== "string") {
125
+ continue;
126
+ }
127
+ if (actual === expected) {
128
+ continue;
129
+ }
130
+ out.push({
131
+ kind: "removed_compat_action_mismatch",
132
+ id: rec.id,
133
+ partition: view.partition.name,
134
+ status: rec.lifecycleStatus,
135
+ file: m.file,
136
+ line: m.line,
137
+ expected,
138
+ actual,
139
+ remediation: "align marker's compatibility_action= with the spec's compatibility_action",
140
+ });
141
+ }
142
+ }
143
+ return out;
144
+ }
145
+ export function ruleSurfaceUnapprovedRef(view) {
146
+ const out = [];
147
+ for (const rec of view.records) {
148
+ if (rec.template !== "Surface") {
149
+ continue;
150
+ }
151
+ const status = rec.lifecycleStatus;
152
+ if (status !== "approved" &&
153
+ status !== "deprecated" &&
154
+ status !== "removed") {
155
+ continue;
156
+ }
157
+ const members = readMembers(rec);
158
+ for (const memberId of members) {
159
+ const member = view.recordsById.get(memberId);
160
+ if (member === undefined) {
161
+ continue;
162
+ }
163
+ const ms = member.lifecycleStatus;
164
+ if (ms === "approved" || ms === "deprecated" || ms === "removed") {
165
+ continue;
166
+ }
167
+ out.push({
168
+ kind: "surface_unapproved_ref",
169
+ id: rec.id,
170
+ partition: view.partition.name,
171
+ status,
172
+ file: rec.file,
173
+ line: rec.line,
174
+ remediation: `member ${memberId} is ${ms ?? "missing-status"}; approve it before approving Surface ${rec.id}`,
175
+ });
176
+ }
177
+ }
178
+ return out;
179
+ }
180
+ export function ruleOrphanCovers(scanned) {
181
+ const out = [];
182
+ for (const s of scanned) {
183
+ if (!s.isPartitionConfigured) {
184
+ continue;
185
+ } /* covered by ruleUnknownPartitionCovers */
186
+ if (s.hasMatchingRecord) {
187
+ continue;
188
+ }
189
+ out.push({
190
+ kind: "orphan_covers",
191
+ id: `${s.marker.partition}:${s.marker.id}`,
192
+ partition: s.marker.partition,
193
+ file: s.marker.file,
194
+ line: s.marker.line,
195
+ remediation: "marker references an ID not present in that partition's spec; remove the marker or add the ID",
196
+ });
197
+ }
198
+ return out;
199
+ }
200
+ export function ruleUnknownPartitionCovers(scanned) {
201
+ const out = [];
202
+ for (const s of scanned) {
203
+ if (s.isPartitionConfigured) {
204
+ continue;
205
+ }
206
+ out.push({
207
+ kind: "unknown_partition_covers",
208
+ id: `${s.marker.partition}:${s.marker.id}`,
209
+ partition: s.marker.partition,
210
+ file: s.marker.file,
211
+ line: s.marker.line,
212
+ remediation: "configure the partition in `.sdd/config.json#partitions` or fix the marker prefix",
213
+ });
214
+ }
215
+ return out;
216
+ }
217
+ function isNormative(rec) {
218
+ return rec.template !== null && NORMATIVE.has(rec.template);
219
+ }
220
+ function isNotApplicableTestObligation(rec) {
221
+ const v = rec.parsed.test_obligation;
222
+ if (typeof v === "string" && v.startsWith("not_applicable")) {
223
+ return true;
224
+ }
225
+ if (isObject(v) && v.not_applicable !== undefined) {
226
+ return true;
227
+ }
228
+ return false;
229
+ }
230
+ function readCompatibilityAction(rec) {
231
+ const ca = rec.parsed.compatibility_action;
232
+ return typeof ca === "string" ? ca : null;
233
+ }
234
+ function readMembers(rec) {
235
+ const m = rec.parsed.members;
236
+ if (!Array.isArray(m)) {
237
+ return [];
238
+ }
239
+ return m.filter((v) => typeof v === "string");
240
+ }
241
+ function isObject(value) {
242
+ return typeof value === "object" && value !== null && !Array.isArray(value);
243
+ }
@@ -0,0 +1,33 @@
1
+ import type { LintRecord } from "../../../shared/domain/SpecRecord.js";
2
+ export type DiffClassification = "predicate_change" | "content_change" | "none";
3
+ export interface ClassifiedDiff {
4
+ id: string;
5
+ template: string | null;
6
+ classification: DiffClassification;
7
+ changedFields: string[];
8
+ }
9
+ /** Per-ID diff: classify each ID present in `curr` against `prev`. IDs new to
10
+ * `curr` are classified as "content_change" (additive). IDs removed in
11
+ * `curr` are not returned (the consumer detects removal separately via
12
+ * lifecycle.status flips, which lint already covers). */
13
+ export declare function classifyDiff(prev: ReadonlyArray<LintRecord>, curr: ReadonlyArray<LintRecord>): ClassifiedDiff[];
14
+ /** Required bump for a single Surface, computed by walking reachable IDs. */
15
+ export type RequiredBump = "patch" | "minor" | "major";
16
+ export interface SurfaceBumpAnalysis {
17
+ surfaceId: string;
18
+ declaredVersion: string | null;
19
+ prevDeclaredVersion: string | null;
20
+ required: RequiredBump;
21
+ drivenBy: ClassifiedDiff[];
22
+ }
23
+ export declare function requiredSurfaceBumps(prev: ReadonlyArray<LintRecord>, curr: ReadonlyArray<LintRecord>, diffs: ReadonlyArray<ClassifiedDiff>): SurfaceBumpAnalysis[];
24
+ export interface GAStructuralDiff {
25
+ surfaceId: string;
26
+ generatedArtifactId: string;
27
+ classification: Exclude<DiffClassification, "none">;
28
+ }
29
+ export declare function generatedArtifactStructuralDiffs(prev: ReadonlyArray<LintRecord>, curr: ReadonlyArray<LintRecord>, diffs: ReadonlyArray<ClassifiedDiff>): GAStructuralDiff[];
30
+ /** Compare two semver strings ("0.3.0" vs "0.4.0") and return the actual bump.
31
+ * Returns null if either string is unparseable. */
32
+ export declare function actualBump(prev: string | null, curr: string | null): RequiredBump | null;
33
+ export declare function bumpAtLeast(actual: RequiredBump | null, required: RequiredBump): boolean;