abelien-harness 0.16.1 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/.env.example +1 -1
  2. package/README.md +7 -10
  3. package/package.json +2 -1
  4. package/skills/abelien-3dgen/domain.json +1 -1
  5. package/skills/abelien-algorithm/SKILL.md +13 -24
  6. package/skills/abelien-algorithm/actions/algorithm.finalize.json +7 -2
  7. package/skills/abelien-algorithm/actions/algorithm.research.json +9 -4
  8. package/skills/abelien-algorithm/bindings.json +0 -13
  9. package/skills/abelien-algorithm/contract/host-tools.generated.json +2438 -223
  10. package/skills/abelien-algorithm/domain.json +6 -23
  11. package/skills/abelien-algorithm/references/actions/algorithm.candidates.generated.md +39 -7
  12. package/skills/abelien-algorithm/references/actions/algorithm.finalize.generated.md +40 -11
  13. package/skills/abelien-algorithm/references/actions/algorithm.research.generated.md +78 -10
  14. package/skills/abelien-algorithm/references/actions.generated.md +2 -3
  15. package/skills/abelien-algorithm/references/research-policy.md +5 -5
  16. package/skills/abelien-algorithm/references/selection-service-contract.md +19 -20
  17. package/skills/abelien-algorithm/schemas/algorithm-bindings.v1.json +42 -18
  18. package/skills/abelien-algorithm/schemas/algorithm-candidates.v1.json +9 -4
  19. package/skills/abelien-algorithm/schemas/algorithm-common.v1.json +104 -2
  20. package/skills/abelien-algorithm/schemas/algorithm-flow-input.v1.json +181 -0
  21. package/skills/abelien-algorithm/schemas/candidates-input.v1.json +3 -3
  22. package/skills/abelien-algorithm/schemas/candidates-result.v1.json +3 -3
  23. package/skills/abelien-algorithm/schemas/finalize-input.v1.json +6 -6
  24. package/skills/abelien-algorithm/schemas/finalize-result.v1.json +12 -4
  25. package/skills/abelien-algorithm/schemas/research-input.v1.json +1 -2
  26. package/skills/abelien-algorithm/schemas/research-result.v1.json +4 -2
  27. package/skills/abelien-algorithm/scripts/candidates.mjs +63 -26
  28. package/skills/abelien-algorithm/scripts/evidence.mjs +17 -6
  29. package/skills/abelien-algorithm/scripts/finalize-selection.mjs +107 -34
  30. package/skills/abelien-algorithm/scripts/hardware-revision.mjs +48 -0
  31. package/skills/abelien-algorithm/scripts/research.mjs +78 -28
  32. package/skills/abelien-algorithm/workflows/user-journey-algorithm.json +7 -6
  33. package/skills/abelien-appearance/actions/appearance.points-fallback.json +1 -1
  34. package/skills/abelien-appearance/contract/host-tools.generated.json +3 -2
  35. package/skills/abelien-appearance/domain.json +1 -1
  36. package/skills/abelien-appearance/references/actions/appearance.points-fallback.generated.md +3 -3
  37. package/skills/abelien-appearance/references/points.md +1 -1
  38. package/skills/abelien-appearance/schemas/points-fallback-input.v1.json +2 -2
  39. package/skills/abelien-appearance/scripts/points.mjs +1 -0
  40. package/skills/abelien-clarify/SKILL.md +2 -2
  41. package/skills/abelien-clarify/domain.json +1 -1
  42. package/skills/abelien-clarify/schemas/skill-result.v1.json +10 -0
  43. package/skills/abelien-clarify/scripts/check_result.py +4 -1
  44. package/skills/abelien-clarify/scripts/test_check_result.py +18 -0
  45. package/skills/abelien-guide/SKILL.md +1 -1
  46. package/skills/abelien-hardware/actions/hardware.guide.json +7 -1
  47. package/skills/abelien-hardware/actions/hardware.search.json +10 -0
  48. package/skills/abelien-hardware/actions/hardware.web-search.json +5 -0
  49. package/skills/abelien-hardware/bindings.json +0 -42
  50. package/skills/abelien-hardware/contract/hardware-journey-orchestration.md +1 -1
  51. package/skills/abelien-hardware/contract/host-tools.generated.json +481 -185
  52. package/skills/abelien-hardware/domain.json +4 -5
  53. package/skills/abelien-hardware/references/actions/hardware.guide.generated.md +3 -1
  54. package/skills/abelien-hardware/references/actions/hardware.search.generated.md +41 -1
  55. package/skills/abelien-hardware/references/actions/hardware.selection-recall.generated.md +2 -1
  56. package/skills/abelien-hardware/references/actions/hardware.web-merge.generated.md +50 -12
  57. package/skills/abelien-hardware/references/actions/hardware.web-search.generated.md +23 -0
  58. package/skills/abelien-hardware/references/actions.generated.md +0 -2
  59. package/skills/abelien-hardware/references/selection-service-contract.md +8 -0
  60. package/skills/abelien-hardware/schemas/classify-reply.v1.json +12 -0
  61. package/skills/abelien-hardware/schemas/extract-reply.v1.json +16 -0
  62. package/skills/abelien-hardware/schemas/hardware-candidates-flow-input.v1.json +16 -0
  63. package/skills/abelien-hardware/schemas/hardware-carry-flow-input.v1.json +36 -0
  64. package/skills/abelien-hardware/schemas/hardware-flow-input.v1.json +16 -0
  65. package/skills/abelien-hardware/schemas/hardware-replace-flow-input.v1.json +32 -0
  66. package/skills/abelien-hardware/schemas/hardware-selection.v2.json +10 -4
  67. package/skills/abelien-hardware/schemas/host-tools-input.v1.json +1 -33
  68. package/skills/abelien-hardware/schemas/proposal-reply.v1.json +7 -0
  69. package/skills/abelien-hardware/schemas/recall-tables.v1.json +247 -0
  70. package/skills/abelien-hardware/schemas/replace-plan-reply.v1.json +27 -0
  71. package/skills/abelien-hardware/schemas/review-reply.v1.json +16 -0
  72. package/skills/abelien-hardware/schemas/search-input.v1.json +1 -1
  73. package/skills/abelien-hardware/schemas/search-result.v1.json +2 -1
  74. package/skills/abelien-hardware/schemas/select-reply.v1.json +7 -0
  75. package/skills/abelien-hardware/schemas/web-merge-input.v1.json +12 -12
  76. package/skills/abelien-hardware/schemas/web-merge-result.v1.json +2 -1
  77. package/skills/abelien-hardware/schemas/web-search-result.v1.json +2 -1
  78. package/skills/abelien-hardware/scripts/oss-wiki-search.mjs +82 -19
  79. package/skills/abelien-hardware/scripts/prismer.mjs +3 -1
  80. package/skills/abelien-hardware/scripts/provider-chain-contract.mjs +26 -0
  81. package/skills/abelien-hardware/scripts/result-schemas.mjs +14 -0
  82. package/skills/abelien-hardware/scripts/select.mjs +24 -12
  83. package/skills/abelien-hardware/scripts/selection-model.mjs +3 -0
  84. package/skills/abelien-hardware/scripts/selection-propose.mjs +12 -10
  85. package/skills/abelien-hardware/scripts/selection-recall.mjs +24 -18
  86. package/skills/abelien-hardware/scripts/volc-web-search.mjs +1 -1
  87. package/skills/abelien-hardware/scripts/web-common.mjs +3 -3
  88. package/skills/abelien-hardware/scripts/web-evidence-storage.mjs +8 -0
  89. package/skills/abelien-hardware/scripts/web-merge.mjs +134 -46
  90. package/skills/abelien-hardware/scripts/web-pdf.mjs +4 -1
  91. package/skills/abelien-hardware/scripts/web-provider-chain.mjs +4 -2
  92. package/skills/abelien-hardware/scripts/wiki-content.mjs +46 -0
  93. package/skills/abelien-hardware/workflows/definitions/07a5d69cf67108f65a466bcb78c03c259d4665405f5c86eb49cc0c6fcac6c658.json +377 -0
  94. package/skills/abelien-hardware/workflows/definitions/0c2fa0e6a2f0dd2c61dcc396174c0ebc74a0aa6283ecb020467550ef726c48e7.json +145 -0
  95. package/skills/abelien-hardware/workflows/definitions/0e9aee1087fab30733fa5a73da252e06d949ecf2a5ee3e97dd06191b5f10d0ff.json +377 -0
  96. package/skills/abelien-hardware/workflows/definitions/145631bcfe0ed2c06af2ccb88f46c3749f3f1d5390dc764a7900208d26f232ea.json +309 -0
  97. package/skills/abelien-hardware/workflows/definitions/184bb6e58daaaccabd651bf42a43b65766da7f7c73c3d3c427d7540324b60ae9.json +437 -0
  98. package/skills/abelien-hardware/workflows/definitions/1d3ec4710a0b6b94dad6b20fd23b31e36e47a8d0bf6807ccbee2a6af53b3133d.json +448 -0
  99. package/skills/abelien-hardware/workflows/definitions/1eff11d69d85f1542b7dc46d90498ff0025a97a3066cbfd30adb09b882e2c3a7.json +438 -0
  100. package/skills/abelien-hardware/workflows/definitions/20453618dcbb5262713342ba2ee006c8a235ab473a32401e1389fa655c34793d.json +389 -0
  101. package/skills/abelien-hardware/workflows/definitions/2d2f040e51ea401ed1913eb1f92cb753d14bd699ebdabfdac408064e9448496f.json +296 -0
  102. package/skills/abelien-hardware/workflows/definitions/2d3819d7f9de9999755e5b4887e9185925e5ae19b3d30b3a0cc9ff4ceedc95db.json +392 -0
  103. package/skills/abelien-hardware/workflows/definitions/38ee23450becf81ee19d29ffbdf715cd02dbaac66fc447e52bb7c34c17d3e648.json +447 -0
  104. package/skills/abelien-hardware/workflows/definitions/3f98517ff28cea95c3402b1c36c3b14888d05a2856c7b6e168dee416b418e53e.json +307 -0
  105. package/skills/abelien-hardware/workflows/definitions/44818c5ac8cde303c0b3b60f5b01c7f680e67c6ab848b56f914f3b19e7dc4a10.json +297 -0
  106. package/skills/abelien-hardware/workflows/definitions/4c35db9add116e824c1da4ddb359fd7d9485911957a70696fcb46855ef38fcda.json +387 -0
  107. package/skills/abelien-hardware/workflows/definitions/50ea928ec99c92ced34003fb460c4577099112b08e8eebe3833b7501f15a2da5.json +452 -0
  108. package/skills/abelien-hardware/workflows/definitions/5269f4b4aeefbe148ae6100557462d3e8af0cd47444d7f3f0e9f493c6646a3a2.json +309 -0
  109. package/skills/abelien-hardware/workflows/definitions/5b1639e607a9b2d8e43d355d01bb9454e43c09216f9da15816223ae643fc4f8b.json +377 -0
  110. package/skills/abelien-hardware/workflows/definitions/5f19c2a16ec3a8fdee759cd0edbbe1c774e564f76a968cd693e49f10eb70509c.json +313 -0
  111. package/skills/abelien-hardware/workflows/definitions/64031f26c71b5940a53613e6434974b97910d80d48f0b9ffc3852283e9fbdc6e.json +388 -0
  112. package/skills/abelien-hardware/workflows/definitions/6925478172e8faa6b05d7c0aa81a34713e4dfd13befa5182da0854c36e2a2c0b.json +443 -0
  113. package/skills/abelien-hardware/workflows/definitions/70323801ae0919cf2db88538d280801bd39674d7b4e4a72551e2aecdbd836f18.json +303 -0
  114. package/skills/abelien-hardware/workflows/definitions/720ae54ed7871edee19e1d728c7255e63a0fb5a2cb5a9ca36edc2e72513e8585.json +310 -0
  115. package/skills/abelien-hardware/workflows/definitions/7c99690da295664767c579ce64b8fdc944a9f12999497042a3a26368b4485d3a.json +437 -0
  116. package/skills/abelien-hardware/workflows/definitions/8e7330bfd83bcc452dc2ef50c5ef16a03d63156952cf536468fe62457a20ef04.json +448 -0
  117. package/skills/abelien-hardware/workflows/definitions/9be15a6d5078d5296340c01177cab9b7d8df924ac405f29924d7d5b8842e4b15.json +452 -0
  118. package/skills/abelien-hardware/workflows/definitions/b3b472e817443960f3fb209c7561947b93350cd4c7538052a2b65362cd207576.json +449 -0
  119. package/skills/abelien-hardware/workflows/definitions/bc48eca9a43214ec0687bcc5361cf68325692e498129965425203682e76cc58f.json +312 -0
  120. package/skills/abelien-hardware/workflows/definitions/bfe4a2d363de928f22aaa1acf58c71ff14b1f0dbc40716da0547a3bac2856704.json +376 -0
  121. package/skills/abelien-hardware/workflows/definitions/c338d59553c9e51e7dc79c19bd8599658b7bb186550e232dc47771a102faf2b6.json +297 -0
  122. package/skills/abelien-hardware/workflows/definitions/ce9380dbb4886a5237665b16e1b19784a52e604c15817914589a86d4d81d9034.json +388 -0
  123. package/skills/abelien-hardware/workflows/definitions/d560de3b0aeeaf9447f7bf2d7f831d638067ab7f6cd028527c892ff623ccd00d.json +297 -0
  124. package/skills/abelien-hardware/workflows/definitions/e31a1d0f33e2980b828dd670879f8ac78344426bfaa7faef1551f50b7b6ba8d0.json +437 -0
  125. package/skills/abelien-hardware/workflows/definitions/f12ea33699b795215620ca81b01052ed76ce79c53796cc2f71166c3cc28cbc54.json +392 -0
  126. package/skills/abelien-hardware/workflows/definitions/fd0c57ea806fbf9c46f313c3905bdfa49f5a1207689551cb3b60ffde3cb23f08.json +383 -0
  127. package/skills/abelien-hardware/workflows/user-journey-hardware-candidates.json +107 -21
  128. package/skills/abelien-hardware/workflows/user-journey-hardware-carry.json +1 -0
  129. package/skills/abelien-hardware/workflows/user-journey-hardware-replace.json +125 -24
  130. package/skills/abelien-hardware/workflows/user-journey-hardware.json +107 -22
  131. package/skills/abelien-harness/SKILL.md +2 -2
  132. package/skills/abelien-harness/contract/action-registry.md +2 -2
  133. package/skills/abelien-harness/contract/fixtures/studio-harness-receipt-v1.json +6 -11
  134. package/skills/abelien-harness/contract/kernel-protocol.md +2 -2
  135. package/skills/abelien-harness/contract/workflow-spec.md +23 -27
  136. package/skills/abelien-harness/contracts/README.md +6 -2
  137. package/skills/abelien-harness/contracts/examples/ModelProfile/invalid-image-detail-low.json +28 -0
  138. package/skills/abelien-harness/contracts/examples/ModelProfile/invalid-missing-output-reserve.json +27 -0
  139. package/skills/abelien-harness/contracts/examples/ModelProfile/valid-deepseek-v4-1-flash.json +28 -0
  140. package/skills/abelien-harness/contracts/examples/expectations.json +8 -0
  141. package/skills/abelien-harness/contracts/index.d.mts +16 -1
  142. package/skills/abelien-harness/contracts/index.mjs +60 -0
  143. package/skills/abelien-harness/contracts/model-profiles/deepseek-v4-1-flash-260910.json +28 -0
  144. package/skills/abelien-harness/contracts/ports/ports.d.ts +5 -0
  145. package/skills/abelien-harness/contracts/schemas/action.v1.json +1 -0
  146. package/skills/abelien-harness/contracts/schemas/confirmation.v1.json +8 -0
  147. package/skills/abelien-harness/contracts/schemas/cross-domain.v1.json +141 -0
  148. package/skills/abelien-harness/contracts/schemas/model-profile.v1.json +157 -0
  149. package/skills/abelien-harness/contracts/schemas/store.v1.json +2 -2
  150. package/skills/abelien-harness/contracts/types.d.ts +28 -1
  151. package/skills/abelien-harness/runtime/README.md +35 -16
  152. package/skills/abelien-harness/runtime/actions.mjs +1 -1
  153. package/skills/abelien-harness/runtime/conformance/README.md +2 -0
  154. package/skills/abelien-harness/runtime/conformance/artifact-store.mjs +28 -1
  155. package/skills/abelien-harness/runtime/conformance/fixtures.mjs +12 -0
  156. package/skills/abelien-harness/runtime/data-contracts.mjs +52 -0
  157. package/skills/abelien-harness/runtime/engine.mjs +187 -20
  158. package/skills/abelien-harness/runtime/errors.mjs +7 -4
  159. package/skills/abelien-harness/runtime/executors.mjs +12 -0
  160. package/skills/abelien-harness/runtime/flow-graph.mjs +14 -1
  161. package/skills/abelien-harness/runtime/graph.mjs +48 -7
  162. package/skills/abelien-harness/runtime/index.mjs +11 -6
  163. package/skills/abelien-harness/runtime/kernel.mjs +20 -1
  164. package/skills/abelien-harness/runtime/model-actions.md +9 -1
  165. package/skills/abelien-harness/runtime/model-actions.mjs +15 -2
  166. package/skills/abelien-harness/runtime/snapshot.mjs +2 -42
  167. package/skills/abelien-harness/runtime/task-view/README.md +7 -5
  168. package/skills/abelien-harness/runtime/task-view/index.mjs +40 -17
  169. package/skills/abelien-harness/runtime/testing/index.mjs +26 -1
  170. package/skills/abelien-harness/runtime/workflow/cli-actions.mjs +29 -0
  171. package/skills/abelien-harness/runtime/workflow/{legacy-flow.mjs → compile.mjs} +19 -15
  172. package/skills/abelien-harness/runtime/{legacy → workflow}/definitions.mjs +15 -47
  173. package/skills/abelien-harness/runtime/{legacy → workflow}/external-recovery.mjs +1 -1
  174. package/skills/abelien-harness/runtime/workflow/flows.mjs +25 -4
  175. package/skills/abelien-harness/runtime/workflow/httl.mjs +3 -3
  176. package/skills/abelien-harness/runtime/workflow/index.mjs +17 -36
  177. package/skills/abelien-harness/runtime/workflow/view.mjs +3 -3
  178. package/skills/abelien-harness/scripts/ab.mjs +13 -18
  179. package/skills/abelien-harness/scripts/action-registry.mjs +22 -3
  180. package/skills/abelien-harness/scripts/calc/errors.mjs +7 -0
  181. package/skills/abelien-harness/scripts/calc/evaluate.mjs +364 -0
  182. package/skills/abelien-harness/scripts/calc/expression.mjs +136 -0
  183. package/skills/abelien-harness/scripts/calc/index.mjs +10 -0
  184. package/skills/abelien-harness/scripts/calc/quantities.mjs +104 -0
  185. package/skills/abelien-harness/scripts/calc/rational.mjs +125 -0
  186. package/skills/abelien-harness/scripts/calc/units.mjs +60 -0
  187. package/skills/abelien-harness/scripts/generate3d-host.mjs +2 -1
  188. package/skills/abelien-harness/scripts/generate3d.mjs +9 -8
  189. package/skills/abelien-harness/scripts/receipt.mjs +9 -98
  190. package/skills/abelien-harness/scripts/store.mjs +0 -2
  191. package/skills/abelien-harness/scripts/studio.mjs +5 -7
  192. package/skills/abelien-harness/scripts/web/common.mjs +6 -1
  193. package/skills/abelien-harness/scripts/web/pdf-reader.mjs +3 -2
  194. package/skills/abelien-harness/scripts/web/public-read.mjs +30 -4
  195. package/skills/abelien-harness/scripts/web/safe-text.mjs +95 -0
  196. package/skills/abelien-harness/scripts/web/search.mjs +1 -1
  197. package/skills/abelien-harness/scripts/web/source-registry.mjs +21 -2
  198. package/skills/abelien-harness/scripts/web/vision.mjs +7 -5
  199. package/skills/abelien-harness/scripts/web/volc.mjs +43 -7
  200. package/skills/abelien-reference/actions/reference.research.json +5 -0
  201. package/skills/abelien-reference/contract/host-responsibilities.md +1 -0
  202. package/skills/abelien-reference/contract/host-tools.generated.json +2 -2
  203. package/skills/abelien-reference/domain.json +1 -1
  204. package/skills/abelien-reference/references/actions/reference.research.generated.md +1 -0
  205. package/skills/abelien-reference/references/research-contract.md +1 -1
  206. package/skills/abelien-reference/scripts/evidence.mjs +1 -1
  207. package/skills/abelien-reference/scripts/finalize.mjs +14 -6
  208. package/skills/abelien-reference/scripts/image-import.mjs +90 -0
  209. package/skills/abelien-reference/scripts/research.mjs +22 -23
  210. package/skills/abelien-structure/SKILL.md +2 -8
  211. package/skills/abelien-structure/actions/cad.assets.json +22 -1
  212. package/skills/abelien-structure/actions/cad.build.json +32 -1
  213. package/skills/abelien-structure/actions/cad.fallback.json +27 -1
  214. package/skills/abelien-structure/actions/cad.precheck.json +21 -1
  215. package/skills/abelien-structure/actions/structure.cad-assemble.json +1 -1
  216. package/skills/abelien-structure/actions/structure.cad-check.json +2 -2
  217. package/skills/abelien-structure/contract/host-tools.generated.json +77 -12
  218. package/skills/abelien-structure/domain.json +3 -2
  219. package/skills/abelien-structure/flows/user-journey-cad.json +2 -2
  220. package/skills/abelien-structure/references/actions/cad.assets.generated.md +6 -1
  221. package/skills/abelien-structure/references/actions/cad.build.generated.md +8 -1
  222. package/skills/abelien-structure/references/actions/cad.fallback.generated.md +7 -1
  223. package/skills/abelien-structure/references/actions/cad.precheck.generated.md +5 -1
  224. package/skills/abelien-structure/references/actions/structure.cad-assemble.generated.md +3 -3
  225. package/skills/abelien-structure/references/actions/structure.cad-check.generated.md +2 -2
  226. package/skills/abelien-structure/references/actions/structure.layout-request.generated.md +17 -0
  227. package/skills/abelien-structure/references/actions.generated.md +1 -1
  228. package/skills/abelien-structure/references/cad-functions.generated.md +43 -2
  229. package/skills/abelien-structure/references/cad-modules.md +4 -4
  230. package/skills/abelien-structure/references/handoff.md +2 -2
  231. package/skills/abelien-structure/references/skeleton.md +12 -2
  232. package/skills/abelien-structure/schemas/cad-flow-input.v1.json +1 -1
  233. package/skills/abelien-structure/schemas/cad-modules.v1.json +2 -2
  234. package/skills/abelien-structure/schemas/cad-result.v1.json +1 -1
  235. package/skills/abelien-structure/schemas/layout-request-input.v1.json +25 -1
  236. package/skills/abelien-structure/scripts/cad.mjs +61 -8
  237. package/skills/abelien-structure/scripts/layout.mjs +56 -1
  238. package/skills/abelien-structure/scripts/schemas.mjs +1 -1
  239. package/skills/abelien-structure-worker/SKILL.md +2 -0
  240. package/skills/abelien-structure-worker/domain.json +1 -1
  241. package/skills/abelien-structure-worker/worker/abelien_cad.py +223 -62
  242. package/skills/abelien-structure-worker/worker/cad.py +441 -91
  243. package/skills/abelien-structure-worker/worker/jobs.mjs +12 -2
  244. package/skills/abelien-structure-worker/worker/source-contract.mjs +3 -2
  245. package/skills/abelien-workspace/SKILL.md +8 -7
  246. package/skills/abelien-workspace/actions/calc.evaluate.json +23 -0
  247. package/skills/abelien-workspace/actions/image.generate.json +27 -1
  248. package/skills/abelien-workspace/actions/image.import.json +27 -1
  249. package/skills/abelien-workspace/actions/reference.image-import.json +64 -0
  250. package/skills/abelien-workspace/actions/step.tool-result.json +27 -0
  251. package/skills/abelien-workspace/actions/studio.prepare.json +17 -1
  252. package/skills/abelien-workspace/actions/visual.review.json +27 -1
  253. package/skills/abelien-workspace/assets/creation-start-flow.json +1 -0
  254. package/skills/abelien-workspace/assets/hardware-reselect-flow.json +2 -1
  255. package/skills/abelien-workspace/assets/journey-stage-plan.json +339 -25
  256. package/skills/abelien-workspace/assets/lane-plan.json +11 -10
  257. package/skills/abelien-workspace/bindings.json +38 -35
  258. package/skills/abelien-workspace/contract/host-binding.md +24 -6
  259. package/skills/abelien-workspace/contract/host-tools.generated.json +1514 -545
  260. package/skills/abelien-workspace/domain.json +18 -51
  261. package/skills/abelien-workspace/flows/creation.create.json +265 -38
  262. package/skills/abelien-workspace/flows/creation.modify.json +265 -38
  263. package/skills/abelien-workspace/flows/creation.remix.json +44 -13
  264. package/skills/abelien-workspace/flows/creation.restore.json +364 -42
  265. package/skills/abelien-workspace/references/actions/calc.evaluate.generated.md +86 -0
  266. package/skills/abelien-workspace/references/actions/image.generate.generated.md +7 -1
  267. package/skills/abelien-workspace/references/actions/image.import.generated.md +7 -1
  268. package/skills/abelien-workspace/references/actions/question.card.generated.md +3 -3
  269. package/skills/abelien-workspace/references/actions/reference.image-import.generated.md +78 -0
  270. package/skills/abelien-workspace/references/actions/step.tool-result.generated.md +50 -0
  271. package/skills/abelien-workspace/references/actions/studio.prepare.generated.md +23 -2
  272. package/skills/abelien-workspace/references/actions/visual.review.generated.md +7 -1
  273. package/skills/abelien-workspace/references/actions/workspace.hardware-reselect-input.generated.md +62 -24
  274. package/skills/abelien-workspace/references/actions/workspace.intake-complete.generated.md +5 -0
  275. package/skills/abelien-workspace/references/actions/workspace.intake-route.generated.md +5 -0
  276. package/skills/abelien-workspace/references/actions/workspace.intake-wait.generated.md +5 -0
  277. package/skills/abelien-workspace/references/actions.generated.md +3 -3
  278. package/skills/abelien-workspace/references/creation-intake.md +2 -0
  279. package/skills/abelien-workspace/references/delivery-policy.md +3 -1
  280. package/skills/abelien-workspace/references/flow-input-contracts.md +23 -0
  281. package/skills/abelien-workspace/references/harness-binding.md +14 -11
  282. package/skills/abelien-workspace/references/journey-stage-plan.md +47 -14
  283. package/skills/abelien-workspace/references/product-flow.md +7 -7
  284. package/skills/abelien-workspace/references/user-journey.md +6 -6
  285. package/skills/abelien-workspace/schemas/calc.v1.json +112 -0
  286. package/skills/abelien-workspace/schemas/creation-flow-input.v1.json +24 -0
  287. package/skills/abelien-workspace/schemas/hardware-reselect-input.v1.json +1 -1
  288. package/skills/abelien-workspace/schemas/host-ack-reply.v1.json +12 -0
  289. package/skills/abelien-workspace/schemas/host-tools.v1.json +155 -14
  290. package/skills/abelien-workspace/schemas/plan-common.v1.json +3 -1
  291. package/skills/abelien-workspace/schemas/reference-image-import-input.v1.json +23 -0
  292. package/skills/abelien-workspace/schemas/reference-image.v1.json +55 -0
  293. package/skills/abelien-workspace/schemas/skeleton-model-reply.v1.json +10 -0
  294. package/skills/abelien-workspace/schemas/stored-result-reply.v1.json +12 -0
  295. package/skills/abelien-workspace/scripts/calc.mjs +109 -0
  296. package/skills/abelien-workspace/scripts/creation-tasks.mjs +212 -50
  297. package/skills/abelien-workspace/scripts/flow-compile.mjs +26 -8
  298. package/skills/abelien-workspace/scripts/plans.mjs +18 -7
  299. package/skills/abelien-algorithm/actions/algorithm.lane-state.json +0 -38
  300. package/skills/abelien-algorithm/references/actions/algorithm.lane-state.generated.md +0 -67
  301. package/skills/abelien-algorithm/schemas/lane-state-input.v1.json +0 -14
  302. package/skills/abelien-algorithm/schemas/lane-state-result.v1.json +0 -14
  303. package/skills/abelien-algorithm/scripts/lane-state.mjs +0 -27
  304. package/skills/abelien-hardware/actions/hardware.prepare.json +0 -28
  305. package/skills/abelien-hardware/actions/hardware.web-extract.json +0 -28
  306. package/skills/abelien-hardware/references/actions/hardware.prepare.generated.md +0 -38
  307. package/skills/abelien-hardware/references/actions/hardware.web-extract.generated.md +0 -36
  308. package/skills/abelien-harness/runtime/legacy/workflow-store.mjs +0 -183
  309. package/skills/abelien-workspace/actions/component.search.json +0 -27
  310. package/skills/abelien-workspace/actions/workspace.journey-next.json +0 -30
  311. package/skills/abelien-workspace/actions/workspace.lanes-next.json +0 -30
  312. package/skills/abelien-workspace/references/actions/component.search.generated.md +0 -35
  313. package/skills/abelien-workspace/references/actions/workspace.journey-next.generated.md +0 -89
  314. package/skills/abelien-workspace/references/actions/workspace.lanes-next.generated.md +0 -59
  315. package/skills/abelien-workspace/schemas/journey-next-input.v1.json +0 -52
  316. package/skills/abelien-workspace/schemas/journey-next-result.v1.json +0 -92
  317. package/skills/abelien-workspace/schemas/lanes-next-input.v1.json +0 -49
  318. package/skills/abelien-workspace/schemas/lanes-next-result.v1.json +0 -54
  319. package/skills/abelien-workspace/scripts/journey-next.mjs +0 -73
  320. package/skills/abelien-workspace/scripts/lanes-next.mjs +0 -36
@@ -10,17 +10,24 @@
10
10
  "description": "核验 Agent 基于 implementation 研究为每个 reaction 提出的候选实现:引用须逐字出现在本次研究存下的正文,候选只能引用为自己 reaction 检索的页面,库内算法须来自研究输入的库清单;每个 reaction 要么有候选、要么写明未解决原因;保存为 status=proposed,不依赖硬件",
11
11
  "input_schema": {
12
12
  "title": "abelien.algorithm.candidates.input.v1",
13
- "description": "基于 implementation 研究为每个 reaction 提出的候选实现;research_id 由宿主按本步检索结果填入,其余字段与 algorithm-candidates 相同。",
13
+ "description": "基于 implementation 研究为每个 reaction 提出的候选实现;research_ids 列出所依据的研究(reaction 多时研究分几次做,同一需求下最多 5 份),其余字段与 algorithm-candidates 相同。",
14
14
  "type": "object",
15
15
  "required": [
16
- "research_id",
16
+ "research_ids",
17
17
  "candidates"
18
18
  ],
19
19
  "properties": {
20
- "research_id": {
21
- "type": "string",
22
- "pattern": "^algorithm-research:[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
23
- "description": "已存的算法研究资源"
20
+ "research_ids": {
21
+ "type": "array",
22
+ "minItems": 1,
23
+ "maxItems": 5,
24
+ "uniqueItems": true,
25
+ "items": {
26
+ "type": "string",
27
+ "pattern": "^algorithm-research:[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
28
+ "description": "已存的算法研究资源"
29
+ },
30
+ "description": "本次所依据的 collected implementation 研究,全部按同一需求与库清单检索"
24
31
  },
25
32
  "candidates": {
26
33
  "type": "array",
@@ -86,7 +93,7 @@
86
93
  "needs": {
87
94
  "type": "object",
88
95
  "additionalProperties": false,
89
- "description": "对硬件的需求,按来源原文记录;原文没写的填 null 或留空列表,不猜。",
96
+ "description": "对硬件的需求,按来源原文记录:每个值都必须原样出现在本候选的某条 quotes 里(不换算、不推算);原文没写的填 null 或留空列表,不猜。",
90
97
  "properties": {
91
98
  "compute": {
92
99
  "type": [
@@ -147,18 +154,23 @@
147
154
  "quotes": {
148
155
  "type": "array",
149
156
  "maxItems": 6,
150
- "description": "逐字取自本次研究读到的正文(可以是为别的 reaction 读到的页面,同一份资料常常支撑几个 reaction);库外候选至少一条。",
157
+ "description": "逐字取自本次研究读到的正文(可以是为别的 reaction 读到的页面,同一份资料常常支撑几个 reaction);库外候选至少一条。needs 里写的值也要出现在这些引文里。",
151
158
  "items": {
152
159
  "type": "object",
153
160
  "additionalProperties": false,
154
161
  "required": [
162
+ "research_id",
155
163
  "page_id",
156
164
  "text"
157
165
  ],
158
166
  "properties": {
167
+ "research_id": {
168
+ "type": "string",
169
+ "description": "这一页所在的研究(research_ids 之一)。"
170
+ },
159
171
  "page_id": {
160
172
  "type": "string",
161
- "description": "本次研究的页面 id,如 p3。"
173
+ "description": "该研究里的页面 id,如 p3。"
162
174
  },
163
175
  "text": {
164
176
  "type": "string",
@@ -212,7 +224,7 @@
212
224
  "id",
213
225
  "status",
214
226
  "schema",
215
- "collected_id",
227
+ "collected_ids",
216
228
  "candidates",
217
229
  "unresolved",
218
230
  "unknowns"
@@ -229,15 +241,179 @@
229
241
  "type": "string",
230
242
  "minLength": 1
231
243
  },
232
- "collected_id": {
233
- "type": "string",
234
- "minLength": 1,
235
- "description": "所依据的 collected 研究"
244
+ "collected_ids": {
245
+ "type": "array",
246
+ "minItems": 1,
247
+ "maxItems": 5,
248
+ "items": {
249
+ "type": "string",
250
+ "pattern": "^algorithm-research:[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
251
+ "description": "已存的算法研究资源"
252
+ },
253
+ "description": "所依据的 collected 研究(候选引文按 research_id 指向其中之一)"
236
254
  },
237
255
  "candidates": {
238
256
  "type": "array",
239
257
  "items": {
240
- "type": "object"
258
+ "description": "algorithm.candidates 核验后存下的候选(bind 只能选同一 reaction 的 implementation_ref)",
259
+ "type": "object",
260
+ "required": [
261
+ "reaction_id",
262
+ "implementation_ref",
263
+ "implementation_version",
264
+ "implementation_type",
265
+ "execution_target",
266
+ "library_entry_id",
267
+ "summary",
268
+ "needs",
269
+ "quotes",
270
+ "evidence"
271
+ ],
272
+ "properties": {
273
+ "reaction_id": {
274
+ "type": "string",
275
+ "minLength": 1
276
+ },
277
+ "implementation_ref": {
278
+ "type": "string",
279
+ "minLength": 1
280
+ },
281
+ "implementation_version": {
282
+ "type": [
283
+ "string",
284
+ "null"
285
+ ]
286
+ },
287
+ "implementation_type": {
288
+ "enum": [
289
+ "firmware",
290
+ "library",
291
+ "model",
292
+ "cloud_service"
293
+ ]
294
+ },
295
+ "execution_target": {
296
+ "enum": [
297
+ "edge",
298
+ "cloud",
299
+ "hybrid"
300
+ ]
301
+ },
302
+ "library_entry_id": {
303
+ "type": [
304
+ "string",
305
+ "null"
306
+ ]
307
+ },
308
+ "summary": {
309
+ "type": "string",
310
+ "minLength": 1
311
+ },
312
+ "needs": {
313
+ "type": "object",
314
+ "required": [
315
+ "compute",
316
+ "memory",
317
+ "storage",
318
+ "runtime",
319
+ "network",
320
+ "interfaces",
321
+ "sensors"
322
+ ],
323
+ "properties": {
324
+ "compute": {
325
+ "type": [
326
+ "string",
327
+ "null"
328
+ ]
329
+ },
330
+ "memory": {
331
+ "type": [
332
+ "string",
333
+ "null"
334
+ ]
335
+ },
336
+ "storage": {
337
+ "type": [
338
+ "string",
339
+ "null"
340
+ ]
341
+ },
342
+ "runtime": {
343
+ "type": [
344
+ "string",
345
+ "null"
346
+ ]
347
+ },
348
+ "network": {
349
+ "type": [
350
+ "string",
351
+ "null"
352
+ ]
353
+ },
354
+ "interfaces": {
355
+ "type": "array",
356
+ "items": {
357
+ "type": "string"
358
+ }
359
+ },
360
+ "sensors": {
361
+ "type": "array",
362
+ "items": {
363
+ "type": "string"
364
+ }
365
+ }
366
+ },
367
+ "additionalProperties": false
368
+ },
369
+ "quotes": {
370
+ "type": "array",
371
+ "items": {
372
+ "type": "object",
373
+ "required": [
374
+ "research_id",
375
+ "page_id",
376
+ "url",
377
+ "text",
378
+ "text_source"
379
+ ],
380
+ "properties": {
381
+ "research_id": {
382
+ "type": "string",
383
+ "pattern": "^algorithm-research:[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
384
+ "description": "已存的算法研究资源"
385
+ },
386
+ "page_id": {
387
+ "type": "string",
388
+ "minLength": 1
389
+ },
390
+ "url": {
391
+ "type": "string",
392
+ "minLength": 1
393
+ },
394
+ "text": {
395
+ "type": "string",
396
+ "minLength": 1
397
+ },
398
+ "text_source": {
399
+ "enum": [
400
+ "page",
401
+ "search_snippet"
402
+ ]
403
+ }
404
+ },
405
+ "additionalProperties": false
406
+ }
407
+ },
408
+ "evidence": {
409
+ "enum": [
410
+ "page",
411
+ "library",
412
+ "search_snippet"
413
+ ]
414
+ }
415
+ },
416
+ "additionalProperties": false
241
417
  }
242
418
  },
243
419
  "unresolved": {
@@ -256,16 +432,15 @@
256
432
  {
257
433
  "action_id": "algorithm.finalize",
258
434
  "contract_version": 1,
259
- "definition_digest": "97b448d37858372a35e5a4040102ccbbeccc9e5437657cf20724c8369594062e",
435
+ "definition_digest": "069d10c2c18a6830867ff6e04251cc073a163a8a618039ca8f281280536f055e",
260
436
  "audience": "agent",
261
- "description": "把 Agent 基于硬件型号和官方联网证据做出的算法绑定归一化为版本化选型资源;operation=bind 时候选取自 algorithm.candidates,来源回执从 Harness 自己存下的研究正文解析,硬件基线尚未 verified 时结果固定为 needs_confirmation",
437
+ "description": "把 Agent 基于硬件型号和官方联网证据做出的算法绑定归一化为版本化选型资源;硬件基线是 hardware_revision_ref 指向的冻结选型修订(按 Ref 读不可变修订,不读可变选型资源);operation=bind 时候选取自 algorithm.candidates,来源回执从 Harness 自己存下的研究正文解析,修订尚未落定(门未开或有未决事项)时结果固定为 needs_confirmation",
262
438
  "input_schema": {
263
439
  "title": "abelien.algorithm.finalize.input.v1",
264
440
  "description": "把 Agent 的算法绑定归一化为版本化选型资源。operation=bind 时候选取自 algorithm.candidates(proposed_id),来源回执由 Harness 从存下的研究正文填写;硬件基线尚未 verified 时结果固定为 needs_confirmation。",
265
441
  "type": "object",
266
442
  "required": [
267
- "hardware_selection_id",
268
- "hardware_selection_revision",
443
+ "hardware_revision_ref",
269
444
  "requirements",
270
445
  "reactions",
271
446
  "research"
@@ -276,16 +451,34 @@
276
451
  "select",
277
452
  "bind"
278
453
  ],
279
- "description": "缺省 select"
454
+ "description": "缺省 select(要求修订已落定:门已开且没有未决事项)"
280
455
  },
281
- "hardware_selection_id": {
282
- "type": "string",
283
- "pattern": "^hardware-selection:[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
284
- "description": "已存的硬件选型资源"
285
- },
286
- "hardware_selection_revision": {
287
- "type": "string",
288
- "minLength": 1
456
+ "hardware_revision_ref": {
457
+ "description": "绑定所在的冻结选型修订;原样抄任务给的 hardware_revision_ref",
458
+ "type": "object",
459
+ "required": [
460
+ "id",
461
+ "version",
462
+ "digest"
463
+ ],
464
+ "properties": {
465
+ "id": {
466
+ "description": "稳定标识符:字母或数字开头,可含 _ . : -,最长 128。与硬件选型、Studio 回执现有的标识符规则相同;不含 @(@ 留给 id@version 的写法)。",
467
+ "type": "string",
468
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"
469
+ },
470
+ "version": {
471
+ "description": "对象版本号,按字符串比较相等,不比较大小(例如 \"7\"、\"r-1a2b3c4d5e6f\")。",
472
+ "type": "string",
473
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,63}$"
474
+ },
475
+ "digest": {
476
+ "description": "sha256 小写十六进制(64 位,不带 sha256: 前缀)。对 JSON 值一律取 harness scripts/web/common.mjs 的 digest(),即对 canonical()(键排序、无空白)后的字节求 sha256。",
477
+ "type": "string",
478
+ "pattern": "^[0-9a-f]{64}$"
479
+ }
480
+ },
481
+ "additionalProperties": false
289
482
  },
290
483
  "proposed_id": {
291
484
  "type": "string",
@@ -300,7 +493,29 @@
300
493
  "properties": {
301
494
  "limits": {
302
495
  "type": "array",
303
- "description": "约束(没有时为空数组)"
496
+ "description": "约束(没有时为空数组);hard 限制带 network 时每条绑定都必须是 edge",
497
+ "items": {
498
+ "type": "object",
499
+ "properties": {
500
+ "id": {
501
+ "type": "string",
502
+ "minLength": 1
503
+ },
504
+ "strength": {
505
+ "enum": [
506
+ "hard",
507
+ "preference"
508
+ ]
509
+ },
510
+ "network": {
511
+ "description": "限制在联网上的含义(只在用户原话说明时填写,原话写进 text):offline 完全不联网也要能工作;no_cloud 可以连本地网络或手机,但数据不出设备、不调用云端服务。两者都意味着算法只能在端侧运行(hard 时由代码强制),差别留给硬件:只有 offline 说明不需要联网模块。",
512
+ "enum": [
513
+ "offline",
514
+ "no_cloud"
515
+ ]
516
+ }
517
+ }
518
+ }
304
519
  }
305
520
  },
306
521
  "description": "clarify 整理后的需求原样"
@@ -401,7 +616,6 @@
401
616
  "type": "object",
402
617
  "additionalProperties": false,
403
618
  "required": [
404
- "status",
405
619
  "summary",
406
620
  "source_ids"
407
621
  ],
@@ -412,7 +626,263 @@
412
626
  "conflict",
413
627
  "unknown"
414
628
  ],
415
- "description": "来源能证明成立才写 pass;证据不够写 unknown,冲突写 conflict。"
629
+ "description": "来源能证明成立才写 pass;证据不够写 unknown,冲突写 conflict。不带数量的判断写 status;带数量的写 formula,两者只写一个。"
630
+ },
631
+ "formula": {
632
+ "description": "数值类检查写公式、不写 status:比较式(unit 写 bool),操作数用 quote(source_id 写本检查 source_ids 里的来源 id,或 limit:<限制 id> 引用户限制原文;text 逐字引含该量的原文,有几个量时给 index)或 choice(你的假设,写依据)。代码求值,真为 pass、假为 conflict。",
633
+ "type": "object",
634
+ "required": [
635
+ "expression",
636
+ "operands",
637
+ "unit"
638
+ ],
639
+ "properties": {
640
+ "expression": {
641
+ "type": "string",
642
+ "minLength": 1,
643
+ "maxLength": 256
644
+ },
645
+ "operands": {
646
+ "type": "object",
647
+ "propertyNames": {
648
+ "pattern": "^[a-z][a-z0-9_]{0,31}$"
649
+ },
650
+ "maxProperties": 16,
651
+ "additionalProperties": {
652
+ "description": "Formula 的操作数,与计算器 calc.evaluate 的操作数同形,另多一种引文来源:带值的写 {value, unit, source};引文的只写 {source: {quote}},不写值和单位(单位取引文里写的;没写单位的裸数是无量纲数)。",
653
+ "type": "object",
654
+ "oneOf": [
655
+ {
656
+ "required": [
657
+ "value",
658
+ "unit",
659
+ "source"
660
+ ],
661
+ "properties": {
662
+ "value": {
663
+ "type": "number"
664
+ },
665
+ "unit": {
666
+ "description": "求值核心(abelien-harness/scripts/calc)认得的单位符号,大小写有别。长度 um mm cm m in mil;角度 deg rad;时间 ms s min h;质量 g kg;电学 mA A mV V mW W mAh Ah mWh Wh;频率 Hz kHz MHz GHz;数据 B kB MB GB(按 1000)、KiB MiB GiB(按 1024)、bit bps kbps Mbps;无量纲 1 % count。",
667
+ "enum": [
668
+ "um",
669
+ "mm",
670
+ "cm",
671
+ "m",
672
+ "in",
673
+ "mil",
674
+ "deg",
675
+ "rad",
676
+ "ms",
677
+ "s",
678
+ "min",
679
+ "h",
680
+ "g",
681
+ "kg",
682
+ "mA",
683
+ "A",
684
+ "mV",
685
+ "V",
686
+ "mW",
687
+ "W",
688
+ "mAh",
689
+ "Ah",
690
+ "mWh",
691
+ "Wh",
692
+ "Hz",
693
+ "kHz",
694
+ "MHz",
695
+ "GHz",
696
+ "B",
697
+ "kB",
698
+ "MB",
699
+ "GB",
700
+ "KiB",
701
+ "MiB",
702
+ "GiB",
703
+ "bit",
704
+ "bps",
705
+ "kbps",
706
+ "Mbps",
707
+ "1",
708
+ "%",
709
+ "count"
710
+ ]
711
+ },
712
+ "source": {
713
+ "description": "带值操作数的来源,三选一。result:本步之前某个动作结果里的 JSON 指针;input:本节点任务视图冻结输入里的 JSON 指针;这两种的值由节点定稿逐一核对(verifyCalcReceipts),抄错就拒收回复。choice:模型的选择或假设,写依据;只要有一个操作数是 choice,结果就标为估算。",
714
+ "type": "object",
715
+ "oneOf": [
716
+ {
717
+ "required": [
718
+ "result"
719
+ ],
720
+ "properties": {
721
+ "result": {
722
+ "type": "object",
723
+ "required": [
724
+ "action_id",
725
+ "pointer"
726
+ ],
727
+ "properties": {
728
+ "action_id": {
729
+ "description": "稳定动作名:域名.动作,小写,可多段(例如 hardware.change-scope、structure.build)。",
730
+ "type": "string",
731
+ "pattern": "^[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)+$"
732
+ },
733
+ "pointer": {
734
+ "type": "string",
735
+ "maxLength": 512,
736
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
737
+ }
738
+ },
739
+ "additionalProperties": false
740
+ }
741
+ },
742
+ "additionalProperties": false
743
+ },
744
+ {
745
+ "required": [
746
+ "input"
747
+ ],
748
+ "properties": {
749
+ "input": {
750
+ "type": "string",
751
+ "maxLength": 512,
752
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
753
+ }
754
+ },
755
+ "additionalProperties": false
756
+ },
757
+ {
758
+ "required": [
759
+ "choice"
760
+ ],
761
+ "properties": {
762
+ "choice": {
763
+ "type": "string",
764
+ "minLength": 1,
765
+ "maxLength": 300
766
+ }
767
+ },
768
+ "additionalProperties": false
769
+ }
770
+ ]
771
+ }
772
+ },
773
+ "additionalProperties": false
774
+ },
775
+ {
776
+ "required": [
777
+ "source"
778
+ ],
779
+ "properties": {
780
+ "source": {
781
+ "type": "object",
782
+ "required": [
783
+ "quote"
784
+ ],
785
+ "properties": {
786
+ "quote": {
787
+ "description": "引文来源:text 是逐字引文,source_id 是它所在的页或 Wiki(硬件写 component_id,算法与参考写 page_id),由消费方核对引文确实在其中;值不由模型写,由消费方代码用核心的量值解析器从引文里取。引文里不止一个量时用 index(从 0 起)指出取第几个。",
788
+ "type": "object",
789
+ "required": [
790
+ "text",
791
+ "source_id"
792
+ ],
793
+ "properties": {
794
+ "text": {
795
+ "type": "string",
796
+ "minLength": 1,
797
+ "maxLength": 2000
798
+ },
799
+ "source_id": {
800
+ "type": "string",
801
+ "minLength": 1,
802
+ "maxLength": 128
803
+ },
804
+ "index": {
805
+ "type": "integer",
806
+ "minimum": 0,
807
+ "maximum": 63
808
+ }
809
+ },
810
+ "additionalProperties": false
811
+ }
812
+ },
813
+ "additionalProperties": false
814
+ }
815
+ },
816
+ "additionalProperties": false
817
+ }
818
+ ]
819
+ }
820
+ },
821
+ "unit": {
822
+ "description": "结果单位:CalcUnit 之一,量纲必须与表达式的结果相同;表达式是顶层比较时写 bool。",
823
+ "enum": [
824
+ "um",
825
+ "mm",
826
+ "cm",
827
+ "m",
828
+ "in",
829
+ "mil",
830
+ "deg",
831
+ "rad",
832
+ "ms",
833
+ "s",
834
+ "min",
835
+ "h",
836
+ "g",
837
+ "kg",
838
+ "mA",
839
+ "A",
840
+ "mV",
841
+ "V",
842
+ "mW",
843
+ "W",
844
+ "mAh",
845
+ "Ah",
846
+ "mWh",
847
+ "Wh",
848
+ "Hz",
849
+ "kHz",
850
+ "MHz",
851
+ "GHz",
852
+ "B",
853
+ "kB",
854
+ "MB",
855
+ "GB",
856
+ "KiB",
857
+ "MiB",
858
+ "GiB",
859
+ "bit",
860
+ "bps",
861
+ "kbps",
862
+ "Mbps",
863
+ "1",
864
+ "%",
865
+ "count",
866
+ "bool"
867
+ ]
868
+ },
869
+ "round": {
870
+ "description": "可选:按结果单位保留的小数位数,银行家舍入。",
871
+ "type": "object",
872
+ "required": [
873
+ "places"
874
+ ],
875
+ "properties": {
876
+ "places": {
877
+ "type": "integer",
878
+ "minimum": 0,
879
+ "maximum": 12
880
+ }
881
+ },
882
+ "additionalProperties": false
883
+ }
884
+ },
885
+ "additionalProperties": false
416
886
  },
417
887
  "summary": {
418
888
  "type": "string",
@@ -432,7 +902,6 @@
432
902
  "type": "object",
433
903
  "additionalProperties": false,
434
904
  "required": [
435
- "status",
436
905
  "summary",
437
906
  "source_ids"
438
907
  ],
@@ -443,7 +912,263 @@
443
912
  "conflict",
444
913
  "unknown"
445
914
  ],
446
- "description": "来源能证明成立才写 pass;证据不够写 unknown,冲突写 conflict。"
915
+ "description": "来源能证明成立才写 pass;证据不够写 unknown,冲突写 conflict。不带数量的判断写 status;带数量的写 formula,两者只写一个。"
916
+ },
917
+ "formula": {
918
+ "description": "数值类检查写公式、不写 status:比较式(unit 写 bool),操作数用 quote(source_id 写本检查 source_ids 里的来源 id,或 limit:<限制 id> 引用户限制原文;text 逐字引含该量的原文,有几个量时给 index)或 choice(你的假设,写依据)。代码求值,真为 pass、假为 conflict。",
919
+ "type": "object",
920
+ "required": [
921
+ "expression",
922
+ "operands",
923
+ "unit"
924
+ ],
925
+ "properties": {
926
+ "expression": {
927
+ "type": "string",
928
+ "minLength": 1,
929
+ "maxLength": 256
930
+ },
931
+ "operands": {
932
+ "type": "object",
933
+ "propertyNames": {
934
+ "pattern": "^[a-z][a-z0-9_]{0,31}$"
935
+ },
936
+ "maxProperties": 16,
937
+ "additionalProperties": {
938
+ "description": "Formula 的操作数,与计算器 calc.evaluate 的操作数同形,另多一种引文来源:带值的写 {value, unit, source};引文的只写 {source: {quote}},不写值和单位(单位取引文里写的;没写单位的裸数是无量纲数)。",
939
+ "type": "object",
940
+ "oneOf": [
941
+ {
942
+ "required": [
943
+ "value",
944
+ "unit",
945
+ "source"
946
+ ],
947
+ "properties": {
948
+ "value": {
949
+ "type": "number"
950
+ },
951
+ "unit": {
952
+ "description": "求值核心(abelien-harness/scripts/calc)认得的单位符号,大小写有别。长度 um mm cm m in mil;角度 deg rad;时间 ms s min h;质量 g kg;电学 mA A mV V mW W mAh Ah mWh Wh;频率 Hz kHz MHz GHz;数据 B kB MB GB(按 1000)、KiB MiB GiB(按 1024)、bit bps kbps Mbps;无量纲 1 % count。",
953
+ "enum": [
954
+ "um",
955
+ "mm",
956
+ "cm",
957
+ "m",
958
+ "in",
959
+ "mil",
960
+ "deg",
961
+ "rad",
962
+ "ms",
963
+ "s",
964
+ "min",
965
+ "h",
966
+ "g",
967
+ "kg",
968
+ "mA",
969
+ "A",
970
+ "mV",
971
+ "V",
972
+ "mW",
973
+ "W",
974
+ "mAh",
975
+ "Ah",
976
+ "mWh",
977
+ "Wh",
978
+ "Hz",
979
+ "kHz",
980
+ "MHz",
981
+ "GHz",
982
+ "B",
983
+ "kB",
984
+ "MB",
985
+ "GB",
986
+ "KiB",
987
+ "MiB",
988
+ "GiB",
989
+ "bit",
990
+ "bps",
991
+ "kbps",
992
+ "Mbps",
993
+ "1",
994
+ "%",
995
+ "count"
996
+ ]
997
+ },
998
+ "source": {
999
+ "description": "带值操作数的来源,三选一。result:本步之前某个动作结果里的 JSON 指针;input:本节点任务视图冻结输入里的 JSON 指针;这两种的值由节点定稿逐一核对(verifyCalcReceipts),抄错就拒收回复。choice:模型的选择或假设,写依据;只要有一个操作数是 choice,结果就标为估算。",
1000
+ "type": "object",
1001
+ "oneOf": [
1002
+ {
1003
+ "required": [
1004
+ "result"
1005
+ ],
1006
+ "properties": {
1007
+ "result": {
1008
+ "type": "object",
1009
+ "required": [
1010
+ "action_id",
1011
+ "pointer"
1012
+ ],
1013
+ "properties": {
1014
+ "action_id": {
1015
+ "description": "稳定动作名:域名.动作,小写,可多段(例如 hardware.change-scope、structure.build)。",
1016
+ "type": "string",
1017
+ "pattern": "^[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)+$"
1018
+ },
1019
+ "pointer": {
1020
+ "type": "string",
1021
+ "maxLength": 512,
1022
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
1023
+ }
1024
+ },
1025
+ "additionalProperties": false
1026
+ }
1027
+ },
1028
+ "additionalProperties": false
1029
+ },
1030
+ {
1031
+ "required": [
1032
+ "input"
1033
+ ],
1034
+ "properties": {
1035
+ "input": {
1036
+ "type": "string",
1037
+ "maxLength": 512,
1038
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
1039
+ }
1040
+ },
1041
+ "additionalProperties": false
1042
+ },
1043
+ {
1044
+ "required": [
1045
+ "choice"
1046
+ ],
1047
+ "properties": {
1048
+ "choice": {
1049
+ "type": "string",
1050
+ "minLength": 1,
1051
+ "maxLength": 300
1052
+ }
1053
+ },
1054
+ "additionalProperties": false
1055
+ }
1056
+ ]
1057
+ }
1058
+ },
1059
+ "additionalProperties": false
1060
+ },
1061
+ {
1062
+ "required": [
1063
+ "source"
1064
+ ],
1065
+ "properties": {
1066
+ "source": {
1067
+ "type": "object",
1068
+ "required": [
1069
+ "quote"
1070
+ ],
1071
+ "properties": {
1072
+ "quote": {
1073
+ "description": "引文来源:text 是逐字引文,source_id 是它所在的页或 Wiki(硬件写 component_id,算法与参考写 page_id),由消费方核对引文确实在其中;值不由模型写,由消费方代码用核心的量值解析器从引文里取。引文里不止一个量时用 index(从 0 起)指出取第几个。",
1074
+ "type": "object",
1075
+ "required": [
1076
+ "text",
1077
+ "source_id"
1078
+ ],
1079
+ "properties": {
1080
+ "text": {
1081
+ "type": "string",
1082
+ "minLength": 1,
1083
+ "maxLength": 2000
1084
+ },
1085
+ "source_id": {
1086
+ "type": "string",
1087
+ "minLength": 1,
1088
+ "maxLength": 128
1089
+ },
1090
+ "index": {
1091
+ "type": "integer",
1092
+ "minimum": 0,
1093
+ "maximum": 63
1094
+ }
1095
+ },
1096
+ "additionalProperties": false
1097
+ }
1098
+ },
1099
+ "additionalProperties": false
1100
+ }
1101
+ },
1102
+ "additionalProperties": false
1103
+ }
1104
+ ]
1105
+ }
1106
+ },
1107
+ "unit": {
1108
+ "description": "结果单位:CalcUnit 之一,量纲必须与表达式的结果相同;表达式是顶层比较时写 bool。",
1109
+ "enum": [
1110
+ "um",
1111
+ "mm",
1112
+ "cm",
1113
+ "m",
1114
+ "in",
1115
+ "mil",
1116
+ "deg",
1117
+ "rad",
1118
+ "ms",
1119
+ "s",
1120
+ "min",
1121
+ "h",
1122
+ "g",
1123
+ "kg",
1124
+ "mA",
1125
+ "A",
1126
+ "mV",
1127
+ "V",
1128
+ "mW",
1129
+ "W",
1130
+ "mAh",
1131
+ "Ah",
1132
+ "mWh",
1133
+ "Wh",
1134
+ "Hz",
1135
+ "kHz",
1136
+ "MHz",
1137
+ "GHz",
1138
+ "B",
1139
+ "kB",
1140
+ "MB",
1141
+ "GB",
1142
+ "KiB",
1143
+ "MiB",
1144
+ "GiB",
1145
+ "bit",
1146
+ "bps",
1147
+ "kbps",
1148
+ "Mbps",
1149
+ "1",
1150
+ "%",
1151
+ "count",
1152
+ "bool"
1153
+ ]
1154
+ },
1155
+ "round": {
1156
+ "description": "可选:按结果单位保留的小数位数,银行家舍入。",
1157
+ "type": "object",
1158
+ "required": [
1159
+ "places"
1160
+ ],
1161
+ "properties": {
1162
+ "places": {
1163
+ "type": "integer",
1164
+ "minimum": 0,
1165
+ "maximum": 12
1166
+ }
1167
+ },
1168
+ "additionalProperties": false
1169
+ }
1170
+ },
1171
+ "additionalProperties": false
447
1172
  },
448
1173
  "summary": {
449
1174
  "type": "string",
@@ -463,7 +1188,6 @@
463
1188
  "type": "object",
464
1189
  "additionalProperties": false,
465
1190
  "required": [
466
- "status",
467
1191
  "summary",
468
1192
  "source_ids"
469
1193
  ],
@@ -474,7 +1198,263 @@
474
1198
  "conflict",
475
1199
  "unknown"
476
1200
  ],
477
- "description": "来源能证明成立才写 pass;证据不够写 unknown,冲突写 conflict。"
1201
+ "description": "来源能证明成立才写 pass;证据不够写 unknown,冲突写 conflict。不带数量的判断写 status;带数量的写 formula,两者只写一个。"
1202
+ },
1203
+ "formula": {
1204
+ "description": "数值类检查写公式、不写 status:比较式(unit 写 bool),操作数用 quote(source_id 写本检查 source_ids 里的来源 id,或 limit:<限制 id> 引用户限制原文;text 逐字引含该量的原文,有几个量时给 index)或 choice(你的假设,写依据)。代码求值,真为 pass、假为 conflict。",
1205
+ "type": "object",
1206
+ "required": [
1207
+ "expression",
1208
+ "operands",
1209
+ "unit"
1210
+ ],
1211
+ "properties": {
1212
+ "expression": {
1213
+ "type": "string",
1214
+ "minLength": 1,
1215
+ "maxLength": 256
1216
+ },
1217
+ "operands": {
1218
+ "type": "object",
1219
+ "propertyNames": {
1220
+ "pattern": "^[a-z][a-z0-9_]{0,31}$"
1221
+ },
1222
+ "maxProperties": 16,
1223
+ "additionalProperties": {
1224
+ "description": "Formula 的操作数,与计算器 calc.evaluate 的操作数同形,另多一种引文来源:带值的写 {value, unit, source};引文的只写 {source: {quote}},不写值和单位(单位取引文里写的;没写单位的裸数是无量纲数)。",
1225
+ "type": "object",
1226
+ "oneOf": [
1227
+ {
1228
+ "required": [
1229
+ "value",
1230
+ "unit",
1231
+ "source"
1232
+ ],
1233
+ "properties": {
1234
+ "value": {
1235
+ "type": "number"
1236
+ },
1237
+ "unit": {
1238
+ "description": "求值核心(abelien-harness/scripts/calc)认得的单位符号,大小写有别。长度 um mm cm m in mil;角度 deg rad;时间 ms s min h;质量 g kg;电学 mA A mV V mW W mAh Ah mWh Wh;频率 Hz kHz MHz GHz;数据 B kB MB GB(按 1000)、KiB MiB GiB(按 1024)、bit bps kbps Mbps;无量纲 1 % count。",
1239
+ "enum": [
1240
+ "um",
1241
+ "mm",
1242
+ "cm",
1243
+ "m",
1244
+ "in",
1245
+ "mil",
1246
+ "deg",
1247
+ "rad",
1248
+ "ms",
1249
+ "s",
1250
+ "min",
1251
+ "h",
1252
+ "g",
1253
+ "kg",
1254
+ "mA",
1255
+ "A",
1256
+ "mV",
1257
+ "V",
1258
+ "mW",
1259
+ "W",
1260
+ "mAh",
1261
+ "Ah",
1262
+ "mWh",
1263
+ "Wh",
1264
+ "Hz",
1265
+ "kHz",
1266
+ "MHz",
1267
+ "GHz",
1268
+ "B",
1269
+ "kB",
1270
+ "MB",
1271
+ "GB",
1272
+ "KiB",
1273
+ "MiB",
1274
+ "GiB",
1275
+ "bit",
1276
+ "bps",
1277
+ "kbps",
1278
+ "Mbps",
1279
+ "1",
1280
+ "%",
1281
+ "count"
1282
+ ]
1283
+ },
1284
+ "source": {
1285
+ "description": "带值操作数的来源,三选一。result:本步之前某个动作结果里的 JSON 指针;input:本节点任务视图冻结输入里的 JSON 指针;这两种的值由节点定稿逐一核对(verifyCalcReceipts),抄错就拒收回复。choice:模型的选择或假设,写依据;只要有一个操作数是 choice,结果就标为估算。",
1286
+ "type": "object",
1287
+ "oneOf": [
1288
+ {
1289
+ "required": [
1290
+ "result"
1291
+ ],
1292
+ "properties": {
1293
+ "result": {
1294
+ "type": "object",
1295
+ "required": [
1296
+ "action_id",
1297
+ "pointer"
1298
+ ],
1299
+ "properties": {
1300
+ "action_id": {
1301
+ "description": "稳定动作名:域名.动作,小写,可多段(例如 hardware.change-scope、structure.build)。",
1302
+ "type": "string",
1303
+ "pattern": "^[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)+$"
1304
+ },
1305
+ "pointer": {
1306
+ "type": "string",
1307
+ "maxLength": 512,
1308
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
1309
+ }
1310
+ },
1311
+ "additionalProperties": false
1312
+ }
1313
+ },
1314
+ "additionalProperties": false
1315
+ },
1316
+ {
1317
+ "required": [
1318
+ "input"
1319
+ ],
1320
+ "properties": {
1321
+ "input": {
1322
+ "type": "string",
1323
+ "maxLength": 512,
1324
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
1325
+ }
1326
+ },
1327
+ "additionalProperties": false
1328
+ },
1329
+ {
1330
+ "required": [
1331
+ "choice"
1332
+ ],
1333
+ "properties": {
1334
+ "choice": {
1335
+ "type": "string",
1336
+ "minLength": 1,
1337
+ "maxLength": 300
1338
+ }
1339
+ },
1340
+ "additionalProperties": false
1341
+ }
1342
+ ]
1343
+ }
1344
+ },
1345
+ "additionalProperties": false
1346
+ },
1347
+ {
1348
+ "required": [
1349
+ "source"
1350
+ ],
1351
+ "properties": {
1352
+ "source": {
1353
+ "type": "object",
1354
+ "required": [
1355
+ "quote"
1356
+ ],
1357
+ "properties": {
1358
+ "quote": {
1359
+ "description": "引文来源:text 是逐字引文,source_id 是它所在的页或 Wiki(硬件写 component_id,算法与参考写 page_id),由消费方核对引文确实在其中;值不由模型写,由消费方代码用核心的量值解析器从引文里取。引文里不止一个量时用 index(从 0 起)指出取第几个。",
1360
+ "type": "object",
1361
+ "required": [
1362
+ "text",
1363
+ "source_id"
1364
+ ],
1365
+ "properties": {
1366
+ "text": {
1367
+ "type": "string",
1368
+ "minLength": 1,
1369
+ "maxLength": 2000
1370
+ },
1371
+ "source_id": {
1372
+ "type": "string",
1373
+ "minLength": 1,
1374
+ "maxLength": 128
1375
+ },
1376
+ "index": {
1377
+ "type": "integer",
1378
+ "minimum": 0,
1379
+ "maximum": 63
1380
+ }
1381
+ },
1382
+ "additionalProperties": false
1383
+ }
1384
+ },
1385
+ "additionalProperties": false
1386
+ }
1387
+ },
1388
+ "additionalProperties": false
1389
+ }
1390
+ ]
1391
+ }
1392
+ },
1393
+ "unit": {
1394
+ "description": "结果单位:CalcUnit 之一,量纲必须与表达式的结果相同;表达式是顶层比较时写 bool。",
1395
+ "enum": [
1396
+ "um",
1397
+ "mm",
1398
+ "cm",
1399
+ "m",
1400
+ "in",
1401
+ "mil",
1402
+ "deg",
1403
+ "rad",
1404
+ "ms",
1405
+ "s",
1406
+ "min",
1407
+ "h",
1408
+ "g",
1409
+ "kg",
1410
+ "mA",
1411
+ "A",
1412
+ "mV",
1413
+ "V",
1414
+ "mW",
1415
+ "W",
1416
+ "mAh",
1417
+ "Ah",
1418
+ "mWh",
1419
+ "Wh",
1420
+ "Hz",
1421
+ "kHz",
1422
+ "MHz",
1423
+ "GHz",
1424
+ "B",
1425
+ "kB",
1426
+ "MB",
1427
+ "GB",
1428
+ "KiB",
1429
+ "MiB",
1430
+ "GiB",
1431
+ "bit",
1432
+ "bps",
1433
+ "kbps",
1434
+ "Mbps",
1435
+ "1",
1436
+ "%",
1437
+ "count",
1438
+ "bool"
1439
+ ]
1440
+ },
1441
+ "round": {
1442
+ "description": "可选:按结果单位保留的小数位数,银行家舍入。",
1443
+ "type": "object",
1444
+ "required": [
1445
+ "places"
1446
+ ],
1447
+ "properties": {
1448
+ "places": {
1449
+ "type": "integer",
1450
+ "minimum": 0,
1451
+ "maximum": 12
1452
+ }
1453
+ },
1454
+ "additionalProperties": false
1455
+ }
1456
+ },
1457
+ "additionalProperties": false
478
1458
  },
479
1459
  "summary": {
480
1460
  "type": "string",
@@ -494,7 +1474,6 @@
494
1474
  "type": "object",
495
1475
  "additionalProperties": false,
496
1476
  "required": [
497
- "status",
498
1477
  "summary",
499
1478
  "source_ids"
500
1479
  ],
@@ -505,7 +1484,263 @@
505
1484
  "conflict",
506
1485
  "unknown"
507
1486
  ],
508
- "description": "来源能证明成立才写 pass;证据不够写 unknown,冲突写 conflict。"
1487
+ "description": "来源能证明成立才写 pass;证据不够写 unknown,冲突写 conflict。不带数量的判断写 status;带数量的写 formula,两者只写一个。"
1488
+ },
1489
+ "formula": {
1490
+ "description": "数值类检查写公式、不写 status:比较式(unit 写 bool),操作数用 quote(source_id 写本检查 source_ids 里的来源 id,或 limit:<限制 id> 引用户限制原文;text 逐字引含该量的原文,有几个量时给 index)或 choice(你的假设,写依据)。代码求值,真为 pass、假为 conflict。",
1491
+ "type": "object",
1492
+ "required": [
1493
+ "expression",
1494
+ "operands",
1495
+ "unit"
1496
+ ],
1497
+ "properties": {
1498
+ "expression": {
1499
+ "type": "string",
1500
+ "minLength": 1,
1501
+ "maxLength": 256
1502
+ },
1503
+ "operands": {
1504
+ "type": "object",
1505
+ "propertyNames": {
1506
+ "pattern": "^[a-z][a-z0-9_]{0,31}$"
1507
+ },
1508
+ "maxProperties": 16,
1509
+ "additionalProperties": {
1510
+ "description": "Formula 的操作数,与计算器 calc.evaluate 的操作数同形,另多一种引文来源:带值的写 {value, unit, source};引文的只写 {source: {quote}},不写值和单位(单位取引文里写的;没写单位的裸数是无量纲数)。",
1511
+ "type": "object",
1512
+ "oneOf": [
1513
+ {
1514
+ "required": [
1515
+ "value",
1516
+ "unit",
1517
+ "source"
1518
+ ],
1519
+ "properties": {
1520
+ "value": {
1521
+ "type": "number"
1522
+ },
1523
+ "unit": {
1524
+ "description": "求值核心(abelien-harness/scripts/calc)认得的单位符号,大小写有别。长度 um mm cm m in mil;角度 deg rad;时间 ms s min h;质量 g kg;电学 mA A mV V mW W mAh Ah mWh Wh;频率 Hz kHz MHz GHz;数据 B kB MB GB(按 1000)、KiB MiB GiB(按 1024)、bit bps kbps Mbps;无量纲 1 % count。",
1525
+ "enum": [
1526
+ "um",
1527
+ "mm",
1528
+ "cm",
1529
+ "m",
1530
+ "in",
1531
+ "mil",
1532
+ "deg",
1533
+ "rad",
1534
+ "ms",
1535
+ "s",
1536
+ "min",
1537
+ "h",
1538
+ "g",
1539
+ "kg",
1540
+ "mA",
1541
+ "A",
1542
+ "mV",
1543
+ "V",
1544
+ "mW",
1545
+ "W",
1546
+ "mAh",
1547
+ "Ah",
1548
+ "mWh",
1549
+ "Wh",
1550
+ "Hz",
1551
+ "kHz",
1552
+ "MHz",
1553
+ "GHz",
1554
+ "B",
1555
+ "kB",
1556
+ "MB",
1557
+ "GB",
1558
+ "KiB",
1559
+ "MiB",
1560
+ "GiB",
1561
+ "bit",
1562
+ "bps",
1563
+ "kbps",
1564
+ "Mbps",
1565
+ "1",
1566
+ "%",
1567
+ "count"
1568
+ ]
1569
+ },
1570
+ "source": {
1571
+ "description": "带值操作数的来源,三选一。result:本步之前某个动作结果里的 JSON 指针;input:本节点任务视图冻结输入里的 JSON 指针;这两种的值由节点定稿逐一核对(verifyCalcReceipts),抄错就拒收回复。choice:模型的选择或假设,写依据;只要有一个操作数是 choice,结果就标为估算。",
1572
+ "type": "object",
1573
+ "oneOf": [
1574
+ {
1575
+ "required": [
1576
+ "result"
1577
+ ],
1578
+ "properties": {
1579
+ "result": {
1580
+ "type": "object",
1581
+ "required": [
1582
+ "action_id",
1583
+ "pointer"
1584
+ ],
1585
+ "properties": {
1586
+ "action_id": {
1587
+ "description": "稳定动作名:域名.动作,小写,可多段(例如 hardware.change-scope、structure.build)。",
1588
+ "type": "string",
1589
+ "pattern": "^[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)+$"
1590
+ },
1591
+ "pointer": {
1592
+ "type": "string",
1593
+ "maxLength": 512,
1594
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
1595
+ }
1596
+ },
1597
+ "additionalProperties": false
1598
+ }
1599
+ },
1600
+ "additionalProperties": false
1601
+ },
1602
+ {
1603
+ "required": [
1604
+ "input"
1605
+ ],
1606
+ "properties": {
1607
+ "input": {
1608
+ "type": "string",
1609
+ "maxLength": 512,
1610
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
1611
+ }
1612
+ },
1613
+ "additionalProperties": false
1614
+ },
1615
+ {
1616
+ "required": [
1617
+ "choice"
1618
+ ],
1619
+ "properties": {
1620
+ "choice": {
1621
+ "type": "string",
1622
+ "minLength": 1,
1623
+ "maxLength": 300
1624
+ }
1625
+ },
1626
+ "additionalProperties": false
1627
+ }
1628
+ ]
1629
+ }
1630
+ },
1631
+ "additionalProperties": false
1632
+ },
1633
+ {
1634
+ "required": [
1635
+ "source"
1636
+ ],
1637
+ "properties": {
1638
+ "source": {
1639
+ "type": "object",
1640
+ "required": [
1641
+ "quote"
1642
+ ],
1643
+ "properties": {
1644
+ "quote": {
1645
+ "description": "引文来源:text 是逐字引文,source_id 是它所在的页或 Wiki(硬件写 component_id,算法与参考写 page_id),由消费方核对引文确实在其中;值不由模型写,由消费方代码用核心的量值解析器从引文里取。引文里不止一个量时用 index(从 0 起)指出取第几个。",
1646
+ "type": "object",
1647
+ "required": [
1648
+ "text",
1649
+ "source_id"
1650
+ ],
1651
+ "properties": {
1652
+ "text": {
1653
+ "type": "string",
1654
+ "minLength": 1,
1655
+ "maxLength": 2000
1656
+ },
1657
+ "source_id": {
1658
+ "type": "string",
1659
+ "minLength": 1,
1660
+ "maxLength": 128
1661
+ },
1662
+ "index": {
1663
+ "type": "integer",
1664
+ "minimum": 0,
1665
+ "maximum": 63
1666
+ }
1667
+ },
1668
+ "additionalProperties": false
1669
+ }
1670
+ },
1671
+ "additionalProperties": false
1672
+ }
1673
+ },
1674
+ "additionalProperties": false
1675
+ }
1676
+ ]
1677
+ }
1678
+ },
1679
+ "unit": {
1680
+ "description": "结果单位:CalcUnit 之一,量纲必须与表达式的结果相同;表达式是顶层比较时写 bool。",
1681
+ "enum": [
1682
+ "um",
1683
+ "mm",
1684
+ "cm",
1685
+ "m",
1686
+ "in",
1687
+ "mil",
1688
+ "deg",
1689
+ "rad",
1690
+ "ms",
1691
+ "s",
1692
+ "min",
1693
+ "h",
1694
+ "g",
1695
+ "kg",
1696
+ "mA",
1697
+ "A",
1698
+ "mV",
1699
+ "V",
1700
+ "mW",
1701
+ "W",
1702
+ "mAh",
1703
+ "Ah",
1704
+ "mWh",
1705
+ "Wh",
1706
+ "Hz",
1707
+ "kHz",
1708
+ "MHz",
1709
+ "GHz",
1710
+ "B",
1711
+ "kB",
1712
+ "MB",
1713
+ "GB",
1714
+ "KiB",
1715
+ "MiB",
1716
+ "GiB",
1717
+ "bit",
1718
+ "bps",
1719
+ "kbps",
1720
+ "Mbps",
1721
+ "1",
1722
+ "%",
1723
+ "count",
1724
+ "bool"
1725
+ ]
1726
+ },
1727
+ "round": {
1728
+ "description": "可选:按结果单位保留的小数位数,银行家舍入。",
1729
+ "type": "object",
1730
+ "required": [
1731
+ "places"
1732
+ ],
1733
+ "properties": {
1734
+ "places": {
1735
+ "type": "integer",
1736
+ "minimum": 0,
1737
+ "maximum": 12
1738
+ }
1739
+ },
1740
+ "additionalProperties": false
1741
+ }
1742
+ },
1743
+ "additionalProperties": false
509
1744
  },
510
1745
  "summary": {
511
1746
  "type": "string",
@@ -525,7 +1760,6 @@
525
1760
  "type": "object",
526
1761
  "additionalProperties": false,
527
1762
  "required": [
528
- "status",
529
1763
  "summary",
530
1764
  "source_ids"
531
1765
  ],
@@ -536,7 +1770,263 @@
536
1770
  "conflict",
537
1771
  "unknown"
538
1772
  ],
539
- "description": "来源能证明成立才写 pass;证据不够写 unknown,冲突写 conflict。"
1773
+ "description": "来源能证明成立才写 pass;证据不够写 unknown,冲突写 conflict。不带数量的判断写 status;带数量的写 formula,两者只写一个。"
1774
+ },
1775
+ "formula": {
1776
+ "description": "数值类检查写公式、不写 status:比较式(unit 写 bool),操作数用 quote(source_id 写本检查 source_ids 里的来源 id,或 limit:<限制 id> 引用户限制原文;text 逐字引含该量的原文,有几个量时给 index)或 choice(你的假设,写依据)。代码求值,真为 pass、假为 conflict。",
1777
+ "type": "object",
1778
+ "required": [
1779
+ "expression",
1780
+ "operands",
1781
+ "unit"
1782
+ ],
1783
+ "properties": {
1784
+ "expression": {
1785
+ "type": "string",
1786
+ "minLength": 1,
1787
+ "maxLength": 256
1788
+ },
1789
+ "operands": {
1790
+ "type": "object",
1791
+ "propertyNames": {
1792
+ "pattern": "^[a-z][a-z0-9_]{0,31}$"
1793
+ },
1794
+ "maxProperties": 16,
1795
+ "additionalProperties": {
1796
+ "description": "Formula 的操作数,与计算器 calc.evaluate 的操作数同形,另多一种引文来源:带值的写 {value, unit, source};引文的只写 {source: {quote}},不写值和单位(单位取引文里写的;没写单位的裸数是无量纲数)。",
1797
+ "type": "object",
1798
+ "oneOf": [
1799
+ {
1800
+ "required": [
1801
+ "value",
1802
+ "unit",
1803
+ "source"
1804
+ ],
1805
+ "properties": {
1806
+ "value": {
1807
+ "type": "number"
1808
+ },
1809
+ "unit": {
1810
+ "description": "求值核心(abelien-harness/scripts/calc)认得的单位符号,大小写有别。长度 um mm cm m in mil;角度 deg rad;时间 ms s min h;质量 g kg;电学 mA A mV V mW W mAh Ah mWh Wh;频率 Hz kHz MHz GHz;数据 B kB MB GB(按 1000)、KiB MiB GiB(按 1024)、bit bps kbps Mbps;无量纲 1 % count。",
1811
+ "enum": [
1812
+ "um",
1813
+ "mm",
1814
+ "cm",
1815
+ "m",
1816
+ "in",
1817
+ "mil",
1818
+ "deg",
1819
+ "rad",
1820
+ "ms",
1821
+ "s",
1822
+ "min",
1823
+ "h",
1824
+ "g",
1825
+ "kg",
1826
+ "mA",
1827
+ "A",
1828
+ "mV",
1829
+ "V",
1830
+ "mW",
1831
+ "W",
1832
+ "mAh",
1833
+ "Ah",
1834
+ "mWh",
1835
+ "Wh",
1836
+ "Hz",
1837
+ "kHz",
1838
+ "MHz",
1839
+ "GHz",
1840
+ "B",
1841
+ "kB",
1842
+ "MB",
1843
+ "GB",
1844
+ "KiB",
1845
+ "MiB",
1846
+ "GiB",
1847
+ "bit",
1848
+ "bps",
1849
+ "kbps",
1850
+ "Mbps",
1851
+ "1",
1852
+ "%",
1853
+ "count"
1854
+ ]
1855
+ },
1856
+ "source": {
1857
+ "description": "带值操作数的来源,三选一。result:本步之前某个动作结果里的 JSON 指针;input:本节点任务视图冻结输入里的 JSON 指针;这两种的值由节点定稿逐一核对(verifyCalcReceipts),抄错就拒收回复。choice:模型的选择或假设,写依据;只要有一个操作数是 choice,结果就标为估算。",
1858
+ "type": "object",
1859
+ "oneOf": [
1860
+ {
1861
+ "required": [
1862
+ "result"
1863
+ ],
1864
+ "properties": {
1865
+ "result": {
1866
+ "type": "object",
1867
+ "required": [
1868
+ "action_id",
1869
+ "pointer"
1870
+ ],
1871
+ "properties": {
1872
+ "action_id": {
1873
+ "description": "稳定动作名:域名.动作,小写,可多段(例如 hardware.change-scope、structure.build)。",
1874
+ "type": "string",
1875
+ "pattern": "^[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)+$"
1876
+ },
1877
+ "pointer": {
1878
+ "type": "string",
1879
+ "maxLength": 512,
1880
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
1881
+ }
1882
+ },
1883
+ "additionalProperties": false
1884
+ }
1885
+ },
1886
+ "additionalProperties": false
1887
+ },
1888
+ {
1889
+ "required": [
1890
+ "input"
1891
+ ],
1892
+ "properties": {
1893
+ "input": {
1894
+ "type": "string",
1895
+ "maxLength": 512,
1896
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
1897
+ }
1898
+ },
1899
+ "additionalProperties": false
1900
+ },
1901
+ {
1902
+ "required": [
1903
+ "choice"
1904
+ ],
1905
+ "properties": {
1906
+ "choice": {
1907
+ "type": "string",
1908
+ "minLength": 1,
1909
+ "maxLength": 300
1910
+ }
1911
+ },
1912
+ "additionalProperties": false
1913
+ }
1914
+ ]
1915
+ }
1916
+ },
1917
+ "additionalProperties": false
1918
+ },
1919
+ {
1920
+ "required": [
1921
+ "source"
1922
+ ],
1923
+ "properties": {
1924
+ "source": {
1925
+ "type": "object",
1926
+ "required": [
1927
+ "quote"
1928
+ ],
1929
+ "properties": {
1930
+ "quote": {
1931
+ "description": "引文来源:text 是逐字引文,source_id 是它所在的页或 Wiki(硬件写 component_id,算法与参考写 page_id),由消费方核对引文确实在其中;值不由模型写,由消费方代码用核心的量值解析器从引文里取。引文里不止一个量时用 index(从 0 起)指出取第几个。",
1932
+ "type": "object",
1933
+ "required": [
1934
+ "text",
1935
+ "source_id"
1936
+ ],
1937
+ "properties": {
1938
+ "text": {
1939
+ "type": "string",
1940
+ "minLength": 1,
1941
+ "maxLength": 2000
1942
+ },
1943
+ "source_id": {
1944
+ "type": "string",
1945
+ "minLength": 1,
1946
+ "maxLength": 128
1947
+ },
1948
+ "index": {
1949
+ "type": "integer",
1950
+ "minimum": 0,
1951
+ "maximum": 63
1952
+ }
1953
+ },
1954
+ "additionalProperties": false
1955
+ }
1956
+ },
1957
+ "additionalProperties": false
1958
+ }
1959
+ },
1960
+ "additionalProperties": false
1961
+ }
1962
+ ]
1963
+ }
1964
+ },
1965
+ "unit": {
1966
+ "description": "结果单位:CalcUnit 之一,量纲必须与表达式的结果相同;表达式是顶层比较时写 bool。",
1967
+ "enum": [
1968
+ "um",
1969
+ "mm",
1970
+ "cm",
1971
+ "m",
1972
+ "in",
1973
+ "mil",
1974
+ "deg",
1975
+ "rad",
1976
+ "ms",
1977
+ "s",
1978
+ "min",
1979
+ "h",
1980
+ "g",
1981
+ "kg",
1982
+ "mA",
1983
+ "A",
1984
+ "mV",
1985
+ "V",
1986
+ "mW",
1987
+ "W",
1988
+ "mAh",
1989
+ "Ah",
1990
+ "mWh",
1991
+ "Wh",
1992
+ "Hz",
1993
+ "kHz",
1994
+ "MHz",
1995
+ "GHz",
1996
+ "B",
1997
+ "kB",
1998
+ "MB",
1999
+ "GB",
2000
+ "KiB",
2001
+ "MiB",
2002
+ "GiB",
2003
+ "bit",
2004
+ "bps",
2005
+ "kbps",
2006
+ "Mbps",
2007
+ "1",
2008
+ "%",
2009
+ "count",
2010
+ "bool"
2011
+ ]
2012
+ },
2013
+ "round": {
2014
+ "description": "可选:按结果单位保留的小数位数,银行家舍入。",
2015
+ "type": "object",
2016
+ "required": [
2017
+ "places"
2018
+ ],
2019
+ "properties": {
2020
+ "places": {
2021
+ "type": "integer",
2022
+ "minimum": 0,
2023
+ "maximum": 12
2024
+ }
2025
+ },
2026
+ "additionalProperties": false
2027
+ }
2028
+ },
2029
+ "additionalProperties": false
540
2030
  },
541
2031
  "summary": {
542
2032
  "type": "string",
@@ -556,7 +2046,6 @@
556
2046
  "type": "object",
557
2047
  "additionalProperties": false,
558
2048
  "required": [
559
- "status",
560
2049
  "summary",
561
2050
  "source_ids"
562
2051
  ],
@@ -567,7 +2056,263 @@
567
2056
  "conflict",
568
2057
  "unknown"
569
2058
  ],
570
- "description": "来源能证明成立才写 pass;证据不够写 unknown,冲突写 conflict。"
2059
+ "description": "来源能证明成立才写 pass;证据不够写 unknown,冲突写 conflict。不带数量的判断写 status;带数量的写 formula,两者只写一个。"
2060
+ },
2061
+ "formula": {
2062
+ "description": "数值类检查写公式、不写 status:比较式(unit 写 bool),操作数用 quote(source_id 写本检查 source_ids 里的来源 id,或 limit:<限制 id> 引用户限制原文;text 逐字引含该量的原文,有几个量时给 index)或 choice(你的假设,写依据)。代码求值,真为 pass、假为 conflict。",
2063
+ "type": "object",
2064
+ "required": [
2065
+ "expression",
2066
+ "operands",
2067
+ "unit"
2068
+ ],
2069
+ "properties": {
2070
+ "expression": {
2071
+ "type": "string",
2072
+ "minLength": 1,
2073
+ "maxLength": 256
2074
+ },
2075
+ "operands": {
2076
+ "type": "object",
2077
+ "propertyNames": {
2078
+ "pattern": "^[a-z][a-z0-9_]{0,31}$"
2079
+ },
2080
+ "maxProperties": 16,
2081
+ "additionalProperties": {
2082
+ "description": "Formula 的操作数,与计算器 calc.evaluate 的操作数同形,另多一种引文来源:带值的写 {value, unit, source};引文的只写 {source: {quote}},不写值和单位(单位取引文里写的;没写单位的裸数是无量纲数)。",
2083
+ "type": "object",
2084
+ "oneOf": [
2085
+ {
2086
+ "required": [
2087
+ "value",
2088
+ "unit",
2089
+ "source"
2090
+ ],
2091
+ "properties": {
2092
+ "value": {
2093
+ "type": "number"
2094
+ },
2095
+ "unit": {
2096
+ "description": "求值核心(abelien-harness/scripts/calc)认得的单位符号,大小写有别。长度 um mm cm m in mil;角度 deg rad;时间 ms s min h;质量 g kg;电学 mA A mV V mW W mAh Ah mWh Wh;频率 Hz kHz MHz GHz;数据 B kB MB GB(按 1000)、KiB MiB GiB(按 1024)、bit bps kbps Mbps;无量纲 1 % count。",
2097
+ "enum": [
2098
+ "um",
2099
+ "mm",
2100
+ "cm",
2101
+ "m",
2102
+ "in",
2103
+ "mil",
2104
+ "deg",
2105
+ "rad",
2106
+ "ms",
2107
+ "s",
2108
+ "min",
2109
+ "h",
2110
+ "g",
2111
+ "kg",
2112
+ "mA",
2113
+ "A",
2114
+ "mV",
2115
+ "V",
2116
+ "mW",
2117
+ "W",
2118
+ "mAh",
2119
+ "Ah",
2120
+ "mWh",
2121
+ "Wh",
2122
+ "Hz",
2123
+ "kHz",
2124
+ "MHz",
2125
+ "GHz",
2126
+ "B",
2127
+ "kB",
2128
+ "MB",
2129
+ "GB",
2130
+ "KiB",
2131
+ "MiB",
2132
+ "GiB",
2133
+ "bit",
2134
+ "bps",
2135
+ "kbps",
2136
+ "Mbps",
2137
+ "1",
2138
+ "%",
2139
+ "count"
2140
+ ]
2141
+ },
2142
+ "source": {
2143
+ "description": "带值操作数的来源,三选一。result:本步之前某个动作结果里的 JSON 指针;input:本节点任务视图冻结输入里的 JSON 指针;这两种的值由节点定稿逐一核对(verifyCalcReceipts),抄错就拒收回复。choice:模型的选择或假设,写依据;只要有一个操作数是 choice,结果就标为估算。",
2144
+ "type": "object",
2145
+ "oneOf": [
2146
+ {
2147
+ "required": [
2148
+ "result"
2149
+ ],
2150
+ "properties": {
2151
+ "result": {
2152
+ "type": "object",
2153
+ "required": [
2154
+ "action_id",
2155
+ "pointer"
2156
+ ],
2157
+ "properties": {
2158
+ "action_id": {
2159
+ "description": "稳定动作名:域名.动作,小写,可多段(例如 hardware.change-scope、structure.build)。",
2160
+ "type": "string",
2161
+ "pattern": "^[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)+$"
2162
+ },
2163
+ "pointer": {
2164
+ "type": "string",
2165
+ "maxLength": 512,
2166
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
2167
+ }
2168
+ },
2169
+ "additionalProperties": false
2170
+ }
2171
+ },
2172
+ "additionalProperties": false
2173
+ },
2174
+ {
2175
+ "required": [
2176
+ "input"
2177
+ ],
2178
+ "properties": {
2179
+ "input": {
2180
+ "type": "string",
2181
+ "maxLength": 512,
2182
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
2183
+ }
2184
+ },
2185
+ "additionalProperties": false
2186
+ },
2187
+ {
2188
+ "required": [
2189
+ "choice"
2190
+ ],
2191
+ "properties": {
2192
+ "choice": {
2193
+ "type": "string",
2194
+ "minLength": 1,
2195
+ "maxLength": 300
2196
+ }
2197
+ },
2198
+ "additionalProperties": false
2199
+ }
2200
+ ]
2201
+ }
2202
+ },
2203
+ "additionalProperties": false
2204
+ },
2205
+ {
2206
+ "required": [
2207
+ "source"
2208
+ ],
2209
+ "properties": {
2210
+ "source": {
2211
+ "type": "object",
2212
+ "required": [
2213
+ "quote"
2214
+ ],
2215
+ "properties": {
2216
+ "quote": {
2217
+ "description": "引文来源:text 是逐字引文,source_id 是它所在的页或 Wiki(硬件写 component_id,算法与参考写 page_id),由消费方核对引文确实在其中;值不由模型写,由消费方代码用核心的量值解析器从引文里取。引文里不止一个量时用 index(从 0 起)指出取第几个。",
2218
+ "type": "object",
2219
+ "required": [
2220
+ "text",
2221
+ "source_id"
2222
+ ],
2223
+ "properties": {
2224
+ "text": {
2225
+ "type": "string",
2226
+ "minLength": 1,
2227
+ "maxLength": 2000
2228
+ },
2229
+ "source_id": {
2230
+ "type": "string",
2231
+ "minLength": 1,
2232
+ "maxLength": 128
2233
+ },
2234
+ "index": {
2235
+ "type": "integer",
2236
+ "minimum": 0,
2237
+ "maximum": 63
2238
+ }
2239
+ },
2240
+ "additionalProperties": false
2241
+ }
2242
+ },
2243
+ "additionalProperties": false
2244
+ }
2245
+ },
2246
+ "additionalProperties": false
2247
+ }
2248
+ ]
2249
+ }
2250
+ },
2251
+ "unit": {
2252
+ "description": "结果单位:CalcUnit 之一,量纲必须与表达式的结果相同;表达式是顶层比较时写 bool。",
2253
+ "enum": [
2254
+ "um",
2255
+ "mm",
2256
+ "cm",
2257
+ "m",
2258
+ "in",
2259
+ "mil",
2260
+ "deg",
2261
+ "rad",
2262
+ "ms",
2263
+ "s",
2264
+ "min",
2265
+ "h",
2266
+ "g",
2267
+ "kg",
2268
+ "mA",
2269
+ "A",
2270
+ "mV",
2271
+ "V",
2272
+ "mW",
2273
+ "W",
2274
+ "mAh",
2275
+ "Ah",
2276
+ "mWh",
2277
+ "Wh",
2278
+ "Hz",
2279
+ "kHz",
2280
+ "MHz",
2281
+ "GHz",
2282
+ "B",
2283
+ "kB",
2284
+ "MB",
2285
+ "GB",
2286
+ "KiB",
2287
+ "MiB",
2288
+ "GiB",
2289
+ "bit",
2290
+ "bps",
2291
+ "kbps",
2292
+ "Mbps",
2293
+ "1",
2294
+ "%",
2295
+ "count",
2296
+ "bool"
2297
+ ]
2298
+ },
2299
+ "round": {
2300
+ "description": "可选:按结果单位保留的小数位数,银行家舍入。",
2301
+ "type": "object",
2302
+ "required": [
2303
+ "places"
2304
+ ],
2305
+ "properties": {
2306
+ "places": {
2307
+ "type": "integer",
2308
+ "minimum": 0,
2309
+ "maximum": 12
2310
+ }
2311
+ },
2312
+ "additionalProperties": false
2313
+ }
2314
+ },
2315
+ "additionalProperties": false
571
2316
  },
572
2317
  "summary": {
573
2318
  "type": "string",
@@ -581,19 +2326,19 @@
581
2326
  },
582
2327
  "description": "支撑这条判断的 sources[].id。"
583
2328
  }
584
- }
2329
+ },
2330
+ "description": "候选 needs 里写了数量(内存、存储、算力)时必须写 formula,比较所需与板上可用。"
585
2331
  }
586
2332
  }
587
2333
  },
588
2334
  "constraint_checks": {
589
2335
  "type": "array",
590
- "description": "需求里每条非 preference 的 limits 各一条。",
2336
+ "description": "需求里每条非 preference、不带 envelope 的 limits 各一条(带 envelope 的尺寸限制由硬件与结构按包络检查);限制原文带数量时写 formula。",
591
2337
  "items": {
592
2338
  "type": "object",
593
2339
  "additionalProperties": false,
594
2340
  "required": [
595
2341
  "constraint_id",
596
- "status",
597
2342
  "summary",
598
2343
  "source_ids"
599
2344
  ],
@@ -606,8 +2351,266 @@
606
2351
  "enum": [
607
2352
  "pass",
608
2353
  "conflict",
609
- "unknown"
610
- ]
2354
+ "unknown",
2355
+ "not_applicable"
2356
+ ],
2357
+ "description": "不带数量的限制写 status;带数量的写 formula,两者只写一个。这条限制与本绑定的实现无关时写 not_applicable 并在 summary 说明理由(不写 formula)。"
2358
+ },
2359
+ "formula": {
2360
+ "description": "数值类检查写公式、不写 status:比较式(unit 写 bool),操作数用 quote(source_id 写本检查 source_ids 里的来源 id,或 limit:<限制 id> 引用户限制原文;text 逐字引含该量的原文,有几个量时给 index)或 choice(你的假设,写依据)。代码求值,真为 pass、假为 conflict。",
2361
+ "type": "object",
2362
+ "required": [
2363
+ "expression",
2364
+ "operands",
2365
+ "unit"
2366
+ ],
2367
+ "properties": {
2368
+ "expression": {
2369
+ "type": "string",
2370
+ "minLength": 1,
2371
+ "maxLength": 256
2372
+ },
2373
+ "operands": {
2374
+ "type": "object",
2375
+ "propertyNames": {
2376
+ "pattern": "^[a-z][a-z0-9_]{0,31}$"
2377
+ },
2378
+ "maxProperties": 16,
2379
+ "additionalProperties": {
2380
+ "description": "Formula 的操作数,与计算器 calc.evaluate 的操作数同形,另多一种引文来源:带值的写 {value, unit, source};引文的只写 {source: {quote}},不写值和单位(单位取引文里写的;没写单位的裸数是无量纲数)。",
2381
+ "type": "object",
2382
+ "oneOf": [
2383
+ {
2384
+ "required": [
2385
+ "value",
2386
+ "unit",
2387
+ "source"
2388
+ ],
2389
+ "properties": {
2390
+ "value": {
2391
+ "type": "number"
2392
+ },
2393
+ "unit": {
2394
+ "description": "求值核心(abelien-harness/scripts/calc)认得的单位符号,大小写有别。长度 um mm cm m in mil;角度 deg rad;时间 ms s min h;质量 g kg;电学 mA A mV V mW W mAh Ah mWh Wh;频率 Hz kHz MHz GHz;数据 B kB MB GB(按 1000)、KiB MiB GiB(按 1024)、bit bps kbps Mbps;无量纲 1 % count。",
2395
+ "enum": [
2396
+ "um",
2397
+ "mm",
2398
+ "cm",
2399
+ "m",
2400
+ "in",
2401
+ "mil",
2402
+ "deg",
2403
+ "rad",
2404
+ "ms",
2405
+ "s",
2406
+ "min",
2407
+ "h",
2408
+ "g",
2409
+ "kg",
2410
+ "mA",
2411
+ "A",
2412
+ "mV",
2413
+ "V",
2414
+ "mW",
2415
+ "W",
2416
+ "mAh",
2417
+ "Ah",
2418
+ "mWh",
2419
+ "Wh",
2420
+ "Hz",
2421
+ "kHz",
2422
+ "MHz",
2423
+ "GHz",
2424
+ "B",
2425
+ "kB",
2426
+ "MB",
2427
+ "GB",
2428
+ "KiB",
2429
+ "MiB",
2430
+ "GiB",
2431
+ "bit",
2432
+ "bps",
2433
+ "kbps",
2434
+ "Mbps",
2435
+ "1",
2436
+ "%",
2437
+ "count"
2438
+ ]
2439
+ },
2440
+ "source": {
2441
+ "description": "带值操作数的来源,三选一。result:本步之前某个动作结果里的 JSON 指针;input:本节点任务视图冻结输入里的 JSON 指针;这两种的值由节点定稿逐一核对(verifyCalcReceipts),抄错就拒收回复。choice:模型的选择或假设,写依据;只要有一个操作数是 choice,结果就标为估算。",
2442
+ "type": "object",
2443
+ "oneOf": [
2444
+ {
2445
+ "required": [
2446
+ "result"
2447
+ ],
2448
+ "properties": {
2449
+ "result": {
2450
+ "type": "object",
2451
+ "required": [
2452
+ "action_id",
2453
+ "pointer"
2454
+ ],
2455
+ "properties": {
2456
+ "action_id": {
2457
+ "description": "稳定动作名:域名.动作,小写,可多段(例如 hardware.change-scope、structure.build)。",
2458
+ "type": "string",
2459
+ "pattern": "^[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)+$"
2460
+ },
2461
+ "pointer": {
2462
+ "type": "string",
2463
+ "maxLength": 512,
2464
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
2465
+ }
2466
+ },
2467
+ "additionalProperties": false
2468
+ }
2469
+ },
2470
+ "additionalProperties": false
2471
+ },
2472
+ {
2473
+ "required": [
2474
+ "input"
2475
+ ],
2476
+ "properties": {
2477
+ "input": {
2478
+ "type": "string",
2479
+ "maxLength": 512,
2480
+ "pattern": "^(?:/(?:[^~/]|~[01])*)*$"
2481
+ }
2482
+ },
2483
+ "additionalProperties": false
2484
+ },
2485
+ {
2486
+ "required": [
2487
+ "choice"
2488
+ ],
2489
+ "properties": {
2490
+ "choice": {
2491
+ "type": "string",
2492
+ "minLength": 1,
2493
+ "maxLength": 300
2494
+ }
2495
+ },
2496
+ "additionalProperties": false
2497
+ }
2498
+ ]
2499
+ }
2500
+ },
2501
+ "additionalProperties": false
2502
+ },
2503
+ {
2504
+ "required": [
2505
+ "source"
2506
+ ],
2507
+ "properties": {
2508
+ "source": {
2509
+ "type": "object",
2510
+ "required": [
2511
+ "quote"
2512
+ ],
2513
+ "properties": {
2514
+ "quote": {
2515
+ "description": "引文来源:text 是逐字引文,source_id 是它所在的页或 Wiki(硬件写 component_id,算法与参考写 page_id),由消费方核对引文确实在其中;值不由模型写,由消费方代码用核心的量值解析器从引文里取。引文里不止一个量时用 index(从 0 起)指出取第几个。",
2516
+ "type": "object",
2517
+ "required": [
2518
+ "text",
2519
+ "source_id"
2520
+ ],
2521
+ "properties": {
2522
+ "text": {
2523
+ "type": "string",
2524
+ "minLength": 1,
2525
+ "maxLength": 2000
2526
+ },
2527
+ "source_id": {
2528
+ "type": "string",
2529
+ "minLength": 1,
2530
+ "maxLength": 128
2531
+ },
2532
+ "index": {
2533
+ "type": "integer",
2534
+ "minimum": 0,
2535
+ "maximum": 63
2536
+ }
2537
+ },
2538
+ "additionalProperties": false
2539
+ }
2540
+ },
2541
+ "additionalProperties": false
2542
+ }
2543
+ },
2544
+ "additionalProperties": false
2545
+ }
2546
+ ]
2547
+ }
2548
+ },
2549
+ "unit": {
2550
+ "description": "结果单位:CalcUnit 之一,量纲必须与表达式的结果相同;表达式是顶层比较时写 bool。",
2551
+ "enum": [
2552
+ "um",
2553
+ "mm",
2554
+ "cm",
2555
+ "m",
2556
+ "in",
2557
+ "mil",
2558
+ "deg",
2559
+ "rad",
2560
+ "ms",
2561
+ "s",
2562
+ "min",
2563
+ "h",
2564
+ "g",
2565
+ "kg",
2566
+ "mA",
2567
+ "A",
2568
+ "mV",
2569
+ "V",
2570
+ "mW",
2571
+ "W",
2572
+ "mAh",
2573
+ "Ah",
2574
+ "mWh",
2575
+ "Wh",
2576
+ "Hz",
2577
+ "kHz",
2578
+ "MHz",
2579
+ "GHz",
2580
+ "B",
2581
+ "kB",
2582
+ "MB",
2583
+ "GB",
2584
+ "KiB",
2585
+ "MiB",
2586
+ "GiB",
2587
+ "bit",
2588
+ "bps",
2589
+ "kbps",
2590
+ "Mbps",
2591
+ "1",
2592
+ "%",
2593
+ "count",
2594
+ "bool"
2595
+ ]
2596
+ },
2597
+ "round": {
2598
+ "description": "可选:按结果单位保留的小数位数,银行家舍入。",
2599
+ "type": "object",
2600
+ "required": [
2601
+ "places"
2602
+ ],
2603
+ "properties": {
2604
+ "places": {
2605
+ "type": "integer",
2606
+ "minimum": 0,
2607
+ "maximum": 12
2608
+ }
2609
+ },
2610
+ "additionalProperties": false
2611
+ }
2612
+ },
2613
+ "additionalProperties": false
611
2614
  },
612
2615
  "summary": {
613
2616
  "type": "string",
@@ -725,7 +2728,8 @@
725
2728
  }
726
2729
  }
727
2730
  }
728
- }
2731
+ },
2732
+ "additionalProperties": false
729
2733
  },
730
2734
  "output_schema": {
731
2735
  "title": "abelien.algorithm.finalize.result.v1",
@@ -734,8 +2738,7 @@
734
2738
  "required": [
735
2739
  "id",
736
2740
  "status",
737
- "hardware_selection_id",
738
- "hardware_selection_revision",
2741
+ "hardware_revision_ref",
739
2742
  "source_snapshot",
740
2743
  "revision",
741
2744
  "bindings",
@@ -756,13 +2759,32 @@
756
2759
  "needs_confirmation"
757
2760
  ]
758
2761
  },
759
- "hardware_selection_id": {
760
- "type": "string",
761
- "minLength": 1
762
- },
763
- "hardware_selection_revision": {
764
- "type": "string",
765
- "minLength": 1
2762
+ "hardware_revision_ref": {
2763
+ "description": "绑定所在的冻结选型修订;algorithm_bind 定稿要求它等于本运行 hardware 产物的 selectionRevisionRef",
2764
+ "type": "object",
2765
+ "required": [
2766
+ "id",
2767
+ "version",
2768
+ "digest"
2769
+ ],
2770
+ "properties": {
2771
+ "id": {
2772
+ "description": "稳定标识符:字母或数字开头,可含 _ . : -,最长 128。与硬件选型、Studio 回执现有的标识符规则相同;不含 @(@ 留给 id@version 的写法)。",
2773
+ "type": "string",
2774
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"
2775
+ },
2776
+ "version": {
2777
+ "description": "对象版本号,按字符串比较相等,不比较大小(例如 \"7\"、\"r-1a2b3c4d5e6f\")。",
2778
+ "type": "string",
2779
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,63}$"
2780
+ },
2781
+ "digest": {
2782
+ "description": "sha256 小写十六进制(64 位,不带 sha256: 前缀)。对 JSON 值一律取 harness scripts/web/common.mjs 的 digest(),即对 canonical()(键排序、无空白)后的字节求 sha256。",
2783
+ "type": "string",
2784
+ "pattern": "^[0-9a-f]{64}$"
2785
+ }
2786
+ },
2787
+ "additionalProperties": false
766
2788
  },
767
2789
  "operation": {
768
2790
  "const": "bind"
@@ -802,6 +2824,62 @@
802
2824
  },
803
2825
  "blocking_unknowns": {
804
2826
  "type": "array"
2827
+ },
2828
+ "numeric_provenance": {
2829
+ "description": "只在 algorithm_bind 的产物上:节点定稿写下的本步计算器调用摘要(verifyCalcReceipts),供审计;动作本身不产出",
2830
+ "type": "array",
2831
+ "items": {
2832
+ "type": "object",
2833
+ "required": [
2834
+ "id",
2835
+ "items"
2836
+ ],
2837
+ "properties": {
2838
+ "id": {
2839
+ "type": "string",
2840
+ "minLength": 1
2841
+ },
2842
+ "items": {
2843
+ "type": "array",
2844
+ "items": {
2845
+ "type": "object",
2846
+ "required": [
2847
+ "name",
2848
+ "expression",
2849
+ "text",
2850
+ "unit",
2851
+ "exact",
2852
+ "basis"
2853
+ ],
2854
+ "properties": {
2855
+ "name": {
2856
+ "type": "string"
2857
+ },
2858
+ "expression": {
2859
+ "type": "string"
2860
+ },
2861
+ "text": {
2862
+ "type": "string"
2863
+ },
2864
+ "unit": {
2865
+ "type": "string"
2866
+ },
2867
+ "exact": {
2868
+ "type": "boolean"
2869
+ },
2870
+ "basis": {
2871
+ "enum": [
2872
+ "computed",
2873
+ "estimate"
2874
+ ]
2875
+ }
2876
+ },
2877
+ "additionalProperties": false
2878
+ }
2879
+ }
2880
+ },
2881
+ "additionalProperties": false
2882
+ }
805
2883
  }
806
2884
  },
807
2885
  "allOf": [
@@ -834,164 +2912,14 @@
834
2912
  }
835
2913
  },
836
2914
  {
837
- "action_id": "algorithm.lane-state",
2915
+ "action_id": "algorithm.research",
838
2916
  "contract_version": 1,
839
- "definition_digest": "49dbca22c3b02beb0157012af6ec3042949f2d6e2efb98c887dbad746dce0e79",
2917
+ "definition_digest": "e16fcb4fd574a25aa53d71a7cc808b28262c107e5f55f9ded3cd6e5a18ede9ea",
840
2918
  "audience": "agent",
841
- "description": "只读:按本草稿已存的资源回答当前需求有没有已提议的候选(落点、reaction、limits 与研究时一致),以及这些候选有没有绑定到给定的硬件选型 id 与 revision;宿主把结果映射成 workspace.lanes-next 的 artifacts",
2919
+ "description": "执行 Agent 的检索计划并保存证据:purpose=implementation 只凭需求检索实现资料(可与硬件选型并行),purpose=hardware 检索冻结选型修订(hardware_revision_ref)里采购件的厂商资料;Volc 检索(每次最多 5 条)与公开 HTTPS 页面安全直读,正文按 sha256 存证;每条付费检索先存 sent 再发送,重跑复用已完成检索、结果未知时要求对账而不重发;同一请求完成后重复运行直接返回已有结果",
842
2920
  "input_schema": {
843
- "title": "abelien.algorithm.lane-state.input.v1",
844
- "description": "只读:按本草稿已存的资源回答当前需求有没有已提议的候选,以及它们有没有绑定到给定的硬件选型。",
845
- "type": "object",
846
- "required": [
847
- "requirements"
848
- ],
849
- "properties": {
850
- "requirements": {
851
- "description": "clarify 整理后的需求(Requirements),原样传入;研究只看 context、reaction 与 limits",
852
- "type": "object",
853
- "required": [
854
- "reaction"
855
- ],
856
- "properties": {
857
- "context": {
858
- "type": "object",
859
- "properties": {
860
- "text": {
861
- "type": "string"
862
- },
863
- "source": {
864
- "enum": [
865
- "user",
866
- "system"
867
- ]
868
- }
869
- },
870
- "description": "使用场景"
871
- },
872
- "reaction": {
873
- "type": "array",
874
- "minItems": 1,
875
- "maxItems": 20,
876
- "items": {
877
- "type": "object",
878
- "required": [
879
- "id",
880
- "text"
881
- ],
882
- "properties": {
883
- "id": {
884
- "type": "string",
885
- "minLength": 1
886
- },
887
- "text": {
888
- "type": "string",
889
- "minLength": 1
890
- }
891
- }
892
- },
893
- "description": "触发→反应条目,1–20 条,id 不重复"
894
- },
895
- "limits": {
896
- "type": "array",
897
- "items": {
898
- "type": "object",
899
- "required": [
900
- "id"
901
- ],
902
- "properties": {
903
- "id": {
904
- "type": "string",
905
- "minLength": 1
906
- },
907
- "text": {
908
- "type": "string"
909
- },
910
- "strength": {
911
- "enum": [
912
- "hard",
913
- "preference"
914
- ]
915
- }
916
- }
917
- },
918
- "description": "约束;只有明确的 preference 不阻断"
919
- },
920
- "intent": {
921
- "type": "object"
922
- }
923
- }
924
- },
925
- "hardware_selection_id": {
926
- "oneOf": [
927
- {
928
- "type": "null"
929
- },
930
- {
931
- "type": "string",
932
- "pattern": "^hardware-selection:[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
933
- "description": "已存的硬件选型资源"
934
- }
935
- ],
936
- "description": "当前硬件选型;还没有时省略或为 null"
937
- },
938
- "hardware_selection_revision": {
939
- "type": "string",
940
- "minLength": 1,
941
- "description": "给出硬件选型时必填"
942
- }
943
- },
944
- "additionalProperties": false
945
- },
946
- "output_schema": {
947
- "title": "abelien.algorithm.lane-state.result.v1",
948
- "description": "车道状态;宿主把它映射成 workspace.lanes-next 的 artifacts。",
949
- "type": "object",
950
- "required": [
951
- "requirements_digest",
952
- "proposed_id",
953
- "selection_id",
954
- "selection_status"
955
- ],
956
- "properties": {
957
- "requirements_digest": {
958
- "type": "string",
959
- "minLength": 1,
960
- "description": "落点、reaction、limits 的规范化摘要"
961
- },
962
- "proposed_id": {
963
- "type": [
964
- "string",
965
- "null"
966
- ],
967
- "description": "同需求最新的已提议候选"
968
- },
969
- "selection_id": {
970
- "type": [
971
- "string",
972
- "null"
973
- ],
974
- "description": "这些候选绑定到给定硬件的选型结果"
975
- },
976
- "selection_status": {
977
- "type": [
978
- "string",
979
- "null"
980
- ],
981
- "description": "该绑定的状态"
982
- }
983
- }
984
- }
985
- },
986
- {
987
- "action_id": "algorithm.research",
988
- "contract_version": 1,
989
- "definition_digest": "2ef67d4c15ed3b06fb3772d7ec7ca83de4fb42b06ed740714e679f9bb08dc072",
990
- "audience": "agent",
991
- "description": "执行 Agent 的检索计划并保存证据:purpose=implementation 只凭需求检索实现资料(可与硬件选型并行),purpose=hardware 检索已选型号的厂商资料;Volc 检索(每次最多 5 条)与公开 HTTPS 页面安全直读,正文按 sha256 存证;每条付费检索先存 sent 再发送,重跑复用已完成检索、结果未知时要求对账而不重发;同一请求完成后重复运行直接返回已有结果",
992
- "input_schema": {
993
- "title": "abelien.algorithm.research.input.v1",
994
- "description": "算法研究的检索计划:implementation 只凭需求检索实现资料(可与硬件选型并行),hardware 检索已选型号的厂商资料。",
2921
+ "title": "abelien.algorithm.research.input.v1",
2922
+ "description": "算法研究的检索计划:implementation 只凭需求检索实现资料(可与硬件选型并行),hardware 检索已选型号的厂商资料。",
995
2923
  "type": "object",
996
2924
  "required": [
997
2925
  "purpose",
@@ -1070,10 +2998,17 @@
1070
2998
  "hard",
1071
2999
  "preference"
1072
3000
  ]
3001
+ },
3002
+ "network": {
3003
+ "description": "限制在联网上的含义(只在用户原话说明时填写,原话写进 text):offline 完全不联网也要能工作;no_cloud 可以连本地网络或手机,但数据不出设备、不调用云端服务。两者都意味着算法只能在端侧运行(hard 时由代码强制),差别留给硬件:只有 offline 说明不需要联网模块。",
3004
+ "enum": [
3005
+ "offline",
3006
+ "no_cloud"
3007
+ ]
1073
3008
  }
1074
3009
  }
1075
3010
  },
1076
- "description": "约束;只有明确的 preference 不阻断"
3011
+ "description": "约束;只有明确的 preference 不阻断;hard 限制带 network 时算法只能在端侧运行"
1077
3012
  },
1078
3013
  "intent": {
1079
3014
  "type": "object"
@@ -1109,15 +3044,32 @@
1109
3044
  }
1110
3045
  }
1111
3046
  },
1112
- "hardware_selection_id": {
1113
- "type": "string",
1114
- "pattern": "^hardware-selection:[A-Za-z0-9][A-Za-z0-9_-]{0,127}$",
1115
- "description": "仅 hardware:所查型号来自这份选型"
1116
- },
1117
- "hardware_selection_revision": {
1118
- "type": "string",
1119
- "minLength": 1,
1120
- "description": "仅 hardware:选型修订号,必须是当前修订"
3047
+ "hardware_revision_ref": {
3048
+ "description": "仅 hardware(且必填):所查型号来自这份冻结的选型修订;原样抄任务给的 hardware_revision_ref",
3049
+ "type": "object",
3050
+ "required": [
3051
+ "id",
3052
+ "version",
3053
+ "digest"
3054
+ ],
3055
+ "properties": {
3056
+ "id": {
3057
+ "description": "稳定标识符:字母或数字开头,可含 _ . : -,最长 128。与硬件选型、Studio 回执现有的标识符规则相同;不含 @(@ 留给 id@version 的写法)。",
3058
+ "type": "string",
3059
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"
3060
+ },
3061
+ "version": {
3062
+ "description": "对象版本号,按字符串比较相等,不比较大小(例如 \"7\"、\"r-1a2b3c4d5e6f\")。",
3063
+ "type": "string",
3064
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,63}$"
3065
+ },
3066
+ "digest": {
3067
+ "description": "sha256 小写十六进制(64 位,不带 sha256: 前缀)。对 JSON 值一律取 harness scripts/web/common.mjs 的 digest(),即对 canonical()(键排序、无空白)后的字节求 sha256。",
3068
+ "type": "string",
3069
+ "pattern": "^[0-9a-f]{64}$"
3070
+ }
3071
+ },
3072
+ "additionalProperties": false
1121
3073
  },
1122
3074
  "plan": {
1123
3075
  "type": "object",
@@ -1177,7 +3129,10 @@
1177
3129
  "id",
1178
3130
  "status",
1179
3131
  "schema",
1180
- "request_digest"
3132
+ "request_digest",
3133
+ "hardware",
3134
+ "pages",
3135
+ "limits"
1181
3136
  ],
1182
3137
  "properties": {
1183
3138
  "id": {
@@ -1216,10 +3171,270 @@
1216
3171
  "type": "object"
1217
3172
  }
1218
3173
  },
3174
+ "hardware": {
3175
+ "description": "purpose=hardware 研究所查的冻结修订:修订引用与它的采购件(algorithm.finalize 的 bind 按 revision_ref 判断这份厂商资料属于哪份硬件);implementation 研究与候选为 null",
3176
+ "oneOf": [
3177
+ {
3178
+ "type": "null"
3179
+ },
3180
+ {
3181
+ "type": "object",
3182
+ "required": [
3183
+ "revision_ref",
3184
+ "models"
3185
+ ],
3186
+ "properties": {
3187
+ "revision_ref": {
3188
+ "description": "本运行冻结的硬件选型修订(hardware 产物的 selectionRevisionRef,hardware-selection-v2 修订的不可变引用);按它读的是那份封存修订,不是可变的选型资源或谱系 head",
3189
+ "type": "object",
3190
+ "required": [
3191
+ "id",
3192
+ "version",
3193
+ "digest"
3194
+ ],
3195
+ "properties": {
3196
+ "id": {
3197
+ "description": "稳定标识符:字母或数字开头,可含 _ . : -,最长 128。与硬件选型、Studio 回执现有的标识符规则相同;不含 @(@ 留给 id@version 的写法)。",
3198
+ "type": "string",
3199
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"
3200
+ },
3201
+ "version": {
3202
+ "description": "对象版本号,按字符串比较相等,不比较大小(例如 \"7\"、\"r-1a2b3c4d5e6f\")。",
3203
+ "type": "string",
3204
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,63}$"
3205
+ },
3206
+ "digest": {
3207
+ "description": "sha256 小写十六进制(64 位,不带 sha256: 前缀)。对 JSON 值一律取 harness scripts/web/common.mjs 的 digest(),即对 canonical()(键排序、无空白)后的字节求 sha256。",
3208
+ "type": "string",
3209
+ "pattern": "^[0-9a-f]{64}$"
3210
+ }
3211
+ },
3212
+ "additionalProperties": false
3213
+ },
3214
+ "models": {
3215
+ "type": "array",
3216
+ "minItems": 1,
3217
+ "items": {
3218
+ "description": "冻结修订里一条采购件 BOM 行的身份(厂商资料检索与绑定只能指向这些 component_id)",
3219
+ "type": "object",
3220
+ "required": [
3221
+ "slot_id",
3222
+ "bom_item_id",
3223
+ "component_id",
3224
+ "manufacturer",
3225
+ "model"
3226
+ ],
3227
+ "properties": {
3228
+ "slot_id": {
3229
+ "type": "string",
3230
+ "minLength": 1
3231
+ },
3232
+ "bom_item_id": {
3233
+ "type": "string",
3234
+ "minLength": 1
3235
+ },
3236
+ "component_id": {
3237
+ "type": "string",
3238
+ "minLength": 1
3239
+ },
3240
+ "manufacturer": {
3241
+ "type": "string",
3242
+ "minLength": 1
3243
+ },
3244
+ "model": {
3245
+ "type": "string",
3246
+ "minLength": 1
3247
+ }
3248
+ },
3249
+ "additionalProperties": false
3250
+ }
3251
+ }
3252
+ },
3253
+ "additionalProperties": false
3254
+ }
3255
+ ]
3256
+ },
3257
+ "limits": {
3258
+ "type": "array",
3259
+ "items": {
3260
+ "description": "研究按 clarify 需求保存的一条限制(algorithm.candidates 按 strength 与 network 拒收非端侧候选)",
3261
+ "type": "object",
3262
+ "required": [
3263
+ "id",
3264
+ "text",
3265
+ "strength",
3266
+ "network"
3267
+ ],
3268
+ "properties": {
3269
+ "id": {
3270
+ "type": [
3271
+ "string",
3272
+ "null"
3273
+ ]
3274
+ },
3275
+ "text": {
3276
+ "type": [
3277
+ "string",
3278
+ "null"
3279
+ ]
3280
+ },
3281
+ "strength": {
3282
+ "enum": [
3283
+ "hard",
3284
+ "preference",
3285
+ null
3286
+ ]
3287
+ },
3288
+ "network": {
3289
+ "oneOf": [
3290
+ {
3291
+ "type": "null"
3292
+ },
3293
+ {
3294
+ "description": "限制在联网上的含义(只在用户原话说明时填写,原话写进 text):offline 完全不联网也要能工作;no_cloud 可以连本地网络或手机,但数据不出设备、不调用云端服务。两者都意味着算法只能在端侧运行(hard 时由代码强制),差别留给硬件:只有 offline 说明不需要联网模块。",
3295
+ "enum": [
3296
+ "offline",
3297
+ "no_cloud"
3298
+ ]
3299
+ }
3300
+ ]
3301
+ }
3302
+ },
3303
+ "additionalProperties": false
3304
+ }
3305
+ },
1219
3306
  "pages": {
1220
3307
  "type": "array",
1221
3308
  "items": {
1222
- "type": "object"
3309
+ "description": "研究读过的一页(algorithm.candidates 与 bind 按 id 取正文与回执)。status=read 时正文按 text_blob_ref 存证、text_sha256 是正文摘要;text_source=search_snippet 的只是检索摘要,只用于发现,bind 不认它作回执",
3310
+ "type": "object",
3311
+ "required": [
3312
+ "id",
3313
+ "url",
3314
+ "final_url",
3315
+ "search_id",
3316
+ "reaction_id",
3317
+ "component_id",
3318
+ "status",
3319
+ "reason",
3320
+ "title",
3321
+ "fetched_at",
3322
+ "text_blob_ref",
3323
+ "text_sha256",
3324
+ "text_source",
3325
+ "excerpt",
3326
+ "registry"
3327
+ ],
3328
+ "properties": {
3329
+ "id": {
3330
+ "type": "string",
3331
+ "pattern": "^p[0-9]{1,3}$"
3332
+ },
3333
+ "url": {
3334
+ "type": "string",
3335
+ "minLength": 1
3336
+ },
3337
+ "final_url": {
3338
+ "type": [
3339
+ "string",
3340
+ "null"
3341
+ ]
3342
+ },
3343
+ "search_id": {
3344
+ "type": "string",
3345
+ "minLength": 1
3346
+ },
3347
+ "reaction_id": {
3348
+ "type": [
3349
+ "string",
3350
+ "null"
3351
+ ]
3352
+ },
3353
+ "component_id": {
3354
+ "type": [
3355
+ "string",
3356
+ "null"
3357
+ ]
3358
+ },
3359
+ "status": {
3360
+ "enum": [
3361
+ "read",
3362
+ "unavailable"
3363
+ ]
3364
+ },
3365
+ "reason": {
3366
+ "type": [
3367
+ "string",
3368
+ "null"
3369
+ ]
3370
+ },
3371
+ "title": {
3372
+ "type": "string"
3373
+ },
3374
+ "fetched_at": {
3375
+ "type": [
3376
+ "string",
3377
+ "null"
3378
+ ]
3379
+ },
3380
+ "text_blob_ref": {
3381
+ "type": [
3382
+ "string",
3383
+ "null"
3384
+ ]
3385
+ },
3386
+ "text_sha256": {
3387
+ "type": [
3388
+ "string",
3389
+ "null"
3390
+ ]
3391
+ },
3392
+ "text_source": {
3393
+ "enum": [
3394
+ "page",
3395
+ "search_snippet",
3396
+ null
3397
+ ]
3398
+ },
3399
+ "excerpt": {
3400
+ "type": "string"
3401
+ },
3402
+ "registry": {
3403
+ "oneOf": [
3404
+ {
3405
+ "type": "null"
3406
+ },
3407
+ {
3408
+ "type": "object",
3409
+ "required": [
3410
+ "record_id",
3411
+ "version",
3412
+ "sha256",
3413
+ "hit"
3414
+ ],
3415
+ "properties": {
3416
+ "record_id": {
3417
+ "type": "string",
3418
+ "minLength": 1
3419
+ },
3420
+ "version": {
3421
+ "type": "integer",
3422
+ "minimum": 1
3423
+ },
3424
+ "sha256": {
3425
+ "type": "string",
3426
+ "pattern": "^[0-9a-f]{64}$"
3427
+ },
3428
+ "hit": {
3429
+ "type": "boolean"
3430
+ }
3431
+ },
3432
+ "additionalProperties": false
3433
+ }
3434
+ ]
3435
+ }
3436
+ },
3437
+ "additionalProperties": false
1223
3438
  },
1224
3439
  "description": "读取的页面:url、status、text_sha256 与正文 blob 引用"
1225
3440
  },