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,175 @@
1
+ import { roleBinding, HarnessError, executionPolicySchema, expandGateRefs, graphIssues, policyDigest, policyIssues, sha256, contextDigest, contextIssues, contextSnapshotSchema, workGraphDigest, workGraphSchema, } from "./contracts/index.js";
2
+ const parse = (schema, value, root) => {
3
+ const parsed = schema.safeParse(value);
4
+ if (parsed.success)
5
+ return parsed.data;
6
+ throw new HarnessError('INVALID_INPUT', `${root}: вход не прошёл проверку схемы`, parsed.error.issues.map((i) => ({
7
+ path: [root, ...i.path],
8
+ message: i.message,
9
+ })));
10
+ };
11
+ /** Путь внутри одного из префиксов (как `withinPaths` DevContour). */
12
+ export const withinPaths = (path, prefixes) => prefixes.some((p) => p === '.' || path === p || path.startsWith(p.endsWith('/') ? p : p + '/'));
13
+ /**
14
+ * Связь поручений с политикой — проверки DevContour `validateTaskContext`,
15
+ * выполнимые без модели и без внешних источников: репозиторий и роль
16
+ * объявлены; ресурсы известны; область записи пересекается с областью роли;
17
+ * область доказательства раскрывается, замкнута по `dependsOn` gates и
18
+ * содержит test gate; требования не повторяются, их текст совпадает с
19
+ * digest, а gate — test gate из области; потребители уникальны, отличны от
20
+ * провайдера, зависят от него и проверяются test gate; поручение уровня
21
+ * workspace затрагивает минимум два известных репозитория.
22
+ *
23
+ * Не проверяется здесь: байты и digests контекста и контрактов — их
24
+ * сверяет движок с `ContextSource` при регистрации графа.
25
+ */
26
+ export function crossIssues(graph, policy) {
27
+ const issues = [];
28
+ const repos = new Map(policy.repositories.map((r) => [r.id, r]));
29
+ const resources = new Set(policy.resources.map((r) => r.id));
30
+ const dependsOn = (consumer, provider) => {
31
+ const seen = new Set();
32
+ const visit = (id) => {
33
+ if (seen.has(id))
34
+ return false;
35
+ seen.add(id);
36
+ return (repos.get(id)?.dependsOn ?? []).some((p) => p === provider || visit(p));
37
+ };
38
+ return visit(consumer);
39
+ };
40
+ graph.prerequisites.forEach((p, i) => {
41
+ if (!repos.has(p.repositoryId))
42
+ issues.push({
43
+ code: 'INVALID_INPUT',
44
+ path: ['graph', 'prerequisites', i, 'repositoryId'],
45
+ message: 'Репозиторий предпосылки не объявлен политикой: ' + p.repositoryId,
46
+ });
47
+ });
48
+ graph.orders.forEach((order, i) => {
49
+ const at = (...p) => ['graph', 'orders', i, ...p];
50
+ const add = (code, path, message) => issues.push({ code, path, message });
51
+ const repo = repos.get(order.repositoryId);
52
+ if (!repo) {
53
+ add('INVALID_INPUT', at('repositoryId'), 'Репозиторий не объявлен политикой: ' + order.repositoryId);
54
+ return;
55
+ }
56
+ const role = roleBinding(policy, order.role, order.repositoryId);
57
+ if (!role)
58
+ add('INVALID_INPUT', at('role'), 'Роль не объявлена политикой: ' + order.role);
59
+ for (const r of order.resources ?? [])
60
+ if (!resources.has(r))
61
+ add('INVALID_INPUT', at('resources'), 'Неизвестный ресурс: ' + r);
62
+ if (role?.writePaths?.length) {
63
+ const reachable = order.writeScope.filter((p) => withinPaths(p, role.writePaths) || role.writePaths.some((r) => withinPaths(r, [p])));
64
+ if (!reachable.length)
65
+ add('INVALID_INPUT', at('writeScope'), `Область записи поручения не пересекается с областью роли ${order.role}: исполнитель не сможет изменить ни одного файла`);
66
+ }
67
+ const expand = (r, refs, path, label) => {
68
+ let gates;
69
+ try {
70
+ gates = expandGateRefs(r, refs);
71
+ }
72
+ catch (error) {
73
+ add(error.code ?? 'GATE_UNKNOWN', path, error.message);
74
+ return undefined;
75
+ }
76
+ for (const id of gates)
77
+ for (const parent of r.gates.find((g) => g.id === id)?.dependsOn ?? [])
78
+ if (!gates.includes(parent))
79
+ add('INVALID_INPUT', path, `Область ${label}: gate ${id} требует ${parent} — добавьте ${parent} явно`);
80
+ if (!gates.some((id) => r.gates.some((g) => g.id === id && g.kind === 'test')))
81
+ add('INVALID_INPUT', path, `Область ${label} должна включать test gate`);
82
+ return gates;
83
+ };
84
+ const own = expand(repo, order.gates, at('gates'), 'поручения');
85
+ const keys = new Set();
86
+ order.requirements.forEach((req, k) => {
87
+ const key = `${req.source}#${req.id}`;
88
+ if (keys.has(key))
89
+ add('INVALID_INPUT', at('requirements', k), 'Повтор требования: ' + key);
90
+ keys.add(key);
91
+ if (sha256(req.text) !== req.digest)
92
+ add('INVALID_INPUT', at('requirements', k, 'digest'), 'Текст требования не соответствует digest');
93
+ if (!repo.gates.some((g) => g.id === req.gate && g.kind === 'test'))
94
+ add('INVALID_INPUT', at('requirements', k, 'gate'), 'Требование должно ссылаться на test gate: ' + req.gate);
95
+ else if (order.gates && own && !own.includes(req.gate))
96
+ add('INVALID_INPUT', at('requirements', k, 'gate'), 'Требование ссылается на проверку вне области поручения: ' + req.gate);
97
+ });
98
+ const consumerIds = (order.consumers ?? []).map((c) => c.repositoryId);
99
+ if (new Set(consumerIds).size !== consumerIds.length)
100
+ add('INVALID_INPUT', at('consumers'), 'Потребитель назван дважды: объедините его проверки в одну запись');
101
+ order.consumers?.forEach((c, k) => {
102
+ const consumer = repos.get(c.repositoryId);
103
+ if (c.repositoryId === order.repositoryId)
104
+ add('INVALID_INPUT', at('consumers', k), 'Потребитель — другой компонент, а не компонент поручения');
105
+ else if (!consumer)
106
+ add('INVALID_INPUT', at('consumers', k), 'Потребитель не объявлен политикой: ' + c.repositoryId);
107
+ else if (!dependsOn(c.repositoryId, order.repositoryId))
108
+ add('INVALID_INPUT', at('consumers', k), `Компонент ${c.repositoryId} не зависит от ${order.repositoryId}: он не потребитель`);
109
+ else
110
+ expand(consumer, c.gates, at('consumers', k, 'gates'), `потребителя ${c.repositoryId}`);
111
+ });
112
+ if (order.relatedRepositories.length && new Set(order.relatedRepositories).size < 2)
113
+ add('INVALID_INPUT', at('relatedRepositories'), 'Поручение уровня workspace должно затрагивать минимум два компонента');
114
+ order.relatedRepositories.forEach((r, k) => {
115
+ if (!repos.has(r))
116
+ add('INVALID_INPUT', at('relatedRepositories', k), 'Репозиторий не объявлен политикой: ' + r);
117
+ });
118
+ });
119
+ return issues;
120
+ }
121
+ /**
122
+ * Снимок контекста против графа: содержимое совпадает с digests, каждый
123
+ * источник, названный поручением, присутствует и обязателен либо явно
124
+ * помечен отсутствующим дополнительным.
125
+ */
126
+ function contextSnapshotIssues(graph, context) {
127
+ const issues = contextIssues(context).map((message) => ({
128
+ code: 'INVALID_INPUT',
129
+ path: ['context'],
130
+ message,
131
+ }));
132
+ const sources = new Map(context.sources.map((s) => [s.id, s]));
133
+ graph.orders.forEach((order, i) => order.context.forEach((id, k) => {
134
+ const source = sources.get(id);
135
+ if (!source)
136
+ issues.push({
137
+ code: 'INVALID_INPUT',
138
+ path: ['graph', 'orders', i, 'context', k],
139
+ message: 'Обязательный источник контекста отсутствует в снимке: ' + id,
140
+ });
141
+ else if (!source.required)
142
+ issues.push({
143
+ code: 'INVALID_INPUT',
144
+ path: ['graph', 'orders', i, 'context', k],
145
+ message: 'Источник, названный поручением, должен быть обязательным: ' + id,
146
+ });
147
+ }));
148
+ return issues;
149
+ }
150
+ /**
151
+ * Проверка входов без вызова моделей и без записи состояния. Ошибки
152
+ * собираются все сразу; код первой определяет класс отказа.
153
+ */
154
+ export function validateInputs(input) {
155
+ const graph = parse(workGraphSchema, input.graph, 'graph');
156
+ const policy = parse(executionPolicySchema, input.policy, 'policy');
157
+ const context = input.context === undefined
158
+ ? undefined
159
+ : parse(contextSnapshotSchema, input.context, 'context');
160
+ const issues = [
161
+ ...(context ? contextSnapshotIssues(graph, context) : []),
162
+ ...graphIssues(graph).map((i) => ({ ...i, path: ['graph', ...i.path] })),
163
+ ...policyIssues(policy).map((i) => ({ ...i, path: ['policy', ...i.path] })),
164
+ ...crossIssues(graph, policy),
165
+ ];
166
+ if (issues.length)
167
+ throw new HarnessError(issues[0].code, `Найдено нарушений: ${issues.length}`, issues.map(({ path, message }) => ({ path, message })));
168
+ return {
169
+ graphId: graph.id,
170
+ graphDigest: workGraphDigest(graph),
171
+ policyDigest: policyDigest(policy),
172
+ orders: graph.orders.length,
173
+ ...(context ? { contextDigest: contextDigest(context) } : {}),
174
+ };
175
+ }
@@ -0,0 +1,284 @@
1
+ import { type CheckSuite, type ContractDocument, type EvidenceRecord, type ExecutionPolicy, type ExecutionView, type RunResult, type WorkOrder } from '../contracts/index.ts';
2
+ import { type CorpusSnapshot } from './checks.ts';
3
+ /**
4
+ * Доказательство договора проверки на границе приёмки.
5
+ *
6
+ * Бит PASS и верная версия проверок не доказывают, что генеративный gate
7
+ * исполнил договор поручения: сохранённое evidence без манифеста свойств
8
+ * или с заниженным корпусом выдало бы прежний уровень за сильный. Поэтому и
9
+ * `finish` (а через него recovery), и проверка переносимого результата
10
+ * требуют для каждого gate объявленных свойств решающую запись обеих фаз с
11
+ * манифестом ожидаемой проверки и исполненным обязательным корпусом
12
+ * закреплённой версии. Поручение без `properties` — прежний уровень.
13
+ */
14
+ type ProofEvidence = Pick<EvidenceRecord, 'kind' | 'phase' | 'gate' | 'sha' | 'passed'> & {
15
+ consumer?: string | undefined;
16
+ checks?: string | undefined;
17
+ exitCode?: number | undefined;
18
+ property?: Pick<NonNullable<EvidenceRecord['property']>, 'level' | 'manifest'> | undefined;
19
+ };
20
+ export interface PropertyProofInput {
21
+ order: Pick<WorkOrder, 'properties'>;
22
+ contracts: ContractDocument[];
23
+ candidateSha: string;
24
+ resultSha: string;
25
+ /** Версия проверок попытки (`checks.effective`). */
26
+ effective?: string | undefined;
27
+ /** Случаи закреплённой версии корпуса; `null` — закреплённая версия не найдена. */
28
+ corpus?: CorpusSnapshot | null | undefined;
29
+ evidence: ProofEvidence[];
30
+ }
31
+ /** Gates объявленных свойств поручения и их свойства. */
32
+ export declare function propertyGates(order: Pick<WorkOrder, 'properties'>, contracts: ContractDocument[]): {
33
+ problem: string;
34
+ byGate?: undefined;
35
+ } | {
36
+ byGate: Map<string, string[]>;
37
+ problem?: undefined;
38
+ };
39
+ /** Причина отказа в доказательстве свойств или undefined. */
40
+ export declare function propertyProofProblem(input: PropertyProofInput): string | undefined;
41
+ /** Случаи закреплённой версии корпуса по состоянию исполнения. */
42
+ export declare function pinnedCorpus(view: ExecutionView, binding: {
43
+ suite: string;
44
+ digest: string;
45
+ }): CorpusSnapshot | null;
46
+ /** Случаи версии корпуса по digest; `null` — версии нет. */
47
+ export declare function suiteCorpus(suite: Pick<CheckSuite, 'versions' | 'cases'> | undefined, digest: string): CorpusSnapshot | null;
48
+ /** Политика получателя: репозитории (gates, группы, зависимости, target), роли и правила ревью. */
49
+ export type ReceiverPolicy = Pick<ExecutionPolicy, 'repositories' | 'roles' | 'review'>;
50
+ /**
51
+ * Что получатель знает сам и передаёт проверке. Всё, что результат
52
+ * утверждает о поручении, его области, входах и ревью, сверяется с этим, а не
53
+ * с другими полями того же результата: согласованная сама с собой подделка
54
+ * иначе проходила бы.
55
+ */
56
+ export interface ReceiverContext {
57
+ /** Постановка поручения у получателя. */
58
+ order: WorkOrder;
59
+ /** Граф, в котором получатель держит поручение. */
60
+ graphId: string;
61
+ /** Договоры поручения по его ссылкам (документы у получателя). */
62
+ contracts: ContractDocument[];
63
+ /** Политика получателя: репозиторий поручения, потребители и их зависимости, роли, ревью. */
64
+ policy: ReceiverPolicy;
65
+ /**
66
+ * Снимок контекста, закреплённый согласованием графа у получателя; `null` —
67
+ * согласование без контекста.
68
+ */
69
+ contextDigest: string | null;
70
+ /** Корпус по id из копии получателя. */
71
+ suite?: (id: string) => Pick<CheckSuite, 'versions' | 'cases' | 'contractId' | 'basis'> | undefined;
72
+ /** Digest согласованной постановки у хоста получателя; по умолчанию — digest поручения. */
73
+ specDigest?: string;
74
+ /** Закреплённая за поручением версия корпуса у получателя (`null` — без корпуса). */
75
+ checkVersion?: {
76
+ suite: string;
77
+ digest: string;
78
+ } | null;
79
+ /**
80
+ * Формула версии проверок хоста получателя (как `BasisProvider.checksDigest`);
81
+ * без неё — формула harness.
82
+ */
83
+ checksDigest?(input: {
84
+ specDigest: string;
85
+ order: WorkOrder;
86
+ policyDigest: string;
87
+ corpus?: {
88
+ suite: string;
89
+ digest: string;
90
+ };
91
+ }): string;
92
+ /** Основание корпуса по формуле хоста получателя (как `BasisProvider.suiteBasis`). */
93
+ suiteBasis?(contract: ContractDocument): string;
94
+ /**
95
+ * Результат прежнего формата хоста, в котором входы попытки не
96
+ * наблюдались: `dependencies` — снимков собственных зависимостей и их
97
+ * свежести нет; `consumers` — у потребителей нет свежести. Тогда пустые
98
+ * списки не сверяются с замыканием — их нет, и проверке они не подлежат;
99
+ * непустые, снимки зависимостей потребителя, провайдер и всё остальное
100
+ * сверяются как обычно. Какой результат имеет прежний формат, решает хост
101
+ * по своим правилам формата.
102
+ */
103
+ unobserved?: {
104
+ dependencies?: boolean;
105
+ consumers?: boolean;
106
+ };
107
+ /**
108
+ * Чем подтверждено ревью: `current` (по умолчанию) — writer и reviewer
109
+ * назначены текущей политикой получателя; `recorded` — результат несёт
110
+ * своё назначение (writer и reviewer записаны при приёмке) и хост
111
+ * перепроверяет его позже, когда назначение ролей могло смениться: тогда
112
+ * оба должны быть runtime политики получателя, а правило вендора роли —
113
+ * соблюдено.
114
+ */
115
+ assignment?: 'current' | 'recorded';
116
+ }
117
+ /**
118
+ * Модель доверия получателя: для каждого поля принятого `RunResult` — как
119
+ * оно участвует в вердикте.
120
+ *
121
+ * - `expected` — сверяется с ожиданием, которое получатель вычисляет сам из
122
+ * `ReceiverContext` (поручение, граф, политика, договоры, корпус, контекст);
123
+ * - `consistency` — сверяется на согласованность с другими полями результата
124
+ * (SHA фаз, свежесть со снимками, уникальность записей);
125
+ * - `informative` — сведение, которое ничего не доказывает: вердикт на него
126
+ * не опирается, и его изменение вердикт не меняет;
127
+ * - `schema` — значение фиксировано схемой.
128
+ *
129
+ * Подлинность SHA, деревьев, artifacts и записей (их наличие в Git и в
130
+ * хранилище исполнителя) получатель не удостоверяет: это транспорт хоста.
131
+ * Таблица — проверяемое утверждение: `tests/receipt-trust.test.ts` строит
132
+ * подделку каждого поля `expected`/`consistency` и требует отказа, а изменение
133
+ * поля `informative` — того же вердикта.
134
+ */
135
+ export declare const receiptTrust: {
136
+ readonly apiVersion: readonly ["schema", "литерал версии API"];
137
+ readonly outcome: readonly ["expected", "только accepted подтверждает приёмку"];
138
+ readonly workOrderId: readonly ["expected", "ID поручения получателя"];
139
+ readonly graphId: readonly ["expected", "граф поручения у получателя"];
140
+ readonly 'source.connector': readonly ["expected", "источник поручения получателя"];
141
+ readonly 'source.ref': readonly ["expected", "источник поручения получателя"];
142
+ readonly 'source.revision': readonly ["expected", "редакция поручения получателя"];
143
+ readonly runId: readonly ["informative", "идентификатор попытки у исполнителя"];
144
+ readonly attempt: readonly ["informative", "номер попытки у исполнителя"];
145
+ readonly repositoryId: readonly ["expected", "репозиторий поручения"];
146
+ readonly targetRef: readonly ["expected", "target ref репозитория в политике получателя"];
147
+ readonly 'inputs.harnessVersion': readonly ["informative", "версия исполнителя"];
148
+ readonly 'inputs.consumerVersion': readonly ["informative", "версия хоста исполнителя"];
149
+ readonly 'inputs.stateVersion': readonly ["schema", "литерал версии состояния"];
150
+ readonly 'inputs.workOrderDigest': readonly ["expected", "digest поручения получателя"];
151
+ readonly 'inputs.graphDigest': readonly ["informative", "граф мог получить новую редакцию при неизменном поручении; привязка — digest поручения и его источник"];
152
+ readonly 'inputs.policyDigest': readonly ["consistency", "входит в вычисление версии проверок"];
153
+ readonly 'inputs.contextDigest': readonly ["expected", "снимок контекста согласования у получателя"];
154
+ readonly 'inputs.checks': readonly ["expected", "версия проверок, вычисленная получателем"];
155
+ readonly 'inputs.corpus.suite': readonly ["expected", "корпус, закреплённый за поручением у получателя"];
156
+ readonly 'inputs.corpus.number': readonly ["expected", "номер этой версии в корпусе получателя"];
157
+ readonly 'inputs.corpus.digest': readonly ["expected", "версия корпуса, закреплённая у получателя"];
158
+ readonly 'inputs.corpus': readonly ["expected", "привязка к корпусу, закреплённому у получателя"];
159
+ readonly 'inputs.requiredGates': readonly ["expected", "область поручения, раскрытая по политике получателя; без поля — область получателя"];
160
+ readonly 'inputs.requiredGates[]': readonly ["expected", "ровно эта область, без повторов"];
161
+ readonly 'inputs.writer': readonly ["expected", "writer роли поручения; без поля — writer роли получателя"];
162
+ readonly 'inputs.writer.runtime': readonly ["expected", "writer роли поручения в политике получателя"];
163
+ readonly 'inputs.writer.model': readonly ["informative", "модель writer"];
164
+ readonly 'checked.dependencies': readonly ["expected", "замыкание зависимостей репозитория по политике получателя"];
165
+ readonly 'checked.dependencies[]': readonly ["expected", "ровно один снимок каждой зависимости замыкания"];
166
+ readonly 'checked.dependencies[].repositoryId': readonly ["expected", "зависимость из замыкания"];
167
+ readonly 'checked.dependencies[].sha': readonly ["consistency", "совпадает со снимком в свежести"];
168
+ readonly 'checked.dependencies[].tree': readonly ["informative", "подлинность дерева — Git хоста"];
169
+ readonly 'checked.dependencies[].artifacts': readonly ["informative", "подлинность artifacts — Git хоста"];
170
+ readonly 'checked.dependencies[].artifacts[]': readonly ["informative", "подлинность artifacts — Git хоста"];
171
+ readonly 'checked.dependencies[].artifacts[].path': readonly ["informative", "подлинность artifacts — Git хоста"];
172
+ readonly 'checked.dependencies[].artifacts[].digest': readonly ["informative", "подлинность artifacts — Git хоста"];
173
+ readonly 'checked.freshness': readonly ["expected", "свежесть каждой зависимости замыкания"];
174
+ readonly 'checked.freshness[]': readonly ["expected", "ровно одна запись на зависимость"];
175
+ readonly 'checked.freshness[].repositoryId': readonly ["expected", "зависимость из замыкания"];
176
+ readonly 'checked.freshness[].snapshot': readonly ["consistency", "совпадает со снимком зависимости"];
177
+ readonly 'checked.freshness[].head': readonly ["consistency", "fresh ⇔ head = snapshot; значение головы — наблюдение"];
178
+ readonly 'checked.freshness[].fresh': readonly ["consistency", "fresh ⇔ head = snapshot"];
179
+ readonly 'checked.consumers': readonly ["expected", "объявленные потребители поручения"];
180
+ readonly 'checked.consumers[]': readonly ["expected", "ровно одно описание каждого объявленного потребителя"];
181
+ readonly 'checked.consumers[].repositoryId': readonly ["expected", "объявленный потребитель"];
182
+ readonly 'checked.consumers[].gates': readonly ["expected", "область потребителя, раскрытая по политике получателя"];
183
+ readonly 'checked.consumers[].gates[]': readonly ["expected", "ровно эта область, без повторов"];
184
+ readonly 'checked.consumers[].sha': readonly ["consistency", "совпадает со снимком потребителя в его свежести"];
185
+ readonly 'checked.consumers[].tree': readonly ["informative", "подлинность дерева — Git хоста"];
186
+ readonly 'checked.consumers[].dependencies': readonly ["expected", "замыкание зависимостей потребителя по политике получателя"];
187
+ readonly 'checked.consumers[].dependencies[]': readonly ["expected", "ровно один снимок каждой зависимости замыкания"];
188
+ readonly 'checked.consumers[].dependencies[].repositoryId': readonly ["expected", "зависимость из замыкания"];
189
+ readonly 'checked.consumers[].dependencies[].sha': readonly ["consistency", "у провайдера — result SHA; у прочих — снимок в свежести"];
190
+ readonly 'checked.consumers[].dependencies[].tree': readonly ["informative", "подлинность дерева — Git хоста"];
191
+ readonly 'checked.consumers[].dependencies[].artifacts': readonly ["informative", "подлинность artifacts — Git хоста"];
192
+ readonly 'checked.consumers[].dependencies[].artifacts[]': readonly ["informative", "подлинность artifacts — Git хоста"];
193
+ readonly 'checked.consumers[].dependencies[].artifacts[].path': readonly ["informative", "подлинность artifacts — Git хоста"];
194
+ readonly 'checked.consumers[].dependencies[].artifacts[].digest': readonly ["informative", "подлинность artifacts — Git хоста"];
195
+ readonly 'checked.consumers[].freshness': readonly ["expected", "свежесть каждого входа потребителя, кроме провайдера, и его самого"];
196
+ readonly 'checked.consumers[].freshness[]': readonly ["expected", "ровно одна запись на вход"];
197
+ readonly 'checked.consumers[].freshness[].repositoryId': readonly ["expected", "вход потребителя"];
198
+ readonly 'checked.consumers[].freshness[].snapshot': readonly ["consistency", "совпадает со снимком входа"];
199
+ readonly 'checked.consumers[].freshness[].head': readonly ["consistency", "fresh ⇔ head = snapshot; значение головы — наблюдение"];
200
+ readonly 'checked.consumers[].freshness[].fresh': readonly ["consistency", "fresh ⇔ head = snapshot"];
201
+ readonly evidence: readonly ["expected", "решающие записи всех обязательных проверок обеих фаз"];
202
+ readonly 'evidence[]': readonly ["consistency", "записи уникальны по ID"];
203
+ readonly 'evidence[].id': readonly ["consistency", "уникален"];
204
+ readonly 'evidence[].kind': readonly ["consistency", "согласован с gate (ревью ⇔ independent-review) и с потребителем"];
205
+ readonly 'evidence[].phase': readonly ["consistency", "SHA записи — SHA её фазы"];
206
+ readonly 'evidence[].gate': readonly ["expected", "обязательная проверка поручения, потребителя или ревью"];
207
+ readonly 'evidence[].sha': readonly ["consistency", "SHA фазы: candidate или result"];
208
+ readonly 'evidence[].passed': readonly ["expected", "решающая запись каждой обязательной проверки — PASS"];
209
+ readonly 'evidence[].digest': readonly ["informative", "подлинность записи — хранилище исполнителя"];
210
+ readonly 'evidence[].summary': readonly ["informative", "описание записи"];
211
+ readonly 'evidence[].consumer': readonly ["expected", "объявленный потребитель"];
212
+ readonly 'evidence[].checks': readonly ["expected", "версия проверок, вычисленная получателем, у каждой записи"];
213
+ readonly 'evidence[].tests': readonly ["expected", "доказательство названного testcase решающей записью"];
214
+ readonly 'evidence[].tests[]': readonly ["expected", "элемент названного testcase; прочие элементы — сведения"];
215
+ readonly 'evidence[].tests[].id': readonly ["expected", "ID названного testcase"];
216
+ readonly 'evidence[].tests[].status': readonly ["expected", "названный testcase прошёл"];
217
+ readonly 'evidence[].tests[].opaque': readonly ["expected", "имя названного testcase не скрыто"];
218
+ readonly 'evidence[].testsTruncated': readonly ["expected", "список решающей записи полон"];
219
+ readonly 'evidence[].property': readonly ["expected", "доказательство договора проверки; у записи потребителя — только legacy без манифеста"];
220
+ readonly 'evidence[].property.level': readonly ["expected", "уровень manifest; у записи потребителя — legacy"];
221
+ readonly 'evidence[].property.manifest': readonly ["expected", "манифест договора поручения"];
222
+ readonly 'evidence[].property.manifest.digest': readonly ["expected", "манифест, вычисленный получателем"];
223
+ readonly 'evidence[].property.manifest.properties': readonly ["expected", "свойства поручения"];
224
+ readonly 'evidence[].property.manifest.properties[]': readonly ["expected", "свойства поручения"];
225
+ readonly 'evidence[].property.manifest.corpus': readonly ["expected", "корпус закреплённой версии"];
226
+ readonly 'evidence[].property.manifest.corpus.digest': readonly ["expected", "версия корпуса у получателя"];
227
+ readonly 'evidence[].property.manifest.corpus.cases': readonly ["expected", "число случаев этой версии"];
228
+ readonly 'evidence[].reviewer': readonly ["expected", "reviewer, назначенный политикой получателя"];
229
+ readonly 'evidence[].reviewer.runtime': readonly ["expected", "reviewer роли в политике получателя"];
230
+ readonly 'evidence[].reviewer.model': readonly ["informative", "модель reviewer"];
231
+ readonly 'evidence[].reviewer.sameVendor': readonly ["consistency", "вендоры writer и reviewer"];
232
+ readonly 'evidence[].review': readonly ["informative", "раунд протокола ревью кода"];
233
+ readonly 'evidence[].review.round': readonly ["informative", "раунд протокола ревью кода"];
234
+ readonly 'evidence[].review.call': readonly ["informative", "раунд протокола ревью кода"];
235
+ readonly 'evidence[].review.protocol': readonly ["informative", "раунд протокола ревью кода"];
236
+ readonly 'evidence[].review.issues': readonly ["informative", "раунд протокола ревью кода"];
237
+ readonly 'evidence[].review.issues[]': readonly ["informative", "раунд протокола ревью кода"];
238
+ readonly 'evidence[].review.issues[].path': readonly ["informative", "раунд протокола ревью кода"];
239
+ readonly 'evidence[].review.issues[].reason': readonly ["informative", "раунд протокола ревью кода"];
240
+ readonly 'evidence[].review.issues[].message': readonly ["informative", "раунд протокола ревью кода"];
241
+ readonly 'evidence[].review.transitions': readonly ["informative", "раунд протокола ревью кода"];
242
+ readonly 'evidence[].review.transitions[]': readonly ["informative", "раунд протокола ревью кода"];
243
+ readonly 'evidence[].review.transitions[].id': readonly ["informative", "раунд протокола ревью кода"];
244
+ readonly 'evidence[].review.transitions[].from': readonly ["informative", "раунд протокола ревью кода"];
245
+ readonly 'evidence[].review.transitions[].to': readonly ["informative", "раунд протокола ревью кода"];
246
+ readonly findings: readonly ["informative", "сводка находок может относиться к отклонённым раундам"];
247
+ readonly 'findings[]': readonly ["informative", "сводка находок"];
248
+ readonly 'findings[].severity': readonly ["informative", "сводка находок"];
249
+ readonly 'findings[].message': readonly ["informative", "сводка находок"];
250
+ readonly 'findings[].path': readonly ["informative", "сводка находок"];
251
+ readonly 'findings[].line': readonly ["informative", "сводка находок"];
252
+ readonly 'findings[].rule': readonly ["informative", "сводка находок"];
253
+ readonly 'findings[].id': readonly ["informative", "сводка находок"];
254
+ readonly 'findings[].status': readonly ["informative", "сводка находок"];
255
+ readonly limitations: readonly ["informative", "чего результат не доказывает"];
256
+ readonly 'limitations[]': readonly ["informative", "чего результат не доказывает"];
257
+ readonly finishedAt: readonly ["informative", "время окончания"];
258
+ readonly 'shas.base': readonly ["informative", "база кандидата; подлинность — Git хоста"];
259
+ readonly 'shas.candidate': readonly ["consistency", "SHA решающих записей кандидата"];
260
+ readonly 'shas.integration': readonly ["consistency", "равен result SHA"];
261
+ readonly 'shas.result': readonly ["consistency", "SHA решающих записей интеграции и снимка провайдера у потребителей"];
262
+ };
263
+ /**
264
+ * Проверка переносимого результата (receipt) принятой попытки получателем.
265
+ *
266
+ * Получатель повторяет все условия приёмки, проверяемые по результату, против
267
+ * того, что знает сам (`ReceiverContext`); как участвует каждое поле, задаёт
268
+ * `receiptTrust`. Результат не может: относиться к другому поручению,
269
+ * графу, редакции источника, репозиторию или ветке; сократить или подменить
270
+ * область gates; выдать запись другого вида или ревью за test gate;
271
+ * доказать testcase не решающей записью или записью другой версии; убрать
272
+ * проверку источника требований; опустить, повторить или выдумать
273
+ * потребителя, его область или входы; описать неполный, повторный или
274
+ * противоречивый состав зависимостей и свежести; заявить ревью reviewer-ом,
275
+ * которого политика получателя не назначает, или того же вендора без явного
276
+ * разрешения; смешать версии проверок; убрать или занизить манифест и корпус.
277
+ * Чего не хватает в контексте получателя, — отказ, а не PASS. Результат
278
+ * прежнего формата (без версии проверок, области и writer) у поручения без
279
+ * договора проверки читается на прежнем уровне.
280
+ */
281
+ export declare function resultProblems(result: RunResult, context: ReceiverContext): string[];
282
+ /** Отказ получателя: результат не подтверждает приёмку. */
283
+ export declare function assertResult(...args: Parameters<typeof resultProblems>): void;
284
+ export {};