@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
@@ -10,23 +10,114 @@ a location, never the matched content.
10
10
  ### release:audit
11
11
 
12
12
  `npm run release:audit` (`scripts/check-release-tarball.mjs`) audits the exact
13
- tarball `npm pack` would publish:
13
+ tarball `npm pack` would publish. `npm run release:candidate` packs once and
14
+ passes the same archive and expected SHA-256 through this audit and both
15
+ consumer smokes:
14
16
 
15
17
  - Package metadata: name, license, exposed CLI bins, and a mandatory `files`
16
18
  allowlist in `package.json`.
17
19
  - Tarball allowlist: every packed path must match a known-good pattern; any
18
- unexpected file fails the audit.
20
+ unexpected file fails the audit. The extracted archive inventory must match
21
+ the `npm pack --json` inventory exactly.
19
22
  - Content scan: every packed file is scanned against committed structural
20
23
  patterns (absolute user paths, machine-local temp paths, agent-local state
21
24
  paths, key material, secret-like assignments) and against the maintainer-held
22
25
  denylist described below.
26
+ - Egress scan: the canonical egress control receives the exact `npm pack`
27
+ inventory and inspects every packed executable or markup file, including a
28
+ test-shaped path if one is ever admitted to the artifact. Packed test-fixture
29
+ suppression markers are refused; reviewed local-computed markers are counted.
23
30
  - Version drift: `CHANGELOG.md` must contain a `## <version>` heading and
24
31
  `README.md` must mention the version. The expected version and tarball name
25
32
  are derived from `package.json`, never hardcoded.
33
+ - Declared exports: every `exports` target in the packed `package.json` must
34
+ be a file the tarball carries.
35
+ - Obsidian package contents: see [Obsidian package contents](#obsidian-package-contents).
26
36
 
27
37
  Exit codes: `0` clean, `1` findings, `2` configuration error (for example an
28
38
  unavailable denylist without explicit acknowledgment).
29
39
 
40
+ `release:candidate` additionally requires a clean tree, records the candidate
41
+ commit and tarball digest, and refuses a version already bound to a different
42
+ tagged commit. It is a release-evidence command, not a publication command.
43
+ When `ATELIER_RELEASE_OUTPUT_DIR` is set, it atomically retains the verified
44
+ tarball, npm-pack metadata, and a machine-readable receipt. The trusted
45
+ publishing workflow runs `prepublishOnly` explicitly with that output directory,
46
+ re-verifies the retained digest, and publishes the retained tarball path rather
47
+ than repacking the source checkout.
48
+
49
+ ### Obsidian package contents
50
+
51
+ The Obsidian projection ships as runtime, contracts and documents, and its
52
+ proof tooling does not ship. `release:audit` enforces both halves on the exact
53
+ tarball.
54
+
55
+ Shipped, and required by the audit:
56
+
57
+ - The entry points behind the package subpaths `./obsidian` (maintenance
58
+ runtime, `src/runtime/obsidian/index.mjs`), `./obsidian/contracts`,
59
+ `./obsidian/materialize`, `./obsidian/publication`, `./obsidian/recovery`,
60
+ `./obsidian/edits`, `./obsidian/proposals` and `./obsidian/selection`, with
61
+ `src/commands/obsidian.mjs`, the service entry and the two contribution
62
+ modules under `src/runtime/obsidian/contributions/`.
63
+ - Every `contracts/atelier-obsidian-<name>.v<n>.schema.json` present in the
64
+ source tree (lowercase name, versioned). Each must be packed and exported
65
+ under its own path, and the audit fails if it finds none.
66
+ - `docs/obsidian.md` and `docs/obsidian-contract.md`.
67
+ - `fixtures/obsidian/**`: small synthetic text only. Every packed fixture, in
68
+ any subtree and spelling under `fixtures/`, is at most 262,144 bytes. The
69
+ acceptance receipts under `fixtures/obsidian/acceptance/receipts/` are
70
+ synthetic shape fixtures whose host id matches `host-synthetic-*` and whose
71
+ operator id is `operator-synthetic`; the schema fixtures under
72
+ `fixtures/obsidian/contracts/` carry no identity block. Validating one closes
73
+ nothing.
74
+
75
+ Never shipped, and refused by name in addition to the path allowlist:
76
+
77
+ - `scripts/**` (including the `scripts/obsidian/` desktop harness, scale
78
+ generator and receipt verifier), `test/**`, `experiments/**`, `examples/**`.
79
+ - Any `.artifacts/` directory, where acceptance receipts and their evidence
80
+ are written.
81
+ - Any `.asar` file.
82
+ - An acceptance receipt outside `fixtures/obsidian/`, one carrying the desktop
83
+ harness extension (`mnstry.atelier.obsidian.desktop-receipts`), or one whose
84
+ host or operator id is not the synthetic form above (or, outside the schema
85
+ fixtures, one with no identity block): that document records a real host,
86
+ even with the harness block removed.
87
+ - Scale corpora and binary samples. They are generated in temporary storage at
88
+ test time and are never files of this repository.
89
+
90
+ The path allowlist was not widened for the Obsidian projection. Every check
91
+ above refuses more than the allowlist alone did.
92
+
93
+ `test/obsidian-package.test.mjs` is the AP-06 package proof and runs with the
94
+ ordinary test suite. It packs the package, extracts it into a bare consumer
95
+ project, links the locked runtime dependencies from the checkout, and from a
96
+ separate process imports every Obsidian subpath by package name, checks that
97
+ an undeclared internal path stays closed, and runs the production pipeline
98
+ (canonical graph, source snapshot, `prepareView`, `publishView`) over a
99
+ synthetic workspace into a temporary vault that no application has open. A
100
+ document the census did not classify must not reach the vault. It also packs
101
+ a synthetic package containing each refused class and matches each audit
102
+ refusal by message. It does not run `npm install`; `consumer:smoke` does, on
103
+ the same tarball contents, and imports every declared export including these.
104
+
105
+ Limits of this proof:
106
+
107
+ - It is package proof only. Gate G18 also requires a separately recorded
108
+ adopter acceptance, and nothing in this repository produces or implies one.
109
+ - It never starts the app. Behaviour inside a running app is acceptance
110
+ evidence from `scripts/obsidian/desktop-receipts.mjs` on a desktop host and
111
+ is not covered by any CI lane. No CI lane has a desktop session.
112
+ - Publication is skipped where no atomic exchange exists. On Windows the
113
+ publisher refuses with `exchange-unsupported-platform`, so the Windows
114
+ portability lane runs the pack, import and `prepareView` cases and skips the
115
+ publish case.
116
+ - The `*ForOracleTests` names exported by the Obsidian modules are mutation
117
+ controls for the test suite. They ship because the modules that define them
118
+ ship; they are not a supported API and carry no compatibility promise. They
119
+ should be excluded when the public API baseline is next regenerated.
120
+
30
121
  ### repo:check
31
122
 
32
123
  `npm run repo:check` (`scripts/check-repo-disclosure.mjs`) sweeps the whole
@@ -43,6 +134,27 @@ Git-tracked tree, not just the tarball:
43
134
  Exit codes match `release:audit`: `0` clean, `1` findings, `2` configuration or
44
135
  usage error.
45
136
 
137
+ ### disclosure check
138
+
139
+ `atelier disclosure check` is the portable consumer-facing content gate. It
140
+ scans every tracked text file by default or the exact staged index with
141
+ `--staged`, never follows tracked symlinks, and reports labels plus locations
142
+ without echoing matched content. `--untrusted` suppresses finding details.
143
+
144
+ The command loads private patterns from `ATELIER_DENYLIST_JSON`, an explicit
145
+ `--denylist` path, or ignored
146
+ `.atelier-local/disclosure-denylist.json`. A repository-local denylist is
147
+ refused if it is tracked or not covered by `.gitignore`. Missing private
148
+ patterns are a configuration failure unless `--structural-only` explicitly
149
+ acknowledges the reduced verdict. Public text-only packaging can also use
150
+ `--fail-on-binary`; Atelier's own tarball audit separately refuses packed
151
+ binary files.
152
+
153
+ The public Atelier repository keeps the stronger `repo:check` identity and
154
+ commit-message controls. The portable command exists so consumer repositories
155
+ can enforce the same public/private content boundary without inheriting
156
+ MNSTRY-specific commit identities.
157
+
46
158
  ### Commit-identity gate
47
159
 
48
160
  Part of `repo:check --commits`. Commit authors must match a hardcoded
@@ -65,18 +177,58 @@ changelog and the migration registry honest about breaking changes:
65
177
  - Every registered migration record is re-validated against the migration
66
178
  record contract.
67
179
 
180
+ ### public-api:compat
181
+
182
+ `npm run public-api:compat` compares every package subpath and named JavaScript
183
+ export published by `v0.2.0-alpha.4` with the current package. Removing one
184
+ fails closed. It also rejects modified source that retains the already-tagged
185
+ baseline version, independently of the release-candidate check. The baseline
186
+ records and verifies its tag commit and the public npm artifact identity; the
187
+ published archive was independently checked to contain all 20 subpaths and 212
188
+ named exports. This is runtime JavaScript shape continuity, not a promise about
189
+ function signatures, types, or behavior.
190
+
68
191
  ### egress:check
69
192
 
70
193
  `npm run egress:check` (`atelier egress check`) scans package runtime paths for
71
- forbidden non-localhost egress. The package claims no network egress in runtime
72
- paths; this gate is the mechanical check behind that claim.
194
+ forbidden non-localhost HTTP egress primitives. The package claims no silent or
195
+ undocumented runtime egress; this gate is one mechanical check behind that
196
+ claim. It does not interpret data-only Markdown/JSON and does not model
197
+ `child_process`, so the reviewed `gh` identity-resolution subprocesses and the
198
+ explicitly enrolled Atelier Sync Git fetch/non-force-push subprocesses are
199
+ documented exceptions backed by dedicated refusal tests. Sync refuses fetch on
200
+ an incomplete observation, refuses publish while prior local commits are
201
+ unpublished, strips repository/config retargeting environment variables, and
202
+ pushes the exact post-hook-verified commit object without following tags or
203
+ recursively publishing submodule refs. Its boundary check also suppresses the
204
+ optional network actor fallback.
205
+
206
+ The optional `vault` API is explicitly host-bound: provider storage, metadata
207
+ and identity bindings can perform network I/O when invoked by a consuming host.
208
+ The core does not install SDKs or start a listener. The lexical egress scanner
209
+ does not model SDK method calls; vault behavior requires its own conformance
210
+ suite and independent review. No egress suppression marker is added for it.
73
211
 
74
212
  ### consumer:smoke
75
213
 
76
214
  `npm run consumer:smoke` (`scripts/consumer-smoke.mjs`) packs the real tarball,
77
215
  installs it offline into a throwaway consumer project with lifecycle scripts
78
- disabled, and imports the public API to validate a sample export. It proves the
79
- tarball is installable and functional exactly as a consumer receives it.
216
+ disabled and without copying the publisher's `overrides`, checks the installed
217
+ dependency tree, imports every declared JavaScript export, parses every
218
+ declared JSON export, and validates a sample export through both API and CLI.
219
+ It proves the tarball is installable and functional exactly as a bare consumer
220
+ receives it from disk. The offline smoke deliberately warms the locked registry
221
+ dependency closure first; it does not prove that a not-yet-published version
222
+ resolves from a cold or live registry.
223
+
224
+ ### assurance:mutation-smoke
225
+
226
+ `npm run assurance:mutation-smoke` runs local, synthetic negative controls for
227
+ the boundary, graph, packed and direct egress, sidecar, and distribution
228
+ families. Every fixture introduces one named failure and must be refused by the
229
+ terminal CLI or release command where one exists. This is part of
230
+ `prepublishOnly`; a control that stops detecting its failure mode blocks the
231
+ release even if positive-path tests remain green.
80
232
 
81
233
  ### Egress-marker inventory
82
234
 
@@ -105,7 +257,7 @@ maintainer-reviewed before entering the list.
105
257
  Four jobs run on pushes to `main` and on pull requests, and all four are
106
258
  required status checks:
107
259
 
108
- - `test`: syntax check (`node --check`, not a type system), the full test suite, contract checks, `egress:check`, and
260
+ - `test`: syntax check (`node --check`, not a type system), the full test suite (including isolated consumer disclosure-command proofs), contract checks, `egress:check`, `assurance:mutation-smoke`, and
109
261
  `migrations:check`. This job sets `ATELIER_ALLOW_MISSING_DENYLIST=1` scoped
110
262
  to the job only — denylist assertions belong to the secret lane.
111
263
  - `consumer-smoke`: warms the npm cache with `npm ci` (the offline tarball
@@ -127,11 +279,14 @@ the only safe block.
127
279
 
128
280
  To clear a fork pull request, a maintainer verifies the head SHA and dispatches
129
281
  the `fork-sweep` workflow with the pull-request number and that SHA. The
130
- workflow runs the trusted scanner from `main` against the fork's tree checked
131
- out as data — it never installs or executes anything from the untrusted tree —
132
- re-verifies that the head SHA has not moved, and posts a `secret-sweep` check
133
- run on the SHA. The newest check run with that name supersedes the earlier
134
- failure for branch protection.
282
+ workflow pins the trusted scanner checkout to the protected default branch and
283
+ runs it against the fork checked out as data — it never installs or executes
284
+ anything from the untrusted tree. It requires an open PR whose base repository
285
+ and branch are the protected default, pins the base and head SHAs from GitHub,
286
+ scans the complete bounded base-to-head object range while waiving only
287
+ repository-specific commit identity, re-verifies that the head SHA has not
288
+ moved, and posts a `secret-sweep` check run on the SHA. The newest check run
289
+ with that name supersedes the earlier failure for branch protection.
135
290
 
136
291
  `release:audit` never runs against untrusted code (`npm pack` executes
137
292
  lifecycle scripts); it re-runs on the push build of the merge commit. No
@@ -145,6 +300,13 @@ A version bump touches exactly:
145
300
  - `CHANGELOG.md` (a `## <version>` heading)
146
301
  - the pinned install tags in `README.md`, `docs/install.md`,
147
302
  and `docs/upgrade.md`
303
+ - `compatibleRootVersions` in
304
+ `templates/external-project-workspace/pack-lifecycle.json`, so the shipped
305
+ starter's pack is qualified for the released root version (the
306
+ `review packs` consumer smoke and `test/review-portability.test.mjs` fail
307
+ when it lags)
308
+ - the linked package version recorded in
309
+ `examples/astro-presentation/package-lock.json`
148
310
 
149
311
  The release scripts derive the expected version and tarball name from
150
312
  `package.json`, so they are not part of the bump surface, and `release:audit`
@@ -170,12 +170,22 @@ machine for weeks.
170
170
  - `pre-push` runs `atelier boundary push-check` — git writes the ref updates to
171
171
  the hook's stdin, and only that range is judged. A brand-new branch is diffed
172
172
  against the empty tree, so nothing slips through unscanned.
173
- - `atelier boundary audit` scans the whole tree and **reports without blocking**,
174
- listing both matches and declared exceptions with their reasons.
173
+ - `atelier boundary audit` scans the current working tree by default and
174
+ **reports without blocking**, listing matches, incomplete-read diagnostics,
175
+ and declared exceptions with their reasons. Use `--head` for a committed
176
+ snapshot. The output names its source so a dirty tree cannot be mistaken for
177
+ `HEAD` evidence.
175
178
 
176
179
  If the guard cannot work out which repo it is running in, it fails closed. A
177
180
  guard that silently judges nothing is worse than one that stops you.
178
181
 
182
+ Path scopes are segment-aware globs: `*` does not cross `/`, `**` does, and
183
+ patterns are matched against normalized repository-relative paths. Explicitly
184
+ declaring `contentRules: []` is invalid; omit the field to receive defaults.
185
+ Git diff output and binary reads have per-file and aggregate budgets. A failed,
186
+ truncated, oversized, or unparsable evidence read produces a blocking
187
+ completeness diagnostic rather than a partial clean verdict.
188
+
179
189
  ### Declaring an exception
180
190
 
181
191
  Exceptions live in the boundary policy, not in the guard script. A repo-specific
@@ -0,0 +1,55 @@
1
+ # Review state and portable inspection
2
+
3
+ | State | Ownership and portability |
4
+ | --- | --- |
5
+ | Contracts, adapter configuration and declared packs | Track in the adapter; domain facts stay in their source repository. |
6
+ | Real answers, evidence snapshots, responses and decisions | Ignored owner-local state; backup is an explicit owner action. |
7
+ | Projections and caches | Regenerable, subject to the same content disclosure boundary. |
8
+ | Session state, nonces and presence | Ephemeral; never exported with review records. |
9
+ | Secrets, credentials, grants and signing keys | Nontransferable through the inspection format. |
10
+
11
+ Moving a Git checkout does not transfer active review authority. This feature
12
+ exports selected historical evidence for inspection; it does not synchronize
13
+ state, upload files, install packs, execute migrations or import current approval.
14
+ There is no encrypted-export option. Encryption, recipient selection and key
15
+ custody require a separate design and qualification. Hashes are not encryption
16
+ and do not authenticate a sender.
17
+
18
+ Preview a selected run and optionally selected response/position request IDs:
19
+
20
+ ```sh
21
+ atelier review export --runs RUN_ID --responses RESPONSE_ID,POSITION_ID --denylist PRIVATE_POLICY.json
22
+ ```
23
+
24
+ The disclosure policy must contain the `patterns` array used by the existing
25
+ scanner; maintain it privately. The command fails closed if that policy is
26
+ unavailable or rejects selected content. Preview reports selected identities,
27
+ byte counts and digests. Inspect the selected local history and evidence before
28
+ writing the reviewed selection. Then repeat with `--write --out inspection.json`.
29
+ An existing output file is never overwritten. The current selection is validated
30
+ and disclosure-checked again at write time. Exports contain private excerpts and
31
+ asserted names, so an empty policy is appropriate only for an invented fixture.
32
+
33
+ `atelier review inspect inspection.json` validates the version, closed contracts,
34
+ member count/byte bounds, JCS SHA-256 digests, duplicate identities and historical
35
+ links before displaying inert JSON. It does not resolve a project or write active
36
+ state. Foreign decisions remain visibly unverified historical assertions. The
37
+ format carries no trusted signature: there is no applicable signer authorization
38
+ or attestation to verify. Valid hashes prove internal consistency only.
39
+
40
+ The `atelier-review.v1.schema.json` contract defines these separate artifacts.
41
+ Evidence and contributions use the existing JCS implementation; the bundle hash
42
+ covers every top-level member except `digest`. A member hash covers its complete
43
+ `value`; `bytes` is the UTF-8 byte count of `JSON.stringify(value)`. Record input
44
+ hashes cover complete submitted input. Maximum bundle size is 4 MiB, with at most
45
+ 20 runs and 2,000 selected document contributions. Current capture supports up to
46
+ 256 text source nodes and 1 MiB per source; unsupported inputs refuse capture.
47
+ No archive extraction or arbitrary path writing occurs. Symlink input/output
48
+ leaves, absolute machine-path values, credential-bearing URLs and nontransferable
49
+ field names are refused. Generic text still needs the owner's private disclosure
50
+ policy; structural checks do not determine disclosure permission.
51
+
52
+ To roll back, pin the earlier package and pack/configuration/lock together,
53
+ disable the optional review surface, and retain both ledgers. Legacy proposal
54
+ readers continue using their separate files. Never delete historical records or
55
+ reinterpret them under a replacement pack to make an upgrade appear complete.
@@ -0,0 +1,156 @@
1
+ # Skill stewardship
2
+
3
+ Atelier skill stewardship is a local, evidence-gated loop for keeping agent
4
+ skills useful without turning every repeated request into permanent
5
+ instructions. It separates four concerns that are easy to blur together:
6
+
7
+ ```text
8
+ bounded observation -> evidence candidate -> authored and tested change
9
+ |
10
+ package release -> content-bound sync plan -> repo-scoped managed projection
11
+ ```
12
+
13
+ Git remains the source of record for authored skills. Ignored local state holds
14
+ only enumerated observations, staging directories, and recoverable quarantine.
15
+ The steward has no telemetry, model provider, prompt capture, send path, browser
16
+ apply endpoint, or authority to mutate its source catalog.
17
+
18
+ ## The operating loop
19
+
20
+ ### 1. Observe outcomes, not conversations
21
+
22
+ An equipped agent can record one outcome after relevant work:
23
+
24
+ ```bash
25
+ atelier skills observe \
26
+ --workflow weekly.release \
27
+ --signal repeated-task \
28
+ --outcome success
29
+ ```
30
+
31
+ The observation accepts only a stable workflow key, one enumerated signal, an
32
+ optional skill name, and an enumerated outcome. It has no fields for prompts,
33
+ transcripts, summaries, source excerpts, names, or client material; callers
34
+ must not encode any of them into the workflow key. Records live under ignored
35
+ `.atelier-local/skill-steward/observations.ndjson`.
36
+
37
+ Signals are `repeated-task`, `missing-workflow`, `user-correction`,
38
+ `trigger-miss`, `trigger-collision`, `tool-failure`, `stale-guidance`,
39
+ `successful-run`, `unused-skill`, and `superseded-skill`. Outcomes are
40
+ `success`, `failure`, `corrected`, `missing`, and `unknown`.
41
+
42
+ ### 2. Promote only repeated evidence
43
+
44
+ ```bash
45
+ atelier skills candidates --json
46
+ ```
47
+
48
+ The candidate builder is deterministic. It proposes no source edit and uses
49
+ fixed minimums:
50
+
51
+ | Candidate | Evidence required |
52
+ | --- | --- |
53
+ | Create | Three combined `repeated-task` or `missing-workflow` signals with no named skill |
54
+ | Improve | Two `user-correction` signals, or three combined correction/failure/staleness signals, for a named skill |
55
+ | Reconcile | Two `trigger-collision` signals |
56
+ | Retire | Two `superseded-skill` signals or three `unused-skill` signals for a named skill |
57
+
58
+ An agent using the shipped `atelier-skill-steward` skill may turn an eligible
59
+ candidate into an authored change, test positive and negative triggers, and
60
+ run the catalog audit. Instruction-only changes that retain the same tools,
61
+ data boundary, and external authority may progress through that automated
62
+ lane. Any new network access, filesystem scope, external message, spending,
63
+ destructive action, credential handling, or audience change pauses for human
64
+ authorization.
65
+
66
+ ### 3. Audit the whole catalog
67
+
68
+ ```bash
69
+ atelier skills audit
70
+ atelier skills audit --root ./skills/codex --peer ./skills/claude --json
71
+ ```
72
+
73
+ The audit validates required YAML frontmatter, lowercase names, directory/name
74
+ agreement, UTF-8 `SKILL.md` text, bounded bundle size, real files and directories,
75
+ bundle-contained relative resources, unfinished placeholders, and byte-level
76
+ parity between agent surfaces. Errors fail the command. Warnings remain
77
+ visible and reviewable.
78
+
79
+ Catalog audits should run after authored changes and on a regular schedule.
80
+ A scheduled agent task can run the audit and candidate builder, exercise
81
+ eligible instruction-only changes, and leave a tested Git diff for ordinary
82
+ review. Scheduling invokes the same skill and does not widen its permissions or
83
+ lower its evidence thresholds.
84
+
85
+ A portable recurring-task prompt is:
86
+
87
+ > Use the `atelier-skill-steward` skill in this repository. Audit the complete
88
+ > skill catalog, inspect evidence-thresholded candidates, and integrate eligible
89
+ > authority-neutral instruction changes with behavioral and repository gates.
90
+ > Reconcile overlaps and retire only evidence-backed vestiges. Do not capture
91
+ > task content, add authority, overwrite drift, or bypass an exact sync plan.
92
+
93
+ ### 4. Update deployed skills from the released root package
94
+
95
+ A consuming repository can project the released package's `skills/codex`
96
+ catalog into repo-scoped `.agents/skills`:
97
+
98
+ ```bash
99
+ atelier skills sync --json
100
+ atelier skills sync --apply --confirm sha256:<the-reviewed-plan-digest>
101
+ ```
102
+
103
+ The first command is read-only. The second recomputes the current plan and
104
+ requires the exact digest that was reviewed. It refuses:
105
+
106
+ - a target outside the enrolled workspace;
107
+ - malformed or redirected bundles and lock files;
108
+ - a collision with an unmanaged local skill;
109
+ - local drift from the last managed digest; or
110
+ - any source catalog that fails audit.
111
+
112
+ Replaced and retired managed bundles move to
113
+ `.atelier-local/skill-steward/quarantine/`; they are never permanently deleted
114
+ by sync. The projection lock at
115
+ `.agents/skills/.atelier-skill-lock.json` binds each installed bundle to its
116
+ content digest and the source package version. This is the update bridge: after
117
+ a newer `@mnstry/atelier` is installed, the same plan/apply sequence brings its
118
+ shipped skills into the current repository without overwriting local ownership.
119
+
120
+ Installation is explicit per repository; installing the package alone does not
121
+ install a discoverable skill projection. Existing unmanaged bundles, including
122
+ byte-identical bundles, are never adopted implicitly. Missing managed bundles
123
+ count as local drift. Source and target may not overlap. A confirmation is
124
+ bound to the workspace and source location as well as their observed content.
125
+ Location hashes are local identifiers, not anonymization or authentication.
126
+ Interrupted operations leave a lock and recovery state for inspection; do not
127
+ automatically clear them or overwrite a locally edited projection.
128
+
129
+ ## Portable contracts
130
+
131
+ `contracts/atelier-skill-steward.v1.schema.json` defines four independently
132
+ addressable documents:
133
+
134
+ - `mnstry.atelier-skill-audit@v1` for catalog findings;
135
+ - `mnstry.atelier-skill-candidates@v1` for thresholded work;
136
+ - `mnstry.atelier-skill-sync-plan@v1` for review and exact confirmation; and
137
+ - `mnstry.atelier-skill-sync-lock@v1` for the managed projection inventory.
138
+
139
+ Fixtures cover valid and invalid examples, and the registry, compatibility,
140
+ disclosure, packaging, and release gates treat the contract and portable skill
141
+ bundles as public artifacts.
142
+
143
+ ## Automation policy
144
+
145
+ The safe autonomous lane is deliberately narrower than everything an agent
146
+ could theoretically do:
147
+
148
+ 1. record only enumerated, content-free outcomes during ordinary work;
149
+ 2. audit and aggregate on a schedule;
150
+ 3. author only evidence-backed, authority-neutral skill changes;
151
+ 4. validate behavior, catalog integrity, disclosure, and package gates;
152
+ 5. leave public source changes in Git for review; and
153
+ 6. update a deployed projection only from a reviewed, exact digest plan.
154
+
155
+ This makes “self-improving” mean accumulated evidence plus reversible changes,
156
+ not silent memory, prompt harvesting, or unbounded self-modification.