@mnstry/atelier 0.2.0-alpha.5 → 0.2.0-alpha.8

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 (383) hide show
  1. package/CHANGELOG.md +191 -0
  2. package/README.md +86 -25
  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/docs/assurance-controls.md +12 -2
  31. package/docs/atelier-runtime.md +13 -2
  32. package/docs/atelier-sync.md +172 -0
  33. package/docs/blocks/claims.md +28 -18
  34. package/docs/blocks/will-not-do.md +12 -3
  35. package/docs/coauthor-session.md +57 -0
  36. package/docs/connected-composition.md +75 -0
  37. package/docs/decisions.md +167 -0
  38. package/docs/exact-upgrades.md +159 -0
  39. package/docs/extension-pack-lifecycle.md +33 -0
  40. package/docs/guided-upgrades.md +99 -0
  41. package/docs/install.md +65 -9
  42. package/docs/intake-and-guides.md +65 -0
  43. package/docs/integration-and-review-plan.md +409 -0
  44. package/docs/integration-contract-decisions.md +22 -0
  45. package/docs/local-review.md +84 -0
  46. package/docs/local-services.md +227 -0
  47. package/docs/local-state.md +107 -0
  48. package/docs/obsidian-contract.md +687 -0
  49. package/docs/obsidian.md +387 -0
  50. package/docs/portable-presentation.md +328 -0
  51. package/docs/presentation-consumer-boundaries.md +75 -0
  52. package/docs/presentation-review-disposition.md +47 -0
  53. package/docs/project-command-inventory.md +38 -0
  54. package/docs/project-options.md +53 -0
  55. package/docs/release-engineering.md +99 -2
  56. package/docs/review-portability.md +55 -0
  57. package/docs/skill-steward.md +156 -0
  58. package/docs/upgrade.md +70 -2
  59. package/docs/vault-service.md +292 -0
  60. package/fixtures/atelier-coauthor/invalid/authority.v1.json +5 -0
  61. package/fixtures/atelier-coauthor/valid/config.v1.json +12 -0
  62. package/fixtures/atelier-guide/invalid/authority.v1.json +11 -0
  63. package/fixtures/atelier-guide/valid/capability.v1.json +10 -0
  64. package/fixtures/atelier-guide/valid/consent.v1.json +11 -0
  65. package/fixtures/atelier-guide/valid/engagement.v1.json +7 -0
  66. package/fixtures/atelier-guide/valid/offer.v1.json +10 -0
  67. package/fixtures/atelier-intake/invalid/authority.v1.json +9 -0
  68. package/fixtures/atelier-intake/valid/attempt.v1.json +8 -0
  69. package/fixtures/atelier-intake/valid/completion.v1.json +9 -0
  70. package/fixtures/atelier-intake/valid/source.v1.json +7 -0
  71. package/fixtures/atelier-repository-observation/invalid/complete-with-blocker.v1.json +18 -0
  72. package/fixtures/atelier-repository-observation/valid/complete-local.v1.json +48 -0
  73. package/fixtures/atelier-review/invalid/authenticated-identity.v1.json +22 -0
  74. package/fixtures/atelier-review/valid/bound.v1.json +229 -0
  75. package/fixtures/atelier-review/valid/bundle.v1.json +267 -0
  76. package/fixtures/atelier-review/valid/contribution.v1.json +22 -0
  77. package/fixtures/atelier-review/valid/lifecycle.v1.json +14 -0
  78. package/fixtures/atelier-skill-steward/audit/invalid/source-mutation.v1.json +26 -0
  79. package/fixtures/atelier-skill-steward/audit/valid/clean.v1.json +26 -0
  80. package/fixtures/atelier-skill-steward/candidates/invalid/workflow-key.v1.json +37 -0
  81. package/fixtures/atelier-skill-steward/candidates/valid/create.v1.json +37 -0
  82. package/fixtures/atelier-skill-steward/lock/invalid/bad-digest.v1.json +18 -0
  83. package/fixtures/atelier-skill-steward/lock/valid/installed.v1.json +23 -0
  84. package/fixtures/atelier-skill-steward/plan/invalid/delete-action.v1.json +33 -0
  85. package/fixtures/atelier-skill-steward/plan/valid/add.v1.json +33 -0
  86. package/fixtures/atelier-upgrade-transaction/adoption-policy/invalid/example.json +12 -0
  87. package/fixtures/atelier-upgrade-transaction/adoption-policy/valid/example.json +11 -0
  88. package/fixtures/atelier-upgrade-transaction/migration/invalid/example.json +20 -0
  89. package/fixtures/atelier-upgrade-transaction/migration/valid/example.json +19 -0
  90. package/fixtures/atelier-upgrade-transaction/upgrade-plan/invalid/example.json +58 -0
  91. package/fixtures/atelier-upgrade-transaction/upgrade-plan/valid/example.json +57 -0
  92. package/fixtures/atelier-upgrade-transaction/upgrade-receipt/invalid/example.json +15 -0
  93. package/fixtures/atelier-upgrade-transaction/upgrade-receipt/valid/example.json +14 -0
  94. package/fixtures/atelier-vault-publication/invalid/publication.json +5 -0
  95. package/fixtures/atelier-vault-publication/valid/publication.json +11 -0
  96. package/fixtures/decisions/request/invalid/unknown-authority.v1.json +61 -0
  97. package/fixtures/decisions/request/valid/triage.v1.json +60 -0
  98. package/fixtures/decisions/result/invalid/execution-authority.v1.json +50 -0
  99. package/fixtures/decisions/result/valid/abstained.v1.json +23 -0
  100. package/fixtures/decisions/result/valid/assessed.v1.json +50 -0
  101. package/fixtures/obsidian/acceptance/ap05-extra-notes.json +14 -0
  102. package/fixtures/obsidian/acceptance/receipts/G07.valid.v1.json +63 -0
  103. package/fixtures/obsidian/acceptance/receipts/G13.valid.v1.json +69 -0
  104. package/fixtures/obsidian/acceptance/receipts/G14.valid.v1.json +62 -0
  105. package/fixtures/obsidian/acceptance/receipts/G15.valid.v1.json +56 -0
  106. package/fixtures/obsidian/acceptance/receipts/G16.valid.v1.json +73 -0
  107. package/fixtures/obsidian/acceptance/receipts/G17.valid.v1.json +75 -0
  108. package/fixtures/obsidian/acceptance/receipts/G18.valid.v1.json +64 -0
  109. package/fixtures/obsidian/acceptance/service-sentinels.json +10 -0
  110. package/fixtures/obsidian/contracts/acceptance-receipt/invalid/duplicate-evidence-name.v1.json +39 -0
  111. package/fixtures/obsidian/contracts/acceptance-receipt/invalid/evidence-by-absolute-path.v1.json +34 -0
  112. package/fixtures/obsidian/contracts/acceptance-receipt/invalid/missing-candidate-tree.v1.json +33 -0
  113. package/fixtures/obsidian/contracts/acceptance-receipt/invalid/no-evidence.v1.json +28 -0
  114. package/fixtures/obsidian/contracts/acceptance-receipt/invalid/unknown-outcome.v1.json +34 -0
  115. package/fixtures/obsidian/contracts/acceptance-receipt/invalid/unknown-top-level-field.v1.json +35 -0
  116. package/fixtures/obsidian/contracts/acceptance-receipt/valid/node-gate.v1.json +34 -0
  117. package/fixtures/obsidian/contracts/apply-policy/invalid/automatic-without-edit-class.v1.json +27 -0
  118. package/fixtures/obsidian/contracts/apply-policy/invalid/conflict-overwrite.v1.json +29 -0
  119. package/fixtures/obsidian/contracts/apply-policy/invalid/missing-policy-digest.v1.json +28 -0
  120. package/fixtures/obsidian/contracts/apply-policy/invalid/unbounded-batch.v1.json +29 -0
  121. package/fixtures/obsidian/contracts/apply-policy/invalid/unimplemented-edit-class.v1.json +30 -0
  122. package/fixtures/obsidian/contracts/apply-policy/invalid/unknown-mode.v1.json +29 -0
  123. package/fixtures/obsidian/contracts/apply-policy/invalid/unknown-selector-operator.v1.json +22 -0
  124. package/fixtures/obsidian/contracts/apply-policy/invalid/unknown-top-level-field.v1.json +30 -0
  125. package/fixtures/obsidian/contracts/apply-policy/valid/automatic-scoped.v1.json +29 -0
  126. package/fixtures/obsidian/contracts/apply-policy/valid/manual-default.v1.json +20 -0
  127. package/fixtures/obsidian/contracts/corpus-profile/invalid/absolute-path-in-ext.v1.json +30 -0
  128. package/fixtures/obsidian/contracts/corpus-profile/invalid/absolute-repository-root.v1.json +27 -0
  129. package/fixtures/obsidian/contracts/corpus-profile/invalid/duplicate-repository-id.v1.json +27 -0
  130. package/fixtures/obsidian/contracts/corpus-profile/invalid/overlapping-managed-roots.v1.json +27 -0
  131. package/fixtures/obsidian/contracts/corpus-profile/invalid/unknown-enrollment.v1.json +27 -0
  132. package/fixtures/obsidian/contracts/corpus-profile/invalid/unknown-top-level-field.v1.json +28 -0
  133. package/fixtures/obsidian/contracts/corpus-profile/valid/three-repositories.v1.json +27 -0
  134. package/fixtures/obsidian/contracts/edit-operation/invalid/absolute-recovery-ref.v1.json +21 -0
  135. package/fixtures/obsidian/contracts/edit-operation/invalid/inline-observed-bytes.v1.json +22 -0
  136. package/fixtures/obsidian/contracts/edit-operation/invalid/missing-base-digest.v1.json +20 -0
  137. package/fixtures/obsidian/contracts/edit-operation/invalid/short-idempotency-key.v1.json +21 -0
  138. package/fixtures/obsidian/contracts/edit-operation/invalid/unknown-kind.v1.json +21 -0
  139. package/fixtures/obsidian/contracts/edit-operation/valid/pending-body-replacement.v1.json +21 -0
  140. package/fixtures/obsidian/contracts/ext-settings/invalid/absolute-path-prefix.v1.json +28 -0
  141. package/fixtures/obsidian/contracts/ext-settings/invalid/apply-policy-in-portable-settings.v1.json +30 -0
  142. package/fixtures/obsidian/contracts/ext-settings/invalid/duplicate-scope-id.v1.json +27 -0
  143. package/fixtures/obsidian/contracts/ext-settings/invalid/machine-local-vault-path.v1.json +28 -0
  144. package/fixtures/obsidian/contracts/ext-settings/invalid/service-port-in-portable-settings.v1.json +28 -0
  145. package/fixtures/obsidian/contracts/ext-settings/invalid/unknown-default-scope.v1.json +27 -0
  146. package/fixtures/obsidian/contracts/ext-settings/valid/disabled.v1.json +5 -0
  147. package/fixtures/obsidian/contracts/ext-settings/valid/enabled-with-scopes.v1.json +27 -0
  148. package/fixtures/obsidian/contracts/generation-manifest/invalid/absolute-note-path.v1.json +114 -0
  149. package/fixtures/obsidian/contracts/generation-manifest/invalid/complete-with-unwritten-notes.v1.json +114 -0
  150. package/fixtures/obsidian/contracts/generation-manifest/invalid/derived-link-claimed-declared.v1.json +114 -0
  151. package/fixtures/obsidian/contracts/generation-manifest/invalid/duplicate-note-identity.v1.json +114 -0
  152. package/fixtures/obsidian/contracts/generation-manifest/invalid/in-scope-endpoint-missing.v1.json +114 -0
  153. package/fixtures/obsidian/contracts/generation-manifest/invalid/title-only-note-path.v1.json +114 -0
  154. package/fixtures/obsidian/contracts/generation-manifest/invalid/unknown-note-field.v1.json +115 -0
  155. package/fixtures/obsidian/contracts/generation-manifest/invalid/unknown-relation-type.v1.json +114 -0
  156. package/fixtures/obsidian/contracts/generation-manifest/invalid/withheld-endpoint.v1.json +114 -0
  157. package/fixtures/obsidian/contracts/generation-manifest/valid/two-notes.v1.json +114 -0
  158. package/fixtures/obsidian/contracts/oracles/scope-cases.json +412 -0
  159. package/fixtures/obsidian/contracts/proposal-receipt/invalid/accepted-without-proposal-id.v1.json +12 -0
  160. package/fixtures/obsidian/contracts/proposal-receipt/invalid/missing-adapter-operation-id.v1.json +11 -0
  161. package/fixtures/obsidian/contracts/proposal-receipt/invalid/unknown-backpressure-outcome.v1.json +12 -0
  162. package/fixtures/obsidian/contracts/proposal-receipt/invalid/unknown-top-level-field.v1.json +13 -0
  163. package/fixtures/obsidian/contracts/proposal-receipt/valid/accepted-new.v1.json +12 -0
  164. package/fixtures/obsidian/contracts/proposal-receipt/valid/deferred.v1.json +12 -0
  165. package/fixtures/obsidian/contracts/publication-journal/invalid/absolute-recovery-ref.v1.json +47 -0
  166. package/fixtures/obsidian/contracts/publication-journal/invalid/duplicate-sequence.v1.json +47 -0
  167. package/fixtures/obsidian/contracts/publication-journal/invalid/empty-protocol-id.v1.json +47 -0
  168. package/fixtures/obsidian/contracts/publication-journal/invalid/missing-protocol-id.v1.json +46 -0
  169. package/fixtures/obsidian/contracts/publication-journal/invalid/unknown-entry-field.v1.json +48 -0
  170. package/fixtures/obsidian/contracts/publication-journal/invalid/unknown-state.v1.json +47 -0
  171. package/fixtures/obsidian/contracts/publication-journal/valid/committed.v1.json +47 -0
  172. package/fixtures/obsidian/contracts/publication-journal/valid/updating-after-restart.v1.json +22 -0
  173. package/fixtures/obsidian/contracts/scope/invalid/absolute-path-prefix.v1.json +15 -0
  174. package/fixtures/obsidian/contracts/scope/invalid/duplicate-ids.v1.json +18 -0
  175. package/fixtures/obsidian/contracts/scope/invalid/expansion-without-node-budget.v1.json +40 -0
  176. package/fixtures/obsidian/contracts/scope/invalid/full-mode-with-subset.v1.json +8 -0
  177. package/fixtures/obsidian/contracts/scope/invalid/unknown-mode.v1.json +41 -0
  178. package/fixtures/obsidian/contracts/scope/invalid/unknown-selector-key.v1.json +15 -0
  179. package/fixtures/obsidian/contracts/scope/invalid/unknown-selector-operator.v1.json +14 -0
  180. package/fixtures/obsidian/contracts/scope/invalid/unknown-top-level-field.v1.json +42 -0
  181. package/fixtures/obsidian/contracts/scope/valid/explicit-empty.v1.json +8 -0
  182. package/fixtures/obsidian/contracts/scope/valid/focus.v1.json +11 -0
  183. package/fixtures/obsidian/contracts/scope/valid/full.v1.json +8 -0
  184. package/fixtures/obsidian/contracts/scope/valid/scoped-set-expression.v1.json +41 -0
  185. package/fixtures/obsidian/contracts/service-state/invalid/hostname-instead-of-literal-loopback.v1.json +23 -0
  186. package/fixtures/obsidian/contracts/service-state/invalid/missing-consent.v1.json +18 -0
  187. package/fixtures/obsidian/contracts/service-state/invalid/privileged-port.v1.json +23 -0
  188. package/fixtures/obsidian/contracts/service-state/invalid/unknown-top-level-field.v1.json +24 -0
  189. package/fixtures/obsidian/contracts/service-state/invalid/wildcard-bind.v1.json +23 -0
  190. package/fixtures/obsidian/contracts/service-state/valid/healthy.v1.json +23 -0
  191. package/fixtures/obsidian/contracts/source-snapshot/invalid/absolute-file-path.v1.json +48 -0
  192. package/fixtures/obsidian/contracts/source-snapshot/invalid/duplicate-repository-id.v1.json +48 -0
  193. package/fixtures/obsidian/contracts/source-snapshot/invalid/mixed-read.v1.json +48 -0
  194. package/fixtures/obsidian/contracts/source-snapshot/invalid/parent-traversal-path.v1.json +48 -0
  195. package/fixtures/obsidian/contracts/source-snapshot/invalid/unknown-file-field.v1.json +49 -0
  196. package/fixtures/obsidian/contracts/source-snapshot/valid/two-repositories.v1.json +48 -0
  197. package/fixtures/obsidian/edits/workspace.json +65 -0
  198. package/fixtures/obsidian/materialization/expected-full.json +99 -0
  199. package/fixtures/obsidian/materialization/expected-scoped.json +39 -0
  200. package/fixtures/obsidian/materialization/workspace.json +54 -0
  201. package/fixtures/obsidian/proposals/expected-shapes.json +11 -0
  202. package/fixtures/ui/presentation/pane.v1.json +7 -0
  203. package/fixtures/ui/presentation/reference.v1.json +293 -0
  204. package/package.json +61 -6
  205. package/skills/claude/atelier-guided-coauthor/SKILL.md +49 -0
  206. package/skills/claude/atelier-guided-upgrade/SKILL.md +97 -0
  207. package/skills/claude/atelier-open/SKILL.md +5 -0
  208. package/skills/claude/atelier-skill-steward/SKILL.md +62 -0
  209. package/skills/claude/mnstry-readiness/SKILL.md +5 -0
  210. package/skills/codex/atelier-guided-coauthor/SKILL.md +49 -0
  211. package/skills/codex/atelier-guided-upgrade/SKILL.md +97 -0
  212. package/skills/codex/atelier-open/SKILL.md +5 -0
  213. package/skills/codex/atelier-skill-steward/SKILL.md +62 -0
  214. package/skills/codex/mnstry-readiness/SKILL.md +5 -0
  215. package/src/access/preview-enforcer.mjs +84 -0
  216. package/src/boundary/content-rules.mjs +9 -4
  217. package/src/boundary/policy.mjs +74 -42
  218. package/src/cli/project-options.mjs +58 -0
  219. package/src/cli/run.mjs +61 -3
  220. package/src/coauthor/session.mjs +161 -0
  221. package/src/coauthor/store.mjs +173 -0
  222. package/src/collaboration/event-ledger.mjs +16 -33
  223. package/src/collaboration/inspection-bundle.mjs +223 -0
  224. package/src/collaboration/review-contracts.mjs +25 -0
  225. package/src/collaboration/review-store.mjs +305 -0
  226. package/src/commands/coauthor.mjs +26 -0
  227. package/src/commands/config.mjs +6 -1
  228. package/src/commands/extension-pack.mjs +15 -8
  229. package/src/commands/init.mjs +44 -5
  230. package/src/commands/obsidian.mjs +368 -0
  231. package/src/commands/review.mjs +147 -0
  232. package/src/commands/setup.mjs +51 -14
  233. package/src/commands/skills.mjs +199 -0
  234. package/src/commands/sync.mjs +107 -0
  235. package/src/composition/registry.mjs +27 -0
  236. package/src/composition/wire.mjs +122 -0
  237. package/src/contracts/corpus.mjs +35 -0
  238. package/src/decisions/contracts.d.mts +96 -0
  239. package/src/decisions/contracts.mjs +321 -0
  240. package/src/disclosure/content-scan.mjs +13 -0
  241. package/src/export/atelier-export-contract.mjs +16 -1
  242. package/src/extension-packs/lifecycle.mjs +154 -0
  243. package/src/graph/graph.mjs +64 -2
  244. package/src/graph/knowledge-graph.mjs +548 -24
  245. package/src/guides/contracts.mjs +54 -0
  246. package/src/index.mjs +29 -0
  247. package/src/intake/store.mjs +119 -0
  248. package/src/preview/channel.mjs +89 -0
  249. package/src/project/config.mjs +50 -49
  250. package/src/project/durable-state.mjs +161 -0
  251. package/src/project/file-class.mjs +166 -0
  252. package/src/project/private-state.mjs +11 -1
  253. package/src/projection/obsidian/contracts.mjs +571 -0
  254. package/src/projection/obsidian/edits/align.mjs +169 -0
  255. package/src/projection/obsidian/edits/apply.mjs +889 -0
  256. package/src/projection/obsidian/edits/arbitrate.mjs +414 -0
  257. package/src/projection/obsidian/edits/contribution.mjs +108 -0
  258. package/src/projection/obsidian/edits/index.mjs +19 -0
  259. package/src/projection/obsidian/edits/object-identity.mjs +61 -0
  260. package/src/projection/obsidian/edits/object-store.mjs +517 -0
  261. package/src/projection/obsidian/edits/observe.mjs +123 -0
  262. package/src/projection/obsidian/edits/policy.mjs +123 -0
  263. package/src/projection/obsidian/edits/regions.mjs +648 -0
  264. package/src/projection/obsidian/materialize/byte-lens.mjs +98 -0
  265. package/src/projection/obsidian/materialize/index.mjs +7 -0
  266. package/src/projection/obsidian/materialize/path-registry.mjs +105 -0
  267. package/src/projection/obsidian/materialize/prepare-view.mjs +746 -0
  268. package/src/projection/obsidian/materialize/settings.mjs +57 -0
  269. package/src/projection/obsidian/materialize/stage.mjs +27 -0
  270. package/src/projection/obsidian/proposals/adapter.mjs +572 -0
  271. package/src/projection/obsidian/proposals/backpressure.mjs +113 -0
  272. package/src/projection/obsidian/proposals/contribution.mjs +55 -0
  273. package/src/projection/obsidian/proposals/index.mjs +23 -0
  274. package/src/projection/obsidian/proposals/observation.mjs +216 -0
  275. package/src/projection/obsidian/proposals/queue.mjs +277 -0
  276. package/src/projection/obsidian/proposals/router.mjs +168 -0
  277. package/src/projection/obsidian/publication/bridge-script.mjs +266 -0
  278. package/src/projection/obsidian/publication/exchange.mjs +117 -0
  279. package/src/projection/obsidian/publication/index.mjs +5 -0
  280. package/src/projection/obsidian/publication/publisher.mjs +588 -0
  281. package/src/projection/obsidian/publication/test-seam.mjs +16 -0
  282. package/src/projection/obsidian/publication/transport.mjs +139 -0
  283. package/src/projection/obsidian/recovery/index.mjs +6 -0
  284. package/src/projection/obsidian/recovery/journal.mjs +134 -0
  285. package/src/projection/obsidian/recovery/late-writer.mjs +46 -0
  286. package/src/projection/obsidian/recovery/restart.mjs +316 -0
  287. package/src/projection/obsidian/recovery/store.mjs +234 -0
  288. package/src/projection/obsidian/selection-ui/conflict-view.mjs +91 -0
  289. package/src/projection/obsidian/selection-ui/contribution.mjs +141 -0
  290. package/src/projection/obsidian/selection-ui/focus.mjs +82 -0
  291. package/src/projection/obsidian/selection-ui/index.mjs +12 -0
  292. package/src/projection/obsidian/selection-ui/policy-setup.mjs +107 -0
  293. package/src/projection/obsidian/selection-ui/receipt.mjs +173 -0
  294. package/src/projection/obsidian/selection-ui/selection-state.mjs +122 -0
  295. package/src/projection/obsidian/selection-ui/selection.mjs +109 -0
  296. package/src/projection/project.mjs +28 -19
  297. package/src/readiness-protocols/evidence.mjs +282 -0
  298. package/src/readiness-protocols/runtime.mjs +4 -3
  299. package/src/readiness-protocols/source-read.mjs +39 -0
  300. package/src/runtime/git-adapter.mjs +189 -0
  301. package/src/runtime/local-state.mjs +439 -0
  302. package/src/runtime/obsidian/app-capability.mjs +110 -0
  303. package/src/runtime/obsidian/app-production-seams.mjs +96 -0
  304. package/src/runtime/obsidian/contributions/proposal-adapter.mjs +4 -0
  305. package/src/runtime/obsidian/contributions/selection-ui.mjs +4 -0
  306. package/src/runtime/obsidian/contributions/source-apply.mjs +4 -0
  307. package/src/runtime/obsidian/contributions.mjs +27 -0
  308. package/src/runtime/obsidian/documents.mjs +37 -0
  309. package/src/runtime/obsidian/enablement.mjs +53 -0
  310. package/src/runtime/obsidian/engine.mjs +532 -0
  311. package/src/runtime/obsidian/errors.mjs +14 -0
  312. package/src/runtime/obsidian/extension-points.mjs +103 -0
  313. package/src/runtime/obsidian/index.mjs +34 -0
  314. package/src/runtime/obsidian/lifecycle.mjs +258 -0
  315. package/src/runtime/obsidian/machine-settings.mjs +260 -0
  316. package/src/runtime/obsidian/observation.mjs +158 -0
  317. package/src/runtime/obsidian/opening.mjs +243 -0
  318. package/src/runtime/obsidian/pending-edits.mjs +141 -0
  319. package/src/runtime/obsidian/pipeline.mjs +122 -0
  320. package/src/runtime/obsidian/private-lock.mjs +156 -0
  321. package/src/runtime/obsidian/process-identity.mjs +58 -0
  322. package/src/runtime/obsidian/service-client.mjs +66 -0
  323. package/src/runtime/obsidian/service-main.mjs +89 -0
  324. package/src/runtime/obsidian/service-record.mjs +169 -0
  325. package/src/runtime/obsidian/service-server.mjs +121 -0
  326. package/src/runtime/obsidian/service.mjs +216 -0
  327. package/src/runtime/obsidian/startup-adapters.mjs +87 -0
  328. package/src/runtime/obsidian/state-store.mjs +180 -0
  329. package/src/runtime/obsidian/sync-notice.mjs +33 -0
  330. package/src/runtime/obsidian/tick-loop.mjs +84 -0
  331. package/src/runtime/obsidian/watchers.mjs +36 -0
  332. package/src/runtime/repository-observation.mjs +491 -0
  333. package/src/runtime/supervisor.mjs +803 -0
  334. package/src/server/local-sidecar.mjs +44 -0
  335. package/src/server/server.mjs +1 -0
  336. package/src/skills/steward.mjs +780 -0
  337. package/src/ui/presentation/browser.mjs +278 -0
  338. package/src/ui/presentation/contract.mjs +116 -0
  339. package/src/ui/presentation/index.mjs +7 -0
  340. package/src/ui/presentation/native.mjs +153 -0
  341. package/src/ui/presentation/proof.mjs +57 -0
  342. package/src/ui/presentation/schema-check.mjs +30 -0
  343. package/src/ui/presentation/schema.generated.mjs +1371 -0
  344. package/src/ui/presentation/state.mjs +43 -0
  345. package/src/ui/presentation/styles.mjs +67 -0
  346. package/src/ui/presentation/tokens.mjs +74 -0
  347. package/src/ui/presentation/web.mjs +85 -0
  348. package/src/ui/review-page.mjs +32 -0
  349. package/src/upgrade/explanation.mjs +33 -0
  350. package/src/upgrade/provenance.mjs +338 -0
  351. package/src/upgrade/transaction-files.mjs +103 -0
  352. package/src/upgrade/transaction.mjs +475 -0
  353. package/src/upgrade/upgrade.mjs +63 -28
  354. package/src/vault/hosts.mjs +21 -0
  355. package/src/vault/identity.mjs +19 -0
  356. package/src/vault/index.mjs +7 -0
  357. package/src/vault/interface.mjs +11 -0
  358. package/src/vault/metadata.mjs +31 -0
  359. package/src/vault/privacy.mjs +148 -0
  360. package/src/vault/probe.mjs +89 -0
  361. package/src/vault/service.mjs +131 -0
  362. package/src/vault/source.mjs +45 -0
  363. package/src/vault/storage.mjs +23 -0
  364. package/templates/distribution-workspace/.claude/launch.json +6 -2
  365. package/templates/distribution-workspace/gitignore +1 -0
  366. package/templates/distribution-workspace/project/README.md +2 -2
  367. package/templates/external-project-workspace/README.md +45 -0
  368. package/templates/external-project-workspace/answers.example.json +4 -0
  369. package/templates/external-project-workspace/atelier.project.json +40 -0
  370. package/templates/external-project-workspace/boundary-policy.v1.json +60 -0
  371. package/templates/external-project-workspace/gitignore +8 -0
  372. package/templates/external-project-workspace/pack-lifecycle.json +14 -0
  373. package/templates/external-project-workspace/packs/protocols/contract-gate.v1.json +109 -0
  374. package/templates/external-project-workspace/packs/sample-pack.v1.json +48 -0
  375. package/templates/external-project-workspace/repo-access.v1.json +9 -0
  376. package/templates/external-project-workspace/source/README.md +11 -0
  377. package/templates/launch.json +6 -2
  378. package/templates/private-domain-workspace/.claude/launch.json +6 -2
  379. package/templates/private-domain-workspace/domain/README.md +2 -2
  380. package/templates/private-domain-workspace/gitignore +1 -0
  381. package/templates/shared-project-workspace/.claude/launch.json +6 -2
  382. package/templates/shared-project-workspace/gitignore +1 -0
  383. package/templates/shared-project-workspace/project/README.md +2 -2
@@ -0,0 +1,328 @@
1
+ # Portable presentation v1
2
+
3
+ Status: opt-in implementation candidate, not a published or adopted interface.
4
+ Contract discussion: [issue 39](https://github.com/MNSTRY/atelier/issues/39).
5
+ Current corrections and remaining adoption conditions:
6
+ [review disposition](presentation-review-disposition.md).
7
+
8
+ ## Placement and authority
9
+
10
+ Atelier owns the domain-neutral presentation model, bounded validators, neutral
11
+ tokens, reference views and proof mechanisms in this module. A host supplies
12
+ meaning, capabilities, action references, data, business validation, persistence,
13
+ operation outcomes and receipts. A renderer cannot promote a request into an
14
+ operation, permission, accepted decision or publication.
15
+
16
+ This implementation was independently derived from generic presentation
17
+ requirements and public accessibility standards. The paper-shape fixture is
18
+ invented. No client implementation, brand palette, information architecture or
19
+ methodology was imported. The existing CLI, sidecar HTML helpers and unpublished
20
+ control-grammar work are not replaced or silently adopted. This is a new optional
21
+ subpath, not a second semantic interpretation or route-adoption authority.
22
+
23
+ Source reservation: `src/ui/presentation/**`, the two presentation schemas,
24
+ `fixtures/ui/presentation/**`, the presentation tests and proof/generation scripts,
25
+ and this document. Package exports, pinned test-only dependencies, the local
26
+ proof command, and contract-corpus entries are scoped shared-file hunks. No runtime, server, command catalog, existing UI
27
+ helper, release guard, route, template or consumer source is changed.
28
+
29
+ ## API and host connection
30
+
31
+ ```js
32
+ import { assertPresentation, renderPresentation } from '@mnstry/atelier/presentation'
33
+ import { bindPresentation } from '@mnstry/atelier/presentation/browser'
34
+
35
+ assertPresentation(model)
36
+ container.innerHTML = renderPresentation(model)
37
+ const binding = bindPresentation(container.querySelector('[data-ap-root]'), model, {
38
+ onRequest: request => host.receivePresentationRequest(request),
39
+ })
40
+ // Refresh the same presentation without losing drafts, focus or selection:
41
+ binding.update(nextModel)
42
+ // For a host-approved draft reset, use { discardDrafts: true } explicitly.
43
+ // Before a genuine unmount or a change of presentation identity:
44
+ binding.dispose()
45
+ ```
46
+
47
+ `host` is a consumer-owned port, not a shipped implementation. Do not pass
48
+ arbitrary HTML; only the validated renderer output is intended for insertion.
49
+ Give simultaneously mounted models distinct IDs. Styles and DOM IDs are scoped
50
+ by that identity. Callers embedding more than one workspace must supply an
51
+ appropriate page-level landmark hierarchy; the document renderer emits a main
52
+ landmark for one workspace.
53
+
54
+ Required model identity is `schema: "atelier.presentation/v1"` and
55
+ `version: "1.0.0"`. Optional `contractVersion` follows the repository's schema
56
+ epoch convention; it is metadata, not an alternative version-negotiation path.
57
+ Optional `ext` containers are retained, bounded plain JSON and never interpreted,
58
+ rendered or used to authorize an action. Unknown ordinary fields and unsupported
59
+ versions refuse. Validation, serialization and parsing share a 1 MiB UTF-8 limit
60
+ on the canonical model; parsing also bounds the incoming bytes (including extra
61
+ whitespace). Canonical serialization does not mean signing or acceptance.
62
+
63
+ All callback requests carry `schema: "atelier.presentation-request/v1"`,
64
+ `version: "1.0.0"`, `presentationId`, `status: "proposed"`, and
65
+ `executionAuthority: false`. Kinds and payloads:
66
+
67
+ | Kind | Payload | Host obligation |
68
+ | --- | --- | --- |
69
+ | action | `id`, opaque `actionRef`, optional `presentationConfirmed: true` | Resolve current permission, operation and final outcome independently |
70
+ | selection | `id`, `itemId` | Return authoritative selection; do not infer persistence |
71
+ | resize | pane `id`, bounded percentage `value` | Apply current host geometry rules and return the next model |
72
+ | edit | field/editor `id`, string `value` | Maintain local draft promptly; validate and persist through existing authority |
73
+ | move | sequence `id`, `itemId`, zero-based `position` | Recheck eligibility and current ordering; apply only through the host |
74
+ | navigation | native `id`, `paneId`, or `itemId` and local `href` | Resolve host navigation and focus; never create a global shortcut bridge |
75
+
76
+ Callback resolution confirms delivery only. Rejection reports delivery failure,
77
+ not business refusal or rollback. Both projections use one delivery-message
78
+ function: each settlement describes its own outcome and identifies other pending
79
+ requests; an unrelated earlier failure cannot relabel a later successful delivery.
80
+ Repeated pending actions are suppressed without
81
+ disabling the focused web control. Every valid edit is delivered synchronously to
82
+ the host callback, including during earlier async delivery; there is no hidden
83
+ coalescing queue to lose at unmount. The host must capture drafts on callback
84
+ entry and order acknowledgements through its existing concurrency mechanism.
85
+ Out-of-order persistence responses must not replace a newer accepted host state.
86
+ Unmount removes scoped
87
+ listeners and pending visual flags but cannot cancel a callback already delivered
88
+ to a host. Host operations therefore need their own concurrency, idempotency,
89
+ authorization and outcome-recovery controls. Use `binding.update(nextModel)` for
90
+ same-ID refreshes: it closes obsolete confirmations, preserves surviving control
91
+ focus/selection, and retains each draft until the model acknowledges that value.
92
+ Removed nodes and changed input kinds lose their local drafts. A same-ID host reset must explicitly pass
93
+ `discardDrafts: true`; a different document must use a new presentation identity.
94
+ During IME composition, updates validate immediately and retain only the latest
95
+ valid model without replacing the composing DOM. `isComposing` and
96
+ `hasPendingUpdate` expose this lifecycle. On `compositionend`, the final draft
97
+ is delivered before applying that model; a synchronous newer host update wins.
98
+ Removal, disable, input-kind change or `discardDrafts` in the queued model
99
+ suppresses the obsolete edit. Other widget requests wait without dispatch while
100
+ an update is queued. Disposal clears the queue; it is not durable draft storage.
101
+ Email/number fields retain the same focused input element on compatible refresh
102
+ because those types expose no selection API. A host reset or input-kind change
103
+ does not promise caret continuity. Token overrides must be supplied again on
104
+ update if used.
105
+ Dispose/re-render is an unmount, not the controlled-update path. The native
106
+ component must be keyed to its model identity; its host resets use a React key
107
+ change, and draft acknowledgement follows the same value-matching rule.
108
+
109
+ The edit limit is 32,768 Unicode code points, matching the schema rather than
110
+ UTF-16 code units. Over-limit or incomplete Unicode input remains visible locally
111
+ with an error and is not sent; it is never silently shortened. Web composition
112
+ is evaluated when composition ends. Local drafts are not durable persistence.
113
+
114
+ The module installs no transport, storage, process, global keyboard handler,
115
+ telemetry, hosted account, command registration or navigation service. Web links
116
+ are local paths or fragments and use ordinary browser navigation: they do not
117
+ emit `onRequest` navigation events. Native links require the host's navigation
118
+ request port because native has no browser default. A web host with unsaved work
119
+ must omit item hrefs until safe navigation is available through its existing
120
+ route/draft authority; this module does not install an unsaved-work route guard.
121
+ Do not infer identical web/native navigation interception from shared labels.
122
+ Media resolves only local paths; hosts must prevent
123
+ those routes from redirecting outside their intended boundary. The model is not
124
+ a network-security boundary for a consumer's asset server.
125
+
126
+ ## Tokens, composition and component families
127
+
128
+ One checked token source covers typography, light/dark color, spacing, layout,
129
+ density, elevation, borders, motion and state. Overrides are restricted to known
130
+ keys and safe values. Text/background pairs have a 4.5:1 floor, control boundaries
131
+ and focus have 3:1, and reference controls have 44-unit minimum targets in both
132
+ densities. Compact density changes spacing, not target or type floors. A host's
133
+ font metrics, zoom, transparency and surrounding surface still need verification.
134
+
135
+ One primary pane is required. Context/utility panes remain linear and reachable
136
+ at narrow container widths; resizing is hidden when panes stack. Width values are
137
+ relative flex weights after gaps, not independent percentages plus gaps. Missing
138
+ weights default to 50. A 60/40 pair shares one row; allocations below the minimum
139
+ pane width wrap rather than crushing controls. The native host supplies its measured
140
+ container width; the web projection uses the presentation root's content box.
141
+ Panes accept block IDs,
142
+ not executable routes, business schemas or workspace-allocation commands.
143
+
144
+ Implemented reference families: text, collection, ordered sequence, graph node
145
+ list with relationship table, media, action, status, refusal, decision, receipt,
146
+ offer, field, editor, preview, diff, review and publication. The latter names are
147
+ display slots: their text, tone and actions come from the host. No business
148
+ lifecycle is defined. Graph lists and relationship tables are the accessible
149
+ baseline; a force layout, query engine, graph editing and virtualization are not
150
+ implemented by this reference. Rich text/media editors likewise belong in
151
+ separately proved adapters, not in an unbounded interpretation of a text field.
152
+
153
+ Only host-selected blocks should enter a workspace. The all-family fixture is a
154
+ coverage gallery, not a recommended product screen. Use the workspace's primary
155
+ task and context needs to limit simultaneous controls; preserve visible reasons,
156
+ action consequences and recovery state when applying progressive disclosure.
157
+
158
+ ## Interaction and accessibility contract
159
+
160
+ Hover, focus, pressed, selected, disabled, pending, invalid and dragging are
161
+ independent axes; selection must not erase focus. Web focus is visible, pressed
162
+ feedback differs from hover, and reduced-motion preference removes transitions.
163
+ Forced-color mode retains focus and selection boundaries. Ordinary keys and Tab
164
+ remain native; only a focused range's Arrow/Home/End keys and the confirmation
165
+ dialog's Tab endpoints are locally handled. Host-resolved shortcut display and
166
+ ARIA hints register no commands and promise no shortcut implementation.
167
+
168
+ Confirmation shows host-supplied consequences, initially focuses Cancel, contains
169
+ Tab, accepts Escape and restores the opener (or surviving pane). Confirmation is
170
+ never an authorization or successful irreversible operation. A missing native
171
+ confirmation port refuses to send. A host still owns reauthentication, irreversible
172
+ action eligibility, last-moment checks, receipt interpretation and recovery.
173
+
174
+ Sequences optionally expose drag requests and equivalent earlier/later buttons.
175
+ Drop handling accepts only an active drag begun in the same bound sequence; it
176
+ never imports external drop data. Touch and keyboard users need not drag. Bounds
177
+ and order remain host-controlled after either interaction. Browser/native
178
+ platforms may supply additional drag affordances only after equivalent proof.
179
+
180
+ The reference follows the intent of W3C guidance on
181
+ [modal dialogs](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/),
182
+ [range/separator interaction](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/),
183
+ [non-drag alternatives](https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html)
184
+ and [target size](https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html).
185
+ The range is a labelled native range, not an assertion of splitter-pattern
186
+ conformance. Automated checks do not establish WCAG certification or assistive
187
+ technology acceptance.
188
+
189
+ ## Host projections and explicit exceptions
190
+
191
+ | Host | Implemented projection | Remaining receiving-host proof |
192
+ | --- | --- | --- |
193
+ | Web | Semantic HTML, scoped CSS and local binder | Real route, keyboard catalogue, assistive technology and host updates |
194
+ | Desktop webview | Same optional web module | Webview version, OS shortcuts/focus, process and broker isolation; no Desktop runtime included |
195
+ | Native | Injected React/native-compatible primitives, tokens, requests, linear graph/diff, pane layout | Actual framework build, font scaling, screen reader, keyboard/focus, dialogs, touch and device proof |
196
+ | Documents | `renderReadOnlyDocument`, linear content and print styles | Exact PDF/export pipeline, tagging, pagination, font embedding and document semantics |
197
+
198
+ `createNativePresentation` accepts the consumer's existing `React`, `View`,
199
+ `Text`, `Pressable`, `TextInput`, `ScrollView`, and `Image`; compatible wrappers
200
+ can use existing Tamagui primitives. Atelier takes no runtime framework dependency;
201
+ React and React DOM are pinned development-only proof dependencies.
202
+ `Pressable` must support React Native's state-function style. The host supplies
203
+ measured `containerWidth`, `resolveAsset` and a `confirm` port implementing cancel
204
+ initial focus and focus restoration. Native uses step/move buttons instead of a
205
+ browser range/drag API. Focus treatment and OS keyboard behavior remain native
206
+ host obligations; injected-tree tests cannot prove them. The proof runner also
207
+ mounts real React against deliberately minimal DOM bindings to exercise stale
208
+ confirmation rejection and concurrent pending state; this is lifecycle proof,
209
+ not React Native or Tamagui compatibility. Committed model changes invalidate
210
+ an outstanding native confirmation conservatively, with a visible explanation.
211
+ Equivalent-model rerenders with fresh callback identities do not revoke it;
212
+ delivery uses the latest committed callback. Removing either host port refuses
213
+ confirmation. Request settlement remains visible across model updates, with
214
+ each settlement's own outcome reported independently of other request failures.
215
+ Do not claim compatibility
216
+ with a specific framework version until its mounted adapter has been tested.
217
+
218
+ Document output has no edit, resize, confirmation or move controls. It preserves
219
+ host status text but cannot create a receipt. Print neutralizes dark colors and
220
+ hides navigation and interactive buttons, retaining action explanations and
221
+ unavailability reasons. This is HTML suitable for an existing export
222
+ pipeline, not a new semantic document or PDF authority.
223
+
224
+ ## Proof and visual-regression governance
225
+
226
+ Browser proof envelopes now use `atelier.presentation-browser-proof/v3`.
227
+ The envelope records `sourceDirty`; comparison requires it to be explicitly false.
228
+ Dirty-tree runs can provide development evidence but cannot compare as unchanged.
229
+ The runner eagerly decodes fixture images and waits for fonts before measuring,
230
+ then verifies stable document dimensions across capture against the PNG header.
231
+ Each frame records pixel dimensions and document scroll dimensions separately
232
+ from viewport conditions. Old v1/v2 receipts remain historical evidence, but compare
233
+ as incomparable: recapture under v3 rather than automatically accepting them.
234
+ Dimension assertions and hashes do not establish image custody or owner approval.
235
+
236
+ Run from a source checkout using Node 22.18.0:
237
+
238
+ ```sh
239
+ node scripts/generate-presentation-schema.mjs --check
240
+ node --test test/ui-presentation.test.mjs test/contract-hygiene.test.mjs
241
+ node scripts/prove-presentation-browser.mjs
242
+ npm run contract:compat
243
+ npm run public-api:compat
244
+ npm run syntax:check
245
+ npm test
246
+ ```
247
+
248
+ The browser runner is also exposed as `npm run presentation:proof`. `npm ci`
249
+ installs lockfile-pinned Playwright, React, React DOM and esbuild as development
250
+ dependencies; no framework is added to the distributed runtime dependency set.
251
+ Provision matching browser binaries separately with `npx playwright install
252
+ chromium firefox webkit` (CI Linux images may also need `--with-deps`). The proof
253
+ command itself performs no browser download or server startup. An optional
254
+ `ATELIER_PLAYWRIGHT_MODULE` selects an explicitly provisioned runtime. All requests
255
+ are intercepted to invented fixtures, with other
256
+ origins refused. Default engines: Chromium, Firefox, WebKit. Optional
257
+ `ATELIER_PROOF_BROWSERS` narrows coverage and must remain visible in the receipt.
258
+
259
+ Outputs live in ignored `.artifacts/presentation-browser` (override with
260
+ `ATELIER_PROOF_OUTPUT`). A receipt records exact source-module and fixture hashes,
261
+ Git HEAD, browser versions, named assertions and screenshot hashes. Each frame
262
+ records viewport, theme, density, motion, locale, scale and font conditions. A
263
+ separate runner digest binds the assertions, mounted React fixture and lockfile.
264
+ Missing/null/unknown proof fields refuse comparison rather than yielding a green
265
+ result. During development HEAD
266
+ alone does not identify the working source; freeze a commit and rerun before
267
+ using it for acceptance. Successful rendering explicitly does not accept a
268
+ visual baseline, native device, or downstream adopter.
269
+
270
+ This local gate now exercises controlled host refresh, pending focus, full
271
+ Unicode input/refusal, composition boundaries, embedded container geometry,
272
+ invalid-state styles, read-only print visibility and real React callback lifetime.
273
+ Text-size proof measures all rendered text categories at twice the reference
274
+ root font size; it remains synthetic CSS scaling, not platform zoom or WCAG
275
+ certification. Remote CI wiring and accepted screenshot baselines remain explicit
276
+ integration gates, not claims made by a successful local run.
277
+
278
+ Baseline governance is deliberate: never auto-update expected images after a
279
+ failure. Store a baseline's exact source/fixture/environment identity and its
280
+ reviewing owner's disposition outside generated output. Compare at equal engine
281
+ version, viewport, scale, locale, theme, density, motion and font environment.
282
+ Changed pixels require explanation and a retained before/after pair. Keep
283
+ geometry, accessible names, focus, behavior and content assertions alongside
284
+ images; screenshot equality alone is insufficient. A host with no accepted
285
+ baseline remains unaccepted, not silently green. Actual device and assistive
286
+ technology runs are separate required evidence for those adoption claims.
287
+
288
+ `comparePresentationProofs(baseline, candidate)` returns `incomparable` for missing
289
+ or changed coverage, `review-required` for changed screenshot digests, or
290
+ `unchanged`. It always reports `baselineApprovalVerified: false` and
291
+ `executionAuthority: false`. The calling proof owner must verify the referenced
292
+ image bytes and baseline provenance; matching self-reported digests are not
293
+ proof of image custody or an accepted design.
294
+
295
+ Reference chrome is currently English. `lang` and `direction` preserve host
296
+ content language and logical layout, not complete translated control copy.
297
+ Localization, rich editor composition, large-graph exploration, native hover and
298
+ keyboard-focus treatment, and a mounted framework-specific adapter remain
299
+ explicit extensions requiring focused proof before those capabilities are claimed.
300
+
301
+ ## Versioning, migration and adoption
302
+
303
+ The implementation uses presentation v1.0.0 but does not publish a new package
304
+ version. Existing published subpaths retain the repository's compatibility gate;
305
+ new presentation contracts have no historical baseline yet. Changes to token
306
+ meaning, state behavior, focus, required labels, request payloads or host defaults
307
+ must be treated as compatibility changes even when TypeScript would accept them.
308
+
309
+ An adoption handoff must pin package/source/tree, model and token version,
310
+ consumer source/tree, exact write set, host/framework versions, supported family
311
+ set, shortcut/focus owner, business request resolver, proof matrix and rollback.
312
+ Adapter conversion is explicit: validate both input and output, retain the old
313
+ source and rendered evidence, and migrate one synthetic consumer before any
314
+ real content. There is no automatic data migration, global token switch, route
315
+ replacement or private adapter import in this module.
316
+
317
+ Completion ladder:
318
+
319
+ 1. Root source, schema parity, neutral reference rendering and defensive tests.
320
+ 2. Exact committed source, full existing suite, private disclosure scan and
321
+ tarball inspection; maintainer integration review and actual CI separately.
322
+ 3. A bounded consumer adapter with explicit business/keyboard/focus handoffs.
323
+ 4. Mounted host/browser/device/document proofs and accepted visual baselines.
324
+ 5. Separately authorized package publication, route adoption and activation.
325
+
326
+ Only the root implementation is allocated here. Other owners' source stays
327
+ read-only. A local proof, commit, package audit or issue does not advance the
328
+ later milestones by implication.
@@ -0,0 +1,75 @@
1
+ # Presentation and public-page consumers
2
+
3
+ Status: compatibility reference, not consumer migration or acceptance.
4
+
5
+ The portable presentation API serves both workspaces and simpler consumers.
6
+ Public pages may consume resolved tokens without rendering a workspace or
7
+ shipping a framework hydration runtime. The Astro example demonstrates that
8
+ build-time boundary with invented content and native HTML controls.
9
+
10
+ | Concern | Owning layer | Integration rule |
11
+ | --- | --- | --- |
12
+ | Neutral color, type, spacing and accessibility floors | Atelier token API | Map roles explicitly; retain consumer aliases until migration is proved |
13
+ | Workspace requests, pending and presentation confirmation | Atelier presentation API | Requests carry no operation authority; host decides outcomes |
14
+ | Public-page navigation, scroll and overlay lifecycle | Existing consumer framework | Never attach a second global focus/keyboard/scroll controller |
15
+ | Reading geometry, editorial sections and brand fonts | Consumer | No tenant palette, content, private methodology or layout is promoted by copying |
16
+ | Production forms, identity, persistence and publication | Host/business authority | A reference form is not a transport or successful submission |
17
+ | Responsive and visual proof | Shared proof mechanism plus consumer fixtures | Accepted baselines and real-host accessibility remain separate |
18
+
19
+ ## Compatibility constraints
20
+
21
+ Current root colors accept validated six-digit hexadecimal values. A consumer
22
+ using another color representation needs an explicitly verified mapping; its
23
+ stylesheets cannot be passed through as token overrides. Typography family is
24
+ currently limited to generic serif, sans-serif and monospace. Custom brand-font
25
+ delivery is not silently supported by that restriction. Do not widen the API
26
+ or lower a floor to make an adapter appear compatible.
27
+
28
+ The example uses native document scrolling and a non-overlay disclosure menu.
29
+ This is a fixture choice, not a ruling that overrides a consumer framework's
30
+ bounded scroll owner or overlay lifecycle. It has no reveal effects or custom
31
+ font loads; no-JavaScript readability and absence of motion are the baseline.
32
+
33
+ ## Migration gates
34
+
35
+ 1. Pin the clean supplier and consumer commits plus their adopted-practice
36
+ manifests; a package version alone is insufficient.
37
+ 2. Record shared roles, intentional exceptions, and which controller owns each
38
+ interaction. Preserve existing behavior and compatibility aliases.
39
+ 3. Test a representative consumer under its existing framework. Verify actual
40
+ rendered contrast, keyboard, form failure, reflow, reduced motion and page
41
+ weight, not just token arithmetic.
42
+ 4. Review before/after frames and accept the exact baseline explicitly. Retain
43
+ rollback to the previous dependency and adapter as one reversible unit.
44
+ 5. Obtain the separate source, CI, maintainer and deployment authorities. The
45
+ reference consumer neither allocates a product path nor activates a site.
46
+
47
+ ## CI integration handoff
48
+
49
+ The existing workflow does not yet execute either browser proof. A maintainer
50
+ must allocate a bounded browser-proof job using the repository's approved
51
+ runner and required-check policy; this document does not create or dispatch it.
52
+ Use one job, read-only repository permissions, a finite timeout, no application
53
+ credentials and no deployment steps. Retain receipts and screenshots even on
54
+ failure. A successful CI exit does not establish visual-baseline acceptance.
55
+
56
+ The execution sequence, from the checked-out candidate root, is:
57
+
58
+ ```sh
59
+ # Node 22.18.0: existing root proof runtime.
60
+ npm ci --ignore-scripts
61
+ npx --no-install playwright install --with-deps chromium firefox webkit
62
+ node scripts/prove-presentation-browser.mjs
63
+ # Node 22.22.2: isolated Astro build; keep the root runtime contract unchanged.
64
+ npm ci --ignore-scripts --prefix examples/astro-presentation
65
+ ASTRO_TELEMETRY_DISABLED=1 npm run build --prefix examples/astro-presentation
66
+ # Return to Node 22.18.0 for the same proof runtime used locally.
67
+ node scripts/prove-astro-presentation.mjs
68
+ ```
69
+
70
+ Archive `.artifacts/presentation-browser/` and `.artifacts/astro-presentation/`.
71
+ Browser binary versions are determined by the root lockfile. Linux and macOS
72
+ frames are separate environments, not interchangeable visual baselines. On
73
+ macOS WebKit the synthetic keyboard script uses Option-Tab for link navigation
74
+ when system full keyboard access is disabled. This is a host exception, not a
75
+ new global keyboard handler.
@@ -0,0 +1,47 @@
1
+ # Presentation correction disposition — 2026-09-15
2
+
3
+ Status: bounded root correction, not maintainer acceptance, release or adoption.
4
+ Reviewed source: `9ea81f087131e909e22fbcff50df1b57050c76af`.
5
+
6
+ The returned manual defensive review conditionally accepted that source for root
7
+ integration and found no new critical/high issue. It ran no tests or live sites;
8
+ its visual inspection was partial. The source owner independently verified and
9
+ corrected the following findings. Those corrections are a successor, not covered
10
+ by an inherited approval of the prior commit.
11
+
12
+ | Finding | Source disposition | Regression evidence |
13
+ | --- | --- | --- |
14
+ | S1/S2: native failure contamination and web/native concurrent-delivery drift | Fixed using shared delivery-message logic; current settlement and remaining pending deliveries are distinct from business state | A regression first reproduced failure A contaminating successful B; focused unit tests and both actual web binder and React-backed native fixture exercise settlement |
15
+ | S3: schema-dependent attribute safety | Escaped string attributes and generated DOM identifiers in addition to retaining strict validation | Existing text/attribute refusal/escaping tests and browser proof |
16
+ | S4: HEAD without dirty-source marker | Proof v3 requires explicit sourceDirty:false for comparison; missing/dirty/old envelopes remain incomparable | Negative comparison cases; dirty development proofs cannot become unchanged baselines |
17
+ | S6: implicit form submit without scripts | Static example uses a labelled group and explicit local input validation, not a submitting form | All three engines exercise Enter with scripts both off and on; navigation, retained value and absent form checked |
18
+ | N9: repeated pending resize silently dropped | Suppression now gives explicit no-additional-request feedback; host still owns geometry | Shared message test; no optimistic resize or queue added |
19
+ | N5: host refresh during IME throws | Queue latest validated model, expose composition state, flush after final edit; newer synchronous host updates win | Browser cases for unchanged composing DOM, latest/invalid model ordering, no stale widget dispatch, removal/disable/reset/disposal |
20
+ | N6: email/number caret continuity | Confirmed email regression; retain compatible focused DOM input without calling unsupported selection APIs | Actual key events insert consecutive characters mid-value during controlled refresh in all three engines |
21
+ | N7/N8: neutral-looking warnings and inconsistent chrome | Shared tone labels, dashed warning edge, focus-revealed skip link, aligned header and distinct link/action styling | Web/document/native label assertions; focus/geometry/style/print checks; new before/after frames retained without accepting a baseline |
22
+ | N10: printed skip chrome | Skip link excluded in print | Print visibility assertion |
23
+
24
+ ## Conditions retained before controlled-host adoption
25
+
26
+ - Synthetic composition events prove the binder lifecycle, not a real OS IME or
27
+ assistive-technology session. Receiving hosts still need their actual input,
28
+ device and screen-reader proof, including real navigation/draft lifecycle.
29
+ - Visual changes have new before/after frames, not a newly accepted baseline.
30
+ - N10 performance: retain the bounded per-render signature used to invalidate
31
+ stale native confirmations. Object-identity memoization would miss in-place
32
+ host mutation. Actual native profiling is still needed before replacing this
33
+ correctness guard; local browser/React fixture proof is not native performance
34
+ acceptance.
35
+ - S5: screen-reader busy announcements remain an assistive-technology hypothesis.
36
+ Do not remove pending semantics on the strength of an unrun AT scenario.
37
+ - S7: actual browser-proof CI integration remains unimplemented; use the bounded
38
+ receiving-owner recipe in [consumer boundaries](presentation-consumer-boundaries.md).
39
+
40
+ No source in existing server, harness, vault, coauthor, runtime, private auth,
41
+ business, keyboard, Desktop or downstream site implementations changes here.
42
+ Connected component placement and portable auth remain a separate unimplemented
43
+ proposal. Shape checks of that proposal do not establish enforcement or admission.
44
+
45
+ The remaining integration gates are exact host proof, maintainer integration,
46
+ visual-baseline disposition and actual CI. Local testing and a
47
+ source commit do not publish a package, accept a visual baseline or deploy a site.
@@ -0,0 +1,38 @@
1
+ # Project option and command inventory
2
+
3
+ `--project PATH` and `--project-config PATH` select the first explicit config.
4
+ Repeated `--repo-path NAME=PATH` uses the last value for each name; paths resolve
5
+ from the invocation's current directory. Both separated and equals forms work.
6
+ Resolution precedence is CLI override, ignored local overlay, tracked relative
7
+ location, then declared sibling discovery. Overrides do not declare repositories
8
+ or widen read boundaries. Missing required sources still fail.
9
+
10
+ `atelier config check --explain` reports logical names, resolution sources,
11
+ resolved state and read boundary without machine paths. Normal config diagnostics
12
+ remain local. `MNSTRY_ATELIER_PROJECT_CONFIG` and local overlays retain their established
13
+ resolver behavior. Shared options are parsed by the resolver, including direct
14
+ module calls and branded `runCli` wrappers; wrapper authors must forward argv.
15
+
16
+ | Family (aliases share implementation) | Location and side effects |
17
+ | --- | --- |
18
+ | graph; project/build; readiness/generated; context/resolve/capabilities/proposal | Shared project resolver. Graph/projection/readiness and proposal operations can create local outputs/history. |
19
+ | dev/server | Shared project resolver; foreground loopback service. `--review` opts into local review ledgers. |
20
+ | config/manifest; extension-pack/list/validate | Shared resolver; project resolution may ensure ignored local state. Pack loading is declarative, with no extension execution. |
21
+ | support/bundle; analysis/analyze | Project-aware implementation; local previews/explicit output or disabled-by-default analysis contracts retain their existing controls. |
22
+ | boundary/check/doctor/push-check/audit/install-hooks; promote | Project-aware implementation; checks and explicit hook/promotion operations retain their own mutation guards. |
23
+ | lock/check/write; upgrade | Shared project resolver, except standalone `lock provenance`. Lock write and upgrade apply retain their explicit operation semantics. |
24
+ | review run/history/handoff/packs/export | Shared resolver; bound runs and contributions use ignored state. Export previews unless explicitly written. |
25
+ | review inspect | Standalone inert file inspection; does not resolve a project or create active review state. |
26
+ | coauthor | Current Git workspace only; JSON stdin. Explicit start/event/recover writes ignored private drafts and ledger events. Never relocates or edits canonical sources. |
27
+ | init; setup/adopt/doctor | Scaffold/adoption-specific target handling; no new universal target semantics. |
28
+ | sync | Repository-operation interface owns `--repo`; enrollment accepts its existing project-config option. It is not an adapter source relocation command. |
29
+ | distribution; disclosure; attestation; feedback; announcements; egress; contract; export/dry-run | Artifact/package/repository-specific entry points retain their own targets and option validation. |
30
+
31
+ Command-specific parsers retain ownership of their options. The shared project
32
+ parser never globally allows arbitrary flags. The strict extension-pack and new
33
+ review interfaces reject unknown options before operation. Legacy permissive
34
+ entry points retain compatibility rather than gaining an unrelated syntax change.
35
+ Regression coverage exercises moved sources through the published CLI, legacy
36
+ alias, branded wrapper and direct pack module, plus project command families.
37
+ The installed consumer gate repeats the external adapter journey across two
38
+ source locations and checks that missing or stale inputs cannot gain authority.
@@ -0,0 +1,53 @@
1
+ # Project location and repository overrides
2
+
3
+ Project-aware commands share these options through the project resolver:
4
+
5
+ ```sh
6
+ atelier extension-pack validate --project adapter/atelier.project.json --repo-path content=../source
7
+ atelier graph --project-config=adapter/atelier.project.json --repo-path=content=../source
8
+ atelier config check --project adapter/atelier.project.json --explain
9
+ ```
10
+
11
+ Both `--flag=value` and `--flag value` work. Repeat `--repo-path NAME=PATH`
12
+ for multiple logical repositories. Names must already be declared in the
13
+ project; an undeclared name adds no repository or read authority. The last
14
+ override for a name wins. The first `--project` or `--project-config` selection
15
+ wins, preserving existing alias behavior. Missing or malformed values now fail
16
+ with `project-option-invalid` instead of silently falling back to another path.
17
+ Paths may contain spaces or equals signs; quote them as your shell requires.
18
+
19
+ Resolution precedence is CLI override, ignored local overlay, tracked relative
20
+ path, then sibling discovery. CLI paths resolve from the working directory;
21
+ tracked and overlay paths resolve from the project config directory. Sibling
22
+ discovery checks the declared remote when one is supplied. An override does not
23
+ change the repo's declared identity or read boundary; downstream graph and
24
+ boundary checks still apply. `kind: external` means unmanaged with no read
25
+ boundary, not an adapter for reading arbitrary external content.
26
+
27
+ `config check --explain` shows logical names, resolution sources and declared
28
+ read boundaries without machine paths or remote URLs. `resolved` means a path
29
+ was selected, not that the repo exists or passed identity and content checks.
30
+ Resolution may create ignored `.atelier-local/` directories; this diagnostic is
31
+ not a promise of a write-free invocation. The ordinary config report retains
32
+ its existing shape and local config path.
33
+
34
+ ## Command inventory
35
+
36
+ | Family | Project handling | Other effects |
37
+ | --- | --- | --- |
38
+ | config, graph, project/build | Shared resolver | Validation or generated artifacts |
39
+ | readiness, generated aliases | Shared resolver; protocol listing can be standalone | Runs, packets, generated artifacts |
40
+ | extension-pack list/validate | Shared resolver and strict command options | Loads declared packs locally |
41
+ | setup, doctor | Shared resolver | Ignored state repair when requested |
42
+ | boundary, promote | Shared resolver | Boundary checks, explicit hooks or ledger operations |
43
+ | upgrade, lock | Shared resolver | Explicit lock/upgrade operations |
44
+ | dev/server, support | Forward project arguments to the shared resolver | Local listener or local support preview |
45
+ | context/resolve/capabilities/proposal | Shared resolver | Local context envelope or capabilities report |
46
+ | init/adopt | Target/template inputs; generated config then resolved | Creates starter/config files |
47
+ | contract, export/dry-run, analysis, egress, distribution, disclosure, attestation, feedback, announcements, sync | File/repo-specific inputs | Follow their own command contracts |
48
+
49
+ The shared options do not turn standalone commands into project consumers.
50
+ Command-specific parsers retain their existing behavior; in particular the
51
+ extension-pack allowlist still refuses unknown options. Public and legacy CLI
52
+ names, `runCli` distribution wrappers, and direct project-aware modules all
53
+ reach the same resolver.