@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,180 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeTraceability = mergeTraceability;
4
+ const Reconciliation_1 = require("./Reconciliation");
5
+ const TraceabilityFormat_1 = require("./TraceabilityFormat");
6
+ /**
7
+ * Merging two versions of `docs/specs/traceability.md`, row by row.
8
+ *
9
+ * ## Why this exists
10
+ *
11
+ * Run the harness with `--concurrency 3` and you get three green branches, each
12
+ * having flipped **its own** requirement to `Implemented`. Merge the second one
13
+ * and git reports a conflict in the matrix — even though no two branches touched
14
+ * the same row.
15
+ *
16
+ * The reason is not concurrency. Git's three-way merge works on lines, and it
17
+ * needs at least one *unchanged* line between two changed regions to treat them
18
+ * as independent. Matrix rows are consecutive lines, so two edits one row apart
19
+ * land in the same hunk. Measured: rows 1 and 2 conflict, rows 1 and 5 merge
20
+ * clean. Same writers, same file, same concurrency — only the distance differs.
21
+ *
22
+ * So the fix is not a lock (there is no race: every worker writes its own
23
+ * worktree) and not a different diff algorithm (myers, patience, histogram and
24
+ * minimal all conflict). The fix is to merge the file in the unit it is actually
25
+ * made of: rows.
26
+ *
27
+ * ## How a row is identified
28
+ *
29
+ * By `Requirement` + `Scenario ID`, and **never** by anything that changes.
30
+ *
31
+ * That is not a stylistic preference, it is the bug that nearly shipped: a first
32
+ * prototype keyed rows on the first two cells of a two-column test table, where
33
+ * the second cell *was* the status. A row whose status had changed then looked
34
+ * like a *different* row, the merge came out "clean", and the other branch's
35
+ * edit was lost in silence. A merge that loses an edit is worse than one that
36
+ * refuses, so the key is the pair of columns that a status flip never touches.
37
+ *
38
+ * ## What it will and will not do
39
+ *
40
+ * It resolves the case it was built for — two branches, two different rows — and
41
+ * it still **conflicts** when two branches change the same row to different
42
+ * values. Losing an edit quietly is the one outcome worse than a conflict, so
43
+ * anything genuinely ambiguous comes back with markers for a human.
44
+ *
45
+ * The per-row decision is not reimplemented here: it is `reconcile`, the same
46
+ * function `specops sync` uses to decide what to do when a pack and a project
47
+ * have both changed a file. Identical question, one granularity down.
48
+ */
49
+ /** Conflict markers, in git's own shape so existing tooling recognises them. */
50
+ const OURS_MARK = "<<<<<<<";
51
+ const SPLIT_MARK = "=======";
52
+ const THEIRS_MARK = ">>>>>>>";
53
+ /**
54
+ * A row key that a status flip cannot change.
55
+ *
56
+ * `parseMatrixRows` splits on `|`, which leaves an empty cell at each end, so
57
+ * `cells[1]` is the first column. `readRowFields` owns that offset for both
58
+ * matrix shapes; going through it means this module never learns the layout.
59
+ */
60
+ function rowKey(line, mode) {
61
+ const cells = line.split("|").map((c) => c.trim());
62
+ const { requirementId, scenarioId } = (0, TraceabilityFormat_1.readRowFields)(cells, mode);
63
+ const key = `${requirementId}::${scenarioId}`;
64
+ return key === "::" ? null : key;
65
+ }
66
+ /** Every data row of a matrix, keyed and in file order. */
67
+ function indexRows(content, mode) {
68
+ const rows = new Map();
69
+ for (const line of content.split("\n")) {
70
+ if (!line.trim().startsWith("|"))
71
+ continue;
72
+ if (line.includes("---"))
73
+ continue;
74
+ const key = rowKey(line, mode);
75
+ if (key)
76
+ rows.set(key, line);
77
+ }
78
+ return rows;
79
+ }
80
+ /**
81
+ * A row both sides changed differently is a conflict, full stop.
82
+ *
83
+ * `reconcile` takes a merge function for the case where base, ours and theirs
84
+ * all differ. One row is a single fact — a status is `Implemented` or it is
85
+ * `Verified`, there is no blend — so this always reports a conflict and lets
86
+ * `reconcile` produce the outcome.
87
+ */
88
+ const rowsDoNotBlend = () => ({ merged: "", conflict: true });
89
+ /**
90
+ * Three-way merge of a traceability matrix.
91
+ *
92
+ * @param base the common ancestor's content, or "" when git has none
93
+ * @param ours the version being merged into
94
+ * @param theirs the version being merged in
95
+ */
96
+ function mergeTraceability(base, ours, theirs) {
97
+ // The mode comes from `ours`: git is merging *into* that file, and a merge is
98
+ // not the place to convert a project between matrix shapes. A file with
99
+ // neither header has no rows to key, so the whole merge is handed back
100
+ // unresolved rather than guessed at.
101
+ const mode = (0, TraceabilityFormat_1.detectTraceabilityMode)(ours);
102
+ if (mode === null) {
103
+ return { content: ours, conflicts: ["(traceability.md has no recognisable matrix header)"] };
104
+ }
105
+ const baseRows = indexRows(base, mode);
106
+ const ourRows = indexRows(ours, mode);
107
+ const theirRows = indexRows(theirs, mode);
108
+ const conflicts = [];
109
+ const emitted = new Set();
110
+ const out = [];
111
+ for (const line of ours.split("\n")) {
112
+ const key = line.trim().startsWith("|") && !line.includes("---") ? rowKey(line, mode) : null;
113
+ if (!key) {
114
+ out.push(line); // header, separator, prose — carried through untouched
115
+ continue;
116
+ }
117
+ emitted.add(key);
118
+ const ourRow = ourRows.get(key) ?? line;
119
+ const baseRow = baseRows.get(key) ?? null;
120
+ const theirRow = theirRows.get(key);
121
+ if (theirRow === undefined) {
122
+ // They do not have this row. Either we added it, or they deleted it.
123
+ if (baseRow === null || baseRow === ourRow) {
124
+ // We added it (no base), or they deleted a row we left alone. Keeping
125
+ // ours in the first case is right; in the second, honouring a deletion
126
+ // would drop a requirement during a merge, which is a decision no
127
+ // driver should make silently — so the row stays and `validate` on the
128
+ // result is what tells the truth.
129
+ out.push(ourRow);
130
+ }
131
+ else {
132
+ // We changed it, they deleted it. Nothing here can be right by itself.
133
+ conflicts.push(key);
134
+ out.push(conflictBlock(ourRow, "(row deleted on the other side)"));
135
+ }
136
+ continue;
137
+ }
138
+ const decision = (0, Reconciliation_1.reconcile)(baseRow, ourRow, theirRow, {}, rowsDoNotBlend);
139
+ if (decision.outcome === "conflict" || decision.outcome === "conflict-no-base") {
140
+ conflicts.push(key);
141
+ out.push(conflictBlock(ourRow, theirRow));
142
+ continue;
143
+ }
144
+ // `write === null` means "leave ours alone" — unchanged, or their side did
145
+ // not move. Anything else is the row to take.
146
+ out.push(decision.write ?? ourRow);
147
+ }
148
+ // Rows only they have. Appended after the last row rather than interleaved:
149
+ // the matrix has no total order the driver could honour, and inventing one
150
+ // would reshuffle a file nobody asked to reshuffle. `specgate req` owns ordering.
151
+ const added = [...theirRows].filter(([key]) => !emitted.has(key)).map(([, line]) => line);
152
+ if (added.length > 0) {
153
+ const lastRow = lastRowIndex(out, mode);
154
+ out.splice(lastRow + 1, 0, ...added);
155
+ }
156
+ return { content: out.join("\n"), conflicts };
157
+ }
158
+ /** Where the final data row sits, so appended rows land inside the table. */
159
+ function lastRowIndex(lines, mode) {
160
+ for (let i = lines.length - 1; i >= 0; i -= 1) {
161
+ const line = lines[i];
162
+ if (line.trim().startsWith("|") && !line.includes("---") && rowKey(line, mode))
163
+ return i;
164
+ }
165
+ return lines.length - 1;
166
+ }
167
+ /**
168
+ * One row, both versions, in git's marker shape.
169
+ *
170
+ * **How to resolve one of these by hand:** the two lines are the same row as the
171
+ * two branches left it. Delete the three marker lines and the version you do not
172
+ * want, keeping exactly one row. Then run `specgate validate <project>` — it checks
173
+ * the statuses are legal and that no scenario id is duplicated, which is what
174
+ * catches a half-finished resolution. Do not keep both lines: a duplicated
175
+ * requirement is the one shape of corruption this file must never have.
176
+ */
177
+ function conflictBlock(ourRow, theirRow) {
178
+ return [`${OURS_MARK} ours`, ourRow, SPLIT_MARK, theirRow, `${THEIRS_MARK} theirs`].join("\n");
179
+ }
180
+ //# sourceMappingURL=TraceabilityMerge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraceabilityMerge.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/TraceabilityMerge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ValidationReport = void 0;
4
+ class ValidationReport {
5
+ findings = [];
6
+ get valid() {
7
+ return !this.findings.some((f) => f.severity === "error");
8
+ }
9
+ get errors() {
10
+ return this.findings.filter((f) => f.severity === "error");
11
+ }
12
+ get warnings() {
13
+ return this.findings.filter((f) => f.severity === "warning");
14
+ }
15
+ addError(code, message, opts = {}) {
16
+ this.findings.push({
17
+ severity: "error",
18
+ code,
19
+ message,
20
+ file: opts.file,
21
+ line: opts.line,
22
+ target: opts.target,
23
+ fix: opts.fix,
24
+ fixLines: opts.fixLines,
25
+ });
26
+ }
27
+ addWarning(code, message, opts = {}) {
28
+ this.findings.push({
29
+ severity: "warning",
30
+ code,
31
+ message,
32
+ file: opts.file,
33
+ line: opts.line,
34
+ target: opts.target,
35
+ fix: opts.fix,
36
+ fixLines: opts.fixLines,
37
+ });
38
+ }
39
+ addInfo(code, message, opts = {}) {
40
+ this.findings.push({
41
+ severity: "info",
42
+ code,
43
+ message,
44
+ file: opts.file,
45
+ line: opts.line,
46
+ target: opts.target,
47
+ fix: opts.fix,
48
+ fixLines: opts.fixLines,
49
+ });
50
+ }
51
+ }
52
+ exports.ValidationReport = ValidationReport;
53
+ //# sourceMappingURL=ValidationReport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationReport.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/ValidationReport.ts"],"names":[],"mappings":";;;AAoBA,MAAa,gBAAgB;IACpB,QAAQ,GAAwB,EAAE,CAAC;IAE1C,IAAW,KAAK;QACd,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAC7D,CAAC;IAED,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC;IAC/D,CAAC;IAEM,QAAQ,CAAC,IAAY,EAAE,OAAe,EAAE,OAAuB,EAAE;QACtE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,QAAQ,EAAE,OAAO;YACjB,IAAI;YACJ,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;IACL,CAAC;IAEM,UAAU,CAAC,IAAY,EAAE,OAAe,EAAE,OAAuB,EAAE;QACxE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,QAAQ,EAAE,SAAS;YACnB,IAAI;YACJ,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;IACL,CAAC;IAEM,OAAO,CAAC,IAAY,EAAE,OAAe,EAAE,OAAuB,EAAE;QACrE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,QAAQ,EAAE,MAAM;YAChB,IAAI;YACJ,OAAO;YACP,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;IACL,CAAC;CACF;AArDD,4CAqDC"}
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ /**
3
+ * Does the value a spec declares match the value the code declares?
4
+ * (`PLAN_PREDICTABLE_CODE_EVOLUTION.md` §8.6.)
5
+ *
6
+ * ## The gap this closes
7
+ *
8
+ * `--strict-requirements` (F6) checks that a requirement's prose states an
9
+ * obligation. `--strict-links` checks that a declared file still exists.
10
+ * Neither checks what Predictable Code's own page uses as its example:
11
+ * *"session timeout is 30m but spec requires 15m"*. This module compares an
12
+ * explicit value on each side — no AST, no unit inference, no guessing a
13
+ * variable's name from a requirement's prose.
14
+ *
15
+ * ## Why explicit annotation, and not something smarter
16
+ *
17
+ * The comparison is exact string equality between two things a human (or an
18
+ * agent) wrote on purpose:
19
+ *
20
+ * spec: `<!-- csda:trace uc=Login value_session_timeout=15m -->`
21
+ * code: `// csda:value session_timeout=15m`
22
+ *
23
+ * `csda:value` is a plain literal string, not a language-specific comment
24
+ * form — the same reason `csda:trace` works identically in every markdown
25
+ * file without knowing anything about markdown grammar. It is found by
26
+ * scanning line by line, so it reads the same inside `//`, `#`, `--`, or no
27
+ * comment marker at all. Interpreting units (`15m` vs `900000`) is exactly
28
+ * the claim `PLAN_PREDICTABLE_CODE_EVOLUTION.md` §5 refuses to make — that is
29
+ * the H13 trap, a check asserting authority over a grammar it does not parse.
30
+ *
31
+ * ## Why this is a report, not a gate
32
+ *
33
+ * See §8.6: annotating every checkable fact by hand does not scale with
34
+ * project size, and the fraction of requirements that reduce to a scalar
35
+ * value shrinks as a system gets more complex. `compareDeclaredValues` never
36
+ * decides pass/fail — it classifies. The caller (`ReportCommand.ts`) turns
37
+ * that into a coverage-style report section, the same shape as `needsTest`
38
+ * or `orphanFeatures`.
39
+ */
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.declaredSpecValues = declaredSpecValues;
42
+ exports.declaredCodeValues = declaredCodeValues;
43
+ exports.compareDeclaredValues = compareDeclaredValues;
44
+ const VALUE_PREFIX = "value_";
45
+ /**
46
+ * Every `value_<id>=<literal>` key in an already-parsed `csda:trace` comment.
47
+ *
48
+ * `SpecParser.parseTraceComment` already accepts any `[a-z_]+` key — this
49
+ * reads the convention out of the flat object it returns. No parser change,
50
+ * no new field.
51
+ */
52
+ function declaredSpecValues(trace) {
53
+ const out = [];
54
+ if (!trace)
55
+ return out;
56
+ for (const key of Object.keys(trace)) {
57
+ if (key.length > VALUE_PREFIX.length && key.startsWith(VALUE_PREFIX)) {
58
+ out.push({ id: key.slice(VALUE_PREFIX.length), value: trace[key] });
59
+ }
60
+ }
61
+ return out;
62
+ }
63
+ /**
64
+ * Every `csda:value <id>=<literal>` marker in a source file's text.
65
+ *
66
+ * Line-oriented, not language-aware — the marker is found by scanning text,
67
+ * not by parsing whatever comment syntax the file uses. `id` is restricted to
68
+ * `[a-z_]+`, the same identifier space `csda:trace` keys use, so a name is
69
+ * either checkable on both sides or on neither.
70
+ */
71
+ function declaredCodeValues(source) {
72
+ const out = [];
73
+ const re = /csda:value\s+([a-z_]+)\s*=\s*(\S+)/i;
74
+ const lines = String(source || "").split(/\r?\n/);
75
+ for (let i = 0; i < lines.length; i++) {
76
+ const m = re.exec(lines[i]);
77
+ if (m)
78
+ out.push({ id: m[1].toLowerCase(), value: m[2], line: i + 1 });
79
+ }
80
+ return out;
81
+ }
82
+ /**
83
+ * Compares one requirement's spec-declared values against the code values
84
+ * found in the file(s) that requirement's matrix row points at.
85
+ *
86
+ * Scoped per requirement, not global: two unrelated requirements reusing the
87
+ * same id (`session_timeout`) are never compared against each other, because
88
+ * the caller only ever passes one requirement's code entries at a time.
89
+ *
90
+ * A repeated code id (the same marker in two files) keeps its first
91
+ * occurrence, in the order the caller supplied — deterministic, not
92
+ * "whichever file happened to be read last".
93
+ */
94
+ function compareDeclaredValues(specEntries, codeEntries) {
95
+ const codeById = new Map();
96
+ for (const entry of codeEntries) {
97
+ if (!codeById.has(entry.id))
98
+ codeById.set(entry.id, entry);
99
+ }
100
+ const out = [];
101
+ const specIds = new Set(specEntries.map((e) => e.id));
102
+ for (const spec of specEntries) {
103
+ const code = codeById.get(spec.id);
104
+ if (!code) {
105
+ out.push({
106
+ id: spec.id,
107
+ specValue: spec.value,
108
+ codeValue: null,
109
+ codeFile: null,
110
+ codeLine: null,
111
+ status: "spec_only",
112
+ });
113
+ continue;
114
+ }
115
+ out.push({
116
+ id: spec.id,
117
+ specValue: spec.value,
118
+ codeValue: code.value,
119
+ codeFile: code.file,
120
+ codeLine: code.line,
121
+ status: code.value === spec.value ? "matched" : "diverging",
122
+ });
123
+ }
124
+ for (const code of codeById.values()) {
125
+ if (!specIds.has(code.id)) {
126
+ out.push({
127
+ id: code.id,
128
+ specValue: null,
129
+ codeValue: code.value,
130
+ codeFile: code.file,
131
+ codeLine: code.line,
132
+ status: "code_only",
133
+ });
134
+ }
135
+ }
136
+ return out;
137
+ }
138
+ //# sourceMappingURL=ValueAnnotations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValueAnnotations.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/ValueAnnotations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ /**
3
+ * What the agent was allowed to write — checked, not merely asked for (A1, H16).
4
+ *
5
+ * ## The hole this closes
6
+ *
7
+ * The prompt tells the agent not to touch the spec. Nothing verified it. An
8
+ * agent that cannot make a scenario pass can instead relax the scenario, or add
9
+ * a permissive line to `AI_RULES.md`, and the gate approves: `validate
10
+ * --strict-tdd` checks that the feature **exists** and is in the matrix, never
11
+ * that it still **says what it said before**.
12
+ *
13
+ * That is not a hypothetical. It is precisely the failure this product claims
14
+ * to prevent — "specs as executable contracts" stops being true the moment the
15
+ * executor can edit the contract. Same family as H1, H14 and H15: the gate
16
+ * approving without having verified.
17
+ *
18
+ * ## Why a new file is not a violation
19
+ *
20
+ * A requirement in category `NEEDS_FEATURE` is *supposed* to create its feature
21
+ * file, so a blanket ban on `features/**` would fail the legitimate case. The
22
+ * distinction A1 asks for — creating a file that did not exist is fine,
23
+ * modifying one that did is not — is one git already draws for us: an untracked
24
+ * path is new, a tracked change is an edit. No heuristics required.
25
+ *
26
+ * The exception is safe in the direction that matters. A matrix row points the
27
+ * gate at one specific feature file, so a *new* file cannot loosen the contract
28
+ * the gate is running; deleting the declared feature and writing a fresh one in
29
+ * its place shows up as a tracked deletion, and is refused.
30
+ *
31
+ * ## Why this module holds no git
32
+ *
33
+ * Deciding whether `features/core/health.feature` is protected is a rule.
34
+ * Finding out which paths changed is I/O. Keeping them apart is what lets every
35
+ * case below be tested without a repository, an agent, or twenty minutes.
36
+ */
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.DEFAULT_PROTECTED_PATHS = void 0;
39
+ exports.matchesGlob = matchesGlob;
40
+ exports.protectingPattern = protectingPattern;
41
+ exports.checkWriteScope = checkWriteScope;
42
+ exports.parseGitStatus = parseGitStatus;
43
+ /**
44
+ * Protected unless the project says otherwise.
45
+ *
46
+ * Everything here is a term of the contract the agent is working *against*:
47
+ * the business manifesto, the execution rules, the scenarios that decide pass
48
+ * or fail, the specification documents, the pack lockfile, and the harness
49
+ * configuration itself — an agent that may edit `harness.config.yaml` may
50
+ * disable its own gate.
51
+ */
52
+ exports.DEFAULT_PROTECTED_PATHS = Object.freeze([
53
+ "spec.md",
54
+ "AI_RULES.md",
55
+ "features/**/*.feature",
56
+ "docs/specs/**",
57
+ ".specops.lock",
58
+ "harness.config.yaml",
59
+ ]);
60
+ /**
61
+ * Glob matching, in the small dialect these patterns actually use.
62
+ *
63
+ * `**` crosses directory separators, `*` does not, `?` is one character. Enough
64
+ * for `features/**\/*.feature` and `docs/specs/**`, and no more: this package
65
+ * has no runtime dependencies (the CLI runs through `npx` on other people's
66
+ * machines), so a matcher is written rather than installed.
67
+ *
68
+ * A pattern naming a directory — `docs/specs/**` — also matches the directory
69
+ * itself, because a person writing that means "this subtree".
70
+ */
71
+ function matchesGlob(filePath, pattern) {
72
+ const normalise = (p) => p.replace(/\\/g, "/").replace(/^\.\//, "");
73
+ const target = normalise(filePath);
74
+ const glob = normalise(pattern);
75
+ const source = glob.split("").reduce((acc, _ch, i, chars) => {
76
+ if (i < acc.i)
77
+ return acc;
78
+ const rest = chars.slice(i).join("");
79
+ if (rest.startsWith("**/"))
80
+ return { out: acc.out + "(?:.*/)?", i: i + 3 };
81
+ if (rest.startsWith("**"))
82
+ return { out: acc.out + ".*", i: i + 2 };
83
+ const ch = chars[i];
84
+ if (ch === "*")
85
+ return { out: acc.out + "[^/]*", i: i + 1 };
86
+ if (ch === "?")
87
+ return { out: acc.out + "[^/]", i: i + 1 };
88
+ return { out: acc.out + ch.replace(/[.+^${}()|[\]\\]/g, "\\$&"), i: i + 1 };
89
+ }, { out: "", i: 0 }).out;
90
+ if (new RegExp(`^${source}$`).test(target))
91
+ return true;
92
+ // `docs/specs/**` means the subtree, and a person writing it means the
93
+ // directory too. Without this, `docs/specs` itself slips through.
94
+ if (glob.endsWith("/**")) {
95
+ const dir = glob.slice(0, -3);
96
+ return target === dir || target.startsWith(`${dir}/`);
97
+ }
98
+ return false;
99
+ }
100
+ /** The first protecting pattern, or `null` when the path is not protected. */
101
+ function protectingPattern(filePath, rules = {}) {
102
+ const allow = rules.allowPaths || [];
103
+ if (allow.some((pattern) => matchesGlob(filePath, pattern)))
104
+ return null;
105
+ const guarded = rules.protectedPaths || exports.DEFAULT_PROTECTED_PATHS;
106
+ return guarded.find((pattern) => matchesGlob(filePath, pattern)) || null;
107
+ }
108
+ /**
109
+ * Which of the agent's writes were out of scope.
110
+ *
111
+ * `added` paths are never violations — see the module note on `NEEDS_FEATURE`.
112
+ * Ordered by path so a report reads the same twice.
113
+ */
114
+ function checkWriteScope(changes, rules = {}) {
115
+ const violations = [];
116
+ for (const filePath of [...changes.modified].sort()) {
117
+ const pattern = protectingPattern(filePath, rules);
118
+ if (pattern)
119
+ violations.push({ path: filePath, pattern });
120
+ }
121
+ return violations;
122
+ }
123
+ /**
124
+ * `git status --porcelain`, split into what was edited and what is new.
125
+ *
126
+ * Parsing the status codes rather than guessing from the path is the lesson
127
+ * `change author` taught the hard way: it ran `git checkout` on everything and
128
+ * deleted the files that had never been tracked. `??` means new; every other
129
+ * code means the file existed and the agent changed it — including `D`
130
+ * (deleted) and both halves of a rename, which are edits to the contract by any
131
+ * reading.
132
+ */
133
+ function parseGitStatus(porcelain) {
134
+ const modified = [];
135
+ const added = [];
136
+ for (const raw of porcelain.split("\n")) {
137
+ if (!raw.trim())
138
+ continue;
139
+ const code = raw.slice(0, 2);
140
+ const rest = raw.slice(3);
141
+ if (code === "??") {
142
+ added.push(rest.trim());
143
+ continue;
144
+ }
145
+ // `R old -> new`: both sides are edits to something that existed.
146
+ if (rest.includes(" -> ")) {
147
+ const [from, to] = rest.split(" -> ");
148
+ modified.push(from.trim(), to.trim());
149
+ continue;
150
+ }
151
+ modified.push(rest.trim());
152
+ }
153
+ return { modified, added };
154
+ }
155
+ //# sourceMappingURL=WriteScope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WriteScope.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/WriteScope.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;;;AAkDH,kCA4BC;AAGD,8CAMC;AAQD,0CAUC;AAYD,wCAqBC;AAxID;;;;;;;;GAQG;AACU,QAAA,uBAAuB,GAAsB,MAAM,CAAC,MAAM,CAAC;IACtE,SAAS;IACT,aAAa;IACb,uBAAuB;IACvB,eAAe;IACf,eAAe;IACf,qBAAqB;CACtB,CAAC,CAAC;AAqBH;;;;;;;;;;GAUG;AACH,SAAgB,WAAW,CAAC,QAAgB,EAAE,OAAe;IAC3D,MAAM,SAAS,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAEhC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAClC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE;QACrB,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,UAAU,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3E,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;QACpE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,EAAE,KAAK,GAAG;YAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,OAAO,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5D,IAAI,EAAE,KAAK,GAAG;YAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3D,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IAC9E,CAAC,EACD,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAClB,CAAC,GAAG,CAAC;IAEN,IAAI,IAAI,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAExD,uEAAuE;IACvE,kEAAkE;IAClE,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9B,OAAO,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,SAAgB,iBAAiB,CAAC,QAAgB,EAAE,QAAyB,EAAE;IAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC;IACrC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzE,MAAM,OAAO,GAAG,KAAK,CAAC,cAAc,IAAI,+BAAuB,CAAC;IAChE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC;AAC3E,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAC7B,OAA0B,EAC1B,QAAyB,EAAE;IAE3B,MAAM,UAAU,GAA0B,EAAE,CAAC;IAC7C,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACpD,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACnD,IAAI,OAAO;YAAE,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,cAAc,CAAC,SAAiB;IAC9C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;YAAE,SAAS;QAC1B,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACxB,SAAS;QACX,CAAC;QACD,mEAAmE;QACnE,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACtC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;YACtC,SAAS;QACX,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC"}