devcontour-harness 0.0.0-stage → 0.1.0-alpha.6

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 (390) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +183 -2
  3. package/docs/architecture.md +473 -0
  4. package/docs/compatibility-versions.md +56 -0
  5. package/docs/compatibility.md +192 -0
  6. package/docs/connectors.md +323 -0
  7. package/docs/contracts.md +603 -0
  8. package/docs/integrations/hindsight.md +148 -0
  9. package/docs/quickstart.md +182 -0
  10. package/docs/release-notes/0.1.0-alpha.6.md +238 -0
  11. package/docs/review-probes.md +120 -0
  12. package/docs/review-protocol.md +251 -0
  13. package/docs/toolchains.md +167 -0
  14. package/docs/turbo-starter.md +269 -0
  15. package/docs/upgrade.md +202 -0
  16. package/examples/README.md +27 -0
  17. package/examples/external-connector/README.md +19 -0
  18. package/examples/external-connector/connector.mjs +55 -0
  19. package/examples/files-only/README.md +28 -0
  20. package/examples/files-only/context/norms/rules.md +4 -0
  21. package/examples/files-only/graph.json +23 -0
  22. package/examples/files-only/policy.json +30 -0
  23. package/examples/one-vendor/README.md +19 -0
  24. package/examples/one-vendor/policy.json +27 -0
  25. package/examples/single-task/README.md +18 -0
  26. package/examples/single-task/graph.json +27 -0
  27. package/examples/single-task/policy-same-vendor.json +55 -0
  28. package/examples/single-task/policy.json +52 -0
  29. package/examples/single-task/src/.gitkeep +0 -0
  30. package/examples/single-task/test/run.js +19 -0
  31. package/examples/toolchains/README.md +32 -0
  32. package/examples/toolchains/go/bad/label/label.go +9 -0
  33. package/examples/toolchains/go/good/label/label.go +9 -0
  34. package/examples/toolchains/go/policy.json +79 -0
  35. package/examples/toolchains/go/repo/REQUIREMENTS.md +9 -0
  36. package/examples/toolchains/go/repo/_gitignore +1 -0
  37. package/examples/toolchains/go/repo/go.mod +5 -0
  38. package/examples/toolchains/go/repo/go.sum +2 -0
  39. package/examples/toolchains/go/repo/label/label.go +9 -0
  40. package/examples/toolchains/go/repo/label/label_test.go +27 -0
  41. package/examples/toolchains/go/repo/label/version.go +9 -0
  42. package/examples/toolchains/go/task.json +25 -0
  43. package/examples/toolchains/mixed-go/bad/backend/label/label.go +9 -0
  44. package/examples/toolchains/mixed-go/bad/frontend/src/label.js +4 -0
  45. package/examples/toolchains/mixed-go/good/backend/label/label.go +9 -0
  46. package/examples/toolchains/mixed-go/good/frontend/src/label.js +4 -0
  47. package/examples/toolchains/mixed-go/policy.json +126 -0
  48. package/examples/toolchains/mixed-go/repo/REQUIREMENTS.md +9 -0
  49. package/examples/toolchains/mixed-go/repo/_gitignore +6 -0
  50. package/examples/toolchains/mixed-go/repo/backend/go.mod +3 -0
  51. package/examples/toolchains/mixed-go/repo/backend/label/label.go +9 -0
  52. package/examples/toolchains/mixed-go/repo/backend/label/label_test.go +30 -0
  53. package/examples/toolchains/mixed-go/repo/contract/check.mjs +17 -0
  54. package/examples/toolchains/mixed-go/repo/contract/label.json +9 -0
  55. package/examples/toolchains/mixed-go/repo/frontend/package.json +15 -0
  56. package/examples/toolchains/mixed-go/repo/frontend/pnpm-lock.yaml +22 -0
  57. package/examples/toolchains/mixed-go/repo/frontend/src/label.js +4 -0
  58. package/examples/toolchains/mixed-go/repo/frontend/test/label.test.js +11 -0
  59. package/examples/toolchains/mixed-go/task.json +25 -0
  60. package/examples/toolchains/mixed-python/bad/backend/src/fx_backend/__init__.py +6 -0
  61. package/examples/toolchains/mixed-python/bad/frontend/src/label.js +4 -0
  62. package/examples/toolchains/mixed-python/good/backend/src/fx_backend/__init__.py +6 -0
  63. package/examples/toolchains/mixed-python/good/frontend/src/label.js +4 -0
  64. package/examples/toolchains/mixed-python/policy.json +121 -0
  65. package/examples/toolchains/mixed-python/repo/REQUIREMENTS.md +9 -0
  66. package/examples/toolchains/mixed-python/repo/_gitignore +6 -0
  67. package/examples/toolchains/mixed-python/repo/backend/.python-version +1 -0
  68. package/examples/toolchains/mixed-python/repo/backend/pyproject.toml +19 -0
  69. package/examples/toolchains/mixed-python/repo/backend/src/fx_backend/__init__.py +6 -0
  70. package/examples/toolchains/mixed-python/repo/backend/tests/test_label.py +11 -0
  71. package/examples/toolchains/mixed-python/repo/backend/uv.lock +108 -0
  72. package/examples/toolchains/mixed-python/repo/contract/check.mjs +17 -0
  73. package/examples/toolchains/mixed-python/repo/contract/label.json +9 -0
  74. package/examples/toolchains/mixed-python/repo/frontend/package.json +15 -0
  75. package/examples/toolchains/mixed-python/repo/frontend/pnpm-lock.yaml +22 -0
  76. package/examples/toolchains/mixed-python/repo/frontend/src/label.js +4 -0
  77. package/examples/toolchains/mixed-python/repo/frontend/test/label.test.js +11 -0
  78. package/examples/toolchains/mixed-python/task.json +25 -0
  79. package/examples/toolchains/npm/bad/src/label.js +4 -0
  80. package/examples/toolchains/npm/good/src/label.js +4 -0
  81. package/examples/toolchains/npm/policy.json +82 -0
  82. package/examples/toolchains/npm/repo/REQUIREMENTS.md +9 -0
  83. package/examples/toolchains/npm/repo/_gitignore +4 -0
  84. package/examples/toolchains/npm/repo/package-lock.json +22 -0
  85. package/examples/toolchains/npm/repo/package.json +13 -0
  86. package/examples/toolchains/npm/repo/src/label.js +4 -0
  87. package/examples/toolchains/npm/repo/test/label.test.js +13 -0
  88. package/examples/toolchains/npm/task.json +25 -0
  89. package/examples/toolchains/pnpm/bad/packages/label/src/label.js +4 -0
  90. package/examples/toolchains/pnpm/good/packages/label/src/label.js +4 -0
  91. package/examples/toolchains/pnpm/policy.json +85 -0
  92. package/examples/toolchains/pnpm/repo/REQUIREMENTS.md +9 -0
  93. package/examples/toolchains/pnpm/repo/_gitignore +4 -0
  94. package/examples/toolchains/pnpm/repo/package.json +10 -0
  95. package/examples/toolchains/pnpm/repo/packages/checker/check.mjs +5 -0
  96. package/examples/toolchains/pnpm/repo/packages/checker/package.json +9 -0
  97. package/examples/toolchains/pnpm/repo/packages/label/package.json +14 -0
  98. package/examples/toolchains/pnpm/repo/packages/label/src/label.js +4 -0
  99. package/examples/toolchains/pnpm/repo/packages/label/test/label.test.js +13 -0
  100. package/examples/toolchains/pnpm/repo/pnpm-lock.yaml +29 -0
  101. package/examples/toolchains/pnpm/repo/pnpm-workspace.yaml +2 -0
  102. package/examples/toolchains/pnpm/task.json +25 -0
  103. package/examples/toolchains/python/bad/src/fx_label/__init__.py +6 -0
  104. package/examples/toolchains/python/good/src/fx_label/__init__.py +6 -0
  105. package/examples/toolchains/python/policy.json +80 -0
  106. package/examples/toolchains/python/repo/.python-version +1 -0
  107. package/examples/toolchains/python/repo/REQUIREMENTS.md +9 -0
  108. package/examples/toolchains/python/repo/_gitignore +5 -0
  109. package/examples/toolchains/python/repo/pyproject.toml +19 -0
  110. package/examples/toolchains/python/repo/src/fx_label/__init__.py +6 -0
  111. package/examples/toolchains/python/repo/tests/test_label.py +13 -0
  112. package/examples/toolchains/python/repo/uv.lock +108 -0
  113. package/examples/toolchains/python/task.json +25 -0
  114. package/examples/toolchains/turbo/bad/packages/label/src/label.js +4 -0
  115. package/examples/toolchains/turbo/good/packages/label/src/label.js +4 -0
  116. package/examples/toolchains/turbo/policy.json +110 -0
  117. package/examples/toolchains/turbo/repo/REQUIREMENTS.md +9 -0
  118. package/examples/toolchains/turbo/repo/_gitignore +4 -0
  119. package/examples/toolchains/turbo/repo/package.json +13 -0
  120. package/examples/toolchains/turbo/repo/packages/checker/check.mjs +5 -0
  121. package/examples/toolchains/turbo/repo/packages/checker/package.json +9 -0
  122. package/examples/toolchains/turbo/repo/packages/label/package.json +14 -0
  123. package/examples/toolchains/turbo/repo/packages/label/src/label.js +4 -0
  124. package/examples/toolchains/turbo/repo/packages/label/test/label.test.js +13 -0
  125. package/examples/toolchains/turbo/repo/pnpm-lock.yaml +94 -0
  126. package/examples/toolchains/turbo/repo/pnpm-workspace.yaml +2 -0
  127. package/examples/toolchains/turbo/repo/turbo.json +7 -0
  128. package/examples/toolchains/turbo/task.json +25 -0
  129. package/examples/turbo-starter/README.md +16 -0
  130. package/examples/turbo-starter/changes/issued-at-consumer-only.patch +12 -0
  131. package/examples/turbo-starter/changes/issued-at.patch +130 -0
  132. package/examples/turbo-starter/cleanup.mjs +58 -0
  133. package/examples/turbo-starter/graph.json +32 -0
  134. package/examples/turbo-starter/harness/acceptance/db-isolation.test.mjs +97 -0
  135. package/examples/turbo-starter/harness/acceptance/env-probe.test.mjs +75 -0
  136. package/examples/turbo-starter/harness/acceptance/generation.test.mjs +54 -0
  137. package/examples/turbo-starter/harness/acceptance/issued-at.test.mjs +43 -0
  138. package/examples/turbo-starter/harness/acceptance/lifecycle-probe.test.mjs +47 -0
  139. package/examples/turbo-starter/harness/compose-bridge.mjs +593 -0
  140. package/examples/turbo-starter/harness/compose.acceptance.yml +23 -0
  141. package/examples/turbo-starter/harness/env/backend.env.template +7 -0
  142. package/examples/turbo-starter/harness/env/compose.env.template +6 -0
  143. package/examples/turbo-starter/policy.json +109 -0
  144. package/examples/turbo-starter/policy.lifecycle.json +114 -0
  145. package/examples/turbo-starter/setup.mjs +352 -0
  146. package/examples/two-vendors/policy.json +30 -0
  147. package/lib/agents/cli-adapter.d.ts +48 -0
  148. package/lib/agents/cli-adapter.js +386 -0
  149. package/lib/agents/inspect.d.ts +6 -0
  150. package/lib/agents/inspect.js +46 -0
  151. package/lib/agents/probe-server.d.ts +2 -0
  152. package/lib/agents/probe-server.js +13 -0
  153. package/lib/agents/review-probe.d.ts +295 -0
  154. package/lib/agents/review-probe.js +872 -0
  155. package/lib/agents/runtime-events.d.ts +11 -0
  156. package/lib/agents/runtime-events.js +21 -0
  157. package/lib/agents/schemas.d.ts +217 -0
  158. package/lib/agents/schemas.js +124 -0
  159. package/lib/agents/usage.d.ts +8 -0
  160. package/lib/agents/usage.js +83 -0
  161. package/lib/cli.d.ts +2 -0
  162. package/lib/cli.js +491 -0
  163. package/lib/connectors/files.d.ts +108 -0
  164. package/lib/connectors/files.js +133 -0
  165. package/lib/contracts/checks.d.ts +307 -0
  166. package/lib/contracts/checks.js +181 -0
  167. package/lib/contracts/cli.d.ts +3895 -0
  168. package/lib/contracts/cli.js +664 -0
  169. package/lib/contracts/context.d.ts +135 -0
  170. package/lib/contracts/context.js +129 -0
  171. package/lib/contracts/digest.d.ts +9 -0
  172. package/lib/contracts/digest.js +22 -0
  173. package/lib/contracts/errors.d.ts +81 -0
  174. package/lib/contracts/errors.js +70 -0
  175. package/lib/contracts/events.d.ts +827 -0
  176. package/lib/contracts/events.js +258 -0
  177. package/lib/contracts/execution.d.ts +3216 -0
  178. package/lib/contracts/execution.js +872 -0
  179. package/lib/contracts/failure.d.ts +67 -0
  180. package/lib/contracts/failure.js +127 -0
  181. package/lib/contracts/index.d.ts +18 -0
  182. package/lib/contracts/index.js +18 -0
  183. package/lib/contracts/policy.d.ts +1080 -0
  184. package/lib/contracts/policy.js +544 -0
  185. package/lib/contracts/ports.d.ts +417 -0
  186. package/lib/contracts/ports.js +1 -0
  187. package/lib/contracts/primitives.d.ts +63 -0
  188. package/lib/contracts/primitives.js +73 -0
  189. package/lib/contracts/profiles.d.ts +336 -0
  190. package/lib/contracts/profiles.js +109 -0
  191. package/lib/contracts/published.d.ts +3237 -0
  192. package/lib/contracts/published.js +34 -0
  193. package/lib/contracts/result.d.ts +1280 -0
  194. package/lib/contracts/result.js +311 -0
  195. package/lib/contracts/review.d.ts +441 -0
  196. package/lib/contracts/review.js +477 -0
  197. package/lib/contracts/toolchain.d.ts +96 -0
  198. package/lib/contracts/toolchain.js +89 -0
  199. package/lib/contracts/version.d.ts +17 -0
  200. package/lib/contracts/version.js +17 -0
  201. package/lib/contracts/work.d.ts +173 -0
  202. package/lib/contracts/work.js +178 -0
  203. package/lib/control/base-move.d.ts +44 -0
  204. package/lib/control/base-move.js +90 -0
  205. package/lib/control/doctor.d.ts +50 -0
  206. package/lib/control/doctor.js +113 -0
  207. package/lib/control/harness.d.ts +1125 -0
  208. package/lib/control/harness.js +741 -0
  209. package/lib/control/provenance.d.ts +17 -0
  210. package/lib/control/provenance.js +25 -0
  211. package/lib/control/recovery.d.ts +237 -0
  212. package/lib/control/recovery.js +236 -0
  213. package/lib/control/review.d.ts +62 -0
  214. package/lib/control/review.js +178 -0
  215. package/lib/control/workflow.d.ts +247 -0
  216. package/lib/control/workflow.js +259 -0
  217. package/lib/engine/budget.d.ts +345 -0
  218. package/lib/engine/budget.js +278 -0
  219. package/lib/engine/classify.d.ts +8 -0
  220. package/lib/engine/classify.js +32 -0
  221. package/lib/engine/engine.d.ts +1527 -0
  222. package/lib/engine/engine.js +2259 -0
  223. package/lib/engine/failure.d.ts +1 -0
  224. package/lib/engine/failure.js +3 -0
  225. package/lib/engine/joint-runner.d.ts +257 -0
  226. package/lib/engine/joint-runner.js +254 -0
  227. package/lib/engine/measured.d.ts +15 -0
  228. package/lib/engine/measured.js +82 -0
  229. package/lib/engine/prompt.d.ts +66 -0
  230. package/lib/engine/prompt.js +131 -0
  231. package/lib/engine/property-recovery.d.ts +50 -0
  232. package/lib/engine/property-recovery.js +171 -0
  233. package/lib/engine/repair.d.ts +33 -0
  234. package/lib/engine/repair.js +82 -0
  235. package/lib/engine/result.d.ts +9 -0
  236. package/lib/engine/result.js +218 -0
  237. package/lib/engine/reuse.d.ts +80 -0
  238. package/lib/engine/reuse.js +102 -0
  239. package/lib/engine/runner.d.ts +360 -0
  240. package/lib/engine/runner.js +1836 -0
  241. package/lib/engine/standalone.d.ts +6 -0
  242. package/lib/engine/standalone.js +48 -0
  243. package/lib/engine/usage.d.ts +87 -0
  244. package/lib/engine/usage.js +165 -0
  245. package/lib/environment/isolation.d.ts +110 -0
  246. package/lib/environment/isolation.js +238 -0
  247. package/lib/environment/lifecycle.d.ts +40 -0
  248. package/lib/environment/lifecycle.js +197 -0
  249. package/lib/environment/live-calls.d.ts +14 -0
  250. package/lib/environment/live-calls.js +73 -0
  251. package/lib/environment/os-tools.d.ts +16 -0
  252. package/lib/environment/os-tools.js +35 -0
  253. package/lib/environment/process.d.ts +32 -0
  254. package/lib/environment/process.js +369 -0
  255. package/lib/environment/redaction.d.ts +22 -0
  256. package/lib/environment/redaction.js +102 -0
  257. package/lib/environment/resources.d.ts +31 -0
  258. package/lib/environment/resources.js +120 -0
  259. package/lib/index.d.ts +65 -0
  260. package/lib/index.js +67 -0
  261. package/lib/integrations/connector/commands.d.ts +358 -0
  262. package/lib/integrations/connector/commands.js +428 -0
  263. package/lib/integrations/connector/config.d.ts +215 -0
  264. package/lib/integrations/connector/config.js +214 -0
  265. package/lib/integrations/connector/delivery.d.ts +107 -0
  266. package/lib/integrations/connector/delivery.js +591 -0
  267. package/lib/integrations/connector/fake.d.ts +291 -0
  268. package/lib/integrations/connector/fake.js +786 -0
  269. package/lib/integrations/connector/history.d.ts +124 -0
  270. package/lib/integrations/connector/history.js +497 -0
  271. package/lib/integrations/connector/index.d.ts +16 -0
  272. package/lib/integrations/connector/index.js +16 -0
  273. package/lib/integrations/connector/redact.d.ts +19 -0
  274. package/lib/integrations/connector/redact.js +91 -0
  275. package/lib/integrations/connector/registry.d.ts +15 -0
  276. package/lib/integrations/connector/registry.js +43 -0
  277. package/lib/integrations/connector/snapshot.d.ts +131 -0
  278. package/lib/integrations/connector/snapshot.js +422 -0
  279. package/lib/integrations/connector/source.d.ts +37 -0
  280. package/lib/integrations/connector/source.js +73 -0
  281. package/lib/integrations/connector/steps.d.ts +71 -0
  282. package/lib/integrations/connector/steps.js +188 -0
  283. package/lib/integrations/connector/store.d.ts +140 -0
  284. package/lib/integrations/connector/store.js +277 -0
  285. package/lib/integrations/connector/summary.d.ts +38 -0
  286. package/lib/integrations/connector/summary.js +59 -0
  287. package/lib/integrations/connector/testing-worker.d.ts +1 -0
  288. package/lib/integrations/connector/testing-worker.js +81 -0
  289. package/lib/integrations/connector/testing.d.ts +205 -0
  290. package/lib/integrations/connector/testing.js +1615 -0
  291. package/lib/integrations/connector/transport.d.ts +240 -0
  292. package/lib/integrations/connector/transport.js +28 -0
  293. package/lib/integrations/memory/context.d.ts +120 -0
  294. package/lib/integrations/memory/context.js +239 -0
  295. package/lib/integrations/memory/index.d.ts +8 -0
  296. package/lib/integrations/memory/index.js +8 -0
  297. package/lib/integrations/memory/provider.d.ts +79 -0
  298. package/lib/integrations/memory/provider.js +22 -0
  299. package/lib/integrations/memory/sink.d.ts +56 -0
  300. package/lib/integrations/memory/sink.js +116 -0
  301. package/lib/integrations/memory/testing.d.ts +44 -0
  302. package/lib/integrations/memory/testing.js +61 -0
  303. package/lib/integrations/relay-v1/index.d.ts +122 -0
  304. package/lib/integrations/relay-v1/index.js +860 -0
  305. package/lib/integrations/relay-v2/index.d.ts +145 -0
  306. package/lib/integrations/relay-v2/index.js +752 -0
  307. package/lib/integrations/relay-v2/process.d.ts +32 -0
  308. package/lib/integrations/relay-v2/process.js +112 -0
  309. package/lib/integrations/relay-v2/protocol.d.ts +172 -0
  310. package/lib/integrations/relay-v2/protocol.js +142 -0
  311. package/lib/package.d.ts +2 -0
  312. package/lib/package.js +3 -0
  313. package/lib/profiles/resolve.d.ts +190 -0
  314. package/lib/profiles/resolve.js +273 -0
  315. package/lib/storage/document.d.ts +1234 -0
  316. package/lib/storage/document.js +80 -0
  317. package/lib/storage/sqlite.d.ts +35 -0
  318. package/lib/storage/sqlite.js +260 -0
  319. package/lib/testing/index.d.ts +5 -0
  320. package/lib/testing/index.js +5 -0
  321. package/lib/testing/store-contract.d.ts +8 -0
  322. package/lib/testing/store-contract.js +167 -0
  323. package/lib/toolchains/index.d.ts +9 -0
  324. package/lib/toolchains/index.js +9 -0
  325. package/lib/toolchains/inspect.d.ts +105 -0
  326. package/lib/toolchains/inspect.js +831 -0
  327. package/lib/toolchains/manifests.d.ts +67 -0
  328. package/lib/toolchains/manifests.js +238 -0
  329. package/lib/toolchains/probe.d.ts +28 -0
  330. package/lib/toolchains/probe.js +54 -0
  331. package/lib/toolchains/recipes.d.ts +33 -0
  332. package/lib/toolchains/recipes.js +51 -0
  333. package/lib/validate.d.ts +36 -0
  334. package/lib/validate.js +175 -0
  335. package/lib/verification/acceptance.d.ts +284 -0
  336. package/lib/verification/acceptance.js +670 -0
  337. package/lib/verification/checks.d.ts +72 -0
  338. package/lib/verification/checks.js +190 -0
  339. package/lib/verification/confirm.d.ts +125 -0
  340. package/lib/verification/confirm.js +411 -0
  341. package/lib/verification/corpus.d.ts +1303 -0
  342. package/lib/verification/corpus.js +744 -0
  343. package/lib/verification/dependencies.d.ts +66 -0
  344. package/lib/verification/dependencies.js +144 -0
  345. package/lib/verification/gates.d.ts +160 -0
  346. package/lib/verification/gates.js +600 -0
  347. package/lib/verification/joint.d.ts +63 -0
  348. package/lib/verification/joint.js +121 -0
  349. package/lib/verification/proof.d.ts +54 -0
  350. package/lib/verification/proof.js +96 -0
  351. package/lib/verification/property.d.ts +86 -0
  352. package/lib/verification/property.js +214 -0
  353. package/lib/verification/requirements.d.ts +25 -0
  354. package/lib/verification/requirements.js +69 -0
  355. package/lib/verification/self-check.d.ts +29 -0
  356. package/lib/verification/self-check.js +99 -0
  357. package/lib/verification/spike.d.ts +79 -0
  358. package/lib/verification/spike.js +124 -0
  359. package/package.json +100 -4
  360. package/profiles/expo-mobile.json +15 -0
  361. package/profiles/go-api.json +15 -0
  362. package/profiles/go-gotestsum.json +21 -0
  363. package/profiles/mobile-maestro.json +29 -0
  364. package/profiles/nest-api.json +26 -0
  365. package/profiles/next-product.json +72 -0
  366. package/profiles/node-checks.json +77 -0
  367. package/profiles/npm-ci.json +22 -0
  368. package/profiles/pnpm-frozen.json +24 -0
  369. package/profiles/python-api.json +32 -0
  370. package/profiles/python-uv.json +26 -0
  371. package/profiles/react-native.json +50 -0
  372. package/profiles/react-vite-admin.json +71 -0
  373. package/schemas/context-snapshot.schema.json +231 -0
  374. package/schemas/contract-document.schema.json +385 -0
  375. package/schemas/execution-document.schema.json +3695 -0
  376. package/schemas/execution-policy.schema.json +2196 -0
  377. package/schemas/joint-verification.schema.json +617 -0
  378. package/schemas/result-envelope.schema.json +1652 -0
  379. package/schemas/review-record.schema.json +177 -0
  380. package/schemas/run-event.schema.json +2458 -0
  381. package/schemas/run-result.schema.json +1570 -0
  382. package/schemas/stack-profile.schema.json +535 -0
  383. package/schemas/work-graph.schema.json +381 -0
  384. package/schemas/work-order.schema.json +256 -0
  385. package/skills/harness/SKILL.md +64 -0
  386. package/templates/AGENTS.md +13 -0
  387. package/templates/controller-mode/AGENTS.controller.md +58 -0
  388. package/templates/controller-mode/README.md +44 -0
  389. package/templates/graph.json +22 -0
  390. package/templates/policy.json +28 -0
@@ -0,0 +1,67 @@
1
+ /** Lockfile → менеджер пакетов, которому он принадлежит. */
2
+ export declare const lockfiles: {
3
+ readonly 'package-lock.json': "npm";
4
+ readonly 'npm-shrinkwrap.json': "npm";
5
+ readonly 'pnpm-lock.yaml': "pnpm";
6
+ readonly 'yarn.lock': "yarn";
7
+ readonly 'bun.lock': "bun";
8
+ readonly 'bun.lockb': "bun";
9
+ };
10
+ export type LockManager = (typeof lockfiles)[keyof typeof lockfiles];
11
+ export declare class Manifests {
12
+ readonly root: string;
13
+ private cache;
14
+ constructor(root: string);
15
+ /** Путь `rel` относительно корня; `.` — корень. */
16
+ abs(rel: string): string;
17
+ /** Относительный путь каталога; вне корня — undefined. */
18
+ rel(abs: string): string | undefined;
19
+ /** Каталог внутри корня без symlink на пути. */
20
+ isDir(rel: string): boolean;
21
+ isFile(rel: string): boolean;
22
+ private stat;
23
+ /** Текст файла внутри корня (до 4 MiB) или undefined. */
24
+ text(rel: string): string | undefined;
25
+ json(rel: string): Record<string, unknown> | undefined;
26
+ /** Каталог и его предки до корня включительно, от ближнего. */
27
+ ancestors(dir: string): string[];
28
+ /** Ближайший к `dir` каталог (до корня), где есть файл `name`. */
29
+ nearest(dir: string, name: string): string | undefined;
30
+ lockfilesIn(dir: string): string[];
31
+ list(rel: string): string[];
32
+ }
33
+ export declare const join2: (dir: string, name: string) => string;
34
+ /** Скрипты package.json каталога. */
35
+ export declare function scriptsOf(m: Manifests, dir: string): Record<string, string> | undefined;
36
+ /** `packageManager` из package.json: `pnpm@10.12.3+sha512…` → { name, version }. */
37
+ export declare function packageManagerField(m: Manifests, dir: string): {
38
+ name: string;
39
+ version: string;
40
+ raw: string;
41
+ } | {
42
+ name: string;
43
+ raw: string;
44
+ version?: undefined;
45
+ } | undefined;
46
+ /** Пакеты workspace pnpm: `packages:` из pnpm-workspace.yaml (простые шаблоны `dir/*`). */
47
+ export declare function workspacePackages(m: Manifests, workspaceRoot: string): {
48
+ dir: string;
49
+ name: string | undefined;
50
+ scripts: Record<string, string>;
51
+ }[];
52
+ /** Задачи turbo.json (`tasks` v2 либо `pipeline` v1). */
53
+ export declare function turboTasks(m: Manifests, dir: string): string[] | undefined;
54
+ /** go.mod: директивы `go`, `toolchain` и наличие require. */
55
+ export declare function goModule(m: Manifests, dir: string): {
56
+ go: string | undefined;
57
+ toolchain: string | undefined;
58
+ requires: boolean;
59
+ } | undefined;
60
+ /** Пакеты, закреплённые uv.lock (`name = "…"` записей `[[package]]`). */
61
+ export declare function uvLocked(m: Manifests, dir: string): Map<string, string> | undefined;
62
+ /**
63
+ * Точная версия зависимости `name` корневого пакета каталога, закреплённая
64
+ * lockfile: `importers['.']` pnpm-lock.yaml либо `packages['node_modules/<name>']`
65
+ * package-lock.json. Нет закрепления — undefined.
66
+ */
67
+ export declare function lockedVersion(m: Manifests, dir: string, name: string): string | undefined;
@@ -0,0 +1,238 @@
1
+ import { lstatSync, readFileSync, readdirSync, realpathSync } from 'node:fs';
2
+ import { dirname, join, relative, resolve, sep } from 'node:path';
3
+ /**
4
+ * Чтение манифестов целевого репозитория — только чтение файлов внутри его
5
+ * корня, без symlink наружу и без исполнения чего-либо. Всё, что здесь
6
+ * разбирается (package.json, pnpm-workspace.yaml, turbo.json, go.mod,
7
+ * pyproject.toml, uv.lock), читается как данные.
8
+ */
9
+ const FILE_LIMIT = 4 * 1024 * 1024;
10
+ /** Lockfile → менеджер пакетов, которому он принадлежит. */
11
+ export const lockfiles = {
12
+ 'package-lock.json': 'npm',
13
+ 'npm-shrinkwrap.json': 'npm',
14
+ 'pnpm-lock.yaml': 'pnpm',
15
+ 'yarn.lock': 'yarn',
16
+ 'bun.lock': 'bun',
17
+ 'bun.lockb': 'bun',
18
+ };
19
+ export class Manifests {
20
+ root;
21
+ cache = new Map();
22
+ constructor(root) {
23
+ this.root = realpathSync(root);
24
+ }
25
+ /** Путь `rel` относительно корня; `.` — корень. */
26
+ abs(rel) {
27
+ return rel === '.' ? this.root : join(this.root, rel);
28
+ }
29
+ /** Относительный путь каталога; вне корня — undefined. */
30
+ rel(abs) {
31
+ const r = relative(this.root, resolve(abs));
32
+ if (r === '')
33
+ return '.';
34
+ if (r === '..' || r.startsWith('..' + sep) || r.startsWith(sep))
35
+ return undefined;
36
+ return r.split(sep).join('/');
37
+ }
38
+ /** Каталог внутри корня без symlink на пути. */
39
+ isDir(rel) {
40
+ const stat = this.stat(rel);
41
+ return stat?.isDirectory() ?? false;
42
+ }
43
+ isFile(rel) {
44
+ const stat = this.stat(rel);
45
+ return stat?.isFile() ?? false;
46
+ }
47
+ stat(rel) {
48
+ if (rel === '.')
49
+ return lstatSync(this.root);
50
+ let cursor = this.root;
51
+ let stat;
52
+ for (const part of rel.split('/')) {
53
+ if (!part || part === '..')
54
+ return undefined;
55
+ if (part === '.')
56
+ continue;
57
+ cursor = join(cursor, part);
58
+ try {
59
+ stat = lstatSync(cursor);
60
+ }
61
+ catch {
62
+ return undefined;
63
+ }
64
+ if (stat.isSymbolicLink())
65
+ return undefined;
66
+ }
67
+ return stat;
68
+ }
69
+ /** Текст файла внутри корня (до 4 MiB) или undefined. */
70
+ text(rel) {
71
+ if (this.cache.has(rel))
72
+ return this.cache.get(rel);
73
+ const stat = this.stat(rel);
74
+ const value = stat?.isFile() && stat.size <= FILE_LIMIT ? readFileSync(this.abs(rel), 'utf8') : undefined;
75
+ this.cache.set(rel, value);
76
+ return value;
77
+ }
78
+ json(rel) {
79
+ const text = this.text(rel);
80
+ if (text === undefined)
81
+ return undefined;
82
+ try {
83
+ const value = JSON.parse(text);
84
+ return value && typeof value === 'object' && !Array.isArray(value)
85
+ ? value
86
+ : undefined;
87
+ }
88
+ catch {
89
+ return undefined;
90
+ }
91
+ }
92
+ /** Каталог и его предки до корня включительно, от ближнего. */
93
+ ancestors(dir) {
94
+ const out = [];
95
+ let cursor = dir;
96
+ for (;;) {
97
+ out.push(cursor);
98
+ if (cursor === '.')
99
+ return out;
100
+ const up = dirname(cursor);
101
+ cursor = up === '' || up === '.' ? '.' : up;
102
+ }
103
+ }
104
+ /** Ближайший к `dir` каталог (до корня), где есть файл `name`. */
105
+ nearest(dir, name) {
106
+ return this.ancestors(dir).find((d) => this.isFile(join2(d, name)));
107
+ }
108
+ lockfilesIn(dir) {
109
+ return Object.keys(lockfiles).filter((f) => this.isFile(join2(dir, f)));
110
+ }
111
+ list(rel) {
112
+ if (!this.isDir(rel))
113
+ return [];
114
+ return readdirSync(this.abs(rel), { withFileTypes: true })
115
+ .filter((e) => e.isDirectory())
116
+ .map((e) => e.name)
117
+ .sort();
118
+ }
119
+ }
120
+ export const join2 = (dir, name) => (dir === '.' ? name : `${dir}/${name}`);
121
+ /** Скрипты package.json каталога. */
122
+ export function scriptsOf(m, dir) {
123
+ const pkg = m.json(join2(dir, 'package.json'));
124
+ if (!pkg)
125
+ return undefined;
126
+ const scripts = pkg.scripts;
127
+ return scripts && typeof scripts === 'object' ? scripts : {};
128
+ }
129
+ /** `packageManager` из package.json: `pnpm@10.12.3+sha512…` → { name, version }. */
130
+ export function packageManagerField(m, dir) {
131
+ const value = m.json(join2(dir, 'package.json'))?.packageManager;
132
+ if (typeof value !== 'string')
133
+ return undefined;
134
+ const match = /^(npm|pnpm|yarn|bun)@(\d+\.\d+\.\d+[^+]*)/.exec(value);
135
+ return match ? { name: match[1], version: match[2], raw: value } : { name: value, raw: value };
136
+ }
137
+ /** Пакеты workspace pnpm: `packages:` из pnpm-workspace.yaml (простые шаблоны `dir/*`). */
138
+ export function workspacePackages(m, workspaceRoot) {
139
+ const text = m.text(join2(workspaceRoot, 'pnpm-workspace.yaml'));
140
+ const patterns = [];
141
+ if (text) {
142
+ let inPackages = false;
143
+ for (const line of text.split('\n')) {
144
+ if (/^packages\s*:/.test(line)) {
145
+ inPackages = true;
146
+ continue;
147
+ }
148
+ if (inPackages) {
149
+ const item = /^\s+-\s*['"]?([^'"#]+?)['"]?\s*(?:#.*)?$/.exec(line);
150
+ if (item)
151
+ patterns.push(item[1].trim());
152
+ else if (/^\S/.test(line))
153
+ inPackages = false;
154
+ }
155
+ }
156
+ }
157
+ else {
158
+ const workspaces = m.json(join2(workspaceRoot, 'package.json'))?.workspaces;
159
+ if (Array.isArray(workspaces))
160
+ patterns.push(...workspaces.filter((w) => typeof w === 'string'));
161
+ }
162
+ const dirs = new Set([workspaceRoot]);
163
+ for (const pattern of patterns) {
164
+ if (pattern.startsWith('!'))
165
+ continue;
166
+ const clean = pattern.replace(/\/$/, '');
167
+ if (clean.endsWith('/*') || clean.endsWith('/**')) {
168
+ const base = join2(workspaceRoot, clean.replace(/\/\*\*?$/, ''));
169
+ for (const child of m.list(base))
170
+ dirs.add(join2(base, child));
171
+ }
172
+ else
173
+ dirs.add(join2(workspaceRoot, clean));
174
+ }
175
+ return [...dirs]
176
+ .filter((d) => m.isFile(join2(d, 'package.json')))
177
+ .map((dir) => {
178
+ const pkg = m.json(join2(dir, 'package.json')) ?? {};
179
+ return {
180
+ dir,
181
+ name: typeof pkg.name === 'string' ? pkg.name : undefined,
182
+ scripts: scriptsOf(m, dir) ?? {},
183
+ };
184
+ });
185
+ }
186
+ /** Задачи turbo.json (`tasks` v2 либо `pipeline` v1). */
187
+ export function turboTasks(m, dir) {
188
+ const turbo = m.json(join2(dir, 'turbo.json'));
189
+ if (!turbo)
190
+ return undefined;
191
+ const tasks = (turbo.tasks ?? turbo.pipeline);
192
+ return tasks && typeof tasks === 'object' ? Object.keys(tasks) : [];
193
+ }
194
+ /** go.mod: директивы `go`, `toolchain` и наличие require. */
195
+ export function goModule(m, dir) {
196
+ const text = m.text(join2(dir, 'go.mod'));
197
+ if (text === undefined)
198
+ return undefined;
199
+ return {
200
+ go: /^go\s+(\d+\.\d+(?:\.\d+)?)\s*$/m.exec(text)?.[1],
201
+ toolchain: /^toolchain\s+go(\d+\.\d+(?:\.\d+)?)\s*$/m.exec(text)?.[1],
202
+ requires: /^require\b/m.test(text),
203
+ };
204
+ }
205
+ /** Пакеты, закреплённые uv.lock (`name = "…"` записей `[[package]]`). */
206
+ export function uvLocked(m, dir) {
207
+ const text = m.text(join2(dir, 'uv.lock'));
208
+ if (text === undefined)
209
+ return undefined;
210
+ const names = new Map();
211
+ for (const block of text.split(/^\[\[package\]\]\s*$/m).slice(1)) {
212
+ const name = /^name\s*=\s*"([^"]+)"/m.exec(block)?.[1];
213
+ const version = /^version\s*=\s*"([^"]+)"/m.exec(block)?.[1];
214
+ if (name)
215
+ names.set(name.toLowerCase(), version ?? '');
216
+ }
217
+ return names;
218
+ }
219
+ /**
220
+ * Точная версия зависимости `name` корневого пакета каталога, закреплённая
221
+ * lockfile: `importers['.']` pnpm-lock.yaml либо `packages['node_modules/<name>']`
222
+ * package-lock.json. Нет закрепления — undefined.
223
+ */
224
+ export function lockedVersion(m, dir, name) {
225
+ const pnpm = m.text(join2(dir, 'pnpm-lock.yaml'));
226
+ if (pnpm !== undefined) {
227
+ const importers = pnpm.split(/^importers:\s*$/m)[1]?.split(/^\S/m)[0] ?? '';
228
+ const root = /^ {2}\.:\s*$([\s\S]*?)(?=^ {2}\S|(?![\s\S]))/m.exec(importers)?.[1] ?? '';
229
+ const quoted = name.replace(/[.*+?^${}()|[\]\\/]/g, '\\$&');
230
+ const entry = new RegExp(`^ {6}'?${quoted}'?:\\s*$\\n {8}specifier:[^\\n]*\\n {8}version: ([^\\s(]+)`, 'm').exec(root);
231
+ if (entry && /^\d+\.\d+\.\d+/.test(entry[1]))
232
+ return entry[1];
233
+ }
234
+ const npm = m.json(join2(dir, 'package-lock.json'));
235
+ const packages = npm?.packages;
236
+ const version = packages?.[`node_modules/${name}`]?.version;
237
+ return version && /^\d+\.\d+\.\d+/.test(version) ? version : undefined;
238
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Проба версии — единственный процесс, который запускает диагностика
3
+ * toolchain: `<tool> --version` (у go — `go version`, у собранного без метки
4
+ * версии Go-бинарника — `go version -m <файл>`, который только читает файл).
5
+ * Каталог пробы — нейтральный временный: менеджер пакетов не должен увидеть
6
+ * `packageManager` проекта и переключиться на другую версию.
7
+ */
8
+ export interface ToolProbe {
9
+ (argv: string[], options: {
10
+ timeoutMs: number;
11
+ env: NodeJS.ProcessEnv;
12
+ }): Promise<{
13
+ code: number;
14
+ stdout: string;
15
+ stderr: string;
16
+ timedOut: boolean;
17
+ }>;
18
+ }
19
+ export declare const PROBE_TIMEOUT_MS = 10000;
20
+ export declare const defaultProbe: ToolProbe;
21
+ /** Исполняемый файл из PATH (как его нашёл бы spawn) или undefined. */
22
+ export declare function resolveExecutable(name: string, path: string | undefined): string | undefined;
23
+ /** Версия из вывода пробы: первое `1.2.3`/`1.2` (в том числе `go1.24.5`, `v24.3.0`). */
24
+ export declare function versionOf(output: string): string | undefined;
25
+ /** Версия модуля в build info Go-бинарника (`go version -m`). */
26
+ export declare function moduleVersionOf(output: string): string | undefined;
27
+ /** Требование версии: `1.12.3` — названные компоненты совпадают, `>=1.24` — не ниже. */
28
+ export declare function satisfies(version: string, required: string): boolean;
@@ -0,0 +1,54 @@
1
+ import { accessSync, constants, statSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { delimiter, isAbsolute, join } from 'node:path';
4
+ import { command } from "../environment/process.js";
5
+ export const PROBE_TIMEOUT_MS = 10000;
6
+ export const defaultProbe = async (argv, options) => {
7
+ const r = await command(argv, tmpdir(), { timeoutMs: options.timeoutMs, env: options.env });
8
+ return { code: r.code, stdout: r.stdout, stderr: r.stderr, timedOut: r.timedOut };
9
+ };
10
+ /** Исполняемый файл из PATH (как его нашёл бы spawn) или undefined. */
11
+ export function resolveExecutable(name, path) {
12
+ if (isAbsolute(name))
13
+ return executable(name) ? name : undefined;
14
+ for (const dir of (path ?? '').split(delimiter).filter(Boolean)) {
15
+ const file = join(dir, name);
16
+ if (executable(file))
17
+ return file;
18
+ }
19
+ return undefined;
20
+ }
21
+ function executable(file) {
22
+ try {
23
+ accessSync(file, constants.X_OK);
24
+ return statSync(file).isFile();
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ }
30
+ /** Версия из вывода пробы: первое `1.2.3`/`1.2` (в том числе `go1.24.5`, `v24.3.0`). */
31
+ export function versionOf(output) {
32
+ return /(?:^|[^\d.])v?(?:go)?(\d+\.\d+(?:\.\d+)?)/.exec(output)?.[1];
33
+ }
34
+ /** Версия модуля в build info Go-бинарника (`go version -m`). */
35
+ export function moduleVersionOf(output) {
36
+ return /^\s*mod\s+\S+\s+v(\d+\.\d+\.\d+)/m.exec(output)?.[1];
37
+ }
38
+ /** Требование версии: `1.12.3` — названные компоненты совпадают, `>=1.24` — не ниже. */
39
+ export function satisfies(version, required) {
40
+ const parse = (v) => v.split('.').map((n) => Number(n));
41
+ if (required.startsWith('>=')) {
42
+ const want = parse(required.slice(2));
43
+ const have = parse(version);
44
+ for (let i = 0; i < want.length; i++) {
45
+ const h = have[i] ?? 0;
46
+ if (h !== want[i])
47
+ return h > want[i];
48
+ }
49
+ return true;
50
+ }
51
+ const want = parse(required);
52
+ const have = parse(version);
53
+ return want.every((n, i) => have[i] === n);
54
+ }
@@ -0,0 +1,33 @@
1
+ import type { z } from 'zod';
2
+ import type { gateSchema, repositoryPolicySchema } from '../contracts/index.ts';
3
+ type Gate = z.input<typeof gateSchema>;
4
+ type RepositoryInput = z.input<typeof repositoryPolicySchema>;
5
+ /**
6
+ * Рецепты установки зависимостей: точные locked-команды менеджера, каталог —
7
+ * собственным флагом инструмента (шаг `prepare` исполняется в корне
8
+ * worktree). Рецепт не меняет lockfile: несовместимый lockfile — отказ шага.
9
+ */
10
+ export declare const installRecipes: {
11
+ readonly npm: (dir: string) => string[];
12
+ readonly pnpm: (dir: string) => string[];
13
+ readonly uv: (dir: string) => string[];
14
+ readonly go: (dir: string) => string[];
15
+ };
16
+ export type InstallRecipe = keyof typeof installRecipes;
17
+ export interface ToolchainComponent {
18
+ /** Каталог компонента в репозитории (`.` — корень); gates исполняются в нём. */
19
+ dir: string;
20
+ install?: InstallRecipe;
21
+ installTimeoutMs?: number;
22
+ /** Gates компонента; `cwd` по умолчанию — каталог компонента. */
23
+ gates: Gate[];
24
+ }
25
+ /**
26
+ * Описание репозитория политики из компонентов: у каждого свой рецепт
27
+ * установки, каталог и gates; один Git root — одна запись репозитория.
28
+ * Никакого «типа проекта»: Node-компонент на pnpm и Go-компонент — просто два
29
+ * компонента с разными рецептами. Для node-компонента выбор менеджера
30
+ * записывается явно (`toolchain.packageManagers`).
31
+ */
32
+ export declare function composeRepository(own: Pick<RepositoryInput, 'id' | 'path' | 'targetRef'> & Partial<RepositoryInput>, components: ToolchainComponent[], tools?: Record<string, string>): RepositoryInput;
33
+ export {};
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Рецепты установки зависимостей: точные locked-команды менеджера, каталог —
3
+ * собственным флагом инструмента (шаг `prepare` исполняется в корне
4
+ * worktree). Рецепт не меняет lockfile: несовместимый lockfile — отказ шага.
5
+ */
6
+ export const installRecipes = {
7
+ npm: (dir) => (dir === '.' ? ['npm', 'ci'] : ['npm', '--prefix', dir, 'ci']),
8
+ pnpm: (dir) => [
9
+ 'pnpm',
10
+ ...(dir === '.' ? [] : ['--dir', dir]),
11
+ 'install',
12
+ '--frozen-lockfile',
13
+ ],
14
+ uv: (dir) => ['uv', 'sync', '--locked', ...(dir === '.' ? [] : ['--directory', dir])],
15
+ go: (dir) => ['go', ...(dir === '.' ? [] : ['-C', dir]), 'mod', 'download'],
16
+ };
17
+ /**
18
+ * Описание репозитория политики из компонентов: у каждого свой рецепт
19
+ * установки, каталог и gates; один Git root — одна запись репозитория.
20
+ * Никакого «типа проекта»: Node-компонент на pnpm и Go-компонент — просто два
21
+ * компонента с разными рецептами. Для node-компонента выбор менеджера
22
+ * записывается явно (`toolchain.packageManagers`).
23
+ */
24
+ export function composeRepository(own, components, tools = {}) {
25
+ const prepare = [];
26
+ const gates = [];
27
+ const packageManagers = {};
28
+ for (const c of components) {
29
+ if (c.install) {
30
+ const id = (c.dir === '.' ? 'root' : c.dir.replace(/[^A-Za-z0-9_-]/g, '-')) + '-install';
31
+ prepare.push({
32
+ id,
33
+ command: [...installRecipes[c.install](c.dir)],
34
+ timeoutMs: c.installTimeoutMs ?? 600000,
35
+ });
36
+ if (c.install === 'npm' || c.install === 'pnpm')
37
+ packageManagers[c.dir] = c.install;
38
+ }
39
+ for (const g of c.gates)
40
+ gates.push({ ...g, ...(g.cwd === undefined && c.dir !== '.' ? { cwd: c.dir } : {}) });
41
+ }
42
+ return {
43
+ ...own,
44
+ prepare: [...(own.prepare ?? []), ...prepare],
45
+ gates: [...(own.gates ?? []), ...gates],
46
+ toolchain: {
47
+ tools: { ...own.toolchain?.tools, ...tools },
48
+ packageManagers: { ...own.toolchain?.packageManagers, ...packageManagers },
49
+ },
50
+ };
51
+ }
@@ -0,0 +1,36 @@
1
+ import { type ErrorIssue, type ExecutionPolicy, type WorkGraph } from './contracts/index.ts';
2
+ type CodedIssue = ErrorIssue & {
3
+ code: string;
4
+ };
5
+ /** Путь внутри одного из префиксов (как `withinPaths` DevContour). */
6
+ export declare const withinPaths: (path: string, prefixes: string[]) => boolean;
7
+ /**
8
+ * Связь поручений с политикой — проверки DevContour `validateTaskContext`,
9
+ * выполнимые без модели и без внешних источников: репозиторий и роль
10
+ * объявлены; ресурсы известны; область записи пересекается с областью роли;
11
+ * область доказательства раскрывается, замкнута по `dependsOn` gates и
12
+ * содержит test gate; требования не повторяются, их текст совпадает с
13
+ * digest, а gate — test gate из области; потребители уникальны, отличны от
14
+ * провайдера, зависят от него и проверяются test gate; поручение уровня
15
+ * workspace затрагивает минимум два известных репозитория.
16
+ *
17
+ * Не проверяется здесь: байты и digests контекста и контрактов — их
18
+ * сверяет движок с `ContextSource` при регистрации графа.
19
+ */
20
+ export declare function crossIssues(graph: WorkGraph, policy: ExecutionPolicy): CodedIssue[];
21
+ /**
22
+ * Проверка входов без вызова моделей и без записи состояния. Ошибки
23
+ * собираются все сразу; код первой определяет класс отказа.
24
+ */
25
+ export declare function validateInputs(input: {
26
+ graph: unknown;
27
+ policy: unknown;
28
+ context?: unknown;
29
+ }): {
30
+ contextDigest?: string | undefined;
31
+ graphId: string;
32
+ graphDigest: string;
33
+ policyDigest: string;
34
+ orders: number;
35
+ };
36
+ export {};