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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (560) hide show
  1. package/CHANGELOG.md +1005 -0
  2. package/README.md +149 -9
  3. package/contracts/atelier-adoption-policy.v2.schema.json +55 -0
  4. package/contracts/atelier-architecture.v1.schema.json +258 -0
  5. package/contracts/atelier-boundary-delegations.v1.schema.json +161 -0
  6. package/contracts/atelier-boundary-owner-keys.v1.schema.json +98 -0
  7. package/contracts/atelier-build.v1.schema.json +1076 -0
  8. package/contracts/atelier-capability.v1.schema.json +1252 -0
  9. package/contracts/atelier-coordination.v1.schema.json +1050 -0
  10. package/contracts/atelier-evidence-navigation.v1.schema.json +603 -0
  11. package/contracts/atelier-harness.v1.schema.json +234 -0
  12. package/contracts/atelier-ingestion.v1.schema.json +806 -0
  13. package/contracts/atelier-inquiry.v1.schema.json +1772 -0
  14. package/contracts/atelier-instruction-adoption.v1.schema.json +490 -0
  15. package/contracts/atelier-interaction.v1.schema.json +553 -0
  16. package/contracts/atelier-judgment.v1.schema.json +690 -0
  17. package/contracts/atelier-knowledge.v1.schema.json +1512 -0
  18. package/contracts/atelier-learning.v1.schema.json +1095 -0
  19. package/contracts/atelier-migration.v3.schema.json +64 -0
  20. package/contracts/atelier-obsidian-generation-manifest.v2.schema.json +372 -0
  21. package/contracts/atelier-personal-workspace-manifest.v1.schema.json +87 -0
  22. package/contracts/atelier-personal-workspace-overlay.v1.schema.json +299 -0
  23. package/contracts/atelier-template-adoption.v1.schema.json +223 -0
  24. package/contracts/atelier-template-profile.v1.schema.json +1168 -0
  25. package/contracts/atelier-trackable.v1.schema.json +781 -0
  26. package/contracts/atelier-upgrade-plan.v3.schema.json +532 -0
  27. package/contracts/compat-baseline.json +1 -1
  28. package/docs/architecture.md +89 -0
  29. package/docs/assurance-controls.md +4 -3
  30. package/docs/blocks/capability-stewardship.md +17 -0
  31. package/docs/blocks/claims.md +16 -3
  32. package/docs/blocks/inquiry-harnesses.md +19 -0
  33. package/docs/blocks/learning-harnesses.md +17 -0
  34. package/docs/capability-stewardship.md +269 -0
  35. package/docs/coordination.md +51 -0
  36. package/docs/decision-practices.md +111 -0
  37. package/docs/decisions.md +29 -0
  38. package/docs/evidence-navigation.md +237 -0
  39. package/docs/exact-upgrades.md +3 -2
  40. package/docs/ingestion.md +181 -0
  41. package/docs/inquiry-harnesses.md +211 -0
  42. package/docs/install.md +80 -3
  43. package/docs/intake-and-guides.md +5 -0
  44. package/docs/integration-contract-decisions.md +24 -2
  45. package/docs/interaction-and-reflection.md +72 -0
  46. package/docs/knowledge-graph.md +20 -0
  47. package/docs/knowledge-health/api.md +30 -0
  48. package/docs/knowledge-health/assessment/api.md +96 -0
  49. package/docs/knowledge-health/assessment/capabilities.md +40 -0
  50. package/docs/knowledge-health/assessment/evaluation.md +27 -0
  51. package/docs/knowledge-health/assessment/facilitator.md +30 -0
  52. package/docs/knowledge-health/assessment/quickstart.md +61 -0
  53. package/docs/knowledge-health/assessment/troubleshooting.md +23 -0
  54. package/docs/knowledge-health/devday/facilitator.md +16 -0
  55. package/docs/knowledge-health/devday/participant-response.md +22 -0
  56. package/docs/knowledge-health/devday/public-default.md +107 -0
  57. package/docs/knowledge-health/devday/quickstart.md +18 -0
  58. package/docs/knowledge-health/devday/support.md +22 -0
  59. package/docs/knowledge-health/exercise.md +17 -0
  60. package/docs/knowledge-health/facilitator.md +20 -0
  61. package/docs/knowledge-health/quickstart.md +94 -0
  62. package/docs/knowledge-health/readme.md +15 -0
  63. package/docs/knowledge-health/support.md +34 -0
  64. package/docs/knowledge-setup.md +248 -0
  65. package/docs/knowledge-workspace.md +264 -0
  66. package/docs/learning-harnesses.md +238 -0
  67. package/docs/learning.md +215 -0
  68. package/docs/local-services.md +242 -26
  69. package/docs/obsidian-contract.md +878 -36
  70. package/docs/obsidian-plugin.md +619 -0
  71. package/docs/obsidian.md +809 -64
  72. package/docs/optional-ingestion.md +83 -0
  73. package/docs/personal-workspace.md +257 -0
  74. package/docs/practical-judgment.md +92 -0
  75. package/docs/progressive-ingestion-acceptance.md +89 -0
  76. package/docs/progressive-ingestion.md +235 -0
  77. package/docs/project-command-inventory.md +1 -0
  78. package/docs/release-engineering.md +56 -1
  79. package/docs/repo-boundary-guard.md +94 -0
  80. package/docs/research-starter-quickstart.md +66 -0
  81. package/docs/research-starter.md +114 -0
  82. package/docs/semantic-ingestion.md +198 -0
  83. package/docs/semantic-operation.md +317 -0
  84. package/docs/skill-steward.md +6 -0
  85. package/docs/template-profile.md +164 -0
  86. package/docs/template-upgrades.md +114 -0
  87. package/docs/trackables.md +111 -0
  88. package/docs/upgrade.md +68 -3
  89. package/fixtures/atelier-architecture/binding/invalid/document.json +19 -0
  90. package/fixtures/atelier-architecture/binding/valid/document.json +19 -0
  91. package/fixtures/atelier-architecture/catalog/invalid/document.json +290 -0
  92. package/fixtures/atelier-architecture/catalog/valid/document.json +343 -0
  93. package/fixtures/atelier-build-contract/attempt/invalid/document.json +20 -0
  94. package/fixtures/atelier-build-contract/attempt/valid/document.json +19 -0
  95. package/fixtures/atelier-build-contract/candidate/invalid/document.json +24 -0
  96. package/fixtures/atelier-build-contract/candidate/valid/document.json +23 -0
  97. package/fixtures/atelier-build-contract/decision/invalid/document.json +31 -0
  98. package/fixtures/atelier-build-contract/decision/valid/document.json +30 -0
  99. package/fixtures/atelier-build-contract/delivery/invalid/document.json +18 -0
  100. package/fixtures/atelier-build-contract/delivery/valid/document.json +17 -0
  101. package/fixtures/atelier-build-contract/gate/invalid/document.json +22 -0
  102. package/fixtures/atelier-build-contract/gate/valid/document.json +21 -0
  103. package/fixtures/atelier-build-contract/ledger/invalid/document.json +270 -0
  104. package/fixtures/atelier-build-contract/ledger/valid/document.json +269 -0
  105. package/fixtures/atelier-build-contract/objective/invalid/document.json +73 -0
  106. package/fixtures/atelier-build-contract/objective/valid/document.json +72 -0
  107. package/fixtures/atelier-build-contract/progress/invalid/document.json +18 -0
  108. package/fixtures/atelier-build-contract/progress/valid/document.json +17 -0
  109. package/fixtures/atelier-capability-contract/adoption/invalid/document.json +71 -0
  110. package/fixtures/atelier-capability-contract/adoption/valid/document.json +70 -0
  111. package/fixtures/atelier-capability-contract/event/invalid/document.json +18 -0
  112. package/fixtures/atelier-capability-contract/event/valid/document.json +17 -0
  113. package/fixtures/atelier-capability-contract/journal/invalid/document.json +382 -0
  114. package/fixtures/atelier-capability-contract/journal/valid/document.json +381 -0
  115. package/fixtures/atelier-capability-contract/notice/invalid/document.json +8 -0
  116. package/fixtures/atelier-capability-contract/notice/valid/document.json +7 -0
  117. package/fixtures/atelier-capability-contract/package/invalid/document.json +59 -0
  118. package/fixtures/atelier-capability-contract/package/valid/document.json +58 -0
  119. package/fixtures/atelier-capability-contract/plan/invalid/document.json +107 -0
  120. package/fixtures/atelier-capability-contract/plan/valid/document.json +106 -0
  121. package/fixtures/atelier-capability-contract/release/invalid/document.json +85 -0
  122. package/fixtures/atelier-capability-contract/release/valid/document.json +84 -0
  123. package/fixtures/atelier-capability-contract/state/invalid/document.json +316 -0
  124. package/fixtures/atelier-capability-contract/state/valid/document.json +315 -0
  125. package/fixtures/atelier-coordination/dependency/invalid/document.json +37 -0
  126. package/fixtures/atelier-coordination/dependency/valid/document.json +36 -0
  127. package/fixtures/atelier-coordination/directive/invalid/document.json +25 -0
  128. package/fixtures/atelier-coordination/directive/valid/document.json +24 -0
  129. package/fixtures/atelier-coordination/disposition/invalid/document.json +34 -0
  130. package/fixtures/atelier-coordination/disposition/valid/document.json +33 -0
  131. package/fixtures/atelier-coordination/outcome/invalid/document.json +39 -0
  132. package/fixtures/atelier-coordination/outcome/valid/document.json +38 -0
  133. package/fixtures/atelier-coordination/recovery/invalid/document.json +34 -0
  134. package/fixtures/atelier-coordination/recovery/valid/document.json +33 -0
  135. package/fixtures/atelier-harness-contract/handoff/invalid/document.json +25 -0
  136. package/fixtures/atelier-harness-contract/handoff/valid/document.json +24 -0
  137. package/fixtures/atelier-ingestion/invalid/authority.json +19 -0
  138. package/fixtures/atelier-ingestion/semantic-baseline.json +26 -0
  139. package/fixtures/atelier-ingestion/semantic-operation.json +75 -0
  140. package/fixtures/atelier-ingestion/valid/plan-input.json +18 -0
  141. package/fixtures/atelier-inquiry-contract/assessment/invalid/document.json +41 -0
  142. package/fixtures/atelier-inquiry-contract/assessment/valid/document.json +40 -0
  143. package/fixtures/atelier-inquiry-contract/bundle/invalid/document.json +51 -0
  144. package/fixtures/atelier-inquiry-contract/bundle/valid/document.json +50 -0
  145. package/fixtures/atelier-inquiry-contract/campaign/invalid/document.json +17 -0
  146. package/fixtures/atelier-inquiry-contract/campaign/valid/document.json +16 -0
  147. package/fixtures/atelier-inquiry-contract/decision/invalid/document.json +22 -0
  148. package/fixtures/atelier-inquiry-contract/decision/valid/document.json +21 -0
  149. package/fixtures/atelier-inquiry-contract/feedback/invalid/document.json +19 -0
  150. package/fixtures/atelier-inquiry-contract/feedback/valid/document.json +18 -0
  151. package/fixtures/atelier-inquiry-contract/handoff/invalid/document.json +92 -0
  152. package/fixtures/atelier-inquiry-contract/handoff/valid/document.json +91 -0
  153. package/fixtures/atelier-inquiry-contract/hypothesis/invalid/document.json +20 -0
  154. package/fixtures/atelier-inquiry-contract/hypothesis/valid/document.json +19 -0
  155. package/fixtures/atelier-inquiry-contract/ledger/invalid/document.json +680 -0
  156. package/fixtures/atelier-inquiry-contract/ledger/valid/document.json +679 -0
  157. package/fixtures/atelier-inquiry-contract/legacy-assessment/invalid/document.json +19 -0
  158. package/fixtures/atelier-inquiry-contract/legacy-assessment/valid/document.json +18 -0
  159. package/fixtures/atelier-inquiry-contract/request/invalid/document.json +50 -0
  160. package/fixtures/atelier-inquiry-contract/request/valid/document.json +49 -0
  161. package/fixtures/atelier-inquiry-contract/source/invalid/document.json +18 -0
  162. package/fixtures/atelier-inquiry-contract/source/valid/document.json +17 -0
  163. package/fixtures/atelier-inquiry-contract/withdrawal/invalid/document.json +16 -0
  164. package/fixtures/atelier-inquiry-contract/withdrawal/valid/document.json +15 -0
  165. package/fixtures/atelier-instruction-adoption/context-receipt/invalid/document.json +18 -0
  166. package/fixtures/atelier-instruction-adoption/context-receipt/valid/document.json +17 -0
  167. package/fixtures/atelier-instruction-adoption/plan/invalid/document.json +63 -0
  168. package/fixtures/atelier-instruction-adoption/plan/valid/document.json +62 -0
  169. package/fixtures/atelier-instruction-adoption/receipt/invalid/document.json +22 -0
  170. package/fixtures/atelier-instruction-adoption/receipt/valid/document.json +21 -0
  171. package/fixtures/atelier-instruction-adoption/state/invalid/document.json +30 -0
  172. package/fixtures/atelier-instruction-adoption/state/valid/document.json +29 -0
  173. package/fixtures/atelier-interaction/act/invalid/document.json +25 -0
  174. package/fixtures/atelier-interaction/act/valid/document.json +24 -0
  175. package/fixtures/atelier-interaction/assessment/invalid/document.json +32 -0
  176. package/fixtures/atelier-interaction/assessment/valid/document.json +31 -0
  177. package/fixtures/atelier-interaction/observation/invalid/document.json +22 -0
  178. package/fixtures/atelier-interaction/observation/valid/document.json +21 -0
  179. package/fixtures/atelier-interaction/policy/invalid/document.json +20 -0
  180. package/fixtures/atelier-interaction/policy/valid/document.json +19 -0
  181. package/fixtures/atelier-judgment/case/invalid/document.json +76 -0
  182. package/fixtures/atelier-judgment/case/valid/document.json +75 -0
  183. package/fixtures/atelier-judgment/decision/invalid/document.json +38 -0
  184. package/fixtures/atelier-judgment/decision/valid/document.json +37 -0
  185. package/fixtures/atelier-judgment/native-decision.md +3 -0
  186. package/fixtures/atelier-judgment/practice-reconsideration/definition.json +92 -0
  187. package/fixtures/atelier-judgment/practice-reconsideration/scenario.json +435 -0
  188. package/fixtures/atelier-knowledge-contract/activation/invalid/document.json +26 -0
  189. package/fixtures/atelier-knowledge-contract/activation/valid/document.json +25 -0
  190. package/fixtures/atelier-knowledge-contract/contribution/invalid/document.json +34 -0
  191. package/fixtures/atelier-knowledge-contract/contribution/valid/document.json +33 -0
  192. package/fixtures/atelier-knowledge-contract/domain/invalid/document.json +41 -0
  193. package/fixtures/atelier-knowledge-contract/domain/valid/document.json +40 -0
  194. package/fixtures/atelier-knowledge-contract/domain-revision/invalid/document.json +46 -0
  195. package/fixtures/atelier-knowledge-contract/domain-revision/valid/document.json +45 -0
  196. package/fixtures/atelier-knowledge-contract/evaluation/invalid/document.json +21 -0
  197. package/fixtures/atelier-knowledge-contract/evaluation/valid/document.json +20 -0
  198. package/fixtures/atelier-knowledge-contract/ledger/invalid/document.json +318 -0
  199. package/fixtures/atelier-knowledge-contract/ledger/valid/document.json +317 -0
  200. package/fixtures/atelier-knowledge-contract/relation/invalid/document.json +25 -0
  201. package/fixtures/atelier-knowledge-contract/relation/valid/document.json +24 -0
  202. package/fixtures/atelier-knowledge-contract/review/invalid/document.json +18 -0
  203. package/fixtures/atelier-knowledge-contract/review/valid/document.json +17 -0
  204. package/fixtures/atelier-knowledge-contract/withdrawal/invalid/document.json +16 -0
  205. package/fixtures/atelier-knowledge-contract/withdrawal/valid/document.json +15 -0
  206. package/fixtures/atelier-learning/invalid/authority.json +14 -0
  207. package/fixtures/atelier-learning/valid/capture.json +13 -0
  208. package/fixtures/atelier-personal-workspace-contract/manifest/invalid/authority-key.json +17 -0
  209. package/fixtures/atelier-personal-workspace-contract/manifest/invalid/nonempty-ext.json +25 -0
  210. package/fixtures/atelier-personal-workspace-contract/manifest/invalid/wrong-schema.json +22 -0
  211. package/fixtures/atelier-personal-workspace-contract/manifest/valid/manifest.json +22 -0
  212. package/fixtures/atelier-personal-workspace-contract/overlay/invalid/authority-key.json +25 -0
  213. package/fixtures/atelier-personal-workspace-contract/overlay/invalid/unknown-top-level-field.json +27 -0
  214. package/fixtures/atelier-personal-workspace-contract/overlay/invalid/wrong-schema.json +24 -0
  215. package/fixtures/atelier-trackable/definition/invalid/document.json +15 -0
  216. package/fixtures/atelier-trackable/definition/valid/document.json +14 -0
  217. package/fixtures/atelier-trackable/request/invalid/document.json +23 -0
  218. package/fixtures/atelier-trackable/request/valid/document.json +22 -0
  219. package/fixtures/boundary-delegations/invalid/authority-key.v1.json +30 -0
  220. package/fixtures/boundary-delegations/invalid/push-operation.v1.json +28 -0
  221. package/fixtures/boundary-delegations/invalid/unsigned.v1.json +25 -0
  222. package/fixtures/boundary-delegations/valid/empty.v1.json +4 -0
  223. package/fixtures/boundary-delegations/valid/signed-operator.v1.json +30 -0
  224. package/fixtures/boundary-owner-keys/invalid/wrong-algorithm.v1.json +15 -0
  225. package/fixtures/boundary-owner-keys/invalid/wrong-curve.v1.json +15 -0
  226. package/fixtures/boundary-owner-keys/valid/one-owner.v1.json +17 -0
  227. package/fixtures/capability-packages/adoption.example.json +70 -0
  228. package/fixtures/capability-packages/evidence-review/capability-package.json +58 -0
  229. package/fixtures/capability-packages/evidence-review/capability-release.json +84 -0
  230. package/fixtures/capability-packages/evidence-review/evaluation.md +15 -0
  231. package/fixtures/capability-packages/evidence-review/skills/evidence-review/SKILL.md +22 -0
  232. package/fixtures/capability-packages/evidence-review/skills/evidence-review/references/ledger.md +7 -0
  233. package/fixtures/capability-packages/research/capability-package.json +88 -0
  234. package/fixtures/capability-packages/research/capability-release.json +134 -0
  235. package/fixtures/capability-packages/research/evaluation.md +15 -0
  236. package/fixtures/capability-packages/research/skills/research-integrate/SKILL.md +29 -0
  237. package/fixtures/capability-packages/research/skills/research-integrate/references/integration.md +10 -0
  238. package/fixtures/capability-packages/research/skills/research-plan/SKILL.md +27 -0
  239. package/fixtures/capability-packages/research/skills/research-plan/references/inquiries.md +26 -0
  240. package/fixtures/capability-packages/research/skills/research-synthesize/SKILL.md +23 -0
  241. package/fixtures/capability-packages/research/skills/research-synthesize/references/synthesis.md +12 -0
  242. package/fixtures/evidence-navigation/invalid/duplicate-operation.json +16 -0
  243. package/fixtures/evidence-navigation/invalid/instruction-kind.json +36 -0
  244. package/fixtures/evidence-navigation/invalid/invalid-digest.json +36 -0
  245. package/fixtures/evidence-navigation/invalid/invalid-time.json +36 -0
  246. package/fixtures/evidence-navigation/invalid/missing-attribution.json +35 -0
  247. package/fixtures/evidence-navigation/invalid/reserved-extension.json +19 -0
  248. package/fixtures/evidence-navigation/invalid/unattributed-acceptance.json +36 -0
  249. package/fixtures/evidence-navigation/invalid/uncoerced-version.json +16 -0
  250. package/fixtures/evidence-navigation/invalid/unknown-currency.json +17 -0
  251. package/fixtures/evidence-navigation/invalid/unknown-selector-field.json +37 -0
  252. package/fixtures/evidence-navigation/invalid/unsupported-operation.json +15 -0
  253. package/fixtures/evidence-navigation/valid/claim.json +36 -0
  254. package/fixtures/evidence-navigation/valid/host.json +16 -0
  255. package/fixtures/evidence-navigation/valid/profile.json +16 -0
  256. package/fixtures/evidence-navigation/valid/snapshot.json +17 -0
  257. package/fixtures/harness-packages/build-harness/capability-package.json +61 -0
  258. package/fixtures/harness-packages/build-harness/capability-release.json +82 -0
  259. package/fixtures/harness-packages/build-harness/evaluation.md +3 -0
  260. package/fixtures/harness-packages/build-harness/skills/atelier-build-harness/SKILL.md +59 -0
  261. package/fixtures/harness-packages/knowledge-harness/capability-package.json +61 -0
  262. package/fixtures/harness-packages/knowledge-harness/capability-release.json +82 -0
  263. package/fixtures/harness-packages/knowledge-harness/evaluation.md +3 -0
  264. package/fixtures/harness-packages/knowledge-harness/skills/atelier-knowledge-harness/SKILL.md +60 -0
  265. package/fixtures/harnesses/learning-cycle.json +780 -0
  266. package/fixtures/inquiry/workshop.json +675 -0
  267. package/fixtures/inquiry-packages/discovery-harness/capability-package.json +61 -0
  268. package/fixtures/inquiry-packages/discovery-harness/capability-release.json +82 -0
  269. package/fixtures/inquiry-packages/discovery-harness/evaluation.md +3 -0
  270. package/fixtures/inquiry-packages/discovery-harness/skills/atelier-discovery-harness/SKILL.md +48 -0
  271. package/fixtures/inquiry-packages/research-harness/capability-package.json +61 -0
  272. package/fixtures/inquiry-packages/research-harness/capability-release.json +82 -0
  273. package/fixtures/inquiry-packages/research-harness/evaluation.md +3 -0
  274. package/fixtures/inquiry-packages/research-harness/skills/atelier-research-harness/SKILL.md +43 -0
  275. package/fixtures/knowledge-health/calibration-suite.json +26 -0
  276. package/fixtures/knowledge-health/calibration-trial.json +37 -0
  277. package/fixtures/knowledge-health/corrected/checklist.md +18 -0
  278. package/fixtures/knowledge-health/devday/participant-record.json +19 -0
  279. package/fixtures/knowledge-health/expected-summary.json +27 -0
  280. package/fixtures/knowledge-health/workshop/README.md +20 -0
  281. package/fixtures/knowledge-health/workshop/atelier.project.json +7 -0
  282. package/fixtures/knowledge-health/workshop/knowledge-plan.json +65 -0
  283. package/fixtures/knowledge-health/workshop/records/checklist.md +18 -0
  284. package/fixtures/knowledge-health/workshop/records/workshop.md +18 -0
  285. package/fixtures/knowledge-health/workshop/repo-access.v1.json +5 -0
  286. package/fixtures/knowledge-health/workspace/atelier.project.json +18 -0
  287. package/fixtures/knowledge-health/workspace/knowledge-plan.json +74 -0
  288. package/fixtures/knowledge-health/workspace/records/checklist.md +18 -0
  289. package/fixtures/knowledge-health/workspace/records/pilot.md +16 -0
  290. package/fixtures/knowledge-health/workspace/repo-access.v1.json +9 -0
  291. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/case-only-collision.v2.json +160 -0
  292. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/flat-note-path.v2.json +160 -0
  293. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/hidden-folder.v2.json +160 -0
  294. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/identity-in-the-body.v2.json +160 -0
  295. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/link-breaking-name.v2.json +160 -0
  296. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/missing-identity-region.v2.json +156 -0
  297. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/missing-layout-version.v2.json +159 -0
  298. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/note-named-like-a-folder.v2.json +160 -0
  299. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/unknown-region-kind.v2.json +160 -0
  300. package/fixtures/obsidian/contracts/generation-manifest-v2/invalid/v1-contract-version.v2.json +161 -0
  301. package/fixtures/obsidian/contracts/generation-manifest-v2/valid/three-notes.v2.json +160 -0
  302. package/fixtures/obsidian/edits/workspace.json +1 -1
  303. package/fixtures/obsidian/materialization/expected-full.json +21 -21
  304. package/fixtures/obsidian/materialization/expected-full.layout-1.json +99 -0
  305. package/fixtures/obsidian/materialization/expected-scoped.json +7 -7
  306. package/fixtures/obsidian/materialization/expected-scoped.layout-1.json +39 -0
  307. package/fixtures/personal-workspace/overlay.json +24 -0
  308. package/fixtures/templates/local-library.v1.json +75 -0
  309. package/fixtures/templates/upgrade-contracts/adoption-policy.v2/invalid.json +16 -0
  310. package/fixtures/templates/upgrade-contracts/adoption-policy.v2/valid.json +13 -0
  311. package/fixtures/templates/upgrade-contracts/migration.v3/invalid.json +24 -0
  312. package/fixtures/templates/upgrade-contracts/migration.v3/valid.json +21 -0
  313. package/fixtures/templates/upgrade-contracts/template-adoption.v1/invalid.json +60 -0
  314. package/fixtures/templates/upgrade-contracts/template-adoption.v1/valid.json +57 -0
  315. package/fixtures/templates/upgrade-contracts/upgrade-plan.v3/invalid.json +85 -0
  316. package/fixtures/templates/upgrade-contracts/upgrade-plan.v3/valid.json +82 -0
  317. package/package.json +64 -6
  318. package/plugins/obsidian/main.js +444 -0
  319. package/plugins/obsidian/manifest.json +9 -0
  320. package/plugins/obsidian/styles.css +22 -0
  321. package/skills/claude/atelier-build-harness/SKILL.md +59 -0
  322. package/skills/claude/atelier-coordination/SKILL.md +32 -0
  323. package/skills/claude/atelier-discovery-harness/SKILL.md +48 -0
  324. package/skills/claude/atelier-guided-upgrade/SKILL.md +29 -0
  325. package/skills/claude/atelier-interaction/SKILL.md +34 -0
  326. package/skills/claude/atelier-knowledge-harness/SKILL.md +60 -0
  327. package/skills/claude/atelier-knowledge-setup/SKILL.md +72 -0
  328. package/skills/claude/atelier-practical-judgment/SKILL.md +64 -0
  329. package/skills/claude/atelier-research-harness/SKILL.md +43 -0
  330. package/skills/claude/atelier-skill-steward/SKILL.md +53 -0
  331. package/skills/claude/atelier-trackables/SKILL.md +40 -0
  332. package/skills/codex/atelier-build-harness/SKILL.md +59 -0
  333. package/skills/codex/atelier-coordination/SKILL.md +32 -0
  334. package/skills/codex/atelier-discovery-harness/SKILL.md +48 -0
  335. package/skills/codex/atelier-guided-upgrade/SKILL.md +29 -0
  336. package/skills/codex/atelier-interaction/SKILL.md +34 -0
  337. package/skills/codex/atelier-knowledge-harness/SKILL.md +60 -0
  338. package/skills/codex/atelier-knowledge-setup/SKILL.md +72 -0
  339. package/skills/codex/atelier-practical-judgment/SKILL.md +64 -0
  340. package/skills/codex/atelier-research-harness/SKILL.md +43 -0
  341. package/skills/codex/atelier-skill-steward/SKILL.md +53 -0
  342. package/skills/codex/atelier-trackables/SKILL.md +40 -0
  343. package/src/architecture/catalog.mjs +355 -0
  344. package/src/architecture/index.mjs +93 -0
  345. package/src/boundary/content-rules.mjs +4 -2
  346. package/src/boundary/delegation-command.mjs +158 -0
  347. package/src/boundary/delegation.mjs +396 -0
  348. package/src/boundary/policy.mjs +52 -10
  349. package/src/build/git.mjs +18 -0
  350. package/src/build/index.mjs +3 -0
  351. package/src/build/ledger.mjs +88 -0
  352. package/src/capabilities/adoption.mjs +381 -0
  353. package/src/capabilities/evidence.mjs +140 -0
  354. package/src/capabilities/files.mjs +124 -0
  355. package/src/capabilities/index.mjs +4 -0
  356. package/src/capabilities/instructions.mjs +250 -0
  357. package/src/capabilities/package.mjs +136 -0
  358. package/src/cli/command-failure.mjs +36 -0
  359. package/src/cli/execute-command.mjs +16 -2
  360. package/src/cli/run.mjs +65 -9
  361. package/src/coauthor/store.mjs +43 -2
  362. package/src/collaboration/proposals.mjs +189 -0
  363. package/src/commands/architecture.mjs +27 -0
  364. package/src/commands/boundary.mjs +3 -0
  365. package/src/commands/capability.mjs +73 -0
  366. package/src/commands/enroll.mjs +3 -0
  367. package/src/commands/harness.mjs +79 -0
  368. package/src/commands/ingest.mjs +39 -0
  369. package/src/commands/init.mjs +4 -1
  370. package/src/commands/inquiry.mjs +66 -0
  371. package/src/commands/knowledge-semantic.mjs +128 -0
  372. package/src/commands/knowledge.mjs +119 -0
  373. package/src/commands/learn.mjs +61 -0
  374. package/src/commands/obsidian.mjs +832 -62
  375. package/src/commands/practice.mjs +24 -0
  376. package/src/commands/setup.mjs +22 -2
  377. package/src/commands/trackable.mjs +19 -0
  378. package/src/contracts/corpus.mjs +36 -0
  379. package/src/coordination/index.mjs +110 -0
  380. package/src/egress/forbidden-egress.mjs +2 -0
  381. package/src/evidence-navigation/contracts.mjs +60 -0
  382. package/src/evidence-navigation/evaluate.mjs +69 -0
  383. package/src/evidence-navigation/generation.mjs +22 -0
  384. package/src/evidence-navigation/index.mjs +2 -0
  385. package/src/evidence-navigation/local.mjs +167 -0
  386. package/src/evidence-navigation/schema.generated.mjs +604 -0
  387. package/src/evidence-navigation/types.mjs +12 -0
  388. package/src/export/atelier-export-contract.mjs +35 -8
  389. package/src/graph/enroll.mjs +248 -0
  390. package/src/graph/graph.mjs +17 -1
  391. package/src/graph/knowledge-graph.mjs +58 -8
  392. package/src/harnesses/contracts.mjs +41 -0
  393. package/src/harnesses/exchange.mjs +154 -0
  394. package/src/harnesses/feedback.mjs +16 -0
  395. package/src/harnesses/history.mjs +37 -0
  396. package/src/harnesses/index.mjs +4 -0
  397. package/src/harnesses/store.mjs +29 -0
  398. package/src/ingestion/contracts.mjs +41 -0
  399. package/src/ingestion/evaluation.mjs +119 -0
  400. package/src/ingestion/optional/composition/index.mjs +171 -0
  401. package/src/ingestion/optional/evaluation/index.mjs +219 -0
  402. package/src/ingestion/optional/graphify/composition-binding.mjs +60 -0
  403. package/src/ingestion/optional/graphify/composition_receiving.py +185 -0
  404. package/src/ingestion/optional/graphify/graphify_supplier.py +933 -0
  405. package/src/ingestion/optional/graphify/json_bridge.py +163 -0
  406. package/src/ingestion/optional/graphify/query_receiving.py +209 -0
  407. package/src/ingestion/optional/index.mjs +9 -0
  408. package/src/ingestion/optional/jev/bridge.mjs +166 -0
  409. package/src/ingestion/optional/jev/composition-binding.mjs +116 -0
  410. package/src/ingestion/optional/jev/judgments.mjs +174 -0
  411. package/src/ingestion/optional/jev/native-translation.mjs +32 -0
  412. package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/__init__.py +7 -0
  413. package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/adapter.py +966 -0
  414. package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/artifacts.py +101 -0
  415. package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/projection.py +146 -0
  416. package/src/ingestion/optional/lightrag/composition-binding.mjs +67 -0
  417. package/src/ingestion/optional/vanilla/composition-binding.mjs +102 -0
  418. package/src/ingestion/optional/vanilla/index.mjs +218 -0
  419. package/src/ingestion/optional/vanilla/native-normalization.mjs +187 -0
  420. package/src/ingestion/processors.mjs +218 -0
  421. package/src/ingestion/semantic.mjs +203 -0
  422. package/src/ingestion/store.mjs +372 -0
  423. package/src/inquiry/beliefs.mjs +32 -0
  424. package/src/inquiry/contracts.mjs +23 -0
  425. package/src/inquiry/index.mjs +5 -0
  426. package/src/inquiry/ledger.mjs +135 -0
  427. package/src/inquiry/lenses.mjs +15 -0
  428. package/src/inquiry/projection.mjs +77 -0
  429. package/src/inquiry/store.mjs +35 -0
  430. package/src/intake/read-scope.mjs +12 -0
  431. package/src/intake/store.mjs +69 -6
  432. package/src/interaction/index.mjs +91 -0
  433. package/src/judgment/index.mjs +82 -0
  434. package/src/judgment/practice-evaluation.mjs +70 -0
  435. package/src/judgment/practice.mjs +144 -0
  436. package/src/knowledge/context.mjs +217 -0
  437. package/src/knowledge/index.mjs +5 -0
  438. package/src/knowledge/ingestion.mjs +79 -0
  439. package/src/knowledge/intake.mjs +33 -0
  440. package/src/knowledge/ledger.mjs +110 -0
  441. package/src/knowledge/participatory/guidance.mjs +36 -0
  442. package/src/knowledge/participatory/guided-contribution.mjs +44 -0
  443. package/src/knowledge/participatory/index.mjs +2 -0
  444. package/src/knowledge/participatory/installed-workshop.mjs +108 -0
  445. package/src/knowledge/plan.mjs +67 -0
  446. package/src/knowledge/projection.mjs +43 -0
  447. package/src/knowledge/semantic-operation.mjs +567 -0
  448. package/src/knowledge/sessions.mjs +467 -0
  449. package/src/knowledge/workspace.mjs +295 -0
  450. package/src/knowledge-health/assessment.mjs +165 -0
  451. package/src/knowledge-health/capabilities.mjs +350 -0
  452. package/src/knowledge-health/context.mjs +62 -0
  453. package/src/knowledge-health/example.mjs +47 -0
  454. package/src/knowledge-health/index.mjs +10 -0
  455. package/src/knowledge-health/owner-join.mjs +88 -0
  456. package/src/knowledge-health/proof/common.mjs +24 -0
  457. package/src/knowledge-health/proof/installed-check.mjs +100 -0
  458. package/src/knowledge-health/proof/native-readback.mjs +37 -0
  459. package/src/knowledge-health/proof/rehearse.mjs +68 -0
  460. package/src/knowledge-health/proof/validate-participant.mjs +17 -0
  461. package/src/knowledge-health/proof/verify-native-capture.mjs +14 -0
  462. package/src/knowledge-health/proof/workshop-check.mjs +36 -0
  463. package/src/knowledge-health/rule-identity.mjs +44 -0
  464. package/src/knowledge-health/workshop-composition.mjs +19 -0
  465. package/src/knowledge-health/workshop-profile.mjs +176 -0
  466. package/src/knowledge-health/workshop.mjs +99 -0
  467. package/src/learning/adapters.mjs +68 -0
  468. package/src/learning/assistance.mjs +127 -0
  469. package/src/learning/contracts.mjs +65 -0
  470. package/src/learning/store.mjs +272 -0
  471. package/src/personal-workspace/index.mjs +391 -0
  472. package/src/personal-workspace/selection.mjs +385 -0
  473. package/src/project/config.mjs +8 -0
  474. package/src/project/durable-state.mjs +3 -1
  475. package/src/project/file-class.mjs +1 -1
  476. package/src/project/private-state.mjs +10 -1
  477. package/src/projection/obsidian/contracts.mjs +224 -18
  478. package/src/projection/obsidian/edits/apply.mjs +63 -19
  479. package/src/projection/obsidian/edits/regions.mjs +137 -42
  480. package/src/projection/obsidian/materialize/index.mjs +6 -3
  481. package/src/projection/obsidian/materialize/path-registry.mjs +443 -57
  482. package/src/projection/obsidian/materialize/prepare-view.mjs +382 -131
  483. package/src/projection/obsidian/materialize/redaction.mjs +327 -0
  484. package/src/projection/obsidian/materialize/settings.mjs +113 -34
  485. package/src/projection/obsidian/personal-workspace.mjs +436 -0
  486. package/src/projection/obsidian/plugin-bridge/bundle.mjs +50 -0
  487. package/src/projection/obsidian/plugin-bridge/channel.mjs +174 -0
  488. package/src/projection/obsidian/plugin-bridge/index.mjs +10 -0
  489. package/src/projection/obsidian/proposals/adapter.mjs +47 -8
  490. package/src/projection/obsidian/proposals/observation.mjs +20 -7
  491. package/src/projection/obsidian/publication/bridge-script.mjs +11 -5
  492. package/src/projection/obsidian/publication/index.mjs +2 -1
  493. package/src/projection/obsidian/publication/publisher.mjs +312 -36
  494. package/src/projection/obsidian/publication/transport.mjs +63 -8
  495. package/src/projection/obsidian/publication/vault-list.mjs +200 -0
  496. package/src/projection/obsidian/recovery/index.mjs +4 -1
  497. package/src/projection/obsidian/recovery/restart.mjs +3 -1
  498. package/src/projection/obsidian/recovery/store.mjs +168 -8
  499. package/src/projection/obsidian/selection-ui/contribution.mjs +6 -5
  500. package/src/projection/obsidian/selection-ui/focus.mjs +14 -7
  501. package/src/projection/obsidian/selection-ui/selection-state.mjs +2 -2
  502. package/src/projection/obsidian/selection-ui/selection.mjs +8 -3
  503. package/src/readiness/readiness.mjs +10 -3
  504. package/src/reflection/index.mjs +56 -0
  505. package/src/runtime/obsidian/app-capability.mjs +104 -12
  506. package/src/runtime/obsidian/app-production-seams.mjs +161 -42
  507. package/src/runtime/obsidian/app-registration.mjs +313 -0
  508. package/src/runtime/obsidian/app-restart.mjs +154 -0
  509. package/src/runtime/obsidian/engine.mjs +288 -29
  510. package/src/runtime/obsidian/extension-points.mjs +1 -1
  511. package/src/runtime/obsidian/index.mjs +15 -8
  512. package/src/runtime/obsidian/launch-plan.mjs +91 -0
  513. package/src/runtime/obsidian/lifecycle.mjs +193 -22
  514. package/src/runtime/obsidian/login-item.mjs +332 -0
  515. package/src/runtime/obsidian/machine-settings.mjs +119 -12
  516. package/src/runtime/obsidian/opening.mjs +369 -63
  517. package/src/runtime/obsidian/pending-edits.mjs +10 -0
  518. package/src/runtime/obsidian/pipeline.mjs +71 -3
  519. package/src/runtime/obsidian/plugin-channel.mjs +289 -0
  520. package/src/runtime/obsidian/plugin-choice.mjs +182 -0
  521. package/src/runtime/obsidian/plugin-drift.mjs +124 -0
  522. package/src/runtime/obsidian/plugin-presence.mjs +61 -0
  523. package/src/runtime/obsidian/process-identity.mjs +20 -10
  524. package/src/runtime/obsidian/project-views.mjs +282 -0
  525. package/src/runtime/obsidian/questions.mjs +48 -0
  526. package/src/runtime/obsidian/release-watch.mjs +56 -0
  527. package/src/runtime/obsidian/service-main.mjs +113 -17
  528. package/src/runtime/obsidian/service-manager-production.mjs +61 -0
  529. package/src/runtime/obsidian/service-managers.mjs +275 -0
  530. package/src/runtime/obsidian/service-record.mjs +105 -5
  531. package/src/runtime/obsidian/service-server.mjs +50 -12
  532. package/src/runtime/obsidian/service.mjs +134 -7
  533. package/src/runtime/obsidian/startup-adapters.mjs +59 -21
  534. package/src/runtime/obsidian/state-store.mjs +13 -1
  535. package/src/runtime/obsidian/unheld-evidence.mjs +84 -0
  536. package/src/runtime/obsidian/vault-location.mjs +300 -0
  537. package/src/runtime/obsidian/view-counts.mjs +34 -0
  538. package/src/server/local-sidecar.mjs +193 -7
  539. package/src/server/server.mjs +45 -6
  540. package/src/template-bindings/project.mjs +92 -0
  541. package/src/templates/profile.mjs +225 -0
  542. package/src/trackables/domain.mjs +175 -0
  543. package/src/trackables/store.mjs +114 -0
  544. package/src/ui/knowledge-page.mjs +1388 -0
  545. package/src/upgrade/explanation.mjs +1 -1
  546. package/src/upgrade/template-participant.mjs +171 -0
  547. package/src/upgrade/transaction.mjs +72 -25
  548. package/src/upgrade/upgrade.mjs +2 -1
  549. package/templates/external-project-workspace/pack-lifecycle.json +6 -1
  550. package/templates/knowledge-workspace/.gitattributes +2 -0
  551. package/templates/knowledge-workspace/AGENTS.md +27 -0
  552. package/templates/knowledge-workspace/README.md +44 -0
  553. package/templates/knowledge-workspace/atelier.project.json +22 -0
  554. package/templates/knowledge-workspace/gitignore +6 -0
  555. package/templates/knowledge-workspace/knowledge-plan.json +111 -0
  556. package/templates/knowledge-workspace/knowledge-plan.schema.json +281 -0
  557. package/templates/knowledge-workspace/records/forecast.md +22 -0
  558. package/templates/knowledge-workspace/records/inspection.md +25 -0
  559. package/templates/knowledge-workspace/records/telescope.md +24 -0
  560. package/templates/knowledge-workspace/repo-access.v1.json +9 -0
package/src/cli/run.mjs CHANGED
@@ -14,6 +14,8 @@ export const commandMap = new Map([
14
14
  ['export:dry-run', ['src/validate-atelier-export-dry-run.mjs']],
15
15
  ['dry-run', ['src/validate-atelier-export-dry-run.mjs']],
16
16
  ['graph', ['src/commands/graph.mjs']],
17
+ ['knowledge', ['src/commands/knowledge.mjs']],
18
+ ['enroll', ['src/commands/enroll.mjs']],
17
19
  ['project', ['src/commands/project.mjs']],
18
20
  ['build', ['src/commands/project.mjs']],
19
21
  ['dev', ['src/commands/server.mjs']],
@@ -61,7 +63,15 @@ export const commandMap = new Map([
61
63
  ['sync', ['src/commands/sync.mjs']],
62
64
  ['review', ['src/commands/review.mjs']],
63
65
  ['coauthor', ['src/commands/coauthor.mjs']],
66
+ ['architecture', ['src/commands/architecture.mjs']],
67
+ ['trackable', ['src/commands/trackable.mjs']],
68
+ ['practice', ['src/commands/practice.mjs']],
64
69
  ['skills', ['src/commands/skills.mjs']],
70
+ ['capability', ['src/commands/capability.mjs']],
71
+ ['inquiry', ['src/commands/inquiry.mjs']],
72
+ ['harness', ['src/commands/harness.mjs']],
73
+ ['learn', ['src/commands/learn.mjs']],
74
+ ['ingest', ['src/commands/ingest.mjs']],
65
75
  ['obsidian', ['src/commands/obsidian.mjs']],
66
76
  ])
67
77
 
@@ -105,6 +115,10 @@ Core commands:
105
115
  adopt Add Atelier to an existing repo/workspace.
106
116
  setup --yes Repair ignored local machine state.
107
117
  graph [--check] Build or check the knowledge graph.
118
+ knowledge check|context|evaluate Check an ontology plan and select bounded evidence.
119
+ knowledge dashboard|session Inspect guided work and retain private drafts.
120
+ knowledge semantic OPERATION Record a host-run semantic extraction for review.
121
+ enroll documents Write private sidecars for documents missing one.
108
122
  project [--check] Build or check the workspace projection.
109
123
  build [--check] Build or check a realm portal.
110
124
  dev Run the local Atelier sidecar.
@@ -143,7 +157,15 @@ Core commands:
143
157
  review run|history|handoff Evidence-bound local human review.
144
158
  review export|inspect|packs Preview inspection bundles and pack lifecycle.
145
159
  coauthor start|read|event|recover Save and resume private authoring drafts.
160
+ architecture catalog|entry|resolve Inspect responsibility names and consumer bindings.
161
+ trackable preview|execute|view Follow adopted definitions and occurrence evidence.
162
+ practice plan|apply|status|context Adopt scoped instruction guidance and inspect use.
146
163
  skills audit|observe|candidates|sync Audit and manage local skill projections.
164
+ capability seal|plan|apply|status Publish local capability bundles and govern adoption.
165
+ harness Govern knowledge and build workflows.
166
+ inquiry append|handoff|status|graph Run the local Discovery and Research Harness workflow.
167
+ learn capture|propose|decide|activate|withdraw Manage scoped lessons and their evidence.
168
+ ingest plan|run|status|query Preserve selected sources and search bounded evidence.
147
169
  config check Validate project config.
148
170
  extension-pack validate Validate declared extension packs.
149
171
  extension-pack list List declared extension packs.
@@ -168,7 +190,22 @@ Machine-local repo paths belong in
168
190
 
169
191
  export function buildCommandHelpText(command, brand = DEFAULT_BRAND) {
170
192
  const c = brand.command
193
+ const serverHelp = (name) => `Usage: ${c} ${name} [--project ./atelier.project.json] [--port=PORT] [--review] [--knowledge]
194
+
195
+ Serves the project's built projection on 127.0.0.1 in the foreground until stopped. It builds nothing: run ${c} graph, then ${c} build, with the same --project path first. The port is --port=PORT, else the PORT environment variable, else 8137; 0 picks a free port, and the address printed on start names it. --review also serves the local review workspace at /review (docs/local-review.md). --knowledge adds guided knowledge dashboards and private coauthoring at /knowledge (docs/knowledge-workspace.md).`
171
196
  const help = {
197
+ capability: `Usage: ${c} capability seal|verify|inventory|plan|apply|status|observe|candidates|recover|fleet|graph|profiles
198
+ Run ${c} capability help for options. Releases stay local; adoption is per repository
199
+ and requires an exact plan digest. Installed bytes, host loading and successful
200
+ exercise are separate evidence. No model execution or tool permission grants.`,
201
+ ingest: `Usage: ${c} ingest plan|run|status|query
202
+
203
+ Read one bounded UTF-8 JSON object {workspaceId,input} from stdin inside the intended Git workspace. Plans bind explicit sources, scope and budgets. Run performs bounded local text, CSV and JSON extraction. Query returns source-bound lexical evidence with partial coverage; it does not synthesize or accept claims. Private state stays in ignored .atelier-local/. See docs/ingestion.md.`,
204
+ learn: `Usage: ${c} learn capture|propose|decide|activate|withdraw|list|context|render|graph|export|plan
205
+
206
+ Read a bounded JSON object from stdin in the intended Git workspace. Every request includes workspaceId. Writes include actor, requestId, expectedRevision and input. Context and render include query. Local actor identity is asserted, not authenticated. State stays in ignored .atelier-local/. Accepted content becomes context only after explicit activation for a named harness; no permission grant, file installation or sending occurs. See docs/learning.md.`,
207
+ dev: serverHelp('dev'),
208
+ server: serverHelp('server'),
172
209
  skills: `Usage: ${c} skills audit|observe|candidates|sync
173
210
  Audit bundled skills or --root DIR [--peer DIR].
174
211
  Sync previews by default; applying requires --apply --confirm PLAN_DIGEST.
@@ -176,12 +213,22 @@ Observations are local metadata, never automatic telemetry.`,
176
213
  coauthor: `Usage: ${c} coauthor start|read|event|recover
177
214
 
178
215
  Read one JSON request from stdin (maximum 1 MiB). Start takes {"config":{"id":"SESSION","fields":[{"id":"FIELD","source":{"ref":"packet.md","digest":"SHA256"}}]}}. Read/recover take {"sessionId":"SESSION"}. Event takes {"sessionId":"SESSION","event":{"id":"UNIQUE","expectedRevision":0,"type":"answer","text":"ANSWER"}}. Run from the intended Git workspace with ignored .atelier-local/. Saves are private drafts, never canonical source edits.`,
179
- init: `Usage: ${c} init [--template private-domain|shared-project|sample-workspace|distribution|external-project] [--target DIR] [--actor ID]
216
+ knowledge: `Usage: ${c} knowledge check|context|evaluate|dashboard [--project FILE] [--plan FILE]
217
+ ${c} knowledge session start|read|event|recover|list [--project FILE] [--plan FILE]
218
+ ${c} knowledge semantic begin|status|reconcile|complete|proposals|contribution|relation|record|cascade|context|project
219
+
220
+ Start with ${c} init --template knowledge-workspace --target DIR.
221
+ check reports ontology-to-question coverage against the current canonical graph.
222
+ context --question TEXT [--mode graph|lexical] [--max-bytes N] prints a bounded JSON packet of complete active Markdown sources.
223
+ evaluate compares lexical and graph selection on the plan's pinned evidence cases; exit 1 means missing or stale expected evidence, missing relationships, or an expected abstention that retrieved or omitted matching evidence.
224
+ The packet is local operator context, may contain private material, and grants no sharing or execution authority. Payload bytes are exact; token estimates are not measured usage. Session operations read JSON on stdin (except list); saved answers are private drafts.
225
+ semantic reads one JSON object {workspaceId, run, request} on stdin (at most 256 KiB) in the intended Git workspace, the one ingest uses. Each operation accepts exactly its documented request fields: required fields non-null, every field of its declared kind; anything else refuses as SEMANTIC_OPERATION_INVALID before anything is written. Formats such as timestamps are the runner's to check. Atelier calls no model: the host supplies its raw output, candidates and usage (null when unknown), and every interpretation stays pending until receiver records accept it; those records are caller assertions, not authenticated identity. Failures print {ok:false, code, error}, with recorded or captured details for reopening when the runner attached them. See docs/knowledge-setup.md, docs/knowledge-workspace.md and docs/semantic-operation.md.`,
226
+ init: `Usage: ${c} init [--template private-domain|shared-project|sample-workspace|distribution|external-project|knowledge-workspace] [--target DIR] [--actor ID]
180
227
 
181
228
  Creates tracked starter files and an Atelier lockfile. It does not install hooks unless asked separately. An unrecognized --template exits 1 and writes nothing; omit --template for the blank scaffold.`,
182
- adopt: `Usage: ${c} adopt [--profile single-repo|private-domain|shared-project|multi-repo|monorepo|control-workspace] [--target DIR] [--yes]
229
+ adopt: `Usage: ${c} adopt [--profile single-repo|private-domain|shared-project|multi-repo|monorepo|control-workspace] [--target DIR] [--include PATTERN] [--exclude PATTERN] [--enroll-documents [--audience private]] [--yes]
183
230
 
184
- Creates or checks a tracked atelier.project.json for an existing workspace and writes machine-local path bindings only to ignored local overlay files.`,
231
+ Creates or checks a tracked atelier.project.json for an existing workspace and writes machine-local path bindings only to ignored local overlay files. --include and --exclude record setup.include and setup.exclude, path patterns relative to the project config that scope which files the knowledge graph reads. --enroll-documents then runs ${c} enroll documents.`,
185
232
  setup: `Usage: ${c} setup --yes [--project ./atelier.project.json]
186
233
 
187
234
  Ensures ignored local Atelier state exists, verifies ignore coverage, and records unambiguous local repo path bindings.`,
@@ -194,6 +241,9 @@ check --staged judges the staged diff. push-check reads pre-push ref updates on
194
241
  graph: `Usage: ${c} graph [--check] [--project ./atelier.project.json]
195
242
 
196
243
  Builds or checks the project knowledge graph from tracked sources plus ignored local path bindings.`,
244
+ enroll: `Usage: ${c} enroll documents [--audience private] [--dry-run] [--json] [--project ./atelier.project.json]
245
+
246
+ Writes a minimal <file>.kg.json sidecar next to every .html, .pdf and .docx document the knowledge graph reads that has none, so ${c} graph can pass. Each sidecar classifies its document for --audience (default private), which the repository's boundary policy must allow, and keeps the domain, lifecycle and status the graph infers. An existing sidecar, even one Git ignores, is never changed, and sources are never changed. --dry-run lists what would be written.`,
197
247
  readiness: `Usage:
198
248
  ${c} readiness [--check] [--project ./atelier.project.json]
199
249
  ${c} readiness protocols [--json]
@@ -229,22 +279,28 @@ Assembles a local feedback report under ignored .atelier-local/feedback/ (mode 0
229
279
  announcements: `Usage: ${c} announcements list [--dir DIR] [--public-key FILE] | verify <file> [--public-key FILE] [--json] | show <file> [--public-key FILE]
230
280
 
231
281
  MNSTRY announcements are a pull-only channel: signed JSON documents under announcements/ in the repository. The trust anchor is always the committed MNSTRY key, or one you pass explicitly with --public-key; --dir changes only where documents are read from and never which key verifies them. Every run names the key and keyId it used. The kit never fetches anything — receiving announcements is the git pull you chose to run, and show refuses to print a body whose signature does not verify.`,
232
- obsidian: `Usage: ${c} obsidian status|scope|audience|mode|policy|service|open|apply|conflicts|apply-policy|selection|proposals [--project atelier.project.json] [--data-root DIR] [--json]
282
+ obsidian: `Usage: ${c} obsidian status|settings|location|scope|view|audience|mode|policy|service|open|uninstall|plugin|apply|conflicts|apply-policy|selection|proposals [--project atelier.project.json] [--data-root DIR] [--json] [--no-input]
233
283
 
234
284
  ${c} obsidian status
285
+ ${c} obsidian settings
286
+ ${c} obsidian location show | set DIR [--allow-synced-location]
235
287
  ${c} obsidian scope list | scope show ID
236
- ${c} obsidian audience show | set A,B | clear
288
+ ${c} obsidian view add ID (--all | --folder PATH [--folder PATH ...] [--repo R] | --tag T) [--expand DEPTH:MAX] [--default] [--allow-empty] [--yes]
289
+ ${c} obsidian audience show | set me|A,B | clear
237
290
  ${c} obsidian mode show | set manual|automatic
238
- ${c} obsidian policy show | install FILE | revoke
239
- ${c} obsidian service start [--consent-actor ID] --adapter=obsidian-cli | status | stop | unit --print --adapter=obsidian-cli
240
- ${c} obsidian open [--scope ID] [--consent-actor ID] [--allow-stale] --adapter=obsidian-cli
291
+ ${c} obsidian policy show | install FILE | revoke | digest FILE
292
+ ${c} obsidian service start [--consent-actor ID] [--adapter=obsidian-cli] | status | stop | unit --print [--adapter=obsidian-cli]
293
+ ${c} obsidian service unit --install [--consent-actor ID] [--adapter=obsidian-cli] | unit --remove
294
+ ${c} obsidian open [--scope ID] [--consent-actor ID] [--allow-stale] [--restart-obsidian] [--wait-ms MS] [--adapter=obsidian-cli]
295
+ ${c} obsidian uninstall
296
+ ${c} obsidian plugin show [--scope ID] | on [--scope ID] [--adapter=obsidian-cli]
241
297
  ${c} obsidian apply list | show EDIT | run EDIT [--actor ID] | recover
242
298
  ${c} obsidian conflicts [ID]
243
299
  ${c} obsidian apply-policy create FILE | show | revoke
244
300
  ${c} obsidian selection resolve ID | persist ID [allow-empty] | show ID | list
245
301
  ${c} obsidian proposals list | show OPERATION
246
302
 
247
- Noninteractive. With --json exactly one JSON document is printed, for a refusal too. status, scope, audience show, mode show, policy show and service status are read-only. open reports current only when the owned maintenance service ticked after the request, the view's trusted generation is the prepared one and reads back byte for byte, and the installed Obsidian meets the minimum version and answers for that vault; every other outcome is typed and exits 3. Reaching the installed app is never a default: open, service start and service unit need --adapter=obsidian-cli. Audiences, mode and the apply policy are private machine settings, never project configuration and never a note. apply, conflicts, apply-policy, selection and proposals are contributed operations registered from modules shipped under src/runtime/obsidian/contributions/; the built-in names cannot be replaced. While no apply operation is registered every apply reports apply-unavailable. Exit codes: 0 done, 1 internal error, 2 refusal or usage, 3 ran and the answer is not success.`,
303
+ Every input is an argument. view add changes the project configuration, which you commit: it shows the change and how many notes the view would show, and asks a person at a terminal first (--yes answers beforehand); anyone else's command is their consent, and nothing is ever committed. With --json exactly one JSON document is printed, for a refusal too. status, settings, location show, scope, audience show, mode show, policy show, policy digest, plugin show and service status are read-only. open reports current only when the owned maintenance service ticked after the request, the view's trusted generation is the prepared one and reads back byte for byte, and the installed Obsidian meets the minimum version and answers for that vault; every other outcome is typed and exits 3. Reaching the installed app is never a default: open, service start and service unit need --adapter=obsidian-cli once for a workspace, which remembers it (never used under the test runner). service unit --install installs a login item on macOS (a launchd agent) or Linux (a systemd user unit) so maintenance starts when you log in, under a consent that covers startup; it runs the package installed in the project and is refused from a package runner's cache. Once installed, the service is started through it, and service start replaces a service of an earlier release. service unit --remove removes it and starts the service for this session only. uninstall removes the login item and stops the service, and keeps vaults, private state, the project file and Obsidian's vault list. Obsidian's own settings file is written only while no Obsidian runs, and every write is shown in open's answer: the view's vault is added to its list with a backup of the file as it was, its command line is turned on (cli: true), and for an Obsidian that never started the file is created. A running Obsidian that open cannot reach (its command line turned off, or no vault open) is quit and started again only with --restart-obsidian, which no other flag implies; otherwise open names that flag. --wait-ms bounds open's wait for maintenance's tick. The first start of the maintenance service records who allowed it: --consent-actor ID, or for a person at a terminal the account's name; --json, --no-input, CI or ATELIER_NONINTERACTIVE=1 mean nobody is at a terminal. Audiences (audience set me: only you, with the notes that carry no classification, which no other list shows), mode, the apply policy and what was decided are private machine settings, never project configuration and never a note. apply, conflicts, apply-policy, selection and proposals are contributed operations registered from modules shipped under src/runtime/obsidian/contributions/; the built-in names cannot be replaced. While no apply operation is registered every apply reports apply-unavailable. Exit codes: 0 done, 1 internal error, 2 refusal or usage, 3 ran and the answer is not success.`,
248
304
  sync: `Usage:
249
305
  ${c} sync enroll --repo DIR [--project atelier.project.json] [--git ABSOLUTE_PATH]
250
306
  ${c} sync status --repo DIR
@@ -57,8 +57,7 @@ export function createCoauthorStore({ workspaceRoot = process.cwd() } = {}) {
57
57
  const lockPath = path.join(directory(), 'operation.lock');
58
58
  return withPrivateLock(lockPath, operation);
59
59
  }
60
- function load(id) {
61
- const result = ledger().eventsFor(aggregate(id));
60
+ function load(id, result = ledger().eventsFor(aggregate(id))) {
62
61
  if (!result.ok) throw new Error(result.error);
63
62
  if (!result.events.length) throw new Error('coauthor session not found');
64
63
  let state;
@@ -151,6 +150,48 @@ export function createCoauthorStore({ workspaceRoot = process.cwd() } = {}) {
151
150
  });
152
151
  },
153
152
  read(id) { return load(id).state; },
153
+ // Owning readback of the existing immutable values and verified event chain.
154
+ // Read only: missing values are unknown/unavailable, never repaired here.
155
+ readSavedFields(id) {
156
+ return locked(() => {
157
+ const state = load(id).state;
158
+ const values = state.saved.map(saved => {
159
+ const parents = ['.atelier-local', 'coauthor', 'values', contentDigest(id)];
160
+ let dir = root;
161
+ for (const part of parents) {
162
+ dir = path.join(dir, part);
163
+ const info = fs.lstatSync(dir);
164
+ if (!info.isDirectory() || info.isSymbolicLink()) throw new Error('redirected saved-value directory refused');
165
+ }
166
+ const raw = readText(path.join(dir, `${contentDigest(saved.receipt.requestId)}.json`));
167
+ const value = JSON.parse(raw);
168
+ validate(value, 'draft');
169
+ const expected = { schema: 'atelier-coauthor-draft@v1', status: 'draft', text: saved.text, receipt: saved.receipt };
170
+ if (raw !== canonicalize(expected) || canonicalize(value) !== canonicalize(expected)) throw new Error('saved value differs from owning event receipt');
171
+ return value;
172
+ });
173
+ return { state, values };
174
+ });
175
+ },
176
+ // One verified ledger snapshot for a bounded history listing. Keep failures
177
+ // per aggregate, and do not cache across calls or trust a caller's events.
178
+ readMany(ids) {
179
+ if (!Array.isArray(ids) || ids.length > 200 || ids.some(id => typeof id !== 'string' || !id))
180
+ throw new Error('session ids required and bounded');
181
+ if (!ids.length) return new Map();
182
+ const all = ledger().readAll();
183
+ const groups = new Map();
184
+ if (all.ok) for (const record of all.events) {
185
+ if (!groups.has(record.aggregateId)) groups.set(record.aggregateId, []);
186
+ groups.get(record.aggregateId).push(record);
187
+ }
188
+ return new Map(ids.map(id => {
189
+ try {
190
+ const state = load(id, all.ok ? { ok: true, events: groups.get(aggregate(id)) || [] } : all).state;
191
+ return [id, { ok: true, state }];
192
+ } catch (error) { return [id, { ok: false, error: error.message }]; }
193
+ }));
194
+ },
154
195
  dispatch(id, event) {
155
196
  return locked(() => {
156
197
  if (['receipt', 'failed'].includes(event?.type)) throw new Error('receipt and failure events are store-owned');
@@ -1,6 +1,7 @@
1
1
  import crypto from 'node:crypto'
2
2
  import fs from 'node:fs'
3
3
  import path from 'node:path'
4
+ import { canonicalize } from '../attestation/jcs.mjs'
4
5
  import { createCollaborationEventLedger } from './event-ledger.mjs'
5
6
  import {
6
7
  atomicReplacePrivateText,
@@ -12,6 +13,7 @@ export const ATELIER_PROPOSAL_SCHEMA = 'atelier-proposal@v1'
12
13
  export const ATELIER_PROPOSALS_SCHEMA = 'atelier-proposals@v1'
13
14
  export const PROPOSAL_REVIEW_STATUSES = new Set(['reviewed', 'accepted', 'rejected', 'superseded'])
14
15
  export const COPY_ONLY_PROPOSAL_CAPABILITY = 'proposal.copy-only'
16
+ export const WORKSHOP_HANDOFF_RETENTION_KIND = 'workshop-handoff'
15
17
  const PROPOSAL_ID_PATTERN = /^proposal-[a-z0-9]+(?:-[a-z0-9]+)*$/
16
18
 
17
19
  function nowIso() {
@@ -383,6 +385,190 @@ export function createProposalStore({
383
385
  return { ok: true, status: 200, record, diagnostics }
384
386
  }
385
387
 
388
+ const RETAINED_FIELD_LIMITS = { sessionId: 120, viewId: 120, path: 500, action: 120, intent: 500, actor: 160 }
389
+ const sha256Hex = (text) => crypto.createHash('sha256').update(text, 'utf8').digest('hex')
390
+
391
+ // The original saved receipt that names one retained handoff. Nothing is
392
+ // trimmed: a value that is not already usable is not an identity.
393
+ function retentionIdentity(receipt) {
394
+ if (!isRecord(receipt)) return null
395
+ const { sessionId, requestId, valueDigest } = receipt
396
+ if (typeof sessionId !== 'string' || !sessionId || sessionId.length > 120) return null
397
+ if (typeof requestId !== 'string' || !requestId || requestId.length > 200) return null
398
+ if (typeof valueDigest !== 'string' || !/^[a-f0-9]{64}$/.test(valueDigest)) return null
399
+ return { kind: WORKSHOP_HANDOFF_RETENTION_KIND, sessionId, requestId, valueDigest }
400
+ }
401
+
402
+ // The value digest is not part of the id, so another value saved under the
403
+ // same original request meets the first record and is refused.
404
+ function retainedProposalId(identity) {
405
+ return proposalId(canonicalize({ kind: identity.kind, sessionId: identity.sessionId, requestId: identity.requestId }))
406
+ }
407
+
408
+ // The digest covers exactly what the record holds, so a lookup recomputes it.
409
+ function retainedDigest(record) {
410
+ const proposal = record.proposal
411
+ return sha256Hex(canonicalize({
412
+ sessionId: proposal.sessionId,
413
+ viewId: proposal.viewId,
414
+ path: proposal.path,
415
+ action: proposal.action,
416
+ intent: proposal.intent,
417
+ actor: record.retention.actor,
418
+ diff: record.diff,
419
+ payload: record.payload,
420
+ }))
421
+ }
422
+
423
+ // Lookup by the original saved receipt. Only the ledger answers: a
424
+ // compatibility snapshot is never a retained outcome, and a ledger that
425
+ // cannot be read is unknown, not absent.
426
+ function lookupRetainedProposal(receipt) {
427
+ const identity = retentionIdentity(receipt)
428
+ if (!identity) {
429
+ return { ok: false, status: 422, outcome: 'refused', error: 'selected draft receipt is not usable as a retention identity' }
430
+ }
431
+ const id = retainedProposalId(identity)
432
+ const found = materializedProposal(id)
433
+ if (!found.ok && found.status === 404) {
434
+ return fs.existsSync(proposalPath(id))
435
+ ? { ok: false, status: 409, outcome: 'unknown', id, error: 'a snapshot exists for this receipt without a ledger record; inspect it before retrying' }
436
+ : { ok: true, status: 200, outcome: 'not-found', id, record: null }
437
+ }
438
+ if (!found.ok) return { ok: false, status: found.status, outcome: 'unknown', id, error: found.error }
439
+ const kept = found.record?.retention
440
+ let digest = null
441
+ try {
442
+ digest = isRecord(kept) ? retainedDigest(found.record) : null
443
+ } catch {
444
+ digest = null
445
+ }
446
+ if (
447
+ !isRecord(kept) || kept.kind !== identity.kind || kept.sessionId !== identity.sessionId ||
448
+ kept.requestId !== identity.requestId || digest === null || digest !== kept.payloadDigest
449
+ ) {
450
+ return { ok: false, status: 422, outcome: 'unknown', id, error: 'the retained proposal does not match its own receipt identity or digest' }
451
+ }
452
+ if (kept.valueDigest !== identity.valueDigest) {
453
+ return { ok: false, status: 409, outcome: 'conflict', id, error: 'a different value is already retained for this original receipt' }
454
+ }
455
+ return { ok: true, status: 200, outcome: 'retained', id, record: found.record }
456
+ }
457
+
458
+ // The handoff as it was retained, for readback after a lost reply or a
459
+ // source change.
460
+ function retainedHandoff(record) {
461
+ const proposal = record.proposal
462
+ return {
463
+ sessionId: proposal.sessionId,
464
+ viewId: proposal.viewId,
465
+ path: proposal.path,
466
+ action: proposal.action,
467
+ actor: record.retention.actor,
468
+ intent: proposal.intent,
469
+ directWrite: false,
470
+ applyEndpoint: null,
471
+ diff: JSON.parse(record.diff),
472
+ proposal: record.payload,
473
+ }
474
+ }
475
+
476
+ // Retain one server-derived handoff once, keyed by its original saved
477
+ // receipt. The caller derives the handoff; this store never trims or cuts
478
+ // it. A field that would not fit is refused, and the ledger's own line
479
+ // ceiling refuses the rest. A retained record is `proposed`: it is neither a
480
+ // review decision nor a source change.
481
+ function retainProposal(handoff = {}) {
482
+ if (!isRecord(handoff) || !isRecord(handoff.proposal) || !isRecord(handoff.diff)) {
483
+ return { ok: false, status: 422, outcome: 'refused', error: 'handoff shape is not supported' }
484
+ }
485
+ const authority = validateCopyOnlyProposalAuthority({ ...handoff.proposal, ...handoff })
486
+ if (!authority.ok || handoff.directWrite !== false || handoff.applyEndpoint !== null) {
487
+ return { ok: false, status: 409, outcome: 'refused', error: 'proposal authority refused: a retained handoff is copy-only' }
488
+ }
489
+ for (const [field, max] of Object.entries(RETAINED_FIELD_LIMITS)) {
490
+ const value = handoff[field]
491
+ if (typeof value !== 'string' || !value || value !== value.trim() || value.length > max) {
492
+ return { ok: false, status: 413, outcome: 'refused', error: `handoff ${field} cannot be retained without changing it` }
493
+ }
494
+ }
495
+ const identity = retentionIdentity(handoff.proposal.selectedDraftReceipt)
496
+ if (!identity || identity.sessionId !== handoff.sessionId) {
497
+ return { ok: false, status: 422, outcome: 'refused', error: 'selected draft receipt is not usable as a retention identity' }
498
+ }
499
+ let record
500
+ try {
501
+ const diffText = JSON.stringify(handoff.diff, null, 2)
502
+ if (diffText.length > 50000) {
503
+ return { ok: false, status: 413, outcome: 'refused', error: 'handoff diff cannot be retained without truncation' }
504
+ }
505
+ const createdAt = nowIso()
506
+ record = {
507
+ schema: ATELIER_PROPOSAL_SCHEMA,
508
+ workspaceId,
509
+ proposal: {
510
+ id: retainedProposalId(identity),
511
+ status: 'proposed',
512
+ createdAt,
513
+ updatedAt: createdAt,
514
+ sessionId: handoff.sessionId,
515
+ viewId: handoff.viewId,
516
+ path: handoff.path,
517
+ action: handoff.action,
518
+ intent: handoff.intent,
519
+ reason: '',
520
+ storage: {
521
+ kind: 'local',
522
+ ignored: true,
523
+ },
524
+ authority: copyOnlyActionSummary(handoff.action),
525
+ eventVersion: 1,
526
+ },
527
+ diff: diffText,
528
+ payload: handoff.proposal,
529
+ retention: { ...identity, actor: handoff.actor, receipt: handoff.proposal.selectedDraftReceipt },
530
+ }
531
+ record.retention.payloadDigest = retainedDigest(record)
532
+ } catch {
533
+ return { ok: false, status: 422, outcome: 'refused', error: 'handoff cannot be canonicalized' }
534
+ }
535
+ const unknown = (error) => ({ ok: false, status: 409, outcome: 'unknown', error })
536
+ const settle = (known) => {
537
+ if (known.outcome !== 'retained') return known
538
+ return known.record.retention.payloadDigest === record.retention.payloadDigest
539
+ ? { ok: true, status: 200, outcome: 'existing', record: known.record, diagnostics: [] }
540
+ : { ok: false, status: 409, outcome: 'conflict', error: 'a different handoff is already retained for this original receipt' }
541
+ }
542
+ const known = lookupRetainedProposal(identity)
543
+ if (known.outcome !== 'not-found') return settle(known)
544
+ const appended = eventLedger.append({
545
+ aggregateId: record.proposal.id,
546
+ expectedVersion: 0,
547
+ type: 'proposal-created',
548
+ actor: handoff.actor,
549
+ at: record.proposal.createdAt,
550
+ payload: { record },
551
+ })
552
+ if (!appended.ok) {
553
+ // A version conflict means another writer appended first. Read back the
554
+ // original identity; never append again.
555
+ if (appended.status === 409) {
556
+ const again = lookupRetainedProposal(identity)
557
+ return again.outcome === 'retained'
558
+ ? settle(again)
559
+ : unknown('the append conflicted and the original receipt could not be read back; repeat the same request')
560
+ }
561
+ return { ok: false, status: appended.status, outcome: appended.status === 413 ? 'refused' : 'unknown', error: appended.error }
562
+ }
563
+ // Retention is acknowledged only from the ledger's own readback.
564
+ const back = lookupRetainedProposal(identity)
565
+ if (back.outcome !== 'retained' || back.record.retention.payloadDigest !== record.retention.payloadDigest) {
566
+ return unknown('the retained proposal could not be read back after its append; repeat the same request')
567
+ }
568
+ const diagnostics = writeSnapshotProjectionWith(snapshotWriter, proposalPath(record.proposal.id), back.record)
569
+ return { ok: true, status: 200, outcome: 'created', record: back.record, diagnostics }
570
+ }
571
+
386
572
  function reviewProposal(id, body = {}) {
387
573
  const read = readProposal(id)
388
574
  if (!read.ok) return read
@@ -457,6 +643,9 @@ export function createProposalStore({
457
643
  readProposal,
458
644
  listProposals,
459
645
  createProposal,
646
+ lookupRetainedProposal,
647
+ retainedHandoff,
648
+ retainProposal,
460
649
  reviewProposal,
461
650
  }
462
651
  }
@@ -0,0 +1,27 @@
1
+ import { architectureEntry, responsibilityCatalog, resolveBehaviorBinding } from '../architecture/index.mjs'
2
+ import { reportCommandFailure, parseJsonRequest } from '../cli/command-failure.mjs'
3
+
4
+ try {
5
+ const [command, name, ...rest] = process.argv.slice(2)
6
+ if (rest.length) throw new Error('unexpected architecture arguments')
7
+ let result
8
+ if (command === 'catalog' && name === undefined) result = responsibilityCatalog()
9
+ else if (command === 'entry' && name !== undefined) {
10
+ result = architectureEntry(name)
11
+ if (!result) throw new Error('unknown architecture name')
12
+ } else if (command === 'resolve' && name === undefined) {
13
+ const chunks = []; let bytes = 0
14
+ for await (const chunk of process.stdin) {
15
+ bytes += chunk.length
16
+ if (bytes > 256 * 1024) throw new Error('architecture request exceeds limit')
17
+ chunks.push(chunk)
18
+ }
19
+ const value = parseJsonRequest(Buffer.concat(chunks), 'architecture request')
20
+ if (!value || Object.keys(value).sort().join(',') !== 'binding,consumers') throw new Error('binding and consumers required')
21
+ result = resolveBehaviorBinding(value)
22
+ if (!result.resolved) process.exitCode = 1
23
+ } else throw new Error('Usage: atelier architecture catalog|entry NAME|resolve (JSON stdin)')
24
+ console.log(JSON.stringify(result, null, 2))
25
+ } catch (error) {
26
+ reportCommandFailure(error)
27
+ }
@@ -6,6 +6,7 @@ import {
6
6
  runBoundaryInstallHooksCommand,
7
7
  runBoundaryPushCheckCommand,
8
8
  } from '../boundary/policy.mjs'
9
+ import { runBoundaryDelegationCommand } from '../boundary/delegation-command.mjs'
9
10
 
10
11
  const args = parseArgs(process.argv.slice(2))
11
12
  const subcommand = args._[0] || 'check'
@@ -19,6 +20,8 @@ if (subcommand === 'check' || subcommand === 'doctor') {
19
20
  runBoundaryAuditCommand(rest('audit'))
20
21
  } else if (subcommand === 'install-hooks') {
21
22
  runBoundaryInstallHooksCommand(rest('install-hooks'))
23
+ } else if (subcommand === 'delegation') {
24
+ runBoundaryDelegationCommand(rest('delegation'))
22
25
  } else {
23
26
  console.error(`Unknown boundary command: ${subcommand}`)
24
27
  process.exit(1)
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs'
3
+ import path from 'node:path'
4
+ import * as capability from '../capabilities/index.mjs'
5
+ import { jsonAt } from '../capabilities/files.mjs'
6
+ import { reportCommandFailure } from '../cli/command-failure.mjs'
7
+
8
+ const USAGE = `Usage: atelier capability <command> [options]
9
+
10
+ seal --package DIR Seal a local package, without overwriting a release.
11
+ verify --package DIR [--digest SHA] Verify all payload bytes; no publisher authentication.
12
+ inventory --surfaces FILE Read only the explicitly listed skill surfaces.
13
+ plan --adoption FILE [--source DIR ...] [--tool ID ...] [--notices FILE]
14
+ apply --adoption FILE [--source DIR ...] [--tool ID ...] [--notices FILE] --confirm PLAN_DIGEST
15
+ status [--session ID] Separate installation and caller-reported host evidence.
16
+ observe --event FILE Record a content-free, version-bound evidence reference.
17
+ candidates Propose cause-specific review from repeated evidence.
18
+ recover [--confirm PLAN_DIGEST] Preview recovery; exact confirmation restores prior state.
19
+ fleet --repo DIR [--repo DIR ...] Inspect explicitly selected repositories independently.
20
+ graph --namespace ID [--audience private|team|public]
21
+ Emit draft graph source documents as JSON for review.
22
+ profiles Show repository host projection profiles and their limits.
23
+
24
+ All output is JSON. --workspace DIR defaults to the current repository.
25
+ No command downloads packages, executes their scripts, probes a host, or grants tool authority.
26
+ The --tool values are caller observations of available tools, not permission grants.
27
+ Exit codes: 0 success, 1 refusal or blocked plan, 2 usage error.`
28
+
29
+ const COMMANDS = {
30
+ seal: ['package'], verify: ['package', 'digest'], inventory: ['surfaces'],
31
+ plan: ['adoption', 'source', 'tool', 'notices'], apply: ['adoption', 'source', 'tool', 'notices', 'confirm'],
32
+ status: ['session'], observe: ['event'], candidates: [], recover: ['confirm'],
33
+ fleet: ['repo'], graph: ['namespace', 'audience'], profiles: [],
34
+ }
35
+ const argv = process.argv.slice(2), command = argv.shift()
36
+ if (['--help', '-h', 'help'].includes(command) || argv.includes('--help')) { console.log(USAGE); process.exit(0) }
37
+ function usage(message) { console.error(`${message}\n\n${USAGE}`); process.exit(2) }
38
+ if (!Object.hasOwn(COMMANDS, command ?? '')) usage('unknown capability command')
39
+ const options = {}, repeated = new Set(['source', 'tool', 'repo'])
40
+ for (let index = 0; index < argv.length; index += 1) {
41
+ const match = /^--([a-z-]+)(?:=(.*))?$/.exec(argv[index])
42
+ if (!match || ![...COMMANDS[command], 'workspace', 'json'].includes(match[1])) usage('unknown capability option')
43
+ const key = match[1]
44
+ if (key === 'json') { if (match[2] !== undefined) usage('--json does not take a value'); continue }
45
+ const value = match[2] ?? argv[++index]
46
+ if (!value || value.startsWith('--')) usage('option requires a value')
47
+ if (repeated.has(key)) (options[key] ??= []).push(value)
48
+ else { if (options[key] !== undefined) usage('duplicate option'); options[key] = value }
49
+ }
50
+ function required(name) { if (!options[name]) usage(`--${name} is required`); return options[name] }
51
+ function read(file) { const absolute = path.resolve(file); return jsonAt(fs.realpathSync(path.dirname(absolute)), path.basename(absolute)) }
52
+ const common = { workspaceRoot: options.workspace ?? process.cwd() }
53
+ try {
54
+ let result
55
+ if (command === 'seal') result = capability.sealCapabilityRelease({ packageRoot: required('package') })
56
+ if (command === 'verify') result = capability.verifyCapabilityRelease({ packageRoot: required('package'), expectedDigest: options.digest })
57
+ if (command === 'inventory') result = capability.inventorySkillSurfaces({ surfaces: read(required('surfaces')) })
58
+ if (['plan', 'apply'].includes(command)) {
59
+ const settings = { ...common, adoption: read(required('adoption')), sources: options.source ?? [], availableTools: options.tool ?? [], notices: options.notices ? read(options.notices) : [] }
60
+ result = command === 'plan' ? capability.planCapabilityAdoption(settings) : capability.applyCapabilityAdoption({ ...settings, confirm: required('confirm') })
61
+ if (result.applyAllowed === false) process.exitCode = 1
62
+ }
63
+ if (command === 'status') result = capability.capabilityEvidenceStatus({ ...common, session: options.session ?? null })
64
+ if (command === 'observe') result = capability.recordCapabilityEvent({ ...common, event: read(required('event')) })
65
+ if (command === 'candidates') result = capability.capabilityImprovementCandidates(common)
66
+ if (command === 'recover') result = options.confirm ? capability.recoverCapabilityAdoption({ ...common, confirm: options.confirm }) : capability.inspectCapabilityRecovery(common)
67
+ if (command === 'fleet') result = capability.inspectCapabilityFleet({ workspaces: required('repo') })
68
+ if (command === 'graph') result = capability.capabilityGraphSources({ ...common, namespace: required('namespace'), audience: options.audience ?? 'private' })
69
+ if (command === 'profiles') result = capability.HOST_PROFILES
70
+ console.log(JSON.stringify(result, null, 2))
71
+ } catch (error) {
72
+ reportCommandFailure(error, 'stdout')
73
+ }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { runEnrollCommand } from '../graph/enroll.mjs'
3
+ runEnrollCommand()
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ import fs from 'node:fs'
3
+ import path from 'node:path'
4
+ import * as harness from '../harnesses/index.mjs'
5
+ import { knowledgeGraphProposal, prepareIntakeContribution, prepareKnowledgeImport } from '../knowledge/index.mjs'
6
+ import { prepareGitCandidate } from '../build/git.mjs'
7
+ import { jsonAt } from '../capabilities/files.mjs'
8
+ import { reportCommandFailure } from '../cli/command-failure.mjs'
9
+ const HELP = `Usage: atelier harness <command> [options]
10
+ knowledge|build append --record FILE --confirm DIGEST [--workspace DIR]
11
+ knowledge|build status|export --run ID [--workspace DIR]
12
+ knowledge graph --run ID --activation ID --namespace ID [--dependencies FILE] [--workspace DIR]
13
+ knowledge reconcile --run ID [--dependencies FILE] [--workspace DIR]
14
+ knowledge intake --run ID --attempt ID --title TEXT --term ID [--workspace DIR]
15
+ knowledge import --run ID --handoff FILE --history FILE --title TEXT --term ID [--dependencies FILE] [--workspace DIR]
16
+ build readiness|coordination --run ID [--dependencies FILE] [--workspace DIR]
17
+ build candidate --run ID --artifact FILE --writer FILE [--workspace DIR]
18
+ inspect --profile knowledge|build|inquiry --history FILE
19
+ validate --profile knowledge|build --record FILE
20
+ handoff --profile PROFILE --history FILE --repository ID --subject ID --target-repository ID --target-profile PROFILE --purpose TEXT [--dependencies FILE]
21
+ verify --handoff FILE --history FILE [--dependencies FILE]
22
+ feedback --profile knowledge|build --history FILE --event FILE
23
+ example
24
+
25
+ History files are complete ledgers; dependencies are explicit repository/profile/records snapshots.
26
+ The initial history digest is ${harness.EMPTY_HARNESS_HEAD}.
27
+ All output is JSON. Proposals and reported acceptance never authorize execution.
28
+ The existing atelier build command remains the workspace projection command.`
29
+ const args = process.argv.slice(2), first = args.shift(), profile = ['knowledge', 'build'].includes(first) ? first : null
30
+ const command = profile ? args.shift() : first, options = {}
31
+ if (['help', '--help', '-h'].includes(first) || args.includes('--help')) { console.log(HELP); process.exit(0) }
32
+ const common = { inspect: ['profile', 'history'], validate: ['profile', 'record'], handoff: ['profile', 'history', 'repository', 'subject', 'target-repository', 'target-profile', 'purpose', 'dependencies'], verify: ['handoff', 'history', 'dependencies'], feedback: ['profile', 'history', 'event'], example: [] }
33
+ const domain = { append: ['record', 'confirm'], status: ['run'], export: ['run'], graph: ['run', 'activation', 'namespace', 'dependencies'], reconcile: ['run', 'dependencies'], intake: ['run', 'attempt', 'title', 'term'], import: ['run', 'handoff', 'history', 'title', 'term', 'dependencies'], readiness: ['run', 'dependencies'], coordination: ['run', 'dependencies'], candidate: ['run', 'artifact', 'writer'] }
34
+ const allowed = profile ? domain[command] : common[command]
35
+ const usage = message => { console.error(`${message}\n${HELP}`); process.exit(2) }
36
+ if (!allowed || (profile === 'knowledge' && ['readiness', 'coordination', 'candidate'].includes(command)) || (profile === 'build' && ['graph', 'intake', 'import', 'reconcile'].includes(command))) usage('unknown harness command')
37
+ for (let i = 0; i < args.length; i++) {
38
+ const key = args[i].startsWith('--') ? args[i].slice(2) : ''
39
+ if (![...allowed, ...(profile ? ['workspace'] : [])].includes(key) || Object.hasOwn(options, key)) usage('unknown or duplicate option')
40
+ const value = args[++i]; if (!value || value.startsWith('--')) usage('option requires a value'); options[key] = value
41
+ }
42
+ const need = key => { if (!options[key]) usage(`--${key} required`); return options[key] }
43
+ const read = file => { const p = path.resolve(file); return jsonAt(fs.realpathSync(path.dirname(p)), path.basename(p)) }
44
+ function history(file, selected) {
45
+ const ledger = read(file), p = selected ?? ledger.profile ?? (ledger.schema === 'atelier-inquiry-ledger@v1' ? 'inquiry' : null)
46
+ if (p === 'inquiry') {
47
+ if (ledger.schema !== 'atelier-inquiry-ledger@v1') throw new Error('invalid inquiry ledger')
48
+ } else if (harness.validateHarnessDocument(ledger, p, 'ledger').length) throw new Error('invalid harness ledger')
49
+ const state = harness.inspectHarness(p, ledger.records)
50
+ if (state.head !== ledger.head) throw new Error('history digest mismatch')
51
+ return state.records
52
+ }
53
+ try {
54
+ let result
55
+ const dependencySnapshots = options.dependencies ? read(options.dependencies) : []
56
+ const workspaceRoot = options.workspace ?? process.cwd()
57
+ if (profile) {
58
+ if (command === 'append') result = harness.appendHarness({ workspaceRoot, profile, record: read(need('record')), confirm: need('confirm') })
59
+ else {
60
+ const state = harness.readHarness({ workspaceRoot, profile, run: need('run') })
61
+ if (command !== 'status' && !state.establishment) throw new Error('harness run missing')
62
+ if (command === 'status') result = state
63
+ if (command === 'export') result = { schema: 'atelier-harness-ledger@v1', profile, records: state.records, head: state.head }
64
+ if (command === 'graph') result = knowledgeGraphProposal(state.records, { namespace: need('namespace'), activationId: need('activation'), dependencySnapshots })
65
+ if (command === 'reconcile') result = harness.reconcileKnowledge(state.records, { dependencySnapshots })
66
+ if (command === 'intake') result = prepareIntakeContribution({ workspaceRoot, records: state.records, attemptId: need('attempt'), title: need('title'), term: need('term') })
67
+ if (command === 'import') result = prepareKnowledgeImport({ records: state.records, handoff: read(need('handoff')), sourceRecords: history(need('history')), title: need('title'), term: need('term'), dependencySnapshots })
68
+ if (command === 'readiness') result = harness.buildReadiness(state.records, { dependencySnapshots })
69
+ if (command === 'coordination') result = harness.buildCoordinationProposal(state.records, { dependencySnapshots })
70
+ if (command === 'candidate') result = prepareGitCandidate({ workspaceRoot, records: state.records, artifact: need('artifact'), writer: read(need('writer')) })
71
+ }
72
+ } else if (command === 'example') result = JSON.parse(fs.readFileSync(new URL('../../fixtures/harnesses/learning-cycle.json', import.meta.url), 'utf8'))
73
+ else if (command === 'validate') { const errors = harness.validateHarnessDocument(read(need('record')), need('profile')); result = { valid: !errors.length, errors, assurance: 'shape-only' }; if (errors.length) process.exitCode = 1 }
74
+ else if (command === 'inspect') result = harness.inspectHarness(need('profile'), history(need('history'), options.profile))
75
+ else if (command === 'handoff') result = harness.createHarnessHandoff({ profile: need('profile'), repository: need('repository'), records: history(need('history'), options.profile), subjectId: need('subject'), target: { repository: need('target-repository'), profile: need('target-profile'), purpose: need('purpose') }, dependencySnapshots })
76
+ else if (command === 'verify') { const handoff = read(need('handoff')); result = harness.verifyHarnessHandoff({ handoff, records: history(need('history'), handoff.source.profile), dependencySnapshots }) }
77
+ else if (command === 'feedback') result = harness.prepareHarnessFeedback({ ...read(need('event')), profile: need('profile'), records: history(need('history'), options.profile) })
78
+ console.log(JSON.stringify(result, null, 2))
79
+ } catch (error) { reportCommandFailure(error, 'stdout') }