@mnstry/atelier 0.2.0-alpha.1 → 0.2.0-alpha.10

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 (414) hide show
  1. package/CHANGELOG.md +372 -0
  2. package/README.md +402 -205
  3. package/SECURITY.md +6 -1
  4. package/contracts/atelier-adoption-policy.v1.schema.json +49 -0
  5. package/contracts/atelier-coauthor.v1.schema.json +163 -0
  6. package/contracts/atelier-decision-request.v1.schema.json +476 -0
  7. package/contracts/atelier-decision-result.v1.schema.json +500 -0
  8. package/contracts/atelier-guide.v1.schema.json +227 -0
  9. package/contracts/atelier-intake.v1.schema.json +151 -0
  10. package/contracts/atelier-migration.v2.schema.json +61 -0
  11. package/contracts/atelier-obsidian-acceptance-receipt.v1.schema.json +211 -0
  12. package/contracts/atelier-obsidian-apply-policy.v1.schema.json +298 -0
  13. package/contracts/atelier-obsidian-corpus-profile.v1.schema.json +98 -0
  14. package/contracts/atelier-obsidian-edit-operation.v1.schema.json +138 -0
  15. package/contracts/atelier-obsidian-ext-settings.v1.schema.json +287 -0
  16. package/contracts/atelier-obsidian-generation-manifest.v1.schema.json +353 -0
  17. package/contracts/atelier-obsidian-proposal-receipt.v1.schema.json +110 -0
  18. package/contracts/atelier-obsidian-publication-journal.v1.schema.json +167 -0
  19. package/contracts/atelier-obsidian-scope.v1.schema.json +264 -0
  20. package/contracts/atelier-obsidian-service-state.v1.schema.json +149 -0
  21. package/contracts/atelier-obsidian-source-snapshot.v1.schema.json +179 -0
  22. package/contracts/atelier-pane-presentation.v1.schema.json +76 -0
  23. package/contracts/atelier-presentation.v1.schema.json +1293 -0
  24. package/contracts/atelier-repository-observation.v1.schema.json +163 -0
  25. package/contracts/atelier-review.v1.schema.json +1601 -0
  26. package/contracts/atelier-skill-steward.v1.schema.json +692 -0
  27. package/contracts/atelier-upgrade-plan.v2.schema.json +398 -0
  28. package/contracts/atelier-upgrade-receipt.v1.schema.json +99 -0
  29. package/contracts/atelier-vault-publication.v1.schema.json +58 -0
  30. package/contracts/public-api-baseline.json +57 -0
  31. package/docs/assurance-controls.md +49 -0
  32. package/docs/atelier-runtime.md +28 -2
  33. package/docs/atelier-sync.md +172 -0
  34. package/docs/blocks/audience-visibility.md +9 -0
  35. package/docs/blocks/claims.md +61 -0
  36. package/docs/blocks/conformance-admission.md +15 -0
  37. package/docs/blocks/will-not-do.md +18 -0
  38. package/docs/coauthor-session.md +57 -0
  39. package/docs/connected-composition.md +75 -0
  40. package/docs/continuity.md +3 -4
  41. package/docs/decisions.md +167 -0
  42. package/docs/design.md +167 -0
  43. package/docs/exact-upgrades.md +159 -0
  44. package/docs/extension-pack-lifecycle.md +33 -0
  45. package/docs/guided-upgrades.md +99 -0
  46. package/docs/install.md +99 -16
  47. package/docs/intake-and-guides.md +65 -0
  48. package/docs/integration-and-review-plan.md +409 -0
  49. package/docs/integration-contract-decisions.md +22 -0
  50. package/docs/knowledge-graph.md +8 -4
  51. package/docs/local-review.md +84 -0
  52. package/docs/local-services.md +328 -0
  53. package/docs/local-state.md +107 -0
  54. package/docs/obsidian-contract.md +690 -0
  55. package/docs/obsidian.md +423 -0
  56. package/docs/portable-presentation.md +328 -0
  57. package/docs/presentation-consumer-boundaries.md +75 -0
  58. package/docs/presentation-review-disposition.md +47 -0
  59. package/docs/project-command-inventory.md +38 -0
  60. package/docs/project-options.md +53 -0
  61. package/docs/release-engineering.md +174 -12
  62. package/docs/repo-boundary-guard.md +12 -2
  63. package/docs/review-portability.md +55 -0
  64. package/docs/skill-steward.md +156 -0
  65. package/docs/upgrade.md +146 -5
  66. package/docs/vault-service.md +292 -0
  67. package/fixtures/atelier-coauthor/invalid/authority.v1.json +5 -0
  68. package/fixtures/atelier-coauthor/valid/config.v1.json +12 -0
  69. package/fixtures/atelier-guide/invalid/authority.v1.json +11 -0
  70. package/fixtures/atelier-guide/valid/capability.v1.json +10 -0
  71. package/fixtures/atelier-guide/valid/consent.v1.json +11 -0
  72. package/fixtures/atelier-guide/valid/engagement.v1.json +7 -0
  73. package/fixtures/atelier-guide/valid/offer.v1.json +10 -0
  74. package/fixtures/atelier-intake/invalid/authority.v1.json +9 -0
  75. package/fixtures/atelier-intake/valid/attempt.v1.json +8 -0
  76. package/fixtures/atelier-intake/valid/completion.v1.json +9 -0
  77. package/fixtures/atelier-intake/valid/source.v1.json +7 -0
  78. package/fixtures/atelier-repository-observation/invalid/complete-with-blocker.v1.json +18 -0
  79. package/fixtures/atelier-repository-observation/valid/complete-local.v1.json +48 -0
  80. package/fixtures/atelier-review/invalid/authenticated-identity.v1.json +22 -0
  81. package/fixtures/atelier-review/valid/bound.v1.json +229 -0
  82. package/fixtures/atelier-review/valid/bundle.v1.json +267 -0
  83. package/fixtures/atelier-review/valid/contribution.v1.json +22 -0
  84. package/fixtures/atelier-review/valid/lifecycle.v1.json +14 -0
  85. package/fixtures/atelier-skill-steward/audit/invalid/source-mutation.v1.json +26 -0
  86. package/fixtures/atelier-skill-steward/audit/valid/clean.v1.json +26 -0
  87. package/fixtures/atelier-skill-steward/candidates/invalid/workflow-key.v1.json +37 -0
  88. package/fixtures/atelier-skill-steward/candidates/valid/create.v1.json +37 -0
  89. package/fixtures/atelier-skill-steward/lock/invalid/bad-digest.v1.json +18 -0
  90. package/fixtures/atelier-skill-steward/lock/valid/installed.v1.json +23 -0
  91. package/fixtures/atelier-skill-steward/plan/invalid/delete-action.v1.json +33 -0
  92. package/fixtures/atelier-skill-steward/plan/valid/add.v1.json +33 -0
  93. package/fixtures/atelier-upgrade-transaction/adoption-policy/invalid/example.json +12 -0
  94. package/fixtures/atelier-upgrade-transaction/adoption-policy/valid/example.json +11 -0
  95. package/fixtures/atelier-upgrade-transaction/migration/invalid/example.json +20 -0
  96. package/fixtures/atelier-upgrade-transaction/migration/valid/example.json +19 -0
  97. package/fixtures/atelier-upgrade-transaction/upgrade-plan/invalid/example.json +58 -0
  98. package/fixtures/atelier-upgrade-transaction/upgrade-plan/valid/example.json +57 -0
  99. package/fixtures/atelier-upgrade-transaction/upgrade-receipt/invalid/example.json +15 -0
  100. package/fixtures/atelier-upgrade-transaction/upgrade-receipt/valid/example.json +14 -0
  101. package/fixtures/atelier-vault-publication/invalid/publication.json +5 -0
  102. package/fixtures/atelier-vault-publication/valid/publication.json +11 -0
  103. package/fixtures/decisions/request/invalid/unknown-authority.v1.json +61 -0
  104. package/fixtures/decisions/request/valid/triage.v1.json +60 -0
  105. package/fixtures/decisions/result/invalid/execution-authority.v1.json +50 -0
  106. package/fixtures/decisions/result/valid/abstained.v1.json +23 -0
  107. package/fixtures/decisions/result/valid/assessed.v1.json +50 -0
  108. package/fixtures/obsidian/acceptance/ap05-extra-notes.json +14 -0
  109. package/fixtures/obsidian/acceptance/receipts/G07.valid.v1.json +63 -0
  110. package/fixtures/obsidian/acceptance/receipts/G13.valid.v1.json +69 -0
  111. package/fixtures/obsidian/acceptance/receipts/G14.valid.v1.json +62 -0
  112. package/fixtures/obsidian/acceptance/receipts/G15.valid.v1.json +56 -0
  113. package/fixtures/obsidian/acceptance/receipts/G16.valid.v1.json +73 -0
  114. package/fixtures/obsidian/acceptance/receipts/G17.valid.v1.json +75 -0
  115. package/fixtures/obsidian/acceptance/receipts/G18.valid.v1.json +64 -0
  116. package/fixtures/obsidian/acceptance/service-sentinels.json +10 -0
  117. package/fixtures/obsidian/contracts/acceptance-receipt/invalid/duplicate-evidence-name.v1.json +39 -0
  118. package/fixtures/obsidian/contracts/acceptance-receipt/invalid/evidence-by-absolute-path.v1.json +34 -0
  119. package/fixtures/obsidian/contracts/acceptance-receipt/invalid/missing-candidate-tree.v1.json +33 -0
  120. package/fixtures/obsidian/contracts/acceptance-receipt/invalid/no-evidence.v1.json +28 -0
  121. package/fixtures/obsidian/contracts/acceptance-receipt/invalid/unknown-outcome.v1.json +34 -0
  122. package/fixtures/obsidian/contracts/acceptance-receipt/invalid/unknown-top-level-field.v1.json +35 -0
  123. package/fixtures/obsidian/contracts/acceptance-receipt/valid/node-gate.v1.json +34 -0
  124. package/fixtures/obsidian/contracts/apply-policy/invalid/automatic-without-edit-class.v1.json +27 -0
  125. package/fixtures/obsidian/contracts/apply-policy/invalid/conflict-overwrite.v1.json +29 -0
  126. package/fixtures/obsidian/contracts/apply-policy/invalid/missing-policy-digest.v1.json +28 -0
  127. package/fixtures/obsidian/contracts/apply-policy/invalid/unbounded-batch.v1.json +29 -0
  128. package/fixtures/obsidian/contracts/apply-policy/invalid/unimplemented-edit-class.v1.json +30 -0
  129. package/fixtures/obsidian/contracts/apply-policy/invalid/unknown-mode.v1.json +29 -0
  130. package/fixtures/obsidian/contracts/apply-policy/invalid/unknown-selector-operator.v1.json +22 -0
  131. package/fixtures/obsidian/contracts/apply-policy/invalid/unknown-top-level-field.v1.json +30 -0
  132. package/fixtures/obsidian/contracts/apply-policy/valid/automatic-scoped.v1.json +29 -0
  133. package/fixtures/obsidian/contracts/apply-policy/valid/manual-default.v1.json +20 -0
  134. package/fixtures/obsidian/contracts/corpus-profile/invalid/absolute-path-in-ext.v1.json +30 -0
  135. package/fixtures/obsidian/contracts/corpus-profile/invalid/absolute-repository-root.v1.json +27 -0
  136. package/fixtures/obsidian/contracts/corpus-profile/invalid/duplicate-repository-id.v1.json +27 -0
  137. package/fixtures/obsidian/contracts/corpus-profile/invalid/overlapping-managed-roots.v1.json +27 -0
  138. package/fixtures/obsidian/contracts/corpus-profile/invalid/unknown-enrollment.v1.json +27 -0
  139. package/fixtures/obsidian/contracts/corpus-profile/invalid/unknown-top-level-field.v1.json +28 -0
  140. package/fixtures/obsidian/contracts/corpus-profile/valid/three-repositories.v1.json +27 -0
  141. package/fixtures/obsidian/contracts/edit-operation/invalid/absolute-recovery-ref.v1.json +21 -0
  142. package/fixtures/obsidian/contracts/edit-operation/invalid/inline-observed-bytes.v1.json +22 -0
  143. package/fixtures/obsidian/contracts/edit-operation/invalid/missing-base-digest.v1.json +20 -0
  144. package/fixtures/obsidian/contracts/edit-operation/invalid/short-idempotency-key.v1.json +21 -0
  145. package/fixtures/obsidian/contracts/edit-operation/invalid/unknown-kind.v1.json +21 -0
  146. package/fixtures/obsidian/contracts/edit-operation/valid/pending-body-replacement.v1.json +21 -0
  147. package/fixtures/obsidian/contracts/ext-settings/invalid/absolute-path-prefix.v1.json +28 -0
  148. package/fixtures/obsidian/contracts/ext-settings/invalid/apply-policy-in-portable-settings.v1.json +30 -0
  149. package/fixtures/obsidian/contracts/ext-settings/invalid/duplicate-scope-id.v1.json +27 -0
  150. package/fixtures/obsidian/contracts/ext-settings/invalid/machine-local-vault-path.v1.json +28 -0
  151. package/fixtures/obsidian/contracts/ext-settings/invalid/service-port-in-portable-settings.v1.json +28 -0
  152. package/fixtures/obsidian/contracts/ext-settings/invalid/unknown-default-scope.v1.json +27 -0
  153. package/fixtures/obsidian/contracts/ext-settings/valid/disabled.v1.json +5 -0
  154. package/fixtures/obsidian/contracts/ext-settings/valid/enabled-with-scopes.v1.json +27 -0
  155. package/fixtures/obsidian/contracts/generation-manifest/invalid/absolute-note-path.v1.json +114 -0
  156. package/fixtures/obsidian/contracts/generation-manifest/invalid/complete-with-unwritten-notes.v1.json +114 -0
  157. package/fixtures/obsidian/contracts/generation-manifest/invalid/derived-link-claimed-declared.v1.json +114 -0
  158. package/fixtures/obsidian/contracts/generation-manifest/invalid/duplicate-note-identity.v1.json +114 -0
  159. package/fixtures/obsidian/contracts/generation-manifest/invalid/in-scope-endpoint-missing.v1.json +114 -0
  160. package/fixtures/obsidian/contracts/generation-manifest/invalid/title-only-note-path.v1.json +114 -0
  161. package/fixtures/obsidian/contracts/generation-manifest/invalid/unknown-note-field.v1.json +115 -0
  162. package/fixtures/obsidian/contracts/generation-manifest/invalid/unknown-relation-type.v1.json +114 -0
  163. package/fixtures/obsidian/contracts/generation-manifest/invalid/withheld-endpoint.v1.json +114 -0
  164. package/fixtures/obsidian/contracts/generation-manifest/valid/two-notes.v1.json +114 -0
  165. package/fixtures/obsidian/contracts/oracles/scope-cases.json +412 -0
  166. package/fixtures/obsidian/contracts/proposal-receipt/invalid/accepted-without-proposal-id.v1.json +12 -0
  167. package/fixtures/obsidian/contracts/proposal-receipt/invalid/missing-adapter-operation-id.v1.json +11 -0
  168. package/fixtures/obsidian/contracts/proposal-receipt/invalid/unknown-backpressure-outcome.v1.json +12 -0
  169. package/fixtures/obsidian/contracts/proposal-receipt/invalid/unknown-top-level-field.v1.json +13 -0
  170. package/fixtures/obsidian/contracts/proposal-receipt/valid/accepted-new.v1.json +12 -0
  171. package/fixtures/obsidian/contracts/proposal-receipt/valid/deferred.v1.json +12 -0
  172. package/fixtures/obsidian/contracts/publication-journal/invalid/absolute-recovery-ref.v1.json +47 -0
  173. package/fixtures/obsidian/contracts/publication-journal/invalid/duplicate-sequence.v1.json +47 -0
  174. package/fixtures/obsidian/contracts/publication-journal/invalid/empty-protocol-id.v1.json +47 -0
  175. package/fixtures/obsidian/contracts/publication-journal/invalid/missing-protocol-id.v1.json +46 -0
  176. package/fixtures/obsidian/contracts/publication-journal/invalid/unknown-entry-field.v1.json +48 -0
  177. package/fixtures/obsidian/contracts/publication-journal/invalid/unknown-state.v1.json +47 -0
  178. package/fixtures/obsidian/contracts/publication-journal/valid/committed.v1.json +47 -0
  179. package/fixtures/obsidian/contracts/publication-journal/valid/updating-after-restart.v1.json +22 -0
  180. package/fixtures/obsidian/contracts/scope/invalid/absolute-path-prefix.v1.json +15 -0
  181. package/fixtures/obsidian/contracts/scope/invalid/duplicate-ids.v1.json +18 -0
  182. package/fixtures/obsidian/contracts/scope/invalid/expansion-without-node-budget.v1.json +40 -0
  183. package/fixtures/obsidian/contracts/scope/invalid/full-mode-with-subset.v1.json +8 -0
  184. package/fixtures/obsidian/contracts/scope/invalid/unknown-mode.v1.json +41 -0
  185. package/fixtures/obsidian/contracts/scope/invalid/unknown-selector-key.v1.json +15 -0
  186. package/fixtures/obsidian/contracts/scope/invalid/unknown-selector-operator.v1.json +14 -0
  187. package/fixtures/obsidian/contracts/scope/invalid/unknown-top-level-field.v1.json +42 -0
  188. package/fixtures/obsidian/contracts/scope/valid/explicit-empty.v1.json +8 -0
  189. package/fixtures/obsidian/contracts/scope/valid/focus.v1.json +11 -0
  190. package/fixtures/obsidian/contracts/scope/valid/full.v1.json +8 -0
  191. package/fixtures/obsidian/contracts/scope/valid/scoped-set-expression.v1.json +41 -0
  192. package/fixtures/obsidian/contracts/service-state/invalid/hostname-instead-of-literal-loopback.v1.json +23 -0
  193. package/fixtures/obsidian/contracts/service-state/invalid/missing-consent.v1.json +18 -0
  194. package/fixtures/obsidian/contracts/service-state/invalid/privileged-port.v1.json +23 -0
  195. package/fixtures/obsidian/contracts/service-state/invalid/unknown-top-level-field.v1.json +24 -0
  196. package/fixtures/obsidian/contracts/service-state/invalid/wildcard-bind.v1.json +23 -0
  197. package/fixtures/obsidian/contracts/service-state/valid/healthy.v1.json +23 -0
  198. package/fixtures/obsidian/contracts/source-snapshot/invalid/absolute-file-path.v1.json +48 -0
  199. package/fixtures/obsidian/contracts/source-snapshot/invalid/duplicate-repository-id.v1.json +48 -0
  200. package/fixtures/obsidian/contracts/source-snapshot/invalid/mixed-read.v1.json +48 -0
  201. package/fixtures/obsidian/contracts/source-snapshot/invalid/parent-traversal-path.v1.json +48 -0
  202. package/fixtures/obsidian/contracts/source-snapshot/invalid/unknown-file-field.v1.json +49 -0
  203. package/fixtures/obsidian/contracts/source-snapshot/valid/two-repositories.v1.json +48 -0
  204. package/fixtures/obsidian/edits/workspace.json +65 -0
  205. package/fixtures/obsidian/materialization/expected-full.json +99 -0
  206. package/fixtures/obsidian/materialization/expected-scoped.json +39 -0
  207. package/fixtures/obsidian/materialization/workspace.json +54 -0
  208. package/fixtures/obsidian/proposals/expected-shapes.json +11 -0
  209. package/fixtures/projects/sample-workspace/content/source.html.kg.json +4 -1
  210. package/fixtures/projects/source-formats-workspace/content/data.json.kg.json +4 -1
  211. package/fixtures/projects/source-formats-workspace/content/logo.png.kg.json +4 -1
  212. package/fixtures/projects/source-formats-workspace/content/metrics.csv.kg.json +4 -1
  213. package/fixtures/projects/source-formats-workspace/content/pipeline.yaml.kg.json +4 -1
  214. package/fixtures/ui/presentation/pane.v1.json +7 -0
  215. package/fixtures/ui/presentation/reference.v1.json +293 -0
  216. package/package.json +86 -10
  217. package/skills/claude/atelier-guided-coauthor/SKILL.md +49 -0
  218. package/skills/claude/atelier-guided-upgrade/SKILL.md +97 -0
  219. package/skills/claude/atelier-local-service/SKILL.md +47 -0
  220. package/skills/claude/atelier-open/SKILL.md +11 -5
  221. package/skills/claude/atelier-public-boundary/SKILL.md +31 -0
  222. package/skills/claude/atelier-skill-steward/SKILL.md +62 -0
  223. package/skills/claude/mnstry-readiness/SKILL.md +5 -0
  224. package/skills/codex/atelier-guided-coauthor/SKILL.md +49 -0
  225. package/skills/codex/atelier-guided-upgrade/SKILL.md +97 -0
  226. package/skills/codex/atelier-local-service/SKILL.md +47 -0
  227. package/skills/codex/atelier-open/SKILL.md +11 -5
  228. package/skills/codex/atelier-public-boundary/SKILL.md +31 -0
  229. package/skills/codex/atelier-skill-steward/SKILL.md +62 -0
  230. package/skills/codex/mnstry-readiness/SKILL.md +5 -0
  231. package/src/access/preview-enforcer.mjs +84 -0
  232. package/src/boundary/content-rules.mjs +283 -20
  233. package/src/boundary/policy.mjs +213 -91
  234. package/src/cli/execute-command.mjs +36 -0
  235. package/src/cli/project-options.mjs +58 -0
  236. package/src/cli/run.mjs +78 -10
  237. package/src/coauthor/session.mjs +161 -0
  238. package/src/coauthor/store.mjs +173 -0
  239. package/src/collaboration/event-ledger.mjs +348 -0
  240. package/src/collaboration/index.mjs +17 -0
  241. package/src/collaboration/inspection-bundle.mjs +223 -0
  242. package/src/collaboration/proposals.mjs +265 -65
  243. package/src/collaboration/review-contracts.mjs +25 -0
  244. package/src/collaboration/review-store.mjs +305 -0
  245. package/src/commands/attestation.mjs +20 -6
  246. package/src/commands/coauthor.mjs +26 -0
  247. package/src/commands/config.mjs +6 -1
  248. package/src/commands/disclosure.mjs +133 -0
  249. package/src/commands/distribution.mjs +2 -1
  250. package/src/commands/extension-pack.mjs +17 -9
  251. package/src/commands/init.mjs +46 -6
  252. package/src/commands/obsidian.mjs +371 -0
  253. package/src/commands/review.mjs +147 -0
  254. package/src/commands/server.mjs +1 -4
  255. package/src/commands/setup.mjs +51 -14
  256. package/src/commands/skills.mjs +199 -0
  257. package/src/commands/sync.mjs +107 -0
  258. package/src/composition/registry.mjs +27 -0
  259. package/src/composition/wire.mjs +122 -0
  260. package/src/contracts/corpus.mjs +35 -0
  261. package/src/decisions/contracts.d.mts +96 -0
  262. package/src/decisions/contracts.mjs +321 -0
  263. package/src/disclosure/content-scan.mjs +206 -0
  264. package/src/egress/check.mjs +7 -38
  265. package/src/egress/forbidden-egress.mjs +32 -18
  266. package/src/export/atelier-export-contract.mjs +16 -1
  267. package/src/extension-packs/lifecycle.mjs +154 -0
  268. package/src/graph/graph.mjs +176 -316
  269. package/src/graph/knowledge-graph.mjs +643 -43
  270. package/src/guides/contracts.mjs +54 -0
  271. package/src/harness/context-client.mjs +9 -1
  272. package/src/index.mjs +41 -0
  273. package/src/intake/store.mjs +119 -0
  274. package/src/preview/channel.mjs +89 -0
  275. package/src/project/config.mjs +112 -52
  276. package/src/project/durable-state.mjs +161 -0
  277. package/src/project/file-class.mjs +180 -0
  278. package/src/project/package-root.mjs +10 -0
  279. package/src/project/path-match.mjs +38 -15
  280. package/src/project/private-state.mjs +120 -0
  281. package/src/projection/obsidian/contracts.mjs +571 -0
  282. package/src/projection/obsidian/edits/align.mjs +169 -0
  283. package/src/projection/obsidian/edits/apply.mjs +889 -0
  284. package/src/projection/obsidian/edits/arbitrate.mjs +414 -0
  285. package/src/projection/obsidian/edits/contribution.mjs +108 -0
  286. package/src/projection/obsidian/edits/index.mjs +19 -0
  287. package/src/projection/obsidian/edits/object-identity.mjs +61 -0
  288. package/src/projection/obsidian/edits/object-store.mjs +517 -0
  289. package/src/projection/obsidian/edits/observe.mjs +123 -0
  290. package/src/projection/obsidian/edits/policy.mjs +123 -0
  291. package/src/projection/obsidian/edits/regions.mjs +648 -0
  292. package/src/projection/obsidian/materialize/byte-lens.mjs +98 -0
  293. package/src/projection/obsidian/materialize/index.mjs +7 -0
  294. package/src/projection/obsidian/materialize/path-registry.mjs +105 -0
  295. package/src/projection/obsidian/materialize/prepare-view.mjs +746 -0
  296. package/src/projection/obsidian/materialize/settings.mjs +57 -0
  297. package/src/projection/obsidian/materialize/stage.mjs +27 -0
  298. package/src/projection/obsidian/proposals/adapter.mjs +572 -0
  299. package/src/projection/obsidian/proposals/backpressure.mjs +113 -0
  300. package/src/projection/obsidian/proposals/contribution.mjs +55 -0
  301. package/src/projection/obsidian/proposals/index.mjs +23 -0
  302. package/src/projection/obsidian/proposals/observation.mjs +216 -0
  303. package/src/projection/obsidian/proposals/queue.mjs +277 -0
  304. package/src/projection/obsidian/proposals/router.mjs +168 -0
  305. package/src/projection/obsidian/publication/bridge-script.mjs +266 -0
  306. package/src/projection/obsidian/publication/exchange.mjs +117 -0
  307. package/src/projection/obsidian/publication/index.mjs +5 -0
  308. package/src/projection/obsidian/publication/publisher.mjs +588 -0
  309. package/src/projection/obsidian/publication/test-seam.mjs +16 -0
  310. package/src/projection/obsidian/publication/transport.mjs +160 -0
  311. package/src/projection/obsidian/recovery/index.mjs +6 -0
  312. package/src/projection/obsidian/recovery/journal.mjs +134 -0
  313. package/src/projection/obsidian/recovery/late-writer.mjs +46 -0
  314. package/src/projection/obsidian/recovery/restart.mjs +316 -0
  315. package/src/projection/obsidian/recovery/store.mjs +234 -0
  316. package/src/projection/obsidian/selection-ui/conflict-view.mjs +91 -0
  317. package/src/projection/obsidian/selection-ui/contribution.mjs +141 -0
  318. package/src/projection/obsidian/selection-ui/focus.mjs +82 -0
  319. package/src/projection/obsidian/selection-ui/index.mjs +12 -0
  320. package/src/projection/obsidian/selection-ui/policy-setup.mjs +107 -0
  321. package/src/projection/obsidian/selection-ui/receipt.mjs +173 -0
  322. package/src/projection/obsidian/selection-ui/selection-state.mjs +122 -0
  323. package/src/projection/obsidian/selection-ui/selection.mjs +109 -0
  324. package/src/projection/project.mjs +28 -19
  325. package/src/readiness-protocols/evidence.mjs +282 -0
  326. package/src/readiness-protocols/runtime.mjs +4 -3
  327. package/src/readiness-protocols/source-read.mjs +39 -0
  328. package/src/runtime/git-adapter.mjs +189 -0
  329. package/src/runtime/local-state.mjs +439 -0
  330. package/src/runtime/obsidian/app-capability.mjs +129 -0
  331. package/src/runtime/obsidian/app-production-seams.mjs +105 -0
  332. package/src/runtime/obsidian/contributions/proposal-adapter.mjs +4 -0
  333. package/src/runtime/obsidian/contributions/selection-ui.mjs +4 -0
  334. package/src/runtime/obsidian/contributions/source-apply.mjs +4 -0
  335. package/src/runtime/obsidian/contributions.mjs +27 -0
  336. package/src/runtime/obsidian/documents.mjs +37 -0
  337. package/src/runtime/obsidian/enablement.mjs +53 -0
  338. package/src/runtime/obsidian/engine.mjs +532 -0
  339. package/src/runtime/obsidian/errors.mjs +14 -0
  340. package/src/runtime/obsidian/extension-points.mjs +103 -0
  341. package/src/runtime/obsidian/index.mjs +34 -0
  342. package/src/runtime/obsidian/lifecycle.mjs +258 -0
  343. package/src/runtime/obsidian/machine-settings.mjs +260 -0
  344. package/src/runtime/obsidian/observation.mjs +158 -0
  345. package/src/runtime/obsidian/opening.mjs +263 -0
  346. package/src/runtime/obsidian/pending-edits.mjs +141 -0
  347. package/src/runtime/obsidian/pipeline.mjs +122 -0
  348. package/src/runtime/obsidian/private-lock.mjs +156 -0
  349. package/src/runtime/obsidian/process-identity.mjs +58 -0
  350. package/src/runtime/obsidian/service-client.mjs +66 -0
  351. package/src/runtime/obsidian/service-entry-path.mjs +9 -0
  352. package/src/runtime/obsidian/service-main.mjs +91 -0
  353. package/src/runtime/obsidian/service-record.mjs +169 -0
  354. package/src/runtime/obsidian/service-server.mjs +121 -0
  355. package/src/runtime/obsidian/service.mjs +216 -0
  356. package/src/runtime/obsidian/startup-adapters.mjs +87 -0
  357. package/src/runtime/obsidian/state-store.mjs +180 -0
  358. package/src/runtime/obsidian/sync-notice.mjs +33 -0
  359. package/src/runtime/obsidian/tick-loop.mjs +84 -0
  360. package/src/runtime/obsidian/watchers.mjs +36 -0
  361. package/src/runtime/repository-observation.mjs +491 -0
  362. package/src/runtime/supervisor.mjs +803 -0
  363. package/src/server/local-sidecar.mjs +125 -59
  364. package/src/server/security.mjs +89 -4
  365. package/src/server/server.mjs +4 -2
  366. package/src/skills/steward.mjs +780 -0
  367. package/src/support/feedback-report.mjs +4 -3
  368. package/src/ui/presentation/browser.mjs +278 -0
  369. package/src/ui/presentation/contract.mjs +116 -0
  370. package/src/ui/presentation/index.mjs +7 -0
  371. package/src/ui/presentation/native.mjs +153 -0
  372. package/src/ui/presentation/proof.mjs +57 -0
  373. package/src/ui/presentation/schema-check.mjs +30 -0
  374. package/src/ui/presentation/schema.generated.mjs +1371 -0
  375. package/src/ui/presentation/state.mjs +43 -0
  376. package/src/ui/presentation/styles.mjs +67 -0
  377. package/src/ui/presentation/tokens.mjs +74 -0
  378. package/src/ui/presentation/web.mjs +85 -0
  379. package/src/ui/review-page.mjs +32 -0
  380. package/src/upgrade/explanation.mjs +33 -0
  381. package/src/upgrade/provenance.mjs +338 -0
  382. package/src/upgrade/transaction-files.mjs +103 -0
  383. package/src/upgrade/transaction.mjs +475 -0
  384. package/src/upgrade/upgrade.mjs +65 -29
  385. package/src/vault/hosts.mjs +21 -0
  386. package/src/vault/identity.mjs +19 -0
  387. package/src/vault/index.mjs +7 -0
  388. package/src/vault/interface.mjs +11 -0
  389. package/src/vault/metadata.mjs +31 -0
  390. package/src/vault/privacy.mjs +148 -0
  391. package/src/vault/probe.mjs +89 -0
  392. package/src/vault/service.mjs +131 -0
  393. package/src/vault/source.mjs +45 -0
  394. package/src/vault/storage.mjs +23 -0
  395. package/templates/distribution-workspace/.claude/launch.json +6 -2
  396. package/templates/distribution-workspace/gitignore +1 -0
  397. package/templates/distribution-workspace/project/README.md +2 -2
  398. package/templates/external-project-workspace/README.md +45 -0
  399. package/templates/external-project-workspace/answers.example.json +4 -0
  400. package/templates/external-project-workspace/atelier.project.json +40 -0
  401. package/templates/external-project-workspace/boundary-policy.v1.json +60 -0
  402. package/templates/external-project-workspace/gitignore +8 -0
  403. package/templates/external-project-workspace/pack-lifecycle.json +14 -0
  404. package/templates/external-project-workspace/packs/protocols/contract-gate.v1.json +109 -0
  405. package/templates/external-project-workspace/packs/sample-pack.v1.json +48 -0
  406. package/templates/external-project-workspace/repo-access.v1.json +9 -0
  407. package/templates/external-project-workspace/source/README.md +11 -0
  408. package/templates/launch.json +6 -2
  409. package/templates/private-domain-workspace/.claude/launch.json +6 -2
  410. package/templates/private-domain-workspace/domain/README.md +2 -2
  411. package/templates/private-domain-workspace/gitignore +1 -0
  412. package/templates/shared-project-workspace/.claude/launch.json +6 -2
  413. package/templates/shared-project-workspace/gitignore +1 -0
  414. package/templates/shared-project-workspace/project/README.md +2 -2
package/docs/upgrade.md CHANGED
@@ -1,10 +1,124 @@
1
1
  # Upgrade Guide
2
2
 
3
+ For an owner asking their agent to prepare an update, start with
4
+ [guided upgrades](guided-upgrades.md). It separates release selection and staged
5
+ installation from the exact local transaction and the owner's adoption decision.
6
+
3
7
  Use this guide when upgrading a copied private-domain or shared-project starter
4
8
  workspace between Atelier package releases. The flow is local-only: it does not
5
9
  provision repositories, contact a Git host, mutate the MNSTRY runtime, or write
6
10
  through a browser view.
7
11
 
12
+ ## Upgrading to 0.2.0-alpha.10
13
+
14
+ This release fixes the first activation of the Obsidian projection. In
15
+ 0.2.0-alpha.9 the check for a running Obsidian matched Atelier's own maintenance
16
+ service, so with Obsidian quit no view was ever published, and an Obsidian
17
+ with no vault open was reported as an unsupported version. To publish a view
18
+ for the first time, quit Obsidian, let the service publish, then run
19
+ `atelier obsidian open --scope ID --adapter=obsidian-cli`. No project or
20
+ machine setting needs to change.
21
+
22
+ ## Upgrading to 0.2.0-alpha.9
23
+
24
+ This release fixes a defect in 0.2.0-alpha.8: the Obsidian maintenance service
25
+ could not start from the published package (`atelier obsidian service start`
26
+ reported `start-failed` with `service-exited-13`). Upgrade from 0.2.0-alpha.8
27
+ directly; nothing else changes and no project or machine setting needs to be
28
+ touched. 0.2.0-alpha.8 is deprecated.
29
+
30
+ ## Upgrading to 0.2.0-alpha.8
31
+
32
+ This release adds typed advisory decision contracts and an experimental,
33
+ opt-in Obsidian projection. Nothing is published for a project that does not
34
+ enable `ext["mnstry.atelier.obsidian"]`; see [obsidian.md](obsidian.md).
35
+
36
+ The link resolver that produces `links_to` edges changed in five classes
37
+ (links inside code and front matter, directory links, links that climb above
38
+ the repository root, malformed percent-encoding, and workspace-only wikilink
39
+ and cross-repository edges). Regenerate committed graph artifacts after
40
+ upgrading and review the difference; the classes are listed in the changelog
41
+ and in [obsidian-contract.md](obsidian-contract.md).
42
+
43
+ ## Upgrading to 0.2.0-alpha.7
44
+
45
+ This release adds optional evidence-bound local review and the external-project
46
+ starter. Existing v1 locks and readers remain compatible. To use bound review,
47
+ explicitly qualify each pack for the new root version, regenerate the graph and
48
+ projection, and create a fresh run. Historical runs retain their original
49
+ snapshot and never acquire renewed approval from an upgrade. See
50
+ [local review](local-review.md) for the complete workflow.
51
+
52
+ ## Upgrading to 0.2.0-alpha.6
53
+
54
+ This release adds Atelier Sync Deliverable Zero: a headless, local repository
55
+ supervisor with explicit enrollment, complete repository observations,
56
+ fast-forward-only reconciliation, pause/resume control, hash-chained local
57
+ operation traces, and two-phase user-confirmed commit and publication. It does
58
+ not add a desktop shell, semantic conflict resolution, force operations,
59
+ telemetry, or unattended semantic writes.
60
+
61
+ Consumers that adopt the new runtime should enroll one repository explicitly,
62
+ treat watchers as hints rather than truth, require a fresh complete observation
63
+ before each confirmed mutation, and keep commit and publication as separate
64
+ user decisions. Existing consumers that do not import the runtime subpaths are
65
+ contract-compatible and need only update their pinned dependency.
66
+
67
+ ## Upgrading to 0.2.0-alpha.5
68
+
69
+ This release hardens public/private boundary enforcement, local serving,
70
+ collaboration-ledger integrity, disclosure review, and release provenance.
71
+ Documents valid against `0.2.0-alpha.0` remain contract-compatible, but some
72
+ previously tolerated unsafe or ambiguous states now fail closed.
73
+
74
+ - Projects using `atelier dev` must provide a generated
75
+ `atelier.manifest.json`; only enrolled, safe, realpath-validated static files
76
+ are served, and the sidecar accepts loopback traffic only.
77
+ - Empty or malformed content-rule policies, incomplete Git reads, corrupt or
78
+ oversized collaboration ledgers, and unsafe manifest entries are now
79
+ blocking errors with typed CLI diagnostics.
80
+ - Run `atelier disclosure check` before sharing tracked or staged content. A
81
+ private denylist is required by default and must remain outside the public
82
+ repository.
83
+ - Release candidates are packed once, SHA-256-bound, and the exact audited
84
+ tarball is the artifact sent through npm trusted publishing.
85
+
86
+ Re-run the boundary, disclosure, graph, readiness, and lock checks below after
87
+ updating. If `atelier dev` previously served files without a manifest, generate
88
+ and review the manifest before restarting it.
89
+
90
+ ## Upgrading to 0.2.0-alpha.4
91
+
92
+ This is a presentation release. There are no contract changes and no runtime
93
+ behaviour changes: documents valid against `0.2.0-alpha.0` remain valid, and
94
+ `npm run contract:compat` is clean against the same epoch baseline. The README,
95
+ package metadata, and public documentation now describe the Atelier as a
96
+ repository substrate for people, agents, teams, and tools. Upgrading is a
97
+ dependency bump.
98
+
99
+ ## Upgrading to 0.2.0-alpha.3
100
+
101
+ No contract changes and no runtime behaviour changes: documents valid against
102
+ `0.2.0-alpha.0` remain valid, and `npm run contract:compat` is clean against
103
+ the same epoch baseline. Upgrading is a dependency bump.
104
+
105
+ One thing worth knowing, because it changes what you type. Outside an
106
+ installed workspace, use `npx mnstry-atelier` rather than `npx atelier`: the
107
+ unscoped npm name `atelier` belongs to an unrelated third-party package, so a
108
+ bare `npx atelier` there runs someone else's code. Inside an installed
109
+ workspace both names resolve from `node_modules/.bin`, so npm scripts and
110
+ workspace shells need no change.
111
+
112
+ ## Upgrading to 0.2.0-alpha.2
113
+
114
+ No contract changes and no runtime behaviour changes: documents valid against
115
+ `0.2.0-alpha.0` remain valid, and `npm run contract:compat` is clean against
116
+ the same epoch baseline. Upgrading is a dependency bump.
117
+
118
+ Note on version numbering: `0.2.0` was published in error and unpublished the
119
+ same day. If a lockfile anywhere pins `0.2.0`, repin it to `0.2.0-alpha.2` —
120
+ that number is permanently retired on npm and will not resolve.
121
+
8
122
  ## Upgrading to 0.2.0-alpha.1
9
123
 
10
124
  No contract changes and no authored-content changes: documents valid against
@@ -12,7 +126,7 @@ No contract changes and no authored-content changes: documents valid against
12
126
  the same epoch baseline. Upgrading is a dependency bump.
13
127
 
14
128
  Two things worth knowing. The package is now on the npm registry, so the
15
- install command changes from a Git reference to `@mnstry/atelier@0.2.0-alpha.1`
129
+ install command changes from a Git reference to `@mnstry/atelier@0.2.0-alpha.2`
16
130
  — keep the `@mnstry/` scope, since the unscoped name belongs to an unrelated
17
131
  package. And a local sidecar that previously exited on a malformed request now
18
132
  answers it, so anything that supervised `atelier dev` through restarts can stop
@@ -62,16 +176,16 @@ For registry installs, pin the exact version and record the resolved version
62
176
  in the lockfile:
63
177
 
64
178
  ```bash
65
- npm install --save-dev @mnstry/atelier@0.2.0-alpha.1
66
- npx atelier lock write --project ./atelier.project.json
179
+ npm install --save-dev @mnstry/atelier@0.2.0-alpha.10
180
+ npx mnstry-atelier lock write --project ./atelier.project.json
67
181
  ```
68
182
 
69
183
  For Git installs, pin the release tag rather than a branch, so the lock file
70
184
  records exactly what was reviewed:
71
185
 
72
186
  ```bash
73
- npm install --save-dev "git+https://github.com/MNSTRY/atelier.git#v0.2.0-alpha.1"
74
- npx atelier lock write --project ./atelier.project.json
187
+ npm install --save-dev "git+https://github.com/MNSTRY/atelier.git#v0.2.0-alpha.10"
188
+ npx mnstry-atelier lock write --project ./atelier.project.json
75
189
  ```
76
190
 
77
191
  Before accepting upstream changes, run the non-mutating upgrade planner:
@@ -122,3 +236,30 @@ older workspaces and should not be used in new docs or package scripts.
122
236
  When unsure, fail closed: keep source in the private-domain workspace and move
123
237
  only a reviewed summary into the shared-project workspace through ordinary Git
124
238
  review.
239
+
240
+ ## Exact installed source and review history
241
+
242
+ `atelier lock provenance --exact-source-required` and
243
+ `atelier lock check --exact-source-required` refuse unverified bindings.
244
+ Supported npm lock metadata is a declaration matched to the exact installation
245
+ slot, including nested instances; a SHA in that declaration is not proof of the
246
+ installed bytes. Linked/unsupported stores remain unresolved when no trustworthy
247
+ instance evidence is available. Tarball/registry integrity is reported when
248
+ available, without inventing a Git origin. Dirty, ignored or untracked executable
249
+ inputs prevent verified checkout qualification. Inventory excludes Git metadata
250
+ and dependency trees; two observed byte inventories must agree and match the commit tree, including when Git index hints conceal changes. A verified clean
251
+ checkout does not authenticate an upstream publisher.
252
+
253
+ Review snapshots and decisions are separate from historical v1 locks. See
254
+ [pack lifecycle](extension-pack-lifecycle.md) and
255
+ [inspection portability](review-portability.md) before replacing packs or moving
256
+ state. Updating a package or a digest never silently renews old approval.
257
+
258
+ ## Exact local candidate transactions
259
+
260
+ For the bounded, manually confirmed single-repository workflow, see
261
+ [Local exact-plan upgrades](exact-upgrades.md). The `upgrade plan --save`,
262
+ `upgrade apply --plan ... --confirm ...`, `upgrade status`, and recovery dry-run
263
+ commands are separate from the legacy flag-based migration workflow above.
264
+ They preserve history and honor existing commit hooks; they do not install a
265
+ new package or activate a runtime.
@@ -0,0 +1,292 @@
1
+ # Portable private artifact vaults (experimental)
2
+
3
+ This is an optional hosted service contract, not part of the local authoring
4
+ server. The core does not start a service, provision infrastructure, select an
5
+ identity provider, or make network requests on import. A host explicitly binds
6
+ provider SDKs and owns their network access, credentials, costs and operations.
7
+ Canonical sources and editorial review remain in the consuming repository.
8
+ Uploading a derived artifact does not satisfy an editorial publication gate.
9
+
10
+ ## HTTP contract
11
+
12
+ - `GET /<vault>/<artifact-path>` and `HEAD` authenticate a browser session and
13
+ require exact owner issuer + subject equality. Every asset uses this route.
14
+ - `POST /_publish/<vault>` requires a separate vault-scoped machine credential.
15
+ Browser cookies and Origin headers are refused on this endpoint. The JSON
16
+ body has schema `atelier-vault-publication/v1`, `contractVersion: "1.0.0"`,
17
+ `expectedRevision` (initially
18
+ zero), and `files: [{path, base64}]`. No URL retrieval or directory discovery
19
+ occurs. The caller explicitly selects all uploaded files and is responsible
20
+ for source selection, disclosure checks and any editorial approval.
21
+ - Successful publication returns 201 and a receipt containing vault, revision
22
+ and the SHA-256 publication digest. Conflicts return 409. Retry after uncertain
23
+ delivery uses `GET /_publish/<vault>` with the same machine credential. It
24
+ returns only schema `atelier-vault-status/v1`, vault, revision and publication
25
+ digest (null before the first publication), never the file manifest. Compare
26
+ both revision and digest with the intended publication before declaring it
27
+ delivered. A differing digest or later revision requires reconciliation; do
28
+ not silently overwrite it. There is no automatic retry or idempotency promise.
29
+ - Unauthenticated reads return 401; a host may route these to its established
30
+ sign-in UI. Missing and non-owned vaults both return 404. Failures return 503
31
+ without leaking adapter errors. No CORS grants or sharing bypass exist.
32
+ - Requests are limited to 4 MiB encoded JSON, 100 files, conservative ASCII
33
+ paths and allowlisted types. HTML and CSS are supported with restrictive CSP;
34
+ scripts, SVG and arbitrary interactive applications are excluded. HTML is
35
+ sandboxed without same-origin or script privileges. PDF is a download.
36
+
37
+ All output, including errors, is private/no-store. Content bytes are checked
38
+ against the committed manifest before delivery. No public object URLs or
39
+ presigned download redirects are returned. Revocation blocks subsequent
40
+ checks; it cannot recall a response already authorized or a downloaded file.
41
+
42
+ The optional `contractVersion` and inert `ext` containers follow the kit schema
43
+ epoch. Extension data never grants authority and is not copied into artifacts.
44
+
45
+ ## Host interfaces
46
+
47
+ Import the `@mnstry/atelier/vault` entrypoint. `createVaultService` takes:
48
+
49
+ - `identity.read(request)` returns a verified `{issuer, subject}` or null. It
50
+ must verify signatures, issuer/audience, expiry and current revocation using
51
+ the chosen provider. Never derive identity from a caller-provided header.
52
+ - `identity.publish(request, vault)` verifies a machine credential. The supplied
53
+ `vaultIdentity` helper hashes a high-entropy bearer credential and calls the
54
+ host's authoritative `lookupCredential(hash)`. A record contains `vault`,
55
+ `owner`, `revoked: false` and finite millisecond `expiresAt`. Generate at least
56
+ 32 random bytes; never place credentials in repository files or URLs.
57
+ - `metadata.get(vault)` returns owner, revision and manifest. `commit` compares
58
+ owner AND expected revision atomically before replacing the current manifest.
59
+ - `storage.put(key, bytes)` and `get(key)` use private storage. Keys are generated
60
+ from validated vault IDs and byte digests; request paths never become keys.
61
+
62
+ Metadata lookup and credential lookup must use authoritative current state,
63
+ not eventually consistent caches. Provision vault ownership out of band; the
64
+ publication endpoint cannot claim a vault or change ownership. A host identity
65
+ migration must explicitly map issuer and subject, not match email strings.
66
+
67
+ ## Provider bindings
68
+
69
+ `createVercelVault` composes Blob/PostgreSQL bindings into a Web handler.
70
+ `createCloudflareVault` returns a Worker with per-request first-primary D1
71
+ sessions, using `env.VAULT_OBJECTS` and `env.VAULT_DB`. Both require explicit
72
+ verified-session and current-credential lookup functions from the host.
73
+
74
+
75
+ Vercel: pass the host-installed `@vercel/blob` SDK to `vercelPrivateStorage` and
76
+ an established PostgreSQL client object exposing `query(sql, args)` to `postgresVaultMetadata`. Use the
77
+ exported `VAULT_TABLE_SQL` to initialize a new disposable/purpose-built store.
78
+ Bind an established browser identity SDK to `verifySession`; the kit does not
79
+ ship a bespoke login system. Route all vault paths through the handler. Do not
80
+ copy artifact output into public/static deployment directories.
81
+
82
+ Cloudflare: pass a private R2 binding to `r2PrivateStorage` and D1 to
83
+ `d1VaultMetadata`. If using D1 read replication, pass a session with
84
+ `first-primary` semantics so ownership lookup cannot use a stale replica.
85
+ The Web Request/Response handler can run directly in a Worker. Disable public
86
+ R2 access and do not attach a public R2 domain. All Worker/provider aliases must
87
+ run the same handler; no cache rule or static-assets shortcut may bypass it.
88
+
89
+ Each adapter puts immutable-in-meaning content-addressed bytes first, then
90
+ switches the manifest through an atomic SQL update. Concurrent publications
91
+ cannot overwrite a newer revision. Failed uploads can leave unreferenced
92
+ private objects; garbage collection and retention are host responsibilities.
93
+ There is no automatic deletion. Republishing a selected earlier artifact set
94
+ at the current expected revision implements rollback as a new revision.
95
+
96
+ References:
97
+ - https://vercel.com/docs/vercel-blob/private-storage
98
+ - https://developers.cloudflare.com/r2/api/workers/workers-api-reference/
99
+ - https://developers.cloudflare.com/d1/worker-api/d1-database/
100
+
101
+ ## Qualification and remaining integration
102
+
103
+ `node --test test/vault.test.mjs` exercises both storage adapters with SDK-shaped
104
+ local doubles and a real SQLite engine behind both SQL interfaces. PostgreSQL
105
+ placeholder translation in the test is a local double, not a PostgreSQL engine. This proves
106
+ shared local behavior, not Vercel, R2, D1 or PostgreSQL hosted operation.
107
+
108
+ Before serving real material: qualify the chosen identity SDK and browser
109
+ login/revocation, deployed provider bindings, owner/wrong-owner/anonymous reads,
110
+ all aliases and assets, CSS/image rendering under sandbox CSP, publication
111
+ failure recovery, limits and credentials. Run a source-bound independent
112
+ review. These are open gates. The implementation is not deployment-ready.
113
+ The SDKs, production credential store, provisioning UI, CLI integration and
114
+ hosted conformance runner remain consumer-host work for the next integration
115
+ step. No existing deployment or protection setting is modified by this code.
116
+
117
+ ## Privacy gate and vault interface
118
+
119
+ This is an experimental contract, not a qualified hosted product. The service
120
+ requires a trusted `deployment: {id, origins}` binding. Origins are canonical
121
+ HTTPS origins, including every deployment alias and direct handler origin (up
122
+ to 16). The provider inspector must discover any additional bypass surfaces and
123
+ refuse `completeInventory` if this binding is stale. Configuration evidence is
124
+ trusted host input, never publisher/browser input or a repository assertion.
125
+
126
+ The context carries vault, owner, publication digest, metadata revision, manifest, deployment,
127
+ request origin/path, phase, and `objects: [{key, sha256, size}]`. Object keys are
128
+ explicit even before upload. The evaluator requires both vault home routes and
129
+ every manifest path on every configured origin, plus every unique object key.
130
+ Each route target has `kind: "route"`, URL and expected SHA-256; each storage
131
+ target has `kind: "storage"`, URL, key, SHA-256 and size. Storage URLs are only
132
+ passed to the trusted inspector/transport, never returned to the browser.
133
+
134
+ Privacy checks ask whether **anonymous and other-user identities are denied**.
135
+ They never request an owner's session or probe as the author. Owner rendering
136
+ and login continuity are separate functional acceptance checks. Consequently,
137
+ probes against the real handler exit at authorization without recursively
138
+ entering the privacy gate. No substitute owner route or privileged inspection
139
+ endpoint is used to manufacture a verified verdict.
140
+
141
+ `privacy.verify(context)` collects before-upload and before-activation evidence.
142
+ Before upload, authoritative provider configuration must attest private storage
143
+ and owner-only routing before private bytes are written. Denial probes of paths
144
+ that do not yet exist are supplementary; a 404 alone cannot prove future bytes
145
+ will be protected. A host can supply public synthetic canary markers to check
146
+ its protection machinery, without uploading private data to discover exposure.
147
+ Before activation, the same gate checks actual staged object locations and all
148
+ planned artifact routes. Unactivated artifact paths may return 404; their future
149
+ owner rendering is not asserted by a denial verdict. Provider configuration and
150
+ the handler's authorization remain the preventive controls. A change between
151
+ checks refuses activation, but cannot atomically lock external provider policy.
152
+
153
+ Read requests call only `privacy.current(context)`, which must load stored
154
+ current evidence. They never collect probes. Missing, expired, wrong-owner,
155
+ wrong-deployment, wrong-publication or incomplete evidence blocks delivery.
156
+ `createVaultPrivacyState({probe, load, compareAndSet})` supplies an explicit refresher and
157
+ host-owned evidence persistence. Call `refresh(context)` after commit and from
158
+ the host scheduler with the current authoritative manifest and owner. Use the public
159
+ `createVaultContext({vault, record, deployment})` export to build that context
160
+ from `metadata.get(vault)`; it includes storage keys, revision and null handling
161
+ without copying internal formats. Refresh rejects a missing, negative or
162
+ non-integer revision before reading the evidence store. Activation
163
+ evidence is deliberately not promoted to read evidence; owner delivery remains
164
+ unavailable until the first successful read-phase refresh. Refresh failure never
165
+ extends a validity window. A policy change requires immediate host invalidation;
166
+ the kit cannot discover that change from an evidence-store read alone.
167
+
168
+ The store key includes deployment ID and vault. `load(key)` returns an immutable
169
+ snapshot `{version, evidence}`; a missing record is `{version: 0, evidence: null}`.
170
+ `compareAndSet(key, evidence, {expectedVersion})` must atomically compare the
171
+ version, increment it on success and return exactly `true`, or return `false`
172
+ without writing. Its transaction must refuse replacement of any exposure alarm
173
+ and refuse older metadata revisions for green evidence. Exposure alarms must
174
+ be allowed to replace newer green evidence regardless of the alarm revision: a
175
+ staged-only exposure can concern objects outside the current manifest. Separate atomic load/save calls are not
176
+ sufficient. Protect the store from publishers; no unconditional save adapter is
177
+ accepted. Evidence and refresh contexts bind the authoritative metadata revision.
178
+
179
+ Green evidence retains the version loaded before collection. A conflict refuses
180
+ that collection; it is never converted into an unconditional overwrite. Before
181
+ returning non-read green evidence, the wrapper reloads the store to notice an
182
+ alarm another instance persisted during probing. This check is not atomic with
183
+ metadata activation; hosts must still own provider containment and transactions.
184
+
185
+ Exposure alarms use a different path. The wrapper latches the original evidence
186
+ in memory, then reloads and conditionally writes it, with at most three attempts
187
+ per verify/refresh call. If a durable alarm already exists, no rewrite is needed.
188
+ If writes conflict, each retry uses a fresh snapshot. If the store throws or the
189
+ attempt bound is reached, verify/refresh rejects with the public
190
+ `VaultAlarmPersistenceError` (`code: "VAULT_ALARM_NOT_PERSISTED"`, `evidence`).
191
+ Hosts must alert on that error and retry the same wrapper after store recovery.
192
+ Its next verify/refresh retries the original pending evidence without re-probing,
193
+ so a vanished or staged-only exposure is not forgotten. Store calls themselves
194
+ must have host-enforced deadlines; the attempt bound is not a network timeout.
195
+
196
+ `current` performs no persistence retry or probe and immediately returns any
197
+ local alarm, including an unpersisted one. The service's gate translates the
198
+ typed error into an exposed/refused result with `persistence: "unconfirmed"`;
199
+ the underlying wrapper API exposes the typed error to host refresh/verification
200
+ callers. Other instances and restarts cannot see an unpersisted memory latch,
201
+ so durable-store failure is an unresolved incident, never a success receipt.
202
+ Best-effort notification alone does not settle it.
203
+
204
+ No alarm-clear API is provided. Recovery is an explicit host operator procedure:
205
+ contain the external exposure, verify restored controls, reconcile durable state,
206
+ then replace affected handler instances. Restart alone is not recovery and does
207
+ not clear a successfully persisted alarm. No provider containment is implemented
208
+ by this module.
209
+
210
+ ### Reusable denial probe collector
211
+
212
+ `createVaultPrivacyProbe({inspect, request, onExposure})` takes an explicit
213
+ provider inspector and transport, without choosing a network implementation.
214
+ The transport receives only anonymous/otherUser identity, manual redirects and
215
+ an AbortSignal; otherUser must be a dedicated synthetic unauthorized principal,
216
+ not another real person's session. Never give this collector an owner credential.
217
+ The inspector supplies configuration, policy revision and the full target list.
218
+ Configuration must report `ownerOnly`, `privateStorage`, `completeInventory`.
219
+
220
+ The collector supports at most 2000 targets, sufficient for 100 files across
221
+ 16 origins plus home routes and unique storage objects. Exceeding the bound or
222
+ the configurable whole-operation deadline (maximum/default 60 seconds) refuses
223
+ verification; completeness is never replaced with sampling. The serial transport
224
+ may not finish a large inventory in time. Qualify provider latency and choose a
225
+ smaller deployment or a separately reviewed batched collector if needed. The
226
+ current 60-second validity starts at collection start; refresher period plus
227
+ worst-case collection time must be strictly less than 60 seconds. A minute
228
+ schedule or a near-deadline collection cannot provide continuous availability.
229
+ These defaults are an open product limitation, not a scheduling recommendation.
230
+
231
+ Each target supplies an expected SHA-256, optionally a public synthetic `canary`
232
+ marker of at least 32 characters. Nonempty whole-body digest or embedded canary matches
233
+ are exposure even on error or already-followed responses. Zero-byte artifacts
234
+ remain valid: an empty refusal discloses no bytes and never raises an exposure
235
+ alarm. Home-route digests may use an inspector-defined placeholder; use an
236
+ explicit public canary to detect actual listing disclosure. Nonempty 401/403/404 bodies without a match
237
+ are inconclusive, because a body fragment is not proof of non-disclosure. Empty
238
+ 401/403/404 responses count as denial. Arbitrary HTML and 5xx are inconclusive.
239
+ Login redirects may match trusted `loginEndpoints: [{url, queryKeys}]`; endpoints
240
+ are exact HTTPS origin/path, with an explicit allowlist of supported non-secret
241
+ parameter names. Credential-bearing or unexpected parameters, hosts and paths
242
+ are inconclusive. The collector never follows redirects or copies login values
243
+ into evidence. This verifies refusal, not the return-to user experience.
244
+
245
+ Evidence starts its freshness window at collection start (60 seconds), binds
246
+ owner/operation/publication/deployment, retains target digests and keys, and
247
+ re-inspects provider policy using canonical object-key ordering. An unauthorized
248
+ content observation returns immediately and stays `exposed` even if evidence
249
+ later expires. Optional `onExposure(evidence)` is a best-effort host notification;
250
+ it cannot delay or downgrade the alarm and is not durable containment. Hosts
251
+ must persist incidents and enforce provider-side containment independently.
252
+ No scheduler, provider configuration collector, credential store, containment
253
+ operation, or hosted transport is bundled here.
254
+
255
+ A provider bypass can expose staged objects after a successful preflight. This
256
+ handler can refuse its own delivery/activation but cannot close an external
257
+ public origin or delete orphaned bytes. Before real material, qualify atomic
258
+ incident persistence, provider protection restoration, staging retention/deletion
259
+ and owner-visible recovery. Do not advertise a denied handler response as global
260
+ containment or an observed denial as permanent privacy.
261
+
262
+ ### Reference interface and browser qualification
263
+
264
+ The reference home provides privacy status, revision, navigation, search, empty
265
+ and unavailable states, accessible labels and responsive layout. Its status
266
+ states that unauthorized-access checks passed at a recorded time, not that owner
267
+ rendering or every future provider state is proven. Generated HTML stays outside
268
+ the trusted shell under script-disabled sandbox CSP. This is a minimal reference
269
+ interface, not full authoring/review parity.
270
+
271
+ **Open browser design gate:** opaque-origin sandboxed HTML may lose SameSite
272
+ session cookies on CSS/image requests. Widening cookies can permit cross-site
273
+ embedding. The kit does not silently remove sandbox isolation or widen cookie
274
+ scope. A consuming host must qualify an isolated artifact-origin/session design,
275
+ including Chromium/Firefox/WebKit subresources and refused cross-site embeds,
276
+ before claiming browser-product readiness. No browser acceptance is claimed.
277
+
278
+ ### Source layouts
279
+
280
+ The Node-only `@mnstry/atelier/vault/source` entrypoint exports
281
+ `prepareVaultSource({root, paths, expectedRevision})`. Pass an absolute local
282
+ artifact root and explicit relative file paths. A root can be a folder inside
283
+ the authoring repository or a separate artifact checkout; neither is scanned
284
+ automatically. It returns the publication request, digest and manifest without
285
+ uploading anything. Keep machine-specific roots in local host configuration.
286
+
287
+ The reader refuses symlinks, hard-linked files, path escapes, directories,
288
+ unsupported formats and oversized bundles. It checks file identity and metadata
289
+ around the read and binds the resulting bytes to the manifest. Run against a
290
+ quiescent source tree; portable filesystem checks are not a sandbox against a
291
+ malicious process concurrently replacing ancestor directories. The publication
292
+ bundle is an immutable byte snapshot, not a live directory handle.
@@ -0,0 +1,5 @@
1
+ {
2
+ "id": "sample-session",
3
+ "fields": [],
4
+ "publication": true
5
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "id": "sample-session",
3
+ "fields": [
4
+ {
5
+ "id": "sample-field",
6
+ "source": {
7
+ "ref": "packet.md",
8
+ "digest": "0000000000000000000000000000000000000000000000000000000000000000"
9
+ }
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "schema": "mnstry.atelier-remote-capability@v1",
3
+ "id": "sample-capability",
4
+ "serviceRef": "https://example.invalid/mcp",
5
+ "inputSchemaDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
6
+ "outputSchemaDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
7
+ "maxInputBytes": 1024,
8
+ "implementation": "remote",
9
+ "executionAuthority": false,
10
+ "command": "execute"
11
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "schema": "mnstry.atelier-remote-capability@v1",
3
+ "id": "sample-capability",
4
+ "serviceRef": "https://example.invalid/mcp",
5
+ "inputSchemaDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
6
+ "outputSchemaDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
7
+ "maxInputBytes": 1024,
8
+ "implementation": "remote",
9
+ "executionAuthority": false
10
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "schema": "mnstry.atelier-guide-consent@v1",
3
+ "offerDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
4
+ "capabilityDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
5
+ "payloadDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
6
+ "engagementRevision": 1,
7
+ "status": "approved",
8
+ "validFrom": "2026-01-01T00:00:00Z",
9
+ "expiresAt": "2026-01-02T00:00:00Z",
10
+ "authority": "local-assertion-only"
11
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "schema": "mnstry.atelier-guide-engagement@v1",
3
+ "offerDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
4
+ "revision": 0,
5
+ "status": "proposed",
6
+ "authority": "local-assertion-only"
7
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "schema": "mnstry.atelier-guide-offer@v1",
3
+ "id": "sample-offer",
4
+ "guideId": "sample-guide",
5
+ "capabilityIds": [
6
+ "sample-capability"
7
+ ],
8
+ "deliverableReview": "required",
9
+ "commercialAuthority": false
10
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "schema": "mnstry.atelier-intake-completion@v1",
3
+ "attemptId": "sample",
4
+ "attemptDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
5
+ "outputDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
6
+ "bytes": 12,
7
+ "integrity": "verified",
8
+ "semanticAcceptance": "accepted"
9
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "schema": "mnstry.atelier-intake-attempt@v1",
3
+ "attemptId": "sample",
4
+ "blobId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
5
+ "extractorId": "plain-text",
6
+ "extractorVersion": "1",
7
+ "configurationDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
8
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "schema": "mnstry.atelier-intake-completion@v1",
3
+ "attemptId": "sample",
4
+ "attemptDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
5
+ "outputDigest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
6
+ "bytes": 12,
7
+ "integrity": "verified",
8
+ "semanticAcceptance": "pending"
9
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "schema": "mnstry.atelier-intake-source@v1",
3
+ "sourceRef": "sample.txt",
4
+ "blobId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
5
+ "bytes": 12,
6
+ "originalMutation": false
7
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "schema": "atelier-repository-observation@v1",
3
+ "observedAt": "2026-08-25T00:00:00.000Z",
4
+ "complete": true,
5
+ "root": "/workspace/project",
6
+ "filesystem": {
7
+ "supported": true,
8
+ "code": "local-filesystem"
9
+ },
10
+ "blockers": [
11
+ {
12
+ "code": "partial-clone-unsupported",
13
+ "message": "partial clones may omit required Git objects",
14
+ "details": {}
15
+ }
16
+ ],
17
+ "warnings": []
18
+ }