@mnstry/atelier 0.2.0-alpha.11 → 0.2.0-alpha.13

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 (560) hide show
  1. package/CHANGELOG.md +1005 -0
  2. package/README.md +149 -9
  3. package/contracts/atelier-adoption-policy.v2.schema.json +55 -0
  4. package/contracts/atelier-architecture.v1.schema.json +258 -0
  5. package/contracts/atelier-boundary-delegations.v1.schema.json +161 -0
  6. package/contracts/atelier-boundary-owner-keys.v1.schema.json +98 -0
  7. package/contracts/atelier-build.v1.schema.json +1076 -0
  8. package/contracts/atelier-capability.v1.schema.json +1252 -0
  9. package/contracts/atelier-coordination.v1.schema.json +1050 -0
  10. package/contracts/atelier-evidence-navigation.v1.schema.json +603 -0
  11. package/contracts/atelier-harness.v1.schema.json +234 -0
  12. package/contracts/atelier-ingestion.v1.schema.json +806 -0
  13. package/contracts/atelier-inquiry.v1.schema.json +1772 -0
  14. package/contracts/atelier-instruction-adoption.v1.schema.json +490 -0
  15. package/contracts/atelier-interaction.v1.schema.json +553 -0
  16. package/contracts/atelier-judgment.v1.schema.json +690 -0
  17. package/contracts/atelier-knowledge.v1.schema.json +1512 -0
  18. package/contracts/atelier-learning.v1.schema.json +1095 -0
  19. package/contracts/atelier-migration.v3.schema.json +64 -0
  20. package/contracts/atelier-obsidian-generation-manifest.v2.schema.json +372 -0
  21. package/contracts/atelier-personal-workspace-manifest.v1.schema.json +87 -0
  22. package/contracts/atelier-personal-workspace-overlay.v1.schema.json +299 -0
  23. package/contracts/atelier-template-adoption.v1.schema.json +223 -0
  24. package/contracts/atelier-template-profile.v1.schema.json +1168 -0
  25. package/contracts/atelier-trackable.v1.schema.json +781 -0
  26. package/contracts/atelier-upgrade-plan.v3.schema.json +532 -0
  27. package/contracts/compat-baseline.json +1 -1
  28. package/docs/architecture.md +89 -0
  29. package/docs/assurance-controls.md +4 -3
  30. package/docs/blocks/capability-stewardship.md +17 -0
  31. package/docs/blocks/claims.md +16 -3
  32. package/docs/blocks/inquiry-harnesses.md +19 -0
  33. package/docs/blocks/learning-harnesses.md +17 -0
  34. package/docs/capability-stewardship.md +269 -0
  35. package/docs/coordination.md +51 -0
  36. package/docs/decision-practices.md +111 -0
  37. package/docs/decisions.md +29 -0
  38. package/docs/evidence-navigation.md +237 -0
  39. package/docs/exact-upgrades.md +3 -2
  40. package/docs/ingestion.md +181 -0
  41. package/docs/inquiry-harnesses.md +211 -0
  42. package/docs/install.md +80 -3
  43. package/docs/intake-and-guides.md +5 -0
  44. package/docs/integration-contract-decisions.md +24 -2
  45. package/docs/interaction-and-reflection.md +72 -0
  46. package/docs/knowledge-graph.md +20 -0
  47. package/docs/knowledge-health/api.md +30 -0
  48. package/docs/knowledge-health/assessment/api.md +96 -0
  49. package/docs/knowledge-health/assessment/capabilities.md +40 -0
  50. package/docs/knowledge-health/assessment/evaluation.md +27 -0
  51. package/docs/knowledge-health/assessment/facilitator.md +30 -0
  52. package/docs/knowledge-health/assessment/quickstart.md +61 -0
  53. package/docs/knowledge-health/assessment/troubleshooting.md +23 -0
  54. package/docs/knowledge-health/devday/facilitator.md +16 -0
  55. package/docs/knowledge-health/devday/participant-response.md +22 -0
  56. package/docs/knowledge-health/devday/public-default.md +107 -0
  57. package/docs/knowledge-health/devday/quickstart.md +18 -0
  58. package/docs/knowledge-health/devday/support.md +22 -0
  59. package/docs/knowledge-health/exercise.md +17 -0
  60. package/docs/knowledge-health/facilitator.md +20 -0
  61. package/docs/knowledge-health/quickstart.md +94 -0
  62. package/docs/knowledge-health/readme.md +15 -0
  63. package/docs/knowledge-health/support.md +34 -0
  64. package/docs/knowledge-setup.md +248 -0
  65. package/docs/knowledge-workspace.md +264 -0
  66. package/docs/learning-harnesses.md +238 -0
  67. package/docs/learning.md +215 -0
  68. package/docs/local-services.md +242 -26
  69. package/docs/obsidian-contract.md +878 -36
  70. package/docs/obsidian-plugin.md +619 -0
  71. package/docs/obsidian.md +809 -64
  72. package/docs/optional-ingestion.md +83 -0
  73. package/docs/personal-workspace.md +257 -0
  74. package/docs/practical-judgment.md +92 -0
  75. package/docs/progressive-ingestion-acceptance.md +89 -0
  76. package/docs/progressive-ingestion.md +235 -0
  77. package/docs/project-command-inventory.md +1 -0
  78. package/docs/release-engineering.md +56 -1
  79. package/docs/repo-boundary-guard.md +94 -0
  80. package/docs/research-starter-quickstart.md +66 -0
  81. package/docs/research-starter.md +114 -0
  82. package/docs/semantic-ingestion.md +198 -0
  83. package/docs/semantic-operation.md +317 -0
  84. package/docs/skill-steward.md +6 -0
  85. package/docs/template-profile.md +164 -0
  86. package/docs/template-upgrades.md +114 -0
  87. package/docs/trackables.md +111 -0
  88. package/docs/upgrade.md +68 -3
  89. package/fixtures/atelier-architecture/binding/invalid/document.json +19 -0
  90. package/fixtures/atelier-architecture/binding/valid/document.json +19 -0
  91. package/fixtures/atelier-architecture/catalog/invalid/document.json +290 -0
  92. package/fixtures/atelier-architecture/catalog/valid/document.json +343 -0
  93. package/fixtures/atelier-build-contract/attempt/invalid/document.json +20 -0
  94. package/fixtures/atelier-build-contract/attempt/valid/document.json +19 -0
  95. package/fixtures/atelier-build-contract/candidate/invalid/document.json +24 -0
  96. package/fixtures/atelier-build-contract/candidate/valid/document.json +23 -0
  97. package/fixtures/atelier-build-contract/decision/invalid/document.json +31 -0
  98. package/fixtures/atelier-build-contract/decision/valid/document.json +30 -0
  99. package/fixtures/atelier-build-contract/delivery/invalid/document.json +18 -0
  100. package/fixtures/atelier-build-contract/delivery/valid/document.json +17 -0
  101. package/fixtures/atelier-build-contract/gate/invalid/document.json +22 -0
  102. package/fixtures/atelier-build-contract/gate/valid/document.json +21 -0
  103. package/fixtures/atelier-build-contract/ledger/invalid/document.json +270 -0
  104. package/fixtures/atelier-build-contract/ledger/valid/document.json +269 -0
  105. package/fixtures/atelier-build-contract/objective/invalid/document.json +73 -0
  106. package/fixtures/atelier-build-contract/objective/valid/document.json +72 -0
  107. package/fixtures/atelier-build-contract/progress/invalid/document.json +18 -0
  108. package/fixtures/atelier-build-contract/progress/valid/document.json +17 -0
  109. package/fixtures/atelier-capability-contract/adoption/invalid/document.json +71 -0
  110. package/fixtures/atelier-capability-contract/adoption/valid/document.json +70 -0
  111. package/fixtures/atelier-capability-contract/event/invalid/document.json +18 -0
  112. package/fixtures/atelier-capability-contract/event/valid/document.json +17 -0
  113. package/fixtures/atelier-capability-contract/journal/invalid/document.json +382 -0
  114. package/fixtures/atelier-capability-contract/journal/valid/document.json +381 -0
  115. package/fixtures/atelier-capability-contract/notice/invalid/document.json +8 -0
  116. package/fixtures/atelier-capability-contract/notice/valid/document.json +7 -0
  117. package/fixtures/atelier-capability-contract/package/invalid/document.json +59 -0
  118. package/fixtures/atelier-capability-contract/package/valid/document.json +58 -0
  119. package/fixtures/atelier-capability-contract/plan/invalid/document.json +107 -0
  120. package/fixtures/atelier-capability-contract/plan/valid/document.json +106 -0
  121. package/fixtures/atelier-capability-contract/release/invalid/document.json +85 -0
  122. package/fixtures/atelier-capability-contract/release/valid/document.json +84 -0
  123. package/fixtures/atelier-capability-contract/state/invalid/document.json +316 -0
  124. package/fixtures/atelier-capability-contract/state/valid/document.json +315 -0
  125. package/fixtures/atelier-coordination/dependency/invalid/document.json +37 -0
  126. package/fixtures/atelier-coordination/dependency/valid/document.json +36 -0
  127. package/fixtures/atelier-coordination/directive/invalid/document.json +25 -0
  128. package/fixtures/atelier-coordination/directive/valid/document.json +24 -0
  129. package/fixtures/atelier-coordination/disposition/invalid/document.json +34 -0
  130. package/fixtures/atelier-coordination/disposition/valid/document.json +33 -0
  131. package/fixtures/atelier-coordination/outcome/invalid/document.json +39 -0
  132. package/fixtures/atelier-coordination/outcome/valid/document.json +38 -0
  133. package/fixtures/atelier-coordination/recovery/invalid/document.json +34 -0
  134. package/fixtures/atelier-coordination/recovery/valid/document.json +33 -0
  135. package/fixtures/atelier-harness-contract/handoff/invalid/document.json +25 -0
  136. package/fixtures/atelier-harness-contract/handoff/valid/document.json +24 -0
  137. package/fixtures/atelier-ingestion/invalid/authority.json +19 -0
  138. package/fixtures/atelier-ingestion/semantic-baseline.json +26 -0
  139. package/fixtures/atelier-ingestion/semantic-operation.json +75 -0
  140. package/fixtures/atelier-ingestion/valid/plan-input.json +18 -0
  141. package/fixtures/atelier-inquiry-contract/assessment/invalid/document.json +41 -0
  142. package/fixtures/atelier-inquiry-contract/assessment/valid/document.json +40 -0
  143. package/fixtures/atelier-inquiry-contract/bundle/invalid/document.json +51 -0
  144. package/fixtures/atelier-inquiry-contract/bundle/valid/document.json +50 -0
  145. package/fixtures/atelier-inquiry-contract/campaign/invalid/document.json +17 -0
  146. package/fixtures/atelier-inquiry-contract/campaign/valid/document.json +16 -0
  147. package/fixtures/atelier-inquiry-contract/decision/invalid/document.json +22 -0
  148. package/fixtures/atelier-inquiry-contract/decision/valid/document.json +21 -0
  149. package/fixtures/atelier-inquiry-contract/feedback/invalid/document.json +19 -0
  150. package/fixtures/atelier-inquiry-contract/feedback/valid/document.json +18 -0
  151. package/fixtures/atelier-inquiry-contract/handoff/invalid/document.json +92 -0
  152. package/fixtures/atelier-inquiry-contract/handoff/valid/document.json +91 -0
  153. package/fixtures/atelier-inquiry-contract/hypothesis/invalid/document.json +20 -0
  154. package/fixtures/atelier-inquiry-contract/hypothesis/valid/document.json +19 -0
  155. package/fixtures/atelier-inquiry-contract/ledger/invalid/document.json +680 -0
  156. package/fixtures/atelier-inquiry-contract/ledger/valid/document.json +679 -0
  157. package/fixtures/atelier-inquiry-contract/legacy-assessment/invalid/document.json +19 -0
  158. package/fixtures/atelier-inquiry-contract/legacy-assessment/valid/document.json +18 -0
  159. package/fixtures/atelier-inquiry-contract/request/invalid/document.json +50 -0
  160. package/fixtures/atelier-inquiry-contract/request/valid/document.json +49 -0
  161. package/fixtures/atelier-inquiry-contract/source/invalid/document.json +18 -0
  162. package/fixtures/atelier-inquiry-contract/source/valid/document.json +17 -0
  163. package/fixtures/atelier-inquiry-contract/withdrawal/invalid/document.json +16 -0
  164. package/fixtures/atelier-inquiry-contract/withdrawal/valid/document.json +15 -0
  165. package/fixtures/atelier-instruction-adoption/context-receipt/invalid/document.json +18 -0
  166. package/fixtures/atelier-instruction-adoption/context-receipt/valid/document.json +17 -0
  167. package/fixtures/atelier-instruction-adoption/plan/invalid/document.json +63 -0
  168. package/fixtures/atelier-instruction-adoption/plan/valid/document.json +62 -0
  169. package/fixtures/atelier-instruction-adoption/receipt/invalid/document.json +22 -0
  170. package/fixtures/atelier-instruction-adoption/receipt/valid/document.json +21 -0
  171. package/fixtures/atelier-instruction-adoption/state/invalid/document.json +30 -0
  172. package/fixtures/atelier-instruction-adoption/state/valid/document.json +29 -0
  173. package/fixtures/atelier-interaction/act/invalid/document.json +25 -0
  174. package/fixtures/atelier-interaction/act/valid/document.json +24 -0
  175. package/fixtures/atelier-interaction/assessment/invalid/document.json +32 -0
  176. package/fixtures/atelier-interaction/assessment/valid/document.json +31 -0
  177. package/fixtures/atelier-interaction/observation/invalid/document.json +22 -0
  178. package/fixtures/atelier-interaction/observation/valid/document.json +21 -0
  179. package/fixtures/atelier-interaction/policy/invalid/document.json +20 -0
  180. package/fixtures/atelier-interaction/policy/valid/document.json +19 -0
  181. package/fixtures/atelier-judgment/case/invalid/document.json +76 -0
  182. package/fixtures/atelier-judgment/case/valid/document.json +75 -0
  183. package/fixtures/atelier-judgment/decision/invalid/document.json +38 -0
  184. package/fixtures/atelier-judgment/decision/valid/document.json +37 -0
  185. package/fixtures/atelier-judgment/native-decision.md +3 -0
  186. package/fixtures/atelier-judgment/practice-reconsideration/definition.json +92 -0
  187. package/fixtures/atelier-judgment/practice-reconsideration/scenario.json +435 -0
  188. package/fixtures/atelier-knowledge-contract/activation/invalid/document.json +26 -0
  189. package/fixtures/atelier-knowledge-contract/activation/valid/document.json +25 -0
  190. package/fixtures/atelier-knowledge-contract/contribution/invalid/document.json +34 -0
  191. package/fixtures/atelier-knowledge-contract/contribution/valid/document.json +33 -0
  192. package/fixtures/atelier-knowledge-contract/domain/invalid/document.json +41 -0
  193. package/fixtures/atelier-knowledge-contract/domain/valid/document.json +40 -0
  194. package/fixtures/atelier-knowledge-contract/domain-revision/invalid/document.json +46 -0
  195. package/fixtures/atelier-knowledge-contract/domain-revision/valid/document.json +45 -0
  196. package/fixtures/atelier-knowledge-contract/evaluation/invalid/document.json +21 -0
  197. package/fixtures/atelier-knowledge-contract/evaluation/valid/document.json +20 -0
  198. package/fixtures/atelier-knowledge-contract/ledger/invalid/document.json +318 -0
  199. package/fixtures/atelier-knowledge-contract/ledger/valid/document.json +317 -0
  200. package/fixtures/atelier-knowledge-contract/relation/invalid/document.json +25 -0
  201. package/fixtures/atelier-knowledge-contract/relation/valid/document.json +24 -0
  202. package/fixtures/atelier-knowledge-contract/review/invalid/document.json +18 -0
  203. package/fixtures/atelier-knowledge-contract/review/valid/document.json +17 -0
  204. package/fixtures/atelier-knowledge-contract/withdrawal/invalid/document.json +16 -0
  205. package/fixtures/atelier-knowledge-contract/withdrawal/valid/document.json +15 -0
  206. package/fixtures/atelier-learning/invalid/authority.json +14 -0
  207. package/fixtures/atelier-learning/valid/capture.json +13 -0
  208. package/fixtures/atelier-personal-workspace-contract/manifest/invalid/authority-key.json +17 -0
  209. package/fixtures/atelier-personal-workspace-contract/manifest/invalid/nonempty-ext.json +25 -0
  210. package/fixtures/atelier-personal-workspace-contract/manifest/invalid/wrong-schema.json +22 -0
  211. package/fixtures/atelier-personal-workspace-contract/manifest/valid/manifest.json +22 -0
  212. package/fixtures/atelier-personal-workspace-contract/overlay/invalid/authority-key.json +25 -0
  213. package/fixtures/atelier-personal-workspace-contract/overlay/invalid/unknown-top-level-field.json +27 -0
  214. package/fixtures/atelier-personal-workspace-contract/overlay/invalid/wrong-schema.json +24 -0
  215. package/fixtures/atelier-trackable/definition/invalid/document.json +15 -0
  216. package/fixtures/atelier-trackable/definition/valid/document.json +14 -0
  217. package/fixtures/atelier-trackable/request/invalid/document.json +23 -0
  218. package/fixtures/atelier-trackable/request/valid/document.json +22 -0
  219. package/fixtures/boundary-delegations/invalid/authority-key.v1.json +30 -0
  220. package/fixtures/boundary-delegations/invalid/push-operation.v1.json +28 -0
  221. package/fixtures/boundary-delegations/invalid/unsigned.v1.json +25 -0
  222. package/fixtures/boundary-delegations/valid/empty.v1.json +4 -0
  223. package/fixtures/boundary-delegations/valid/signed-operator.v1.json +30 -0
  224. package/fixtures/boundary-owner-keys/invalid/wrong-algorithm.v1.json +15 -0
  225. package/fixtures/boundary-owner-keys/invalid/wrong-curve.v1.json +15 -0
  226. package/fixtures/boundary-owner-keys/valid/one-owner.v1.json +17 -0
  227. package/fixtures/capability-packages/adoption.example.json +70 -0
  228. package/fixtures/capability-packages/evidence-review/capability-package.json +58 -0
  229. package/fixtures/capability-packages/evidence-review/capability-release.json +84 -0
  230. package/fixtures/capability-packages/evidence-review/evaluation.md +15 -0
  231. package/fixtures/capability-packages/evidence-review/skills/evidence-review/SKILL.md +22 -0
  232. package/fixtures/capability-packages/evidence-review/skills/evidence-review/references/ledger.md +7 -0
  233. package/fixtures/capability-packages/research/capability-package.json +88 -0
  234. package/fixtures/capability-packages/research/capability-release.json +134 -0
  235. package/fixtures/capability-packages/research/evaluation.md +15 -0
  236. package/fixtures/capability-packages/research/skills/research-integrate/SKILL.md +29 -0
  237. package/fixtures/capability-packages/research/skills/research-integrate/references/integration.md +10 -0
  238. package/fixtures/capability-packages/research/skills/research-plan/SKILL.md +27 -0
  239. package/fixtures/capability-packages/research/skills/research-plan/references/inquiries.md +26 -0
  240. package/fixtures/capability-packages/research/skills/research-synthesize/SKILL.md +23 -0
  241. package/fixtures/capability-packages/research/skills/research-synthesize/references/synthesis.md +12 -0
  242. package/fixtures/evidence-navigation/invalid/duplicate-operation.json +16 -0
  243. package/fixtures/evidence-navigation/invalid/instruction-kind.json +36 -0
  244. package/fixtures/evidence-navigation/invalid/invalid-digest.json +36 -0
  245. package/fixtures/evidence-navigation/invalid/invalid-time.json +36 -0
  246. package/fixtures/evidence-navigation/invalid/missing-attribution.json +35 -0
  247. package/fixtures/evidence-navigation/invalid/reserved-extension.json +19 -0
  248. package/fixtures/evidence-navigation/invalid/unattributed-acceptance.json +36 -0
  249. package/fixtures/evidence-navigation/invalid/uncoerced-version.json +16 -0
  250. package/fixtures/evidence-navigation/invalid/unknown-currency.json +17 -0
  251. package/fixtures/evidence-navigation/invalid/unknown-selector-field.json +37 -0
  252. package/fixtures/evidence-navigation/invalid/unsupported-operation.json +15 -0
  253. package/fixtures/evidence-navigation/valid/claim.json +36 -0
  254. package/fixtures/evidence-navigation/valid/host.json +16 -0
  255. package/fixtures/evidence-navigation/valid/profile.json +16 -0
  256. package/fixtures/evidence-navigation/valid/snapshot.json +17 -0
  257. package/fixtures/harness-packages/build-harness/capability-package.json +61 -0
  258. package/fixtures/harness-packages/build-harness/capability-release.json +82 -0
  259. package/fixtures/harness-packages/build-harness/evaluation.md +3 -0
  260. package/fixtures/harness-packages/build-harness/skills/atelier-build-harness/SKILL.md +59 -0
  261. package/fixtures/harness-packages/knowledge-harness/capability-package.json +61 -0
  262. package/fixtures/harness-packages/knowledge-harness/capability-release.json +82 -0
  263. package/fixtures/harness-packages/knowledge-harness/evaluation.md +3 -0
  264. package/fixtures/harness-packages/knowledge-harness/skills/atelier-knowledge-harness/SKILL.md +60 -0
  265. package/fixtures/harnesses/learning-cycle.json +780 -0
  266. package/fixtures/inquiry/workshop.json +675 -0
  267. package/fixtures/inquiry-packages/discovery-harness/capability-package.json +61 -0
  268. package/fixtures/inquiry-packages/discovery-harness/capability-release.json +82 -0
  269. package/fixtures/inquiry-packages/discovery-harness/evaluation.md +3 -0
  270. package/fixtures/inquiry-packages/discovery-harness/skills/atelier-discovery-harness/SKILL.md +48 -0
  271. package/fixtures/inquiry-packages/research-harness/capability-package.json +61 -0
  272. package/fixtures/inquiry-packages/research-harness/capability-release.json +82 -0
  273. package/fixtures/inquiry-packages/research-harness/evaluation.md +3 -0
  274. package/fixtures/inquiry-packages/research-harness/skills/atelier-research-harness/SKILL.md +43 -0
  275. package/fixtures/knowledge-health/calibration-suite.json +26 -0
  276. package/fixtures/knowledge-health/calibration-trial.json +37 -0
  277. package/fixtures/knowledge-health/corrected/checklist.md +18 -0
  278. package/fixtures/knowledge-health/devday/participant-record.json +19 -0
  279. package/fixtures/knowledge-health/expected-summary.json +27 -0
  280. package/fixtures/knowledge-health/workshop/README.md +20 -0
  281. package/fixtures/knowledge-health/workshop/atelier.project.json +7 -0
  282. package/fixtures/knowledge-health/workshop/knowledge-plan.json +65 -0
  283. package/fixtures/knowledge-health/workshop/records/checklist.md +18 -0
  284. package/fixtures/knowledge-health/workshop/records/workshop.md +18 -0
  285. package/fixtures/knowledge-health/workshop/repo-access.v1.json +5 -0
  286. package/fixtures/knowledge-health/workspace/atelier.project.json +18 -0
  287. package/fixtures/knowledge-health/workspace/knowledge-plan.json +74 -0
  288. package/fixtures/knowledge-health/workspace/records/checklist.md +18 -0
  289. package/fixtures/knowledge-health/workspace/records/pilot.md +16 -0
  290. package/fixtures/knowledge-health/workspace/repo-access.v1.json +9 -0
  291. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/case-only-collision.v2.json +160 -0
  292. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/flat-note-path.v2.json +160 -0
  293. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/hidden-folder.v2.json +160 -0
  294. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/identity-in-the-body.v2.json +160 -0
  295. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/link-breaking-name.v2.json +160 -0
  296. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/missing-identity-region.v2.json +156 -0
  297. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/missing-layout-version.v2.json +159 -0
  298. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/note-named-like-a-folder.v2.json +160 -0
  299. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/unknown-region-kind.v2.json +160 -0
  300. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/v1-contract-version.v2.json +161 -0
  301. package/fixtures/obsidian/contracts/generation-manifest-v2/valid/three-notes.v2.json +160 -0
  302. package/fixtures/obsidian/edits/workspace.json +1 -1
  303. package/fixtures/obsidian/materialization/expected-full.json +21 -21
  304. package/fixtures/obsidian/materialization/expected-full.layout-1.json +99 -0
  305. package/fixtures/obsidian/materialization/expected-scoped.json +7 -7
  306. package/fixtures/obsidian/materialization/expected-scoped.layout-1.json +39 -0
  307. package/fixtures/personal-workspace/overlay.json +24 -0
  308. package/fixtures/templates/local-library.v1.json +75 -0
  309. package/fixtures/templates/upgrade-contracts/adoption-policy.v2/invalid.json +16 -0
  310. package/fixtures/templates/upgrade-contracts/adoption-policy.v2/valid.json +13 -0
  311. package/fixtures/templates/upgrade-contracts/migration.v3/invalid.json +24 -0
  312. package/fixtures/templates/upgrade-contracts/migration.v3/valid.json +21 -0
  313. package/fixtures/templates/upgrade-contracts/template-adoption.v1/invalid.json +60 -0
  314. package/fixtures/templates/upgrade-contracts/template-adoption.v1/valid.json +57 -0
  315. package/fixtures/templates/upgrade-contracts/upgrade-plan.v3/invalid.json +85 -0
  316. package/fixtures/templates/upgrade-contracts/upgrade-plan.v3/valid.json +82 -0
  317. package/package.json +64 -6
  318. package/plugins/obsidian/main.js +444 -0
  319. package/plugins/obsidian/manifest.json +9 -0
  320. package/plugins/obsidian/styles.css +22 -0
  321. package/skills/claude/atelier-build-harness/SKILL.md +59 -0
  322. package/skills/claude/atelier-coordination/SKILL.md +32 -0
  323. package/skills/claude/atelier-discovery-harness/SKILL.md +48 -0
  324. package/skills/claude/atelier-guided-upgrade/SKILL.md +29 -0
  325. package/skills/claude/atelier-interaction/SKILL.md +34 -0
  326. package/skills/claude/atelier-knowledge-harness/SKILL.md +60 -0
  327. package/skills/claude/atelier-knowledge-setup/SKILL.md +72 -0
  328. package/skills/claude/atelier-practical-judgment/SKILL.md +64 -0
  329. package/skills/claude/atelier-research-harness/SKILL.md +43 -0
  330. package/skills/claude/atelier-skill-steward/SKILL.md +53 -0
  331. package/skills/claude/atelier-trackables/SKILL.md +40 -0
  332. package/skills/codex/atelier-build-harness/SKILL.md +59 -0
  333. package/skills/codex/atelier-coordination/SKILL.md +32 -0
  334. package/skills/codex/atelier-discovery-harness/SKILL.md +48 -0
  335. package/skills/codex/atelier-guided-upgrade/SKILL.md +29 -0
  336. package/skills/codex/atelier-interaction/SKILL.md +34 -0
  337. package/skills/codex/atelier-knowledge-harness/SKILL.md +60 -0
  338. package/skills/codex/atelier-knowledge-setup/SKILL.md +72 -0
  339. package/skills/codex/atelier-practical-judgment/SKILL.md +64 -0
  340. package/skills/codex/atelier-research-harness/SKILL.md +43 -0
  341. package/skills/codex/atelier-skill-steward/SKILL.md +53 -0
  342. package/skills/codex/atelier-trackables/SKILL.md +40 -0
  343. package/src/architecture/catalog.mjs +355 -0
  344. package/src/architecture/index.mjs +93 -0
  345. package/src/boundary/content-rules.mjs +4 -2
  346. package/src/boundary/delegation-command.mjs +158 -0
  347. package/src/boundary/delegation.mjs +396 -0
  348. package/src/boundary/policy.mjs +52 -10
  349. package/src/build/git.mjs +18 -0
  350. package/src/build/index.mjs +3 -0
  351. package/src/build/ledger.mjs +88 -0
  352. package/src/capabilities/adoption.mjs +381 -0
  353. package/src/capabilities/evidence.mjs +140 -0
  354. package/src/capabilities/files.mjs +124 -0
  355. package/src/capabilities/index.mjs +4 -0
  356. package/src/capabilities/instructions.mjs +250 -0
  357. package/src/capabilities/package.mjs +136 -0
  358. package/src/cli/command-failure.mjs +36 -0
  359. package/src/cli/execute-command.mjs +16 -2
  360. package/src/cli/run.mjs +65 -9
  361. package/src/coauthor/store.mjs +43 -2
  362. package/src/collaboration/proposals.mjs +189 -0
  363. package/src/commands/architecture.mjs +27 -0
  364. package/src/commands/boundary.mjs +3 -0
  365. package/src/commands/capability.mjs +73 -0
  366. package/src/commands/enroll.mjs +3 -0
  367. package/src/commands/harness.mjs +79 -0
  368. package/src/commands/ingest.mjs +39 -0
  369. package/src/commands/init.mjs +4 -1
  370. package/src/commands/inquiry.mjs +66 -0
  371. package/src/commands/knowledge-semantic.mjs +128 -0
  372. package/src/commands/knowledge.mjs +119 -0
  373. package/src/commands/learn.mjs +61 -0
  374. package/src/commands/obsidian.mjs +832 -62
  375. package/src/commands/practice.mjs +24 -0
  376. package/src/commands/setup.mjs +22 -2
  377. package/src/commands/trackable.mjs +19 -0
  378. package/src/contracts/corpus.mjs +36 -0
  379. package/src/coordination/index.mjs +110 -0
  380. package/src/egress/forbidden-egress.mjs +2 -0
  381. package/src/evidence-navigation/contracts.mjs +60 -0
  382. package/src/evidence-navigation/evaluate.mjs +69 -0
  383. package/src/evidence-navigation/generation.mjs +22 -0
  384. package/src/evidence-navigation/index.mjs +2 -0
  385. package/src/evidence-navigation/local.mjs +167 -0
  386. package/src/evidence-navigation/schema.generated.mjs +604 -0
  387. package/src/evidence-navigation/types.mjs +12 -0
  388. package/src/export/atelier-export-contract.mjs +35 -8
  389. package/src/graph/enroll.mjs +248 -0
  390. package/src/graph/graph.mjs +17 -1
  391. package/src/graph/knowledge-graph.mjs +58 -8
  392. package/src/harnesses/contracts.mjs +41 -0
  393. package/src/harnesses/exchange.mjs +154 -0
  394. package/src/harnesses/feedback.mjs +16 -0
  395. package/src/harnesses/history.mjs +37 -0
  396. package/src/harnesses/index.mjs +4 -0
  397. package/src/harnesses/store.mjs +29 -0
  398. package/src/ingestion/contracts.mjs +41 -0
  399. package/src/ingestion/evaluation.mjs +119 -0
  400. package/src/ingestion/optional/composition/index.mjs +171 -0
  401. package/src/ingestion/optional/evaluation/index.mjs +219 -0
  402. package/src/ingestion/optional/graphify/composition-binding.mjs +60 -0
  403. package/src/ingestion/optional/graphify/composition_receiving.py +185 -0
  404. package/src/ingestion/optional/graphify/graphify_supplier.py +933 -0
  405. package/src/ingestion/optional/graphify/json_bridge.py +163 -0
  406. package/src/ingestion/optional/graphify/query_receiving.py +209 -0
  407. package/src/ingestion/optional/index.mjs +9 -0
  408. package/src/ingestion/optional/jev/bridge.mjs +166 -0
  409. package/src/ingestion/optional/jev/composition-binding.mjs +116 -0
  410. package/src/ingestion/optional/jev/judgments.mjs +174 -0
  411. package/src/ingestion/optional/jev/native-translation.mjs +32 -0
  412. package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/__init__.py +7 -0
  413. package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/adapter.py +966 -0
  414. package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/artifacts.py +101 -0
  415. package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/projection.py +146 -0
  416. package/src/ingestion/optional/lightrag/composition-binding.mjs +67 -0
  417. package/src/ingestion/optional/vanilla/composition-binding.mjs +102 -0
  418. package/src/ingestion/optional/vanilla/index.mjs +218 -0
  419. package/src/ingestion/optional/vanilla/native-normalization.mjs +187 -0
  420. package/src/ingestion/processors.mjs +218 -0
  421. package/src/ingestion/semantic.mjs +203 -0
  422. package/src/ingestion/store.mjs +372 -0
  423. package/src/inquiry/beliefs.mjs +32 -0
  424. package/src/inquiry/contracts.mjs +23 -0
  425. package/src/inquiry/index.mjs +5 -0
  426. package/src/inquiry/ledger.mjs +135 -0
  427. package/src/inquiry/lenses.mjs +15 -0
  428. package/src/inquiry/projection.mjs +77 -0
  429. package/src/inquiry/store.mjs +35 -0
  430. package/src/intake/read-scope.mjs +12 -0
  431. package/src/intake/store.mjs +69 -6
  432. package/src/interaction/index.mjs +91 -0
  433. package/src/judgment/index.mjs +82 -0
  434. package/src/judgment/practice-evaluation.mjs +70 -0
  435. package/src/judgment/practice.mjs +144 -0
  436. package/src/knowledge/context.mjs +217 -0
  437. package/src/knowledge/index.mjs +5 -0
  438. package/src/knowledge/ingestion.mjs +79 -0
  439. package/src/knowledge/intake.mjs +33 -0
  440. package/src/knowledge/ledger.mjs +110 -0
  441. package/src/knowledge/participatory/guidance.mjs +36 -0
  442. package/src/knowledge/participatory/guided-contribution.mjs +44 -0
  443. package/src/knowledge/participatory/index.mjs +2 -0
  444. package/src/knowledge/participatory/installed-workshop.mjs +108 -0
  445. package/src/knowledge/plan.mjs +67 -0
  446. package/src/knowledge/projection.mjs +43 -0
  447. package/src/knowledge/semantic-operation.mjs +567 -0
  448. package/src/knowledge/sessions.mjs +467 -0
  449. package/src/knowledge/workspace.mjs +295 -0
  450. package/src/knowledge-health/assessment.mjs +165 -0
  451. package/src/knowledge-health/capabilities.mjs +350 -0
  452. package/src/knowledge-health/context.mjs +62 -0
  453. package/src/knowledge-health/example.mjs +47 -0
  454. package/src/knowledge-health/index.mjs +10 -0
  455. package/src/knowledge-health/owner-join.mjs +88 -0
  456. package/src/knowledge-health/proof/common.mjs +24 -0
  457. package/src/knowledge-health/proof/installed-check.mjs +100 -0
  458. package/src/knowledge-health/proof/native-readback.mjs +37 -0
  459. package/src/knowledge-health/proof/rehearse.mjs +68 -0
  460. package/src/knowledge-health/proof/validate-participant.mjs +17 -0
  461. package/src/knowledge-health/proof/verify-native-capture.mjs +14 -0
  462. package/src/knowledge-health/proof/workshop-check.mjs +36 -0
  463. package/src/knowledge-health/rule-identity.mjs +44 -0
  464. package/src/knowledge-health/workshop-composition.mjs +19 -0
  465. package/src/knowledge-health/workshop-profile.mjs +176 -0
  466. package/src/knowledge-health/workshop.mjs +99 -0
  467. package/src/learning/adapters.mjs +68 -0
  468. package/src/learning/assistance.mjs +127 -0
  469. package/src/learning/contracts.mjs +65 -0
  470. package/src/learning/store.mjs +272 -0
  471. package/src/personal-workspace/index.mjs +391 -0
  472. package/src/personal-workspace/selection.mjs +385 -0
  473. package/src/project/config.mjs +8 -0
  474. package/src/project/durable-state.mjs +3 -1
  475. package/src/project/file-class.mjs +1 -1
  476. package/src/project/private-state.mjs +10 -1
  477. package/src/projection/obsidian/contracts.mjs +224 -18
  478. package/src/projection/obsidian/edits/apply.mjs +63 -19
  479. package/src/projection/obsidian/edits/regions.mjs +137 -42
  480. package/src/projection/obsidian/materialize/index.mjs +6 -3
  481. package/src/projection/obsidian/materialize/path-registry.mjs +443 -57
  482. package/src/projection/obsidian/materialize/prepare-view.mjs +382 -131
  483. package/src/projection/obsidian/materialize/redaction.mjs +327 -0
  484. package/src/projection/obsidian/materialize/settings.mjs +113 -34
  485. package/src/projection/obsidian/personal-workspace.mjs +436 -0
  486. package/src/projection/obsidian/plugin-bridge/bundle.mjs +50 -0
  487. package/src/projection/obsidian/plugin-bridge/channel.mjs +174 -0
  488. package/src/projection/obsidian/plugin-bridge/index.mjs +10 -0
  489. package/src/projection/obsidian/proposals/adapter.mjs +47 -8
  490. package/src/projection/obsidian/proposals/observation.mjs +20 -7
  491. package/src/projection/obsidian/publication/bridge-script.mjs +11 -5
  492. package/src/projection/obsidian/publication/index.mjs +2 -1
  493. package/src/projection/obsidian/publication/publisher.mjs +312 -36
  494. package/src/projection/obsidian/publication/transport.mjs +63 -8
  495. package/src/projection/obsidian/publication/vault-list.mjs +200 -0
  496. package/src/projection/obsidian/recovery/index.mjs +4 -1
  497. package/src/projection/obsidian/recovery/restart.mjs +3 -1
  498. package/src/projection/obsidian/recovery/store.mjs +168 -8
  499. package/src/projection/obsidian/selection-ui/contribution.mjs +6 -5
  500. package/src/projection/obsidian/selection-ui/focus.mjs +14 -7
  501. package/src/projection/obsidian/selection-ui/selection-state.mjs +2 -2
  502. package/src/projection/obsidian/selection-ui/selection.mjs +8 -3
  503. package/src/readiness/readiness.mjs +10 -3
  504. package/src/reflection/index.mjs +56 -0
  505. package/src/runtime/obsidian/app-capability.mjs +104 -12
  506. package/src/runtime/obsidian/app-production-seams.mjs +161 -42
  507. package/src/runtime/obsidian/app-registration.mjs +313 -0
  508. package/src/runtime/obsidian/app-restart.mjs +154 -0
  509. package/src/runtime/obsidian/engine.mjs +288 -29
  510. package/src/runtime/obsidian/extension-points.mjs +1 -1
  511. package/src/runtime/obsidian/index.mjs +15 -8
  512. package/src/runtime/obsidian/launch-plan.mjs +91 -0
  513. package/src/runtime/obsidian/lifecycle.mjs +193 -22
  514. package/src/runtime/obsidian/login-item.mjs +332 -0
  515. package/src/runtime/obsidian/machine-settings.mjs +119 -12
  516. package/src/runtime/obsidian/opening.mjs +369 -63
  517. package/src/runtime/obsidian/pending-edits.mjs +10 -0
  518. package/src/runtime/obsidian/pipeline.mjs +71 -3
  519. package/src/runtime/obsidian/plugin-channel.mjs +289 -0
  520. package/src/runtime/obsidian/plugin-choice.mjs +182 -0
  521. package/src/runtime/obsidian/plugin-drift.mjs +124 -0
  522. package/src/runtime/obsidian/plugin-presence.mjs +61 -0
  523. package/src/runtime/obsidian/process-identity.mjs +20 -10
  524. package/src/runtime/obsidian/project-views.mjs +282 -0
  525. package/src/runtime/obsidian/questions.mjs +48 -0
  526. package/src/runtime/obsidian/release-watch.mjs +56 -0
  527. package/src/runtime/obsidian/service-main.mjs +113 -17
  528. package/src/runtime/obsidian/service-manager-production.mjs +61 -0
  529. package/src/runtime/obsidian/service-managers.mjs +275 -0
  530. package/src/runtime/obsidian/service-record.mjs +105 -5
  531. package/src/runtime/obsidian/service-server.mjs +50 -12
  532. package/src/runtime/obsidian/service.mjs +134 -7
  533. package/src/runtime/obsidian/startup-adapters.mjs +59 -21
  534. package/src/runtime/obsidian/state-store.mjs +13 -1
  535. package/src/runtime/obsidian/unheld-evidence.mjs +84 -0
  536. package/src/runtime/obsidian/vault-location.mjs +300 -0
  537. package/src/runtime/obsidian/view-counts.mjs +34 -0
  538. package/src/server/local-sidecar.mjs +193 -7
  539. package/src/server/server.mjs +45 -6
  540. package/src/template-bindings/project.mjs +92 -0
  541. package/src/templates/profile.mjs +225 -0
  542. package/src/trackables/domain.mjs +175 -0
  543. package/src/trackables/store.mjs +114 -0
  544. package/src/ui/knowledge-page.mjs +1388 -0
  545. package/src/upgrade/explanation.mjs +1 -1
  546. package/src/upgrade/template-participant.mjs +171 -0
  547. package/src/upgrade/transaction.mjs +72 -25
  548. package/src/upgrade/upgrade.mjs +2 -1
  549. package/templates/external-project-workspace/pack-lifecycle.json +6 -1
  550. package/templates/knowledge-workspace/.gitattributes +2 -0
  551. package/templates/knowledge-workspace/AGENTS.md +27 -0
  552. package/templates/knowledge-workspace/README.md +44 -0
  553. package/templates/knowledge-workspace/atelier.project.json +22 -0
  554. package/templates/knowledge-workspace/gitignore +6 -0
  555. package/templates/knowledge-workspace/knowledge-plan.json +111 -0
  556. package/templates/knowledge-workspace/knowledge-plan.schema.json +281 -0
  557. package/templates/knowledge-workspace/records/forecast.md +22 -0
  558. package/templates/knowledge-workspace/records/inspection.md +25 -0
  559. package/templates/knowledge-workspace/records/telescope.md +24 -0
  560. package/templates/knowledge-workspace/repo-access.v1.json +9 -0
@@ -0,0 +1,163 @@
1
+ """Finite JSON workflow bridge for a host-owned supplier factory.
2
+
3
+ Host module must define create_supplier() -> GraphifySupplier. This does not
4
+ choose a processor or discover credentials. The executable host module belongs
5
+ to host custody. Workflow shape is validated before importing that module.
6
+ """
7
+ from __future__ import annotations
8
+ import argparse
9
+ import importlib.util
10
+ import json
11
+ import math
12
+ import sys
13
+ from pathlib import Path
14
+
15
+ from graphify_supplier import GraphifySupplier, PINS, SupplierError, json_safe, require
16
+
17
+
18
+ def validate_workflow(requests) -> list[dict]:
19
+ """Validate the complete finite transport, including later steps, before effects.
20
+
21
+ Source admission, budgets and per-operation native settings still belong to
22
+ the supplier/host. A valid transport never confers acceptance or authority.
23
+ """
24
+ require(isinstance(requests, list) and 0 < len(requests) <= 128, "WORKFLOW_BOUND", "Finite native workflow required")
25
+ labels, count = set(), 0
26
+
27
+ def value_shape(value, depth=0):
28
+ nonlocal count
29
+ count += 1
30
+ require(depth <= 64 and count <= 100000, "WORKFLOW_BOUND", "Bounded JSON workflow required")
31
+ if isinstance(value, dict):
32
+ require(all(isinstance(k, str) for k in value), "WORKFLOW_SHAPE", "JSON object keys required")
33
+ if "generationFrom" in value:
34
+ require(set(value) == {"generationFrom"} and isinstance(value["generationFrom"], str)
35
+ and value["generationFrom"] in labels, "WORKFLOW_REFERENCE", "Generation must reference an earlier operation label")
36
+ else:
37
+ for item in value.values():
38
+ value_shape(item, depth + 1)
39
+ elif isinstance(value, list):
40
+ for item in value:
41
+ value_shape(item, depth + 1)
42
+ else:
43
+ require(value is None or isinstance(value, (str, bool, int, float)), "WORKFLOW_SHAPE", "JSON scalar required")
44
+ require(not isinstance(value, float) or math.isfinite(value), "WORKFLOW_SHAPE", "Finite JSON number required")
45
+ require(not isinstance(value, str) or len(value) <= 1048576, "WORKFLOW_BOUND", "Bounded JSON string required")
46
+
47
+ for request in requests:
48
+ require(isinstance(request, dict) and {"id", "operation"} <= set(request)
49
+ and set(request) <= {"id", "operation", "params"}, "WORKFLOW_SHAPE", "ID and operation are required")
50
+ rid, operation = request["id"], request["operation"]
51
+ require(isinstance(rid, str) and 0 < len(rid) <= 128 and rid not in labels,
52
+ "WORKFLOW_REFERENCE", "Unique bounded operation label required")
53
+ require(isinstance(operation, str), "WORKFLOW_SHAPE", "Operation name must be a string")
54
+ require(operation in PINS["operations"], "CAPABILITY_UNSUPPORTED", "Unknown or unsupported workflow operation")
55
+ params = request.get("params", {})
56
+ require(isinstance(params, dict), "WORKFLOW_SHAPE", "Operation params must be an object")
57
+ value_shape(params)
58
+ labels.add(rid)
59
+ # A detached JSON value prevents caller mutation during an admitted workflow.
60
+ return json.loads(json.dumps(requests, allow_nan=False))
61
+
62
+
63
+ def _portable(value):
64
+ return json.loads(json.dumps(json_safe(value), sort_keys=True, ensure_ascii=False, allow_nan=False))
65
+
66
+
67
+ def _error_receipt(receipt):
68
+ try:
69
+ return _portable(receipt)
70
+ except BaseException as exc:
71
+ # Retain useful existing receipt identities without pretending an unknown
72
+ # result was transported. Earlier successful snapshots are unaffected.
73
+ safe = {"transportState": "receipt-serialization-failed", "errorType": type(exc).__name__,
74
+ "authority": "none", "canonicalMutation": False}
75
+ if isinstance(receipt, dict):
76
+ for key in ("operationId", "operation", "status", "generationId", "rootIdentity"):
77
+ if isinstance(receipt.get(key), str):
78
+ safe[key] = receipt[key]
79
+ for key in ("artifacts", "nativeExecution", "error"):
80
+ try:
81
+ safe[key] = _portable(receipt.get(key))
82
+ except BaseException:
83
+ pass
84
+ return safe
85
+
86
+
87
+ def run_workflow(supplier: GraphifySupplier, requests: list[dict]) -> dict:
88
+ completed, receipts = {}, []
89
+ try:
90
+ requests = validate_workflow(requests)
91
+ except BaseException as exc:
92
+ return {"status": "failed", "completed": [], "executionState": "workflow-not-started",
93
+ "error": {"code": getattr(exc, "code", "WORKFLOW_VALIDATION_FAILURE"), "type": type(exc).__name__},
94
+ "authority": "none", "canonicalMutation": False}
95
+
96
+ def bind(value):
97
+ if isinstance(value, dict) and set(value) == {"generationFrom"}:
98
+ previous = completed[value["generationFrom"]]
99
+ require(isinstance(previous.get("generationId"), str), "WORKFLOW_REFERENCE", "Earlier operation did not create a generation")
100
+ return previous["generationId"]
101
+ if isinstance(value, list):
102
+ return [bind(x) for x in value]
103
+ if isinstance(value, dict):
104
+ return {k: bind(v) for k, v in value.items()}
105
+ return value
106
+
107
+ for request in requests:
108
+ rid, receipt, invoked, returned = request["id"], None, False, False
109
+ try:
110
+ params = bind(request.get("params", {}))
111
+ invoked = True
112
+ receipt = supplier.call(request["operation"], params)
113
+ returned = True
114
+ snapshot = _portable(receipt)
115
+ require(isinstance(snapshot, dict) and snapshot.get("status") in {"complete", "partial"},
116
+ "WORKFLOW_RECEIPT", "Supplier returned no terminal usable receipt")
117
+ except BaseException as exc:
118
+ current_receipt = getattr(exc, "receipt", None) or receipt
119
+ return {"status": "failed", "completed": receipts, "failedOperation": rid,
120
+ "executionState": "not-started" if not invoked else "returned-transport-failed" if returned else "unknown-owned-invocation",
121
+ "error": {"code": getattr(exc, "code", "OWNED_INVOCATION_FAILURE"), "type": type(exc).__name__,
122
+ "receipt": _error_receipt(current_receipt)}, "authority": "none", "canonicalMutation": False}
123
+ completed[rid] = snapshot
124
+ receipts.append({"id": rid, "receipt": snapshot})
125
+ return {"status": "partial" if any(r["receipt"]["status"] == "partial" for r in receipts) else "complete",
126
+ "completed": receipts, "authority": "none", "canonicalMutation": False}
127
+
128
+
129
+ def main():
130
+ parser = argparse.ArgumentParser(description=__doc__)
131
+ parser.add_argument("--host", required=True, help="Admitted local Python factory module")
132
+ parser.add_argument("--request", required=True, help="Finite JSON workflow file")
133
+ args = parser.parse_args()
134
+ output = sys.stdout
135
+ try:
136
+ # No host import/factory/cache creation until the whole request is valid.
137
+ raw = Path(args.request).read_bytes()
138
+ require(len(raw) <= 16777216, "WORKFLOW_BOUND", "Finite request file required")
139
+ requests = validate_workflow(json.loads(raw))
140
+ spec = importlib.util.spec_from_file_location("atelier_graphify_host", Path(args.host).resolve())
141
+ require(spec is not None and spec.loader is not None, "HOST_FACTORY", "Readable host factory required")
142
+ host = importlib.util.module_from_spec(spec)
143
+ sys.stdout = sys.stderr
144
+ spec.loader.exec_module(host)
145
+ supplier = host.create_supplier()
146
+ require(isinstance(supplier, GraphifySupplier), "HOST_FACTORY", "Host must return the supplier boundary")
147
+ result = run_workflow(supplier, requests)
148
+ except SupplierError as exc:
149
+ result = {"status": "failed", "completed": [], "error": {"code": exc.code, "receipt": _error_receipt(exc.receipt)},
150
+ "authority": "none", "canonicalMutation": False}
151
+ except BaseException as exc:
152
+ result = {"status": "failed", "completed": [], "error": {"code": "HOST_BRIDGE_FAILURE", "type": type(exc).__name__},
153
+ "authority": "none", "canonicalMutation": False}
154
+ finally:
155
+ sys.stdout = output
156
+ # run_workflow has already encoded each receipt independently; a later owned
157
+ # invocation/encoding failure cannot erase earlier completed portable receipts.
158
+ print(json.dumps(result, sort_keys=True, ensure_ascii=False, allow_nan=False))
159
+ return {"complete": 0, "failed": 1, "partial": 2}[result["status"]]
160
+
161
+
162
+ if __name__ == "__main__":
163
+ raise SystemExit(main())
@@ -0,0 +1,209 @@
1
+ """Private current-owner receiving of retained Graphify queries, no native call.
2
+
3
+ Host callbacks return original evidence/hits/receipt references. These structures
4
+ are composition transport, not a new evidence, receipt or acceptance canonical.
5
+ """
6
+ from __future__ import annotations
7
+ import copy
8
+ import fcntl
9
+ import hashlib
10
+ import json
11
+ import re
12
+ import uuid
13
+ from pathlib import Path
14
+ from graphify_supplier import SupplierError, digest, json_safe, require
15
+
16
+
17
+ def _reference(value):
18
+ return (isinstance(value, dict) and set(value) == {"id", "digest"}
19
+ and isinstance(value["id"], str) and 0 < len(value["id"]) <= 256
20
+ and isinstance(value["digest"], str) and re.fullmatch(r"sha256:[a-f0-9]{64}", value["digest"]))
21
+
22
+
23
+ def _selection(result, declared):
24
+ if isinstance(declared, str):
25
+ declared = {"pointer": declared}
26
+ require(isinstance(declared, dict) and set(declared) <= {"pointer", "span"}
27
+ and isinstance(declared.get("pointer"), str) and len(declared["pointer"]) <= 4096,
28
+ "QUERY_SELECTION", "Bounded existing-result pointer required")
29
+ pointer, value = declared["pointer"], result
30
+ require(pointer == "" or pointer.startswith("/"), "QUERY_SELECTION", "JSON pointer required")
31
+ for safe_name in pointer[1:].split("/") if pointer else []:
32
+ require(not re.search(r"~(?![01])", safe_name), "QUERY_SELECTION", "Exact JSON pointer escaping required")
33
+ safe_name = safe_name.replace("~1", "/").replace("~0", "~")
34
+ if isinstance(value, list):
35
+ require(re.fullmatch(r"0|[1-9][0-9]*", safe_name) is not None and int(safe_name) < len(value), "QUERY_SELECTION", "Selected result index absent")
36
+ value = value[int(safe_name)]
37
+ else:
38
+ require(isinstance(value, dict) and safe_name in value, "QUERY_SELECTION", "Selected result member absent")
39
+ value = value[safe_name]
40
+ if "span" in declared:
41
+ span = declared["span"]
42
+ require(isinstance(value, str) and isinstance(span, dict) and set(span) == {"start", "end"}
43
+ and type(span["start"]) is int and type(span["end"]) is int
44
+ and 0 <= span["start"] < span["end"] <= len(value), "QUERY_SELECTION", "Exact native text span required")
45
+ value = value[span["start"]:span["end"]]
46
+ return {"selection": copy.deepcopy(declared), "nativeResult": copy.deepcopy(value), "nativeResultDigest": digest(value)}
47
+
48
+
49
+ def _valid_mapping(entry, selection, sources):
50
+ require(isinstance(entry, dict) and entry.get("selection") == selection["selection"]
51
+ and entry.get("nativeResultDigest") == selection["nativeResultDigest"], "QUERY_MAPPING_BINDING", "Mapping must bind the selected original native result")
52
+ evidence, hit = entry.get("evidence"), entry.get("hit")
53
+ require(isinstance(evidence, dict) and isinstance(hit, dict), "QUERY_MAPPING_MISSING", "Original owner evidence and hit are required")
54
+ ref = hit.get("evidenceRef")
55
+ require(isinstance(ref, dict) and set(ref) == {"sourceId", "revision", "representationId", "locator"}
56
+ and all(isinstance(ref[k], str) and 0 < len(ref[k]) <= 256 for k in ("sourceId", "revision", "representationId"))
57
+ and isinstance(ref["locator"], dict), "QUERY_EVIDENCE_REFERENCE", "Original composition evidence reference required")
58
+ source = sources.get(ref["sourceId"])
59
+ # Existing vanilla private projection uses the original evidence sourceDigest
60
+ # as revision and its original attemptId as representationId. Native catalogue
61
+ # revision remains a separate lifecycle binding; no new identity is inferred.
62
+ require(source is not None and source["sourceDigest"] == ref["revision"]
63
+ and evidence.get("sourceId") == ref["sourceId"] and evidence.get("sourceDigest") == source["sourceDigest"],
64
+ "QUERY_MAPPING_SOURCE", "Mapping source/revision must match current native dependencies")
65
+ require(evidence.get("schema") == "mnstry.atelier-ingestion-evidence@v1"
66
+ and evidence.get("freshness") == "current" and evidence.get("integrity") == "verified"
67
+ and evidence.get("readScope") == "all-plan" and evidence.get("synthesized") is False
68
+ and evidence.get("semanticAcceptance") == "pending" and evidence.get("locator") == ref["locator"]
69
+ and isinstance(evidence.get("ref"), str) and 0 < len(evidence["ref"]) <= 16384
70
+ and isinstance(evidence.get("text"), str), "QUERY_EVIDENCE_UNVERIFIED", "Original current located evidence receipt required")
71
+ locator = evidence["locator"]
72
+ require(set(locator) == {"kind", "value"} and locator["kind"] in {"line", "csv-cell", "json-pointer"}
73
+ and isinstance(locator["value"], str) and 0 < len(locator["value"]) <= 16384,
74
+ "QUERY_EVIDENCE_REFERENCE", "Supported exact original owner locator required")
75
+ require(isinstance(evidence.get("planId"), str) and bool(evidence["planId"])
76
+ and isinstance(evidence.get("planDigest"), str) and re.fullmatch(r"[a-f0-9]{64}", evidence["planDigest"])
77
+ and isinstance(evidence.get("attemptId"), str) and bool(evidence["attemptId"]),
78
+ "QUERY_EVIDENCE_UNVERIFIED", "Original owner plan/digest/attempt bindings required")
79
+ require(all(evidence.get(k) == source[k] for k in ("attemptId", "planId", "planDigest") if k in source),
80
+ "QUERY_MAPPING_SOURCE", "Located evidence attempt/plan differs from current dependency")
81
+ require(isinstance(source.get("attemptId"), str) and bool(source["attemptId"])
82
+ and ref["representationId"] == evidence["attemptId"] == source["attemptId"],
83
+ "QUERY_MAPPING_REPRESENTATION", "Original evidence representation must match its original owner attempt")
84
+ require(isinstance(hit.get("quote"), str) and bool(hit["quote"]) and hit["quote"] in evidence["text"],
85
+ "QUERY_QUOTE_UNVERIFIED", "Original hit quote must occur in its owner-read evidence")
86
+ # The existing owner verifier still qualifies representation identity, exact
87
+ # passage/current permission and canonical receipts. Shape never grants it.
88
+ return copy.deepcopy(hit)
89
+
90
+
91
+ def receive_query(supplier, operation_id, *, selections=None):
92
+ require(supplier.lock.acquire(blocking=False), "WRITER_BUSY", "A supplier operation owns receiving")
93
+ lease, envelope, body, directory = None, None, None, None
94
+ try:
95
+ lease = (supplier.artifacts / ".writer.lock").open("a+b")
96
+ try:
97
+ fcntl.flock(lease, fcntl.LOCK_EX | fcntl.LOCK_NB)
98
+ except BlockingIOError as exc:
99
+ raise SupplierError("WRITER_BUSY", "Another process owns this supplier destination") from exc
100
+ receipt = supplier.read_capture(operation_id)["receipt"]
101
+ require(receipt.get("operation") == "query" and receipt.get("status") == "complete", "QUERY_RECEIVING_SCOPE", "Existing successful retained query required")
102
+ generation = receipt.get("graphGeneration")
103
+ directory = supplier.artifacts / operation_id
104
+ artifacts = [a for a in receipt["artifacts"] if Path(a["path"]).name == "result.json"]
105
+ require(len(artifacts) == 1, "QUERY_RECEIVING_ARTIFACT", "Exactly one original retained query result required")
106
+ artifact = copy.deepcopy(artifacts[0])
107
+ result = json.loads(Path(artifact["path"]).read_bytes())
108
+ original_receipt = directory / "receipt.json"
109
+ receipt_bytes = original_receipt.read_bytes()
110
+ receipt_artifact = {"path": str(original_receipt), "sha256": hashlib.sha256(receipt_bytes).hexdigest(), "bytes": len(receipt_bytes)}
111
+ declared = [""] if selections is None else selections
112
+ require(isinstance(declared, list) and 0 < len(declared) <= 128, "QUERY_SELECTION", "Finite explicit native selection required")
113
+ selected = [_selection(result, selection) for selection in declared]
114
+ require(len({digest(s["selection"]) for s in selected}) == len(selected), "QUERY_SELECTION_AMBIGUOUS", "Duplicate native selection is ambiguous")
115
+ context = {"queryArtifact": artifact, "queryReceiptArtifact": receipt_artifact, "generation": generation,
116
+ "sourceBindings": copy.deepcopy(receipt["sourceBindings"]), "rootIdentity": supplier.root_id,
117
+ "epoch": receipt["epoch"], "view": receipt["view"], "nativeSelections": selected}
118
+ envelope = {"provider": "graphify", "generation": generation, "artifactRef": artifact,
119
+ "hits": [], "unresolved": [], "receiptRef": None, "usage": copy.deepcopy(receipt.get("usage")),
120
+ "authority": "none", "canonicalMutation": False}
121
+ body = {"queryOperationId": operation_id, "queryBinding": context, "hostMappingOriginal": None,
122
+ "hostEligibilityOriginal": None, "envelope": envelope, "qualification": "private receiving; original canonical owners retain authority"}
123
+ def finish():
124
+ envelope["status"] = "received" if envelope["hits"] and not envelope["unresolved"] else "partial-received" if envelope["hits"] else "unresolved"
125
+ capture = supplier._write(directory, f"receiving-{uuid.uuid4().hex}.json", body)
126
+ envelope["receivingArtifact"] = capture
127
+ return envelope
128
+ def propagate_control(exc):
129
+ if isinstance(exc, Exception): return
130
+ envelope["hits"] = []
131
+ envelope["receiptRef"] = None
132
+ body["controlSignal"] = {"type": type(exc).__name__, "propagated": True}
133
+ try:
134
+ finish()
135
+ except BaseException as capture_error:
136
+ body["captureError"] = {"type": type(capture_error).__name__, "code": getattr(capture_error, "code", "CAPTURE_FAILURE")}
137
+ exc.receipt = copy.deepcopy(body)
138
+ raise exc
139
+ try:
140
+ item = supplier._fresh(generation, "graph")
141
+ require(context["sourceBindings"] == item["dependencies"] and receipt["epoch"] == supplier.epoch,
142
+ "QUERY_RECEIVING_STALE", "Query generation/source bindings differ from current graph")
143
+ if item.get("accepted_reference") is not None:
144
+ build_receipt = supplier.read_capture(item["operationId"])["receipt"]
145
+ context.update(historyDigest=build_receipt["acceptedHead"], activationRef=copy.deepcopy(item["accepted_reference"]))
146
+ except BaseException as exc:
147
+ envelope["unresolved"].append({"reason": getattr(exc, "code", "QUERY_RECEIVING_STALE"), "type": type(exc).__name__})
148
+ propagate_control(exc)
149
+ return finish()
150
+ if not callable(supplier.query_hydrator) or not callable(supplier.query_verifier):
151
+ envelope["unresolved"] = [{"selection": s["selection"], "reason": "current-owner-receiving-unreceived"} for s in selected]
152
+ else:
153
+ try:
154
+ hydrated = json_safe(supplier.query_hydrator(copy.deepcopy(context)))
155
+ body["hostMappingOriginal"] = hydrated
156
+ require(isinstance(hydrated, dict) and _reference(hydrated.get("mappingReceipt"))
157
+ and isinstance(hydrated.get("mappings"), list), "QUERY_MAPPING_RECEIPT", "Original owner mapping receipt/mappings required")
158
+ entries, hits = hydrated["mappings"], []
159
+ # Hydrator may decline an exact selection. Multiple mappings for
160
+ # the same selection remain ambiguous; there is no arbitrary winner.
161
+ require(all(isinstance(e, dict) and e.get("selection") in [s["selection"] for s in selected] for e in entries),
162
+ "QUERY_MAPPING_BINDING", "Mapping includes an unselected native result")
163
+ for selection in selected:
164
+ matches = [e for e in entries if e.get("selection") == selection["selection"]]
165
+ if len(matches) != 1:
166
+ envelope["unresolved"].append({"selection": selection["selection"], "reason": "mapping-absent" if not matches else "mapping-ambiguous"})
167
+ continue
168
+ try:
169
+ hits.append(_valid_mapping(matches[0], selection, context["sourceBindings"]))
170
+ except SupplierError as exc:
171
+ envelope["unresolved"].append({"selection": selection["selection"], "reason": exc.code})
172
+ if hits:
173
+ binding = {**copy.deepcopy(context), "mappingReceipt": copy.deepcopy(hydrated["mappingReceipt"]),
174
+ "mappingDigest": digest(hydrated), "hitsDigest": digest(hits)}
175
+ # Repeat current generation/source/accepted-head checks around
176
+ # the existing owner's actual mapping+eligibility verification.
177
+ supplier._fresh(generation, "graph")
178
+ verdict = json_safe(supplier.query_verifier({"binding": copy.deepcopy(binding), "mapping": copy.deepcopy(hydrated), "hits": copy.deepcopy(hits)}))
179
+ body["hostEligibilityOriginal"] = verdict
180
+ require(isinstance(verdict, dict) and verdict.get("binding") == binding
181
+ and verdict.get("current") is True and verdict.get("permitted") is True
182
+ and _reference(verdict.get("eligibilityReceipt")) and _reference(verdict.get("receiptRef")),
183
+ "QUERY_ELIGIBILITY_UNVERIFIED", "Current owner must bind original query/source/generation/mapping/hits and eligibility receipts")
184
+ envelope.update(hits=hits, mappingReceipt=copy.deepcopy(hydrated["mappingReceipt"]),
185
+ eligibilityReceipt=copy.deepcopy(verdict["eligibilityReceipt"]), receiptRef=copy.deepcopy(verdict["receiptRef"]))
186
+ except BaseException as exc:
187
+ envelope["hits"] = []
188
+ envelope["unresolved"].append({"reason": getattr(exc, "code", "QUERY_OWNER_RECEIVING_FAILURE"), "type": type(exc).__name__})
189
+ propagate_control(exc)
190
+ try:
191
+ supplier._fresh(generation, "graph")
192
+ supplier.read_capture(operation_id)
193
+ require(original_receipt.read_bytes() == receipt_bytes, "ARTIFACT_DRIFT", "Original query receipt changed during receiving")
194
+ except BaseException as exc:
195
+ envelope["hits"] = []
196
+ envelope["receiptRef"] = None
197
+ envelope["unresolved"].append({"reason": getattr(exc, "code", "QUERY_RECEIVING_STALE"), "type": type(exc).__name__})
198
+ propagate_control(exc)
199
+ # Supplemental capture uses existing owned artifact custody and links the
200
+ # original immutable query receipt. It is not a new canonical journal.
201
+ return finish()
202
+ except BaseException as exc:
203
+ if not isinstance(exc, Exception) and not hasattr(exc, "receipt"):
204
+ exc.receipt = copy.deepcopy(body) if body is not None else {"queryOperationId": operation_id, "nativeReplay": False}
205
+ raise
206
+ finally:
207
+ if lease:
208
+ lease.close()
209
+ supplier.lock.release()
@@ -0,0 +1,9 @@
1
+ export { createComposition, compileRoute, composeEvidence, CompositionFailure } from './composition/index.mjs'
2
+ export { createVanillaCompositionBinding } from './vanilla/composition-binding.mjs'
3
+ export { createVanillaIngestionBridge, createCandidateExtractor, normalizeCandidateJson, readVanillaCapture, VanillaIngestionError } from './vanilla/index.mjs'
4
+ export { normalizeNativeExtraction, createNativeNormalizer, NativeHandoffError } from './vanilla/native-normalization.mjs'
5
+ export { createCompositionJudgmentBinding } from './jev/composition-binding.mjs'
6
+ export { prepareIngestionJudgments } from './jev/judgments.mjs'
7
+ export { createGraphifyCompositionBinding, GraphifyCompositionBindingError } from './graphify/composition-binding.mjs'
8
+ export { createLightRAGCompositionBinding, LightRAGCompositionBindingError } from './lightrag/composition-binding.mjs'
9
+ export { PRESENCE_PROFILES, createQualificationExecutor, validateExecutionPlan, accountComponents, summarizeCohort, amortizedCosts } from './evaluation/index.mjs'
@@ -0,0 +1,166 @@
1
+ import {closed, freeze, materialDigest, requireContracts, requirePrepared, requireThat, snapshot, text, validId, RUBRIC_VERSION} from './judgments.mjs';
2
+
3
+ function abstention(batch, model, mode, reason, elapsedMs, usage = null) {
4
+ return freeze({schema: 'atelier-decision-result@v1', requestId: batch.request.id,
5
+ requestDigest: batch.requestDigest, task: batch.request.task, rubricVersion: batch.request.rubricVersion,
6
+ scope: batch.request.scope, provider: {id: 'jev', model}, authority: 'proposal-only',
7
+ mode, status: 'abstained', reason, answers: {}, usage, elapsedMs});
8
+ }
9
+ function qualified(batch, qualifications, model) {
10
+ return Object.entries(batch.questionPlacements).every(([id, placement]) => {
11
+ const q = qualifications[placement], type = batch.request.questions[id].type;
12
+ return q && q.model === model && q.rubricVersion === RUBRIC_VERSION && validId(q.reference) &&
13
+ q.sourceProfile === 'invented-public-offline' &&
14
+ (type !== 'boolean' || Number.isFinite(q.rejectAtOrBelow) && Number.isFinite(q.acceptAtOrAbove) &&
15
+ q.rejectAtOrBelow >= 0 && q.acceptAtOrAbove <= 1 && q.rejectAtOrBelow < q.acceptAtOrAbove) &&
16
+ (type !== 'choice' || Number.isFinite(q.minimumConfidence) && q.minimumConfidence >= 0 && q.minimumConfidence <= 1 &&
17
+ Number.isFinite(q.minimumMargin) && q.minimumMargin > 0 && q.minimumMargin <= 1) &&
18
+ (type !== 'score' || Number.isFinite(q.minimumConfidence) && q.minimumConfidence >= 0 && q.minimumConfidence <= 1);
19
+ });
20
+ }
21
+ function dispositions(batch, result, qualifications) {
22
+ if (result.status === 'abstained') return Object.fromEntries(Object.keys(batch.request.questions).map(id => [id, {status: 'abstained', reason: result.reason}]));
23
+ return Object.fromEntries(Object.entries(result.answers).map(([id, answer]) => {
24
+ const placement = batch.questionPlacements[id], q = qualifications[placement]; let ambiguous = false;
25
+ if (answer.type === 'choice') {
26
+ const values = Object.values(answer.probabilities).sort((a, b) => b - a);
27
+ ambiguous = ['uncertain', 'unmodeled'].includes(answer.choice) || answer.confidence < q.minimumConfidence || values[0] - values[1] < q.minimumMargin;
28
+ } else if (answer.type === 'boolean') ambiguous = answer.probability > q.rejectAtOrBelow && answer.probability < q.acceptAtOrAbove;
29
+ else if (answer.type === 'score') ambiguous = answer.confidence < q.minimumConfidence;
30
+ return [id, {placement, status: ambiguous ? 'abstained' : 'proposal', ...(ambiguous ? {reason: 'ambiguous'} : {}),
31
+ answerRef: {requestId: result.requestId, requestDigest: result.requestDigest, questionId: id},
32
+ ...(answer.type === 'choice' && batch.choiceBindings[id]?.[answer.choice] ? {selection: batch.choiceBindings[id][answer.choice]} : {}),
33
+ qualificationRef: q.reference, authority: 'proposal-only'}];
34
+ }));
35
+ }
36
+ /**
37
+ * An offline supplier around the existing assess(request, options) host port.
38
+ * No HTTP, credentials, Consent implementation, cache, budget or executor.
39
+ * This packet profile deliberately refuses native activation; the transport
40
+ * owner must receive the narrow compatibility proposal before native use.
41
+ */
42
+ export function createIngestionJudgmentBridge({contracts, assess, checkCurrent, admitAssessment, transport,
43
+ model = 'jev-1.13.0', mode = 'off', qualifications = {}, deadlineMs = 15000, now = Date.now}) {
44
+ requireContracts(contracts);
45
+ requireThat(['off', 'shadow', 'advisory'].includes(mode) && /^jev-\d+\.\d+\.\d+$/.test(model) &&
46
+ Number.isInteger(deadlineMs) && deadlineMs >= 1 && deadlineMs <= 30000 && typeof now === 'function', 'invalid-bridge-configuration');
47
+ const qualificationSnapshot = freeze(snapshot(qualifications)),
48
+ transportSnapshot = transport === undefined ? null : freeze(snapshot(transport)),
49
+ attempts = new Map(), observedRequests = new Set();
50
+ async function run(batch, {attemptId, signal, originalHostReceiptRef} = {}) {
51
+ requirePrepared(batch, model); requireThat(validId(attemptId), 'original-attempt-identity-required');
52
+ requireThat(!attempts.has(attemptId), 'attempt-already-observed-no-replay');
53
+ const originalRequestKey = batch.operationId + ':' + batch.requestDigest;
54
+ requireThat(!observedRequests.has(originalRequestKey), 'request-already-observed-no-replay');
55
+ const started = now(), elapsed = () => Math.max(0, now() - started), resultMode = mode === 'off' ? 'shadow' : mode;
56
+ const record = {attemptId, requestId: batch.request.id, requestDigest: batch.requestDigest, execution: 'not-invoked', transportInvoked: false,
57
+ hostAdmission: {status: 'not-requested', authenticity: 'owned-by-existing-host-not-observed-by-bridge'}};
58
+ attempts.set(attemptId, record);
59
+ observedRequests.add(originalRequestKey);
60
+ const finish = (result, reason, originalResult = null) => {
61
+ requireThat(contracts.validateDecisionResult(batch.request, result).ok, 'canonical-result-refused');
62
+ const receipt = freeze({attemptId, operationId: batch.operationId, requestId: batch.request.id,
63
+ requestDigest: batch.requestDigest, nativePayloadDigest: batch.nativePayloadDigest,
64
+ nativePayloadDigestKind: 'prepared-body-only', actualProviderPayloadDigest: null,
65
+ bindings: batch.bindings, questionPlacements: batch.questionPlacements,
66
+ model, rubricVersion: RUBRIC_VERSION, execution: record.execution,
67
+ transportInvoked: record.transportInvoked, providerInvocation: 'not-observed-by-bridge',
68
+ authority: 'proposal-only', nativeQualified: false,
69
+ hostAdmission: record.hostAdmission,
70
+ result, originalHostResult: originalResult, dispositions: dispositions(batch, result, qualificationSnapshot),
71
+ ...(reason ? {bridgeReason: reason} : {})});
72
+ record.returnedReceipt = receipt; return receipt;
73
+ };
74
+ const stop = (reason, bridgeReason = reason, usage = null, original = null) => finish(abstention(batch, model, resultMode, reason, elapsed(), usage), bridgeReason, original);
75
+ if (mode === 'off') return stop('unauthorized', 'off');
76
+ if (signal?.aborted) return stop('timeout', 'cancelled-before-invocation');
77
+ if (!qualified(batch, qualificationSnapshot, model)) return stop('unauthorized', 'placement-profile-unqualified');
78
+ if (typeof assess !== 'function' || typeof checkCurrent !== 'function') return stop('provider-unavailable', 'existing-assess-and-current-source-ports-required');
79
+ // Fixture qualification labels and integrity digests are never admission.
80
+ // Native transport is still outside this supplier's received profile.
81
+ if (!transportSnapshot || transportSnapshot.kind !== 'offline-fixture' || !validId(transportSnapshot.reference) ||
82
+ Object.keys(transportSnapshot).length !== 2) return stop('unauthorized', 'offline-host-transport-required');
83
+ if (typeof admitAssessment !== 'function' || !text(originalHostReceiptRef, 2048))
84
+ return stop('unauthorized', 'original-host-admission-and-receipt-required');
85
+ const controller = new AbortController(), abort = () => controller.abort();
86
+ signal?.addEventListener('abort', abort, {once: true});
87
+ const timer = setTimeout(abort, deadlineMs);
88
+ async function bounded(promise) {
89
+ if (controller.signal.aborted) throw Error('bounded-abort');
90
+ return new Promise((resolve, reject) => {
91
+ const cancel = () => reject(Error('bounded-abort'));
92
+ controller.signal.addEventListener('abort', cancel, {once: true});
93
+ Promise.resolve(promise).then(value => {controller.signal.removeEventListener('abort', cancel); resolve(value);}, error => {
94
+ controller.signal.removeEventListener('abort', cancel); reject(error);
95
+ });
96
+ });
97
+ }
98
+ const current = phase => checkCurrent(freeze({phase, attemptId, operationId: batch.operationId,
99
+ requestDigest: batch.requestDigest, nativePayloadDigest: batch.nativePayloadDigest, bindings: batch.bindings}), controller.signal);
100
+ let stage = 'source-check', receivedHostResult = null, validatedHostResult = null;
101
+ try {
102
+ if (await bounded(Promise.resolve().then(() => current('before-assess'))) !== true) return stop('insufficient-evidence', 'source-stale-or-withdrawn');
103
+ if (controller.signal.aborted) return stop('timeout', 'cancelled-before-invocation');
104
+ const intent = freeze({phase: 'before-assess', attemptId, operationId: batch.operationId,
105
+ originalHostReceiptRef, request: batch.request, requestDigest: batch.requestDigest,
106
+ scope: batch.request.scope, model, mode, rubricVersion: RUBRIC_VERSION,
107
+ questionPlacements: batch.questionPlacements, bindings: batch.bindings,
108
+ placementQualifications: Object.fromEntries([...new Set(Object.values(batch.questionPlacements))].map(p => [p, qualificationSnapshot[p]])),
109
+ transport: transportSnapshot, nativeBody: batch.nativeBody,
110
+ preparedNativePayloadDigest: batch.nativePayloadDigest, actualProviderPayloadDigest: null,
111
+ authority: 'proposal-only', nativeQualified: false});
112
+ const bindingDigest = materialDigest(intent);
113
+ stage = 'admission';
114
+ record.hostAdmission = {status: 'unknown', intent, bindingDigest,
115
+ authenticity: 'owned-by-existing-host-not-observed-by-bridge'};
116
+ const admitted = snapshot(await bounded(Promise.resolve().then(() => admitAssessment(freeze({...intent, bindingDigest}), {signal: controller.signal}))));
117
+ closed(admitted, ['allowed', 'receiptRef', 'bindingDigest']);
118
+ if (admitted.allowed !== true || !text(admitted.receiptRef, 2048) || admitted.bindingDigest !== bindingDigest) {
119
+ record.hostAdmission = {...record.hostAdmission, status: 'refused', originalHostReply: freeze(admitted)};
120
+ return stop('unauthorized', 'original-host-admission-refused');
121
+ }
122
+ record.hostAdmission = {...record.hostAdmission, status: 'host-received', receiptRef: admitted.receiptRef};
123
+ stage = 'source-check';
124
+ if (await bounded(Promise.resolve().then(() => current('after-admission-before-assess'))) !== true)
125
+ return stop('insufficient-evidence', 'source-stale-or-withdrawn-after-admission');
126
+ if (controller.signal.aborted) return stop('timeout', 'cancelled-before-invocation');
127
+ stage = 'assessment';
128
+ const hostPromise = Promise.resolve().then(() => {
129
+ if (controller.signal.aborted) throw Error('bounded-abort');
130
+ record.transportInvoked = true; record.execution = 'unknown';
131
+ return assess(batch.request, {
132
+ attemptId, operationId: batch.operationId, model, mode, rubricVersion: RUBRIC_VERSION,
133
+ signal: controller.signal, nativePayloadDigest: batch.nativePayloadDigest,
134
+ nativeBody: batch.nativeBody, bindings: batch.bindings, qualificationProfile: 'invented-public-offline',
135
+ originalHostReceiptRef, hostAdmissionReceiptRef: admitted.receiptRef,
136
+ admissionBindingDigest: bindingDigest, transport: transportSnapshot});
137
+ });
138
+ hostPromise.then(value => {record.hostReturned = true; try {record.originalHostResult = freeze(snapshot(value));} catch {record.invalidHostResult = true;}},
139
+ () => {record.hostReturned = true; record.hostError = 'host-assessment-failed';});
140
+ const output = snapshot(await bounded(hostPromise));
141
+ receivedHostResult = output;
142
+ // Return of this port does not independently settle the underlying provider.
143
+ record.execution = 'host-returned';
144
+ if (!contracts.validateDecisionResult(batch.request, output).ok || output.provider.id !== 'jev' || output.provider.model !== model || output.mode !== resultMode)
145
+ return stop('invalid-response', 'unbound-or-invalid-host-result', null, output);
146
+ validatedHostResult = output; stage = 'result-check';
147
+ if (await bounded(Promise.resolve().then(() => current('before-result-use'))) !== true)
148
+ return stop('insufficient-evidence', 'source-stale-or-withdrawn-after-assess', output.usage, output);
149
+ return finish(freeze(output), null, output);
150
+ } catch {
151
+ return stop(controller.signal.aborted ? 'timeout' : validatedHostResult ? 'insufficient-evidence' : 'provider-unavailable',
152
+ stage === 'result-check' ? 'post-assessment-currency-check-unavailable' :
153
+ stage === 'admission' ? 'original-host-admission-unavailable' :
154
+ record.transportInvoked ? 'host-outcome-requires-original-transport-reconciliation' : 'pre-invocation-check-unavailable',
155
+ validatedHostResult?.usage ?? null, receivedHostResult ?? record.originalHostResult ?? null);
156
+ } finally {clearTimeout(timer); signal?.removeEventListener('abort', abort);}
157
+ }
158
+ return Object.freeze({assess: run, inspect(attemptId) {
159
+ const record = attempts.get(attemptId); if (!record) return null;
160
+ return freeze(snapshot({attemptId: record.attemptId, requestId: record.requestId,
161
+ requestDigest: record.requestDigest, execution: record.execution, transportInvoked: record.transportInvoked,
162
+ hostReturned: record.hostReturned ?? false, originalHostResult: record.originalHostResult ?? null,
163
+ hostAdmission: record.hostAdmission,
164
+ providerExecutionSettled: 'not-observed-by-bridge', hostError: record.hostError ?? null}));
165
+ }});
166
+ }