ws-spec-kit 0.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (353) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +79 -0
  3. package/dist/adapters/cli/output.d.ts +15 -0
  4. package/dist/adapters/cli/output.js +21 -0
  5. package/dist/adapters/cli/output.js.map +1 -0
  6. package/dist/adapters/cli/workflow.d.ts +25 -0
  7. package/dist/adapters/cli/workflow.js +131 -0
  8. package/dist/adapters/cli/workflow.js.map +1 -0
  9. package/dist/adapters/connectors/git-native.d.ts +23 -0
  10. package/dist/adapters/connectors/git-native.js +521 -0
  11. package/dist/adapters/connectors/git-native.js.map +1 -0
  12. package/dist/adapters/connectors/github-cli.d.ts +23 -0
  13. package/dist/adapters/connectors/github-cli.js +213 -0
  14. package/dist/adapters/connectors/github-cli.js.map +1 -0
  15. package/dist/adapters/connectors/gitlab-cli.d.ts +23 -0
  16. package/dist/adapters/connectors/gitlab-cli.js +199 -0
  17. package/dist/adapters/connectors/gitlab-cli.js.map +1 -0
  18. package/dist/adapters/connectors/lark-cli.d.ts +24 -0
  19. package/dist/adapters/connectors/lark-cli.js +296 -0
  20. package/dist/adapters/connectors/lark-cli.js.map +1 -0
  21. package/dist/adapters/process/redaction.d.ts +2 -0
  22. package/dist/adapters/process/redaction.js +51 -0
  23. package/dist/adapters/process/redaction.js.map +1 -0
  24. package/dist/adapters/process/spawn-json.d.ts +37 -0
  25. package/dist/adapters/process/spawn-json.js +312 -0
  26. package/dist/adapters/process/spawn-json.js.map +1 -0
  27. package/dist/adapters/skills/claude.d.ts +1 -0
  28. package/dist/adapters/skills/claude.js +3 -0
  29. package/dist/adapters/skills/claude.js.map +1 -0
  30. package/dist/adapters/skills/codex.d.ts +1 -0
  31. package/dist/adapters/skills/codex.js +3 -0
  32. package/dist/adapters/skills/codex.js.map +1 -0
  33. package/dist/adapters/skills/cursor.d.ts +1 -0
  34. package/dist/adapters/skills/cursor.js +3 -0
  35. package/dist/adapters/skills/cursor.js.map +1 -0
  36. package/dist/adapters/skills/generic.d.ts +1 -0
  37. package/dist/adapters/skills/generic.js +2 -0
  38. package/dist/adapters/skills/generic.js.map +1 -0
  39. package/dist/adapters/skills/install.d.ts +28 -0
  40. package/dist/adapters/skills/install.js +571 -0
  41. package/dist/adapters/skills/install.js.map +1 -0
  42. package/dist/application/acquire.d.ts +60 -0
  43. package/dist/application/acquire.js +964 -0
  44. package/dist/application/acquire.js.map +1 -0
  45. package/dist/application/application.d.ts +21 -0
  46. package/dist/application/application.js +31 -0
  47. package/dist/application/application.js.map +1 -0
  48. package/dist/application/artifact-reader.d.ts +1 -0
  49. package/dist/application/artifact-reader.js +150 -0
  50. package/dist/application/artifact-reader.js.map +1 -0
  51. package/dist/application/artifact-writer.d.ts +1 -0
  52. package/dist/application/artifact-writer.js +268 -0
  53. package/dist/application/artifact-writer.js.map +1 -0
  54. package/dist/application/artifact.d.ts +28 -0
  55. package/dist/application/artifact.js +523 -0
  56. package/dist/application/artifact.js.map +1 -0
  57. package/dist/application/decide.d.ts +12 -0
  58. package/dist/application/decide.js +168 -0
  59. package/dist/application/decide.js.map +1 -0
  60. package/dist/application/doctor-connectors.d.ts +34 -0
  61. package/dist/application/doctor-connectors.js +99 -0
  62. package/dist/application/doctor-connectors.js.map +1 -0
  63. package/dist/application/external-action.d.ts +164 -0
  64. package/dist/application/external-action.js +670 -0
  65. package/dist/application/external-action.js.map +1 -0
  66. package/dist/application/initial-stages.d.ts +3 -0
  67. package/dist/application/initial-stages.js +7 -0
  68. package/dist/application/initial-stages.js.map +1 -0
  69. package/dist/application/inspect.d.ts +2 -0
  70. package/dist/application/inspect.js +31 -0
  71. package/dist/application/inspect.js.map +1 -0
  72. package/dist/application/profile.d.ts +32 -0
  73. package/dist/application/profile.js +70 -0
  74. package/dist/application/profile.js.map +1 -0
  75. package/dist/application/snapshot.d.ts +75 -0
  76. package/dist/application/snapshot.js +338 -0
  77. package/dist/application/snapshot.js.map +1 -0
  78. package/dist/application/start.d.ts +43 -0
  79. package/dist/application/start.js +360 -0
  80. package/dist/application/start.js.map +1 -0
  81. package/dist/application/state.d.ts +17 -0
  82. package/dist/application/state.js +94 -0
  83. package/dist/application/state.js.map +1 -0
  84. package/dist/application/submit.d.ts +18 -0
  85. package/dist/application/submit.js +1090 -0
  86. package/dist/application/submit.js.map +1 -0
  87. package/dist/cli/commands/core.d.ts +2 -0
  88. package/dist/cli/commands/core.js +205 -0
  89. package/dist/cli/commands/core.js.map +1 -0
  90. package/dist/cli/commands/public-contract.d.ts +12 -0
  91. package/dist/cli/commands/public-contract.js +47 -0
  92. package/dist/cli/commands/public-contract.js.map +1 -0
  93. package/dist/cli/main.d.ts +2 -0
  94. package/dist/cli/main.js +23 -0
  95. package/dist/cli/main.js.map +1 -0
  96. package/dist/domain/artifacts.d.ts +52 -0
  97. package/dist/domain/artifacts.js +241 -0
  98. package/dist/domain/artifacts.js.map +1 -0
  99. package/dist/domain/digests.d.ts +11 -0
  100. package/dist/domain/digests.js +106 -0
  101. package/dist/domain/digests.js.map +1 -0
  102. package/dist/domain/external-receipt.d.ts +48 -0
  103. package/dist/domain/external-receipt.js +138 -0
  104. package/dist/domain/external-receipt.js.map +1 -0
  105. package/dist/domain/ids.d.ts +7 -0
  106. package/dist/domain/ids.js +5 -0
  107. package/dist/domain/ids.js.map +1 -0
  108. package/dist/domain/repository-path.d.ts +3 -0
  109. package/dist/domain/repository-path.js +87 -0
  110. package/dist/domain/repository-path.js.map +1 -0
  111. package/dist/domain/states.d.ts +38 -0
  112. package/dist/domain/states.js +69 -0
  113. package/dist/domain/states.js.map +1 -0
  114. package/dist/domain/work-package-identity.d.ts +2 -0
  115. package/dist/domain/work-package-identity.js +10 -0
  116. package/dist/domain/work-package-identity.js.map +1 -0
  117. package/dist/domain/workflow.d.ts +58 -0
  118. package/dist/domain/workflow.js +2 -0
  119. package/dist/domain/workflow.js.map +1 -0
  120. package/dist/engine/actor-roles.d.ts +15 -0
  121. package/dist/engine/actor-roles.js +53 -0
  122. package/dist/engine/actor-roles.js.map +1 -0
  123. package/dist/engine/approvals.d.ts +44 -0
  124. package/dist/engine/approvals.js +239 -0
  125. package/dist/engine/approvals.js.map +1 -0
  126. package/dist/engine/archive.d.ts +24 -0
  127. package/dist/engine/archive.js +442 -0
  128. package/dist/engine/archive.js.map +1 -0
  129. package/dist/engine/compiler.d.ts +25 -0
  130. package/dist/engine/compiler.js +828 -0
  131. package/dist/engine/compiler.js.map +1 -0
  132. package/dist/engine/control/condition.d.ts +10 -0
  133. package/dist/engine/control/condition.js +49 -0
  134. package/dist/engine/control/condition.js.map +1 -0
  135. package/dist/engine/control/loop.d.ts +23 -0
  136. package/dist/engine/control/loop.js +96 -0
  137. package/dist/engine/control/loop.js.map +1 -0
  138. package/dist/engine/control/retry.d.ts +15 -0
  139. package/dist/engine/control/retry.js +54 -0
  140. package/dist/engine/control/retry.js.map +1 -0
  141. package/dist/engine/docs-integrity.d.ts +13 -0
  142. package/dist/engine/docs-integrity.js +34 -0
  143. package/dist/engine/docs-integrity.js.map +1 -0
  144. package/dist/engine/expressions/ast.d.ts +18 -0
  145. package/dist/engine/expressions/ast.js +9 -0
  146. package/dist/engine/expressions/ast.js.map +1 -0
  147. package/dist/engine/expressions/evaluate.d.ts +7 -0
  148. package/dist/engine/expressions/evaluate.js +47 -0
  149. package/dist/engine/expressions/evaluate.js.map +1 -0
  150. package/dist/engine/expressions/parser.d.ts +2 -0
  151. package/dist/engine/expressions/parser.js +173 -0
  152. package/dist/engine/expressions/parser.js.map +1 -0
  153. package/dist/engine/external-effects/authorization.d.ts +146 -0
  154. package/dist/engine/external-effects/authorization.js +222 -0
  155. package/dist/engine/external-effects/authorization.js.map +1 -0
  156. package/dist/engine/external-effects/idempotency.d.ts +14 -0
  157. package/dist/engine/external-effects/idempotency.js +26 -0
  158. package/dist/engine/external-effects/idempotency.js.map +1 -0
  159. package/dist/engine/external-effects/reconciliation.d.ts +11 -0
  160. package/dist/engine/external-effects/reconciliation.js +18 -0
  161. package/dist/engine/external-effects/reconciliation.js.map +1 -0
  162. package/dist/engine/results.d.ts +14 -0
  163. package/dist/engine/results.js +88 -0
  164. package/dist/engine/results.js.map +1 -0
  165. package/dist/engine/scheduler.d.ts +60 -0
  166. package/dist/engine/scheduler.js +225 -0
  167. package/dist/engine/scheduler.js.map +1 -0
  168. package/dist/engine/tdd/green-gate.d.ts +6 -0
  169. package/dist/engine/tdd/green-gate.js +72 -0
  170. package/dist/engine/tdd/green-gate.js.map +1 -0
  171. package/dist/engine/tdd/red-gate.d.ts +30 -0
  172. package/dist/engine/tdd/red-gate.js +531 -0
  173. package/dist/engine/tdd/red-gate.js.map +1 -0
  174. package/dist/engine/tdd/types.d.ts +89 -0
  175. package/dist/engine/tdd/types.js +38 -0
  176. package/dist/engine/tdd/types.js.map +1 -0
  177. package/dist/engine/verification.d.ts +56 -0
  178. package/dist/engine/verification.js +196 -0
  179. package/dist/engine/verification.js.map +1 -0
  180. package/dist/policy/profile.d.ts +24 -0
  181. package/dist/policy/profile.js +23 -0
  182. package/dist/policy/profile.js.map +1 -0
  183. package/dist/policy/risk.d.ts +33 -0
  184. package/dist/policy/risk.js +138 -0
  185. package/dist/policy/risk.js.map +1 -0
  186. package/dist/protocol/application.d.ts +196 -0
  187. package/dist/protocol/application.js +2 -0
  188. package/dist/protocol/application.js.map +1 -0
  189. package/dist/protocol/public-contract.d.ts +81 -0
  190. package/dist/protocol/public-contract.js +231 -0
  191. package/dist/protocol/public-contract.js.map +1 -0
  192. package/dist/protocol/work-package.d.ts +55 -0
  193. package/dist/protocol/work-package.js +2 -0
  194. package/dist/protocol/work-package.js.map +1 -0
  195. package/dist/registry/connectors/external-executor.d.ts +4 -0
  196. package/dist/registry/connectors/external-executor.js +249 -0
  197. package/dist/registry/connectors/external-executor.js.map +1 -0
  198. package/dist/registry/connectors/feishu-document.d.ts +21 -0
  199. package/dist/registry/connectors/feishu-document.js +197 -0
  200. package/dist/registry/connectors/feishu-document.js.map +1 -0
  201. package/dist/registry/connectors/git-commit.d.ts +32 -0
  202. package/dist/registry/connectors/git-commit.js +122 -0
  203. package/dist/registry/connectors/git-commit.js.map +1 -0
  204. package/dist/registry/connectors/issue.d.ts +68 -0
  205. package/dist/registry/connectors/issue.js +301 -0
  206. package/dist/registry/connectors/issue.js.map +1 -0
  207. package/dist/registry/connectors/knowledge-publish.d.ts +30 -0
  208. package/dist/registry/connectors/knowledge-publish.js +157 -0
  209. package/dist/registry/connectors/knowledge-publish.js.map +1 -0
  210. package/dist/registry/connectors/local-requirement.d.ts +19 -0
  211. package/dist/registry/connectors/local-requirement.js +177 -0
  212. package/dist/registry/connectors/local-requirement.js.map +1 -0
  213. package/dist/registry/connectors/manifest.d.ts +6 -0
  214. package/dist/registry/connectors/manifest.js +164 -0
  215. package/dist/registry/connectors/manifest.js.map +1 -0
  216. package/dist/registry/connectors/registry.d.ts +11 -0
  217. package/dist/registry/connectors/registry.js +34 -0
  218. package/dist/registry/connectors/registry.js.map +1 -0
  219. package/dist/registry/connectors/requirement-source.d.ts +46 -0
  220. package/dist/registry/connectors/requirement-source.js +513 -0
  221. package/dist/registry/connectors/requirement-source.js.map +1 -0
  222. package/dist/registry/connectors/runtime.d.ts +38 -0
  223. package/dist/registry/connectors/runtime.js +127 -0
  224. package/dist/registry/connectors/runtime.js.map +1 -0
  225. package/dist/registry/connectors/secret-detector.d.ts +19 -0
  226. package/dist/registry/connectors/secret-detector.js +85 -0
  227. package/dist/registry/connectors/secret-detector.js.map +1 -0
  228. package/dist/registry/connectors/semver.d.ts +8 -0
  229. package/dist/registry/connectors/semver.js +57 -0
  230. package/dist/registry/connectors/semver.js.map +1 -0
  231. package/dist/registry/connectors/types.d.ts +45 -0
  232. package/dist/registry/connectors/types.js +2 -0
  233. package/dist/registry/connectors/types.js.map +1 -0
  234. package/dist/registry/executors/registry.d.ts +15 -0
  235. package/dist/registry/executors/registry.js +68 -0
  236. package/dist/registry/executors/registry.js.map +1 -0
  237. package/dist/registry/executors/types.d.ts +19 -0
  238. package/dist/registry/executors/types.js +2 -0
  239. package/dist/registry/executors/types.js.map +1 -0
  240. package/dist/registry/skills/lock.d.ts +3 -0
  241. package/dist/registry/skills/lock.js +278 -0
  242. package/dist/registry/skills/lock.js.map +1 -0
  243. package/dist/registry/skills/resolver.d.ts +16 -0
  244. package/dist/registry/skills/resolver.js +353 -0
  245. package/dist/registry/skills/resolver.js.map +1 -0
  246. package/dist/registry/skills/types.d.ts +75 -0
  247. package/dist/registry/skills/types.js +9 -0
  248. package/dist/registry/skills/types.js.map +1 -0
  249. package/dist/resources/catalog.d.ts +20 -0
  250. package/dist/resources/catalog.js +111 -0
  251. package/dist/resources/catalog.js.map +1 -0
  252. package/dist/schemas/definitions.d.ts +5 -0
  253. package/dist/schemas/definitions.js +958 -0
  254. package/dist/schemas/definitions.js.map +1 -0
  255. package/dist/schemas/generate.d.ts +1 -0
  256. package/dist/schemas/generate.js +26 -0
  257. package/dist/schemas/generate.js.map +1 -0
  258. package/dist/schemas/index.d.ts +11 -0
  259. package/dist/schemas/index.js +54 -0
  260. package/dist/schemas/index.js.map +1 -0
  261. package/dist/storage/control-plane.d.ts +136 -0
  262. package/dist/storage/control-plane.js +688 -0
  263. package/dist/storage/control-plane.js.map +1 -0
  264. package/dist/storage/events.d.ts +36 -0
  265. package/dist/storage/events.js +185 -0
  266. package/dist/storage/events.js.map +1 -0
  267. package/dist/storage/external-action-payload.d.ts +33 -0
  268. package/dist/storage/external-action-payload.js +190 -0
  269. package/dist/storage/external-action-payload.js.map +1 -0
  270. package/dist/storage/files.d.ts +13 -0
  271. package/dist/storage/files.js +45 -0
  272. package/dist/storage/files.js.map +1 -0
  273. package/dist/storage/git.d.ts +4 -0
  274. package/dist/storage/git.js +21 -0
  275. package/dist/storage/git.js.map +1 -0
  276. package/dist/storage/project-config.d.ts +11 -0
  277. package/dist/storage/project-config.js +60 -0
  278. package/dist/storage/project-config.js.map +1 -0
  279. package/dist/storage/repository.d.ts +14 -0
  280. package/dist/storage/repository.js +151 -0
  281. package/dist/storage/repository.js.map +1 -0
  282. package/dist/storage/work-items.d.ts +77 -0
  283. package/dist/storage/work-items.js +373 -0
  284. package/dist/storage/work-items.js.map +1 -0
  285. package/dist/storage/workflow-trust.d.ts +38 -0
  286. package/dist/storage/workflow-trust.js +310 -0
  287. package/dist/storage/workflow-trust.js.map +1 -0
  288. package/dist/workflow-package/loader.d.ts +12 -0
  289. package/dist/workflow-package/loader.js +249 -0
  290. package/dist/workflow-package/loader.js.map +1 -0
  291. package/dist/workflow-package/lock.d.ts +6 -0
  292. package/dist/workflow-package/lock.js +12 -0
  293. package/dist/workflow-package/lock.js.map +1 -0
  294. package/dist/workflow-package/path-boundary.d.ts +5 -0
  295. package/dist/workflow-package/path-boundary.js +38 -0
  296. package/dist/workflow-package/path-boundary.js.map +1 -0
  297. package/dist/workflow-package/trust.d.ts +27 -0
  298. package/dist/workflow-package/trust.js +61 -0
  299. package/dist/workflow-package/trust.js.map +1 -0
  300. package/dist/workflow-package/types.d.ts +176 -0
  301. package/dist/workflow-package/types.js +9 -0
  302. package/dist/workflow-package/types.js.map +1 -0
  303. package/dist/workflow-package/workflow-v1.d.ts +3 -0
  304. package/dist/workflow-package/workflow-v1.js +274 -0
  305. package/dist/workflow-package/workflow-v1.js.map +1 -0
  306. package/package.json +40 -0
  307. package/resources/catalog.yaml +37 -0
  308. package/resources/connectors/github-cli.yaml +24 -0
  309. package/resources/connectors/gitlab-cli.yaml +24 -0
  310. package/resources/connectors/lark-cli.yaml +28 -0
  311. package/resources/skills/bug-fixing/SKILL.md +16 -0
  312. package/resources/skills/code-review/SKILL.md +16 -0
  313. package/resources/skills/documentation-editing/SKILL.md +16 -0
  314. package/resources/skills/documentation-exploration/SKILL.md +16 -0
  315. package/resources/skills/documentation-review/SKILL.md +16 -0
  316. package/resources/skills/requirement-exploration/SKILL.md +16 -0
  317. package/resources/skills/solution-design/SKILL.md +16 -0
  318. package/resources/skills/task-planning/SKILL.md +16 -0
  319. package/resources/skills/tdd-implementation/SKILL.md +16 -0
  320. package/resources/workflows/documentation-delivery/manifest.yaml +8 -0
  321. package/resources/workflows/documentation-delivery/profiles/governed.yaml +23 -0
  322. package/resources/workflows/documentation-delivery/profiles/quick.yaml +23 -0
  323. package/resources/workflows/documentation-delivery/profiles/standard.yaml +21 -0
  324. package/resources/workflows/documentation-delivery/workflow.yaml +109 -0
  325. package/resources/workflows/feature-delivery/manifest.yaml +8 -0
  326. package/resources/workflows/feature-delivery/profiles/governed.yaml +27 -0
  327. package/resources/workflows/feature-delivery/profiles/quick.yaml +25 -0
  328. package/resources/workflows/feature-delivery/profiles/standard.yaml +26 -0
  329. package/resources/workflows/feature-delivery/workflow.yaml +150 -0
  330. package/schemas/builtin-agent-action-v1.schema.json +509 -0
  331. package/schemas/builtin-application-acquire-input-v1.schema.json +25 -0
  332. package/schemas/builtin-application-artifact-create-input-v1.schema.json +49 -0
  333. package/schemas/builtin-application-decision-input-v1.schema.json +284 -0
  334. package/schemas/builtin-application-inspect-input-v1.schema.json +20 -0
  335. package/schemas/builtin-application-project-config-snapshot-v1.schema.json +289 -0
  336. package/schemas/builtin-application-project-config-v1.schema.json +293 -0
  337. package/schemas/builtin-application-start-input-v1.schema.json +92 -0
  338. package/schemas/builtin-application-submit-input-v1.schema.json +145 -0
  339. package/schemas/builtin-artifact-v1.schema.json +48 -0
  340. package/schemas/builtin-evidence-v1.schema.json +65 -0
  341. package/schemas/builtin-external-action-grant-v1.schema.json +298 -0
  342. package/schemas/builtin-external-action-request-v1.schema.json +288 -0
  343. package/schemas/builtin-external-binding-v1.schema.json +59 -0
  344. package/schemas/builtin-external-receipt-v1.schema.json +109 -0
  345. package/schemas/builtin-external-write-receipt-v1.schema.json +253 -0
  346. package/schemas/builtin-source-artifact-v1.schema.json +293 -0
  347. package/schemas/builtin-submit-result-v1.schema.json +111 -0
  348. package/schemas/builtin-tdd-cycle-evidence-v1.schema.json +119 -0
  349. package/schemas/builtin-tdd-node-test-report-v1.schema.json +103 -0
  350. package/schemas/builtin-tdd-trusted-evidence-v1.schema.json +184 -0
  351. package/schemas/builtin-work-item-v1.schema.json +201 -0
  352. package/schemas/builtin-work-package-v1.schema.json +254 -0
  353. package/schemas/builtin-workflow-selection-v1.schema.json +40 -0
@@ -0,0 +1,241 @@
1
+ import { readFile, realpath } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import * as canonicalizeModule from "canonicalize";
4
+ import { parse, stringify } from "yaml";
5
+ import { sha256 } from "./digests.js";
6
+ import { resolveRepositoryRegularFile } from "./repository-path.js";
7
+ import { SchemaValidationError, validate } from "../schemas/index.js";
8
+ const canonicalize = canonicalizeModule.default;
9
+ export function artifactOutputId(reference) {
10
+ if (reference.outputId !== undefined && reference.outputId !== "")
11
+ return reference.outputId;
12
+ return reference.artifactType === "requirement-source" ? "requirement-source" : undefined;
13
+ }
14
+ export class ArtifactError extends Error {
15
+ code;
16
+ constructor(code, message) {
17
+ super(message);
18
+ this.code = code;
19
+ this.name = "ArtifactError";
20
+ }
21
+ }
22
+ const sectionContracts = {
23
+ specification: ["目标与背景", "范围", "需求", "验收条件", "约束", "排除项", "开放问题"],
24
+ design: ["上下文与架构", "组件职责和边界", "接口与数据契约", "安全与权限", "失败与恢复", "兼容或迁移", "测试策略", "已知权衡"],
25
+ plan: ["有序交付任务", "任务依赖", "精确文件范围", "验证方式", "人工检查点", "回滚方式"],
26
+ tasks: ["任务"],
27
+ "implementation-result": ["实际改动", "修改文件", "计划偏差", "验证摘要", "未完成项", "残余风险"],
28
+ "review-result": ["Findings"],
29
+ "verification-result": ["Gate/Evidence 矩阵", "未通过项", "覆盖限制", "残余风险"],
30
+ "knowledge-entry": ["背景", "需求或 Bug", "关键决策", "实现摘要", "验证证据", "适用范围", "限制", "相关引用"],
31
+ };
32
+ export function normalizeArtifactBody(body) {
33
+ const normalized = body
34
+ .replaceAll("\r\n", "\n")
35
+ .replaceAll("\r", "\n")
36
+ .split("\n")
37
+ .map((line) => line.replace(/[ \t]+$/u, ""))
38
+ .join("\n")
39
+ .replace(/\n*$/u, "");
40
+ return `${normalized}\n`;
41
+ }
42
+ export function computeArtifactContentHash(metadataWithoutHash, body) {
43
+ const canonicalMetadata = canonicalize(metadataWithoutHash);
44
+ if (canonicalMetadata === undefined) {
45
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "Artifact 元数据无法规范化。");
46
+ }
47
+ return sha256(`${canonicalMetadata}\n${normalizeArtifactBody(body)}`);
48
+ }
49
+ export function createArtifactDocument(input) {
50
+ const body = normalizeArtifactBody(input.body);
51
+ verifySections(input.artifactType, body, true);
52
+ const metadataWithoutHash = {
53
+ artifactType: input.artifactType,
54
+ outputId: input.outputId,
55
+ schemaVersion: 1,
56
+ workItemId: input.workItemId,
57
+ stageId: input.stageId,
58
+ attemptId: input.attemptId,
59
+ revision: 1,
60
+ };
61
+ const contentHash = computeArtifactContentHash(metadataWithoutHash, body);
62
+ const metadata = { ...metadataWithoutHash, contentHash };
63
+ return {
64
+ content: `---\n${stringify(metadata, { lineWidth: 0 })}---\n${body}`,
65
+ reference: {
66
+ artifactType: input.artifactType,
67
+ outputId: input.outputId,
68
+ schemaVersion: 1,
69
+ mediaType: "text/markdown",
70
+ revision: 1,
71
+ contentHash,
72
+ },
73
+ };
74
+ }
75
+ function decodeStrict(buffer) {
76
+ if (buffer.length >= 3 && buffer[0] === 0xef && buffer[1] === 0xbb && buffer[2] === 0xbf) {
77
+ throw new ArtifactError("WSSPEC_ARTIFACT_ENCODING_INVALID", "Artifact 禁止 UTF-8 BOM。");
78
+ }
79
+ try {
80
+ return new TextDecoder("utf-8", { fatal: true }).decode(buffer);
81
+ }
82
+ catch {
83
+ throw new ArtifactError("WSSPEC_ARTIFACT_ENCODING_INVALID", "Artifact 必须是严格 UTF-8。");
84
+ }
85
+ }
86
+ export async function readArtifact(filename) {
87
+ const content = decodeStrict(await readFile(filename));
88
+ const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/u.exec(content);
89
+ if (match === null) {
90
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "Artifact 缺少完整 YAML front matter。");
91
+ }
92
+ let metadata;
93
+ try {
94
+ metadata = validate("builtin.artifact.v1", parse(match[1]));
95
+ }
96
+ catch (error) {
97
+ if (error instanceof SchemaValidationError) {
98
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", `${error.path}: ${error.message}`);
99
+ }
100
+ throw error;
101
+ }
102
+ return { metadata, body: match[2] };
103
+ }
104
+ function escapeRegExp(value) {
105
+ return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
106
+ }
107
+ function sectionBody(type, section, body) {
108
+ const heading = new RegExp(`^#{1,6}\\s+${escapeRegExp(section)}\\s*$`, "mu");
109
+ const match = heading.exec(body);
110
+ if (match === null)
111
+ throw new ArtifactError("WSSPEC_ARTIFACT_INCOMPLETE", `${type} 缺少必需章节:${section}`);
112
+ const afterHeading = body.slice(match.index + match[0].length).replace(/^\r?\n/u, "");
113
+ const nextHeading = /^#{1,6}\s+/mu.exec(afterHeading);
114
+ const content = afterHeading.slice(0, nextHeading?.index ?? afterHeading.length).trim();
115
+ if (content === "")
116
+ throw new ArtifactError("WSSPEC_ARTIFACT_INCOMPLETE", `${type} 的必需章节为空:${section}`);
117
+ return content;
118
+ }
119
+ function isRecord(value) {
120
+ return typeof value === "object" && value !== null && !Array.isArray(value);
121
+ }
122
+ function structuredYaml(type, section, body) {
123
+ const fenced = /```yaml\s*\n([\s\S]*?)\n```/u.exec(sectionBody(type, section, body));
124
+ if (fenced === null)
125
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", `${type}.${section} 缺少 fenced YAML。`);
126
+ const value = parse(fenced[1]);
127
+ if (!isRecord(value))
128
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", `${type}.${section} 必须是对象。`);
129
+ return value;
130
+ }
131
+ function requireString(record, field) {
132
+ const value = record[field];
133
+ if (typeof value !== "string" || value.trim() === "") {
134
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", `结构化字段 ${field} 必须是非空字符串。`);
135
+ }
136
+ return value;
137
+ }
138
+ function verifyStructuredContent(type, body) {
139
+ if (type === "tasks") {
140
+ const tasks = structuredYaml(type, "任务", body).tasks;
141
+ if (!Array.isArray(tasks) || tasks.length === 0)
142
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "tasks 必须是非空数组。");
143
+ for (const task of tasks) {
144
+ if (!isRecord(task) || !Array.isArray(task.dependencies))
145
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "task 结构不完整。");
146
+ requireString(task, "id");
147
+ requireString(task, "completion");
148
+ if (!["pending", "in_progress", "completed", "blocked"].includes(requireString(task, "status"))) {
149
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "task.status 不合法。");
150
+ }
151
+ }
152
+ }
153
+ if (type === "review-result") {
154
+ const findings = structuredYaml(type, "Findings", body).findings;
155
+ if (!Array.isArray(findings))
156
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "findings 必须是数组。");
157
+ for (const finding of findings) {
158
+ if (!isRecord(finding))
159
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "finding 必须是对象。");
160
+ requireString(finding, "id");
161
+ if (!["P0", "P1", "P2", "P3"].includes(requireString(finding, "severity"))) {
162
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "finding.severity 不合法。");
163
+ }
164
+ requireString(finding, "description");
165
+ requireString(finding, "evidence");
166
+ const findingPath = requireString(finding, "path");
167
+ if (path.isAbsolute(findingPath) || findingPath.split(/[\\/]/u).includes("..")) {
168
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "finding.path 必须是仓库相对路径。");
169
+ }
170
+ if (!["open", "fixed", "accepted", "false-positive"].includes(requireString(finding, "disposition"))) {
171
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "finding.disposition 不合法。");
172
+ }
173
+ if (finding.line !== undefined && (!Number.isInteger(finding.line) || finding.line < 1)) {
174
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "finding.line 必须是正整数。");
175
+ }
176
+ }
177
+ }
178
+ if (type === "verification-result") {
179
+ const gates = structuredYaml(type, "Gate/Evidence 矩阵", body).gates;
180
+ if (!Array.isArray(gates) || gates.length === 0)
181
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "gates 必须是非空数组。");
182
+ for (const gate of gates) {
183
+ if (!isRecord(gate) || typeof gate.required !== "boolean")
184
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "gate 结构不完整。");
185
+ for (const field of ["gateId", "expectedLevel", "evidenceId", "workspaceTreeDigest", "result"])
186
+ requireString(gate, field);
187
+ if (!(typeof gate.occurredAt === "string" || gate.occurredAt instanceof Date)) {
188
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_MISMATCH", "gate.occurredAt 必须是时间字符串。");
189
+ }
190
+ }
191
+ }
192
+ }
193
+ function verifySections(type, body, allowUnregisteredType) {
194
+ const sections = sectionContracts[type];
195
+ if (sections === undefined) {
196
+ if (allowUnregisteredType)
197
+ return;
198
+ throw new ArtifactError("WSSPEC_ARTIFACT_SCHEMA_NOT_FOUND", `未注册内置 Artifact 类型:${type}`);
199
+ }
200
+ for (const section of sections)
201
+ sectionBody(type, section, body);
202
+ verifyStructuredContent(type, body);
203
+ }
204
+ export async function verifyArtifact(filename, expected, options = {}) {
205
+ const root = await realpath(expected.repositoryRoot);
206
+ const relative = path.relative(path.resolve(expected.repositoryRoot), path.resolve(filename));
207
+ if (relative.startsWith("..") || path.isAbsolute(relative) || relative === "") {
208
+ throw new ArtifactError("WSSPEC_ARTIFACT_REFERENCE_INVALID", "Artifact 路径越出仓库边界。");
209
+ }
210
+ let actual;
211
+ try {
212
+ actual = await resolveRepositoryRegularFile(root, relative.split(path.sep).join("/"));
213
+ }
214
+ catch {
215
+ throw new ArtifactError("WSSPEC_ARTIFACT_REFERENCE_INVALID", "Artifact 必须是仓库内的普通文件,且不能经过符号链接。");
216
+ }
217
+ const artifact = await readArtifact(actual);
218
+ const { metadata } = artifact;
219
+ if (metadata.artifactType !== expected.artifactType ||
220
+ metadata.workItemId !== expected.workItemId ||
221
+ metadata.stageId !== expected.stageId ||
222
+ metadata.attemptId !== expected.attemptId) {
223
+ throw new ArtifactError("WSSPEC_ARTIFACT_REFERENCE_INVALID", "Artifact 类型或生产者身份与预期不符。");
224
+ }
225
+ verifySections(metadata.artifactType, artifact.body, options.allowUnregisteredType === true);
226
+ const { contentHash, ...metadataWithoutHash } = metadata;
227
+ const actualHash = computeArtifactContentHash(metadataWithoutHash, artifact.body);
228
+ if (actualHash !== contentHash) {
229
+ throw new ArtifactError("WSSPEC_ARTIFACT_HASH_MISMATCH", "Artifact 内容哈希与规范化内容不匹配。");
230
+ }
231
+ return {
232
+ artifactType: metadata.artifactType,
233
+ ...(metadata.outputId === undefined ? {} : { outputId: metadata.outputId }),
234
+ schemaVersion: metadata.schemaVersion,
235
+ path: relative.split(path.sep).join("/"),
236
+ mediaType: "text/markdown",
237
+ revision: metadata.revision,
238
+ contentHash,
239
+ };
240
+ }
241
+ //# sourceMappingURL=artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/domain/artifacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,kBAAkB,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAExC,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEtE,MAAM,YAAY,GAAG,kBAAkB,CAAC,OAA4D,CAAC;AAoCrG,MAAM,UAAU,gBAAgB,CAAC,SAA+D;IAC9F,IAAI,SAAS,CAAC,QAAQ,KAAK,SAAS,IAAI,SAAS,CAAC,QAAQ,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC,QAAQ,CAAC;IAC7F,OAAO,SAAS,CAAC,YAAY,KAAK,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5F,CAAC;AAED,MAAM,OAAO,aAAc,SAAQ,KAAK;IACjB;IAArB,YAAqB,IAAY,EAAE,OAAe;QAChD,KAAK,CAAC,OAAO,CAAC,CAAC;QADI,SAAI,GAAJ,IAAI,CAAQ;QAE/B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,gBAAgB,GAA6B;IACjD,aAAa,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC;IACjE,MAAM,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC;IACnF,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC;IAC3D,KAAK,EAAE,CAAC,IAAI,CAAC;IACb,uBAAuB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IACzE,eAAe,EAAE,CAAC,UAAU,CAAC;IAC7B,qBAAqB,EAAE,CAAC,kBAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IACnE,iBAAiB,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC;CACnF,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,MAAM,UAAU,GAAG,IAAI;SACpB,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC;SACxB,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC;SACtB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;SAC3C,IAAI,CAAC,IAAI,CAAC;SACV,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACxB,OAAO,GAAG,UAAU,IAAI,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,mBAA4C,EAAE,IAAY;IACnG,MAAM,iBAAiB,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAAC;IAC5D,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,oBAAoB,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,iBAAiB,KAAK,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAOtC;IACC,MAAM,IAAI,GAAG,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/C,cAAc,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/C,MAAM,mBAAmB,GAAG;QAC1B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,aAAa,EAAE,CAAU;QACzB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,QAAQ,EAAE,CAAC;KACZ,CAAC;IACF,MAAM,WAAW,GAAG,0BAA0B,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IAC1E,MAAM,QAAQ,GAAqB,EAAE,GAAG,mBAAmB,EAAE,WAAW,EAAE,CAAC;IAC3E,OAAO;QACL,OAAO,EAAE,QAAQ,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,QAAQ,IAAI,EAAE;QACpE,SAAS,EAAE;YACT,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,aAAa,EAAE,CAAC;YAChB,SAAS,EAAE,eAAe;YAC1B,QAAQ,EAAE,CAAC;YACX,WAAW;SACZ;KACF,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,MAAc;IAClC,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACzF,MAAM,IAAI,aAAa,CAAC,kCAAkC,EAAE,wBAAwB,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,aAAa,CAAC,kCAAkC,EAAE,uBAAuB,CAAC,CAAC;IACvF,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,6CAA6C,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1E,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,kCAAkC,CAAC,CAAC;IACjG,CAAC;IACD,IAAI,QAA0B,CAAC;IAC/B,IAAI,CAAC;QACH,QAAQ,GAAG,QAAQ,CAAmB,qBAAqB,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC;IACjF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,qBAAqB,EAAE,CAAC;YAC3C,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAChG,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC;AACvC,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK,CAAC,OAAO,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,OAAe,EAAE,IAAY;IAC9D,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,cAAc,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,KAAK,IAAI;QAAE,MAAM,IAAI,aAAa,CAAC,4BAA4B,EAAE,GAAG,IAAI,WAAW,OAAO,EAAE,CAAC,CAAC;IACvG,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACtF,MAAM,WAAW,GAAG,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACxF,IAAI,OAAO,KAAK,EAAE;QAAE,MAAM,IAAI,aAAa,CAAC,4BAA4B,EAAE,GAAG,IAAI,YAAY,OAAO,EAAE,CAAC,CAAC;IACxG,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,OAAe,EAAE,IAAY;IACjE,MAAM,MAAM,GAAG,8BAA8B,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IACrF,IAAI,MAAM,KAAK,IAAI;QAAE,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,GAAG,IAAI,IAAI,OAAO,kBAAkB,CAAC,CAAC;IACtH,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC;IAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,GAAG,IAAI,IAAI,OAAO,SAAS,CAAC,CAAC;IAC9G,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,MAA+B,EAAE,KAAa;IACnE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,SAAS,KAAK,YAAY,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,uBAAuB,CAAC,IAAY,EAAE,IAAY;IACzD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC;QACrD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,gBAAgB,CAAC,CAAC;QAC9H,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC;gBAAE,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,aAAa,CAAC,CAAC;YACpI,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC1B,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;YAClC,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;gBAChG,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,kBAAkB,CAAC,CAAC;YACjF,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC;QACjE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,iBAAiB,CAAC,CAAC;QAC5G,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,gBAAgB,CAAC,CAAC;YACrG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC7B,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;gBAC3E,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,uBAAuB,CAAC,CAAC;YACtF,CAAC;YACD,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YACtC,aAAa,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YACnC,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACnD,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/E,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,yBAAyB,CAAC,CAAC;YACxF,CAAC;YACD,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC;gBACrG,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,0BAA0B,CAAC,CAAC;YACzF,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAK,OAAO,CAAC,IAAe,GAAG,CAAC,CAAC,EAAE,CAAC;gBACpG,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,sBAAsB,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,IAAI,KAAK,qBAAqB,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC;QACnE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,gBAAgB,CAAC,CAAC;QAC9H,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAAE,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,aAAa,CAAC,CAAC;YACrI,KAAK,MAAM,KAAK,IAAI,CAAC,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,qBAAqB,EAAE,QAAQ,CAAC;gBAAE,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC3H,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,YAAY,IAAI,CAAC,EAAE,CAAC;gBAC9E,MAAM,IAAI,aAAa,CAAC,iCAAiC,EAAE,2BAA2B,CAAC,CAAC;YAC1F,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,IAAY,EAAE,qBAA8B;IAChF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,qBAAqB;YAAE,OAAO;QAClC,MAAM,IAAI,aAAa,CAAC,kCAAkC,EAAE,qBAAqB,IAAI,EAAE,CAAC,CAAC;IAC3F,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,QAAQ;QAAE,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACjE,uBAAuB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,QAAgB,EAChB,QAA6B,EAC7B,UAA+C,EAAE;IAEjD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9F,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;QAC9E,MAAM,IAAI,aAAa,CAAC,mCAAmC,EAAE,oBAAoB,CAAC,CAAC;IACrF,CAAC;IACD,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QAAC,MAAM,GAAG,MAAM,4BAA4B,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAAC,CAAC;IAC9F,MAAM,CAAC;QAAC,MAAM,IAAI,aAAa,CAAC,mCAAmC,EAAE,iCAAiC,CAAC,CAAC;IAAC,CAAC;IAC1G,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;IAC9B,IACE,QAAQ,CAAC,YAAY,KAAK,QAAQ,CAAC,YAAY;QAC/C,QAAQ,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU;QAC3C,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO;QACrC,QAAQ,CAAC,SAAS,KAAK,QAAQ,CAAC,SAAS,EACzC,CAAC;QACD,MAAM,IAAI,aAAa,CAAC,mCAAmC,EAAE,yBAAyB,CAAC,CAAC;IAC1F,CAAC;IACD,cAAc,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,qBAAqB,KAAK,IAAI,CAAC,CAAC;IAC7F,MAAM,EAAE,WAAW,EAAE,GAAG,mBAAmB,EAAE,GAAG,QAAQ,CAAC;IACzD,MAAM,UAAU,GAAG,0BAA0B,CAAC,mBAAmB,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClF,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;QAC/B,MAAM,IAAI,aAAa,CAAC,+BAA+B,EAAE,yBAAyB,CAAC,CAAC;IACtF,CAAC;IACD,OAAO;QACL,YAAY,EAAE,QAAQ,CAAC,YAAY;QACnC,GAAG,CAAC,QAAQ,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC3E,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QACxC,SAAS,EAAE,eAAe;QAC1B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,WAAW;KACZ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ export interface TreeEntry {
2
+ path: string;
3
+ type: "file" | "symlink" | "deleted";
4
+ mode: "100644" | "100755" | "120000" | "deleted";
5
+ digest?: string;
6
+ target?: string;
7
+ }
8
+ export declare function sha256(content: string | Uint8Array): string;
9
+ export declare function computeWorkspaceSnapshot(cwd: string): Promise<TreeEntry[]>;
10
+ export declare function computeWorkspaceTreeDigest(cwd: string): Promise<string>;
11
+ export declare function computeArtifactTreeDigest(cwd: string): Promise<string>;
@@ -0,0 +1,106 @@
1
+ import { createHash } from "node:crypto";
2
+ import { lstat, readFile, readdir, readlink } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { repositoryRoot, runGitRaw } from "../storage/git.js";
5
+ export function sha256(content) {
6
+ return `sha256:${createHash("sha256").update(content).digest("hex")}`;
7
+ }
8
+ function volatileRuntimePath(candidate) {
9
+ return /^\.wsspec\/work-items\/[^/]+\/control-plane\/(?:runtime\.json|events\.jsonl|runtime\.lock)$/u.test(candidate);
10
+ }
11
+ function artifactPath(candidate) {
12
+ return /^\.wsspec\/work-items\/[^/]+\/artifacts\//u.test(candidate);
13
+ }
14
+ async function snapshotPaths(root, paths) {
15
+ const entries = [];
16
+ for (const relativePath of paths) {
17
+ const absolutePath = path.join(root, relativePath);
18
+ try {
19
+ const stat = await lstat(absolutePath);
20
+ if (stat.isSymbolicLink()) {
21
+ entries.push({ path: relativePath, type: "symlink", mode: "120000", target: await readlink(absolutePath) });
22
+ }
23
+ else if (stat.isFile()) {
24
+ entries.push({
25
+ path: relativePath,
26
+ type: "file",
27
+ mode: (stat.mode & 0o111) === 0 ? "100644" : "100755",
28
+ digest: sha256(await readFile(absolutePath)),
29
+ });
30
+ }
31
+ }
32
+ catch (error) {
33
+ if (error.code === "ENOENT")
34
+ entries.push({ path: relativePath, type: "deleted", mode: "deleted" });
35
+ else
36
+ throw error;
37
+ }
38
+ }
39
+ return entries;
40
+ }
41
+ async function listedPaths(root) {
42
+ const output = await runGitRaw(root, ["ls-files", "-z", "--cached", "--others", "--exclude-standard"]);
43
+ return output.split("\0").filter((candidate) => candidate !== "")
44
+ .sort((left, right) => Buffer.from(left).compare(Buffer.from(right)));
45
+ }
46
+ async function artifactPaths(root) {
47
+ const itemRoot = path.join(root, ".wsspec", "work-items");
48
+ const result = [];
49
+ const walk = async (directory, relative) => {
50
+ const entries = await readdir(directory, { withFileTypes: true });
51
+ entries.sort((left, right) => Buffer.from(left.name).compare(Buffer.from(right.name)));
52
+ for (const entry of entries) {
53
+ const childRelative = `${relative}/${entry.name}`;
54
+ if (entry.isDirectory())
55
+ await walk(path.join(directory, entry.name), childRelative);
56
+ else
57
+ result.push(childRelative);
58
+ }
59
+ };
60
+ let items;
61
+ try {
62
+ items = await readdir(itemRoot, { withFileTypes: true });
63
+ }
64
+ catch (error) {
65
+ if (error.code === "ENOENT")
66
+ return [];
67
+ throw error;
68
+ }
69
+ items.sort((left, right) => Buffer.from(left.name).compare(Buffer.from(right.name)));
70
+ for (const item of items) {
71
+ if (!item.isDirectory())
72
+ continue;
73
+ const artifacts = path.join(itemRoot, item.name, "artifacts");
74
+ const relative = `.wsspec/work-items/${item.name}/artifacts`;
75
+ let stat;
76
+ try {
77
+ stat = await lstat(artifacts);
78
+ }
79
+ catch (error) {
80
+ if (error.code === "ENOENT")
81
+ continue;
82
+ throw error;
83
+ }
84
+ if (stat.isDirectory())
85
+ await walk(artifacts, relative);
86
+ else
87
+ result.push(relative);
88
+ }
89
+ return result.sort((left, right) => Buffer.from(left).compare(Buffer.from(right)));
90
+ }
91
+ export async function computeWorkspaceSnapshot(cwd) {
92
+ const root = await repositoryRoot(cwd);
93
+ const paths = (await listedPaths(root)).filter((candidate) => !artifactPath(candidate)
94
+ && !volatileRuntimePath(candidate) && !candidate.startsWith(".wsspec/archive/"));
95
+ return snapshotPaths(root, paths);
96
+ }
97
+ export async function computeWorkspaceTreeDigest(cwd) {
98
+ const entries = await computeWorkspaceSnapshot(cwd);
99
+ return sha256(`${JSON.stringify({ version: 1, entries })}\n`);
100
+ }
101
+ export async function computeArtifactTreeDigest(cwd) {
102
+ const root = await repositoryRoot(cwd);
103
+ const entries = await snapshotPaths(root, await artifactPaths(root));
104
+ return sha256(`${JSON.stringify({ version: 1, entries })}\n`);
105
+ }
106
+ //# sourceMappingURL=digests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digests.js","sourceRoot":"","sources":["../../src/domain/digests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import type { WorkPackage } from "../protocol/work-package.js";
2
+ export type ExternalTarget = "issue" | "knowledge";
3
+ export interface ExternalBinding {
4
+ version: 1;
5
+ kind: "external-binding";
6
+ target: ExternalTarget;
7
+ exists: true;
8
+ stableId: string;
9
+ externalWorkItemId: string;
10
+ publishStepId: string;
11
+ publishAttemptId: string;
12
+ publishInputDigest: string;
13
+ expectedPublishedContentDigest: string;
14
+ }
15
+ export interface ExternalReceipt {
16
+ version: 1;
17
+ kind: "external-receipt";
18
+ target: ExternalTarget;
19
+ stableId: string;
20
+ externalEffectKind?: "issue.comment";
21
+ externalEffectId?: string;
22
+ externalWorkItemId: string;
23
+ publishStepId: string;
24
+ publishAttemptId: string;
25
+ publishInputDigest: string;
26
+ publishedContentDigest: string;
27
+ readBackContentDigest: string;
28
+ status: "confirmed";
29
+ readBackStatus: "confirmed" | "stale" | "failed";
30
+ }
31
+ export declare function parseExternalReceipt(value: unknown): ExternalReceipt | undefined;
32
+ export declare function parseExternalBinding(value: unknown): ExternalBinding | undefined;
33
+ export declare function externalPublishTarget(action: string | undefined): ExternalTarget | undefined;
34
+ export declare function createExternalBinding(input: {
35
+ target: ExternalTarget;
36
+ workPackage: WorkPackage;
37
+ discoveryBinding: unknown;
38
+ expectedPublishedContentDigest?: string;
39
+ }): ExternalBinding;
40
+ export declare function externalReceiptValues(evidence: Readonly<Record<string, unknown>>): unknown[];
41
+ export declare function externalBindingValues(evidence: Readonly<Record<string, unknown>>): unknown[];
42
+ export declare function assertExternalReceipts(evidence: Readonly<Record<string, unknown>>, code: `WSSPEC_${string}`): void;
43
+ export declare function externalReceiptMatches(input: {
44
+ receipt: unknown;
45
+ target: ExternalTarget;
46
+ binding: unknown;
47
+ readBackRequired: boolean;
48
+ }): boolean;
@@ -0,0 +1,138 @@
1
+ import * as canonicalizeModule from "canonicalize";
2
+ import { sha256 } from "./digests.js";
3
+ import { validate } from "../schemas/index.js";
4
+ const canonicalize = canonicalizeModule.default;
5
+ function record(value) {
6
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : undefined;
7
+ }
8
+ export function parseExternalReceipt(value) {
9
+ try {
10
+ return validate("builtin.external-receipt.v1", value);
11
+ }
12
+ catch {
13
+ return undefined;
14
+ }
15
+ }
16
+ export function parseExternalBinding(value) {
17
+ try {
18
+ return validate("builtin.external-binding.v1", value);
19
+ }
20
+ catch {
21
+ return undefined;
22
+ }
23
+ }
24
+ function normalizedArtifacts(artifacts) {
25
+ if (artifacts.length === 0 || artifacts.some((artifact) => typeof artifact.contentHash !== "string" || artifact.contentHash === "")) {
26
+ throw new Error("External publish input 必须包含至少一个具有内容摘要的 Artifact。");
27
+ }
28
+ return artifacts.map((artifact) => ({
29
+ artifactType: artifact.artifactType,
30
+ ...(artifact.outputId === undefined ? {} : { outputId: artifact.outputId }),
31
+ schemaVersion: artifact.schemaVersion,
32
+ ...(artifact.path === undefined ? {} : { path: artifact.path.replaceAll("\\", "/") }),
33
+ ...(artifact.revision === undefined ? {} : { revision: artifact.revision }),
34
+ ...(artifact.contentHash === undefined ? {} : { contentHash: artifact.contentHash }),
35
+ ...(artifact.mediaType === undefined ? {} : { mediaType: artifact.mediaType }),
36
+ ...(artifact.contentLevel === undefined ? {} : { contentLevel: artifact.contentLevel }),
37
+ })).sort((left, right) => Buffer.from(JSON.stringify(left)).compare(Buffer.from(JSON.stringify(right))));
38
+ }
39
+ export function externalPublishTarget(action) {
40
+ if (action === "issue.update")
41
+ return "issue";
42
+ if (action === "knowledge.publish")
43
+ return "knowledge";
44
+ return undefined;
45
+ }
46
+ export function createExternalBinding(input) {
47
+ const discovery = record(input.discoveryBinding);
48
+ if (discovery?.exists !== true || typeof discovery.stableId !== "string" || discovery.stableId === ""
49
+ || typeof discovery.externalWorkItemId !== "string" || discovery.externalWorkItemId !== input.workPackage.workItemId) {
50
+ throw new Error(`External ${input.target} discovery binding 缺少当前 Work Item 的稳定身份。`);
51
+ }
52
+ const artifacts = normalizedArtifacts(input.workPackage.artifacts);
53
+ const content = canonicalize({ version: 1, target: input.target, artifacts });
54
+ const publishInput = canonicalize({
55
+ version: 1,
56
+ target: input.target,
57
+ workItemId: input.workPackage.workItemId,
58
+ stepId: input.workPackage.stepId,
59
+ attemptId: input.workPackage.attemptId,
60
+ artifacts,
61
+ });
62
+ if (content === undefined || publishInput === undefined)
63
+ throw new Error(`External ${input.target} publish input 无法规范化。`);
64
+ const expectedPublishedContentDigest = input.target === "knowledge"
65
+ ? input.expectedPublishedContentDigest
66
+ : sha256(content);
67
+ if ((input.target === "knowledge" && !/^sha256:[a-f0-9]{64}$/u.test(expectedPublishedContentDigest ?? ""))
68
+ || (input.target === "issue" && input.expectedPublishedContentDigest !== undefined)) {
69
+ throw new Error(`External ${input.target} publish content 摘要缺失或不符合生成规则。`);
70
+ }
71
+ return {
72
+ version: 1,
73
+ kind: "external-binding",
74
+ target: input.target,
75
+ exists: true,
76
+ stableId: discovery.stableId,
77
+ externalWorkItemId: discovery.externalWorkItemId,
78
+ publishStepId: input.workPackage.stepId,
79
+ publishAttemptId: input.workPackage.attemptId,
80
+ publishInputDigest: sha256(publishInput),
81
+ expectedPublishedContentDigest: expectedPublishedContentDigest,
82
+ };
83
+ }
84
+ export function externalReceiptValues(evidence) {
85
+ return Object.entries(evidence).filter(([key, value]) => key.startsWith("external-receipt:") || record(value)?.kind === "external-receipt")
86
+ .map(([, value]) => value);
87
+ }
88
+ export function externalBindingValues(evidence) {
89
+ return Object.entries(evidence).filter(([key, value]) => key.startsWith("external-binding:") || record(value)?.kind === "external-binding")
90
+ .map(([, value]) => value);
91
+ }
92
+ export function assertExternalReceipts(evidence, code) {
93
+ const invalidBinding = Object.entries(evidence)
94
+ .filter(([key, value]) => key.startsWith("external-binding:") || record(value)?.kind === "external-binding")
95
+ .some(([key, value]) => {
96
+ const binding = parseExternalBinding(value);
97
+ return binding === undefined
98
+ || key !== `external-binding:${binding.target}`;
99
+ });
100
+ const invalidReceipt = Object.entries(evidence)
101
+ .filter(([key, value]) => key.startsWith("external-receipt:") || record(value)?.kind === "external-receipt")
102
+ .some(([key, value]) => {
103
+ const receipt = parseExternalReceipt(value);
104
+ if (receipt === undefined)
105
+ return true;
106
+ return key !== `external-receipt:${receipt.target}`
107
+ || !externalReceiptMatches({
108
+ receipt,
109
+ target: receipt.target,
110
+ binding: evidence[`external-binding:${receipt.target}`],
111
+ readBackRequired: true,
112
+ });
113
+ });
114
+ if (invalidBinding || invalidReceipt) {
115
+ const error = new Error("External receipt 不符合严格身份与内容摘要契约。");
116
+ error.code = code;
117
+ throw error;
118
+ }
119
+ }
120
+ export function externalReceiptMatches(input) {
121
+ const receipt = parseExternalReceipt(input.receipt);
122
+ const binding = parseExternalBinding(input.binding);
123
+ return receipt !== undefined
124
+ && binding !== undefined
125
+ && receipt.target === input.target
126
+ && binding.target === input.target
127
+ && receipt.stableId === binding.stableId
128
+ && receipt.externalWorkItemId === binding.externalWorkItemId
129
+ && receipt.publishStepId === binding.publishStepId
130
+ && receipt.publishAttemptId === binding.publishAttemptId
131
+ && receipt.publishInputDigest === binding.publishInputDigest
132
+ && receipt.publishedContentDigest === binding.expectedPublishedContentDigest
133
+ && receipt.readBackContentDigest === binding.expectedPublishedContentDigest
134
+ && receipt.status === "confirmed"
135
+ && (!input.readBackRequired || (receipt.readBackStatus === "confirmed"
136
+ && receipt.readBackContentDigest === receipt.publishedContentDigest));
137
+ }
138
+ //# sourceMappingURL=external-receipt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-receipt.js","sourceRoot":"","sources":["../../src/domain/external-receipt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export type RepositoryId = `repo-${string}`;
2
+ export type WorkItemId = `WSS-${string}`;
3
+ export type ErrorCode = `WSSPEC_${string}`;
4
+ export type StageId = string;
5
+ export type AttemptId = `attempt-${string}`;
6
+ export declare const isWorkItemId: (value: string) => value is WorkItemId;
7
+ export declare const isErrorCode: (value: string) => value is ErrorCode;
@@ -0,0 +1,5 @@
1
+ const workItemIdPattern = /^WSS-[A-Za-z0-9-]+$/;
2
+ const errorCodePattern = /^WSSPEC_[A-Z0-9_]+$/;
3
+ export const isWorkItemId = (value) => workItemIdPattern.test(value);
4
+ export const isErrorCode = (value) => errorCodePattern.test(value);
5
+ //# sourceMappingURL=ids.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ids.js","sourceRoot":"","sources":["../../src/domain/ids.ts"],"names":[],"mappings":"AAMA,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAChD,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAE/C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAa,EAAuB,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAClG,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAa,EAAsB,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function isRepositoryRelativePattern(value: string): boolean;
2
+ export declare function matchesRepositoryPath(pattern: string, candidate: string): boolean;
3
+ export declare function resolveRepositoryRegularFile(root: string, relativePath: string): Promise<string>;