@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
@@ -6,7 +6,7 @@ import { AtelierDiagnosticError } from '../../../project/config.mjs'
6
6
  import { compareText, isoTime } from '../../../runtime/obsidian/documents.mjs'
7
7
  import { ObsidianMaintenanceRefusal } from '../../../runtime/obsidian/errors.mjs'
8
8
  import { readMachineSettings } from '../../../runtime/obsidian/machine-settings.mjs'
9
- import { DEFAULT_ELIGIBILITY, createProductionSeams } from '../../../runtime/obsidian/pipeline.mjs'
9
+ import { createProductionSeams, eligibilityFor } from '../../../runtime/obsidian/pipeline.mjs'
10
10
  import { acquirePrivateGenerationLock, createAbandonmentProof } from '../../../runtime/obsidian/private-lock.mjs'
11
11
  import { OBSIDIAN_EXT_KEY, ObsidianContractRefusal, assertObsidianContract } from '../contracts.mjs'
12
12
  import { SOURCE_APPLY_PRIMITIVES } from '../edits/apply.mjs'
@@ -15,6 +15,8 @@ import { isIdentifier } from '../edits/object-identity.mjs'
15
15
  import { openObjectStore } from '../edits/object-store.mjs'
16
16
  import { decideApply } from '../edits/policy.mjs'
17
17
  import { applyEditLens } from '../edits/regions.mjs'
18
+ import { createCooperativeBudget } from '../materialize/prepare-view.mjs'
19
+ import { PERSONAL_VALIDATION_PENDING, personalOverlayRepoOf } from '../personal-workspace.mjs'
18
20
  import { PublicationRefusal } from '../recovery/store.mjs'
19
21
  import {
20
22
  PROPOSAL_BACKPRESSURE, PROPOSAL_LEDGER_LIMITS, classifyLedgerRead, classifyStoreRefusal, estimateEventLineBytes, isDue, isExhausted, nextAttemptAt, preflightAppend,
@@ -168,7 +170,7 @@ export function createProposalAdapterForOracleTests(primitives = PROPOSAL_ADAPTE
168
170
  // two questions asked of the machine; `proveAbandoned` is the proof a held lock is passed over with.
169
171
  return function createProposalAdapter(options = {}) {
170
172
  const {
171
- crash = () => {}, bounds: boundsInput = {}, limits = PROPOSAL_LEDGER_LIMITS, eligibility = DEFAULT_ELIGIBILITY,
173
+ crash = () => {}, bounds: boundsInput = {}, limits = PROPOSAL_LEDGER_LIMITS, eligibility: fixedEligibility = null,
172
174
  openStore = createProposalStore, objectStore = openObjectStore, isGitIgnored = SOURCE_APPLY_PRIMITIVES.isGitIgnored, proveAbandoned = createAbandonmentProof(), queueCrash = () => {},
173
175
  } = options
174
176
  const bounds = { ...PROPOSAL_BACKPRESSURE, ...boundsInput }
@@ -184,6 +186,12 @@ export function createProposalAdapterForOracleTests(primitives = PROPOSAL_ADAPTE
184
186
  let observation = { key: null, run: null }
185
187
  // Edits whose operation is known not to be a proposal. A cache: losing it costs one read of an object.
186
188
  const notProposals = new Set()
189
+ // Set when an observation found the personal workspace's graph pending: the edits it could not look at are offered
190
+ // again on the next observation, not parked until a full reconciliation.
191
+ let observePendingAgain = false
192
+ // The observation under way, if any. An observation waits between two edits, and what it reads of this adapter
193
+ // (the flag above, the workspace it opens) is read when it begins: so the next one begins when this one has ended.
194
+ let observing = Promise.resolve()
187
195
 
188
196
  // -- the workspace of one call -------------------------------------------
189
197
 
@@ -198,12 +206,31 @@ export function createProposalAdapterForOracleTests(primitives = PROPOSAL_ADAPTE
198
206
  if (!stores.has(scopeId)) stores.set(scopeId, seams.createRecoveryStore({ workspaceRoot, workspaceId, scopeId, repositoryRoots }))
199
207
  return stores.get(scopeId)
200
208
  }
201
- // The canonical graph as it is now and the corpus profile of this machine, built once per call. Throws typed.
209
+ // The canonical graph as it is now and the corpus profile of this machine, built once per call with the notes the
210
+ // machine settings let into a view, as the engine builds it (eligibilityFor). Throws typed.
202
211
  let corpus = null
203
- const currentCorpus = () => (corpus ??= {
204
- graph: seams.buildGraph({ project, eligibility }),
205
- profile: seams.profileFor({ project, workspaceId, audienceAllow: readMachineSettings({ workspaceRoot, workspaceId })?.audienceAllow ?? [] }),
206
- })
212
+ // A pending answer is kept for the call too, so a call that looks at several edits builds at most once.
213
+ let pendingCorpus = null
214
+ const currentCorpus = () => {
215
+ if (corpus !== null) return corpus
216
+ if (pendingCorpus !== null) throw pendingCorpus
217
+ const machine = readMachineSettings({ workspaceRoot, workspaceId })
218
+ corpus = {
219
+ // The engine hands its deferral over: a personal workspace is then never composed on its event loop here.
220
+ graph: (() => {
221
+ try { return seams.buildGraph({ project, eligibility: fixedEligibility ?? eligibilityFor({ machine, project }), deferPersonalValidation: context.deferPersonalValidation === true }) } catch (error) {
222
+ if (error?.code === PERSONAL_VALIDATION_PENDING) pendingCorpus = error
223
+ throw error
224
+ }
225
+ })(),
226
+ profile: seams.profileFor({ project, workspaceId, audienceAllow: machine?.audienceAllow ?? [] }),
227
+ }
228
+ return corpus
229
+ }
230
+ // Whether the personal workspace's graph is pending on this call. Asked only where a graph would be built anyway.
231
+ const personalPending = () => {
232
+ try { currentCorpus(); return false } catch (error) { if (error?.code === PERSONAL_VALIDATION_PENDING) return true; if (isTyped(error)) return false; throw error }
233
+ }
207
234
  // true, false, or null when the canonical graph cannot be read now. The rule is the one source apply asks.
208
235
  const visible = options.isVisible ? (identity) => options.isVisible(identity, context) : ({ repoId, nodeId }) => {
209
236
  let built
@@ -223,6 +250,7 @@ export function createProposalAdapterForOracleTests(primitives = PROPOSAL_ADAPTE
223
250
  return {
224
251
  ...context, recoveryOf, visible, clock, env: env ?? context.env ?? process.env,
225
252
  corpus: currentCorpus,
253
+ personalPending,
226
254
  objects: () => (objects ??= objectStore({ stateRoot: workspaceRoot, workspaceId, repositoryRoots, clock })),
227
255
  queue,
228
256
  managedRoots: () => [workspaceRoot, ...[...stores.values()].map((store) => store.vaultRoot)],
@@ -304,6 +332,8 @@ export function createProposalAdapterForOracleTests(primitives = PROPOSAL_ADAPTE
304
332
  if (requireOpenEdit && editState !== 'open') return known ? refused(`edit-${editState}`) : outcome('skipped', null, { code: `edit-${editState}` })
305
333
  // The object store no longer says this is a proposed structural edit, so there is nothing to describe.
306
334
  if (item.observed === null) return refused('operation-not-proposed')
335
+ // A personal workspace whose graph is pending leaves the operation as it is: no attempt is spent on this tick.
336
+ if (workspace.deferPersonalValidation === true && personalOverlayRepoOf(workspace.project) !== null && workspace.personalPending()) return outcome('deferred', history?.head ?? null, { code: PERSONAL_VALIDATION_PENDING })
307
337
  const resolved = resolveProposalRoute({ project: workspace.project, workspaceId: workspace.workspaceId, identity: item, sourcePath: item.sourcePath, managedRoots: workspace.managedRoots(), isVisible: workspace.visible, isGitIgnored, env: env ?? workspace.env ?? process.env })
308
338
  if (!resolved.ok && !resolved.transient) return refused(resolved.code)
309
339
  // Recorded before anything is asked of the store.
@@ -405,10 +435,13 @@ export function createProposalAdapterForOracleTests(primitives = PROPOSAL_ADAPTE
405
435
 
406
436
  // One repository: its lock, then each of its operations in turn. What goes wrong with one repository, or with one
407
437
  // operation, is reported by its code and stops nothing else.
408
- async function settleRepository(workspace, repoId, works, report) {
438
+ // `budget`, when a tick hands one over, gives the event loop a turn between two operations: each operation is
439
+ // settled without interruption, and the lock of the repository is held from the first to the last.
440
+ async function settleRepository(workspace, repoId, works, report, budget = null) {
409
441
  try {
410
- const held = await withRepositoryLock(workspace, repoId, () => {
411
- for (const work of works) {
442
+ const held = await withRepositoryLock(workspace, repoId, async () => {
443
+ for (const [index, work] of works.entries()) {
444
+ if (budget !== null && index > 0) await budget.checkpoint('settle-operation', true)
412
445
  try { report.outcomes.push(settleOne(workspace, work.item, work)) } catch (error) {
413
446
  if (error?.crashSeam === true || !isTyped(error)) throw error
414
447
  report.outcomes.push({ status: 'failed', code: error.code, editId: work.item.editId, repoId, nodeId: work.item.nodeId, adapterOperationId: work.item.adapterOperationId, state: null, proposalId: null })
@@ -422,6 +455,26 @@ export function createProposalAdapterForOracleTests(primitives = PROPOSAL_ADAPTE
422
455
  }
423
456
  }
424
457
 
458
+ // One observation, from opening the workspace to the flag it leaves for the next.
459
+ async function observeNow(context, { retryRefused = false } = {}) {
460
+ const workspace = open(context)
461
+ const edits = Array.isArray(context.edits) ? context.edits : []
462
+ // A private note of a personal workspace lives in a generation the personal-workspace module owns: its edit is
463
+ // not observed, recorded or proposed, and stays held in the vault. Answered by name, with nothing written.
464
+ const overlayRepoId = personalOverlayRepoOf(workspace.project)
465
+ const isPrivate = (edit) => overlayRepoId !== null && edit?.identity?.repoId === overlayRepoId
466
+ const privateNotes = edits.filter((edit) => isPrivate(edit) && edit.closedAt === null)
467
+ .map((edit) => ({ editId: edit.editId, repoId: edit.identity.repoId, nodeId: edit.identity.nodeId, status: 'refused', code: 'personal-overlay-not-proposed' }))
468
+ const shared = edits.filter((edit) => !isPrivate(edit))
469
+ // The graph is built only when an edit is looked at, as for any project. When the personal workspace's graph is
470
+ // pending, the edits it reached are not reported or recorded, and are offered again on the next observation.
471
+ const retry = retryRefused || observePendingAgain
472
+ const looked = await observation.run.cooperatively(workspace, { edits: shared, retryRefused: retry })
473
+ const pending = looked.filter((item) => item.code === PERSONAL_VALIDATION_PENDING)
474
+ observePendingAgain = pending.length > 0
475
+ return { adapterId: PROPOSAL_ADAPTER_ID, observed: [...privateNotes, ...looked.filter((item) => item.code !== PERSONAL_VALIDATION_PENDING)], ...(pending.length > 0 ? { deferred: PERSONAL_VALIDATION_PENDING } : {}) }
476
+ }
477
+
425
478
  return {
426
479
  id: PROPOSAL_ADAPTER_ID,
427
480
 
@@ -429,10 +482,10 @@ export function createProposalAdapterForOracleTests(primitives = PROPOSAL_ADAPTE
429
482
  // observed from its preserved bytes against the source as it is now and recorded as what it is, a bounded number
430
483
  // per tick and never twice. `retryRefused` offers once more the edits whose observation refused before anything
431
484
  // could be recorded. Writes no source and no vault. Returns codes and identifiers only.
432
- async observe(context, { retryRefused = false } = {}) {
433
- const workspace = open(context)
434
- const edits = Array.isArray(context.edits) ? context.edits : []
435
- return { adapterId: PROPOSAL_ADAPTER_ID, observed: observation.run(workspace, { edits, retryRefused }) }
485
+ observe(context, options = {}) {
486
+ const run = observing.then(() => observeNow(context, options))
487
+ observing = run.catch(() => {})
488
+ return run
436
489
  },
437
490
 
438
491
  // The tick. `context` is { project, workspaceRoot, workspaceId, repositoryRoots, edits }: the pending edit
@@ -442,6 +495,9 @@ export function createProposalAdapterForOracleTests(primitives = PROPOSAL_ADAPTE
442
495
  const nowMs = Date.parse(isoTime(clock))
443
496
  const report = { adapterId: PROPOSAL_ADAPTER_ID, examined: 0, outcomes: [], repositories: [] }
444
497
  const edits = Array.isArray(context.edits) ? context.edits : []
498
+ // The tick goes on answering while it routes: a turn of the event loop when describing has taken its share
499
+ // of time, and one before each repository and between two of its operations.
500
+ const budget = createCooperativeBudget()
445
501
  const { operations: heads, unreadable } = workspace.queue().heads()
446
502
  for (const item of unreadable) report.repositories.push({ repoId: null, code: item.code })
447
503
  const byEdit = new Map(edits.map((edit) => [edit.editId, edit]))
@@ -458,7 +514,8 @@ export function createProposalAdapterForOracleTests(primitives = PROPOSAL_ADAPTE
458
514
  const editState = edit === null || edit.closedAt === null ? 'open' : ['withdrawn', 'superseded'].includes(edit.state) ? edit.state : 'closed'
459
515
  let item = itemOfHead(head, edit)
460
516
  if (edit !== null && head.state !== 'submitted') {
461
- try { item = { ...item, ...(describe(workspace, edit) ?? {}) } } catch (error) { if (!isTyped(error)) throw error; report.outcomes.push({ status: 'failed', code: error.code, editId: head.editId, repoId: head.repoId, nodeId: head.nodeId, adapterOperationId: head.adapterOperationId, state: head.state, proposalId: null }); continue }
517
+ try { item = { ...item, ...(describe(workspace, edit) ?? {}) } } catch (error) { if (!isTyped(error)) throw error; report.outcomes.push({ status: 'failed', code: error.code, editId: head.editId, repoId: head.repoId, nodeId: head.nodeId, adapterOperationId: head.adapterOperationId, state: head.state, proposalId: null }); await budget.checkpoint('describe-operation'); continue }
518
+ await budget.checkpoint('describe-operation')
462
519
  }
463
520
  add(head.repoId, { item, editState })
464
521
  }
@@ -471,11 +528,16 @@ export function createProposalAdapterForOracleTests(primitives = PROPOSAL_ADAPTE
471
528
  for (const edit of looked) {
472
529
  report.examined += 1
473
530
  let item
474
- try { item = describe(workspace, edit) } catch (error) { if (!isTyped(error)) throw error; report.outcomes.push({ status: 'failed', code: error.code, editId: edit.editId, repoId: edit.identity.repoId, nodeId: edit.identity.nodeId, adapterOperationId: null, state: null, proposalId: null }); continue }
531
+ try { item = describe(workspace, edit) } catch (error) { if (!isTyped(error)) throw error; report.outcomes.push({ status: 'failed', code: error.code, editId: edit.editId, repoId: edit.identity.repoId, nodeId: edit.identity.nodeId, adapterOperationId: null, state: null, proposalId: null }); await budget.checkpoint('describe-edit'); continue }
475
532
  if (item !== null) add(item.repoId, { item, editState: 'open' })
533
+ await budget.checkpoint('describe-edit')
476
534
  }
477
535
 
478
- for (const [repoId, list] of [...works].sort(([left], [right]) => compareText(left, right))) await settleRepository(workspace, repoId, list, report)
536
+ for (const [repoId, list] of [...works].sort(([left], [right]) => compareText(left, right))) {
537
+ await budget.checkpoint('settle-repository', true)
538
+ await settleRepository(workspace, repoId, list, report, budget)
539
+ }
540
+ budget.finish('propose-finalize')
479
541
  return report
480
542
  },
481
543
 
@@ -10,6 +10,7 @@ import { SOURCE_APPLY_PRIMITIVES, SourceApplyRefusal, locateSource } from '../ed
10
10
  import { EditArbitrationRefusal } from '../edits/arbitrate.mjs'
11
11
  import { createEditObserverForOracleTests, editIdempotencyKey, observeEdit } from '../edits/observe.mjs'
12
12
  import { decideApply } from '../edits/policy.mjs'
13
+ import { createCooperativeBudget } from '../materialize/prepare-view.mjs'
13
14
  import { PublicationRefusal, readFileBytes, sha256Digest } from '../recovery/store.mjs'
14
15
  import { PROPOSAL_BACKPRESSURE } from './backpressure.mjs'
15
16
 
@@ -38,6 +39,14 @@ import { PROPOSAL_BACKPRESSURE } from './backpressure.mjs'
38
39
  // reconciliation cadence, never on every tick. A bounded number of edits is
39
40
  // looked at per tick, in the order they were observed, starting where the last
40
41
  // tick stopped.
42
+ //
43
+ // One edit is one unit: it is read, judged and recorded without interruption.
44
+ // Between two edits the cooperative form (`cooperatively`, which the adapter
45
+ // uses on a tick) gives the event loop a turn, so the process that runs the
46
+ // tick goes on answering while a burst of edits is observed. A second
47
+ // cooperative observation waits for the first to finish; what is looked at,
48
+ // and in what order, is the same in both forms. The uninterrupted form
49
+ // cannot wait, so it refuses to run beside a cooperative one.
41
50
 
42
51
  const EXT = OBSIDIAN_EXT_KEY
43
52
  const GONE = new Set(['ENOENT', 'ENOTDIR', 'ELOOP'])
@@ -126,6 +135,11 @@ export function createTickObservation(options = {}) {
126
135
  // The note exactly as it was published, which the lens needs to tell generated bytes from authored ones. The
127
136
  // publisher keeps no copy of a note it created, so the note is prepared again from the sources as they are now and
128
137
  // used only when it has the digest the manifest recorded; a retained object of that digest serves as well.
138
+ //
139
+ // A source replaced between the look at its path and its open (ELEAFCHANGED) is another program writing it, as it
140
+ // is to the publisher and to source apply: the preparation answers null, and the caller reads the source again and
141
+ // refuses stale-source when it changed. Only a preparation that succeeded is kept for its scope and generation: one
142
+ // failure tells of one moment and is never the answer for the other edits of that generation in the tick.
129
143
  function publishedNoteOf(workspace, { scope, manifest, noteEntry }, now) {
130
144
  const store = workspace.recoveryOf(scope.scopeId)
131
145
  const kept = retained(store, noteEntry.noteDigest)
@@ -134,7 +148,7 @@ export function createTickObservation(options = {}) {
134
148
  // Prepared in the vault layout of the edit's generation, once per generation.
135
149
  const preparedKey = `${scope.scopeId}\u0000${manifest.generationId}`
136
150
  if (!workspace.prepared.has(preparedKey)) {
137
- let files = []
151
+ let files
138
152
  try {
139
153
  const { graph, profile } = workspace.corpus()
140
154
  const snapshot = seams.captureSnapshot({ project: workspace.project, graph, workspaceId: workspace.workspaceId, index: new Map(), configDigest: manifest.ext?.[EXT]?.configDigest ?? `sha256:${'0'.repeat(64)}`, capturedAt: now })
@@ -143,7 +157,10 @@ export function createTickObservation(options = {}) {
143
157
  snapshot, profile, scope, persistentPathRegistry, priorManifest: manifest, existingSettings: null, clock: workspace.clock,
144
158
  vaultRootBytes: Buffer.byteLength(store.vaultRoot, 'utf8'), layout: manifestLayoutVersion(manifest),
145
159
  }).files
146
- } catch (error) { if (!isTyped(error) && !GONE.has(error?.code)) throw error }
160
+ } catch (error) {
161
+ if (!isTyped(error) && error?.code !== 'ELEAFCHANGED' && !GONE.has(error?.code)) throw error
162
+ return null
163
+ }
147
164
  workspace.prepared.set(preparedKey, files)
148
165
  }
149
166
  const file = workspace.prepared.get(preparedKey).find((item) => item.path === noteEntry.path && item.digest === noteEntry.noteDigest)
@@ -195,7 +212,8 @@ export function createTickObservation(options = {}) {
195
212
  // `workspace` is the opened workspace of the adapter; `edits` the pending edit records, open and closed;
196
213
  // `retryRefused` offers the edits whose observation refused earlier once more. Returns one entry per edit looked
197
214
  // at: { editId, repoId, nodeId, status: 'observed' | 'refused', code, kind?, operationState?, idempotencyKey? }.
198
- return function observePendingEdits(workspace, { edits, retryRefused = false }) {
215
+ // Yields between two edits, never within one, and returns the entries when it is done.
216
+ function* observeSteps(workspace, { edits, retryRefused = false }) {
199
217
  if (retryRefused) unobservable.clear()
200
218
  const now = isoTime(workspace.clock)
201
219
  const candidates = edits.filter((edit) => edit.closedAt === null && OPEN_EDIT_STATES.includes(edit.state) && !recorded.has(edit.editId) && !unobservable.has(edit.editId))
@@ -204,7 +222,8 @@ export function createTickObservation(options = {}) {
204
222
  const looked = [...candidates.slice(start), ...candidates.slice(0, start)].slice(0, bounds.maxObservedPerTick)
205
223
  cursor = candidates.length > bounds.maxObservedPerTick ? start + looked.length : 0
206
224
  const observed = []
207
- for (const edit of looked) {
225
+ for (const [index, edit] of looked.entries()) {
226
+ if (index > 0) yield 'observe-edit'
208
227
  const entry = { editId: edit.editId, repoId: edit.identity.repoId, nodeId: edit.identity.nodeId }
209
228
  try {
210
229
  const outcome = observeOne(workspace, edit, now)
@@ -218,4 +237,31 @@ export function createTickObservation(options = {}) {
218
237
  }
219
238
  return observed
220
239
  }
240
+
241
+ // Cooperative observations asked for and not yet finished, and the last of them.
242
+ let underWay = 0
243
+ let last = Promise.resolve()
244
+ function observePendingEdits(workspace, input) {
245
+ if (underWay > 0) throw Object.assign(new Error('a cooperative observation of this instance is under way; the uninterrupted form cannot run beside it'), { code: 'observation-under-way' })
246
+ const steps = observeSteps(workspace, input)
247
+ for (;;) { const step = steps.next(); if (step.done) return step.value }
248
+ }
249
+ // The same observation with a turn of the event loop between two edits. One at a time: an observation asked for
250
+ // while another is under way starts when that one has finished, so no edit is looked at by both. One that failed
251
+ // holds back none that follow.
252
+ observePendingEdits.cooperatively = (workspace, input) => {
253
+ underWay += 1
254
+ const run = last.then(async () => {
255
+ const budget = createCooperativeBudget()
256
+ const steps = observeSteps(workspace, input)
257
+ for (;;) {
258
+ const step = steps.next()
259
+ if (step.done) { budget.finish('observe-finalize'); return step.value }
260
+ await budget.checkpoint(step.value, true)
261
+ }
262
+ }).finally(() => { underWay -= 1 })
263
+ last = run.catch(() => {})
264
+ return run
265
+ }
266
+ return observePendingEdits
221
267
  }