@mnstry/atelier 0.2.0-alpha.12 → 0.2.0-alpha.14

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 (531) hide show
  1. package/CHANGELOG.md +894 -0
  2. package/README.md +159 -6
  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-personal-workspace-manifest.v1.schema.json +87 -0
  21. package/contracts/atelier-personal-workspace-overlay.v1.schema.json +299 -0
  22. package/contracts/atelier-template-adoption.v1.schema.json +223 -0
  23. package/contracts/atelier-template-profile.v1.schema.json +1168 -0
  24. package/contracts/atelier-trackable.v1.schema.json +781 -0
  25. package/contracts/atelier-upgrade-plan.v3.schema.json +532 -0
  26. package/docs/architecture.md +89 -0
  27. package/docs/assurance-controls.md +2 -2
  28. package/docs/blocks/capability-stewardship.md +17 -0
  29. package/docs/blocks/claims.md +16 -3
  30. package/docs/blocks/inquiry-harnesses.md +19 -0
  31. package/docs/blocks/learning-harnesses.md +17 -0
  32. package/docs/capability-stewardship.md +267 -0
  33. package/docs/coordination.md +51 -0
  34. package/docs/decision-practices.md +111 -0
  35. package/docs/decisions.md +29 -0
  36. package/docs/evidence-navigation.md +237 -0
  37. package/docs/exact-upgrades.md +3 -2
  38. package/docs/ingestion.md +181 -0
  39. package/docs/inquiry-harnesses.md +210 -0
  40. package/docs/install.md +80 -3
  41. package/docs/intake-and-guides.md +5 -0
  42. package/docs/integration-contract-decisions.md +24 -2
  43. package/docs/interaction-and-reflection.md +72 -0
  44. package/docs/knowledge-graph.md +20 -0
  45. package/docs/knowledge-health/api.md +30 -0
  46. package/docs/knowledge-health/assessment/api.md +96 -0
  47. package/docs/knowledge-health/assessment/capabilities.md +40 -0
  48. package/docs/knowledge-health/assessment/evaluation.md +27 -0
  49. package/docs/knowledge-health/assessment/facilitator.md +30 -0
  50. package/docs/knowledge-health/assessment/quickstart.md +61 -0
  51. package/docs/knowledge-health/assessment/troubleshooting.md +23 -0
  52. package/docs/knowledge-health/devday/facilitator.md +16 -0
  53. package/docs/knowledge-health/devday/participant-response.md +22 -0
  54. package/docs/knowledge-health/devday/public-default.md +107 -0
  55. package/docs/knowledge-health/devday/quickstart.md +18 -0
  56. package/docs/knowledge-health/devday/support.md +22 -0
  57. package/docs/knowledge-health/exercise.md +17 -0
  58. package/docs/knowledge-health/facilitator.md +20 -0
  59. package/docs/knowledge-health/quickstart.md +94 -0
  60. package/docs/knowledge-health/readme.md +15 -0
  61. package/docs/knowledge-health/support.md +34 -0
  62. package/docs/knowledge-setup.md +248 -0
  63. package/docs/knowledge-workspace.md +264 -0
  64. package/docs/learning-harnesses.md +237 -0
  65. package/docs/learning.md +215 -0
  66. package/docs/local-services.md +223 -19
  67. package/docs/obsidian-contract.md +246 -15
  68. package/docs/obsidian-plugin.md +252 -7
  69. package/docs/obsidian.md +874 -52
  70. package/docs/optional-ingestion.md +83 -0
  71. package/docs/personal-workspace.md +266 -0
  72. package/docs/practical-judgment.md +92 -0
  73. package/docs/progressive-ingestion-acceptance.md +89 -0
  74. package/docs/progressive-ingestion.md +235 -0
  75. package/docs/project-command-inventory.md +1 -0
  76. package/docs/release-engineering.md +50 -0
  77. package/docs/repo-boundary-guard.md +120 -3
  78. package/docs/research-starter-quickstart.md +66 -0
  79. package/docs/research-starter.md +114 -0
  80. package/docs/semantic-ingestion.md +198 -0
  81. package/docs/semantic-operation.md +318 -0
  82. package/docs/skill-steward.md +6 -0
  83. package/docs/template-profile.md +164 -0
  84. package/docs/template-upgrades.md +114 -0
  85. package/docs/trackables.md +111 -0
  86. package/docs/upgrade.md +219 -2
  87. package/fixtures/atelier-architecture/binding/invalid/document.json +19 -0
  88. package/fixtures/atelier-architecture/binding/valid/document.json +19 -0
  89. package/fixtures/atelier-architecture/catalog/invalid/document.json +290 -0
  90. package/fixtures/atelier-architecture/catalog/valid/document.json +343 -0
  91. package/fixtures/atelier-build-contract/attempt/invalid/document.json +20 -0
  92. package/fixtures/atelier-build-contract/attempt/valid/document.json +19 -0
  93. package/fixtures/atelier-build-contract/candidate/invalid/document.json +24 -0
  94. package/fixtures/atelier-build-contract/candidate/valid/document.json +23 -0
  95. package/fixtures/atelier-build-contract/decision/invalid/document.json +31 -0
  96. package/fixtures/atelier-build-contract/decision/valid/document.json +30 -0
  97. package/fixtures/atelier-build-contract/delivery/invalid/document.json +18 -0
  98. package/fixtures/atelier-build-contract/delivery/valid/document.json +17 -0
  99. package/fixtures/atelier-build-contract/gate/invalid/document.json +22 -0
  100. package/fixtures/atelier-build-contract/gate/valid/document.json +21 -0
  101. package/fixtures/atelier-build-contract/ledger/invalid/document.json +270 -0
  102. package/fixtures/atelier-build-contract/ledger/valid/document.json +269 -0
  103. package/fixtures/atelier-build-contract/objective/invalid/document.json +73 -0
  104. package/fixtures/atelier-build-contract/objective/valid/document.json +72 -0
  105. package/fixtures/atelier-build-contract/progress/invalid/document.json +18 -0
  106. package/fixtures/atelier-build-contract/progress/valid/document.json +17 -0
  107. package/fixtures/atelier-capability-contract/adoption/invalid/document.json +71 -0
  108. package/fixtures/atelier-capability-contract/adoption/valid/document.json +70 -0
  109. package/fixtures/atelier-capability-contract/event/invalid/document.json +18 -0
  110. package/fixtures/atelier-capability-contract/event/valid/document.json +17 -0
  111. package/fixtures/atelier-capability-contract/journal/invalid/document.json +382 -0
  112. package/fixtures/atelier-capability-contract/journal/valid/document.json +381 -0
  113. package/fixtures/atelier-capability-contract/notice/invalid/document.json +8 -0
  114. package/fixtures/atelier-capability-contract/notice/valid/document.json +7 -0
  115. package/fixtures/atelier-capability-contract/package/invalid/document.json +59 -0
  116. package/fixtures/atelier-capability-contract/package/valid/document.json +58 -0
  117. package/fixtures/atelier-capability-contract/plan/invalid/document.json +107 -0
  118. package/fixtures/atelier-capability-contract/plan/valid/document.json +106 -0
  119. package/fixtures/atelier-capability-contract/release/invalid/document.json +85 -0
  120. package/fixtures/atelier-capability-contract/release/valid/document.json +84 -0
  121. package/fixtures/atelier-capability-contract/state/invalid/document.json +316 -0
  122. package/fixtures/atelier-capability-contract/state/valid/document.json +315 -0
  123. package/fixtures/atelier-coordination/dependency/invalid/document.json +37 -0
  124. package/fixtures/atelier-coordination/dependency/valid/document.json +36 -0
  125. package/fixtures/atelier-coordination/directive/invalid/document.json +25 -0
  126. package/fixtures/atelier-coordination/directive/valid/document.json +24 -0
  127. package/fixtures/atelier-coordination/disposition/invalid/document.json +34 -0
  128. package/fixtures/atelier-coordination/disposition/valid/document.json +33 -0
  129. package/fixtures/atelier-coordination/outcome/invalid/document.json +39 -0
  130. package/fixtures/atelier-coordination/outcome/valid/document.json +38 -0
  131. package/fixtures/atelier-coordination/recovery/invalid/document.json +34 -0
  132. package/fixtures/atelier-coordination/recovery/valid/document.json +33 -0
  133. package/fixtures/atelier-harness-contract/handoff/invalid/document.json +25 -0
  134. package/fixtures/atelier-harness-contract/handoff/valid/document.json +24 -0
  135. package/fixtures/atelier-ingestion/invalid/authority.json +19 -0
  136. package/fixtures/atelier-ingestion/semantic-baseline.json +26 -0
  137. package/fixtures/atelier-ingestion/semantic-operation.json +75 -0
  138. package/fixtures/atelier-ingestion/valid/plan-input.json +18 -0
  139. package/fixtures/atelier-inquiry-contract/assessment/invalid/document.json +41 -0
  140. package/fixtures/atelier-inquiry-contract/assessment/valid/document.json +40 -0
  141. package/fixtures/atelier-inquiry-contract/bundle/invalid/document.json +51 -0
  142. package/fixtures/atelier-inquiry-contract/bundle/valid/document.json +50 -0
  143. package/fixtures/atelier-inquiry-contract/campaign/invalid/document.json +17 -0
  144. package/fixtures/atelier-inquiry-contract/campaign/valid/document.json +16 -0
  145. package/fixtures/atelier-inquiry-contract/decision/invalid/document.json +22 -0
  146. package/fixtures/atelier-inquiry-contract/decision/valid/document.json +21 -0
  147. package/fixtures/atelier-inquiry-contract/feedback/invalid/document.json +19 -0
  148. package/fixtures/atelier-inquiry-contract/feedback/valid/document.json +18 -0
  149. package/fixtures/atelier-inquiry-contract/handoff/invalid/document.json +92 -0
  150. package/fixtures/atelier-inquiry-contract/handoff/valid/document.json +91 -0
  151. package/fixtures/atelier-inquiry-contract/hypothesis/invalid/document.json +20 -0
  152. package/fixtures/atelier-inquiry-contract/hypothesis/valid/document.json +19 -0
  153. package/fixtures/atelier-inquiry-contract/ledger/invalid/document.json +680 -0
  154. package/fixtures/atelier-inquiry-contract/ledger/valid/document.json +679 -0
  155. package/fixtures/atelier-inquiry-contract/legacy-assessment/invalid/document.json +19 -0
  156. package/fixtures/atelier-inquiry-contract/legacy-assessment/valid/document.json +18 -0
  157. package/fixtures/atelier-inquiry-contract/request/invalid/document.json +50 -0
  158. package/fixtures/atelier-inquiry-contract/request/valid/document.json +49 -0
  159. package/fixtures/atelier-inquiry-contract/source/invalid/document.json +18 -0
  160. package/fixtures/atelier-inquiry-contract/source/valid/document.json +17 -0
  161. package/fixtures/atelier-inquiry-contract/withdrawal/invalid/document.json +16 -0
  162. package/fixtures/atelier-inquiry-contract/withdrawal/valid/document.json +15 -0
  163. package/fixtures/atelier-instruction-adoption/context-receipt/invalid/document.json +18 -0
  164. package/fixtures/atelier-instruction-adoption/context-receipt/valid/document.json +17 -0
  165. package/fixtures/atelier-instruction-adoption/plan/invalid/document.json +63 -0
  166. package/fixtures/atelier-instruction-adoption/plan/valid/document.json +62 -0
  167. package/fixtures/atelier-instruction-adoption/receipt/invalid/document.json +22 -0
  168. package/fixtures/atelier-instruction-adoption/receipt/valid/document.json +21 -0
  169. package/fixtures/atelier-instruction-adoption/state/invalid/document.json +30 -0
  170. package/fixtures/atelier-instruction-adoption/state/valid/document.json +29 -0
  171. package/fixtures/atelier-interaction/act/invalid/document.json +25 -0
  172. package/fixtures/atelier-interaction/act/valid/document.json +24 -0
  173. package/fixtures/atelier-interaction/assessment/invalid/document.json +32 -0
  174. package/fixtures/atelier-interaction/assessment/valid/document.json +31 -0
  175. package/fixtures/atelier-interaction/observation/invalid/document.json +22 -0
  176. package/fixtures/atelier-interaction/observation/valid/document.json +21 -0
  177. package/fixtures/atelier-interaction/policy/invalid/document.json +20 -0
  178. package/fixtures/atelier-interaction/policy/valid/document.json +19 -0
  179. package/fixtures/atelier-judgment/case/invalid/document.json +76 -0
  180. package/fixtures/atelier-judgment/case/valid/document.json +75 -0
  181. package/fixtures/atelier-judgment/decision/invalid/document.json +38 -0
  182. package/fixtures/atelier-judgment/decision/valid/document.json +37 -0
  183. package/fixtures/atelier-judgment/native-decision.md +3 -0
  184. package/fixtures/atelier-judgment/practice-reconsideration/definition.json +92 -0
  185. package/fixtures/atelier-judgment/practice-reconsideration/scenario.json +435 -0
  186. package/fixtures/atelier-knowledge-contract/activation/invalid/document.json +26 -0
  187. package/fixtures/atelier-knowledge-contract/activation/valid/document.json +25 -0
  188. package/fixtures/atelier-knowledge-contract/contribution/invalid/document.json +34 -0
  189. package/fixtures/atelier-knowledge-contract/contribution/valid/document.json +33 -0
  190. package/fixtures/atelier-knowledge-contract/domain/invalid/document.json +41 -0
  191. package/fixtures/atelier-knowledge-contract/domain/valid/document.json +40 -0
  192. package/fixtures/atelier-knowledge-contract/domain-revision/invalid/document.json +46 -0
  193. package/fixtures/atelier-knowledge-contract/domain-revision/valid/document.json +45 -0
  194. package/fixtures/atelier-knowledge-contract/evaluation/invalid/document.json +21 -0
  195. package/fixtures/atelier-knowledge-contract/evaluation/valid/document.json +20 -0
  196. package/fixtures/atelier-knowledge-contract/ledger/invalid/document.json +318 -0
  197. package/fixtures/atelier-knowledge-contract/ledger/valid/document.json +317 -0
  198. package/fixtures/atelier-knowledge-contract/relation/invalid/document.json +25 -0
  199. package/fixtures/atelier-knowledge-contract/relation/valid/document.json +24 -0
  200. package/fixtures/atelier-knowledge-contract/review/invalid/document.json +18 -0
  201. package/fixtures/atelier-knowledge-contract/review/valid/document.json +17 -0
  202. package/fixtures/atelier-knowledge-contract/withdrawal/invalid/document.json +16 -0
  203. package/fixtures/atelier-knowledge-contract/withdrawal/valid/document.json +15 -0
  204. package/fixtures/atelier-learning/invalid/authority.json +14 -0
  205. package/fixtures/atelier-learning/valid/capture.json +13 -0
  206. package/fixtures/atelier-personal-workspace-contract/manifest/invalid/authority-key.json +17 -0
  207. package/fixtures/atelier-personal-workspace-contract/manifest/invalid/nonempty-ext.json +25 -0
  208. package/fixtures/atelier-personal-workspace-contract/manifest/invalid/wrong-schema.json +22 -0
  209. package/fixtures/atelier-personal-workspace-contract/manifest/valid/manifest.json +22 -0
  210. package/fixtures/atelier-personal-workspace-contract/overlay/invalid/authority-key.json +25 -0
  211. package/fixtures/atelier-personal-workspace-contract/overlay/invalid/unknown-top-level-field.json +27 -0
  212. package/fixtures/atelier-personal-workspace-contract/overlay/invalid/wrong-schema.json +24 -0
  213. package/fixtures/atelier-trackable/definition/invalid/document.json +15 -0
  214. package/fixtures/atelier-trackable/definition/valid/document.json +14 -0
  215. package/fixtures/atelier-trackable/request/invalid/document.json +23 -0
  216. package/fixtures/atelier-trackable/request/valid/document.json +22 -0
  217. package/fixtures/boundary-delegations/invalid/authority-key.v1.json +30 -0
  218. package/fixtures/boundary-delegations/invalid/push-operation.v1.json +28 -0
  219. package/fixtures/boundary-delegations/invalid/unsigned.v1.json +25 -0
  220. package/fixtures/boundary-delegations/valid/empty.v1.json +4 -0
  221. package/fixtures/boundary-delegations/valid/signed-operator.v1.json +30 -0
  222. package/fixtures/boundary-owner-keys/invalid/wrong-algorithm.v1.json +15 -0
  223. package/fixtures/boundary-owner-keys/invalid/wrong-curve.v1.json +15 -0
  224. package/fixtures/boundary-owner-keys/valid/one-owner.v1.json +17 -0
  225. package/fixtures/capability-packages/adoption.example.json +70 -0
  226. package/fixtures/capability-packages/evidence-review/capability-package.json +58 -0
  227. package/fixtures/capability-packages/evidence-review/capability-release.json +84 -0
  228. package/fixtures/capability-packages/evidence-review/evaluation.md +15 -0
  229. package/fixtures/capability-packages/evidence-review/skills/evidence-review/SKILL.md +22 -0
  230. package/fixtures/capability-packages/evidence-review/skills/evidence-review/references/ledger.md +7 -0
  231. package/fixtures/capability-packages/research/capability-package.json +88 -0
  232. package/fixtures/capability-packages/research/capability-release.json +134 -0
  233. package/fixtures/capability-packages/research/evaluation.md +15 -0
  234. package/fixtures/capability-packages/research/skills/research-integrate/SKILL.md +29 -0
  235. package/fixtures/capability-packages/research/skills/research-integrate/references/integration.md +10 -0
  236. package/fixtures/capability-packages/research/skills/research-plan/SKILL.md +27 -0
  237. package/fixtures/capability-packages/research/skills/research-plan/references/inquiries.md +26 -0
  238. package/fixtures/capability-packages/research/skills/research-synthesize/SKILL.md +23 -0
  239. package/fixtures/capability-packages/research/skills/research-synthesize/references/synthesis.md +12 -0
  240. package/fixtures/evidence-navigation/invalid/duplicate-operation.json +16 -0
  241. package/fixtures/evidence-navigation/invalid/instruction-kind.json +36 -0
  242. package/fixtures/evidence-navigation/invalid/invalid-digest.json +36 -0
  243. package/fixtures/evidence-navigation/invalid/invalid-time.json +36 -0
  244. package/fixtures/evidence-navigation/invalid/missing-attribution.json +35 -0
  245. package/fixtures/evidence-navigation/invalid/reserved-extension.json +19 -0
  246. package/fixtures/evidence-navigation/invalid/unattributed-acceptance.json +36 -0
  247. package/fixtures/evidence-navigation/invalid/uncoerced-version.json +16 -0
  248. package/fixtures/evidence-navigation/invalid/unknown-currency.json +17 -0
  249. package/fixtures/evidence-navigation/invalid/unknown-selector-field.json +37 -0
  250. package/fixtures/evidence-navigation/invalid/unsupported-operation.json +15 -0
  251. package/fixtures/evidence-navigation/valid/claim.json +36 -0
  252. package/fixtures/evidence-navigation/valid/host.json +16 -0
  253. package/fixtures/evidence-navigation/valid/profile.json +16 -0
  254. package/fixtures/evidence-navigation/valid/snapshot.json +17 -0
  255. package/fixtures/harness-packages/build-harness/capability-package.json +61 -0
  256. package/fixtures/harness-packages/build-harness/capability-release.json +82 -0
  257. package/fixtures/harness-packages/build-harness/evaluation.md +3 -0
  258. package/fixtures/harness-packages/build-harness/skills/atelier-build-harness/SKILL.md +59 -0
  259. package/fixtures/harness-packages/knowledge-harness/capability-package.json +61 -0
  260. package/fixtures/harness-packages/knowledge-harness/capability-release.json +82 -0
  261. package/fixtures/harness-packages/knowledge-harness/evaluation.md +3 -0
  262. package/fixtures/harness-packages/knowledge-harness/skills/atelier-knowledge-harness/SKILL.md +60 -0
  263. package/fixtures/harnesses/learning-cycle.json +780 -0
  264. package/fixtures/inquiry/workshop.json +675 -0
  265. package/fixtures/inquiry-packages/discovery-harness/capability-package.json +61 -0
  266. package/fixtures/inquiry-packages/discovery-harness/capability-release.json +82 -0
  267. package/fixtures/inquiry-packages/discovery-harness/evaluation.md +3 -0
  268. package/fixtures/inquiry-packages/discovery-harness/skills/atelier-discovery-harness/SKILL.md +48 -0
  269. package/fixtures/inquiry-packages/research-harness/capability-package.json +61 -0
  270. package/fixtures/inquiry-packages/research-harness/capability-release.json +82 -0
  271. package/fixtures/inquiry-packages/research-harness/evaluation.md +3 -0
  272. package/fixtures/inquiry-packages/research-harness/skills/atelier-research-harness/SKILL.md +43 -0
  273. package/fixtures/knowledge-health/calibration-suite.json +26 -0
  274. package/fixtures/knowledge-health/calibration-trial.json +37 -0
  275. package/fixtures/knowledge-health/corrected/checklist.md +18 -0
  276. package/fixtures/knowledge-health/devday/participant-record.json +19 -0
  277. package/fixtures/knowledge-health/expected-summary.json +27 -0
  278. package/fixtures/knowledge-health/workshop/README.md +20 -0
  279. package/fixtures/knowledge-health/workshop/atelier.project.json +7 -0
  280. package/fixtures/knowledge-health/workshop/knowledge-plan.json +65 -0
  281. package/fixtures/knowledge-health/workshop/records/checklist.md +18 -0
  282. package/fixtures/knowledge-health/workshop/records/workshop.md +18 -0
  283. package/fixtures/knowledge-health/workshop/repo-access.v1.json +5 -0
  284. package/fixtures/knowledge-health/workspace/atelier.project.json +18 -0
  285. package/fixtures/knowledge-health/workspace/knowledge-plan.json +74 -0
  286. package/fixtures/knowledge-health/workspace/records/checklist.md +18 -0
  287. package/fixtures/knowledge-health/workspace/records/pilot.md +16 -0
  288. package/fixtures/knowledge-health/workspace/repo-access.v1.json +9 -0
  289. package/fixtures/personal-workspace/overlay.json +24 -0
  290. package/fixtures/templates/local-library.v1.json +76 -0
  291. package/fixtures/templates/upgrade-contracts/adoption-policy.v2/invalid.json +16 -0
  292. package/fixtures/templates/upgrade-contracts/adoption-policy.v2/valid.json +13 -0
  293. package/fixtures/templates/upgrade-contracts/migration.v3/invalid.json +24 -0
  294. package/fixtures/templates/upgrade-contracts/migration.v3/valid.json +21 -0
  295. package/fixtures/templates/upgrade-contracts/template-adoption.v1/invalid.json +60 -0
  296. package/fixtures/templates/upgrade-contracts/template-adoption.v1/valid.json +57 -0
  297. package/fixtures/templates/upgrade-contracts/upgrade-plan.v3/invalid.json +85 -0
  298. package/fixtures/templates/upgrade-contracts/upgrade-plan.v3/valid.json +82 -0
  299. package/package.json +60 -5
  300. package/plugins/obsidian/main.js +57 -8
  301. package/plugins/obsidian/manifest.json +1 -1
  302. package/skills/claude/atelier-build-harness/SKILL.md +59 -0
  303. package/skills/claude/atelier-coordination/SKILL.md +32 -0
  304. package/skills/claude/atelier-discovery-harness/SKILL.md +48 -0
  305. package/skills/claude/atelier-guided-upgrade/SKILL.md +29 -0
  306. package/skills/claude/atelier-interaction/SKILL.md +34 -0
  307. package/skills/claude/atelier-knowledge-harness/SKILL.md +60 -0
  308. package/skills/claude/atelier-knowledge-setup/SKILL.md +72 -0
  309. package/skills/claude/atelier-practical-judgment/SKILL.md +64 -0
  310. package/skills/claude/atelier-research-harness/SKILL.md +43 -0
  311. package/skills/claude/atelier-skill-steward/SKILL.md +53 -0
  312. package/skills/claude/atelier-trackables/SKILL.md +40 -0
  313. package/skills/codex/atelier-build-harness/SKILL.md +59 -0
  314. package/skills/codex/atelier-coordination/SKILL.md +32 -0
  315. package/skills/codex/atelier-discovery-harness/SKILL.md +48 -0
  316. package/skills/codex/atelier-guided-upgrade/SKILL.md +29 -0
  317. package/skills/codex/atelier-interaction/SKILL.md +34 -0
  318. package/skills/codex/atelier-knowledge-harness/SKILL.md +60 -0
  319. package/skills/codex/atelier-knowledge-setup/SKILL.md +72 -0
  320. package/skills/codex/atelier-practical-judgment/SKILL.md +64 -0
  321. package/skills/codex/atelier-research-harness/SKILL.md +43 -0
  322. package/skills/codex/atelier-skill-steward/SKILL.md +53 -0
  323. package/skills/codex/atelier-trackables/SKILL.md +40 -0
  324. package/src/architecture/catalog.mjs +355 -0
  325. package/src/architecture/index.mjs +93 -0
  326. package/src/boundary/content-rules.mjs +536 -69
  327. package/src/boundary/delegation-command.mjs +158 -0
  328. package/src/boundary/delegation.mjs +396 -0
  329. package/src/boundary/policy.mjs +185 -64
  330. package/src/build/git.mjs +18 -0
  331. package/src/build/index.mjs +3 -0
  332. package/src/build/ledger.mjs +88 -0
  333. package/src/capabilities/adoption.mjs +381 -0
  334. package/src/capabilities/evidence.mjs +140 -0
  335. package/src/capabilities/files.mjs +124 -0
  336. package/src/capabilities/index.mjs +4 -0
  337. package/src/capabilities/instructions.mjs +250 -0
  338. package/src/capabilities/package.mjs +136 -0
  339. package/src/cli/command-failure.mjs +36 -0
  340. package/src/cli/execute-command.mjs +16 -2
  341. package/src/cli/run.mjs +66 -9
  342. package/src/coauthor/store.mjs +43 -2
  343. package/src/collaboration/proposals.mjs +189 -0
  344. package/src/commands/architecture.mjs +27 -0
  345. package/src/commands/boundary.mjs +3 -0
  346. package/src/commands/capability.mjs +73 -0
  347. package/src/commands/enroll.mjs +3 -0
  348. package/src/commands/harness.mjs +79 -0
  349. package/src/commands/ingest.mjs +39 -0
  350. package/src/commands/init.mjs +4 -1
  351. package/src/commands/inquiry.mjs +66 -0
  352. package/src/commands/knowledge-semantic.mjs +128 -0
  353. package/src/commands/knowledge.mjs +119 -0
  354. package/src/commands/learn.mjs +61 -0
  355. package/src/commands/obsidian.mjs +772 -65
  356. package/src/commands/practice.mjs +24 -0
  357. package/src/commands/setup.mjs +22 -2
  358. package/src/commands/trackable.mjs +19 -0
  359. package/src/contracts/corpus.mjs +30 -0
  360. package/src/coordination/index.mjs +110 -0
  361. package/src/evidence-navigation/contracts.mjs +60 -0
  362. package/src/evidence-navigation/evaluate.mjs +69 -0
  363. package/src/evidence-navigation/generation.mjs +22 -0
  364. package/src/evidence-navigation/index.mjs +2 -0
  365. package/src/evidence-navigation/local.mjs +167 -0
  366. package/src/evidence-navigation/schema.generated.mjs +604 -0
  367. package/src/evidence-navigation/types.mjs +12 -0
  368. package/src/export/atelier-export-contract.mjs +35 -8
  369. package/src/graph/enroll.mjs +248 -0
  370. package/src/graph/graph.mjs +30 -6
  371. package/src/graph/knowledge-graph.mjs +77 -9
  372. package/src/harnesses/contracts.mjs +41 -0
  373. package/src/harnesses/exchange.mjs +154 -0
  374. package/src/harnesses/feedback.mjs +16 -0
  375. package/src/harnesses/history.mjs +37 -0
  376. package/src/harnesses/index.mjs +4 -0
  377. package/src/harnesses/store.mjs +29 -0
  378. package/src/ingestion/contracts.mjs +41 -0
  379. package/src/ingestion/evaluation.mjs +119 -0
  380. package/src/ingestion/optional/composition/index.mjs +171 -0
  381. package/src/ingestion/optional/evaluation/index.mjs +219 -0
  382. package/src/ingestion/optional/graphify/composition-binding.mjs +60 -0
  383. package/src/ingestion/optional/graphify/composition_receiving.py +185 -0
  384. package/src/ingestion/optional/graphify/graphify_supplier.py +938 -0
  385. package/src/ingestion/optional/graphify/json_bridge.py +163 -0
  386. package/src/ingestion/optional/graphify/native-closure-pins.json +275 -0
  387. package/src/ingestion/optional/graphify/native-pins.json +306 -0
  388. package/src/ingestion/optional/graphify/query_receiving.py +209 -0
  389. package/src/ingestion/optional/index.mjs +9 -0
  390. package/src/ingestion/optional/jev/bridge.mjs +166 -0
  391. package/src/ingestion/optional/jev/composition-binding.mjs +116 -0
  392. package/src/ingestion/optional/jev/judgments.mjs +174 -0
  393. package/src/ingestion/optional/jev/native-translation.mjs +32 -0
  394. package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/__init__.py +7 -0
  395. package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/adapter.py +966 -0
  396. package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/artifacts.py +101 -0
  397. package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/projection.py +146 -0
  398. package/src/ingestion/optional/lightrag/composition-binding.mjs +67 -0
  399. package/src/ingestion/optional/vanilla/composition-binding.mjs +102 -0
  400. package/src/ingestion/optional/vanilla/index.mjs +218 -0
  401. package/src/ingestion/optional/vanilla/native-normalization.mjs +187 -0
  402. package/src/ingestion/processors.mjs +218 -0
  403. package/src/ingestion/semantic.mjs +203 -0
  404. package/src/ingestion/store.mjs +372 -0
  405. package/src/inquiry/beliefs.mjs +32 -0
  406. package/src/inquiry/contracts.mjs +23 -0
  407. package/src/inquiry/index.mjs +5 -0
  408. package/src/inquiry/ledger.mjs +135 -0
  409. package/src/inquiry/lenses.mjs +15 -0
  410. package/src/inquiry/projection.mjs +77 -0
  411. package/src/inquiry/store.mjs +35 -0
  412. package/src/intake/read-scope.mjs +12 -0
  413. package/src/intake/store.mjs +69 -6
  414. package/src/interaction/index.mjs +91 -0
  415. package/src/judgment/index.mjs +82 -0
  416. package/src/judgment/practice-evaluation.mjs +70 -0
  417. package/src/judgment/practice.mjs +144 -0
  418. package/src/knowledge/context.mjs +217 -0
  419. package/src/knowledge/index.mjs +5 -0
  420. package/src/knowledge/ingestion.mjs +79 -0
  421. package/src/knowledge/intake.mjs +33 -0
  422. package/src/knowledge/ledger.mjs +110 -0
  423. package/src/knowledge/participatory/guidance.mjs +36 -0
  424. package/src/knowledge/participatory/guided-contribution.mjs +44 -0
  425. package/src/knowledge/participatory/index.mjs +2 -0
  426. package/src/knowledge/participatory/installed-workshop.mjs +108 -0
  427. package/src/knowledge/plan.mjs +67 -0
  428. package/src/knowledge/projection.mjs +43 -0
  429. package/src/knowledge/semantic-operation.mjs +567 -0
  430. package/src/knowledge/sessions.mjs +467 -0
  431. package/src/knowledge/workspace.mjs +295 -0
  432. package/src/knowledge-health/assessment.mjs +165 -0
  433. package/src/knowledge-health/capabilities.mjs +350 -0
  434. package/src/knowledge-health/context.mjs +62 -0
  435. package/src/knowledge-health/example.mjs +47 -0
  436. package/src/knowledge-health/index.mjs +10 -0
  437. package/src/knowledge-health/owner-join.mjs +88 -0
  438. package/src/knowledge-health/proof/common.mjs +24 -0
  439. package/src/knowledge-health/proof/installed-check.mjs +100 -0
  440. package/src/knowledge-health/proof/native-readback.mjs +37 -0
  441. package/src/knowledge-health/proof/rehearse.mjs +68 -0
  442. package/src/knowledge-health/proof/validate-participant.mjs +17 -0
  443. package/src/knowledge-health/proof/verify-native-capture.mjs +14 -0
  444. package/src/knowledge-health/proof/workshop-check.mjs +36 -0
  445. package/src/knowledge-health/rule-identity.mjs +49 -0
  446. package/src/knowledge-health/workshop-composition.mjs +19 -0
  447. package/src/knowledge-health/workshop-profile.mjs +176 -0
  448. package/src/knowledge-health/workshop.mjs +99 -0
  449. package/src/learning/adapters.mjs +68 -0
  450. package/src/learning/assistance.mjs +127 -0
  451. package/src/learning/contracts.mjs +65 -0
  452. package/src/learning/store.mjs +272 -0
  453. package/src/personal-workspace/index.mjs +391 -0
  454. package/src/personal-workspace/selection.mjs +401 -0
  455. package/src/project/config.mjs +8 -0
  456. package/src/project/durable-state.mjs +3 -1
  457. package/src/project/file-class.mjs +1 -1
  458. package/src/project/path-match.mjs +2 -1
  459. package/src/projection/obsidian/edits/apply.mjs +55 -16
  460. package/src/projection/obsidian/materialize/prepare-view.mjs +87 -5
  461. package/src/projection/obsidian/personal-workspace.mjs +519 -0
  462. package/src/projection/obsidian/proposals/adapter.mjs +79 -17
  463. package/src/projection/obsidian/proposals/observation.mjs +50 -4
  464. package/src/projection/obsidian/publication/publisher.mjs +214 -18
  465. package/src/projection/obsidian/publication/vault-list.mjs +4 -3
  466. package/src/projection/obsidian/recovery/index.mjs +4 -1
  467. package/src/projection/obsidian/recovery/store.mjs +160 -7
  468. package/src/projection/obsidian/selection-ui/contribution.mjs +6 -5
  469. package/src/projection/project.mjs +3 -2
  470. package/src/readiness/readiness.mjs +10 -3
  471. package/src/reflection/index.mjs +56 -0
  472. package/src/runtime/obsidian/app-production-seams.mjs +48 -16
  473. package/src/runtime/obsidian/app-registration.mjs +175 -28
  474. package/src/runtime/obsidian/app-restart.mjs +154 -0
  475. package/src/runtime/obsidian/engine.mjs +437 -56
  476. package/src/runtime/obsidian/extension-points.mjs +1 -1
  477. package/src/runtime/obsidian/index.mjs +10 -7
  478. package/src/runtime/obsidian/launch-plan.mjs +7 -4
  479. package/src/runtime/obsidian/lifecycle.mjs +108 -23
  480. package/src/runtime/obsidian/login-item.mjs +335 -0
  481. package/src/runtime/obsidian/machine-settings.mjs +119 -12
  482. package/src/runtime/obsidian/observation.mjs +36 -4
  483. package/src/runtime/obsidian/opening.mjs +173 -38
  484. package/src/runtime/obsidian/personal-selection.mjs +125 -0
  485. package/src/runtime/obsidian/pipeline.mjs +115 -6
  486. package/src/runtime/obsidian/plugin-channel.mjs +11 -3
  487. package/src/runtime/obsidian/plugin-choice.mjs +16 -4
  488. package/src/runtime/obsidian/plugin-drift.mjs +59 -11
  489. package/src/runtime/obsidian/plugin-presence.mjs +14 -1
  490. package/src/runtime/obsidian/private-lock.mjs +39 -4
  491. package/src/runtime/obsidian/process-identity.mjs +20 -10
  492. package/src/runtime/obsidian/project-views.mjs +282 -0
  493. package/src/runtime/obsidian/questions.mjs +48 -0
  494. package/src/runtime/obsidian/release-watch.mjs +56 -0
  495. package/src/runtime/obsidian/service-main.mjs +148 -19
  496. package/src/runtime/obsidian/service-manager-production.mjs +61 -0
  497. package/src/runtime/obsidian/service-managers.mjs +275 -0
  498. package/src/runtime/obsidian/service-record.mjs +87 -23
  499. package/src/runtime/obsidian/service.mjs +102 -9
  500. package/src/runtime/obsidian/startup-adapters.mjs +59 -21
  501. package/src/runtime/obsidian/unheld-evidence.mjs +84 -0
  502. package/src/runtime/obsidian/vault-location.mjs +300 -0
  503. package/src/runtime/obsidian/view-counts.mjs +34 -0
  504. package/src/runtime/obsidian/view-permission.mjs +334 -0
  505. package/src/server/local-sidecar.mjs +169 -2
  506. package/src/server/server.mjs +28 -2
  507. package/src/template-bindings/project.mjs +92 -0
  508. package/src/templates/profile.mjs +225 -0
  509. package/src/trackables/domain.mjs +175 -0
  510. package/src/trackables/store.mjs +114 -0
  511. package/src/ui/control-system.mjs +201 -0
  512. package/src/ui/html-primitives.mjs +3 -0
  513. package/src/ui/knowledge-page.mjs +1388 -0
  514. package/src/upgrade/closure-diagnostics.mjs +135 -0
  515. package/src/upgrade/closure.mjs +649 -0
  516. package/src/upgrade/explanation.mjs +1 -1
  517. package/src/upgrade/template-participant.mjs +171 -0
  518. package/src/upgrade/transaction.mjs +72 -25
  519. package/src/upgrade/upgrade.mjs +20 -7
  520. package/templates/external-project-workspace/pack-lifecycle.json +7 -1
  521. package/templates/knowledge-workspace/.gitattributes +2 -0
  522. package/templates/knowledge-workspace/AGENTS.md +27 -0
  523. package/templates/knowledge-workspace/README.md +44 -0
  524. package/templates/knowledge-workspace/atelier.project.json +22 -0
  525. package/templates/knowledge-workspace/gitignore +6 -0
  526. package/templates/knowledge-workspace/knowledge-plan.json +111 -0
  527. package/templates/knowledge-workspace/knowledge-plan.schema.json +281 -0
  528. package/templates/knowledge-workspace/records/forecast.md +22 -0
  529. package/templates/knowledge-workspace/records/inspection.md +25 -0
  530. package/templates/knowledge-workspace/records/telescope.md +24 -0
  531. package/templates/knowledge-workspace/repo-access.v1.json +9 -0
@@ -0,0 +1,219 @@
1
+ import { createHash } from 'node:crypto'
2
+ import { performance } from 'node:perf_hooks'
3
+
4
+ // Private Q02 execution/assessment sidecar. Existing intake and knowledge owners
5
+ // retain all authoritative records; this module grants no execution permission.
6
+ export const PRESENCE_PROFILES = Object.freeze(['vanilla', 'graphify', 'lightrag', 'jev',
7
+ 'graphify+lightrag', 'graphify+jev', 'lightrag+jev', 'graphify+lightrag+jev'])
8
+ const digest = value => createHash('sha256').update(JSON.stringify(value)).digest('hex')
9
+ const phases = new Set(['cold', 'incremental', 'warm', 'recovery'])
10
+ const terminalStates = new Set(['completed', 'failed', 'unavailable', 'unsupported', 'not-run', 'uncertain'])
11
+ const numberOrNull = value => value === null || Number.isFinite(value) && value >= 0
12
+ const requiredPins = ['installedCandidate', 'corpusDigest', 'targetsDigest', 'routeDigest', 'questionOrderDigest']
13
+
14
+ export function validateExecutionPlan(plan) {
15
+ if (!plan || requiredPins.some(key => typeof plan[key] !== 'string' || !plan[key]) ||
16
+ !Array.isArray(plan.tasks) || !plan.tasks.length) throw new TypeError('Pinned installed target, frozen inputs and explicit task cohort required')
17
+ const ids = new Set()
18
+ for (const task of plan.tasks) {
19
+ if (!task?.id || ids.has(task.id) || !PRESENCE_PROFILES.includes(task.profile) ||
20
+ !phases.has(task.phase) || !task.routeId || !Number.isSafeInteger(task.repetition) || task.repetition < 1 ||
21
+ !task.questionId || !task.cacheState) throw new TypeError('Unique tasks require profile, phase, route, repetition, question and cache state')
22
+ ids.add(task.id)
23
+ }
24
+ return Object.freeze(structuredClone(plan))
25
+ }
26
+
27
+ // Host returns all attempted components, including failures and fallback. Unknown
28
+ // or omitted required charges remain unknown rather than becoming free work.
29
+ export function accountComponents(components) {
30
+ if (!Array.isArray(components)) throw new TypeError('Explicit accounting components required')
31
+ const currencies = new Set(), ids = new Set()
32
+ let knownSubtotal = 0, unknown = false
33
+ for (const item of components) {
34
+ if (!item?.id || ids.has(item.id) || !item.kind || !numberOrNull(item.cost) ||
35
+ !numberOrNull(item.elapsedMs) || typeof item.complete !== 'boolean') throw new TypeError('Unique valid attempted cost components required')
36
+ ids.add(item.id)
37
+ if (item.currency !== null && !/^[A-Z]{3}$/.test(item.currency ?? '')) throw new TypeError('Explicit currency or null required')
38
+ if (item.cost === null || !item.complete) unknown = true
39
+ else knownSubtotal += item.cost
40
+ if (item.cost !== null && item.cost !== 0 && item.currency === null) unknown = true
41
+ if (item.currency !== null) currencies.add(item.currency)
42
+ }
43
+ if (!components.length || currencies.size > 1) unknown = true
44
+ return { totalCost: unknown ? null : knownSubtotal, knownSubtotal,
45
+ currency: currencies.size === 1 ? [...currencies][0] : null,
46
+ complete: !unknown, attemptedComponents: components.length,
47
+ incompleteComponents: components.filter(x => x.cost === null || !x.complete).map(x => x.id),
48
+ unknownOrMixedCurrency: currencies.size > 1 || components.some(x => x.cost !== null && x.cost !== 0 && x.currency === null) }
49
+ }
50
+
51
+ // Separate existing assessor receipts are verified by a trusted receiving host.
52
+ // Producer-supplied assessment fields never enter the useful-answer numerator.
53
+ export function assessmentBinding(record) {
54
+ return { taskId: record.taskId, planDigest: record.planDigest, questionId: record.questionId,
55
+ routeId: record.routeId, resultDigest: record.resultDigest }
56
+ }
57
+ function assessmentReceived(record, receipt, verifyAssessment) {
58
+ if (record.outcome !== 'completed' || typeof verifyAssessment !== 'function' || !receipt) return false
59
+ const binding = assessmentBinding(record)
60
+ if (Object.values(binding).some(x => typeof x !== 'string' || !x) ||
61
+ !receipt.receiptRef || !receipt.assessorRef || !receipt.rubricRef || receipt.bindingDigest !== digest(binding)) return false
62
+ try {
63
+ const verified = verifyAssessment(structuredClone(receipt), structuredClone(binding))
64
+ if (typeof verified?.then === 'function') { Promise.resolve(verified).catch(() => {}); return false }
65
+ return verified?.verified === true && verified?.current === true && !!verified.ownerRef &&
66
+ verified.receiptRef === receipt.receiptRef && verified.bindingDigest === receipt.bindingDigest &&
67
+ receipt.usefulAccepted === true && receipt.supportAccepted === true
68
+ } catch { return false }
69
+ }
70
+
71
+ export function summarizeCohort({ assignedTaskIds, records, sharedComponents = [], assessmentReceipts = [], verifyAssessment }) {
72
+ if (!Array.isArray(assignedTaskIds) || !assignedTaskIds.length || new Set(assignedTaskIds).size !== assignedTaskIds.length ||
73
+ !Array.isArray(records) || !Array.isArray(assessmentReceipts)) throw new TypeError('Complete assigned denominator required')
74
+ const assigned = new Set(assignedTaskIds), observed = new Set(), assessmentTasks = new Set()
75
+ for (const record of records) {
76
+ if (!assigned.has(record.taskId) || observed.has(record.taskId) || !terminalStates.has(record.outcome)) throw new TypeError('Records must uniquely match the assigned cohort')
77
+ observed.add(record.taskId)
78
+ }
79
+ for (const receipt of assessmentReceipts) {
80
+ if (!assigned.has(receipt?.taskId) || assessmentTasks.has(receipt.taskId)) throw new TypeError('Separate assessor receipts must uniquely match assigned tasks')
81
+ assessmentTasks.add(receipt.taskId)
82
+ }
83
+ const useful = records.filter(record => assessmentReceived(record, assessmentReceipts.find(x => x.taskId === record.taskId), verifyAssessment))
84
+ const costs = [...sharedComponents, ...records.flatMap(x => x.components ?? [])]
85
+ let accounting
86
+ try { accounting = accountComponents(costs) }
87
+ catch (error) {
88
+ // Retain malformed/colliding accounting for reconciliation without losing
89
+ // already executed tasks or treating unverified charges as free work.
90
+ accounting = { totalCost: null, knownSubtotal: null, currency: null, complete: false,
91
+ attemptedComponents: costs.length, accountingIssue: error.message, retainedComponents: costs }
92
+ }
93
+ const missing = assignedTaskIds.filter(id => !observed.has(id))
94
+ const complete = !missing.length && records.every(x => Array.isArray(x.components) && x.components.length)
95
+ const totalCost = complete ? accounting.totalCost : null
96
+ return { assigned: assigned.size, observed: observed.size, missing,
97
+ usefulAccepted: useful.length, usefulAcceptedFraction: useful.length / assigned.size,
98
+ failedOrUnavailable: assigned.size - useful.length, accounting: { ...accounting, complete: complete && accounting.complete, totalCost },
99
+ costPerUsefulAcceptedAnswer: totalCost === null || !useful.length ? null : totalCost / useful.length,
100
+ elapsedObservations: records.map(x => ({ taskId: x.taskId, outcome: x.outcome, elapsedMs: x.elapsedMs ?? null })),
101
+ semanticQualityQualified: false, humanAuthorityVerified: false }
102
+ }
103
+
104
+ export function amortizedCosts({ ingestionComponents, queryComponents, queryCounts = [1, 10, 100] }) {
105
+ const initial = accountComponents(ingestionComponents), query = accountComponents(queryComponents)
106
+ return queryCounts.map(count => {
107
+ if (!Number.isSafeInteger(count) || count < 1) throw new TypeError('Positive predeclared query counts required')
108
+ const compatible = initial.currency === query.currency || initial.totalCost === 0 || query.totalCost === 0
109
+ return { queryCount: count, totalCost: initial.totalCost === null || query.totalCost === null || !compatible ? null : initial.totalCost + count * query.totalCost,
110
+ costPerQuery: initial.totalCost === null || query.totalCost === null || !compatible ? null : initial.totalCost / count + query.totalCost,
111
+ assumedWorkload: true, observedDemand: false }
112
+ })
113
+ }
114
+
115
+ /**
116
+ * Admission, native effects, resource bounds and cleanup belong to injected
117
+ * existing host owners. The host enforces per-call provider/CPU/deadline limits.
118
+ * No automatic retry/fallback, provider construction or rubric loading occurs.
119
+ */
120
+ export function createQualificationExecutor({ admit, openTrial, executeTask, closeTrial, appendSidecar,
121
+ receiveAssessment, verifyAssessment,
122
+ monotonic = () => performance.now(), now = () => new Date().toISOString() }) {
123
+ for (const fn of [admit, openTrial, executeTask, closeTrial, appendSidecar]) if (typeof fn !== 'function') throw new TypeError('Actual admission, execution, sidecar and cleanup owners required')
124
+ if ((receiveAssessment !== undefined || verifyAssessment !== undefined) &&
125
+ (typeof receiveAssessment !== 'function' || typeof verifyAssessment !== 'function')) throw new TypeError('Separate assessment receiving and receipt verification owners required together')
126
+ return Object.freeze({ async run(planInput, { signal } = {}) {
127
+ const plan = validateExecutionPlan(planInput), planDigest = digest(plan)
128
+ const admission = await admit({ plan: structuredClone(plan), planDigest, signal })
129
+ if (admission?.planDigest !== planDigest || admission?.executionAllowed !== true ||
130
+ !admission?.ownerRef || !admission?.limitsRef) throw new Error('Existing owner refused or did not bind actual execution admission')
131
+ const records = [], trials = new Map(), sharedComponents = [], terminalCleanup = [], assessmentReceipts = [], componentIds = new Set(), sidecarFailures = []
132
+ const retainComponents = components => {
133
+ accountComponents(components)
134
+ if (components.some(x => componentIds.has(x.id))) throw new Error('Duplicate attempted accounting component across the cohort')
135
+ for (const x of components) componentIds.add(x.id)
136
+ }
137
+ const unknownAttempt = (task, stage, attemptedResult, error) => {
138
+ let id = `${task.id}/${stage}/unreported-attempt`
139
+ while (componentIds.has(id)) id += '/unreported'
140
+ componentIds.add(id)
141
+ return { outcome: 'uncertain', effectStage: stage, attemptedResult,
142
+ reconciliationReason: error?.message ?? 'actual result unreceived',
143
+ components: [{ id, kind: 'unreported-native-attempt', cost: null, currency: null, elapsedMs: null, complete: false }] }
144
+ }
145
+ const save = async (task, result, started, startedAt) => {
146
+ const record = { outcome: result.outcome, components: result.components, effectStage: result.effectStage,
147
+ reconciliationReason: result.reconciliationReason, executionResult: result, resultDigest: null,
148
+ taskId: task.id, profile: task.profile, phase: task.phase, routeId: task.routeId, repetition: task.repetition,
149
+ questionId: task.questionId, cacheState: task.cacheState, planDigest, startedAt, endedAt: now(), elapsedMs: Math.max(0, monotonic() - started),
150
+ qualification: 'unscored-execution-sidecar', admissionOwnerRef: admission.ownerRef }
151
+ // Retain execution before invoking a separate assessor or sidecar sink.
152
+ records.push(record)
153
+ record.executionResult = structuredClone(result)
154
+ record.resultDigest = digest(record.executionResult)
155
+ if (record.outcome === 'completed' && receiveAssessment) {
156
+ try {
157
+ const receipt = await receiveAssessment({ binding: assessmentBinding(record), result: structuredClone(result), plan: structuredClone(plan), signal })
158
+ if (receipt) {
159
+ record.assessmentReceiving = structuredClone(receipt)
160
+ if (receipt.taskId === task.id && receipt.bindingDigest === digest(assessmentBinding(record)) &&
161
+ receipt.receiptRef && receipt.assessorRef && receipt.rubricRef) assessmentReceipts.push(structuredClone(receipt))
162
+ }
163
+ } catch (error) { record.assessmentReceivingError = error.message }
164
+ }
165
+ await appendSidecar(structuredClone(record))
166
+ }
167
+ let failure
168
+ try {
169
+ for (const task of plan.tasks) {
170
+ if (signal?.aborted) break
171
+ const trialKey = `${task.profile}/${task.routeId}/${task.phase}/${task.repetition}`
172
+ if (!trials.has(trialKey)) {
173
+ const started = monotonic(), startedAt = now(), entry = { handle: null, task: structuredClone(task) }
174
+ trials.set(trialKey, entry)
175
+ let opened
176
+ try {
177
+ opened = await openTrial({ task: structuredClone(task), trialKey, planDigest, admission, signal })
178
+ if (opened?.handle) entry.handle = opened.handle
179
+ if (!entry.handle || !Array.isArray(opened.components) || !opened.components.length) throw new Error('Trial owner must return an actual handle and explicit shared accounting')
180
+ retainComponents(opened.components)
181
+ sharedComponents.push(...opened.components)
182
+ } catch (error) {
183
+ await save(task, unknownAttempt(task, 'trial-open', opened ?? error.attemptedResult, error), started, startedAt)
184
+ break
185
+ }
186
+ }
187
+ const started = monotonic(), startedAt = now()
188
+ let result
189
+ try {
190
+ result = await executeTask({ task: structuredClone(task), trial: trials.get(trialKey).handle, planDigest, admission, signal })
191
+ if (!terminalStates.has(result?.outcome) || !Array.isArray(result.components) || !result.components.length) throw new Error('Incomplete host task receipt')
192
+ retainComponents(result.components)
193
+ } catch (error) {
194
+ result = unknownAttempt(task, 'task-execution', result ?? error.attemptedResult, error)
195
+ }
196
+ await save(task, result, started, startedAt)
197
+ if (result.outcome === 'uncertain') break
198
+ }
199
+ } catch (error) { failure = error }
200
+ finally {
201
+ for (const [trialKey, entry] of [...trials].reverse()) {
202
+ let cleanup
203
+ try { cleanup = await closeTrial({ trial: entry.handle, task: entry.task, trialKey, planDigest, admission }) }
204
+ catch (error) { cleanup = { verified: false, outcome: 'cleanup-uncertain', reason: error.message } }
205
+ terminalCleanup.push({ trialKey, ...cleanup })
206
+ }
207
+ try { await appendSidecar({ kind: 'trial-cleanup', planDigest, terminalCleanup, qualification: 'host-reported-not-independently-verified' }) }
208
+ catch (error) { sidecarFailures.push({ stage: 'trial-cleanup', error }); failure ??= error }
209
+ }
210
+ if (failure) {
211
+ // Original sidecar/cleanup failure retains all executed output and custody.
212
+ Object.assign(failure, { records, sharedComponents, assessmentReceipts, terminalCleanup, sidecarFailures, planDigest, retryAuthorized: false })
213
+ throw failure
214
+ }
215
+ return { planDigest, records, sharedComponents, assessmentReceipts, terminalCleanup,
216
+ cohort: summarizeCohort({ assignedTaskIds: plan.tasks.map(x => x.id), records, sharedComponents, assessmentReceipts, verifyAssessment }),
217
+ cleanupVerified: terminalCleanup.every(x => x.verified === true), nativeQualification: false, benefitQualified: false }
218
+ } })
219
+ }
@@ -0,0 +1,60 @@
1
+ /** Private existing-host dispatch receiving; no SDK, process or receipt owner.
2
+ * The dispatcher owns a single selected query, canonical evidence receiving and
3
+ * independently verified host step receipt receiving, including no-hit output.
4
+ */
5
+ export class GraphifyCompositionBindingError extends Error {
6
+ constructor(message, received, cause) {
7
+ super(message, { cause })
8
+ this.name = 'GraphifyCompositionBindingError'
9
+ // Native failures and rejected bridges retain actual outputs/costs. A failed
10
+ // snapshot keeps the original producer object explicitly in error custody.
11
+ try { this.supplierResult = structuredClone(received); this.snapshotState = 'received' }
12
+ catch (snapshotError) { this.supplierResult = received; this.snapshotState = 'failed'; this.snapshotError = snapshotError }
13
+ this.retryAuthorized = false
14
+ }
15
+ }
16
+
17
+ const same = (left, right) => JSON.stringify(left) === JSON.stringify(right)
18
+ const object = value => value !== null && typeof value === 'object' && !Array.isArray(value)
19
+ const artifact = value => object(value) && Object.keys(value).sort().join(',') === 'bytes,path,sha256' &&
20
+ typeof value.path === 'string' && value.path.length > 0 && /^[a-f0-9]{64}$/.test(value.sha256) && Number.isSafeInteger(value.bytes) && value.bytes >= 0
21
+ const sources = value => object(value) && Object.entries(value).every(([id, source]) => id.length > 0 && object(source) &&
22
+ source.sourceId === id && typeof source.path === 'string' && source.path.length > 0 && /^[a-f0-9]{64}$/.test(source.sourceDigest))
23
+ export function createGraphifyCompositionBinding({ dispatch }) {
24
+ if (typeof dispatch !== 'function') throw new TypeError('Existing host Graphify dispatch required')
25
+ const retrieve = async payload => {
26
+ let received
27
+ try { received = await dispatch({ operation: 'retrieve', payload }) }
28
+ catch (cause) { throw new GraphifyCompositionBindingError('Selected Graphify host dispatch failed; reconcile original custody', cause?.supplierResult ?? cause?.receipt ?? null, cause) }
29
+ const envelope = received?.envelope
30
+ const binding = received?.hostVerificationOriginal?.binding
31
+ if (received?.operation !== 'receive-composition' || received.outcome !== 'composition-envelope-received' ||
32
+ !envelope || envelope.provider !== 'graphify' || envelope.nativeOperation !== 'query' ||
33
+ typeof envelope.generation !== 'string' || !envelope.generation || envelope.generation !== received.generationId || !envelope.receiptRef || !envelope.bridgeReceipt ||
34
+ envelope.receiptAssurance !== 'explicit-verified-existing-host-bridge' ||
35
+ !Array.isArray(envelope.hits) || !Array.isArray(envelope.unresolved) ||
36
+ !artifact(envelope.artifactRef) || !artifact(received.compositionArtifact) ||
37
+ !artifact(envelope.supplierQueryReceipt) || !artifact(received.supplierQueryReceipt) ||
38
+ !artifact(envelope.supplierReceivingReceipt) || !artifact(received.supplierReceivingReceipt) ||
39
+ !sources(envelope.sourceBindings) || !sources(binding?.sourceBindings) ||
40
+ !artifact(binding?.queryArtifact) || !artifact(binding?.queryReceiptArtifact) || !artifact(binding?.receivingArtifact) ||
41
+ !same(envelope.supplierQueryReceipt, received.supplierQueryReceipt) ||
42
+ !same(envelope.supplierReceivingReceipt, received.supplierReceivingReceipt) ||
43
+ !same(envelope.receiptRef, received.receiptBridgeOriginal?.receiptRef) ||
44
+ !same(envelope.bridgeReceipt, received.receiptBridgeOriginal?.bridgeReceipt) ||
45
+ received.hostVerificationOriginal?.verified !== true || received.hostVerificationOriginal?.current !== true ||
46
+ binding?.provider !== 'graphify' || binding.generation !== envelope.generation ||
47
+ !same(binding.sourceBindings, envelope.sourceBindings) || !same(binding.queryArtifact, envelope.artifactRef) ||
48
+ !same(binding.queryReceiptArtifact, envelope.supplierQueryReceipt) || !same(binding.receivingArtifact, envelope.supplierReceivingReceipt) ||
49
+ !same(binding.receiptRef, envelope.receiptRef) || !same(binding.bridgeReceipt, envelope.bridgeReceipt) ||
50
+ !Object.hasOwn(binding, 'bridgeUsage') || !Object.hasOwn(received.receiptBridgeOriginal ?? {}, 'usage') ||
51
+ !object(envelope.usage?.bridge) || !Object.hasOwn(envelope.usage.bridge, 'usage') ||
52
+ !same(binding.bridgeUsage, received.receiptBridgeOriginal.usage) || !same(binding.bridgeUsage, envelope.usage.bridge.usage)) {
53
+ throw new GraphifyCompositionBindingError('Original Graphify receiving and actual verified host receipt bridge required', received)
54
+ }
55
+ return structuredClone(envelope)
56
+ }
57
+ return Object.freeze({ bindings: Object.freeze({ retrieve }), operationRoles: Object.freeze({ retrieve: 'retrieve' }),
58
+ hostRequired: Object.freeze(['single-selected-query', 'existing-canonical-evidence-hydration',
59
+ 'independent-current-quote-eligibility', 'actual-verified-existing-host-step-receipt']) })
60
+ }
@@ -0,0 +1,185 @@
1
+ """Private existing-host step receipt receiving. No native dispatch or canonical.
2
+
3
+ Evidence eligibility and a selected operation's actual host receipt are separate.
4
+ The trusted host owns both callbacks; caller JSON cannot supply their authority.
5
+ """
6
+ from __future__ import annotations
7
+ import copy
8
+ import fcntl
9
+ import hashlib
10
+ import json
11
+ import os
12
+ import stat
13
+ import uuid
14
+ from pathlib import Path
15
+ from graphify_supplier import SupplierError, digest, json_safe, require
16
+ from query_receiving import _reference
17
+
18
+
19
+ def _read_artifact(supplier, directory, artifact):
20
+ require(isinstance(artifact, dict) and set(artifact) == {"path", "sha256", "bytes"},
21
+ "COMPOSITION_ARTIFACT", "Original artifact descriptor required")
22
+ path = Path(artifact["path"])
23
+ require(path.parent == directory and not directory.is_symlink()
24
+ and directory.parent == supplier.artifacts and not supplier.artifacts.is_symlink()
25
+ and path.is_file() and not path.is_symlink(), "COMPOSITION_ARTIFACT", "Original owned artifact required")
26
+ # Original op-directory files only; no symlink traversal at any open step.
27
+ root_fd = os.open(supplier.artifacts, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
28
+ directory_fd, file_fd = None, None
29
+ try:
30
+ directory_fd = os.open(directory.name, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=root_fd)
31
+ file_fd = os.open(path.name, os.O_RDONLY | os.O_NOFOLLOW, dir_fd=directory_fd)
32
+ before = os.fstat(file_fd)
33
+ require(stat.S_ISREG(before.st_mode), "COMPOSITION_ARTIFACT", "Regular original artifact required")
34
+ with os.fdopen(file_fd, "rb", closefd=False) as stream:
35
+ raw = stream.read()
36
+ after = os.fstat(file_fd)
37
+ require((before.st_dev, before.st_ino, before.st_size, before.st_mtime_ns, before.st_ctime_ns)
38
+ == (after.st_dev, after.st_ino, after.st_size, after.st_mtime_ns, after.st_ctime_ns),
39
+ "ARTIFACT_DRIFT", "Original artifact changed during readback")
40
+ finally:
41
+ if file_fd is not None: os.close(file_fd)
42
+ if directory_fd is not None: os.close(directory_fd)
43
+ os.close(root_fd)
44
+ require(len(raw) == artifact["bytes"] and hashlib.sha256(raw).hexdigest() == artifact["sha256"],
45
+ "ARTIFACT_DRIFT", "Original artifact differs from retained receiving")
46
+ return json.loads(raw)
47
+
48
+
49
+ def receive_composition(supplier, received_query, *, receipt_bridge, verify_receipt_bridge):
50
+ """Receive exact retained query output through actual existing host receipts.
51
+
52
+ Returns an explicit unreceived result with original output/unknown costs on a
53
+ host callback or late freshness failure. It never substitutes a supplier hash
54
+ for a receipt owner. The JS binding retains that result on its error cause.
55
+ """
56
+ require(callable(receipt_bridge) and callable(verify_receipt_bridge), "COMPOSITION_OWNER",
57
+ "Actual host receipt bridge and independent verifier required")
58
+ require(supplier.lock.acquire(blocking=False), "WRITER_BUSY", "A supplier operation owns receiving")
59
+ lease, details, directory = None, None, None
60
+ try:
61
+ lease = (supplier.artifacts / ".writer.lock").open("a+b")
62
+ try:
63
+ fcntl.flock(lease, fcntl.LOCK_EX | fcntl.LOCK_NB)
64
+ except BlockingIOError as exc:
65
+ raise SupplierError("WRITER_BUSY", "Another process owns this supplier destination") from exc
66
+ received = json_safe(copy.deepcopy(received_query))
67
+ require(isinstance(received, dict) and isinstance(received.get("receivingArtifact"), dict),
68
+ "COMPOSITION_RECEIVING", "Exact retained query receiving required")
69
+ directory = Path(received["receivingArtifact"]["path"]).parent
70
+ original = _read_artifact(supplier, directory, received["receivingArtifact"])
71
+ require(original.get("envelope") == {k: v for k, v in received.items() if k != "receivingArtifact"},
72
+ "COMPOSITION_RECEIVING", "Original receiving envelope readback must agree")
73
+ operation_id = original["queryOperationId"]
74
+ query = supplier.read_capture(operation_id)["receipt"]
75
+ context = original["queryBinding"]
76
+ require(directory == supplier.artifacts / operation_id and query["operation"] == "query"
77
+ and query["status"] == "complete" and received["provider"] == "graphify"
78
+ and received["generation"] == context["generation"] == query["graphGeneration"]
79
+ and context["sourceBindings"] == query["sourceBindings"]
80
+ and received["artifactRef"] == context["queryArtifact"]
81
+ and isinstance(received["hits"], list) and isinstance(received["unresolved"], list),
82
+ "COMPOSITION_RECEIVING", "Original successful query/source/generation required")
83
+ native = _read_artifact(supplier, directory, context["queryArtifact"])
84
+ original_query_receipt = _read_artifact(supplier, directory, context["queryReceiptArtifact"])
85
+ require(query == original_query_receipt and received["usage"] == query.get("usage"),
86
+ "COMPOSITION_RECEIVING", "Original query receipt and usage must agree")
87
+ payload = {**copy.deepcopy(received), "nativeOperation": "query", "nativeResult": native,
88
+ "sourceBindings": copy.deepcopy(context["sourceBindings"]),
89
+ "supplierQueryReceipt": copy.deepcopy(context["queryReceiptArtifact"]),
90
+ "supplierReceivingReceipt": copy.deepcopy(received["receivingArtifact"]),
91
+ "evidenceReceiptRef": copy.deepcopy(received["receiptRef"]), "receiptRef": None,
92
+ "queryUsage": copy.deepcopy(query.get("usage")),
93
+ "usage": {"query": {"receiptArtifact": copy.deepcopy(context["queryReceiptArtifact"]),
94
+ "usage": copy.deepcopy(query.get("usage")), "assurance": query.get("usageAssurance")},
95
+ "receiving": {"artifact": copy.deepcopy(received["receivingArtifact"]), "usage": None},
96
+ "bridge": {"usage": None}},
97
+ "semanticAcceptance": "existing-owner-only", "canonicalMutation": False}
98
+ details = {"operation": "receive-composition", "queryOperationId": operation_id,
99
+ "generationId": context["generation"], "outcome": "composition-envelope-unreceived",
100
+ "originalQueryEnvelope": copy.deepcopy(received), "envelope": payload,
101
+ "supplierQueryReceipt": copy.deepcopy(context["queryReceiptArtifact"]),
102
+ "supplierReceivingReceipt": copy.deepcopy(received["receivingArtifact"]),
103
+ "receiptBridgeOriginal": None, "hostVerificationOriginal": None,
104
+ "authority": "none", "canonicalMutation": False}
105
+ for name in ("historyDigest", "activationRef"):
106
+ if name in context: payload[name] = copy.deepcopy(context[name])
107
+ try:
108
+ supplier._fresh(context["generation"], "graph")
109
+ bridged = json_safe(receipt_bridge(copy.deepcopy(payload), copy.deepcopy(query), copy.deepcopy(original)))
110
+ details["receiptBridgeOriginal"] = copy.deepcopy(bridged)
111
+ require(isinstance(bridged, dict) and _reference(bridged.get("receiptRef"))
112
+ and _reference(bridged.get("bridgeReceipt")) and "usage" in bridged,
113
+ "COMPOSITION_RECEIPT", "Original actual host step/bridge receipts and known or unknown usage required")
114
+ # This local exact-value guard is not owner authentication. It refuses
115
+ # listed paths and bare/sha256:-prefixed lower-case content hashes;
116
+ # other aliases/case/format variants remain the actual verifier's job.
117
+ identifiers = {digest(query), digest(original), digest(native), digest(payload)}
118
+ artifacts = query["artifacts"] + [context["queryReceiptArtifact"], received["receivingArtifact"]]
119
+ for artifact in artifacts:
120
+ identifiers.update((artifact["path"], artifact["sha256"], "sha256:" + artifact["sha256"]))
121
+ for name in ("receiptRef", "bridgeReceipt"):
122
+ reference = bridged[name]
123
+ require(reference["id"] not in identifiers and reference["id"].removeprefix("sha256:") not in identifiers
124
+ and reference["digest"] not in identifiers
125
+ and reference["digest"].removeprefix("sha256:") not in identifiers,
126
+ "COMPOSITION_RECEIPT", "Supplier artifact digests cannot become existing host receipts")
127
+ binding = {"provider": "graphify", "generation": context["generation"],
128
+ "sourceBindings": copy.deepcopy(context["sourceBindings"]),
129
+ "queryArtifact": copy.deepcopy(context["queryArtifact"]),
130
+ "queryReceiptArtifact": copy.deepcopy(context["queryReceiptArtifact"]),
131
+ "receivingArtifact": copy.deepcopy(received["receivingArtifact"]),
132
+ "envelopeDigest": digest(payload), "receiptRef": copy.deepcopy(bridged["receiptRef"]),
133
+ "bridgeReceipt": copy.deepcopy(bridged["bridgeReceipt"]), "bridgeUsage": copy.deepcopy(bridged["usage"])}
134
+ for name in ("historyDigest", "activationRef"):
135
+ if name in context: binding[name] = copy.deepcopy(context[name])
136
+ verdict = json_safe(verify_receipt_bridge(copy.deepcopy(binding), copy.deepcopy(payload), copy.deepcopy(bridged)))
137
+ details["hostVerificationOriginal"] = copy.deepcopy(verdict)
138
+ require(isinstance(verdict, dict) and verdict.get("binding") == binding
139
+ and verdict.get("verified") is True and verdict.get("current") is True,
140
+ "COMPOSITION_BRIDGE_UNVERIFIED", "Independent existing host must bind exact original query/receiving/source/generation/envelope/receipts")
141
+ supplier._fresh(context["generation"], "graph")
142
+ require(supplier.read_capture(operation_id)["receipt"] == query
143
+ and _read_artifact(supplier, directory, received["receivingArtifact"]) == original
144
+ and _read_artifact(supplier, directory, context["queryReceiptArtifact"]) == query,
145
+ "ARTIFACT_DRIFT", "Original query or receiving changed during host receipt receiving")
146
+ payload.update(receiptRef=copy.deepcopy(bridged["receiptRef"]), bridgeReceipt=copy.deepcopy(bridged["bridgeReceipt"]),
147
+ receiptAssurance="explicit-verified-existing-host-bridge")
148
+ payload["usage"]["bridge"] = {"receiptRef": copy.deepcopy(bridged["bridgeReceipt"]), "usage": copy.deepcopy(bridged["usage"])}
149
+ details["outcome"] = "composition-envelope-received"
150
+ except BaseException as exc:
151
+ details["error"] = {"type": type(exc).__name__, "code": getattr(exc, "code", "COMPOSITION_HOST_FAILURE")}
152
+ # Original potentially stale hits remain diagnostic under the original
153
+ # envelope. Refused bridging cannot provide any composition hit.
154
+ payload["hits"] = []
155
+ payload["receiptRef"] = None
156
+ payload["unresolved"].append({"reason": details["error"]["code"], "type": type(exc).__name__})
157
+ if isinstance(details["receiptBridgeOriginal"], dict):
158
+ payload["usage"]["bridge"] = {"receiptRef": copy.deepcopy(details["receiptBridgeOriginal"].get("bridgeReceipt")),
159
+ "usage": copy.deepcopy(details["receiptBridgeOriginal"].get("usage"))}
160
+ if not isinstance(exc, Exception):
161
+ # Control signals remain control signals; preserve originals and
162
+ # costs, capture cancellation if possible, then let finally clean
163
+ # both leases before the same exception reaches the host.
164
+ details["controlSignal"] = {"type": type(exc).__name__, "propagated": True}
165
+ try:
166
+ details["compositionArtifact"] = supplier._write(directory, f"composition-{uuid.uuid4().hex}.json", details)
167
+ except BaseException as capture_error:
168
+ details["captureError"] = {"type": type(capture_error).__name__, "code": getattr(capture_error, "code", "CAPTURE_FAILURE")}
169
+ exc.receipt = copy.deepcopy(details)
170
+ raise
171
+ capture = supplier._write(directory, f"composition-{uuid.uuid4().hex}.json", details)
172
+ return {**details, "compositionArtifact": capture}
173
+ except Exception as exc:
174
+ if isinstance(exc, SupplierError):
175
+ exc.receipt = copy.deepcopy(details) if details else copy.deepcopy(received_query)
176
+ raise
177
+ raise SupplierError("COMPOSITION_RECEIVING_FAILURE", "Host receiving failed; original custody retained", copy.deepcopy(details)) from exc
178
+ except BaseException as exc:
179
+ if not hasattr(exc, "receipt"):
180
+ exc.receipt = copy.deepcopy(details) if details else copy.deepcopy(received_query)
181
+ raise
182
+ finally:
183
+ if lease:
184
+ lease.close()
185
+ supplier.lock.release()