@rsaglobaltech/specgate 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. package/CHANGELOG.md +1016 -0
  2. package/README.md +148 -0
  3. package/bin/specgate.js +2 -0
  4. package/bin/specgate.ts +383 -0
  5. package/dist/bin/specgate.js +342 -0
  6. package/dist/bin/specgate.js.map +1 -0
  7. package/dist/packages/core/src/application/AddRequirementUseCase.js +24 -0
  8. package/dist/packages/core/src/application/AddRequirementUseCase.js.map +1 -0
  9. package/dist/packages/core/src/application/ArchiveChangeUseCase.js +185 -0
  10. package/dist/packages/core/src/application/ArchiveChangeUseCase.js.map +1 -0
  11. package/dist/packages/core/src/application/CheckAgainstLockUseCase.js +134 -0
  12. package/dist/packages/core/src/application/CheckAgainstLockUseCase.js.map +1 -0
  13. package/dist/packages/core/src/application/GenerateAgentPromptUseCase.js +25 -0
  14. package/dist/packages/core/src/application/GenerateAgentPromptUseCase.js.map +1 -0
  15. package/dist/packages/core/src/application/GeneratePlanUseCase.js +135 -0
  16. package/dist/packages/core/src/application/GeneratePlanUseCase.js.map +1 -0
  17. package/dist/packages/core/src/application/LinkRequirementUseCase.js +25 -0
  18. package/dist/packages/core/src/application/LinkRequirementUseCase.js.map +1 -0
  19. package/dist/packages/core/src/application/RemovePackUseCase.js +28 -0
  20. package/dist/packages/core/src/application/RemovePackUseCase.js.map +1 -0
  21. package/dist/packages/core/src/application/UpdateRequirementStatusUseCase.js +37 -0
  22. package/dist/packages/core/src/application/UpdateRequirementStatusUseCase.js.map +1 -0
  23. package/dist/packages/core/src/application/ValidateChangeUseCase.js +86 -0
  24. package/dist/packages/core/src/application/ValidateChangeUseCase.js.map +1 -0
  25. package/dist/packages/core/src/application/ValidateProjectUseCase.js +101 -0
  26. package/dist/packages/core/src/application/ValidateProjectUseCase.js.map +1 -0
  27. package/dist/packages/core/src/application/ports/IDomainPackRepository.js +3 -0
  28. package/dist/packages/core/src/application/ports/IDomainPackRepository.js.map +1 -0
  29. package/dist/packages/core/src/application/ports/IHarnessConfigRepository.js +3 -0
  30. package/dist/packages/core/src/application/ports/IHarnessConfigRepository.js.map +1 -0
  31. package/dist/packages/core/src/application/ports/ILockfileRepository.js +3 -0
  32. package/dist/packages/core/src/application/ports/ILockfileRepository.js.map +1 -0
  33. package/dist/packages/core/src/application/ports/IManifestRepository.js +3 -0
  34. package/dist/packages/core/src/application/ports/IManifestRepository.js.map +1 -0
  35. package/dist/packages/core/src/application/ports/IProjectRepository.js +3 -0
  36. package/dist/packages/core/src/application/ports/IProjectRepository.js.map +1 -0
  37. package/dist/packages/core/src/application/ports/IRequirementGraphRepository.js +3 -0
  38. package/dist/packages/core/src/application/ports/IRequirementGraphRepository.js.map +1 -0
  39. package/dist/packages/core/src/application/ports/ITraceabilityRepository.js +3 -0
  40. package/dist/packages/core/src/application/ports/ITraceabilityRepository.js.map +1 -0
  41. package/dist/packages/core/src/domain/AgentPrompt.js +79 -0
  42. package/dist/packages/core/src/domain/AgentPrompt.js.map +1 -0
  43. package/dist/packages/core/src/domain/ArchivePlan.js +26 -0
  44. package/dist/packages/core/src/domain/ArchivePlan.js.map +1 -0
  45. package/dist/packages/core/src/domain/AuthoringScope.js +48 -0
  46. package/dist/packages/core/src/domain/AuthoringScope.js.map +1 -0
  47. package/dist/packages/core/src/domain/ChangeTemplates.js +133 -0
  48. package/dist/packages/core/src/domain/ChangeTemplates.js.map +1 -0
  49. package/dist/packages/core/src/domain/CucumberMessages.js +256 -0
  50. package/dist/packages/core/src/domain/CucumberMessages.js.map +1 -0
  51. package/dist/packages/core/src/domain/DeclaredArtifacts.js +117 -0
  52. package/dist/packages/core/src/domain/DeclaredArtifacts.js.map +1 -0
  53. package/dist/packages/core/src/domain/DeltaSpec.js +219 -0
  54. package/dist/packages/core/src/domain/DeltaSpec.js.map +1 -0
  55. package/dist/packages/core/src/domain/Diagnostic.js +75 -0
  56. package/dist/packages/core/src/domain/Diagnostic.js.map +1 -0
  57. package/dist/packages/core/src/domain/DomainPack.js +62 -0
  58. package/dist/packages/core/src/domain/DomainPack.js.map +1 -0
  59. package/dist/packages/core/src/domain/EmptyAttempt.js +60 -0
  60. package/dist/packages/core/src/domain/EmptyAttempt.js.map +1 -0
  61. package/dist/packages/core/src/domain/FileChangeSet.js +37 -0
  62. package/dist/packages/core/src/domain/FileChangeSet.js.map +1 -0
  63. package/dist/packages/core/src/domain/Gherkin.js +272 -0
  64. package/dist/packages/core/src/domain/Gherkin.js.map +1 -0
  65. package/dist/packages/core/src/domain/GherkinDialects.js +97 -0
  66. package/dist/packages/core/src/domain/GherkinDialects.js.map +1 -0
  67. package/dist/packages/core/src/domain/GherkinQuality.js +160 -0
  68. package/dist/packages/core/src/domain/GherkinQuality.js.map +1 -0
  69. package/dist/packages/core/src/domain/GherkinTags.js +119 -0
  70. package/dist/packages/core/src/domain/GherkinTags.js.map +1 -0
  71. package/dist/packages/core/src/domain/GitSafety.js +77 -0
  72. package/dist/packages/core/src/domain/GitSafety.js.map +1 -0
  73. package/dist/packages/core/src/domain/HarnessConfig.js +58 -0
  74. package/dist/packages/core/src/domain/HarnessConfig.js.map +1 -0
  75. package/dist/packages/core/src/domain/HarnessReport.js +162 -0
  76. package/dist/packages/core/src/domain/HarnessReport.js.map +1 -0
  77. package/dist/packages/core/src/domain/HarnessRun.js +154 -0
  78. package/dist/packages/core/src/domain/HarnessRun.js.map +1 -0
  79. package/dist/packages/core/src/domain/InboundChange.js +127 -0
  80. package/dist/packages/core/src/domain/InboundChange.js.map +1 -0
  81. package/dist/packages/core/src/domain/Language.js +112 -0
  82. package/dist/packages/core/src/domain/Language.js.map +1 -0
  83. package/dist/packages/core/src/domain/Lockfile.js +64 -0
  84. package/dist/packages/core/src/domain/Lockfile.js.map +1 -0
  85. package/dist/packages/core/src/domain/PackContribution.js +106 -0
  86. package/dist/packages/core/src/domain/PackContribution.js.map +1 -0
  87. package/dist/packages/core/src/domain/PackDelta.js +298 -0
  88. package/dist/packages/core/src/domain/PackDelta.js.map +1 -0
  89. package/dist/packages/core/src/domain/PackSpec.js +481 -0
  90. package/dist/packages/core/src/domain/PackSpec.js.map +1 -0
  91. package/dist/packages/core/src/domain/ProfileMatch.js +87 -0
  92. package/dist/packages/core/src/domain/ProfileMatch.js.map +1 -0
  93. package/dist/packages/core/src/domain/Reconciliation.js +72 -0
  94. package/dist/packages/core/src/domain/Reconciliation.js.map +1 -0
  95. package/dist/packages/core/src/domain/RequirementGraph.js +197 -0
  96. package/dist/packages/core/src/domain/RequirementGraph.js.map +1 -0
  97. package/dist/packages/core/src/domain/RequirementPlan.js +85 -0
  98. package/dist/packages/core/src/domain/RequirementPlan.js.map +1 -0
  99. package/dist/packages/core/src/domain/RequirementReadiness.js +115 -0
  100. package/dist/packages/core/src/domain/RequirementReadiness.js.map +1 -0
  101. package/dist/packages/core/src/domain/RequirementSyntax.js +91 -0
  102. package/dist/packages/core/src/domain/RequirementSyntax.js.map +1 -0
  103. package/dist/packages/core/src/domain/ResumeState.js +115 -0
  104. package/dist/packages/core/src/domain/ResumeState.js.map +1 -0
  105. package/dist/packages/core/src/domain/RunBudget.js +103 -0
  106. package/dist/packages/core/src/domain/RunBudget.js.map +1 -0
  107. package/dist/packages/core/src/domain/SpecDiff.js +48 -0
  108. package/dist/packages/core/src/domain/SpecDiff.js.map +1 -0
  109. package/dist/packages/core/src/domain/SpecParser.js +406 -0
  110. package/dist/packages/core/src/domain/SpecParser.js.map +1 -0
  111. package/dist/packages/core/src/domain/SpecopsManifest.js +90 -0
  112. package/dist/packages/core/src/domain/SpecopsManifest.js.map +1 -0
  113. package/dist/packages/core/src/domain/TraceabilityFormat.js +317 -0
  114. package/dist/packages/core/src/domain/TraceabilityFormat.js.map +1 -0
  115. package/dist/packages/core/src/domain/TraceabilityMatrix.js +200 -0
  116. package/dist/packages/core/src/domain/TraceabilityMatrix.js.map +1 -0
  117. package/dist/packages/core/src/domain/TraceabilityMerge.js +180 -0
  118. package/dist/packages/core/src/domain/TraceabilityMerge.js.map +1 -0
  119. package/dist/packages/core/src/domain/ValidationReport.js +53 -0
  120. package/dist/packages/core/src/domain/ValidationReport.js.map +1 -0
  121. package/dist/packages/core/src/domain/ValueAnnotations.js +138 -0
  122. package/dist/packages/core/src/domain/ValueAnnotations.js.map +1 -0
  123. package/dist/packages/core/src/domain/WriteScope.js +155 -0
  124. package/dist/packages/core/src/domain/WriteScope.js.map +1 -0
  125. package/dist/packages/core/src/domain/YamlLite.js +226 -0
  126. package/dist/packages/core/src/domain/YamlLite.js.map +1 -0
  127. package/dist/packages/core/src/index.js +120 -0
  128. package/dist/packages/core/src/index.js.map +1 -0
  129. package/dist/packages/core/src/infrastructure/ChangeWorkspace.js +276 -0
  130. package/dist/packages/core/src/infrastructure/ChangeWorkspace.js.map +1 -0
  131. package/dist/packages/core/src/infrastructure/ConsoleReporter.js +19 -0
  132. package/dist/packages/core/src/infrastructure/ConsoleReporter.js.map +1 -0
  133. package/dist/packages/core/src/infrastructure/DirectorySnapshot.js +106 -0
  134. package/dist/packages/core/src/infrastructure/DirectorySnapshot.js.map +1 -0
  135. package/dist/packages/core/src/infrastructure/DiskDomainPackRepository.js +57 -0
  136. package/dist/packages/core/src/infrastructure/DiskDomainPackRepository.js.map +1 -0
  137. package/dist/packages/core/src/infrastructure/DiskHarnessConfigRepository.js +58 -0
  138. package/dist/packages/core/src/infrastructure/DiskHarnessConfigRepository.js.map +1 -0
  139. package/dist/packages/core/src/infrastructure/DiskLanguageRepository.js +69 -0
  140. package/dist/packages/core/src/infrastructure/DiskLanguageRepository.js.map +1 -0
  141. package/dist/packages/core/src/infrastructure/DiskLockfileRepository.js +64 -0
  142. package/dist/packages/core/src/infrastructure/DiskLockfileRepository.js.map +1 -0
  143. package/dist/packages/core/src/infrastructure/DiskManifestRepository.js +88 -0
  144. package/dist/packages/core/src/infrastructure/DiskManifestRepository.js.map +1 -0
  145. package/dist/packages/core/src/infrastructure/DiskPackDeltaRepository.js +138 -0
  146. package/dist/packages/core/src/infrastructure/DiskPackDeltaRepository.js.map +1 -0
  147. package/dist/packages/core/src/infrastructure/DiskPackRepository.js +130 -0
  148. package/dist/packages/core/src/infrastructure/DiskPackRepository.js.map +1 -0
  149. package/dist/packages/core/src/infrastructure/DiskProjectRepository.js +127 -0
  150. package/dist/packages/core/src/infrastructure/DiskProjectRepository.js.map +1 -0
  151. package/dist/packages/core/src/infrastructure/DiskRequirementGraphRepository.js +124 -0
  152. package/dist/packages/core/src/infrastructure/DiskRequirementGraphRepository.js.map +1 -0
  153. package/dist/packages/core/src/infrastructure/DiskTraceabilityRepository.js +53 -0
  154. package/dist/packages/core/src/infrastructure/DiskTraceabilityRepository.js.map +1 -0
  155. package/dist/packages/core/src/infrastructure/GitContributionStager.js +99 -0
  156. package/dist/packages/core/src/infrastructure/GitContributionStager.js.map +1 -0
  157. package/dist/packages/core/src/infrastructure/GitMergeDriver.js +103 -0
  158. package/dist/packages/core/src/infrastructure/GitMergeDriver.js.map +1 -0
  159. package/dist/packages/core/src/infrastructure/HarnessConfigFile.js +348 -0
  160. package/dist/packages/core/src/infrastructure/HarnessConfigFile.js.map +1 -0
  161. package/dist/packages/core/src/infrastructure/PackChangeDeposit.js +106 -0
  162. package/dist/packages/core/src/infrastructure/PackChangeDeposit.js.map +1 -0
  163. package/dist/packages/core/src/infrastructure/RemotePackResolver.js +181 -0
  164. package/dist/packages/core/src/infrastructure/RemotePackResolver.js.map +1 -0
  165. package/dist/packages/core/src/infrastructure/SpecopsConfigFile.js +94 -0
  166. package/dist/packages/core/src/infrastructure/SpecopsConfigFile.js.map +1 -0
  167. package/dist/packages/core/test/unit/authoring-scope.test.js +102 -0
  168. package/dist/packages/core/test/unit/authoring-scope.test.js.map +1 -0
  169. package/dist/packages/core/test/unit/change-templates.test.js +96 -0
  170. package/dist/packages/core/test/unit/change-templates.test.js.map +1 -0
  171. package/dist/packages/core/test/unit/cucumber-messages.test.js +232 -0
  172. package/dist/packages/core/test/unit/cucumber-messages.test.js.map +1 -0
  173. package/dist/packages/core/test/unit/declared-artifacts.test.js +124 -0
  174. package/dist/packages/core/test/unit/declared-artifacts.test.js.map +1 -0
  175. package/dist/packages/core/test/unit/empty-attempt.test.js +79 -0
  176. package/dist/packages/core/test/unit/empty-attempt.test.js.map +1 -0
  177. package/dist/packages/core/test/unit/gherkin-dialects.test.js +115 -0
  178. package/dist/packages/core/test/unit/gherkin-dialects.test.js.map +1 -0
  179. package/dist/packages/core/test/unit/gherkin-keyword-case.test.js +110 -0
  180. package/dist/packages/core/test/unit/gherkin-keyword-case.test.js.map +1 -0
  181. package/dist/packages/core/test/unit/gherkin-quality.test.js +151 -0
  182. package/dist/packages/core/test/unit/gherkin-quality.test.js.map +1 -0
  183. package/dist/packages/core/test/unit/gherkin-tags.test.js +127 -0
  184. package/dist/packages/core/test/unit/gherkin-tags.test.js.map +1 -0
  185. package/dist/packages/core/test/unit/git-safety.test.js +104 -0
  186. package/dist/packages/core/test/unit/git-safety.test.js.map +1 -0
  187. package/dist/packages/core/test/unit/harness-report.test.js +192 -0
  188. package/dist/packages/core/test/unit/harness-report.test.js.map +1 -0
  189. package/dist/packages/core/test/unit/harness-roles.test.js +86 -0
  190. package/dist/packages/core/test/unit/harness-roles.test.js.map +1 -0
  191. package/dist/packages/core/test/unit/inbound-change.test.js +145 -0
  192. package/dist/packages/core/test/unit/inbound-change.test.js.map +1 -0
  193. package/dist/packages/core/test/unit/matrix-dependencies.test.js +100 -0
  194. package/dist/packages/core/test/unit/matrix-dependencies.test.js.map +1 -0
  195. package/dist/packages/core/test/unit/profile-match.test.js +115 -0
  196. package/dist/packages/core/test/unit/profile-match.test.js.map +1 -0
  197. package/dist/packages/core/test/unit/reconciliation.test.js +112 -0
  198. package/dist/packages/core/test/unit/reconciliation.test.js.map +1 -0
  199. package/dist/packages/core/test/unit/requirement-readiness.test.js +161 -0
  200. package/dist/packages/core/test/unit/requirement-readiness.test.js.map +1 -0
  201. package/dist/packages/core/test/unit/resume-state.test.js +124 -0
  202. package/dist/packages/core/test/unit/resume-state.test.js.map +1 -0
  203. package/dist/packages/core/test/unit/run-budget.test.js +113 -0
  204. package/dist/packages/core/test/unit/run-budget.test.js.map +1 -0
  205. package/dist/packages/core/test/unit/traceability-merge.test.js +159 -0
  206. package/dist/packages/core/test/unit/traceability-merge.test.js.map +1 -0
  207. package/dist/packages/core/test/unit/validate-project.test.js +156 -0
  208. package/dist/packages/core/test/unit/validate-project.test.js.map +1 -0
  209. package/dist/packages/core/test/unit/value-annotations.test.js +149 -0
  210. package/dist/packages/core/test/unit/value-annotations.test.js.map +1 -0
  211. package/dist/packages/core/test/unit/write-scope.test.js +165 -0
  212. package/dist/packages/core/test/unit/write-scope.test.js.map +1 -0
  213. package/dist/packages/core/test/unit/yaml-lite.test.js +78 -0
  214. package/dist/packages/core/test/unit/yaml-lite.test.js.map +1 -0
  215. package/dist/scripts/adopt_project.js +11 -0
  216. package/dist/scripts/adopt_project.js.map +1 -0
  217. package/dist/scripts/agents/commands.js +100 -0
  218. package/dist/scripts/agents/commands.js.map +1 -0
  219. package/dist/scripts/agents/init.js +482 -0
  220. package/dist/scripts/agents/init.js.map +1 -0
  221. package/dist/scripts/alm/cli.js +154 -0
  222. package/dist/scripts/alm/cli.js.map +1 -0
  223. package/dist/scripts/alm/clients.js +30 -0
  224. package/dist/scripts/alm/clients.js.map +1 -0
  225. package/dist/scripts/alm/core.js +258 -0
  226. package/dist/scripts/alm/core.js.map +1 -0
  227. package/dist/scripts/alm/port.js +116 -0
  228. package/dist/scripts/alm/port.js.map +1 -0
  229. package/dist/scripts/alm/providers/azure.js +79 -0
  230. package/dist/scripts/alm/providers/azure.js.map +1 -0
  231. package/dist/scripts/alm/providers/github.js +124 -0
  232. package/dist/scripts/alm/providers/github.js.map +1 -0
  233. package/dist/scripts/alm/providers/http-client.js +47 -0
  234. package/dist/scripts/alm/providers/http-client.js.map +1 -0
  235. package/dist/scripts/alm/providers/index.js +107 -0
  236. package/dist/scripts/alm/providers/index.js.map +1 -0
  237. package/dist/scripts/alm/providers/jira.js +129 -0
  238. package/dist/scripts/alm/providers/jira.js.map +1 -0
  239. package/dist/scripts/bundle_pack.js +10 -0
  240. package/dist/scripts/bundle_pack.js.map +1 -0
  241. package/dist/scripts/change/archive.js +68 -0
  242. package/dist/scripts/change/archive.js.map +1 -0
  243. package/dist/scripts/change/artifacts.js +143 -0
  244. package/dist/scripts/change/artifacts.js.map +1 -0
  245. package/dist/scripts/change/cli.js +39 -0
  246. package/dist/scripts/change/cli.js.map +1 -0
  247. package/dist/scripts/change/delta.js +20 -0
  248. package/dist/scripts/change/delta.js.map +1 -0
  249. package/dist/scripts/change/instructions.js +339 -0
  250. package/dist/scripts/change/instructions.js.map +1 -0
  251. package/dist/scripts/ci_init.js +12 -0
  252. package/dist/scripts/ci_init.js.map +1 -0
  253. package/dist/scripts/cli/commands/alm/PullCommand.js +238 -0
  254. package/dist/scripts/cli/commands/alm/PullCommand.js.map +1 -0
  255. package/dist/scripts/cli/commands/change/ChangeCommand.js +867 -0
  256. package/dist/scripts/cli/commands/change/ChangeCommand.js.map +1 -0
  257. package/dist/scripts/cli/commands/config/CiInitCommand.js +144 -0
  258. package/dist/scripts/cli/commands/config/CiInitCommand.js.map +1 -0
  259. package/dist/scripts/cli/commands/config/CompletionCommand.js +160 -0
  260. package/dist/scripts/cli/commands/config/CompletionCommand.js.map +1 -0
  261. package/dist/scripts/cli/commands/config/ConfigInitCommand.js +108 -0
  262. package/dist/scripts/cli/commands/config/ConfigInitCommand.js.map +1 -0
  263. package/dist/scripts/cli/commands/config/ConfigSetCommand.js +166 -0
  264. package/dist/scripts/cli/commands/config/ConfigSetCommand.js.map +1 -0
  265. package/dist/scripts/cli/commands/config/GenAgentContractCommand.js +212 -0
  266. package/dist/scripts/cli/commands/config/GenAgentContractCommand.js.map +1 -0
  267. package/dist/scripts/cli/commands/harness/RunCommand.js +1922 -0
  268. package/dist/scripts/cli/commands/harness/RunCommand.js.map +1 -0
  269. package/dist/scripts/cli/commands/mcp/McpInstallCommand.js +114 -0
  270. package/dist/scripts/cli/commands/mcp/McpInstallCommand.js.map +1 -0
  271. package/dist/scripts/cli/commands/mcp/index.js +29 -0
  272. package/dist/scripts/cli/commands/mcp/index.js.map +1 -0
  273. package/dist/scripts/cli/commands/pack/BundlePackCommand.js +59 -0
  274. package/dist/scripts/cli/commands/pack/BundlePackCommand.js.map +1 -0
  275. package/dist/scripts/cli/commands/pack/ExpandDomainPackCommand.js +559 -0
  276. package/dist/scripts/cli/commands/pack/ExpandDomainPackCommand.js.map +1 -0
  277. package/dist/scripts/cli/commands/pack/InferPackCommand.js +304 -0
  278. package/dist/scripts/cli/commands/pack/InferPackCommand.js.map +1 -0
  279. package/dist/scripts/cli/commands/pack/InitPackCommand.js +368 -0
  280. package/dist/scripts/cli/commands/pack/InitPackCommand.js.map +1 -0
  281. package/dist/scripts/cli/commands/pack/LintPackCommand.js +631 -0
  282. package/dist/scripts/cli/commands/pack/LintPackCommand.js.map +1 -0
  283. package/dist/scripts/cli/commands/pack/pack-args.js +83 -0
  284. package/dist/scripts/cli/commands/pack/pack-args.js.map +1 -0
  285. package/dist/scripts/cli/commands/project/AdoptCommand.js +414 -0
  286. package/dist/scripts/cli/commands/project/AdoptCommand.js.map +1 -0
  287. package/dist/scripts/cli/commands/project/InitFromPackCommand.js +188 -0
  288. package/dist/scripts/cli/commands/project/InitFromPackCommand.js.map +1 -0
  289. package/dist/scripts/cli/commands/project/InitProjectCommand.js +791 -0
  290. package/dist/scripts/cli/commands/project/InitProjectCommand.js.map +1 -0
  291. package/dist/scripts/cli/commands/project/OnboardCommand.js +655 -0
  292. package/dist/scripts/cli/commands/project/OnboardCommand.js.map +1 -0
  293. package/dist/scripts/cli/commands/project/UpdateCommand.js +206 -0
  294. package/dist/scripts/cli/commands/project/UpdateCommand.js.map +1 -0
  295. package/dist/scripts/cli/commands/project/WizardCommand.js +166 -0
  296. package/dist/scripts/cli/commands/project/WizardCommand.js.map +1 -0
  297. package/dist/scripts/cli/commands/quality/DoctorCommand.js +553 -0
  298. package/dist/scripts/cli/commands/quality/DoctorCommand.js.map +1 -0
  299. package/dist/scripts/cli/commands/quality/FixCommand.js +201 -0
  300. package/dist/scripts/cli/commands/quality/FixCommand.js.map +1 -0
  301. package/dist/scripts/cli/commands/quality/LicenseCheckCommand.js +187 -0
  302. package/dist/scripts/cli/commands/quality/LicenseCheckCommand.js.map +1 -0
  303. package/dist/scripts/cli/commands/quality/ReportCommand.js +557 -0
  304. package/dist/scripts/cli/commands/quality/ReportCommand.js.map +1 -0
  305. package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js +764 -0
  306. package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js.map +1 -0
  307. package/dist/scripts/cli/commands/spec/DoneCommand.js +116 -0
  308. package/dist/scripts/cli/commands/spec/DoneCommand.js.map +1 -0
  309. package/dist/scripts/cli/commands/spec/PlanCommand.js +397 -0
  310. package/dist/scripts/cli/commands/spec/PlanCommand.js.map +1 -0
  311. package/dist/scripts/cli/commands/spec/ReqCommand.js +303 -0
  312. package/dist/scripts/cli/commands/spec/ReqCommand.js.map +1 -0
  313. package/dist/scripts/cli/commands/spec/StatusCommand.js +206 -0
  314. package/dist/scripts/cli/commands/spec/StatusCommand.js.map +1 -0
  315. package/dist/scripts/cli/commands/spec/StudioCommand.js +241 -0
  316. package/dist/scripts/cli/commands/spec/StudioCommand.js.map +1 -0
  317. package/dist/scripts/cli/commands/specops/ContributeCommand.js +313 -0
  318. package/dist/scripts/cli/commands/specops/ContributeCommand.js.map +1 -0
  319. package/dist/scripts/cli/commands/specops/DiffCommand.js +394 -0
  320. package/dist/scripts/cli/commands/specops/DiffCommand.js.map +1 -0
  321. package/dist/scripts/cli/commands/specops/SyncCommand.js +380 -0
  322. package/dist/scripts/cli/commands/specops/SyncCommand.js.map +1 -0
  323. package/dist/scripts/completion.js +24 -0
  324. package/dist/scripts/completion.js.map +1 -0
  325. package/dist/scripts/config_init.js +12 -0
  326. package/dist/scripts/config_init.js.map +1 -0
  327. package/dist/scripts/config_set.js +20 -0
  328. package/dist/scripts/config_set.js.map +1 -0
  329. package/dist/scripts/docs/blocks.js +137 -0
  330. package/dist/scripts/docs/blocks.js.map +1 -0
  331. package/dist/scripts/docs/build-site.js +425 -0
  332. package/dist/scripts/docs/build-site.js.map +1 -0
  333. package/dist/scripts/docs/nav.js +198 -0
  334. package/dist/scripts/docs/nav.js.map +1 -0
  335. package/dist/scripts/docs/record-terminal.js +477 -0
  336. package/dist/scripts/docs/record-terminal.js.map +1 -0
  337. package/dist/scripts/docs/terminal-storyboard.js +121 -0
  338. package/dist/scripts/docs/terminal-storyboard.js.map +1 -0
  339. package/dist/scripts/doctor.js +14 -0
  340. package/dist/scripts/doctor.js.map +1 -0
  341. package/dist/scripts/done.js +17 -0
  342. package/dist/scripts/done.js.map +1 -0
  343. package/dist/scripts/expand_domain_pack.js +18 -0
  344. package/dist/scripts/expand_domain_pack.js.map +1 -0
  345. package/dist/scripts/fix.js +12 -0
  346. package/dist/scripts/fix.js.map +1 -0
  347. package/dist/scripts/gen_agent_contract.js +14 -0
  348. package/dist/scripts/gen_agent_contract.js.map +1 -0
  349. package/dist/scripts/gen_mcp_tools.js +264 -0
  350. package/dist/scripts/gen_mcp_tools.js.map +1 -0
  351. package/dist/scripts/harness/init.js +358 -0
  352. package/dist/scripts/harness/init.js.map +1 -0
  353. package/dist/scripts/harness/prompt.js +18 -0
  354. package/dist/scripts/harness/prompt.js.map +1 -0
  355. package/dist/scripts/harness/report.js +323 -0
  356. package/dist/scripts/harness/report.js.map +1 -0
  357. package/dist/scripts/harness/run.js +33 -0
  358. package/dist/scripts/harness/run.js.map +1 -0
  359. package/dist/scripts/infer_pack.js +17 -0
  360. package/dist/scripts/infer_pack.js.map +1 -0
  361. package/dist/scripts/init_from_pack.js +16 -0
  362. package/dist/scripts/init_from_pack.js.map +1 -0
  363. package/dist/scripts/init_pack.js +16 -0
  364. package/dist/scripts/init_pack.js.map +1 -0
  365. package/dist/scripts/init_project.js +17 -0
  366. package/dist/scripts/init_project.js.map +1 -0
  367. package/dist/scripts/lib/agent.js +99 -0
  368. package/dist/scripts/lib/agent.js.map +1 -0
  369. package/dist/scripts/lib/capability-specs.js +80 -0
  370. package/dist/scripts/lib/capability-specs.js.map +1 -0
  371. package/dist/scripts/lib/command.js +17 -0
  372. package/dist/scripts/lib/command.js.map +1 -0
  373. package/dist/scripts/lib/diagnostics.js +62 -0
  374. package/dist/scripts/lib/diagnostics.js.map +1 -0
  375. package/dist/scripts/lib/monorepo-fanout.js +118 -0
  376. package/dist/scripts/lib/monorepo-fanout.js.map +1 -0
  377. package/dist/scripts/lib/placeholders.js +190 -0
  378. package/dist/scripts/lib/placeholders.js.map +1 -0
  379. package/dist/scripts/lib/project-root.js +124 -0
  380. package/dist/scripts/lib/project-root.js.map +1 -0
  381. package/dist/scripts/lib/requirement-graph.js +31 -0
  382. package/dist/scripts/lib/requirement-graph.js.map +1 -0
  383. package/dist/scripts/lib/surface.js +609 -0
  384. package/dist/scripts/lib/surface.js.map +1 -0
  385. package/dist/scripts/license_check.js +15 -0
  386. package/dist/scripts/license_check.js.map +1 -0
  387. package/dist/scripts/lint_pack.js +18 -0
  388. package/dist/scripts/lint_pack.js.map +1 -0
  389. package/dist/scripts/merge-traceability.js +106 -0
  390. package/dist/scripts/merge-traceability.js.map +1 -0
  391. package/dist/scripts/onboard.js +22 -0
  392. package/dist/scripts/onboard.js.map +1 -0
  393. package/dist/scripts/plan.js +17 -0
  394. package/dist/scripts/plan.js.map +1 -0
  395. package/dist/scripts/plugin/gate-hook.js +171 -0
  396. package/dist/scripts/plugin/gate-hook.js.map +1 -0
  397. package/dist/scripts/report.js +17 -0
  398. package/dist/scripts/report.js.map +1 -0
  399. package/dist/scripts/req.js +22 -0
  400. package/dist/scripts/req.js.map +1 -0
  401. package/dist/scripts/schema/cli.js +215 -0
  402. package/dist/scripts/schema/cli.js.map +1 -0
  403. package/dist/scripts/schema/registry.js +264 -0
  404. package/dist/scripts/schema/registry.js.map +1 -0
  405. package/dist/scripts/specops/add.js +180 -0
  406. package/dist/scripts/specops/add.js.map +1 -0
  407. package/dist/scripts/specops/against_lock.js +100 -0
  408. package/dist/scripts/specops/against_lock.js.map +1 -0
  409. package/dist/scripts/specops/as_change.js +49 -0
  410. package/dist/scripts/specops/as_change.js.map +1 -0
  411. package/dist/scripts/specops/contribute.js +24 -0
  412. package/dist/scripts/specops/contribute.js.map +1 -0
  413. package/dist/scripts/specops/diff.js +32 -0
  414. package/dist/scripts/specops/diff.js.map +1 -0
  415. package/dist/scripts/specops/lock.js +39 -0
  416. package/dist/scripts/specops/lock.js.map +1 -0
  417. package/dist/scripts/specops/manifest.js +90 -0
  418. package/dist/scripts/specops/manifest.js.map +1 -0
  419. package/dist/scripts/specops/remove.js +102 -0
  420. package/dist/scripts/specops/remove.js.map +1 -0
  421. package/dist/scripts/specops/sync.js +27 -0
  422. package/dist/scripts/specops/sync.js.map +1 -0
  423. package/dist/scripts/specops/verify.js +149 -0
  424. package/dist/scripts/specops/verify.js.map +1 -0
  425. package/dist/scripts/status.js +17 -0
  426. package/dist/scripts/status.js.map +1 -0
  427. package/dist/scripts/studio.js +14 -0
  428. package/dist/scripts/studio.js.map +1 -0
  429. package/dist/scripts/update.js +17 -0
  430. package/dist/scripts/update.js.map +1 -0
  431. package/dist/scripts/validate_specs.js +10 -0
  432. package/dist/scripts/validate_specs.js.map +1 -0
  433. package/examples/project.config.example +19 -0
  434. package/examples/project.yaml.example +17 -0
  435. package/package.json +105 -0
  436. package/templates/adopt/AI_RULES.md.tpl +27 -0
  437. package/templates/adopt/adr-readme.md.tpl +5 -0
  438. package/templates/adopt/baseline.feature.tpl +9 -0
  439. package/templates/adopt/spec.md.tpl +25 -0
  440. package/templates/adopt/traceability.md.tpl +11 -0
  441. package/templates/backend/AI_RULES.md.tpl +35 -0
  442. package/templates/backend/features/core/health.feature.tpl +7 -0
  443. package/templates/base/.devcontainer/devcontainer.json.tpl +18 -0
  444. package/templates/base/.dockerignore.tpl +11 -0
  445. package/templates/base/.env.dev.app.tpl +13 -0
  446. package/templates/base/.env.dev.infra.tpl +6 -0
  447. package/templates/base/.env.dev.tpl +16 -0
  448. package/templates/base/.env.example.tpl +17 -0
  449. package/templates/base/.env.feature.app.tpl +11 -0
  450. package/templates/base/.env.feature.infra.tpl +4 -0
  451. package/templates/base/.env.feature.tpl +16 -0
  452. package/templates/base/.env.prod.app.tpl +13 -0
  453. package/templates/base/.env.prod.infra.tpl +6 -0
  454. package/templates/base/.env.prod.tpl +16 -0
  455. package/templates/base/.github/workflows/specs.yml.tpl +26 -0
  456. package/templates/base/.gitignore.tpl +9 -0
  457. package/templates/base/.pre-commit-config.yaml.tpl +10 -0
  458. package/templates/base/AGENTS.md.tpl +32 -0
  459. package/templates/base/README.md.tpl +32 -0
  460. package/templates/base/docker-compose.yml.tpl +13 -0
  461. package/templates/base/docs/specs/adr/README.md.tpl +10 -0
  462. package/templates/base/docs/specs/aggregates.md.tpl +5 -0
  463. package/templates/base/docs/specs/commands.md.tpl +13 -0
  464. package/templates/base/docs/specs/domain-model.md.tpl +30 -0
  465. package/templates/base/docs/specs/events.md.tpl +5 -0
  466. package/templates/base/docs/specs/review-checklist.md.tpl +18 -0
  467. package/templates/base/docs/specs/runtime-environments.md.tpl +26 -0
  468. package/templates/base/docs/specs/status-model.md.tpl +16 -0
  469. package/templates/base/docs/specs/traceability.md.tpl +7 -0
  470. package/templates/base/docs/specs/use-cases.md.tpl +5 -0
  471. package/templates/base/spec.md.tpl +63 -0
  472. package/templates/ci/azure.yml.tpl +40 -0
  473. package/templates/ci/github.yml.tpl +40 -0
  474. package/templates/ci/gitlab.yml.tpl +21 -0
  475. package/templates/ci/jenkins.tpl +35 -0
  476. package/templates/contracts/AI_RULES.md.tpl +55 -0
  477. package/templates/contracts/asyncapi-stub.yaml.tpl +24 -0
  478. package/templates/contracts/contract-traceability.md.tpl +10 -0
  479. package/templates/contracts/openapi-stub.yaml.tpl +29 -0
  480. package/templates/contracts/pacts-gitkeep.tpl +0 -0
  481. package/templates/contracts/test-strategy.md.tpl +94 -0
  482. package/templates/frontend/AI_RULES.md.tpl +34 -0
  483. package/templates/frontend/features/core/health.feature.tpl +6 -0
  484. package/templates/harness/harness.config.yaml.tpl +74 -0
  485. package/templates/harness/prompt-prefix.md.tpl +60 -0
  486. package/templates/mobile/AI_RULES.md.tpl +56 -0
  487. package/templates/mobile/features/core/health.feature.tpl +7 -0
  488. package/templates/modules/auth/backend/registration_and_login.feature.tpl +10 -0
  489. package/templates/modules/auth/frontend/login.feature.tpl +5 -0
  490. package/templates/modules/billing/backend/billing_settlement.feature.tpl +5 -0
  491. package/templates/modules/billing/frontend/billing_summary.feature.tpl +5 -0
  492. package/templates/modules/dashboard/backend/dashboard_kpi.feature.tpl +5 -0
  493. package/templates/modules/dashboard/frontend/dashboard.feature.tpl +5 -0
  494. package/vendor/mermaid.min.js +3636 -0
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ /**
3
+ * What `specops sync` does with one file when the pack has moved on.
4
+ *
5
+ * The hard case is the ordinary one: the pack changed a file and so did the
6
+ * project. Sync therefore keeps a baseline — the content the pack last wrote —
7
+ * and treats the three-way comparison as the primary decision rather than a
8
+ * fallback. Without a baseline it refuses to guess, because silently choosing
9
+ * a side is how a local edit disappears without anyone noticing.
10
+ *
11
+ * Pure: the contents arrive as strings and the outcome says what to write.
12
+ * Reading them, running `git merge-file`, and writing the result are the
13
+ * caller's, so every branch below is testable without a filesystem.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.OUTCOME_LABEL = exports.CONFLICT_OUTCOMES = void 0;
17
+ exports.reconcile = reconcile;
18
+ /** The outcomes a human has to resolve by hand. */
19
+ exports.CONFLICT_OUTCOMES = new Set([
20
+ "conflict",
21
+ "conflict-skipped",
22
+ "conflict-no-base",
23
+ ]);
24
+ /** How each outcome is named in the per-pack summary. */
25
+ exports.OUTCOME_LABEL = {
26
+ added: "added",
27
+ unchanged: "unchanged",
28
+ updated: "updated",
29
+ overwritten: "overwritten",
30
+ kept: "kept (local edits preserved)",
31
+ merged: "merged",
32
+ conflict: "CONFLICT (markers written)",
33
+ "conflict-skipped": "CONFLICT (skipped)",
34
+ "conflict-no-base": "CONFLICT (no merge base)",
35
+ };
36
+ /**
37
+ * @param base what the pack wrote last time, or null if never recorded
38
+ * @param local what the project has now, or null if the file does not exist
39
+ * @param incoming what the pack writes this time
40
+ */
41
+ function reconcile(base, local, incoming, opts, merge) {
42
+ if (local === null) {
43
+ return { outcome: "added", write: incoming, baselineContent: incoming };
44
+ }
45
+ if (local === incoming) {
46
+ return { outcome: "unchanged", write: null, baselineContent: incoming };
47
+ }
48
+ if (opts.force) {
49
+ return { outcome: "overwritten", write: incoming, baselineContent: incoming };
50
+ }
51
+ if (base === null) {
52
+ // No merge base recorded — refuse to guess. Leave local untouched.
53
+ return { outcome: "conflict-no-base", write: null, baselineContent: null };
54
+ }
55
+ if (local === base) {
56
+ return { outcome: "updated", write: incoming, baselineContent: incoming };
57
+ }
58
+ if (incoming === base) {
59
+ // Pack unchanged for this file; local edits stand.
60
+ return { outcome: "kept", write: null, baselineContent: base };
61
+ }
62
+ // Both sides diverged from base — real three-way merge.
63
+ const result = merge(base, local, incoming);
64
+ if (!result.conflict) {
65
+ return { outcome: "merged", write: result.merged, baselineContent: incoming };
66
+ }
67
+ if (opts.abortOnConflict) {
68
+ return { outcome: "conflict-skipped", write: null, baselineContent: base };
69
+ }
70
+ return { outcome: "conflict", write: result.merged, baselineContent: base };
71
+ }
72
+ //# sourceMappingURL=Reconciliation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Reconciliation.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/Reconciliation.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AA4DH,8BAqCC;AApFD,mDAAmD;AACtC,QAAA,iBAAiB,GAAkC,IAAI,GAAG,CAAmB;IACxF,UAAU;IACV,kBAAkB;IAClB,kBAAkB;CACnB,CAAC,CAAC;AAEH,yDAAyD;AAC5C,QAAA,aAAa,GAA+C;IACvE,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAClB,WAAW,EAAE,aAAa;IAC1B,IAAI,EAAE,8BAA8B;IACpC,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,4BAA4B;IACtC,kBAAkB,EAAE,oBAAoB;IACxC,kBAAkB,EAAE,0BAA0B;CAC/C,CAAC;AAwBF;;;;GAIG;AACH,SAAgB,SAAS,CACvB,IAAmB,EACnB,KAAoB,EACpB,QAAgB,EAChB,IAAsB,EACtB,KAAc;IAEd,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC;IAC1E,CAAC;IACD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC;IAC1E,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC;IAChF,CAAC;IACD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,mEAAmE;QACnE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IAC7E,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,mDAAmD;QACnD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IACjE,CAAC;IAED,wDAAwD;IACxD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC;IAChF,CAAC;IACD,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IAC7E,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ /**
3
+ * The dependency graph between requirements.
4
+ *
5
+ * `harness run` processed requirements in matrix order and cut every worktree
6
+ * from the same base, which is wrong whenever one requirement builds on
7
+ * another: REQ-002 needed REQ-001's code to exist and there was no way to say
8
+ * so, so somebody had to know it and pass `--base-branch` by hand. That is
9
+ * defect H12 of the closure plan, and the false failure recorded as H9 was the
10
+ * same gap seen from the other side.
11
+ *
12
+ * A requirement declares what it builds on inside the `csda:trace` comment it
13
+ * already carries:
14
+ *
15
+ * <!-- csda:trace uc=UC-002 feature=features/auth/scopes.feature
16
+ * depends=REQ-001 -->
17
+ *
18
+ * That comment is the repository's existing way of attaching machine-readable
19
+ * facts to a requirement, and `change archive` already reads it to write the
20
+ * traceability row. So the model is the one this repository uses everywhere
21
+ * else: **the requirement declares, the matrix reflects.** Nothing about the
22
+ * ten-column format changes, which matters — `done` and `alm sync` both read
23
+ * Status as the penultimate cell, so an extra column would have silently sent
24
+ * status writes to the wrong place.
25
+ *
26
+ * A missing declaration means no dependencies, so every project that never
27
+ * writes one behaves exactly as it does today.
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.RequirementGraph = void 0;
31
+ exports.splitDependencies = splitDependencies;
32
+ /** `"REQ-001, REQ-003"` → `["REQ-001", "REQ-003"]`, de-duplicated and upper-cased. */
33
+ function splitDependencies(raw) {
34
+ const seen = new Set();
35
+ for (const token of String(raw).split(/[,;\s]+/)) {
36
+ const id = token.trim().toUpperCase();
37
+ if (id)
38
+ seen.add(id);
39
+ }
40
+ return [...seen];
41
+ }
42
+ /**
43
+ * The graph over a known set of requirements, and every question the CLI asks
44
+ * of it.
45
+ *
46
+ * Built once and then queried: ordering, levels and cycles are all derived
47
+ * from the same two adjacency maps, so they cannot disagree with each other.
48
+ */
49
+ class RequirementGraph {
50
+ dependsOn;
51
+ dependents;
52
+ unknown;
53
+ selfReferential;
54
+ ids;
55
+ constructor(requirementIds, declared) {
56
+ this.ids = requirementIds.map((id) => String(id).toUpperCase());
57
+ const known = new Set(this.ids);
58
+ const dependsOn = {};
59
+ const dependents = {};
60
+ for (const id of known) {
61
+ dependsOn[id] = [];
62
+ dependents[id] = [];
63
+ }
64
+ const unknown = [];
65
+ const selfReferential = [];
66
+ for (const [requirement, deps] of Object.entries(declared)) {
67
+ if (!known.has(requirement))
68
+ continue; // declared for a REQ not in this project
69
+ for (const dependency of deps) {
70
+ if (dependency === requirement) {
71
+ selfReferential.push(requirement);
72
+ }
73
+ else if (!known.has(dependency)) {
74
+ unknown.push({ requirement, dependency });
75
+ }
76
+ else {
77
+ dependsOn[requirement].push(dependency);
78
+ dependents[dependency].push(requirement);
79
+ }
80
+ }
81
+ }
82
+ this.dependsOn = dependsOn;
83
+ this.dependents = dependents;
84
+ this.unknown = unknown;
85
+ this.selfReferential = selfReferential;
86
+ }
87
+ /** Build from an adjacency map the caller already has — the harness has one. */
88
+ static fromDependencies(requirementIds, declared) {
89
+ return new RequirementGraph(requirementIds, declared);
90
+ }
91
+ /**
92
+ * Requirements in an order where every dependency comes before what needs
93
+ * it, and the sets that could run at the same time.
94
+ *
95
+ * Kahn's algorithm with the queue kept in the caller's original order, so
96
+ * the result is stable: two requirements that do not constrain each other
97
+ * stay in matrix order, and a project with no declarations gets its input
98
+ * back untouched.
99
+ */
100
+ get schedule() {
101
+ const remaining = new Map(this.ids.map((id) => [id, new Set(this.dependsOn[id] ?? [])]));
102
+ const order = [];
103
+ const levels = [];
104
+ while (remaining.size > 0) {
105
+ const ready = this.ids.filter((id) => remaining.get(id)?.size === 0);
106
+ if (ready.length === 0)
107
+ break; // everything left is in, or behind, a cycle
108
+ levels.push(ready);
109
+ for (const id of ready) {
110
+ order.push(id);
111
+ remaining.delete(id);
112
+ }
113
+ for (const deps of remaining.values()) {
114
+ for (const id of ready)
115
+ deps.delete(id);
116
+ }
117
+ }
118
+ return { order, levels };
119
+ }
120
+ get order() {
121
+ return this.schedule.order;
122
+ }
123
+ get levels() {
124
+ return this.schedule.levels;
125
+ }
126
+ /**
127
+ * The cycles among the requirements that could not be ordered.
128
+ *
129
+ * Reporting "there is a cycle" is not actionable; reporting
130
+ * `REQ-002 → REQ-003 → REQ-002` is.
131
+ */
132
+ get cycles() {
133
+ const ordered = new Set(this.order);
134
+ const stuck = this.ids.filter((id) => !ordered.has(id));
135
+ return this.findCycles(stuck);
136
+ }
137
+ /**
138
+ * Everything that transitively waits on `requirement`, so a cascade is
139
+ * reported once as blocked rather than N times as failed.
140
+ */
141
+ transitiveDependents(requirement) {
142
+ const blocked = new Set();
143
+ let grew = true;
144
+ while (grew) {
145
+ grew = false;
146
+ for (const [id, deps] of Object.entries(this.dependsOn)) {
147
+ if (blocked.has(id))
148
+ continue;
149
+ if (deps.some((d) => d === requirement || blocked.has(d))) {
150
+ blocked.add(id);
151
+ grew = true;
152
+ }
153
+ }
154
+ }
155
+ return blocked;
156
+ }
157
+ /** Depth-first, returning each cycle once, as the path that closes it. */
158
+ findCycles(stuck) {
159
+ const inStuck = new Set(stuck);
160
+ const cycles = [];
161
+ const seenSignature = new Set();
162
+ const done = new Set();
163
+ const path = [];
164
+ const visit = (id) => {
165
+ if (done.has(id))
166
+ return;
167
+ const at = path.indexOf(id);
168
+ if (at !== -1) {
169
+ this.recordCycle(path.slice(at), cycles, seenSignature);
170
+ return;
171
+ }
172
+ path.push(id);
173
+ for (const dep of this.dependsOn[id] ?? []) {
174
+ if (inStuck.has(dep))
175
+ visit(dep);
176
+ }
177
+ path.pop();
178
+ done.add(id);
179
+ };
180
+ for (const id of stuck)
181
+ visit(id);
182
+ return cycles;
183
+ }
184
+ /** Rotate to the smallest id so one loop found from two entry points is one cycle. */
185
+ recordCycle(cycle, cycles, seen) {
186
+ const smallest = [...cycle].sort()[0];
187
+ const pivot = cycle.indexOf(smallest);
188
+ const normalised = [...cycle.slice(pivot), ...cycle.slice(0, pivot)];
189
+ const signature = normalised.join(">");
190
+ if (seen.has(signature))
191
+ return;
192
+ seen.add(signature);
193
+ cycles.push(normalised);
194
+ }
195
+ }
196
+ exports.RequirementGraph = RequirementGraph;
197
+ //# sourceMappingURL=RequirementGraph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequirementGraph.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/RequirementGraph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RequirementPlan = void 0;
4
+ class RequirementPlan {
5
+ static DONE_STATUSES = new Set(["Implemented", "Verified", "Released"]);
6
+ static PLACEHOLDER_RE = /^(TBD|TODO|\?+|-)?$|\{\{/;
7
+ static isMeaningful(value) {
8
+ if (typeof value !== "string")
9
+ return false;
10
+ const stripped = value.replace(/^`|`$/g, "").trim();
11
+ if (!stripped)
12
+ return false;
13
+ return !RequirementPlan.PLACEHOLDER_RE.test(stripped);
14
+ }
15
+ static classifyRow(row, fileChecker) {
16
+ const reqId = row.requirement || "";
17
+ if (!/^REQ-\d+/.test(reqId))
18
+ return null;
19
+ const featureExists = fileChecker(row.featureFile || "");
20
+ const techDeclared = RequirementPlan.isMeaningful(row.technicalArtifact);
21
+ const testDeclared = RequirementPlan.isMeaningful(row.testArtifact);
22
+ const techExists = techDeclared && fileChecker(row.technicalArtifact || "");
23
+ const testExists = testDeclared && fileChecker(row.testArtifact || "");
24
+ const isDone = RequirementPlan.DONE_STATUSES.has(row.status || "");
25
+ let category;
26
+ if (!featureExists)
27
+ category = "NEEDS_FEATURE";
28
+ else if (!techDeclared && !testDeclared)
29
+ category = "NEEDS_EVERYTHING";
30
+ else if (testDeclared && !testExists && techDeclared && !techExists)
31
+ category = "NEEDS_EVERYTHING";
32
+ else if (testDeclared && !testExists)
33
+ category = "NEEDS_TEST";
34
+ else if (techDeclared && !techExists)
35
+ category = "NEEDS_IMPLEMENTATION";
36
+ else if (!isDone)
37
+ category = "NEEDS_STATUS_UPDATE";
38
+ else
39
+ category = "DONE";
40
+ return {
41
+ requirement: reqId,
42
+ scenario_id: row.scenarioId || "",
43
+ feature_file: row.featureFile || "",
44
+ technical_artifact: row.technicalArtifact || "",
45
+ test_artifact: row.testArtifact || "",
46
+ status: row.status || "",
47
+ feature_exists: featureExists,
48
+ technical_exists: techExists,
49
+ test_exists: testExists,
50
+ category,
51
+ };
52
+ }
53
+ static buildSummary(items) {
54
+ const summary = {
55
+ total: items.length,
56
+ done: 0,
57
+ needs_feature: 0,
58
+ needs_test: 0,
59
+ needs_implementation: 0,
60
+ needs_status_update: 0,
61
+ needs_everything: 0,
62
+ blocked: 0,
63
+ };
64
+ for (const item of items) {
65
+ if (item.category === "DONE")
66
+ summary.done++;
67
+ else if (item.category === "NEEDS_FEATURE")
68
+ summary.needs_feature++;
69
+ else if (item.category === "NEEDS_TEST")
70
+ summary.needs_test++;
71
+ else if (item.category === "NEEDS_IMPLEMENTATION")
72
+ summary.needs_implementation++;
73
+ else if (item.category === "NEEDS_STATUS_UPDATE")
74
+ summary.needs_status_update++;
75
+ else if (item.category === "NEEDS_EVERYTHING")
76
+ summary.needs_everything++;
77
+ if (item.blocked_by && item.blocked_by.length > 0) {
78
+ summary.blocked++;
79
+ }
80
+ }
81
+ return summary;
82
+ }
83
+ }
84
+ exports.RequirementPlan = RequirementPlan;
85
+ //# sourceMappingURL=RequirementPlan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequirementPlan.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/RequirementPlan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ /**
3
+ * Is this requirement fit to hand to an agent? (B2)
4
+ *
5
+ * ## The attempt with the worst cost/result ratio in the loop
6
+ *
7
+ * `plan` already classifies `NEEDS_FEATURE` and `NEEDS_EVERYTHING`, and
8
+ * `harness run` never used it as a filter. A requirement whose feature does not
9
+ * exist and whose row declares no artifacts is handed over exactly like any
10
+ * other, and the agent discovers halfway through that it has to invent the
11
+ * acceptance criterion — then spends up to `max_attempts` × the timeout on it.
12
+ *
13
+ * What this buys is not a new rule. It is that "is this ready for an agent?"
14
+ * stops being the intuition of whoever typed the command and becomes something
15
+ * calculated, with a fix attached to each answer.
16
+ *
17
+ * ## Blocking versus warning
18
+ *
19
+ * A blocker means the agent cannot succeed, not that the requirement is untidy:
20
+ *
21
+ * - **no feature file** — there is no acceptance criterion to satisfy;
22
+ * - **a scenario the gate cannot fail** — the reward signal is counterfeit
23
+ * (H14), so a green run would prove nothing;
24
+ * - **dependencies not green** — the work it builds on is not there;
25
+ * - **`Deprecated`** — nobody wants it built;
26
+ * - **`Needs Clarification`** — its meaning is disputed, and an agent asked to
27
+ * settle a disagreement will settle it by guessing.
28
+ *
29
+ * Undeclared artifacts only warn. The row being vague about *where* the work
30
+ * goes does not stop the work, and `A2` already reports it against the diff
31
+ * afterwards, which is the moment there is evidence to report.
32
+ *
33
+ * ## Why no I/O here
34
+ *
35
+ * Whether a file exists and what its scenarios say are facts the caller
36
+ * gathers; whether those facts add up to "ready" is a rule. Keeping them apart
37
+ * is what lets every case below be tested without a project on disk.
38
+ */
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.UNBUILDABLE_STATUS = exports.READINESS_CODES = void 0;
41
+ exports.requirementReadiness = requirementReadiness;
42
+ const Diagnostic_1 = require("./Diagnostic");
43
+ exports.READINESS_CODES = Object.freeze({
44
+ NO_FEATURE: "requirement_has_no_feature",
45
+ UNRUNNABLE_SCENARIO: "requirement_scenario_unrunnable",
46
+ BLOCKED_BY: "requirement_blocked_by_dependency",
47
+ NOT_WANTED: "requirement_not_wanted",
48
+ NEEDS_CLARIFICATION: "requirement_needs_clarification",
49
+ NO_TEST_ARTIFACT: "requirement_declares_no_test_artifact",
50
+ NO_TECHNICAL_ARTIFACT: "requirement_declares_no_technical_artifact",
51
+ });
52
+ /** Statuses that mean an agent should not be pointed at this row. */
53
+ exports.UNBUILDABLE_STATUS = Object.freeze({
54
+ Deprecated: exports.READINESS_CODES.NOT_WANTED,
55
+ "Needs Clarification": exports.READINESS_CODES.NEEDS_CLARIFICATION,
56
+ });
57
+ function requirementReadiness(input) {
58
+ const target = input.requirement;
59
+ const blockers = [];
60
+ const unbuildable = exports.UNBUILDABLE_STATUS[String(input.status || "")];
61
+ if (unbuildable) {
62
+ blockers.push((0, Diagnostic_1.error)(unbuildable, unbuildable === exports.READINESS_CODES.NOT_WANTED
63
+ ? `status is ${input.status} — nobody wants this built.`
64
+ : `status is ${input.status} — its meaning is still disputed, and an agent ` +
65
+ `asked to settle a disagreement will settle it by guessing.`, {
66
+ target,
67
+ fix: unbuildable === exports.READINESS_CODES.NOT_WANTED
68
+ ? "Drop it from the run, or move the row out of Deprecated."
69
+ : "Settle the question with the people who raised it, then set the status.",
70
+ }));
71
+ }
72
+ if (!input.featureExists) {
73
+ blockers.push((0, Diagnostic_1.error)(exports.READINESS_CODES.NO_FEATURE, input.featureFile
74
+ ? `its feature file ${input.featureFile} does not exist, so there is no ` +
75
+ `acceptance criterion to satisfy.`
76
+ : "the row declares no feature file, so there is no acceptance criterion to satisfy.", {
77
+ target,
78
+ fix: `Write the scenario first: \`specgate req link ${target} --feature <path>\`.`,
79
+ }));
80
+ }
81
+ // Only errors. A scenario Cucumber sees as empty passes without running
82
+ // anything, so a green gate on it would mean nothing (H14).
83
+ const unrunnable = (input.scenarioFindings || []).filter((f) => f.severity === "error");
84
+ if (unrunnable.length > 0) {
85
+ blockers.push((0, Diagnostic_1.error)(exports.READINESS_CODES.UNRUNNABLE_SCENARIO, `its scenario would pass without testing anything (${unrunnable.length} error(s)), ` +
86
+ `so the gate could not tell success from failure.`, {
87
+ target,
88
+ fix: "Run `specgate validate <dir> --strict-scenarios` to see them, and fix them first.",
89
+ }));
90
+ }
91
+ const blocked = input.blockedBy || [];
92
+ if (blocked.length > 0) {
93
+ blockers.push((0, Diagnostic_1.error)(exports.READINESS_CODES.BLOCKED_BY, `it depends on ${blocked.join(", ")}, which ${blocked.length === 1 ? "is" : "are"} not done.`, {
94
+ target,
95
+ fix: `Run ${blocked.join(", ")} first — \`specgate harness run\` orders them for you.`,
96
+ }));
97
+ }
98
+ // Warnings, not blockers: a vague row does not stop the work, and A2 reports
99
+ // the same gap against the actual diff afterwards — the moment there is
100
+ // evidence rather than an expectation.
101
+ //
102
+ // These are not the noise trap A2 had to avoid. `TBD` in the test column is
103
+ // not a false positive; it is an accurate statement about an incomplete row,
104
+ // and TDD says that column is what should be filled in first.
105
+ if (!input.testDeclared) {
106
+ blockers.push((0, Diagnostic_1.warning)(exports.READINESS_CODES.NO_TEST_ARTIFACT, "the row declares no test artifact, so the agent chooses where the test " +
107
+ "goes and the matrix will point somewhere else.", { target, fix: `specgate req link ${target} --test <path>` }));
108
+ }
109
+ if (!input.technicalDeclared) {
110
+ blockers.push((0, Diagnostic_1.warning)(exports.READINESS_CODES.NO_TECHNICAL_ARTIFACT, "the row declares no production artifact, so the agent chooses where the " +
111
+ "implementation goes and the matrix will point somewhere else.", { target, fix: `specgate req link ${target} --code <path>` }));
112
+ }
113
+ return { ready: !blockers.some((b) => b.severity === "error"), blockers };
114
+ }
115
+ //# sourceMappingURL=RequirementReadiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequirementReadiness.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/RequirementReadiness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /**
3
+ * Whether a requirement's prose is checkable by a machine — EARS, opt-in (F6).
4
+ *
5
+ * ## Why this exists
6
+ *
7
+ * `PLAN_PREDICTABLE_CODE_EVOLUTION.md` §4 names the real gap against
8
+ * Predictable Code: `specgate validate` checks that the paperwork is internally
9
+ * consistent, not that the code does what the spec says. §8.1 draws the
10
+ * consequence — a code verifier is useless while the spec it checks against is
11
+ * prose. `- Max 5 failed attempts per hour per user` is not checkable by
12
+ * anything. So the first step is not a verifier; it is making the requirement
13
+ * itself say something a machine can hold code to.
14
+ *
15
+ * EARS (Easy Approach to Requirements Syntax) is the narrowest tool for that:
16
+ * five sentence shapes, each pairing a trigger keyword with an obligation.
17
+ * This module does not attempt to parse full EARS grammar — no regex can
18
+ * reliably tell "the system" from a response clause. It checks the one thing a
19
+ * regex can tell honestly: whether an obligation keyword (RFC 2119) is present
20
+ * at all, and whether a requirement that opens as an unwanted-behaviour clause
21
+ * (`IF …`) actually resolves with `THEN …`. Anything wider would be the H13
22
+ * mistake again — a check that claims to enforce a grammar it does not parse.
23
+ *
24
+ * ## Why RFC 2119 lives here now
25
+ *
26
+ * `DeltaSpec.ts` already enforces `no_rfc2119_keyword`, but only for
27
+ * requirements inside a delta (`change validate` / `change archive`) — a
28
+ * capability spec at rest has never been checked. Moving the constant here and
29
+ * having `DeltaSpec` import it keeps one definition instead of two that can
30
+ * drift, which is the F1/A3 lesson: a rule enforced in one place and silent in
31
+ * another is not a rule, it is luck.
32
+ */
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.REQUIREMENT_SYNTAX_CODES = exports.RFC2119 = void 0;
35
+ exports.analyseRequirementText = analyseRequirementText;
36
+ const Diagnostic_1 = require("./Diagnostic");
37
+ /** An obligation keyword, English or Spanish. Unchanged from `DeltaSpec`. */
38
+ exports.RFC2119 = /\b(SHALL|MUST|SHOULD|MAY|DEBE|DEBERÁ|DEBERA)\b/;
39
+ /** Every code this module can emit. Callers branch on these, never on prose. */
40
+ exports.REQUIREMENT_SYNTAX_CODES = Object.freeze({
41
+ NO_RFC2119: "no_rfc2119_keyword",
42
+ MISSING_THEN: "requirement_missing_then_clause",
43
+ });
44
+ /**
45
+ * The one paired-keyword EARS shape a regex can check honestly: a requirement
46
+ * that opens as "IF <trigger>" (unwanted behaviour) has to resolve with
47
+ * "THEN <response>" in the same sentence, or it names a trigger and never says
48
+ * what happens.
49
+ *
50
+ * The other four EARS shapes — ubiquitous, event-driven (`WHEN`), state-driven
51
+ * (`WHILE`), optional-feature (`WHERE`) — have no second keyword to be missing;
52
+ * their only checkable requirement is the obligation keyword, which
53
+ * `NO_RFC2119` already covers. Claiming to validate their internal structure
54
+ * beyond that would be checking a shape this module cannot actually parse.
55
+ */
56
+ const IF_TRIGGER = /^\s*(?:IF|SI)\b/i;
57
+ const THEN_KEYWORD = /\b(?:THEN|ENTONCES)\b/i;
58
+ /**
59
+ * Checks one requirement's prose. `text` is the requirement body as
60
+ * `SpecParser` / `DeltaSpec` hand it over — free-text only, scenario steps
61
+ * live separately and are not part of this check.
62
+ *
63
+ * Two independent findings, never conflated: a requirement can state no
64
+ * obligation at all (`NO_RFC2119`), or state one but leave an `IF` trigger
65
+ * unresolved (`MISSING_THEN`). A requirement missing both reports both — they
66
+ * are different defects with different fixes.
67
+ */
68
+ function analyseRequirementText(text, opts) {
69
+ const trimmed = String(text || "").trim();
70
+ const found = [];
71
+ const at = (extra = {}) => ({
72
+ target: opts.target,
73
+ ...(opts.file ? { file: opts.file } : {}),
74
+ ...(opts.line ? { line: opts.line } : {}),
75
+ ...extra,
76
+ });
77
+ if (!trimmed)
78
+ return found;
79
+ const hasObligation = exports.RFC2119.test(trimmed);
80
+ if (!hasObligation) {
81
+ found.push((0, Diagnostic_1.warning)(exports.REQUIREMENT_SYNTAX_CODES.NO_RFC2119, `${opts.target} states no obligation (SHALL / MUST / SHOULD / MAY / DEBE / DEBERÁ).`, at({ fix: 'Rewrite the body as "The system SHALL …" or one of its EARS forms.' })));
82
+ }
83
+ if (IF_TRIGGER.test(trimmed) && !THEN_KEYWORD.test(trimmed)) {
84
+ found.push((0, Diagnostic_1.warning)(exports.REQUIREMENT_SYNTAX_CODES.MISSING_THEN, `${opts.target} opens with "IF" but never resolves with "THEN" — the trigger names a ` +
85
+ "condition and never says what the system does about it.", at({
86
+ fix: 'Complete the EARS unwanted-behaviour form: "IF <trigger>, THEN the system SHALL …".',
87
+ })));
88
+ }
89
+ return found;
90
+ }
91
+ //# sourceMappingURL=RequirementSyntax.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequirementSyntax.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/RequirementSyntax.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;;;AAuCH,wDAwCC;AA5ED,6CAAuC;AAEvC,6EAA6E;AAChE,QAAA,OAAO,GAAG,gDAAgD,CAAC;AAExE,gFAAgF;AACnE,QAAA,wBAAwB,GAAG,MAAM,CAAC,MAAM,CAAC;IACpD,UAAU,EAAE,oBAAoB;IAChC,YAAY,EAAE,iCAAiC;CAChD,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,GAAG,kBAAkB,CAAC;AACtC,MAAM,YAAY,GAAG,wBAAwB,CAAC;AAE9C;;;;;;;;;GASG;AACH,SAAgB,sBAAsB,CACpC,IAAY,EACZ,IAAsD;IAEtD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,MAAM,EAAE,GAAG,CAAC,QAAiC,EAAE,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,GAAG,KAAK;KACT,CAAC,CAAC;IAEH,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAE3B,MAAM,aAAa,GAAG,eAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CACR,IAAA,oBAAO,EACL,gCAAwB,CAAC,UAAU,EACnC,GAAG,IAAI,CAAC,MAAM,sEAAsE,EACpF,EAAE,CAAC,EAAE,GAAG,EAAE,oEAAoE,EAAE,CAAC,CAClF,CACF,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5D,KAAK,CAAC,IAAI,CACR,IAAA,oBAAO,EACL,gCAAwB,CAAC,YAAY,EACrC,GAAG,IAAI,CAAC,MAAM,wEAAwE;YACpF,yDAAyD,EAC3D,EAAE,CAAC;YACD,GAAG,EAAE,qFAAqF;SAC3F,CAAC,CACH,CACF,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}