@zxyycom/vibe-check 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (670) hide show
  1. package/README.md +36 -5
  2. package/dist/esm/check/check.mjs +4 -0
  3. package/dist/esm/check/check.mjs.map +1 -1
  4. package/dist/esm/check/flag-enablement.mjs +32 -0
  5. package/dist/esm/check/flag-enablement.mjs.map +1 -0
  6. package/dist/esm/check/handoff-provider-identity.mjs +18 -0
  7. package/dist/esm/check/handoff-provider-identity.mjs.map +1 -0
  8. package/dist/esm/check/inherited-collection.mjs +1 -1
  9. package/dist/esm/check/inherited-collection.mjs.map +1 -1
  10. package/dist/esm/check/project-changes.mjs +2 -0
  11. package/dist/esm/check/project-changes.mjs.map +1 -0
  12. package/dist/esm/check/project-context.mjs +2 -0
  13. package/dist/esm/check/project-context.mjs.map +1 -0
  14. package/dist/esm/check-settlement/facts.mjs.map +1 -1
  15. package/dist/esm/check-settlement/record-store.mjs +1 -1
  16. package/dist/esm/check-settlement/record-store.mjs.map +1 -1
  17. package/dist/esm/data-boundary/canonical-data.mjs +36 -7
  18. package/dist/esm/data-boundary/canonical-data.mjs.map +1 -1
  19. package/dist/esm/data-boundary/canonical-json.mjs.map +1 -1
  20. package/dist/esm/data-boundary/closed-values.mjs +28 -4
  21. package/dist/esm/data-boundary/closed-values.mjs.map +1 -1
  22. package/dist/esm/{package-checks/project-files → data-boundary}/config-glob.mjs +3 -3
  23. package/dist/esm/data-boundary/config-glob.mjs.map +1 -0
  24. package/dist/esm/data-boundary/project-path.mjs +19 -0
  25. package/dist/esm/data-boundary/project-path.mjs.map +1 -0
  26. package/dist/esm/index.mjs +12 -5
  27. package/dist/esm/index.mjs.map +1 -1
  28. package/dist/esm/machine-output/v4/atomic-publication.mjs +4 -1
  29. package/dist/esm/machine-output/v4/atomic-publication.mjs.map +1 -1
  30. package/dist/esm/package-checks/check-authoring.mjs +69 -0
  31. package/dist/esm/package-checks/check-authoring.mjs.map +1 -0
  32. package/dist/esm/package-checks/code-quality-findings/finding-waiver-authoring.mjs.map +1 -1
  33. package/dist/esm/package-checks/code-quality-findings/finding-waiver-evidence.mjs.map +1 -1
  34. package/dist/esm/package-checks/command-check/command-check.mjs +55 -0
  35. package/dist/esm/package-checks/command-check/command-check.mjs.map +1 -0
  36. package/dist/esm/package-checks/command-check/contract.mjs +2 -0
  37. package/dist/esm/package-checks/command-check/contract.mjs.map +1 -0
  38. package/dist/esm/package-checks/command-check/execution.mjs +134 -0
  39. package/dist/esm/package-checks/command-check/execution.mjs.map +1 -0
  40. package/dist/esm/package-checks/command-check/options.mjs +284 -0
  41. package/dist/esm/package-checks/command-check/options.mjs.map +1 -0
  42. package/dist/esm/package-checks/command-check/transcript.mjs +26 -0
  43. package/dist/esm/package-checks/command-check/transcript.mjs.map +1 -0
  44. package/dist/esm/package-checks/duplicate-detection/default-check.mjs +9 -11
  45. package/dist/esm/package-checks/duplicate-detection/default-check.mjs.map +1 -1
  46. package/dist/esm/package-checks/duplicate-detection/execution.mjs +2 -4
  47. package/dist/esm/package-checks/duplicate-detection/execution.mjs.map +1 -1
  48. package/dist/esm/package-checks/duplicate-detection/finding-messages.mjs +1 -1
  49. package/dist/esm/package-checks/duplicate-detection/finding-messages.mjs.map +1 -1
  50. package/dist/esm/package-checks/duplicate-detection/jscpd/availability.mjs +1 -1
  51. package/dist/esm/package-checks/duplicate-detection/jscpd/availability.mjs.map +1 -1
  52. package/dist/esm/package-checks/duplicate-detection/options.mjs.map +1 -1
  53. package/dist/esm/package-checks/duplicate-detection/records.mjs.map +1 -1
  54. package/dist/esm/package-checks/file-metrics/constructor.mjs +9 -11
  55. package/dist/esm/package-checks/file-metrics/constructor.mjs.map +1 -1
  56. package/dist/esm/package-checks/file-metrics/execution.mjs +2 -4
  57. package/dist/esm/package-checks/file-metrics/execution.mjs.map +1 -1
  58. package/dist/esm/package-checks/file-metrics/finding-messages.mjs +1 -1
  59. package/dist/esm/package-checks/file-metrics/finding-messages.mjs.map +1 -1
  60. package/dist/esm/package-checks/file-metrics/options.mjs.map +1 -1
  61. package/dist/esm/package-checks/file-metrics/records.mjs.map +1 -1
  62. package/dist/esm/package-checks/file-metrics/scc/availability.mjs +1 -1
  63. package/dist/esm/package-checks/file-metrics/scc/availability.mjs.map +1 -1
  64. package/dist/esm/package-checks/file-metrics/scc/batch-planner.mjs +38 -0
  65. package/dist/esm/package-checks/file-metrics/scc/batch-planner.mjs.map +1 -0
  66. package/dist/esm/package-checks/file-metrics/scc/logical-scan-resources.mjs +35 -0
  67. package/dist/esm/package-checks/file-metrics/scc/logical-scan-resources.mjs.map +1 -0
  68. package/dist/esm/package-checks/file-metrics/scc/scanner.mjs +102 -29
  69. package/dist/esm/package-checks/file-metrics/scc/scanner.mjs.map +1 -1
  70. package/dist/esm/package-checks/function-metrics/analysis.mjs +7 -2
  71. package/dist/esm/package-checks/function-metrics/analysis.mjs.map +1 -1
  72. package/dist/esm/package-checks/function-metrics/analyzer/analysis-model.mjs +1 -1
  73. package/dist/esm/package-checks/function-metrics/analyzer/analysis-model.mjs.map +1 -1
  74. package/dist/esm/package-checks/function-metrics/analyzer/extensions/lizardcomplextags.mjs +1 -3
  75. package/dist/esm/package-checks/function-metrics/analyzer/extensions/lizardcomplextags.mjs.map +1 -1
  76. package/dist/esm/package-checks/function-metrics/analyzer/extensions/protocol.mjs.map +1 -1
  77. package/dist/esm/package-checks/function-metrics/analyzer/pipeline.mjs +3 -2
  78. package/dist/esm/package-checks/function-metrics/analyzer/pipeline.mjs.map +1 -1
  79. package/dist/esm/package-checks/function-metrics/analyzer/readers/erlang.mjs +6 -6
  80. package/dist/esm/package-checks/function-metrics/analyzer/readers/erlang.mjs.map +1 -1
  81. package/dist/esm/package-checks/function-metrics/analyzer/readers/fortran.mjs +1 -1
  82. package/dist/esm/package-checks/function-metrics/analyzer/readers/fortran.mjs.map +1 -1
  83. package/dist/esm/package-checks/function-metrics/analyzer/readers/objc.mjs +9 -3
  84. package/dist/esm/package-checks/function-metrics/analyzer/readers/objc.mjs.map +1 -1
  85. package/dist/esm/package-checks/function-metrics/analyzer/readers/php-states.mjs +12 -7
  86. package/dist/esm/package-checks/function-metrics/analyzer/readers/php-states.mjs.map +1 -1
  87. package/dist/esm/package-checks/function-metrics/analyzer/readers/plsql.mjs +6 -6
  88. package/dist/esm/package-checks/function-metrics/analyzer/readers/plsql.mjs.map +1 -1
  89. package/dist/esm/package-checks/function-metrics/analyzer/readers/python.mjs +5 -3
  90. package/dist/esm/package-checks/function-metrics/analyzer/readers/python.mjs.map +1 -1
  91. package/dist/esm/package-checks/function-metrics/analyzer/readers/r.mjs +2 -0
  92. package/dist/esm/package-checks/function-metrics/analyzer/readers/r.mjs.map +1 -1
  93. package/dist/esm/package-checks/function-metrics/analyzer/readers/ttcn.mjs +9 -3
  94. package/dist/esm/package-checks/function-metrics/analyzer/readers/ttcn.mjs.map +1 -1
  95. package/dist/esm/package-checks/function-metrics/analyzer/readers/typescript.mjs +9 -3
  96. package/dist/esm/package-checks/function-metrics/analyzer/readers/typescript.mjs.map +1 -1
  97. package/dist/esm/package-checks/function-metrics/analyzer/readers/zig.mjs +3 -1
  98. package/dist/esm/package-checks/function-metrics/analyzer/readers/zig.mjs.map +1 -1
  99. package/dist/esm/package-checks/function-metrics/analyzer/shared/code-reader.mjs +3 -1
  100. package/dist/esm/package-checks/function-metrics/analyzer/shared/code-reader.mjs.map +1 -1
  101. package/dist/esm/package-checks/function-metrics/analyzer/shared/js-style-regex.mjs +12 -5
  102. package/dist/esm/package-checks/function-metrics/analyzer/shared/js-style-regex.mjs.map +1 -1
  103. package/dist/esm/package-checks/function-metrics/analyzer-worker-port.mjs +20 -8
  104. package/dist/esm/package-checks/function-metrics/analyzer-worker-port.mjs.map +1 -1
  105. package/dist/esm/package-checks/function-metrics/constructor.mjs +9 -11
  106. package/dist/esm/package-checks/function-metrics/constructor.mjs.map +1 -1
  107. package/dist/esm/package-checks/function-metrics/execution.mjs +2 -4
  108. package/dist/esm/package-checks/function-metrics/execution.mjs.map +1 -1
  109. package/dist/esm/package-checks/function-metrics/finding-messages.mjs +1 -1
  110. package/dist/esm/package-checks/function-metrics/finding-messages.mjs.map +1 -1
  111. package/dist/esm/package-checks/function-metrics/measurement.mjs +3 -1
  112. package/dist/esm/package-checks/function-metrics/measurement.mjs.map +1 -1
  113. package/dist/esm/package-checks/function-metrics/options.mjs.map +1 -1
  114. package/dist/esm/package-checks/function-metrics/records.mjs.map +1 -1
  115. package/dist/esm/package-checks/host-environment/git.mjs +11 -0
  116. package/dist/esm/package-checks/host-environment/git.mjs.map +1 -1
  117. package/dist/esm/package-checks/host-environment/path.mjs +1 -17
  118. package/dist/esm/package-checks/host-environment/path.mjs.map +1 -1
  119. package/dist/esm/package-checks/host-environment/process/contract.mjs.map +1 -1
  120. package/dist/esm/package-checks/host-environment/process/result.mjs +43 -17
  121. package/dist/esm/package-checks/host-environment/process/result.mjs.map +1 -1
  122. package/dist/esm/package-checks/host-environment/process/runner.mjs +7 -5
  123. package/dist/esm/package-checks/host-environment/process/runner.mjs.map +1 -1
  124. package/dist/esm/package-checks/json-schema-validation/default-check.mjs +9 -11
  125. package/dist/esm/package-checks/json-schema-validation/default-check.mjs.map +1 -1
  126. package/dist/esm/package-checks/json-schema-validation/options.mjs.map +1 -1
  127. package/dist/esm/package-checks/json-schema-validation/reference-resolver.mjs +6 -2
  128. package/dist/esm/package-checks/json-schema-validation/reference-resolver.mjs.map +1 -1
  129. package/dist/esm/package-checks/json-schema-validation/schema-policy.mjs +11 -3
  130. package/dist/esm/package-checks/json-schema-validation/schema-policy.mjs.map +1 -1
  131. package/dist/esm/package-checks/json-validation/default-check.mjs +9 -11
  132. package/dist/esm/package-checks/json-validation/default-check.mjs.map +1 -1
  133. package/dist/esm/package-checks/json-validation/options.mjs.map +1 -1
  134. package/dist/esm/package-checks/local-cache-options.mjs +28 -0
  135. package/dist/esm/package-checks/local-cache-options.mjs.map +1 -0
  136. package/dist/esm/package-checks/maintenance-reminders/maintenance-reminders.mjs +37 -45
  137. package/dist/esm/package-checks/maintenance-reminders/maintenance-reminders.mjs.map +1 -1
  138. package/dist/esm/package-checks/maintenance-reminders/maintenance-support.mjs +3 -1
  139. package/dist/esm/package-checks/maintenance-reminders/maintenance-support.mjs.map +1 -1
  140. package/dist/esm/package-checks/markdown-link-validation/default-check.mjs +19 -33
  141. package/dist/esm/package-checks/markdown-link-validation/default-check.mjs.map +1 -1
  142. package/dist/esm/package-checks/markdown-link-validation/execution.mjs +1 -1
  143. package/dist/esm/package-checks/markdown-link-validation/execution.mjs.map +1 -1
  144. package/dist/esm/package-checks/markdown-link-validation/finding-messages.mjs +1 -1
  145. package/dist/esm/package-checks/markdown-link-validation/finding-messages.mjs.map +1 -1
  146. package/dist/esm/package-checks/markdown-link-validation/markdown-parser.mjs +1 -3
  147. package/dist/esm/package-checks/markdown-link-validation/markdown-parser.mjs.map +1 -1
  148. package/dist/esm/package-checks/markdown-link-validation/options-resolution.mjs +3 -18
  149. package/dist/esm/package-checks/markdown-link-validation/options-resolution.mjs.map +1 -1
  150. package/dist/esm/package-checks/markdown-link-validation/options-validation.mjs +2 -14
  151. package/dist/esm/package-checks/markdown-link-validation/options-validation.mjs.map +1 -1
  152. package/dist/esm/package-checks/markdown-link-validation/options.mjs.map +1 -1
  153. package/dist/esm/package-checks/markdown-link-validation/parse-facts-cache-payload.mjs +4 -5
  154. package/dist/esm/package-checks/markdown-link-validation/parse-facts-cache-payload.mjs.map +1 -1
  155. package/dist/esm/package-checks/markdown-lint/adapter.mjs +125 -0
  156. package/dist/esm/package-checks/markdown-lint/adapter.mjs.map +1 -0
  157. package/dist/esm/package-checks/markdown-lint/default-check.mjs +37 -0
  158. package/dist/esm/package-checks/markdown-lint/default-check.mjs.map +1 -0
  159. package/dist/esm/package-checks/markdown-lint/execution.mjs +202 -0
  160. package/dist/esm/package-checks/markdown-lint/execution.mjs.map +1 -0
  161. package/dist/esm/package-checks/markdown-lint/final-data.mjs +16 -0
  162. package/dist/esm/package-checks/markdown-lint/final-data.mjs.map +1 -0
  163. package/dist/esm/package-checks/markdown-lint/finding-messages.mjs +72 -0
  164. package/dist/esm/package-checks/markdown-lint/finding-messages.mjs.map +1 -0
  165. package/dist/esm/package-checks/markdown-lint/finding-waiver-identity.mjs +41 -0
  166. package/dist/esm/package-checks/markdown-lint/finding-waiver-identity.mjs.map +1 -0
  167. package/dist/esm/package-checks/markdown-lint/findings-cache.mjs +110 -0
  168. package/dist/esm/package-checks/markdown-lint/findings-cache.mjs.map +1 -0
  169. package/dist/esm/package-checks/markdown-lint/options-resolution.mjs +74 -0
  170. package/dist/esm/package-checks/markdown-lint/options-resolution.mjs.map +1 -0
  171. package/dist/esm/package-checks/markdown-lint/options-validation.mjs +41 -0
  172. package/dist/esm/package-checks/markdown-lint/options-validation.mjs.map +1 -0
  173. package/dist/esm/package-checks/markdown-lint/options.mjs +13 -0
  174. package/dist/esm/package-checks/markdown-lint/options.mjs.map +1 -0
  175. package/dist/esm/package-checks/markdown-lint/records.mjs +65 -0
  176. package/dist/esm/package-checks/markdown-lint/records.mjs.map +1 -0
  177. package/dist/esm/package-checks/markdown-lint/unavailable-reasons.mjs +14 -0
  178. package/dist/esm/package-checks/markdown-lint/unavailable-reasons.mjs.map +1 -0
  179. package/dist/esm/package-checks/project-files/collection.mjs +23 -19
  180. package/dist/esm/package-checks/project-files/collection.mjs.map +1 -1
  181. package/dist/esm/package-checks/project-files/configuration.mjs +1 -1
  182. package/dist/esm/package-checks/project-files/configuration.mjs.map +1 -1
  183. package/dist/esm/package-checks/project-files/gitlink-revision.mjs +2 -5
  184. package/dist/esm/package-checks/project-files/gitlink-revision.mjs.map +1 -1
  185. package/dist/esm/package-checks/project-files/gitlink-worktree.mjs +22 -6
  186. package/dist/esm/package-checks/project-files/gitlink-worktree.mjs.map +1 -1
  187. package/dist/esm/package-checks/project-files/public-collection.mjs +1 -1
  188. package/dist/esm/package-checks/project-files/public-collection.mjs.map +1 -1
  189. package/dist/esm/package-checks/project-files/revision-paths.mjs +3 -3
  190. package/dist/esm/package-checks/project-files/revision-paths.mjs.map +1 -1
  191. package/dist/esm/package-checks/project-files/revision-worktree-files.mjs +11 -15
  192. package/dist/esm/package-checks/project-files/revision-worktree-files.mjs.map +1 -1
  193. package/dist/esm/package-checks/secret-detection/default-check.mjs +9 -11
  194. package/dist/esm/package-checks/secret-detection/default-check.mjs.map +1 -1
  195. package/dist/esm/package-checks/secret-detection/execution.mjs +2 -2
  196. package/dist/esm/package-checks/secret-detection/execution.mjs.map +1 -1
  197. package/dist/esm/package-checks/secret-detection/input-preparation.mjs +46 -7
  198. package/dist/esm/package-checks/secret-detection/input-preparation.mjs.map +1 -1
  199. package/dist/esm/package-checks/secret-detection/options.mjs.map +1 -1
  200. package/dist/esm/package-checks/secret-detection/records.mjs.map +1 -1
  201. package/dist/esm/package-checks/secret-detection/secretlint/adapter.mjs +3 -4
  202. package/dist/esm/package-checks/secret-detection/secretlint/adapter.mjs.map +1 -1
  203. package/dist/esm/package-tools/admission-policy/define-admission-policy.mjs +10 -0
  204. package/dist/esm/package-tools/admission-policy/define-admission-policy.mjs.map +1 -0
  205. package/dist/esm/{cache → package-tools/cache}/cache-json-by-key.mjs +13 -14
  206. package/dist/esm/package-tools/cache/cache-json-by-key.mjs.map +1 -0
  207. package/dist/esm/package-tools/finding-presentation/finding-presentation.mjs.map +1 -0
  208. package/dist/esm/{finding-waivers → package-tools/finding-waivers}/reconciliation.mjs +14 -5
  209. package/dist/esm/package-tools/finding-waivers/reconciliation.mjs.map +1 -0
  210. package/dist/esm/package-tools/learned-critical-path/critical-path-ranking.mjs.map +1 -0
  211. package/dist/esm/package-tools/learned-critical-path/duration-model/bounded-history.mjs.map +1 -0
  212. package/dist/esm/{learned-critical-path → package-tools/learned-critical-path}/duration-model/prediction.mjs +2 -2
  213. package/dist/esm/package-tools/learned-critical-path/duration-model/prediction.mjs.map +1 -0
  214. package/dist/esm/{learned-critical-path → package-tools/learned-critical-path}/duration-model/preparation.mjs +4 -2
  215. package/dist/esm/package-tools/learned-critical-path/duration-model/preparation.mjs.map +1 -0
  216. package/dist/esm/package-tools/learned-critical-path/duration-model/recording.mjs.map +1 -0
  217. package/dist/esm/{learned-critical-path → package-tools/learned-critical-path}/duration-model/storage.mjs +8 -8
  218. package/dist/esm/package-tools/learned-critical-path/duration-model/storage.mjs.map +1 -0
  219. package/dist/esm/{learned-critical-path → package-tools/learned-critical-path}/selection-layers.mjs +1 -2
  220. package/dist/esm/package-tools/learned-critical-path/selection-layers.mjs.map +1 -0
  221. package/dist/esm/package-tools/learned-critical-path/static-decision.mjs.map +1 -0
  222. package/dist/esm/{learned-critical-path → package-tools/learned-critical-path}/strategy.mjs +3 -3
  223. package/dist/esm/package-tools/learned-critical-path/strategy.mjs.map +1 -0
  224. package/dist/esm/project-definition/check-tree/authoring.mjs +8 -5
  225. package/dist/esm/project-definition/check-tree/authoring.mjs.map +1 -1
  226. package/dist/esm/project-definition/check-tree/check-fields-authoring.mjs +79 -66
  227. package/dist/esm/project-definition/check-tree/check-fields-authoring.mjs.map +1 -1
  228. package/dist/esm/project-definition/check-tree/flag-conditions.mjs +71 -0
  229. package/dist/esm/project-definition/check-tree/flag-conditions.mjs.map +1 -0
  230. package/dist/esm/project-definition/check-tree/materialization.mjs +13 -8
  231. package/dist/esm/project-definition/check-tree/materialization.mjs.map +1 -1
  232. package/dist/esm/project-definition/check-tree/resolution.mjs +7 -6
  233. package/dist/esm/project-definition/check-tree/resolution.mjs.map +1 -1
  234. package/dist/esm/project-definition/declarative-snapshot.mjs +2 -1
  235. package/dist/esm/project-definition/declarative-snapshot.mjs.map +1 -1
  236. package/dist/esm/project-definition/project-changes.mjs +70 -0
  237. package/dist/esm/project-definition/project-changes.mjs.map +1 -0
  238. package/dist/esm/project-definition/project-definition-validation.mjs +40 -8
  239. package/dist/esm/project-definition/project-definition-validation.mjs.map +1 -1
  240. package/dist/esm/project-definition/project-definition.mjs +22 -15
  241. package/dist/esm/project-definition/project-definition.mjs.map +1 -1
  242. package/dist/esm/project-definition/scheduler-policy.mjs.map +1 -1
  243. package/dist/esm/project-run/admission-strategy-provider/custom-strategy-preparation.mjs +9 -6
  244. package/dist/esm/project-run/admission-strategy-provider/custom-strategy-preparation.mjs.map +1 -1
  245. package/dist/esm/project-run/admission-strategy-provider/prepared-admission-strategy.mjs.map +1 -1
  246. package/dist/esm/project-run/aggregation.mjs +42 -59
  247. package/dist/esm/project-run/aggregation.mjs.map +1 -1
  248. package/dist/esm/project-run/changes/git.mjs +161 -0
  249. package/dist/esm/project-run/changes/git.mjs.map +1 -0
  250. package/dist/esm/project-run/check-execution/admitted-check-execution.mjs +41 -0
  251. package/dist/esm/project-run/check-execution/admitted-check-execution.mjs.map +1 -0
  252. package/dist/esm/project-run/check-execution/callback.mjs +3 -2
  253. package/dist/esm/project-run/check-execution/callback.mjs.map +1 -1
  254. package/dist/esm/project-run/check-execution/dependencies.mjs +80 -5
  255. package/dist/esm/project-run/check-execution/dependencies.mjs.map +1 -1
  256. package/dist/esm/project-run/check-execution/execution-finalization.mjs +5 -3
  257. package/dist/esm/project-run/check-execution/execution-finalization.mjs.map +1 -1
  258. package/dist/esm/project-run/check-execution/execution-settlement.mjs +37 -16
  259. package/dist/esm/project-run/check-execution/execution-settlement.mjs.map +1 -1
  260. package/dist/esm/project-run/check-execution/flag-controls.mjs +15 -7
  261. package/dist/esm/project-run/check-execution/flag-controls.mjs.map +1 -1
  262. package/dist/esm/project-run/check-execution/lifecycle.mjs.map +1 -1
  263. package/dist/esm/project-run/check-execution/{preflight-result.mjs → preparation-result.mjs} +24 -24
  264. package/dist/esm/project-run/check-execution/preparation-result.mjs.map +1 -0
  265. package/dist/esm/project-run/check-execution/{preflight.mjs → preparation.mjs} +52 -52
  266. package/dist/esm/project-run/check-execution/preparation.mjs.map +1 -0
  267. package/dist/esm/project-run/check-execution/ready-check-execution.mjs +71 -0
  268. package/dist/esm/project-run/check-execution/ready-check-execution.mjs.map +1 -0
  269. package/dist/esm/project-run/check-execution/resolved-checks.mjs +27 -164
  270. package/dist/esm/project-run/check-execution/resolved-checks.mjs.map +1 -1
  271. package/dist/esm/project-run/check-execution/scheduled-check-run.mjs +79 -0
  272. package/dist/esm/project-run/check-execution/scheduled-check-run.mjs.map +1 -0
  273. package/dist/esm/project-run/check-execution/terminal-result.mjs +70 -25
  274. package/dist/esm/project-run/check-execution/terminal-result.mjs.map +1 -1
  275. package/dist/esm/project-run/completion/completion.mjs +18 -1
  276. package/dist/esm/project-run/completion/completion.mjs.map +1 -1
  277. package/dist/esm/project-run/controls/contract.mjs.map +1 -1
  278. package/dist/esm/project-run/controls/validation.mjs +7 -54
  279. package/dist/esm/project-run/controls/validation.mjs.map +1 -1
  280. package/dist/esm/project-run/diagnostic-logging/diagnostic-detail-rendering.mjs +3 -3
  281. package/dist/esm/project-run/diagnostic-logging/diagnostic-detail-rendering.mjs.map +1 -1
  282. package/dist/esm/project-run/diagnostic-logging/observation-rendering.mjs +1 -1
  283. package/dist/esm/project-run/diagnostic-logging/observation-rendering.mjs.map +1 -1
  284. package/dist/esm/project-run/invocation/candidate.mjs +17 -13
  285. package/dist/esm/project-run/invocation/candidate.mjs.map +1 -1
  286. package/dist/esm/project-run/invocation/candidates.mjs +26 -0
  287. package/dist/esm/project-run/invocation/candidates.mjs.map +1 -0
  288. package/dist/esm/project-run/invocation/creation.mjs +7 -3
  289. package/dist/esm/project-run/invocation/creation.mjs.map +1 -1
  290. package/dist/esm/project-run/invocation/execution.mjs +98 -0
  291. package/dist/esm/project-run/invocation/execution.mjs.map +1 -0
  292. package/dist/esm/project-run/invocation/run.mjs +13 -112
  293. package/dist/esm/project-run/invocation/run.mjs.map +1 -1
  294. package/dist/esm/project-run/invocation/scheduler.mjs +13 -6
  295. package/dist/esm/project-run/invocation/scheduler.mjs.map +1 -1
  296. package/dist/esm/project-run/outputs/status.mjs +12 -12
  297. package/dist/esm/project-run/outputs/status.mjs.map +1 -1
  298. package/dist/esm/project-run/progress-rendering/presentation.mjs +31 -11
  299. package/dist/esm/project-run/progress-rendering/presentation.mjs.map +1 -1
  300. package/dist/esm/project-run/progress-rendering/renderer-formatting.mjs +11 -4
  301. package/dist/esm/project-run/progress-rendering/renderer-formatting.mjs.map +1 -1
  302. package/dist/esm/project-run/progress-rendering/renderer-lifecycle.mjs +20 -6
  303. package/dist/esm/project-run/progress-rendering/renderer-lifecycle.mjs.map +1 -1
  304. package/dist/esm/project-run/progress-rendering/renderer.mjs +6 -2
  305. package/dist/esm/project-run/progress-rendering/renderer.mjs.map +1 -1
  306. package/dist/esm/project-run/project-context.mjs +2 -1
  307. package/dist/esm/project-run/project-context.mjs.map +1 -1
  308. package/dist/esm/project-run/result.mjs +2 -2
  309. package/dist/esm/project-run/result.mjs.map +1 -1
  310. package/dist/esm/project-run/run.mjs.map +1 -1
  311. package/dist/esm/project-run/task-scheduler/admission-core/compiled-graph-lookup.mjs +45 -0
  312. package/dist/esm/project-run/task-scheduler/admission-core/compiled-graph-lookup.mjs.map +1 -0
  313. package/dist/esm/project-run/task-scheduler/admission-core/compiled-graph.mjs +9 -4
  314. package/dist/esm/project-run/task-scheduler/admission-core/compiled-graph.mjs.map +1 -1
  315. package/dist/esm/project-run/task-scheduler/admission-core/selection-query.mjs +3 -5
  316. package/dist/esm/project-run/task-scheduler/admission-core/selection-query.mjs.map +1 -1
  317. package/dist/esm/project-run/task-scheduler/admission-core/selection-seed.mjs +25 -8
  318. package/dist/esm/project-run/task-scheduler/admission-core/selection-seed.mjs.map +1 -1
  319. package/dist/esm/project-run/task-scheduler/admission-core/selection-transition.mjs +8 -8
  320. package/dist/esm/project-run/task-scheduler/admission-core/selection-transition.mjs.map +1 -1
  321. package/dist/esm/project-run/task-scheduler/execution-state.mjs.map +1 -1
  322. package/dist/esm/project-run/task-scheduler/measurement/diagnostics.mjs +8 -4
  323. package/dist/esm/project-run/task-scheduler/measurement/diagnostics.mjs.map +1 -1
  324. package/dist/esm/project-run/task-scheduler/measurement/timing.mjs +12 -6
  325. package/dist/esm/project-run/task-scheduler/measurement/timing.mjs.map +1 -1
  326. package/dist/esm/project-run/task-scheduler/scheduler-observation.mjs +3 -1
  327. package/dist/esm/project-run/task-scheduler/scheduler-observation.mjs.map +1 -1
  328. package/dist/esm/project-run/task-scheduler/scheduler-terminal-measurement.mjs +17 -17
  329. package/dist/esm/project-run/task-scheduler/scheduler-terminal-measurement.mjs.map +1 -1
  330. package/dist/esm/project-run/task-scheduler/scheduler.mjs +18 -6
  331. package/dist/esm/project-run/task-scheduler/scheduler.mjs.map +1 -1
  332. package/docs/api-mechanics.md +147 -28
  333. package/docs/changelog.md +145 -2
  334. package/docs/checks/duplicate-detection.md +22 -3
  335. package/docs/checks/file-metrics.md +25 -6
  336. package/docs/checks/function-metrics.md +21 -2
  337. package/docs/checks/json-schema-validation.md +25 -4
  338. package/docs/checks/json-validation.md +24 -5
  339. package/docs/checks/maintenance-reminders.md +30 -6
  340. package/docs/checks/markdown-link-validation.md +24 -4
  341. package/docs/checks/markdown-lint.md +167 -0
  342. package/docs/checks/secret-detection.md +31 -7
  343. package/docs/examples/artifacts/mixed-outcomes/definition.ts +10 -10
  344. package/docs/guides/building-project-gate.md +706 -0
  345. package/docs/guides/callbacks.md +81 -22
  346. package/docs/guides/check-dependencies.md +41 -10
  347. package/docs/guides/collecting-project-files.md +7 -7
  348. package/docs/guides/command-check.md +155 -0
  349. package/docs/guides/data-boundaries.md +140 -0
  350. package/docs/guides/extending-check-lifecycle.md +77 -25
  351. package/docs/guides/finding-waivers.md +43 -1
  352. package/docs/guides/learned-scheduling.md +1 -1
  353. package/docs/guides/run-outputs.md +35 -9
  354. package/docs/guides/scheduling.md +15 -15
  355. package/docs/output.md +6 -5
  356. package/package.json +2 -1
  357. package/src/check/check.ts +332 -92
  358. package/src/check/flag-enablement.ts +76 -0
  359. package/src/check/handoff-provider-identity.ts +34 -0
  360. package/src/check/inherited-collection.ts +1 -1
  361. package/src/check/project-changes.ts +14 -0
  362. package/src/check/project-context.ts +11 -0
  363. package/src/check-settlement/facts.ts +1 -1
  364. package/src/check-settlement/record-store.ts +1 -1
  365. package/src/data-boundary/canonical-data.ts +36 -9
  366. package/src/data-boundary/canonical-json.ts +18 -1
  367. package/src/data-boundary/closed-values.ts +26 -6
  368. package/src/data-boundary/config-glob.ts +17 -0
  369. package/src/data-boundary/project-path.ts +21 -0
  370. package/src/index.ts +72 -11
  371. package/src/machine-output/v4/atomic-publication.ts +3 -1
  372. package/src/package-checks/check-authoring.ts +136 -0
  373. package/src/package-checks/code-quality-findings/finding-waiver-authoring.ts +1 -1
  374. package/src/package-checks/code-quality-findings/finding-waiver-evidence.ts +1 -1
  375. package/src/package-checks/command-check/command-check.ts +152 -0
  376. package/src/package-checks/command-check/contract.ts +168 -0
  377. package/src/package-checks/command-check/execution.ts +211 -0
  378. package/src/package-checks/command-check/options.ts +331 -0
  379. package/src/package-checks/command-check/transcript.ts +35 -0
  380. package/src/package-checks/duplicate-detection/default-check.ts +37 -6
  381. package/src/package-checks/duplicate-detection/execution.ts +2 -4
  382. package/src/package-checks/duplicate-detection/finding-messages.ts +2 -2
  383. package/src/package-checks/duplicate-detection/jscpd/availability.ts +1 -1
  384. package/src/package-checks/duplicate-detection/options.ts +6 -3
  385. package/src/package-checks/duplicate-detection/records.ts +1 -1
  386. package/src/package-checks/file-metrics/constructor.ts +29 -6
  387. package/src/package-checks/file-metrics/execution.ts +2 -4
  388. package/src/package-checks/file-metrics/finding-messages.ts +1 -1
  389. package/src/package-checks/file-metrics/options.ts +6 -3
  390. package/src/package-checks/file-metrics/records.ts +1 -1
  391. package/src/package-checks/file-metrics/scc/availability.ts +1 -1
  392. package/src/package-checks/file-metrics/scc/batch-planner.ts +56 -0
  393. package/src/package-checks/file-metrics/scc/logical-scan-resources.ts +59 -0
  394. package/src/package-checks/file-metrics/scc/scanner.ts +134 -32
  395. package/src/package-checks/function-metrics/analysis.ts +7 -2
  396. package/src/package-checks/function-metrics/analyzer/analysis-model.ts +1 -1
  397. package/src/package-checks/function-metrics/analyzer/extension-output.ts +14 -6
  398. package/src/package-checks/function-metrics/analyzer/extensions/lizardcomplextags.ts +1 -3
  399. package/src/package-checks/function-metrics/analyzer/extensions/protocol.ts +3 -3
  400. package/src/package-checks/function-metrics/analyzer/pipeline.ts +4 -2
  401. package/src/package-checks/function-metrics/analyzer/readers/erlang.ts +6 -6
  402. package/src/package-checks/function-metrics/analyzer/readers/fortran.ts +1 -1
  403. package/src/package-checks/function-metrics/analyzer/readers/objc.ts +9 -3
  404. package/src/package-checks/function-metrics/analyzer/readers/php-states.ts +14 -7
  405. package/src/package-checks/function-metrics/analyzer/readers/plsql.ts +8 -4
  406. package/src/package-checks/function-metrics/analyzer/readers/python.ts +4 -3
  407. package/src/package-checks/function-metrics/analyzer/readers/r.ts +2 -1
  408. package/src/package-checks/function-metrics/analyzer/readers/ttcn.ts +9 -3
  409. package/src/package-checks/function-metrics/analyzer/readers/typescript.ts +9 -3
  410. package/src/package-checks/function-metrics/analyzer/readers/zig.ts +2 -1
  411. package/src/package-checks/function-metrics/analyzer/shared/code-reader.ts +3 -1
  412. package/src/package-checks/function-metrics/analyzer/shared/js-style-regex.ts +10 -5
  413. package/src/package-checks/function-metrics/analyzer-worker-port.ts +20 -6
  414. package/src/package-checks/function-metrics/constructor.ts +30 -7
  415. package/src/package-checks/function-metrics/execution.ts +2 -4
  416. package/src/package-checks/function-metrics/finding-messages.ts +2 -2
  417. package/src/package-checks/function-metrics/measurement.ts +3 -1
  418. package/src/package-checks/function-metrics/options.ts +6 -3
  419. package/src/package-checks/function-metrics/records.ts +1 -1
  420. package/src/package-checks/host-environment/git.ts +11 -0
  421. package/src/package-checks/host-environment/path.ts +1 -20
  422. package/src/package-checks/host-environment/process/contract.ts +17 -9
  423. package/src/package-checks/host-environment/process/result.ts +48 -20
  424. package/src/package-checks/host-environment/process/runner.ts +8 -4
  425. package/src/package-checks/json-schema-validation/default-check.ts +38 -5
  426. package/src/package-checks/json-schema-validation/options.ts +4 -1
  427. package/src/package-checks/json-schema-validation/reference-resolver.ts +6 -2
  428. package/src/package-checks/json-schema-validation/schema-policy.ts +10 -5
  429. package/src/package-checks/json-validation/default-check.ts +27 -6
  430. package/src/package-checks/json-validation/options.ts +4 -1
  431. package/src/package-checks/local-cache-options.ts +40 -0
  432. package/src/package-checks/maintenance-reminders/maintenance-reminders.ts +89 -9
  433. package/src/package-checks/maintenance-reminders/maintenance-support.ts +3 -3
  434. package/src/package-checks/markdown-link-validation/default-check.ts +48 -5
  435. package/src/package-checks/markdown-link-validation/execution.ts +1 -1
  436. package/src/package-checks/markdown-link-validation/finding-messages.ts +1 -1
  437. package/src/package-checks/markdown-link-validation/markdown-parser.ts +1 -5
  438. package/src/package-checks/markdown-link-validation/options-resolution.ts +2 -19
  439. package/src/package-checks/markdown-link-validation/options-validation.ts +2 -17
  440. package/src/package-checks/markdown-link-validation/options.ts +6 -7
  441. package/src/package-checks/markdown-link-validation/parse-facts-cache-payload.ts +4 -5
  442. package/src/package-checks/markdown-lint/adapter.ts +167 -0
  443. package/src/package-checks/markdown-lint/default-check.ts +92 -0
  444. package/src/package-checks/markdown-lint/execution.ts +266 -0
  445. package/src/package-checks/markdown-lint/final-data.ts +33 -0
  446. package/src/package-checks/markdown-lint/finding-messages.ts +87 -0
  447. package/src/package-checks/markdown-lint/finding-waiver-identity.ts +54 -0
  448. package/src/package-checks/markdown-lint/findings-cache.ts +141 -0
  449. package/src/package-checks/markdown-lint/options-resolution.ts +102 -0
  450. package/src/package-checks/markdown-lint/options-validation.ts +50 -0
  451. package/src/package-checks/markdown-lint/options.ts +82 -0
  452. package/src/package-checks/markdown-lint/records.ts +132 -0
  453. package/src/package-checks/markdown-lint/unavailable-reasons.ts +33 -0
  454. package/src/package-checks/project-files/collection.ts +38 -22
  455. package/src/package-checks/project-files/config-glob.ts +1 -17
  456. package/src/package-checks/project-files/configuration.ts +1 -1
  457. package/src/package-checks/project-files/gitlink-revision.ts +4 -6
  458. package/src/package-checks/project-files/gitlink-worktree.ts +35 -7
  459. package/src/package-checks/project-files/public-collection.ts +1 -1
  460. package/src/package-checks/project-files/revision-paths.ts +3 -3
  461. package/src/package-checks/project-files/revision-worktree-files.ts +16 -16
  462. package/src/package-checks/secret-detection/default-check.ts +29 -6
  463. package/src/package-checks/secret-detection/execution.ts +2 -2
  464. package/src/package-checks/secret-detection/input-preparation.ts +64 -7
  465. package/src/package-checks/secret-detection/options.ts +5 -2
  466. package/src/package-checks/secret-detection/records.ts +1 -1
  467. package/src/package-checks/secret-detection/secretlint/adapter.ts +3 -4
  468. package/src/package-tools/admission-policy/define-admission-policy.ts +54 -0
  469. package/src/{cache → package-tools/cache}/cache-json-by-key.ts +13 -17
  470. package/src/{check → package-tools/finding-presentation}/finding-presentation.ts +3 -1
  471. package/src/{finding-waivers → package-tools/finding-waivers}/reconciliation.ts +16 -8
  472. package/src/{learned-critical-path → package-tools/learned-critical-path}/duration-model/prediction.ts +5 -2
  473. package/src/{learned-critical-path → package-tools/learned-critical-path}/duration-model/preparation.ts +5 -3
  474. package/src/{learned-critical-path → package-tools/learned-critical-path}/duration-model/recording.ts +5 -4
  475. package/src/{learned-critical-path → package-tools/learned-critical-path}/duration-model/storage.ts +9 -10
  476. package/src/{learned-critical-path → package-tools/learned-critical-path}/selection-layers.ts +2 -3
  477. package/src/{learned-critical-path → package-tools/learned-critical-path}/static-decision.ts +1 -1
  478. package/src/{learned-critical-path → package-tools/learned-critical-path}/strategy.ts +7 -4
  479. package/src/project-definition/check-tree/authoring.ts +15 -8
  480. package/src/project-definition/check-tree/check-fields-authoring.ts +106 -91
  481. package/src/project-definition/check-tree/flag-conditions.ts +99 -0
  482. package/src/project-definition/check-tree/materialization.ts +12 -8
  483. package/src/project-definition/check-tree/resolution.ts +13 -15
  484. package/src/project-definition/declarative-snapshot.ts +9 -2
  485. package/src/project-definition/project-changes.ts +112 -0
  486. package/src/project-definition/project-definition-validation.ts +58 -10
  487. package/src/project-definition/project-definition.ts +41 -68
  488. package/src/project-definition/scheduler-policy.ts +6 -3
  489. package/src/project-run/admission-strategy-provider/custom-strategy-preparation.ts +11 -8
  490. package/src/project-run/admission-strategy-provider/prepared-admission-strategy.ts +2 -2
  491. package/src/project-run/aggregation.ts +51 -74
  492. package/src/project-run/changes/git.ts +206 -0
  493. package/src/project-run/check-execution/admitted-check-execution.ts +62 -0
  494. package/src/project-run/check-execution/callback.ts +3 -2
  495. package/src/project-run/check-execution/dependencies.ts +120 -6
  496. package/src/project-run/check-execution/execution-finalization.ts +6 -4
  497. package/src/project-run/check-execution/execution-settlement.ts +88 -29
  498. package/src/project-run/check-execution/flag-controls.ts +22 -8
  499. package/src/project-run/check-execution/lifecycle.ts +14 -6
  500. package/src/project-run/check-execution/{preflight-result.ts → preparation-result.ts} +34 -32
  501. package/src/project-run/check-execution/{preflight.ts → preparation.ts} +92 -84
  502. package/src/project-run/check-execution/ready-check-execution.ts +97 -0
  503. package/src/project-run/check-execution/resolved-checks.ts +40 -219
  504. package/src/project-run/check-execution/scheduled-check-run.ts +119 -0
  505. package/src/project-run/check-execution/terminal-result.ts +108 -29
  506. package/src/project-run/completion/completion.ts +17 -3
  507. package/src/project-run/controls/contract.ts +6 -16
  508. package/src/project-run/controls/validation.ts +7 -60
  509. package/src/project-run/diagnostic-logging/diagnostic-detail-rendering.ts +1 -2
  510. package/src/project-run/diagnostic-logging/observation-rendering.ts +1 -1
  511. package/src/project-run/invocation/candidate.ts +28 -15
  512. package/src/project-run/invocation/candidates.ts +56 -0
  513. package/src/project-run/invocation/creation.ts +7 -3
  514. package/src/project-run/invocation/execution.ts +136 -0
  515. package/src/project-run/invocation/run.ts +15 -179
  516. package/src/project-run/invocation/scheduler.ts +13 -6
  517. package/src/project-run/outputs/status.ts +15 -15
  518. package/src/project-run/progress-rendering/presentation.ts +35 -13
  519. package/src/project-run/progress-rendering/renderer-formatting.ts +20 -7
  520. package/src/project-run/progress-rendering/renderer-lifecycle.ts +23 -6
  521. package/src/project-run/progress-rendering/renderer.ts +10 -4
  522. package/src/project-run/project-context.ts +8 -4
  523. package/src/project-run/result.ts +5 -5
  524. package/src/project-run/run.ts +1 -1
  525. package/src/project-run/task-scheduler/admission-core/compiled-graph-lookup.ts +71 -0
  526. package/src/project-run/task-scheduler/admission-core/compiled-graph.ts +9 -4
  527. package/src/project-run/task-scheduler/admission-core/selection-query.ts +6 -4
  528. package/src/project-run/task-scheduler/admission-core/selection-seed.ts +36 -6
  529. package/src/project-run/task-scheduler/admission-core/selection-transition.ts +17 -8
  530. package/src/project-run/task-scheduler/execution-state.ts +4 -4
  531. package/src/project-run/task-scheduler/measurement/diagnostics.ts +10 -4
  532. package/src/project-run/task-scheduler/measurement/timing.ts +13 -5
  533. package/src/project-run/task-scheduler/scheduler-observation.ts +3 -1
  534. package/src/project-run/task-scheduler/scheduler-terminal-measurement.ts +24 -22
  535. package/src/project-run/task-scheduler/scheduler.ts +23 -6
  536. package/types/check/check.d.ts +178 -67
  537. package/types/check/flag-enablement.d.ts +42 -0
  538. package/types/check/handoff-provider-identity.d.ts +12 -0
  539. package/types/check/project-changes.d.ts +13 -0
  540. package/types/check/project-context.d.ts +10 -0
  541. package/types/check-settlement/facts.d.ts +1 -1
  542. package/types/data-boundary/canonical-data.d.ts +28 -5
  543. package/types/data-boundary/canonical-json.d.ts +18 -1
  544. package/types/data-boundary/closed-values.d.ts +17 -1
  545. package/types/data-boundary/config-glob.d.ts +5 -0
  546. package/types/data-boundary/project-path.d.ts +4 -0
  547. package/types/index.d.ts +27 -11
  548. package/types/package-checks/check-authoring.d.ts +45 -0
  549. package/types/package-checks/code-quality-findings/finding-waiver-authoring.d.ts +1 -1
  550. package/types/package-checks/code-quality-findings/finding-waiver-evidence.d.ts +1 -1
  551. package/types/package-checks/command-check/command-check.d.ts +48 -0
  552. package/types/package-checks/command-check/contract.d.ts +108 -0
  553. package/types/package-checks/command-check/execution.d.ts +7 -0
  554. package/types/package-checks/command-check/options.d.ts +11 -0
  555. package/types/package-checks/command-check/transcript.d.ts +8 -0
  556. package/types/package-checks/duplicate-detection/default-check.d.ts +5 -2
  557. package/types/package-checks/duplicate-detection/finding-messages.d.ts +1 -1
  558. package/types/package-checks/duplicate-detection/options.d.ts +4 -3
  559. package/types/package-checks/duplicate-detection/records.d.ts +1 -1
  560. package/types/package-checks/file-metrics/constructor.d.ts +5 -2
  561. package/types/package-checks/file-metrics/options.d.ts +4 -3
  562. package/types/package-checks/file-metrics/records.d.ts +1 -1
  563. package/types/package-checks/file-metrics/scc/batch-planner.d.ts +18 -0
  564. package/types/package-checks/file-metrics/scc/logical-scan-resources.d.ts +14 -0
  565. package/types/package-checks/function-metrics/analyzer/extensions/protocol.d.ts +3 -3
  566. package/types/package-checks/function-metrics/constructor.d.ts +5 -2
  567. package/types/package-checks/function-metrics/finding-messages.d.ts +1 -1
  568. package/types/package-checks/function-metrics/options.d.ts +4 -3
  569. package/types/package-checks/function-metrics/records.d.ts +1 -1
  570. package/types/package-checks/host-environment/git.d.ts +2 -0
  571. package/types/package-checks/host-environment/path.d.ts +1 -3
  572. package/types/package-checks/host-environment/process/contract.d.ts +17 -9
  573. package/types/package-checks/json-schema-validation/default-check.d.ts +4 -1
  574. package/types/package-checks/json-schema-validation/options.d.ts +2 -1
  575. package/types/package-checks/json-validation/default-check.d.ts +4 -1
  576. package/types/package-checks/json-validation/options.d.ts +2 -1
  577. package/types/package-checks/local-cache-options.d.ts +9 -0
  578. package/types/package-checks/maintenance-reminders/maintenance-reminders.d.ts +11 -2
  579. package/types/package-checks/markdown-link-validation/default-check.d.ts +4 -1
  580. package/types/package-checks/markdown-link-validation/options.d.ts +4 -7
  581. package/types/package-checks/markdown-lint/adapter.d.ts +10 -0
  582. package/types/package-checks/markdown-lint/default-check.d.ts +37 -0
  583. package/types/package-checks/markdown-lint/execution.d.ts +24 -0
  584. package/types/package-checks/markdown-lint/final-data.d.ts +8 -0
  585. package/types/package-checks/markdown-lint/finding-messages.d.ts +6 -0
  586. package/types/package-checks/markdown-lint/finding-waiver-identity.d.ts +3 -0
  587. package/types/package-checks/markdown-lint/findings-cache.d.ts +17 -0
  588. package/types/package-checks/markdown-lint/options-resolution.d.ts +3 -0
  589. package/types/package-checks/markdown-lint/options-validation.d.ts +2 -0
  590. package/types/package-checks/markdown-lint/options.d.ts +65 -0
  591. package/types/package-checks/markdown-lint/records.d.ts +39 -0
  592. package/types/package-checks/markdown-lint/unavailable-reasons.d.ts +3 -0
  593. package/types/package-checks/secret-detection/default-check.d.ts +4 -1
  594. package/types/package-checks/secret-detection/options.d.ts +3 -2
  595. package/types/package-tools/admission-policy/define-admission-policy.d.ts +26 -0
  596. package/types/{check → package-tools/finding-presentation}/finding-presentation.d.ts +3 -1
  597. package/types/{finding-waivers → package-tools/finding-waivers}/reconciliation.d.ts +3 -3
  598. package/types/{learned-critical-path → package-tools/learned-critical-path}/duration-model/prediction.d.ts +2 -2
  599. package/types/{learned-critical-path → package-tools/learned-critical-path}/duration-model/preparation.d.ts +1 -1
  600. package/types/{learned-critical-path → package-tools/learned-critical-path}/duration-model/recording.d.ts +1 -1
  601. package/types/{learned-critical-path → package-tools/learned-critical-path}/selection-layers.d.ts +1 -1
  602. package/types/{learned-critical-path → package-tools/learned-critical-path}/static-decision.d.ts +1 -1
  603. package/types/{learned-critical-path → package-tools/learned-critical-path}/strategy.d.ts +1 -1
  604. package/types/project-definition/check-tree/authoring.d.ts +5 -3
  605. package/types/project-definition/check-tree/check-fields-authoring.d.ts +12 -7
  606. package/types/project-definition/check-tree/flag-conditions.d.ts +5 -0
  607. package/types/project-definition/check-tree/resolution.d.ts +6 -4
  608. package/types/project-definition/declarative-snapshot.d.ts +4 -1
  609. package/types/project-definition/project-changes.d.ts +30 -0
  610. package/types/project-definition/project-definition.d.ts +15 -30
  611. package/types/project-definition/scheduler-policy.d.ts +3 -3
  612. package/types/project-run/admission-strategy-provider/prepared-admission-strategy.d.ts +2 -2
  613. package/types/project-run/aggregation.d.ts +8 -6
  614. package/types/project-run/changes/git.d.ts +14 -0
  615. package/types/project-run/check-execution/admitted-check-execution.d.ts +18 -0
  616. package/types/project-run/check-execution/dependencies.d.ts +3 -0
  617. package/types/project-run/check-execution/execution-finalization.d.ts +1 -1
  618. package/types/project-run/check-execution/execution-settlement.d.ts +15 -7
  619. package/types/project-run/check-execution/flag-controls.d.ts +1 -1
  620. package/types/project-run/check-execution/lifecycle.d.ts +9 -5
  621. package/types/project-run/check-execution/{preflight-result.d.ts → preparation-result.d.ts} +3 -3
  622. package/types/project-run/check-execution/{preflight.d.ts → preparation.d.ts} +10 -9
  623. package/types/project-run/check-execution/ready-check-execution.d.ts +18 -0
  624. package/types/project-run/check-execution/resolved-checks.d.ts +12 -13
  625. package/types/project-run/check-execution/scheduled-check-run.d.ts +10 -0
  626. package/types/project-run/check-execution/terminal-result.d.ts +13 -1
  627. package/types/project-run/completion/completion.d.ts +3 -1
  628. package/types/project-run/controls/contract.d.ts +6 -16
  629. package/types/project-run/invocation/candidates.d.ts +8 -0
  630. package/types/project-run/invocation/execution.d.ts +5 -0
  631. package/types/project-run/invocation/run.d.ts +2 -2
  632. package/types/project-run/outputs/status.d.ts +4 -4
  633. package/types/project-run/progress-rendering/presentation.d.ts +4 -3
  634. package/types/project-run/progress-rendering/renderer-formatting.d.ts +5 -2
  635. package/types/project-run/progress-rendering/renderer-lifecycle.d.ts +2 -0
  636. package/types/project-run/progress-rendering/renderer.d.ts +4 -2
  637. package/types/project-run/project-context.d.ts +3 -3
  638. package/types/project-run/result.d.ts +3 -3
  639. package/types/project-run/run.d.ts +1 -1
  640. package/types/project-run/task-scheduler/admission-core/compiled-graph-lookup.d.ts +10 -0
  641. package/types/project-run/task-scheduler/execution-state.d.ts +4 -4
  642. package/types/project-run/task-scheduler/measurement/diagnostics.d.ts +2 -2
  643. package/types/project-run/task-scheduler/scheduler-terminal-measurement.d.ts +1 -1
  644. package/dist/esm/cache/cache-json-by-key.mjs.map +0 -1
  645. package/dist/esm/check/finding-presentation.mjs.map +0 -1
  646. package/dist/esm/finding-waivers/reconciliation.mjs.map +0 -1
  647. package/dist/esm/learned-critical-path/duration-model/bounded-history.mjs.map +0 -1
  648. package/dist/esm/learned-critical-path/duration-model/prediction.mjs.map +0 -1
  649. package/dist/esm/learned-critical-path/duration-model/preparation.mjs.map +0 -1
  650. package/dist/esm/learned-critical-path/duration-model/recording.mjs.map +0 -1
  651. package/dist/esm/learned-critical-path/duration-model/storage.mjs.map +0 -1
  652. package/dist/esm/learned-critical-path/selection-layers.mjs.map +0 -1
  653. package/dist/esm/learned-critical-path/static-decision.mjs.map +0 -1
  654. package/dist/esm/learned-critical-path/strategy.mjs.map +0 -1
  655. package/dist/esm/package-checks/project-files/config-glob.mjs.map +0 -1
  656. package/dist/esm/project-run/check-execution/preflight-result.mjs.map +0 -1
  657. package/dist/esm/project-run/check-execution/preflight.mjs.map +0 -1
  658. package/dist/esm/project-run/task-scheduler/critical-path-ranking.mjs.map +0 -1
  659. package/types/package-checks/project-files/config-glob.d.ts +0 -5
  660. /package/dist/esm/{check → package-tools/finding-presentation}/finding-presentation.mjs +0 -0
  661. /package/dist/esm/{project-run/task-scheduler → package-tools/learned-critical-path}/critical-path-ranking.mjs +0 -0
  662. /package/dist/esm/{learned-critical-path → package-tools/learned-critical-path}/duration-model/bounded-history.mjs +0 -0
  663. /package/dist/esm/{learned-critical-path → package-tools/learned-critical-path}/duration-model/recording.mjs +0 -0
  664. /package/dist/esm/{learned-critical-path → package-tools/learned-critical-path}/static-decision.mjs +0 -0
  665. /package/src/{project-run/task-scheduler → package-tools/learned-critical-path}/critical-path-ranking.ts +0 -0
  666. /package/src/{learned-critical-path → package-tools/learned-critical-path}/duration-model/bounded-history.ts +0 -0
  667. /package/types/{cache → package-tools/cache}/cache-json-by-key.d.ts +0 -0
  668. /package/types/{project-run/task-scheduler → package-tools/learned-critical-path}/critical-path-ranking.d.ts +0 -0
  669. /package/types/{learned-critical-path → package-tools/learned-critical-path}/duration-model/bounded-history.d.ts +0 -0
  670. /package/types/{learned-critical-path → package-tools/learned-critical-path}/duration-model/storage.d.ts +0 -0
package/README.md CHANGED
@@ -16,7 +16,7 @@ npm 负责安装 package;应用代码和质量脚本的最低运行要求是 *
16
16
 
17
17
  ## 随包提供的 Check
18
18
 
19
- 如果项目需要的是常见质量检查,可以先从以下函数开始,而不必自己实现 `execution`。除 `maintenanceReminders(entries)` 与 `secretDetection({ files })` 有必填输入外,其余函数都可以无参调用;每份指南都包含最小用法、options、默认值、结果和安全边界。
19
+ 如果项目需要的是常见质量检查,可以先从以下函数开始,而不必自己实现 `execute`。除 `maintenanceReminders(entries)` 与 `secretDetection({ files })` 有必填输入外,其余函数都可以无参调用;每份指南都包含最小用法、options、默认值、结果和安全边界。
20
20
 
21
21
  | 你想检查什么 | 使用的导出 | 额外环境准备 |
22
22
  | --- | --- | --- |
@@ -25,11 +25,39 @@ npm 负责安装 package;应用代码和质量脚本的最低运行要求是 *
25
25
  | 函数规模、复杂度、最大嵌套和参数数量 | [`functionMetrics(options?)`](./docs/checks/function-metrics.md) | 无需另装分析器。 |
26
26
  | JSON 语法和输入范围 | [`jsonValidation(options?)`](./docs/checks/json-validation.md) | 无。 |
27
27
  | JSON 与 Schema 的匹配关系 | [`jsonSchemaValidation(options?)`](./docs/checks/json-schema-validation.md) | 使用远程 Schema 时,需显式允许对应 HTTPS source 并具备网络访问条件。 |
28
+ | Markdown 结构与明确内容缺陷 | [`markdownLint(options?)`](./docs/checks/markdown-lint.md) | 无。 |
28
29
  | 本地 Markdown 链接与锚点 | [`markdownLinkValidation(options?)`](./docs/checks/markdown-link-validation.md) | 无。 |
29
30
  | 基于 Git 历史的维护提醒 | [`maintenanceReminders(entries)`](./docs/checks/maintenance-reminders.md) | 项目根目录是 Git repository,且环境可以执行 `git`。 |
30
31
  | 高置信 PEM private key | [`secretDetection({ files })`](./docs/checks/secret-detection.md) | 无需另装分析器。 |
31
32
 
32
- `duplicateDetection`、`fileMetrics`、`functionMetrics` 和 `markdownLinkValidation` 默认把普通 Finding 作为 non-blocking 警告保留下来;需要让 Finding 直接使 Check 失败时,在对应 options 中设置 `findingPolicy: "blocking"`。文件选择、阈值、外部工具和具体结果字段以各 Check 指南为准。
33
+ ### 为随包 Check 声明项目行为
34
+
35
+ 八个 object-policy 构造器都在原有顶层 options 接受领域 policy 和项目声明。`maintenanceReminders` 保留
36
+ `maintenanceReminders(entries)`,并增加包含 `entries` 的 object input;为同类 Check 创建多个实例时,直接提供 `checkId`。
37
+
38
+ ```ts
39
+ import { defineConfig, fileMetrics } from "@zxyycom/vibe-check";
40
+
41
+ const definition = defineConfig({
42
+ checks: [
43
+ fileMetrics({
44
+ checkId: "source-file-metrics",
45
+ enabledByFlags: { when: "source-changed" },
46
+ codeAreas: { source: { files: { include: ["src/**/*.ts"] } } }
47
+ }),
48
+ fileMetrics({
49
+ checkId: "test-file-metrics",
50
+ codeAreas: { tests: { files: { include: ["test/**/*.ts"] } } }
51
+ })
52
+ ]
53
+ });
54
+ ```
55
+
56
+ `PackageCheckAuthoringOptions` 可作为可复用的项目声明片段从 package root 导入。构造器返回原生 typed
57
+ Check:项目字段成为 Check 声明,领域字段才形成 `.options` 和 execution `context.options`。完整字段、默认、
58
+ 关系与验证责任见 [API 机制](./docs/api-mechanics.md#随包-check-的构造器项目声明);每个领域字段见对应 Check 指南。
59
+
60
+ `duplicateDetection`、`fileMetrics`、`functionMetrics`、`markdownLint` 和 `markdownLinkValidation` 默认把普通 Finding 作为 non-blocking 警告保留下来;需要让 Finding 直接使 Check 失败时,在对应 options 中设置 `findingPolicy: "blocking"`。文件选择、阈值、外部工具和具体结果字段以各 Check 指南为准。
33
61
 
34
62
  ## 自定义 Check 快速开始
35
63
 
@@ -43,7 +71,7 @@ import { defineCheck, defineConfig, run } from "@zxyycom/vibe-check";
43
71
  const bundleSize = defineCheck({
44
72
  checkId: "bundle-size",
45
73
  displayName: "Bundle size",
46
- execution() {
74
+ execute() {
47
75
  const actualBytes = 82_000;
48
76
  const maximumBytes = 100_000;
49
77
  const data = {
@@ -83,19 +111,21 @@ node quality.ts
83
111
 
84
112
  ## 运行、配置与读取结果
85
113
 
86
- `defineConfig(...)` 定义可复用的 Checks、options、依赖、scheduler 和默认 outputs;`run(definition, controls?)` 的第二个参数只设置本次根目录、flags、取消、产物与日志目标、output overrides 和显式 aggregation。Controls 不能替换 Check 或 scheduler;字段位置和覆盖规则见 [API 机制](./docs/api-mechanics.md#参数应该放在哪里)。
114
+ `defineConfig(...)` 定义可复用的 Checks、options、依赖、scheduler 和默认 outputs;`run(definition, controls?)` 的第二个参数只设置本次根目录、flags、取消、产物与日志目标、output overrides 和可选的本地 aggregation 函数。Controls 不能替换 Check 或 scheduler;字段位置和覆盖规则见 [API 机制](./docs/api-mechanics.md#参数应该放在哪里)。
87
115
 
88
116
  默认最多并行运行四个 Check,显示进度并把 machine files 写入 `artifacts/vibe-check`;diagnostic logging 默认关闭。上例显式关闭 machine publication。配置方法见[输出指南](./docs/guides/run-outputs.md)与[调度指南](./docs/guides/scheduling.md)。
89
117
 
90
- 先判断 `RunResult.kind`;对有 snapshot 的结果,再按 `checkId` 读取 `snapshot.checks[].outcome` 的 `passed`、`failed`、`not-applicable` 或 `unavailable`。`completed` 不代表质量通过:CI 应显式判断目标 outcomes,或配置并读取 [`checkAggregation`](./docs/api-mechanics.md#runcontrols-与-check-aggregation),再决定退出码。
118
+ 先判断 `RunResult.kind`;`completed` 和 `output` 才同时提供完整 facts 与 `aggregate`,随后再按 `checkId` 读取 `snapshot.checks[].outcome` 的 `passed`、`failed`、`not-applicable` 或 `unavailable`。执行阶段取消也有 snapshot,但没有 aggregate。省略定制函数时,aggregate 仅在有效 Check 列表非空且全部 `passed` 时为 `passed`,否则为 `failed`。`completed` 不代表质量通过;CI 可读取这个严格默认值,或在 [`checkAggregation`](./docs/api-mechanics.md#runcontrols-与-check-aggregation) 中同步解释同一有效列表,再决定退出码。
91
119
 
92
120
  ## 按任务继续阅读
93
121
 
94
122
  只读当前任务需要的专题;精确 overload、泛型推断和字段 JSDoc 以安装包中的 `types/**.d.ts` 为准。
95
123
 
124
+ - [从项目质量目标构建 Gate](./docs/guides/building-project-gate.md):从最小入口出发,按实际问题接入脚本、共享准备、增量选择、自建缓存和诊断。
96
125
  - [API 机制](./docs/api-mechanics.md):Run 生命周期、组合继承、结果与 aggregation。
97
126
  - [选择回调位置](./docs/guides/callbacks.md):确定执行前、检查中、显示时或结束后的接入点。
98
127
  - [自定义 Check](./docs/guides/extending-check-lifecycle.md):options 准备、callback context、Records 与协作取消。
128
+ - [执行外部命令的 Check](./docs/guides/command-check.md):以单一 executable 和独立 arguments 接入 exit-status command,配置 environment、输出与终态边界。
99
129
  - [Check 依赖与类型化数据](./docs/guides/check-dependencies.md):`dependsOn` / `observes`、读取授权与 provider parser。
100
130
  - [Run 输出与诊断](./docs/guides/run-outputs.md):输出配置、progress、日志与失败处理。
101
131
  - [调度 Check](./docs/guides/scheduling.md):并发资源、准入策略与终态观察。
@@ -107,6 +137,7 @@ node quality.ts
107
137
  | --- | --- | --- |
108
138
  | 按一份完整 selection 收集项目文件 path | `collectProjectFiles(...)` 在普通项目代码或 custom Check 内返回冻结的 relative path 快照 | [收集项目文件](./docs/guides/collecting-project-files.md) |
109
139
  | 按完整语义 key 复用本地 JSON 计算 | `cacheJsonByKey(...)` 在普通项目代码或 Check 内返回一次调用的缓存结果 | [缓存计算结果](./docs/guides/cache-results.md) |
140
+ | 取得独立 JSON 副本、生成确定性表示,或检查含回调的配置结构 | 两组公开 Core 工具分别负责 JSON 规范化/序列化与外层结构快照,无需创建 Check 或 Run | [Core 数据工具](./docs/guides/data-boundaries.md) |
110
141
  | 对账完整 Finding 集合与 waiver audit | `reconcileFindingWaivers(...)` 在 Finding 形成后返回 disposition 与 audit | [对账 Finding waiver](./docs/guides/finding-waivers.md) |
111
142
  | 生成有限的 Finding 人读摘要 | `presentCheckFindings(...)` 返回 `CheckMessage[]`,由 producing Check 附到自己的 terminal result | [呈现 Check Finding](./docs/guides/presenting-findings.md) |
112
143
  | 在不执行 Check 的前提下分析静态 admission 分支 | `createAdmissionGraph(...)` 独立创建 immutable simulation,不需要 `run(...)` 或 custom policy | [模拟 AdmissionGraph](./docs/guides/simulating-admission.md) |
@@ -1,5 +1,9 @@
1
+ import { registerHandoffProviderIdentity } from "./handoff-provider-identity.mjs";
1
2
  export { inherit, isInheritedCheckCollection, snapshotInheritedCheckCollection } from "./inherited-collection.mjs";
2
3
  export function defineCheck(value) {
4
+ if (value.handoff === true) {
5
+ registerHandoffProviderIdentity(value);
6
+ }
3
7
  return value;
4
8
  }
5
9
  //# sourceMappingURL=check.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"check.mjs","sourceRoot":"","sources":["../../../src/check/check.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,OAAO,EACP,0BAA0B,EAC1B,gCAAgC,EACjC,MAAM,2BAA2B,CAAC;AAyhBnC,MAAM,UAAU,WAAW,CAAC,KAAY;IACtC,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import type { CanonicalJsonObject, CanonicalJsonValue } from \"../data-boundary/canonical-json.ts\";\nimport type { InheritableCheckCollection } from \"./inherited-collection.ts\";\n\nexport {\n inherit,\n isInheritedCheckCollection,\n snapshotInheritedCheckCollection\n} from \"./inherited-collection.ts\";\nexport type {\n InheritCheckCollectionInput,\n InheritableCheckCollection,\n InheritedCheckCollection\n} from \"./inherited-collection.ts\";\n\n/** Check 无法给出 final data 时返回的受控 reason code。 */\nexport type CheckReason = Readonly<{\n /** 由 owning Check 定义、供调用方诊断的稳定 code。 */\n readonly code: string;\n}>;\n\n/** `not-applicable` Check result 的可选 reason。 */\nexport type CheckNotApplicableReason = CheckReason;\n/** author callback 明确返回 `unavailable` 时必须提供的 reason。 */\nexport type CheckDeclaredUnavailableReason = CheckReason;\n\n/** `unavailable` Check outcome 的 reason;可列出导致当前 Check 不可用的上游 Check。 */\nexport type CheckUnavailableReason = Readonly<{\n /** 由当前 Check 或 Product 边界给出的受控原因。 */\n readonly code: string;\n /** 仅在上游关系有助于定位时给出的相关 Check IDs。 */\n readonly checkIds?: readonly string[];\n}>;\n\n/** 终端 Check message 的 presentation severity。 */\nexport type CheckMessageLevel = \"info\" | \"warning\" | \"error\";\n\n/** 由 Check author 附加到 terminal result 的补充消息。 */\nexport interface CheckMessage {\n /** 人读 presentation 使用的 severity。 */\n readonly level: CheckMessageLevel;\n /** owning Check namespace 内的稳定 message code。 */\n readonly code: string;\n /** 非空消息正文;Product 保留 author 提供的字符串。 */\n readonly message: string;\n}\n\n/** 可附加到每个 {@link CheckResult} branch 的有序 terminal messages。 */\nexport interface CheckResultMessages {\n /** 省略、`undefined` 或空数组都表示没有 supplemental messages。 */\n readonly messages?: readonly CheckMessage[];\n}\n\n/** 已结算 Check 在人读 progress 中的可见性。 */\nexport type CheckVisibility = \"always\" | \"attention\";\n\n/** Check Task 在 admission 到 settlement 期间持有的静态 named resource units。 */\nexport type CheckResourceClaims = Readonly<Record<string, number>>;\n\n/** 多 flag Check 启用条件使用的集合 predicate。 */\nexport type CheckFlagEnablementMode = \"all\" | \"any\" | \"none\" | \"not-all\";\n\n/** executable Check 的声明式多 flag 启用条件。 */\nexport interface CheckFlagEnablement {\n /** 非空 flag token 集合;Definition 会去重并稳定排序。 */\n readonly flags: readonly [string, ...string[]];\n /** 对声明 token 与本次 Run flags 执行的 presence predicate。 */\n readonly mode: CheckFlagEnablementMode;\n /**\n * 条件命中时是否启动本 Check 的传递 `dependsOn` prerequisite;省略时保持只选择直接命中 Check 的兼容行为。\n * `observes` 不参与此选择,且 dependency 自己的 flag 条件不会阻止本次已启动的 prerequisite。\n */\n readonly propagateDependsOn?: true;\n}\n\n/**\n * Check callback 的 terminal result。\n *\n * @typeParam FinalData - `passed` 或 `failed` 时保留为 canonical final data 的业务对象。\n * @remarks `not-applicable` 与 `unavailable` 不携带 final data;普通 callback、Record 或取消失败由\n * Product 转换为 `unavailable`,而不是抛出为 Run 的成功结果。\n */\nexport type CheckResult<FinalData extends object = object> = Readonly<\n (\n | {\n /** Check 已产生通过的 final data。 */\n readonly status: \"passed\";\n /** 此 Check 的主要终态事实。 */\n readonly data: FinalData;\n }\n | {\n /** Check 已产生失败的 final data。 */\n readonly status: \"failed\";\n /** 此 Check 的主要终态事实。 */\n readonly data: FinalData;\n }\n | {\n /** Check 在当前 invocation 中不适用。 */\n readonly status: \"not-applicable\";\n /** 不适用的可选受控原因。 */\n readonly reason?: CheckNotApplicableReason;\n }\n | {\n /** Check 不能提供 terminal data。 */\n readonly status: \"unavailable\";\n /** 不可用的受控原因。 */\n readonly reason: CheckDeclaredUnavailableReason;\n }\n ) &\n CheckResultMessages\n>;\n\n/** 已 materialize 到 Core snapshot 的 Check terminal outcome。 */\nexport type CheckOutcome = Readonly<\n | {\n /** 已 materialize 的通过 outcome。 */\n readonly status: \"passed\";\n /** 已 canonicalize 的 primary final fact。 */\n readonly data: CanonicalJsonObject;\n }\n | {\n /** 已 materialize 的失败 outcome。 */\n readonly status: \"failed\";\n /** 已 canonicalize 的 primary final fact。 */\n readonly data: CanonicalJsonObject;\n }\n | {\n /** 已 materialize 的不适用 outcome。 */\n readonly status: \"not-applicable\";\n /** 不适用的可选受控原因。 */\n readonly reason?: CheckNotApplicableReason;\n }\n | {\n /** 已 materialize 的不可用 outcome。 */\n readonly status: \"unavailable\";\n /** 包含相关 upstream Check IDs 的受控原因。 */\n readonly reason: CheckUnavailableReason;\n }\n>;\n\n/** 将 callback options 转为不可变观察值的递归 utility type。 */\nexport type DeepReadonly<T> = T extends string | number | boolean | null\n ? T\n : T extends readonly (infer Item)[]\n ? readonly DeepReadonly<Item>[]\n : T extends object\n ? { readonly [Key in keyof T]: DeepReadonly<T[Key]> }\n : never;\n\n/** callback 写入 supplemental Record 时的 Check-local identity。 */\ninterface RecordIdentityInput {\n /** 在当前 Check 内唯一的 Record ID。 */\n readonly id: string;\n}\n\n/** callback 写入 supplemental Records 的 Product-owned reporter。 */\ninterface CheckRecordReporter {\n /** 记录一个补充事实;它不决定 Check 的 terminal status。 */\n report(identity: RecordIdentityInput, data: object): void;\n}\n\n/** 读取已声明 direct relation final data 时的失败原因。 */\nexport type DependencyReadError = Readonly<\n | {\n /** 当前 Check 未声明所请求的 direct relation ID。 */\n readonly code: \"dependency-not-declared\";\n /** 被拒绝的 direct relation ID。 */\n readonly checkId: string;\n }\n | {\n /** 已声明 upstream 没有可读取的 final data。 */\n readonly code: \"upstream-data-unavailable\";\n /** 没有 final data 的 direct relation ID。 */\n readonly checkId: string;\n /** 阻止 readback 的 upstream terminal status。 */\n readonly status: \"not-applicable\" | \"unavailable\";\n }\n>;\n\n/** {@link CheckDependencies.get} 的受控 readback 结果。 */\nexport type DependencyReadResult = Readonly<\n | {\n /** 成功读取 direct relation final data。 */\n readonly ok: true;\n /** 被读取的 direct relation ID。 */\n readonly checkId: string;\n /** upstream 已结算为 `passed` 或 `failed` 的 status。 */\n readonly status: \"passed\" | \"failed\";\n /** 已与原对象脱离的上游依赖终态数据。 */\n readonly data: CanonicalJsonObject;\n }\n | {\n /** direct relation data 不可读取。 */\n readonly ok: false;\n /** 失败的授权或 upstream-data reason。 */\n readonly error: DependencyReadError;\n }\n>;\n\n/** 当前 Check 的一个已规范化直接 relation 及其完整终态事实。 */\nexport type DependencyObservation = Readonly<{\n /** 已规范化、稳定排序的 direct relation ID。 */\n readonly checkId: string;\n /** Core 已结算并冻结的四态 outcome。 */\n readonly outcome: CheckOutcome;\n}>;\n\n/** 当前 Check 的已规范化直接 relation outcomes 的 data reader。 */\nexport interface CheckDependencies {\n /**\n * 读取一个直接 relation 的 canonical final data。\n *\n * @returns 已声明的 `dependsOn` 或 `observes` relation 且为 `passed`/`failed` 的 Check 返回其 data;\n * 未声明或没有 final data 时返回 `ok: false`,不会授权 transitive Check。\n */\n get(checkId: string): DependencyReadResult;\n\n /**\n * 枚举当前 Check 的全部已规范化 direct relation outcomes。\n *\n * @returns 按有效 direct relation ID 稳定排序、深度冻结的 `{ checkId, outcome }` observations;只含当前\n * Check 显式或继承得到的 `dependsOn` / `observes` relation,不暴露 scheduler 历史、transitive 或未声明\n * Check。\n */\n list(): readonly DependencyObservation[];\n}\n\n/** callback 可读取的、由 Product 规范化的项目上下文。 */\nexport interface CheckProjectContext {\n /** 本次 Run 使用的绝对项目根目录。 */\n readonly root: string;\n /** 已去重、排序的 caller-supplied flags。 */\n readonly flags: readonly string[];\n}\n\n/**\n * Check callback 收到的 Product-owned execution context。\n *\n * @typeParam Options - 此 Check preflight 后传给 execution 的 options shape。\n */\nexport interface CheckExecutionContext<Options extends object> {\n /** 当前 Check 的 absolute invocation artifact directory;caller 未授予时为 `null`。 */\n readonly artifactDirectory: string | null;\n /** 读取当前 Check 的已声明 direct relations。 */\n readonly dependencies: CheckDependencies;\n /** 同一次 invocation 内由 Product 统一提供的 identity。 */\n readonly invocationId: string;\n /** 深度只读、canonical 的 invocation-local prepared Check options。 */\n readonly options: DeepReadonly<Options>;\n /** 已规范化的项目根与 flags。 */\n readonly project: CheckProjectContext;\n /** 写入 supplemental Records 的 reporter。 */\n readonly records: CheckRecordReporter;\n /** 本次 invocation 的 cancellation signal。 */\n readonly signal: AbortSignal;\n}\n\n/**\n * 一个 Check 的 callback signature。\n *\n * @typeParam Options - callback 从 context 读取的 prepared options shape。\n * @returns terminal Check result 或其 Promise。\n */\nexport type CheckExecution<Options extends object = object> = (\n this: void,\n context: CheckExecutionContext<Options>\n) => CheckResult | Promise<CheckResult>;\n\n/**\n * 在 Check execution 前,可选地为本次 invocation 准备 options。\n *\n * @remarks `signal` 与同一次 callback execution 使用同一个 cancellation signal;实现应在可等待工作中\n * 协作退出,而不是留下悬挂 work。bivariant callback 保持具体 options Check 可进入普通递归 Check\n * collection;Product 仍只会用该 Check 自己的 authored options 调用它。精确结果见\n * {@link CheckPreflightResult}。\n */\nexport type CheckPreflight<\n AuthoredOptions extends object = object,\n PreparedOptions extends object = AuthoredOptions\n> = {\n bivarianceHack(\n this: void,\n options: DeepReadonly<AuthoredOptions>,\n signal: AbortSignal\n ): CheckPreflightResult<PreparedOptions> | Promise<CheckPreflightResult<PreparedOptions>>;\n}[\"bivarianceHack\"];\n\n/**\n * Check-owned preflight 的判别结果。\n *\n * `failure/block` 不允许 fallback,直接以 owning reason 结算为 unavailable;`failure/continue` 必须给出\n * fallback 并继续 execution。两种进入 execution 的值都只属于本次 invocation,Product canonicalize/freeze\n * 后传递,不会改写 Definition 中 authored options。两个 failure 分支都必须给出 reason;continue reason\n * 是 Check-owned diagnostic identity,当前不会单独 materialize 为 outcome,调用方通过 messages 与后续\n * outcome 观察结果;block 物理上不含 fallback 字段。\n */\nexport type CheckPreflightResult<PreparedOptions extends object = object> = Readonly<\n | {\n readonly status: \"success\";\n readonly preparedOptions: PreparedOptions;\n readonly messages?: readonly CheckMessage[];\n }\n | {\n readonly status: \"failure\";\n readonly action: \"block\";\n readonly reason: CheckDeclaredUnavailableReason;\n readonly messages?: readonly CheckMessage[];\n }\n | {\n readonly status: \"failure\";\n readonly action: \"continue\";\n readonly fallback: PreparedOptions;\n readonly reason: CheckReason;\n readonly messages?: readonly CheckMessage[];\n }\n>;\n\n/**\n * 普通递归 Check authoring value 的共享字段。\n *\n * @typeParam AuthoredOptions - Definition 中的 declarative options shape。\n * @typeParam PreparedOptions - preflight 后 callback 接收的 invocation-local options shape。\n * @remarks 该值可以同时有 `execution` 和 `checks`;只有 executable node 产生 final Check fact。\n */\ninterface CheckBase<AuthoredOptions extends object, PreparedOptions extends object> {\n /** 在 Definition 内唯一的 stable Check ID。 */\n readonly checkId: string;\n /** 人读 progress 与 output 使用的非空名称。 */\n readonly displayName: string;\n /** Check-owned declarative options;默认 Check 的嵌套 branch 以普通对象组合替换。 */\n readonly options?: AuthoredOptions;\n /** 仅当多 flag presence predicate 匹配时启用 executable Check;省略时始终启用。 */\n readonly enabledByFlags?: CheckFlagEnablement;\n /** 可执行节点的 callback;省略时此节点只承载递归 children。 */\n execution?(\n this: void,\n context: CheckExecutionContext<PreparedOptions>\n ): CheckResult | Promise<CheckResult>;\n /** 继承 scheduling context 的 child Checks,不会单独形成 container result。 */\n readonly checks?: readonly Check[];\n /** 必须全部 `passed` 才能开始当前 Check author work 的直接 prerequisite Check IDs。 */\n readonly dependsOn?: InheritableCheckCollection<string>;\n /** 等待任意 terminal outcome 并授权当前 Check readback 的直接 observation Check IDs。 */\n readonly observes?: InheritableCheckCollection<string>;\n /** 此 Check 及其 descendants 的最大并行预算。 */\n readonly maxParallel?: number;\n /** 同一 ready admission 层级中的静态优先级;省略时继承并最终规范化为 `0`。 */\n readonly admissionPriority?: number;\n /** 共享资源名称,或对父 mutex collection 的显式 edit。 */\n readonly mutex?: InheritableCheckCollection<string>;\n /** 静态 named resource claims;省略时继承,显式 mapping 完整替换。 */\n readonly resourceClaims?: CheckResourceClaims;\n /** 已结算 Check 的人读可见性;可执行节点默认 `always`。 */\n readonly visibility?: CheckVisibility;\n}\n\n/**\n * 判断两个 options shape 是否互相可赋值;互相可赋值时 execution 不需要 preparation 转换。\n */\ntype HasSameOptionsShape<AuthoredOptions extends object, PreparedOptions extends object> = [\n AuthoredOptions\n] extends [PreparedOptions]\n ? [PreparedOptions] extends [AuthoredOptions]\n ? true\n : false\n : false;\n\n/** Prepared shape 不同时,preflight 是建立安全转换的必填边界。 */\ntype CheckPreflightField<AuthoredOptions extends object, PreparedOptions extends object> =\n HasSameOptionsShape<AuthoredOptions, PreparedOptions> extends true\n ? Readonly<{ readonly preflight?: CheckPreflight<AuthoredOptions, PreparedOptions> }>\n : Readonly<{ readonly preflight: CheckPreflight<AuthoredOptions, PreparedOptions> }>;\n\n/**\n * Project Definition 中的普通递归 Check authoring value。\n *\n * @typeParam AuthoredOptions - Definition 中的 declarative options shape。\n * @typeParam PreparedOptions - preflight 后 callback 接收的 invocation-local options shape。\n * @remarks Definition 只闭合 authored JSON options;每个 admitted Check 先在自身 Task lifecycle 内执行\n * preflight,随后才执行 callback。`PreparedOptions` 与 `AuthoredOptions` 不同时必须提供 preflight;同形时可以\n * 省略。它不进入 declarative fingerprint 或 machine output。\n */\nexport type Check<\n AuthoredOptions extends object = object,\n PreparedOptions extends object = AuthoredOptions\n> = CheckBase<AuthoredOptions, PreparedOptions> &\n CheckPreflightField<AuthoredOptions, PreparedOptions>;\n\nexport type EmptyCheckOptions = Readonly<Record<never, never>>;\n\n/**\n * 防止宽泛的 parser 标注擦除 `PromiseLike`。canonical `then` field 可以保存 JSON data,\n * 但不能保存使该值成为 thenable 的 callable。\n */\ntype NonThenableData = Readonly<{ readonly then?: CanonicalJsonValue }>;\n\n/**\n * 将 canonical direct-relation data 还原为 provider final-data shape 的同步 parser。\n *\n * @typeParam FinalData - provider 在 `passed`/`failed` result 中声明的 final-data shape。\n * @remarks Product 不调用此 parser;provider 负责不受信任或跨版本 data 的业务验证。\n */\nexport type CheckDataParser<FinalData extends object = object> = (\n this: void,\n data: CanonicalJsonObject\n) => FinalData & NonThenableData;\n\ntype CheckAuthoringBase<\n Id extends string,\n AuthoredOptions extends object,\n PreparedOptions extends object\n> = Omit<CheckBase<AuthoredOptions, PreparedOptions>, \"checkId\" | \"execution\" | \"options\"> &\n CheckPreflightField<AuthoredOptions, PreparedOptions> &\n Readonly<{ readonly checkId: Id }>;\n\ninterface OrdinaryCheckFields<PreparedOptions extends object> {\n execution?(\n this: void,\n context: CheckExecutionContext<PreparedOptions>\n ): CheckResult | Promise<CheckResult>;\n readonly parseData?: never;\n}\n\nexport type CheckWithOptions<\n Id extends string,\n AuthoredOptions extends object,\n PreparedOptions extends object = AuthoredOptions\n> = CheckAuthoringBase<Id, AuthoredOptions, PreparedOptions> &\n OrdinaryCheckFields<PreparedOptions> &\n Readonly<{\n readonly options: AuthoredOptions;\n }>;\n\nexport type CheckWithoutOptions<Id extends string> = CheckAuthoringBase<\n Id,\n EmptyCheckOptions,\n EmptyCheckOptions\n> &\n OrdinaryCheckFields<EmptyCheckOptions> &\n Readonly<{\n readonly options?: never;\n }>;\n\ninterface TypedCheckFields<PreparedOptions extends object, Parser extends CheckDataParser> {\n /**\n * 将 canonical runtime data 还原为 provider data。\n *\n * 启发式边界:同版本且受信任的 provider 若由测试保证 data shape,可仅将它实现为\n * identity/type anchor。这不验证 JavaScript 或基于 cast 的 producer、历史或跨版本 artifact,\n * 也不验证不受信任输入。\n */\n readonly parseData: Parser;\n\n execution(\n this: void,\n context: CheckExecutionContext<PreparedOptions>\n ): CheckResult<NoInfer<ReturnType<Parser>>> | Promise<CheckResult<NoInfer<ReturnType<Parser>>>>;\n}\n\nexport type TypedCheckWithOptions<\n Id extends string,\n AuthoredOptions extends object,\n Parser extends CheckDataParser,\n PreparedOptions extends object = AuthoredOptions\n> = CheckAuthoringBase<Id, AuthoredOptions, PreparedOptions> &\n TypedCheckFields<PreparedOptions, Parser> &\n Readonly<{\n readonly options: AuthoredOptions;\n }>;\n\nexport type TypedCheckWithoutOptions<\n Id extends string,\n Parser extends CheckDataParser\n> = CheckAuthoringBase<Id, EmptyCheckOptions, EmptyCheckOptions> &\n TypedCheckFields<EmptyCheckOptions, Parser> &\n Readonly<{\n readonly options?: never;\n }>;\n\n/**\n * 定义一个 Check,同时保留 literal `checkId`、options 与 typed-provider parser 的 inference。\n *\n * @remarks 此函数负责 authoring inference;{@link run} 负责 Project Definition validation。\n * @example 定义带 options、Records 与 messages 的自定义 Check\n * ```ts\n * import { defineCheck, defineConfig, run } from \"@zxyycom/vibe-check\";\n *\n * function hasValidLicensePolicyOptions(options: object): boolean {\n * const denied: unknown = Reflect.get(options, \"denied\");\n * return (\n * Object.keys(options).length === 1 &&\n * Object.hasOwn(options, \"denied\") &&\n * Array.isArray(denied) &&\n * denied.every((license) => typeof license === \"string\")\n * );\n * }\n *\n * const licensePolicy = defineCheck({\n * checkId: \"license-policy\",\n * displayName: \"License policy\",\n * options: { denied: [\"GPL-3.0-only\"] },\n * preflight(options) {\n * return hasValidLicensePolicyOptions(options)\n * ? { status: \"success\", preparedOptions: options }\n * : { status: \"failure\", action: \"block\", reason: { code: \"invalid-options\" } };\n * },\n * visibility: \"attention\",\n * execution({ options, records, signal }) {\n * if (signal.aborted) return { status: \"unavailable\", reason: { code: \"cancelled\" } };\n *\n * const deniedCount = options.denied.length;\n * if (deniedCount > 0) {\n * records.report({ id: \"denied-license\" }, { count: deniedCount });\n * return {\n * status: \"failed\",\n * data: { deniedCount },\n * messages: [{ level: \"warning\", code: \"denied-license\", message: \"Denied licenses found.\" }]\n * };\n * }\n * return { status: \"passed\", data: { deniedCount: 0 } };\n * }\n * });\n * ```\n */\nexport function defineCheck<\n const Id extends string,\n AuthoredOptions extends object,\n PreparedOptions extends object = AuthoredOptions\n>(\n value: CheckWithOptions<Id, AuthoredOptions, PreparedOptions>\n): CheckWithOptions<Id, AuthoredOptions, PreparedOptions>;\nexport function defineCheck<const Id extends string>(\n value: CheckWithoutOptions<Id>\n): CheckWithoutOptions<Id>;\nexport function defineCheck<\n const Id extends string,\n AuthoredOptions extends object,\n const Parser extends CheckDataParser,\n PreparedOptions extends object = AuthoredOptions\n>(\n value: TypedCheckWithOptions<Id, AuthoredOptions, Parser, PreparedOptions>\n): TypedCheckWithOptions<Id, AuthoredOptions, Parser, PreparedOptions>;\nexport function defineCheck<const Id extends string, const Parser extends CheckDataParser>(\n value: TypedCheckWithoutOptions<Id, Parser>\n): TypedCheckWithoutOptions<Id, Parser>;\nexport function defineCheck(value: Check): Check {\n return value;\n}\n"]}
1
+ {"version":3,"file":"check.mjs","sourceRoot":"","sources":["../../../src/check/check.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,+BAA+B,EAAE,MAAM,gCAAgC,CAAC;AAEjF,OAAO,EACL,OAAO,EACP,0BAA0B,EAC1B,gCAAgC,EACjC,MAAM,2BAA2B,CAAC;AAmwBnC,MAAM,UAAU,WAAW,CAAC,KAAY;IACtC,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC3B,+BAA+B,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import type { CanonicalJsonObject, CanonicalJsonValue } from \"../data-boundary/canonical-json.ts\";\nimport type { InheritableCheckCollection } from \"./inherited-collection.ts\";\nimport type { CheckFlagEnablement } from \"./flag-enablement.ts\";\nimport type { CheckProjectContext } from \"./project-context.ts\";\nimport { registerHandoffProviderIdentity } from \"./handoff-provider-identity.ts\";\n\nexport {\n inherit,\n isInheritedCheckCollection,\n snapshotInheritedCheckCollection\n} from \"./inherited-collection.ts\";\nexport type {\n InheritCheckCollectionInput,\n InheritableCheckCollection,\n InheritedCheckCollection\n} from \"./inherited-collection.ts\";\n\n/** Check 无法给出 final data 时返回的受控 reason code。 */\nexport type CheckReason = Readonly<{\n /** 由 owning Check 定义、供调用方诊断的稳定 code。 */\n readonly code: string;\n}>;\n\n/** `not-applicable` Check result 的可选 reason。 */\nexport type CheckNotApplicableReason = CheckReason;\n/** author callback 明确返回 `unavailable` 时必须提供的 reason。 */\nexport type CheckDeclaredUnavailableReason = CheckReason;\n\n/** `unavailable` Check outcome 的 reason;可列出导致当前 Check 不可用的上游 Check。 */\nexport type CheckUnavailableReason = Readonly<{\n /** 由当前 Check 或 Product 边界给出的受控原因。 */\n readonly code: string;\n /** 仅在上游关系有助于定位时给出的相关 Check IDs。 */\n readonly checkIds?: readonly string[];\n}>;\n\n/** 终端 Check message 的 presentation severity。 */\nexport type CheckMessageLevel = \"info\" | \"warning\" | \"error\";\n\n/** 由 Check author 附加到 terminal result 的补充消息。 */\nexport interface CheckMessage {\n /** 人读 presentation 使用的 severity。 */\n readonly level: CheckMessageLevel;\n /** owning Check namespace 内的稳定 message code。 */\n readonly code: string;\n /** 非空消息正文;Product 保留 author 提供的字符串。 */\n readonly message: string;\n}\n\n/** 可附加到每个 {@link CheckResult} branch 的有序 terminal messages。 */\nexport interface CheckResultMessages {\n /** 省略、`undefined` 或空数组都表示没有 supplemental messages。 */\n readonly messages?: readonly CheckMessage[] | undefined;\n}\n\ntype HandoffForbidden = Readonly<{ readonly handoff?: never }>;\n\n/** Check Task 在 admission 到 settlement 期间持有的静态 named resource units。 */\nexport type CheckResourceClaims = Readonly<Record<string, number>>;\n\nexport type { CheckFlagCondition, CheckFlagEnablement } from \"./flag-enablement.ts\";\nexport type { ProjectChanges } from \"./project-changes.ts\";\nexport type { CheckProjectContext } from \"./project-context.ts\";\n\n/**\n * Check callback 的 terminal result。\n *\n * @typeParam FinalData - `passed` 或 `failed` 时保留为 canonical final data 的业务对象。\n * @remarks `not-applicable` 与 `unavailable` 不携带 final data;普通 callback、Record 或取消失败由\n * Product 转换为 `unavailable`,而不是抛出为 Run 的成功结果。\n */\nexport type CheckResult<\n FinalData extends object = object,\n Handoff extends object = never\n> = Readonly<\n (\n | ([Handoff] extends [never]\n ? {\n /** Check 已产生通过的 final data。 */\n readonly status: \"passed\";\n /** 此 Check 的主要终态事实。 */\n readonly data: FinalData;\n } & HandoffForbidden\n : {\n /** Check 已产生通过的 final data。 */\n readonly status: \"passed\";\n /** 此 Check 的主要终态事实。 */\n readonly data: FinalData;\n /** 仅由声明 `handoff: true` 的 provider 交接给 direct dependents 的 reference。 */\n readonly handoff: Handoff;\n })\n | ({\n /** Check 已产生失败的 final data。 */\n readonly status: \"failed\";\n /** 此 Check 的主要终态事实。 */\n readonly data: FinalData;\n } & HandoffForbidden)\n | ({\n /** Check 在当前 invocation 中不适用。 */\n readonly status: \"not-applicable\";\n /** 不适用的可选受控原因。 */\n readonly reason?: CheckNotApplicableReason;\n } & HandoffForbidden)\n | ({\n /** Check 不能提供 terminal data。 */\n readonly status: \"unavailable\";\n /** 不可用的受控原因。 */\n readonly reason: CheckDeclaredUnavailableReason;\n } & HandoffForbidden)\n ) &\n CheckResultMessages\n>;\n\n/** Check callback 的同步或异步 terminal result。 */\ntype CheckExecutionResult<FinalData extends object = object, Handoff extends object = never> =\n | CheckResult<FinalData, Handoff>\n | Promise<CheckResult<FinalData, Handoff>>;\n\ndeclare const CHECK_HANDOFF_PROVIDER_BRAND: unique symbol;\n\n/**\n * A Check returned by `defineCheck({ handoff: true })`. The type-only brand lets\n * `dependencies.get(provider)` infer the reference returned by that provider.\n *\n * @internal This is used by public callback types but authors never construct it.\n */\nexport type CheckHandoffProvider<\n Id extends string = string,\n Handoff extends object = object\n> = Readonly<{\n readonly checkId: Id;\n readonly handoff: true;\n readonly [CHECK_HANDOFF_PROVIDER_BRAND]: Handoff;\n}>;\n\n/** 已 materialize 到 Core snapshot 的 Check terminal outcome。 */\nexport type CheckOutcome = Readonly<\n | {\n /** 已 materialize 的通过 outcome。 */\n readonly status: \"passed\";\n /** 已 canonicalize 的 primary final fact。 */\n readonly data: CanonicalJsonObject;\n }\n | {\n /** 已 materialize 的失败 outcome。 */\n readonly status: \"failed\";\n /** 已 canonicalize 的 primary final fact。 */\n readonly data: CanonicalJsonObject;\n }\n | {\n /** 已 materialize 的不适用 outcome。 */\n readonly status: \"not-applicable\";\n /** 不适用的可选受控原因。 */\n readonly reason?: CheckNotApplicableReason;\n }\n | {\n /** 已 materialize 的不可用 outcome。 */\n readonly status: \"unavailable\";\n /** 包含相关 upstream Check IDs 的受控原因。 */\n readonly reason: CheckUnavailableReason;\n }\n>;\n\n/** 递归只读 Check callback options,同时保留 array/tuple 形状和非 object leaf 类型。 */\nexport type DeepReadonly<Value> = Value extends readonly unknown[]\n ? { readonly [Key in keyof Value]: DeepReadonly<Value[Key]> }\n : Value extends object\n ? { readonly [Key in keyof Value]: DeepReadonly<Value[Key]> }\n : Value;\n\n/** callback 写入 supplemental Record 时的 Check-local identity。 */\ninterface RecordIdentityInput {\n /** 在当前 Check 内唯一的 Record ID。 */\n readonly id: string;\n}\n\n/** callback 写入 supplemental Records 的 Product-owned reporter。 */\ninterface CheckRecordReporter {\n /** 记录一个补充事实;它不决定 Check 的 terminal status。 */\n report(identity: RecordIdentityInput, data: object): void;\n}\n\n/** 读取已声明 direct relation final data 时的失败原因。 */\nexport type DependencyReadError = Readonly<\n | {\n /** 当前 Check 未声明所请求的 direct relation ID。 */\n readonly code: \"dependency-not-declared\";\n /** 被拒绝的 direct relation ID。 */\n readonly checkId: string;\n }\n | {\n /** 已声明 upstream 没有可读取的 final data。 */\n readonly code: \"upstream-data-unavailable\";\n /** 没有 final data 的 direct relation ID。 */\n readonly checkId: string;\n /** 阻止 readback 的 upstream terminal status。 */\n readonly status: \"not-applicable\" | \"unavailable\";\n }\n>;\n\n/** {@link CheckDependencies.get} 的受控 readback 结果。 */\nexport type DependencyReadResult = Readonly<\n | {\n /** 成功读取 direct relation final data。 */\n readonly ok: true;\n /** 被读取的 direct relation ID。 */\n readonly checkId: string;\n /** upstream 已结算为 `passed` 或 `failed` 的 status。 */\n readonly status: \"passed\" | \"failed\";\n /** 已与原对象脱离的上游依赖终态数据。 */\n readonly data: CanonicalJsonObject;\n }\n | {\n /** direct relation data 不可读取。 */\n readonly ok: false;\n /** 失败的授权或 upstream-data reason。 */\n readonly error: DependencyReadError;\n }\n>;\n\n/** `dependsOn` provider-object handoff read 的受控结果。 */\nexport type DependencyHandoffReadResult<Id extends string, Handoff extends object> = Readonly<\n | {\n /** 同一 execution graph 中接受的 provider handoff。 */\n readonly ok: true;\n readonly checkId: Id;\n readonly status: \"passed\";\n /** Core-owned canonical provider final data。 */\n readonly data: CanonicalJsonObject;\n /** Provider 交接且未由 Product clone、freeze 或 serialize 的引用。 */\n readonly handoff: Handoff;\n }\n | {\n readonly ok: false;\n readonly error: Readonly<\n | {\n /** 当前 Check 未将 provider 声明为 direct `dependsOn`。 */\n readonly code: \"dependency-not-declared\";\n readonly checkId: string;\n }\n | {\n /** 已授权 provider 没有与其 Definition-internal identity 对应的已接受 passed handoff。 */\n readonly code: \"upstream-handoff-unavailable\";\n readonly checkId: string;\n }\n >;\n }\n>;\n\n/** 当前 Check 的一个已规范化直接 relation 及其完整终态事实。 */\nexport type DependencyObservation = Readonly<{\n /** 已规范化、稳定排序的 direct relation ID。 */\n readonly checkId: string;\n /** Core 已结算并冻结的四态 outcome。 */\n readonly outcome: CheckOutcome;\n}>;\n\n/** 当前 Check 的已规范化直接 relation outcomes 的 data reader。 */\nexport interface CheckDependencies {\n /**\n * Reads a `handoff: true` provider's accepted invocation-private handoff.\n *\n * @returns Only an effective direct `dependsOn` provider declared with `handoff: true`, whose\n * Definition-internal identity has accepted `passed` data, returns canonical data plus its typed\n * reference. `observes`, string IDs, lookalikes and unavailable handoffs fail closed without\n * upstream data.\n */\n get<Id extends string, Handoff extends object>(\n provider: CheckHandoffProvider<Id, Handoff>\n ): DependencyHandoffReadResult<Id, Handoff>;\n\n /**\n * 读取一个直接 relation 的 canonical final data。\n *\n * @returns 已声明的 `dependsOn` 或 `observes` relation 且为 `passed`/`failed` 的 Check 返回其 data;\n * 未声明或没有 final data 时返回 `ok: false`,不会授权 transitive Check。\n */\n get(checkId: string): DependencyReadResult;\n\n /**\n * 枚举当前 Check 的全部已规范化 direct relation outcomes。\n *\n * @returns 按有效 direct relation ID 稳定排序、深度冻结的 `{ checkId, outcome }` observations;只含当前\n * Check 显式或继承得到的 `dependsOn` / `observes` relation,不暴露 scheduler 历史、transitive 或未声明\n * Check。\n */\n list(): readonly DependencyObservation[];\n}\n\n/**\n * Check callback 收到的 Product-owned execution context。\n *\n * @typeParam Options - 此 Check preparation 后传给 execution 的 options shape。\n */\nexport interface CheckExecutionContext<Options extends object> {\n /** 当前 Check 的 absolute invocation artifact directory;caller 未授予时为 `null`。 */\n readonly artifactDirectory: string | null;\n /** 读取当前 Check 的已声明 direct relations。 */\n readonly dependencies: CheckDependencies;\n /** 同一次 invocation 内由 Product 统一提供的 identity。 */\n readonly invocationId: string;\n /** 深度只读、canonical 的 invocation-local prepared Check options。 */\n readonly options: DeepReadonly<Options>;\n /** 已规范化的项目根与 flags。 */\n readonly project: CheckProjectContext;\n /** 写入 supplemental Records 的 reporter。 */\n readonly records: CheckRecordReporter;\n /** 本次 invocation 的 cancellation signal。 */\n readonly signal: AbortSignal;\n}\n\n/**\n * 一个 Check 的 callback signature。\n *\n * @typeParam Options - callback 从 context 读取的 prepared options shape。\n * @returns terminal Check result 或其 Promise。\n */\nexport type CheckExecution<Options extends object = object> = (\n this: void,\n context: CheckExecutionContext<Options>\n) => CheckExecutionResult;\n\n/**\n * 在 Check execution 前,可选地为本次 invocation 准备 options。\n *\n * @remarks `signal` 与同一次 callback execution 使用同一个 cancellation signal;`project` 与 execution\n * 收到同一个冻结 project context。实现应在可等待工作中协作退出,而不是留下悬挂 work。bivariant callback\n * 保持具体 options Check 可进入普通递归 Check collection;Product 仍只会用该 Check 自己的 authored options 调用它。精确结果见\n * {@link CheckPreparationResult}。\n */\nexport type CheckPreparation<\n AuthoredOptions extends object = object,\n PreparedOptions extends object = AuthoredOptions\n> = {\n bivarianceHack(\n this: void,\n options: DeepReadonly<AuthoredOptions>,\n signal: AbortSignal,\n project?: CheckProjectContext\n ): CheckPreparationResult<PreparedOptions> | Promise<CheckPreparationResult<PreparedOptions>>;\n}[\"bivarianceHack\"];\n\n/**\n * Check-owned preparation 的判别结果。\n *\n * `failure/block` 不允许 fallback,直接以 owning reason 结算为 unavailable;`failure/continue` 必须给出\n * fallback 并继续 execution。两种进入 execution 的值都只属于本次 invocation,Product canonicalize/freeze\n * 后传递,不会改写 Definition 中 authored options。两个 failure 分支都必须给出 reason;continue reason\n * 是 Check-owned diagnostic identity,当前不会单独 materialize 为 outcome,调用方通过 messages 与后续\n * outcome 观察结果;block 物理上不含 fallback 字段。\n */\nexport type CheckPreparationResult<PreparedOptions extends object = object> = Readonly<\n | {\n readonly status: \"success\";\n readonly preparedOptions: PreparedOptions;\n readonly messages?: readonly CheckMessage[];\n }\n | {\n readonly status: \"failure\";\n readonly action: \"block\";\n readonly reason: CheckDeclaredUnavailableReason;\n readonly messages?: readonly CheckMessage[];\n }\n | {\n readonly status: \"failure\";\n readonly action: \"continue\";\n readonly fallback: PreparedOptions;\n readonly reason: CheckReason;\n readonly messages?: readonly CheckMessage[];\n }\n>;\n\n/**\n * 普通递归 Check authoring value 的共享字段。\n *\n * @typeParam AuthoredOptions - Definition 中的 declarative options shape。\n * @typeParam PreparedOptions - preparation 后 callback 接收的 invocation-local options shape。\n * @remarks 该值可以同时有 `execute` 和 `checks`;只有 executable node 产生 final Check fact。\n */\ninterface CheckBase<AuthoredOptions extends object, _PreparedOptions extends object> {\n /** 在 Definition 内唯一的 stable Check ID。 */\n readonly checkId: string;\n /** 人读 progress 与 output 使用的非空名称。 */\n readonly displayName: string;\n /** Check-owned declarative options;默认 Check 的嵌套 branch 以普通对象组合替换。 */\n readonly options?: AuthoredOptions;\n /** 仅当多 flag presence predicate 匹配时启用 executable Check;省略时始终启用。 */\n readonly enabledByFlags?: CheckFlagEnablement;\n /** `true` declares an invocation-private handoff on this executable Check. */\n readonly handoff?: true;\n /** 继承 scheduling context 的 child Checks,不会单独形成 container result。 */\n readonly checks?: readonly Check[];\n /** 必须全部 `passed` 才能开始当前 Check author work 的直接 prerequisite Check IDs。 */\n readonly dependsOn?: InheritableCheckCollection<string>;\n /** 等待任意 terminal outcome 并授权当前 Check readback 的直接 observation Check IDs。 */\n readonly observes?: InheritableCheckCollection<string>;\n /** 此 Check 及其 descendants 的最大并行预算。 */\n readonly maxParallel?: number;\n /** 同一 ready admission 层级中的静态优先级;省略时继承并最终规范化为 `0`。 */\n readonly admissionPriority?: number;\n /** 共享资源名称,或对父 mutex collection 的显式 edit。 */\n readonly mutex?: InheritableCheckCollection<string>;\n /** 静态 named resource claims;省略时继承,显式 mapping 完整替换。 */\n readonly resourceClaims?: CheckResourceClaims;\n}\n\ninterface ExecutableCheckFields<\n PreparedOptions extends object,\n ExecutionResult = CheckExecutionResult\n> {\n /** 可执行节点的 callback;拥有本字段的节点产生一个 terminal Check fact。 */\n execute(this: void, context: CheckExecutionContext<PreparedOptions>): ExecutionResult;\n /**\n * `true` 时,progress renderer 不保留没有 accepted Record 或 message 的 passed row;运行中与所有保留的\n * 终态 row 都无编号。该 policy 只属于 executable Check,不继承给 child Checks。\n */\n readonly omitQuietPassedRow?: true;\n}\n\n/** Container 只承载 children 与 scheduling,不能执行或设置 executable presentation policy。 */\ntype ContainerCheckFields = Readonly<{ execute?: never; omitQuietPassedRow?: never }>;\n\n/**\n * 判断两个 options shape 是否互相可赋值;互相可赋值时 execution 不需要 preparation 转换。\n */\ntype HasSameOptionsShape<AuthoredOptions extends object, PreparedOptions extends object> = [\n AuthoredOptions\n] extends [PreparedOptions]\n ? [PreparedOptions] extends [AuthoredOptions]\n ? true\n : false\n : false;\n\n/** Prepared shape 不同时,preparation 是建立安全转换的必填边界。 */\ntype CheckPreparationField<AuthoredOptions extends object, PreparedOptions extends object> =\n HasSameOptionsShape<AuthoredOptions, PreparedOptions> extends true\n ? Readonly<{ readonly prepare?: CheckPreparation<AuthoredOptions, PreparedOptions> }>\n : Readonly<{ readonly prepare: CheckPreparation<AuthoredOptions, PreparedOptions> }>;\n\n/**\n * Project Definition 中的普通递归 Check authoring value。\n *\n * @typeParam AuthoredOptions - Definition 中的 declarative options shape。\n * @typeParam PreparedOptions - preparation 后 callback 接收的 invocation-local options shape。\n * @remarks Definition 只闭合 authored JSON options;每个 admitted Check 先在自身 Task lifecycle 内执行\n * preparation,随后才执行 callback。`PreparedOptions` 与 `AuthoredOptions` 不同时必须提供 preparation;同形时可以\n * 省略。它不进入 declarative fingerprint 或 machine output。\n */\nexport type Check<\n AuthoredOptions extends object = object,\n PreparedOptions extends object = AuthoredOptions\n> = CheckBase<AuthoredOptions, PreparedOptions> &\n CheckPreparationField<AuthoredOptions, PreparedOptions> &\n (\n | ExecutableCheckFields<\n PreparedOptions,\n CheckExecutionResult | CheckExecutionResult<Readonly<Record<never, never>>, object>\n >\n | ContainerCheckFields\n );\n\nexport type EmptyCheckOptions = Readonly<Record<never, never>>;\n\n/**\n * 防止宽泛的 parser 标注擦除 `PromiseLike`。canonical `then` field 可以保存 JSON data,\n * 但不能保存使该值成为 thenable 的 callable。\n */\ntype NonThenableData = Readonly<{ readonly then?: CanonicalJsonValue }>;\n\n/**\n * 将 canonical direct-relation data 还原为 provider final-data shape 的同步 parser。\n *\n * @typeParam FinalData - provider 在 `passed`/`failed` result 中声明的 final-data shape。\n * @remarks Product 不调用此 parser;provider 负责不受信任或跨版本 data 的业务验证。\n */\nexport type CheckDataParser<FinalData extends object = object> = (\n this: void,\n data: CanonicalJsonObject\n) => FinalData & NonThenableData;\n\ntype CheckAuthoringBase<\n Id extends string,\n AuthoredOptions extends object,\n PreparedOptions extends object\n> = Omit<CheckBase<AuthoredOptions, PreparedOptions>, \"checkId\" | \"handoff\" | \"options\"> &\n CheckPreparationField<AuthoredOptions, PreparedOptions> &\n Readonly<{ readonly checkId: Id }>;\n\n/** Ordinary Check branches cannot declare typed-provider parsing or private handoff. */\ntype OrdinaryCheckRestrictions = HandoffForbidden & Readonly<{ parseData?: undefined }>;\n\ntype OrdinaryCheckFields<PreparedOptions extends object> =\n | (ExecutableCheckFields<PreparedOptions> & OrdinaryCheckRestrictions)\n | (ContainerCheckFields & OrdinaryCheckRestrictions);\n\nexport type CheckWithOptions<\n Id extends string,\n AuthoredOptions extends object,\n PreparedOptions extends object = AuthoredOptions\n> = CheckAuthoringBase<Id, AuthoredOptions, PreparedOptions> &\n OrdinaryCheckFields<PreparedOptions> &\n Readonly<{\n readonly options: AuthoredOptions;\n }>;\n\nexport type CheckWithoutOptions<Id extends string> = CheckAuthoringBase<\n Id,\n EmptyCheckOptions,\n EmptyCheckOptions\n> &\n OrdinaryCheckFields<EmptyCheckOptions> &\n Readonly<{\n readonly options?: never;\n }>;\n\ninterface TypedCheckFields<\n PreparedOptions extends object,\n Parser extends CheckDataParser\n> extends ExecutableCheckFields<\n PreparedOptions,\n CheckExecutionResult<NoInfer<ReturnType<Parser>>>\n> {\n /**\n * 将 canonical runtime data 还原为 provider data。\n *\n * 启发式边界:同版本且受信任的 provider 若由测试保证 data shape,可仅将它实现为\n * identity/type anchor。这不验证 JavaScript 或基于 cast 的 producer、历史或跨版本 artifact,\n * 也不验证不受信任输入。\n */\n readonly parseData: Parser;\n\n readonly handoff?: never;\n}\n\ninterface HandoffCheckFields<\n PreparedOptions extends object,\n Handoff extends object\n> extends ExecutableCheckFields<PreparedOptions, CheckExecutionResult<object, Handoff>> {\n readonly handoff: true;\n readonly parseData?: undefined;\n}\n\ninterface TypedHandoffCheckFields<\n PreparedOptions extends object,\n Parser extends CheckDataParser,\n Handoff extends object\n> extends ExecutableCheckFields<\n PreparedOptions,\n CheckExecutionResult<NoInfer<ReturnType<Parser>>, Handoff>\n> {\n readonly handoff: true;\n readonly parseData: Parser;\n}\n\n/** Extracts the private reference type from an already-validated passed terminal result. */\ntype HandoffFromTerminalResult<Result> =\n Extract<Awaited<Result>, { readonly status: \"passed\" }> extends {\n readonly handoff: infer Handoff;\n }\n ? Handoff extends object\n ? Handoff\n : never\n : never;\n\ntype PassedHandoffResult<Result> = Extract<Awaited<Result>, { readonly status: \"passed\" }>;\n\n/** Every passed branch must accept the complete inferred handoff type, not just one union member. */\ntype PassedHandoffBranchIsConsistent<Passed, Handoff> = Passed extends {\n readonly handoff: infer BranchHandoff;\n}\n ? [Handoff] extends [BranchHandoff]\n ? true\n : false\n : false;\n\ntype HandoffTerminalResultConstraint<Result> =\n false extends PassedHandoffBranchIsConsistent<\n PassedHandoffResult<Result>,\n HandoffFromTerminalResult<Result>\n >\n ? never\n : unknown;\n\ntype HandoffExecution<PreparedOptions extends object, FinalData extends object = object> = (\n this: void,\n context: CheckExecutionContext<PreparedOptions>\n) => CheckExecutionResult<FinalData, object>;\n\nexport type TypedCheckWithOptions<\n Id extends string,\n AuthoredOptions extends object,\n Parser extends CheckDataParser,\n PreparedOptions extends object = AuthoredOptions\n> = CheckAuthoringBase<Id, AuthoredOptions, PreparedOptions> &\n TypedCheckFields<PreparedOptions, Parser> &\n Readonly<{\n readonly options: AuthoredOptions;\n }>;\n\nexport type TypedCheckWithoutOptions<\n Id extends string,\n Parser extends CheckDataParser\n> = CheckAuthoringBase<Id, EmptyCheckOptions, EmptyCheckOptions> &\n TypedCheckFields<EmptyCheckOptions, Parser> &\n Readonly<{\n readonly options?: never;\n }>;\n\nexport type HandoffCheckWithOptions<\n Id extends string,\n AuthoredOptions extends object,\n Handoff extends object,\n PreparedOptions extends object = AuthoredOptions\n> = CheckAuthoringBase<Id, AuthoredOptions, PreparedOptions> &\n HandoffCheckFields<PreparedOptions, Handoff> &\n Readonly<{ readonly options: AuthoredOptions }>;\n\nexport type HandoffCheckWithoutOptions<\n Id extends string,\n Handoff extends object\n> = CheckAuthoringBase<Id, EmptyCheckOptions, EmptyCheckOptions> &\n HandoffCheckFields<EmptyCheckOptions, Handoff> &\n Readonly<{ readonly options?: never }>;\n\nexport type TypedHandoffCheckWithOptions<\n Id extends string,\n AuthoredOptions extends object,\n Parser extends CheckDataParser,\n Handoff extends object,\n PreparedOptions extends object = AuthoredOptions\n> = CheckAuthoringBase<Id, AuthoredOptions, PreparedOptions> &\n TypedHandoffCheckFields<PreparedOptions, Parser, Handoff> &\n Readonly<{ readonly options: AuthoredOptions }>;\n\nexport type TypedHandoffCheckWithoutOptions<\n Id extends string,\n Parser extends CheckDataParser,\n Handoff extends object\n> = CheckAuthoringBase<Id, EmptyCheckOptions, EmptyCheckOptions> &\n TypedHandoffCheckFields<EmptyCheckOptions, Parser, Handoff> &\n Readonly<{ readonly options?: never }>;\n\n/**\n * 定义一个 Check,同时保留 literal `checkId`、options 与 typed-provider parser 的 inference。\n *\n * @remarks 此函数负责 authoring inference;{@link run} 负责 Project Definition validation。\n * @example 定义带 options、Records 与 messages 的自定义 Check\n * ```ts\n * import { defineCheck, defineConfig, run } from \"@zxyycom/vibe-check\";\n *\n * function hasValidLicensePolicyOptions(options: object): boolean {\n * const denied: unknown = Reflect.get(options, \"denied\");\n * return (\n * Object.keys(options).length === 1 &&\n * Object.hasOwn(options, \"denied\") &&\n * Array.isArray(denied) &&\n * denied.every((license) => typeof license === \"string\")\n * );\n * }\n *\n * const licensePolicy = defineCheck({\n * checkId: \"license-policy\",\n * displayName: \"License policy\",\n * options: { denied: [\"GPL-3.0-only\"] },\n * prepare(options) {\n * return hasValidLicensePolicyOptions(options)\n * ? { status: \"success\", preparedOptions: options }\n * : { status: \"failure\", action: \"block\", reason: { code: \"invalid-options\" } };\n * },\n * omitQuietPassedRow: true,\n * execute({ options, records, signal }) {\n * if (signal.aborted) return { status: \"unavailable\", reason: { code: \"cancelled\" } };\n *\n * const deniedCount = options.denied.length;\n * if (deniedCount > 0) {\n * records.report({ id: \"denied-license\" }, { count: deniedCount });\n * return {\n * status: \"failed\",\n * data: { deniedCount },\n * messages: [{ level: \"warning\", code: \"denied-license\", message: \"Denied licenses found.\" }]\n * };\n * }\n * return { status: \"passed\", data: { deniedCount: 0 } };\n * }\n * });\n * ```\n */\nexport function defineCheck<\n const Id extends string,\n AuthoredOptions extends object,\n const Execution extends HandoffExecution<PreparedOptions>,\n PreparedOptions extends object = AuthoredOptions\n>(\n value: CheckAuthoringBase<Id, AuthoredOptions, PreparedOptions> &\n Readonly<{\n readonly handoff: true;\n readonly options: AuthoredOptions;\n readonly parseData?: undefined;\n readonly execute: Execution;\n }> &\n HandoffTerminalResultConstraint<ReturnType<Execution>>\n): HandoffCheckWithOptions<\n Id,\n AuthoredOptions,\n HandoffFromTerminalResult<ReturnType<Execution>>,\n PreparedOptions\n> &\n CheckHandoffProvider<Id, HandoffFromTerminalResult<ReturnType<Execution>>>;\nexport function defineCheck<\n const Id extends string,\n const Execution extends HandoffExecution<EmptyCheckOptions>\n>(\n value: CheckAuthoringBase<Id, EmptyCheckOptions, EmptyCheckOptions> &\n Readonly<{\n readonly handoff: true;\n readonly options?: never;\n readonly parseData?: undefined;\n readonly execute: Execution;\n }> &\n HandoffTerminalResultConstraint<ReturnType<Execution>>\n): HandoffCheckWithoutOptions<Id, HandoffFromTerminalResult<ReturnType<Execution>>> &\n CheckHandoffProvider<Id, HandoffFromTerminalResult<ReturnType<Execution>>>;\nexport function defineCheck<\n const Id extends string,\n AuthoredOptions extends object,\n const Parser extends CheckDataParser,\n const Execution extends HandoffExecution<PreparedOptions, NoInfer<ReturnType<Parser>>>,\n PreparedOptions extends object = AuthoredOptions\n>(\n value: CheckAuthoringBase<Id, AuthoredOptions, PreparedOptions> &\n Readonly<{\n readonly handoff: true;\n readonly options: AuthoredOptions;\n readonly parseData: Parser;\n readonly execute: Execution;\n }> &\n HandoffTerminalResultConstraint<ReturnType<Execution>>\n): TypedHandoffCheckWithOptions<\n Id,\n AuthoredOptions,\n Parser,\n HandoffFromTerminalResult<ReturnType<Execution>>,\n PreparedOptions\n> &\n CheckHandoffProvider<Id, HandoffFromTerminalResult<ReturnType<Execution>>>;\nexport function defineCheck<\n const Id extends string,\n const Parser extends CheckDataParser,\n const Execution extends HandoffExecution<EmptyCheckOptions, NoInfer<ReturnType<Parser>>>\n>(\n value: CheckAuthoringBase<Id, EmptyCheckOptions, EmptyCheckOptions> &\n Readonly<{\n readonly handoff: true;\n readonly options?: never;\n readonly parseData: Parser;\n readonly execute: Execution;\n }> &\n HandoffTerminalResultConstraint<ReturnType<Execution>>\n): TypedHandoffCheckWithoutOptions<Id, Parser, HandoffFromTerminalResult<ReturnType<Execution>>> &\n CheckHandoffProvider<Id, HandoffFromTerminalResult<ReturnType<Execution>>>;\nexport function defineCheck<\n const Id extends string,\n AuthoredOptions extends object,\n PreparedOptions extends object = AuthoredOptions\n>(\n value: CheckWithOptions<Id, AuthoredOptions, PreparedOptions>\n): CheckWithOptions<Id, AuthoredOptions, PreparedOptions>;\nexport function defineCheck<const Id extends string>(\n value: CheckWithoutOptions<Id>\n): CheckWithoutOptions<Id>;\nexport function defineCheck<\n const Id extends string,\n AuthoredOptions extends object,\n const Parser extends CheckDataParser,\n PreparedOptions extends object = AuthoredOptions\n>(\n value: TypedCheckWithOptions<Id, AuthoredOptions, Parser, PreparedOptions>\n): TypedCheckWithOptions<Id, AuthoredOptions, Parser, PreparedOptions>;\nexport function defineCheck<const Id extends string, const Parser extends CheckDataParser>(\n value: TypedCheckWithoutOptions<Id, Parser>\n): TypedCheckWithoutOptions<Id, Parser>;\nexport function defineCheck(value: Check): Check {\n if (value.handoff === true) {\n registerHandoffProviderIdentity(value);\n }\n return value;\n}\n"]}
@@ -0,0 +1,32 @@
1
+ /** 构造 `all` 条件;Definition 仍负责 validation、snapshot 与 freeze。 */
2
+ export function all(...conditions) {
3
+ return conditionSet("all", conditions);
4
+ }
5
+ /** 构造 `any` 条件;Definition 仍负责 validation、snapshot 与 freeze。 */
6
+ export function any(...conditions) {
7
+ return conditionSet("any", conditions);
8
+ }
9
+ /** 构造 `none` 条件;Definition 仍负责 validation、snapshot 与 freeze。 */
10
+ export function none(...conditions) {
11
+ return conditionSet("none", conditions);
12
+ }
13
+ /** 构造 `not-all` 条件;Definition 仍负责 validation、snapshot 与 freeze。 */
14
+ export function notAll(...conditions) {
15
+ return conditionSet("not-all", conditions);
16
+ }
17
+ /** 构造 `exactly-one` 条件;Definition 仍负责 validation、snapshot 与 freeze。 */
18
+ export function exactlyOne(...conditions) {
19
+ return conditionSet("exactly-one", conditions);
20
+ }
21
+ /** 构造 `not` 条件;Definition 仍负责 validation、snapshot 与 freeze。 */
22
+ export function not(condition) {
23
+ return { condition, kind: "not" };
24
+ }
25
+ /** 为一个已声明的 project change ID 生成保留 flag token。 */
26
+ export function changeFlag(id) {
27
+ return `vibe-check:change:${id}`;
28
+ }
29
+ function conditionSet(kind, conditions) {
30
+ return { kind, conditions };
31
+ }
32
+ //# sourceMappingURL=flag-enablement.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flag-enablement.mjs","sourceRoot":"","sources":["../../../src/check/flag-enablement.ts"],"names":[],"mappings":"AAuBA,+DAA+D;AAC/D,MAAM,UAAU,GAAG,CAAC,GAAG,UAAkC;IACvD,OAAO,YAAY,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AACzC,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,GAAG,CAAC,GAAG,UAAkC;IACvD,OAAO,YAAY,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AACzC,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,IAAI,CAAC,GAAG,UAAkC;IACxD,OAAO,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,MAAM,CAAC,GAAG,UAAkC;IAC1D,OAAO,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAC7C,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,UAAU,CACxB,GAAG,UAAkC;IAErC,OAAO,YAAY,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;AACjD,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,GAAG,CAAC,SAA6B;IAC/C,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,UAAU,CAA0B,EAAM;IACxD,OAAO,qBAAqB,EAAE,EAAE,CAAC;AACnC,CAAC;AAED,SAAS,YAAY,CACnB,IAAU,EACV,UAAkC;IAElC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAC9B,CAAC","sourcesContent":["/** 一个递归 flag presence 条件表达式。字符串是唯一 leaf;operator 保留 author child 顺序和 multiplicity。 */\nexport type CheckFlagCondition =\n | string\n | Readonly<{\n readonly kind: \"all\" | \"any\" | \"none\" | \"not-all\" | \"exactly-one\";\n readonly conditions: readonly [CheckFlagCondition, ...CheckFlagCondition[]];\n }>\n | Readonly<{\n readonly kind: \"not\";\n readonly condition: CheckFlagCondition;\n }>;\n\ntype CheckFlagConditionSetKind = \"all\" | \"any\" | \"none\" | \"not-all\" | \"exactly-one\";\ntype NonEmptyFlagConditions = readonly [CheckFlagCondition, ...CheckFlagCondition[]];\ntype CheckFlagConditionSet<Kind extends CheckFlagConditionSetKind> = Readonly<{\n readonly kind: Kind;\n readonly conditions: NonEmptyFlagConditions;\n}>;\ntype CheckFlagNegation = Readonly<{\n readonly kind: \"not\";\n readonly condition: CheckFlagCondition;\n}>;\n\n/** 构造 `all` 条件;Definition 仍负责 validation、snapshot 与 freeze。 */\nexport function all(...conditions: NonEmptyFlagConditions): CheckFlagConditionSet<\"all\"> {\n return conditionSet(\"all\", conditions);\n}\n\n/** 构造 `any` 条件;Definition 仍负责 validation、snapshot 与 freeze。 */\nexport function any(...conditions: NonEmptyFlagConditions): CheckFlagConditionSet<\"any\"> {\n return conditionSet(\"any\", conditions);\n}\n\n/** 构造 `none` 条件;Definition 仍负责 validation、snapshot 与 freeze。 */\nexport function none(...conditions: NonEmptyFlagConditions): CheckFlagConditionSet<\"none\"> {\n return conditionSet(\"none\", conditions);\n}\n\n/** 构造 `not-all` 条件;Definition 仍负责 validation、snapshot 与 freeze。 */\nexport function notAll(...conditions: NonEmptyFlagConditions): CheckFlagConditionSet<\"not-all\"> {\n return conditionSet(\"not-all\", conditions);\n}\n\n/** 构造 `exactly-one` 条件;Definition 仍负责 validation、snapshot 与 freeze。 */\nexport function exactlyOne(\n ...conditions: NonEmptyFlagConditions\n): CheckFlagConditionSet<\"exactly-one\"> {\n return conditionSet(\"exactly-one\", conditions);\n}\n\n/** 构造 `not` 条件;Definition 仍负责 validation、snapshot 与 freeze。 */\nexport function not(condition: CheckFlagCondition): CheckFlagNegation {\n return { condition, kind: \"not\" };\n}\n\n/** 为一个已声明的 project change ID 生成保留 flag token。 */\nexport function changeFlag<const Id extends string>(id: Id): `vibe-check:change:${Id}` {\n return `vibe-check:change:${id}`;\n}\n\nfunction conditionSet<Kind extends CheckFlagConditionSetKind>(\n kind: Kind,\n conditions: NonEmptyFlagConditions\n): CheckFlagConditionSet<Kind> {\n return { kind, conditions };\n}\n\n/** executable Check 的 flag 选择控制。 */\nexport interface CheckFlagEnablement {\n readonly when: CheckFlagCondition;\n /**\n * 条件命中时是否启动本 Check 的传递 `dependsOn` prerequisite;省略时只选择直接命中 Check。\n * `observes` 不参与此选择,且 dependency 自己的 flag 条件不会阻止已启动 prerequisite。\n */\n readonly propagateDependsOn?: true;\n}\n"]}
@@ -0,0 +1,18 @@
1
+ const handoffProviderIdentities = new WeakMap();
2
+ class HandoffProviderIdentityValue {
3
+ }
4
+ /** Registers the identity that makes a `handoff: true` Check authentic to this package runtime. */
5
+ export function registerHandoffProviderIdentity(value) {
6
+ handoffProviderIdentities.set(value, Object.freeze(new HandoffProviderIdentityValue()));
7
+ }
8
+ /** Returns the same-package identity registered by `defineCheck`. */
9
+ export function getDefinedHandoffProviderIdentity(value) {
10
+ return typeof value === "object" && value !== null
11
+ ? handoffProviderIdentities.get(value)
12
+ : undefined;
13
+ }
14
+ /** Preserves a Definition-validated provider identity during materialization. */
15
+ export function bindHandoffProviderIdentity(value, identity) {
16
+ handoffProviderIdentities.set(value, identity);
17
+ }
18
+ //# sourceMappingURL=handoff-provider-identity.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoff-provider-identity.mjs","sourceRoot":"","sources":["../../../src/check/handoff-provider-identity.ts"],"names":[],"mappings":"AAOA,MAAM,yBAAyB,GAAG,IAAI,OAAO,EAAmC,CAAC;AAEjF,MAAM,4BAA4B;CAEjC;AAED,mGAAmG;AACnG,MAAM,UAAU,+BAA+B,CAAC,KAAa;IAC3D,yBAAyB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,4BAA4B,EAAE,CAAC,CAAC,CAAC;AAC1F,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,iCAAiC,CAC/C,KAAc;IAEd,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAChD,CAAC,CAAC,yBAAyB,CAAC,GAAG,CAAC,KAAK,CAAC;QACtC,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,2BAA2B,CACzC,KAAa,EACb,QAAiC;IAEjC,yBAAyB,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC","sourcesContent":["declare const HANDOFF_PROVIDER_IDENTITY_BRAND: unique symbol;\n\n/** Opaque same-package identity retained only by Definition and invocation execution. */\nexport type HandoffProviderIdentity = Readonly<{\n readonly [HANDOFF_PROVIDER_IDENTITY_BRAND]: true;\n}>;\n\nconst handoffProviderIdentities = new WeakMap<object, HandoffProviderIdentity>();\n\nclass HandoffProviderIdentityValue implements HandoffProviderIdentity {\n declare readonly [HANDOFF_PROVIDER_IDENTITY_BRAND]: true;\n}\n\n/** Registers the identity that makes a `handoff: true` Check authentic to this package runtime. */\nexport function registerHandoffProviderIdentity(value: object): void {\n handoffProviderIdentities.set(value, Object.freeze(new HandoffProviderIdentityValue()));\n}\n\n/** Returns the same-package identity registered by `defineCheck`. */\nexport function getDefinedHandoffProviderIdentity(\n value: unknown\n): HandoffProviderIdentity | undefined {\n return typeof value === \"object\" && value !== null\n ? handoffProviderIdentities.get(value)\n : undefined;\n}\n\n/** Preserves a Definition-validated provider identity during materialization. */\nexport function bindHandoffProviderIdentity(\n value: object,\n identity: HandoffProviderIdentity\n): void {\n handoffProviderIdentities.set(value, identity);\n}\n"]}
@@ -44,7 +44,7 @@ function snapshotInheritedCollectionEntry(snapshot, key, descriptor) {
44
44
  if (!isDataDescriptor(descriptor))
45
45
  return "invalid";
46
46
  if (key === INHERITED_CHECK_COLLECTION) {
47
- return descriptor.enumerable || descriptor.value !== true ? "invalid" : "marker";
47
+ return descriptor.enumerable === true || descriptor.value !== true ? "invalid" : "marker";
48
48
  }
49
49
  if (typeof key !== "string" || descriptor.enumerable !== true)
50
50
  return "invalid";
@@ -1 +1 @@
1
- {"version":3,"file":"inherited-collection.mjs","sourceRoot":"","sources":["../../../src/check/inherited-collection.ts"],"names":[],"mappings":"AAAA,MAAM,0BAA0B,GAAkB,MAAM,CAAC,uCAAuC,CAAC,CAAC;AAyBlG,MAAM,oBAAoB,GAAG,IAAI,OAAO,EAAE,CAAC;AAI3C;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAI,KAAqC;IAC9D,MAAM,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,0BAA0B,CAAC,EAAE,IAAa,EAAE,CAAC;IACzE,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,0BAA0B,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IACjF,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,KAAc;IAEd,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACxF,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,gCAAgC,CAC9C,KAAwC;IAExC,IAAI,CAAC;QACH,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACtD,MAAM,QAAQ,GAA4B,EAAE,CAAC;QAC7C,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,gCAAgC,CAC5C,QAAQ,EACR,GAAG,EACH,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,GAAG,CAAC,CAC5C,CAAC;YACF,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAC1C,IAAI,KAAK,KAAK,QAAQ;gBAAE,SAAS,GAAG,IAAI,CAAC;QAC3C,CAAC;QACD,OAAO,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAa;IAC5C,MAAM,SAAS,GAAY,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACxD,OAAO,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI,CAAC;AAC9D,CAAC;AAED,SAAS,gCAAgC,CACvC,QAAiC,EACjC,GAAgB,EAChB,UAA0C;IAE1C,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IACpD,IAAI,GAAG,KAAK,0BAA0B,EAAE,CAAC;QACvC,OAAO,UAAU,CAAC,UAAU,IAAI,UAAU,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IACnF,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,UAAU,CAAC,UAAU,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAChF,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,EAAE;QACnC,YAAY,EAAE,IAAI;QAClB,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CACvB,UAA0C;IAE1C,OAAO,UAAU,KAAK,SAAS,IAAI,UAAU,CAAC,GAAG,KAAK,SAAS,IAAI,UAAU,CAAC,GAAG,KAAK,SAAS,CAAC;AAClG,CAAC","sourcesContent":["const INHERITED_CHECK_COLLECTION: unique symbol = Symbol(\"vibe-check.inherited-check-collection\");\n\n/** 使用 {@link inherit} 对父 Check 的 string collection 做显式增删的输入。 */\nexport type InheritCheckCollectionInput<T> = Readonly<\n | { readonly add: readonly T[]; readonly remove?: readonly T[] }\n | { readonly add?: readonly T[]; readonly remove: readonly T[] }\n>;\n\n/**\n * 由 {@link inherit} 创建、带有不可伪造 marker 的 collection edit。\n *\n * @remarks Definition validation 不接受看起来相同的 plain object。\n */\nexport type InheritedCheckCollection<T> = InheritCheckCollectionInput<T> &\n Readonly<{\n readonly [INHERITED_CHECK_COLLECTION]: true;\n }>;\n\n/**\n * 可以直接替换父 collection 的数组,或由 {@link inherit} 表示的显式 edit。\n *\n * @typeParam T - collection item 类型。\n */\nexport type InheritableCheckCollection<T> = readonly T[] | InheritedCheckCollection<T>;\n\nconst inheritedCollections = new WeakSet();\n\ntype InheritedCollectionEntry = \"data\" | \"invalid\" | \"marker\";\n\n/**\n * 创建可用于 `dependsOn`、`observes` 或 `mutex` 的受信任继承编辑。\n *\n * @typeParam T - 要添加或移除的 collection item 类型。\n * @param value - 至少提供 `add` 或 `remove` 的 edit;空数组可显式表示不添加或不移除。\n * @returns 只有此函数创建的值会被 Definition validation 识别为 inherited collection。\n */\nexport function inherit<T>(value: InheritCheckCollectionInput<T>): InheritedCheckCollection<T> {\n const result = { ...value, [INHERITED_CHECK_COLLECTION]: true as const };\n Object.defineProperty(result, INHERITED_CHECK_COLLECTION, { enumerable: false });\n inheritedCollections.add(result);\n return result;\n}\n\nexport function isInheritedCheckCollection(\n value: unknown\n): value is InheritedCheckCollection<unknown> {\n return typeof value === \"object\" && value !== null && inheritedCollections.has(value);\n}\n\n/** Copies the trusted marker while preserving the authoring data's closed shape. */\nexport function snapshotInheritedCheckCollection(\n value: InheritedCheckCollection<unknown>\n): Readonly<Record<string, unknown>> | undefined {\n try {\n if (!hasPlainObjectPrototype(value)) return undefined;\n const snapshot: Record<string, unknown> = {};\n let hasMarker = false;\n for (const key of Reflect.ownKeys(value)) {\n const entry = snapshotInheritedCollectionEntry(\n snapshot,\n key,\n Object.getOwnPropertyDescriptor(value, key)\n );\n if (entry === \"invalid\") return undefined;\n if (entry === \"marker\") hasMarker = true;\n }\n return hasMarker ? Object.freeze(snapshot) : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction hasPlainObjectPrototype(value: object): boolean {\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction snapshotInheritedCollectionEntry(\n snapshot: Record<string, unknown>,\n key: PropertyKey,\n descriptor: PropertyDescriptor | undefined\n): InheritedCollectionEntry {\n if (!isDataDescriptor(descriptor)) return \"invalid\";\n if (key === INHERITED_CHECK_COLLECTION) {\n return descriptor.enumerable || descriptor.value !== true ? \"invalid\" : \"marker\";\n }\n if (typeof key !== \"string\" || descriptor.enumerable !== true) return \"invalid\";\n Object.defineProperty(snapshot, key, {\n configurable: true,\n enumerable: true,\n value: descriptor.value,\n writable: true\n });\n return \"data\";\n}\n\nfunction isDataDescriptor(\n descriptor: PropertyDescriptor | undefined\n): descriptor is PropertyDescriptor {\n return descriptor !== undefined && descriptor.get === undefined && descriptor.set === undefined;\n}\n"]}
1
+ {"version":3,"file":"inherited-collection.mjs","sourceRoot":"","sources":["../../../src/check/inherited-collection.ts"],"names":[],"mappings":"AAAA,MAAM,0BAA0B,GAAkB,MAAM,CAAC,uCAAuC,CAAC,CAAC;AAyBlG,MAAM,oBAAoB,GAAG,IAAI,OAAO,EAAE,CAAC;AAI3C;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAI,KAAqC;IAC9D,MAAM,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC,0BAA0B,CAAC,EAAE,IAAa,EAAE,CAAC;IACzE,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,0BAA0B,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IACjF,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,KAAc;IAEd,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACxF,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,gCAAgC,CAC9C,KAAwC;IAExC,IAAI,CAAC;QACH,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACtD,MAAM,QAAQ,GAA4B,EAAE,CAAC;QAC7C,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,gCAAgC,CAC5C,QAAQ,EACR,GAAG,EACH,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,GAAG,CAAC,CAC5C,CAAC;YACF,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAC1C,IAAI,KAAK,KAAK,QAAQ;gBAAE,SAAS,GAAG,IAAI,CAAC;QAC3C,CAAC;QACD,OAAO,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAa;IAC5C,MAAM,SAAS,GAAY,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACxD,OAAO,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI,CAAC;AAC9D,CAAC;AAED,SAAS,gCAAgC,CACvC,QAAiC,EACjC,GAAgB,EAChB,UAA0C;IAE1C,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IACpD,IAAI,GAAG,KAAK,0BAA0B,EAAE,CAAC;QACvC,OAAO,UAAU,CAAC,UAAU,KAAK,IAAI,IAAI,UAAU,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC5F,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,UAAU,CAAC,UAAU,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAChF,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,EAAE;QACnC,YAAY,EAAE,IAAI;QAClB,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CACvB,UAA0C;IAE1C,OAAO,UAAU,KAAK,SAAS,IAAI,UAAU,CAAC,GAAG,KAAK,SAAS,IAAI,UAAU,CAAC,GAAG,KAAK,SAAS,CAAC;AAClG,CAAC","sourcesContent":["const INHERITED_CHECK_COLLECTION: unique symbol = Symbol(\"vibe-check.inherited-check-collection\");\n\n/** 使用 {@link inherit} 对父 Check 的 string collection 做显式增删的输入。 */\nexport type InheritCheckCollectionInput<T> = Readonly<\n | { readonly add: readonly T[]; readonly remove?: readonly T[] }\n | { readonly add?: readonly T[]; readonly remove: readonly T[] }\n>;\n\n/**\n * 由 {@link inherit} 创建、带有不可伪造 marker 的 collection edit。\n *\n * @remarks Definition validation 不接受看起来相同的 plain object。\n */\nexport type InheritedCheckCollection<T> = InheritCheckCollectionInput<T> &\n Readonly<{\n readonly [INHERITED_CHECK_COLLECTION]: true;\n }>;\n\n/**\n * 可以直接替换父 collection 的数组,或由 {@link inherit} 表示的显式 edit。\n *\n * @typeParam T - collection item 类型。\n */\nexport type InheritableCheckCollection<T> = readonly T[] | InheritedCheckCollection<T>;\n\nconst inheritedCollections = new WeakSet();\n\ntype InheritedCollectionEntry = \"data\" | \"invalid\" | \"marker\";\n\n/**\n * 创建可用于 `dependsOn`、`observes` 或 `mutex` 的受信任继承编辑。\n *\n * @typeParam T - 要添加或移除的 collection item 类型。\n * @param value - 至少提供 `add` 或 `remove` 的 edit;空数组可显式表示不添加或不移除。\n * @returns 只有此函数创建的值会被 Definition validation 识别为 inherited collection。\n */\nexport function inherit<T>(value: InheritCheckCollectionInput<T>): InheritedCheckCollection<T> {\n const result = { ...value, [INHERITED_CHECK_COLLECTION]: true as const };\n Object.defineProperty(result, INHERITED_CHECK_COLLECTION, { enumerable: false });\n inheritedCollections.add(result);\n return result;\n}\n\nexport function isInheritedCheckCollection(\n value: unknown\n): value is InheritedCheckCollection<unknown> {\n return typeof value === \"object\" && value !== null && inheritedCollections.has(value);\n}\n\n/** Copies the trusted marker while preserving the authoring data's closed shape. */\nexport function snapshotInheritedCheckCollection(\n value: InheritedCheckCollection<unknown>\n): Readonly<Record<string, unknown>> | undefined {\n try {\n if (!hasPlainObjectPrototype(value)) return undefined;\n const snapshot: Record<string, unknown> = {};\n let hasMarker = false;\n for (const key of Reflect.ownKeys(value)) {\n const entry = snapshotInheritedCollectionEntry(\n snapshot,\n key,\n Object.getOwnPropertyDescriptor(value, key)\n );\n if (entry === \"invalid\") return undefined;\n if (entry === \"marker\") hasMarker = true;\n }\n return hasMarker ? Object.freeze(snapshot) : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction hasPlainObjectPrototype(value: object): boolean {\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction snapshotInheritedCollectionEntry(\n snapshot: Record<string, unknown>,\n key: PropertyKey,\n descriptor: PropertyDescriptor | undefined\n): InheritedCollectionEntry {\n if (!isDataDescriptor(descriptor)) return \"invalid\";\n if (key === INHERITED_CHECK_COLLECTION) {\n return descriptor.enumerable === true || descriptor.value !== true ? \"invalid\" : \"marker\";\n }\n if (typeof key !== \"string\" || descriptor.enumerable !== true) return \"invalid\";\n Object.defineProperty(snapshot, key, {\n configurable: true,\n enumerable: true,\n value: descriptor.value,\n writable: true\n });\n return \"data\";\n}\n\nfunction isDataDescriptor(\n descriptor: PropertyDescriptor | undefined\n): descriptor is PropertyDescriptor {\n return descriptor !== undefined && descriptor.get === undefined && descriptor.set === undefined;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=project-changes.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-changes.mjs","sourceRoot":"","sources":["../../../src/check/project-changes.ts"],"names":[],"mappings":"","sourcesContent":["/** 已配置的 project change preparation 产生的 file-centric evidence。 */\nexport type ProjectChanges = Readonly<\n | {\n readonly ok: true;\n readonly files: readonly Readonly<{\n readonly path: string;\n readonly flags: readonly string[];\n }>[];\n }\n | {\n readonly ok: false;\n readonly reason: Readonly<{ readonly code: string }>;\n }\n>;\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=project-context.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-context.mjs","sourceRoot":"","sources":["../../../src/check/project-context.ts"],"names":[],"mappings":"","sourcesContent":["import type { ProjectChanges } from \"./project-changes.ts\";\n\n/** 每次 Run 共享、冻结的 caller project context。 */\nexport interface CheckProjectContext {\n /** 本次 Run 使用的绝对项目根目录。 */\n readonly root: string;\n /** 已去重、排序的 invocation-effective flags(caller flags 与派生 change flags)。 */\n readonly flags: readonly string[];\n /** 只在当前 Project Definition 配置 change preparation 时存在。 */\n readonly changes?: ProjectChanges;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"facts.mjs","sourceRoot":"","sources":["../../../src/check-settlement/facts.ts"],"names":[],"mappings":"","sourcesContent":["import type { CheckDescriptor } from \"../check/descriptor.ts\";\nimport type { CheckOutcome } from \"../check/check.ts\";\n\nexport type {\n CanonicalJsonObject,\n CanonicalJsonPrimitive,\n CanonicalJsonValue\n} from \"../data-boundary/canonical-data.ts\";\nexport type { CheckDescriptor, CheckOutcome };\n\n/** A Core Check has exactly one terminal outcome and no execution bookkeeping. */\nexport interface CoreCheck extends CheckDescriptor {\n readonly outcome: CheckOutcome;\n}\n\n/** A supplemental Record is owned by its structural `{ checkId, id }` identity. */\nexport interface CoreRecord {\n readonly checkId: string;\n readonly id: string;\n readonly data: import(\"../data-boundary/canonical-data.ts\").CanonicalJsonObject;\n}\n\n/** The complete Product entity projection. Invocation metadata belongs to Run, not Core. */\nexport interface CoreSnapshot {\n readonly checks: readonly CoreCheck[];\n readonly records: readonly CoreRecord[];\n}\n"]}
1
+ {"version":3,"file":"facts.mjs","sourceRoot":"","sources":["../../../src/check-settlement/facts.ts"],"names":[],"mappings":"","sourcesContent":["import type { CheckDescriptor } from \"../check/descriptor.ts\";\nimport type { CheckOutcome } from \"../check/check.ts\";\n\nexport type {\n CanonicalJsonObject,\n CanonicalJsonPrimitive,\n CanonicalJsonValue\n} from \"../data-boundary/canonical-data.ts\";\nexport type { CheckDescriptor, CheckOutcome };\n\n/** Core Check 恰有一个 terminal outcome,不携带 execution bookkeeping。 */\nexport interface CoreCheck extends CheckDescriptor {\n readonly outcome: CheckOutcome;\n}\n\n/** A supplemental Record is owned by its structural `{ checkId, id }` identity. */\nexport interface CoreRecord {\n readonly checkId: string;\n readonly id: string;\n readonly data: import(\"../data-boundary/canonical-data.ts\").CanonicalJsonObject;\n}\n\n/** The complete Product entity projection. Invocation metadata belongs to Run, not Core. */\nexport interface CoreSnapshot {\n readonly checks: readonly CoreCheck[];\n readonly records: readonly CoreRecord[];\n}\n"]}
@@ -10,7 +10,7 @@ export class CoreRecordStore {
10
10
  if (id === undefined || data === undefined)
11
11
  return this.#reject(slot, "record-invalid");
12
12
  let records = this.#recordsByCheckId.get(slot.checkId);
13
- if (records?.has(id))
13
+ if (records?.has(id) === true)
14
14
  return this.#reject(slot, "record-conflict");
15
15
  if (records === undefined) {
16
16
  records = new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"record-store.mjs","sourceRoot":"","sources":["../../../src/check-settlement/record-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { canonicalizeJsonObject } from \"../data-boundary/canonical-data.ts\";\nimport type { CoreRecord } from \"./facts.ts\";\nimport { snapshotClosedRecord } from \"../data-boundary/closed-values.ts\";\n\nexport type RecordSubmissionResult = \"committed\" | \"rejected\";\n\nconst EMPTY_RECORDS: readonly CoreRecord[] = Object.freeze([]);\nexport type RecordDiagnostic = \"record-conflict\" | \"record-invalid\";\n\nexport interface CoreRecordSlot {\n readonly checkId: string;\n readonly diagnostics: Set<RecordDiagnostic>;\n}\n\n/** Holds Check-local supplemental Records without inventing a composite string identity. */\nexport class CoreRecordStore {\n readonly #recordsByCheckId = new Map<string, Map<string, CoreRecord>>();\n\n public report(\n slot: CoreRecordSlot,\n rawIdentity: unknown,\n rawData: unknown\n ): RecordSubmissionResult {\n const id = recordId(rawIdentity);\n const data = canonicalizeJsonObject(rawData);\n if (id === undefined || data === undefined) return this.#reject(slot, \"record-invalid\");\n\n let records = this.#recordsByCheckId.get(slot.checkId);\n if (records?.has(id)) return this.#reject(slot, \"record-conflict\");\n if (records === undefined) {\n records = new Map<string, CoreRecord>();\n this.#recordsByCheckId.set(slot.checkId, records);\n }\n const record: CoreRecord = Object.freeze({ checkId: slot.checkId, id, data });\n records.set(id, record);\n return \"committed\";\n }\n\n public recordsForCheckInCanonicalOrder(checkId: string): readonly CoreRecord[] {\n const recordsById = this.#recordsByCheckId.get(checkId);\n if (recordsById === undefined) return EMPTY_RECORDS;\n return Object.freeze(\n [...recordsById.values()].sort((left, right) => compareText(left.id, right.id))\n );\n }\n\n public recordsInCanonicalOrder(): readonly CoreRecord[] {\n return Object.freeze(\n [...this.#recordsByCheckId.keys()]\n .sort(compareText)\n .flatMap((checkId) => this.recordsForCheckInCanonicalOrder(checkId))\n );\n }\n\n #reject(slot: CoreRecordSlot, diagnostic: RecordDiagnostic): \"rejected\" {\n slot.diagnostics.add(diagnostic);\n return \"rejected\";\n }\n}\n\nfunction recordId(value: unknown): string | undefined {\n const identity = snapshotClosedRecord(value);\n return identity !== undefined &&\n Object.keys(identity).length === 1 &&\n Object.hasOwn(identity, \"id\") &&\n typeof identity.id === \"string\" &&\n identity.id.length > 0\n ? identity.id\n : undefined;\n}\n\nfunction compareText(left: string, right: string): number {\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n"]}
1
+ {"version":3,"file":"record-store.mjs","sourceRoot":"","sources":["../../../src/check-settlement/record-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { canonicalizeJsonObject } from \"../data-boundary/canonical-data.ts\";\nimport type { CoreRecord } from \"./facts.ts\";\nimport { snapshotClosedRecord } from \"../data-boundary/closed-values.ts\";\n\nexport type RecordSubmissionResult = \"committed\" | \"rejected\";\n\nconst EMPTY_RECORDS: readonly CoreRecord[] = Object.freeze([]);\nexport type RecordDiagnostic = \"record-conflict\" | \"record-invalid\";\n\nexport interface CoreRecordSlot {\n readonly checkId: string;\n readonly diagnostics: Set<RecordDiagnostic>;\n}\n\n/** Holds Check-local supplemental Records without inventing a composite string identity. */\nexport class CoreRecordStore {\n readonly #recordsByCheckId = new Map<string, Map<string, CoreRecord>>();\n\n public report(\n slot: CoreRecordSlot,\n rawIdentity: unknown,\n rawData: unknown\n ): RecordSubmissionResult {\n const id = recordId(rawIdentity);\n const data = canonicalizeJsonObject(rawData);\n if (id === undefined || data === undefined) return this.#reject(slot, \"record-invalid\");\n\n let records = this.#recordsByCheckId.get(slot.checkId);\n if (records?.has(id) === true) return this.#reject(slot, \"record-conflict\");\n if (records === undefined) {\n records = new Map<string, CoreRecord>();\n this.#recordsByCheckId.set(slot.checkId, records);\n }\n const record: CoreRecord = Object.freeze({ checkId: slot.checkId, id, data });\n records.set(id, record);\n return \"committed\";\n }\n\n public recordsForCheckInCanonicalOrder(checkId: string): readonly CoreRecord[] {\n const recordsById = this.#recordsByCheckId.get(checkId);\n if (recordsById === undefined) return EMPTY_RECORDS;\n return Object.freeze(\n [...recordsById.values()].sort((left, right) => compareText(left.id, right.id))\n );\n }\n\n public recordsInCanonicalOrder(): readonly CoreRecord[] {\n return Object.freeze(\n [...this.#recordsByCheckId.keys()]\n .sort(compareText)\n .flatMap((checkId) => this.recordsForCheckInCanonicalOrder(checkId))\n );\n }\n\n #reject(slot: CoreRecordSlot, diagnostic: RecordDiagnostic): \"rejected\" {\n slot.diagnostics.add(diagnostic);\n return \"rejected\";\n }\n}\n\nfunction recordId(value: unknown): string | undefined {\n const identity = snapshotClosedRecord(value);\n return identity !== undefined &&\n Object.keys(identity).length === 1 &&\n Object.hasOwn(identity, \"id\") &&\n typeof identity.id === \"string\" &&\n identity.id.length > 0\n ? identity.id\n : undefined;\n}\n\nfunction compareText(left: string, right: string): number {\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n"]}
@@ -1,17 +1,35 @@
1
1
  const encoder = new TextEncoder();
2
2
  /**
3
- * Materializes arbitrary author data without property reads or JSON hooks.
4
- * The returned graph is detached, prototype-safe, and deeply frozen before it
5
- * becomes a Core fact. Canonical text order is applied explicitly at serialization.
3
+ * 将输入规范化为独立且递归冻结的 canonical JSON 对象副本。
4
+ *
5
+ * 递归内容只接受普通对象或 null-prototype 对象、标准无空洞数组和有限 JSON 基本值;仅当顶层结果是
6
+ * 非数组对象时返回该副本。输出对象使用 null prototype,输出对象和数组均独立于输入且递归冻结。不调用
7
+ * getter 或 `toJSON`;无效输入、循环引用或反射失败返回 `undefined`。反射 Proxy 时仍可能执行其 trap,
8
+ * 不隔离 trap 的副作用。
6
9
  */
7
10
  export function canonicalizeJsonObject(value) {
8
11
  const canonical = canonicalize(value, new Set());
9
12
  return canonical !== undefined && isCanonicalJsonObject(canonical) ? canonical : undefined;
10
13
  }
14
+ /**
15
+ * 将输入规范化为独立且递归冻结的 canonical JSON 值副本。
16
+ *
17
+ * 接受 `null`、boolean、string、有限 number、普通对象或 null-prototype 对象,以及标准无空洞数组;
18
+ * `-0` 转换为 `0`,输出对象使用 null prototype。拒绝存取器、稀疏数组、不可枚举的自有属性、非有限
19
+ * number 和其它 prototype。不调用 getter 或 `toJSON`;无效输入、循环引用或反射失败返回 `undefined`。
20
+ * 反射 Proxy 时仍可能执行其 trap,不隔离 trap 的副作用。`CanonicalJsonPrimitive` 的 `number` 在
21
+ * TypeScript 中仍可表示 `NaN`,有限性只能由本函数在运行时检查。
22
+ */
11
23
  export function canonicalizeJsonValue(value) {
12
24
  return canonicalize(value, new Set());
13
25
  }
14
- /** Serializes detached canonical JSON with explicit lexical object-key ordering. */
26
+ /**
27
+ * 规范化输入后生成确定性的无额外空白 JSON 文本。
28
+ *
29
+ * 对象键按固定的 lexical `<` 顺序输出,不承诺遵循外部 canonical-JSON 标准。即使同一对象已经过
30
+ * 规范化,`JSON.stringify` 仍按 ECMAScript 的整数索引键顺序输出,不能替代本函数。输入规则与 Proxy
31
+ * 边界同 `canonicalizeJsonValue`;无效输入或无法反射的 Proxy 均抛出 `TypeError`。
32
+ */
15
33
  export function canonicalJsonText(value) {
16
34
  const canonical = canonicalizeJsonValue(value);
17
35
  if (canonical === undefined) {
@@ -19,7 +37,12 @@ export function canonicalJsonText(value) {
19
37
  }
20
38
  return canonicalText(canonical);
21
39
  }
22
- /** Emits canonical UTF-8 JSON without invoking author getters or `toJSON`. */
40
+ /**
41
+ * 规范化输入后生成与 `canonicalJsonText` 相同的确定性 UTF-8 JSON 字节。
42
+ *
43
+ * 函数自行完成规范化与固定键排序,不要求调用方先取得 canonical JSON 值。输入规则、Proxy 边界和
44
+ * `TypeError` 失败方式与 `canonicalJsonText` 相同。
45
+ */
23
46
  export function canonicalJsonBytes(value) {
24
47
  return encoder.encode(canonicalJsonText(value));
25
48
  }
@@ -69,7 +92,7 @@ function denseCanonicalArrayLength(value) {
69
92
  return undefined;
70
93
  const keys = Reflect.ownKeys(value);
71
94
  const lengthDescriptor = Object.getOwnPropertyDescriptor(value, "length");
72
- if (!isDataDescriptor(lengthDescriptor) || lengthDescriptor.enumerable)
95
+ if (!isDataDescriptor(lengthDescriptor) || lengthDescriptor.enumerable === true)
73
96
  return undefined;
74
97
  const length = lengthDescriptor.value;
75
98
  if (typeof length !== "number" ||
@@ -143,7 +166,13 @@ function canonicalText(value) {
143
166
  }
144
167
  return `{${Object.keys(value)
145
168
  .sort(compareText)
146
- .map((key) => `${JSON.stringify(key)}:${canonicalText(value[key])}`)
169
+ .map((key) => {
170
+ const entry = value[key];
171
+ if (entry === undefined) {
172
+ throw new TypeError(`Canonical JSON object is missing declared key: ${key}`);
173
+ }
174
+ return `${JSON.stringify(key)}:${canonicalText(entry)}`;
175
+ })
147
176
  .join(",")}}`;
148
177
  }
149
178
  function isCanonicalJsonArray(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-data.mjs","sourceRoot":"","sources":["../../../src/data-boundary/canonical-data.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CanonicalJsonObject, CanonicalJsonValue } from \"./canonical-json.ts\";\n\nexport type {\n CanonicalJsonObject,\n CanonicalJsonPrimitive,\n CanonicalJsonValue\n} from \"./canonical-json.ts\";\n\nconst encoder = new TextEncoder();\n\n/**\n * Materializes arbitrary author data without property reads or JSON hooks.\n * The returned graph is detached, prototype-safe, and deeply frozen before it\n * becomes a Core fact. Canonical text order is applied explicitly at serialization.\n */\nexport function canonicalizeJsonObject(value: unknown): CanonicalJsonObject | undefined {\n const canonical = canonicalize(value, new Set<object>());\n return canonical !== undefined && isCanonicalJsonObject(canonical) ? canonical : undefined;\n}\n\nexport function canonicalizeJsonValue(value: unknown): CanonicalJsonValue | undefined {\n return canonicalize(value, new Set<object>());\n}\n\n/** Serializes detached canonical JSON with explicit lexical object-key ordering. */\nexport function canonicalJsonText(value: unknown): string {\n const canonical = canonicalizeJsonValue(value);\n if (canonical === undefined) {\n throw new TypeError(\"Canonical JSON could not safely materialize the input\");\n }\n return canonicalText(canonical);\n}\n\n/** Emits canonical UTF-8 JSON without invoking author getters or `toJSON`. */\nexport function canonicalJsonBytes(value: unknown): Uint8Array {\n return encoder.encode(canonicalJsonText(value));\n}\n\nfunction canonicalize(value: unknown, ancestors: Set<object>): CanonicalJsonValue | undefined {\n if (value === null) return null;\n const primitive = canonicalPrimitive(value);\n if (primitive !== undefined) return primitive;\n if (typeof value !== \"object\") return undefined;\n if (!admitCanonicalObject(value, ancestors)) return undefined;\n\n try {\n return Array.isArray(value)\n ? canonicalizeArray(value, ancestors)\n : canonicalizeObject(value, ancestors);\n } catch {\n return undefined;\n } finally {\n ancestors.delete(value);\n }\n}\n\nfunction canonicalPrimitive(value: unknown): CanonicalJsonValue | undefined {\n if (typeof value === \"boolean\" || typeof value === \"string\") return value;\n if (typeof value !== \"number\" || !Number.isFinite(value)) return undefined;\n return Object.is(value, -0) ? 0 : value;\n}\n\nfunction admitCanonicalObject(value: object, ancestors: Set<object>): boolean {\n if (ancestors.has(value)) return false;\n ancestors.add(value);\n return true;\n}\n\nfunction canonicalizeArray(\n value: readonly unknown[],\n ancestors: Set<object>\n): readonly CanonicalJsonValue[] | undefined {\n const length = denseCanonicalArrayLength(value);\n if (length === undefined) return undefined;\n return canonicalArrayElements(value, length, ancestors);\n}\n\nfunction denseCanonicalArrayLength(value: readonly unknown[]): number | undefined {\n if (Object.getPrototypeOf(value) !== Array.prototype) return undefined;\n const keys = Reflect.ownKeys(value);\n const lengthDescriptor = Object.getOwnPropertyDescriptor(value, \"length\");\n if (!isDataDescriptor(lengthDescriptor) || lengthDescriptor.enumerable) return undefined;\n const length = lengthDescriptor.value;\n if (\n typeof length !== \"number\" ||\n !Number.isSafeInteger(length) ||\n length < 0 ||\n keys.length !== length + 1\n )\n return undefined;\n if (!keys.includes(\"length\")) return undefined;\n return length;\n}\n\nfunction canonicalArrayElements(\n value: readonly unknown[],\n length: number,\n ancestors: Set<object>\n): readonly CanonicalJsonValue[] | undefined {\n const values: CanonicalJsonValue[] = [];\n for (let index = 0; index < length; index += 1) {\n const key = String(index);\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (!isEnumerableDataDescriptor(descriptor)) return undefined;\n const item = canonicalize(descriptor.value, ancestors);\n if (item === undefined) return undefined;\n values.push(item);\n }\n return Object.freeze(values);\n}\n\nfunction canonicalizeObject(\n value: object,\n ancestors: Set<object>\n): CanonicalJsonObject | undefined {\n const prototype: unknown = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) return undefined;\n const keys: string[] = [];\n for (const key of Reflect.ownKeys(value)) {\n if (typeof key !== \"string\") return undefined;\n keys.push(key);\n }\n\n const snapshot: Record<string, CanonicalJsonValue> = {};\n Object.setPrototypeOf(snapshot, null);\n for (const key of keys.sort(compareText)) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (!isEnumerableDataDescriptor(descriptor)) return undefined;\n const item = canonicalize(descriptor.value, ancestors);\n if (item === undefined) return undefined;\n Object.defineProperty(snapshot, key, {\n configurable: false,\n enumerable: true,\n value: item,\n writable: false\n });\n }\n return Object.freeze(snapshot);\n}\n\ntype DataDescriptor = Omit<PropertyDescriptor, \"get\" | \"set\" | \"value\"> &\n Readonly<{\n get?: undefined;\n set?: undefined;\n value: unknown;\n }>;\n\nfunction isDataDescriptor(\n descriptor: PropertyDescriptor | undefined\n): descriptor is DataDescriptor {\n return (\n descriptor !== undefined &&\n descriptor.get === undefined &&\n descriptor.set === undefined &&\n Object.hasOwn(descriptor, \"value\")\n );\n}\n\nfunction isEnumerableDataDescriptor(\n descriptor: PropertyDescriptor | undefined\n): descriptor is DataDescriptor {\n return isDataDescriptor(descriptor) && descriptor.enumerable === true;\n}\n\nfunction isCanonicalJsonObject(value: CanonicalJsonValue): value is CanonicalJsonObject {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction canonicalText(value: CanonicalJsonValue): string {\n if (value === null || typeof value !== \"object\") return JSON.stringify(value);\n if (isCanonicalJsonArray(value)) {\n return `[${value.map((entry) => canonicalText(entry)).join(\",\")}]`;\n }\n return `{${Object.keys(value)\n .sort(compareText)\n .map((key) => `${JSON.stringify(key)}:${canonicalText(value[key])}`)\n .join(\",\")}}`;\n}\n\nfunction isCanonicalJsonArray(value: CanonicalJsonValue): value is readonly CanonicalJsonValue[] {\n return Array.isArray(value);\n}\n\nfunction compareText(left: string, right: string): number {\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n"]}
1
+ {"version":3,"file":"canonical-data.mjs","sourceRoot":"","sources":["../../../src/data-boundary/canonical-data.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CanonicalJsonObject, CanonicalJsonValue } from \"./canonical-json.ts\";\n\nexport type {\n CanonicalJsonObject,\n CanonicalJsonPrimitive,\n CanonicalJsonValue\n} from \"./canonical-json.ts\";\n\nconst encoder = new TextEncoder();\n\n/**\n * 将输入规范化为独立且递归冻结的 canonical JSON 对象副本。\n *\n * 递归内容只接受普通对象或 null-prototype 对象、标准无空洞数组和有限 JSON 基本值;仅当顶层结果是\n * 非数组对象时返回该副本。输出对象使用 null prototype,输出对象和数组均独立于输入且递归冻结。不调用\n * getter 或 `toJSON`;无效输入、循环引用或反射失败返回 `undefined`。反射 Proxy 时仍可能执行其 trap,\n * 不隔离 trap 的副作用。\n */\nexport function canonicalizeJsonObject(value: unknown): CanonicalJsonObject | undefined {\n const canonical = canonicalize(value, new Set<object>());\n return canonical !== undefined && isCanonicalJsonObject(canonical) ? canonical : undefined;\n}\n\n/**\n * 将输入规范化为独立且递归冻结的 canonical JSON 值副本。\n *\n * 接受 `null`、boolean、string、有限 number、普通对象或 null-prototype 对象,以及标准无空洞数组;\n * `-0` 转换为 `0`,输出对象使用 null prototype。拒绝存取器、稀疏数组、不可枚举的自有属性、非有限\n * number 和其它 prototype。不调用 getter 或 `toJSON`;无效输入、循环引用或反射失败返回 `undefined`。\n * 反射 Proxy 时仍可能执行其 trap,不隔离 trap 的副作用。`CanonicalJsonPrimitive` 的 `number` 在\n * TypeScript 中仍可表示 `NaN`,有限性只能由本函数在运行时检查。\n */\nexport function canonicalizeJsonValue(value: unknown): CanonicalJsonValue | undefined {\n return canonicalize(value, new Set<object>());\n}\n\n/**\n * 规范化输入后生成确定性的无额外空白 JSON 文本。\n *\n * 对象键按固定的 lexical `<` 顺序输出,不承诺遵循外部 canonical-JSON 标准。即使同一对象已经过\n * 规范化,`JSON.stringify` 仍按 ECMAScript 的整数索引键顺序输出,不能替代本函数。输入规则与 Proxy\n * 边界同 `canonicalizeJsonValue`;无效输入或无法反射的 Proxy 均抛出 `TypeError`。\n */\nexport function canonicalJsonText(value: unknown): string {\n const canonical = canonicalizeJsonValue(value);\n if (canonical === undefined) {\n throw new TypeError(\"Canonical JSON could not safely materialize the input\");\n }\n return canonicalText(canonical);\n}\n\n/**\n * 规范化输入后生成与 `canonicalJsonText` 相同的确定性 UTF-8 JSON 字节。\n *\n * 函数自行完成规范化与固定键排序,不要求调用方先取得 canonical JSON 值。输入规则、Proxy 边界和\n * `TypeError` 失败方式与 `canonicalJsonText` 相同。\n */\nexport function canonicalJsonBytes(value: unknown): Uint8Array {\n return encoder.encode(canonicalJsonText(value));\n}\n\nfunction canonicalize(value: unknown, ancestors: Set<object>): CanonicalJsonValue | undefined {\n if (value === null) return null;\n const primitive = canonicalPrimitive(value);\n if (primitive !== undefined) return primitive;\n if (typeof value !== \"object\") return undefined;\n if (!admitCanonicalObject(value, ancestors)) return undefined;\n\n try {\n return Array.isArray(value)\n ? canonicalizeArray(value, ancestors)\n : canonicalizeObject(value, ancestors);\n } catch {\n return undefined;\n } finally {\n ancestors.delete(value);\n }\n}\n\nfunction canonicalPrimitive(value: unknown): CanonicalJsonValue | undefined {\n if (typeof value === \"boolean\" || typeof value === \"string\") return value;\n if (typeof value !== \"number\" || !Number.isFinite(value)) return undefined;\n return Object.is(value, -0) ? 0 : value;\n}\n\nfunction admitCanonicalObject(value: object, ancestors: Set<object>): boolean {\n if (ancestors.has(value)) return false;\n ancestors.add(value);\n return true;\n}\n\nfunction canonicalizeArray(\n value: readonly unknown[],\n ancestors: Set<object>\n): readonly CanonicalJsonValue[] | undefined {\n const length = denseCanonicalArrayLength(value);\n if (length === undefined) return undefined;\n return canonicalArrayElements(value, length, ancestors);\n}\n\nfunction denseCanonicalArrayLength(value: readonly unknown[]): number | undefined {\n if (Object.getPrototypeOf(value) !== Array.prototype) return undefined;\n const keys = Reflect.ownKeys(value);\n const lengthDescriptor = Object.getOwnPropertyDescriptor(value, \"length\");\n if (!isDataDescriptor(lengthDescriptor) || lengthDescriptor.enumerable === true) return undefined;\n const length = lengthDescriptor.value;\n if (\n typeof length !== \"number\" ||\n !Number.isSafeInteger(length) ||\n length < 0 ||\n keys.length !== length + 1\n )\n return undefined;\n if (!keys.includes(\"length\")) return undefined;\n return length;\n}\n\nfunction canonicalArrayElements(\n value: readonly unknown[],\n length: number,\n ancestors: Set<object>\n): readonly CanonicalJsonValue[] | undefined {\n const values: CanonicalJsonValue[] = [];\n for (let index = 0; index < length; index += 1) {\n const key = String(index);\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (!isEnumerableDataDescriptor(descriptor)) return undefined;\n const item = canonicalize(descriptor.value, ancestors);\n if (item === undefined) return undefined;\n values.push(item);\n }\n return Object.freeze(values);\n}\n\nfunction canonicalizeObject(\n value: object,\n ancestors: Set<object>\n): CanonicalJsonObject | undefined {\n const prototype: unknown = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) return undefined;\n const keys: string[] = [];\n for (const key of Reflect.ownKeys(value)) {\n if (typeof key !== \"string\") return undefined;\n keys.push(key);\n }\n\n const snapshot: Record<string, CanonicalJsonValue> = {};\n Object.setPrototypeOf(snapshot, null);\n for (const key of keys.sort(compareText)) {\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (!isEnumerableDataDescriptor(descriptor)) return undefined;\n const item = canonicalize(descriptor.value, ancestors);\n if (item === undefined) return undefined;\n Object.defineProperty(snapshot, key, {\n configurable: false,\n enumerable: true,\n value: item,\n writable: false\n });\n }\n return Object.freeze(snapshot);\n}\n\ntype DataDescriptor = Omit<PropertyDescriptor, \"get\" | \"set\" | \"value\"> &\n Readonly<{\n value: unknown;\n }>;\n\nfunction isDataDescriptor(\n descriptor: PropertyDescriptor | undefined\n): descriptor is DataDescriptor {\n return (\n descriptor !== undefined &&\n descriptor.get === undefined &&\n descriptor.set === undefined &&\n Object.hasOwn(descriptor, \"value\")\n );\n}\n\nfunction isEnumerableDataDescriptor(\n descriptor: PropertyDescriptor | undefined\n): descriptor is DataDescriptor {\n return isDataDescriptor(descriptor) && descriptor.enumerable === true;\n}\n\nfunction isCanonicalJsonObject(value: CanonicalJsonValue): value is CanonicalJsonObject {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction canonicalText(value: CanonicalJsonValue): string {\n if (value === null || typeof value !== \"object\") return JSON.stringify(value);\n if (isCanonicalJsonArray(value)) {\n return `[${value.map((entry) => canonicalText(entry)).join(\",\")}]`;\n }\n return `{${Object.keys(value)\n .sort(compareText)\n .map((key) => {\n const entry = value[key];\n if (entry === undefined) {\n throw new TypeError(`Canonical JSON object is missing declared key: ${key}`);\n }\n return `${JSON.stringify(key)}:${canonicalText(entry)}`;\n })\n .join(\",\")}}`;\n}\n\nfunction isCanonicalJsonArray(value: CanonicalJsonValue): value is readonly CanonicalJsonValue[] {\n return Array.isArray(value);\n}\n\nfunction compareText(left: string, right: string): number {\n if (left < right) return -1;\n if (left > right) return 1;\n return 0;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"canonical-json.mjs","sourceRoot":"","sources":["../../../src/data-boundary/canonical-json.ts"],"names":[],"mappings":"","sourcesContent":["/** Package-private static shape for Product's detached canonical JSON facts. */\nexport type CanonicalJsonPrimitive = boolean | null | number | string;\n\nexport type CanonicalJsonValue =\n | CanonicalJsonPrimitive\n | readonly CanonicalJsonValue[]\n | CanonicalJsonObject;\n\nexport interface CanonicalJsonObject {\n readonly [key: string]: CanonicalJsonValue;\n}\n"]}
1
+ {"version":3,"file":"canonical-json.mjs","sourceRoot":"","sources":["../../../src/data-boundary/canonical-json.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Canonical JSON 基本值的静态结构类型。\n *\n * TypeScript 的 `number` 无法在静态层区分有限值与 `NaN` / `Infinity`;因此此类型不能证明值已经由\n * canonical API 规范化。运行时只接受有限 number,并将 `-0` 转换为 `0`。\n */\nexport type CanonicalJsonPrimitive = boolean | null | number | string;\n\n/**\n * Canonical JSON 值的递归只读静态结构类型。\n *\n * 它描述基本值、数组和对象能够如何组合,便于声明参数和结果;不证明值已经通过 canonical API 的\n * 运行时规范化、递归冻结或循环检查。\n */\nexport type CanonicalJsonValue =\n | CanonicalJsonPrimitive\n | readonly CanonicalJsonValue[]\n | CanonicalJsonObject;\n\n/**\n * Canonical JSON 对象的只读静态结构类型。\n *\n * 该类型不证明值来自 canonical API。API 实际返回的对象使用 null prototype,没有继承的对象方法;\n * 检查属性时使用 `Object.hasOwn`,不要调用 `value.hasOwnProperty`。\n */\nexport interface CanonicalJsonObject {\n readonly [key: string]: CanonicalJsonValue;\n}\n"]}