@mnstry/atelier 0.2.0-alpha.6 → 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.
- package/CHANGELOG.md +176 -0
- package/README.md +59 -15
- package/SECURITY.md +6 -1
- package/contracts/atelier-adoption-policy.v1.schema.json +49 -0
- package/contracts/atelier-coauthor.v1.schema.json +163 -0
- package/contracts/atelier-decision-request.v1.schema.json +476 -0
- package/contracts/atelier-decision-result.v1.schema.json +500 -0
- package/contracts/atelier-guide.v1.schema.json +227 -0
- package/contracts/atelier-intake.v1.schema.json +151 -0
- package/contracts/atelier-migration.v2.schema.json +61 -0
- package/contracts/atelier-obsidian-acceptance-receipt.v1.schema.json +211 -0
- package/contracts/atelier-obsidian-apply-policy.v1.schema.json +298 -0
- package/contracts/atelier-obsidian-corpus-profile.v1.schema.json +98 -0
- package/contracts/atelier-obsidian-edit-operation.v1.schema.json +138 -0
- package/contracts/atelier-obsidian-ext-settings.v1.schema.json +287 -0
- package/contracts/atelier-obsidian-generation-manifest.v1.schema.json +353 -0
- package/contracts/atelier-obsidian-proposal-receipt.v1.schema.json +110 -0
- package/contracts/atelier-obsidian-publication-journal.v1.schema.json +167 -0
- package/contracts/atelier-obsidian-scope.v1.schema.json +264 -0
- package/contracts/atelier-obsidian-service-state.v1.schema.json +149 -0
- package/contracts/atelier-obsidian-source-snapshot.v1.schema.json +179 -0
- package/contracts/atelier-pane-presentation.v1.schema.json +76 -0
- package/contracts/atelier-presentation.v1.schema.json +1293 -0
- package/contracts/atelier-review.v1.schema.json +1601 -0
- package/contracts/atelier-skill-steward.v1.schema.json +692 -0
- package/contracts/atelier-upgrade-plan.v2.schema.json +398 -0
- package/contracts/atelier-upgrade-receipt.v1.schema.json +99 -0
- package/contracts/atelier-vault-publication.v1.schema.json +58 -0
- package/docs/assurance-controls.md +9 -1
- package/docs/atelier-sync.md +5 -4
- package/docs/blocks/claims.md +15 -10
- package/docs/blocks/will-not-do.md +4 -1
- package/docs/coauthor-session.md +57 -0
- package/docs/connected-composition.md +75 -0
- package/docs/decisions.md +167 -0
- package/docs/exact-upgrades.md +159 -0
- package/docs/extension-pack-lifecycle.md +33 -0
- package/docs/guided-upgrades.md +99 -0
- package/docs/install.md +65 -9
- package/docs/intake-and-guides.md +65 -0
- package/docs/integration-and-review-plan.md +409 -0
- package/docs/integration-contract-decisions.md +22 -0
- package/docs/local-review.md +84 -0
- package/docs/local-services.md +227 -0
- package/docs/local-state.md +107 -0
- package/docs/obsidian-contract.md +687 -0
- package/docs/obsidian.md +387 -0
- package/docs/portable-presentation.md +328 -0
- package/docs/presentation-consumer-boundaries.md +75 -0
- package/docs/presentation-review-disposition.md +47 -0
- package/docs/project-command-inventory.md +38 -0
- package/docs/project-options.md +53 -0
- package/docs/release-engineering.md +88 -0
- package/docs/review-portability.md +55 -0
- package/docs/skill-steward.md +156 -0
- package/docs/upgrade.md +55 -2
- package/docs/vault-service.md +292 -0
- package/fixtures/atelier-coauthor/invalid/authority.v1.json +5 -0
- package/fixtures/atelier-coauthor/valid/config.v1.json +12 -0
- package/fixtures/atelier-guide/invalid/authority.v1.json +11 -0
- package/fixtures/atelier-guide/valid/capability.v1.json +10 -0
- package/fixtures/atelier-guide/valid/consent.v1.json +11 -0
- package/fixtures/atelier-guide/valid/engagement.v1.json +7 -0
- package/fixtures/atelier-guide/valid/offer.v1.json +10 -0
- package/fixtures/atelier-intake/invalid/authority.v1.json +9 -0
- package/fixtures/atelier-intake/valid/attempt.v1.json +8 -0
- package/fixtures/atelier-intake/valid/completion.v1.json +9 -0
- package/fixtures/atelier-intake/valid/source.v1.json +7 -0
- package/fixtures/atelier-review/invalid/authenticated-identity.v1.json +22 -0
- package/fixtures/atelier-review/valid/bound.v1.json +229 -0
- package/fixtures/atelier-review/valid/bundle.v1.json +267 -0
- package/fixtures/atelier-review/valid/contribution.v1.json +22 -0
- package/fixtures/atelier-review/valid/lifecycle.v1.json +14 -0
- package/fixtures/atelier-skill-steward/audit/invalid/source-mutation.v1.json +26 -0
- package/fixtures/atelier-skill-steward/audit/valid/clean.v1.json +26 -0
- package/fixtures/atelier-skill-steward/candidates/invalid/workflow-key.v1.json +37 -0
- package/fixtures/atelier-skill-steward/candidates/valid/create.v1.json +37 -0
- package/fixtures/atelier-skill-steward/lock/invalid/bad-digest.v1.json +18 -0
- package/fixtures/atelier-skill-steward/lock/valid/installed.v1.json +23 -0
- package/fixtures/atelier-skill-steward/plan/invalid/delete-action.v1.json +33 -0
- package/fixtures/atelier-skill-steward/plan/valid/add.v1.json +33 -0
- package/fixtures/atelier-upgrade-transaction/adoption-policy/invalid/example.json +12 -0
- package/fixtures/atelier-upgrade-transaction/adoption-policy/valid/example.json +11 -0
- package/fixtures/atelier-upgrade-transaction/migration/invalid/example.json +20 -0
- package/fixtures/atelier-upgrade-transaction/migration/valid/example.json +19 -0
- package/fixtures/atelier-upgrade-transaction/upgrade-plan/invalid/example.json +58 -0
- package/fixtures/atelier-upgrade-transaction/upgrade-plan/valid/example.json +57 -0
- package/fixtures/atelier-upgrade-transaction/upgrade-receipt/invalid/example.json +15 -0
- package/fixtures/atelier-upgrade-transaction/upgrade-receipt/valid/example.json +14 -0
- package/fixtures/atelier-vault-publication/invalid/publication.json +5 -0
- package/fixtures/atelier-vault-publication/valid/publication.json +11 -0
- package/fixtures/decisions/request/invalid/unknown-authority.v1.json +61 -0
- package/fixtures/decisions/request/valid/triage.v1.json +60 -0
- package/fixtures/decisions/result/invalid/execution-authority.v1.json +50 -0
- package/fixtures/decisions/result/valid/abstained.v1.json +23 -0
- package/fixtures/decisions/result/valid/assessed.v1.json +50 -0
- package/fixtures/obsidian/acceptance/ap05-extra-notes.json +14 -0
- package/fixtures/obsidian/acceptance/receipts/G07.valid.v1.json +63 -0
- package/fixtures/obsidian/acceptance/receipts/G13.valid.v1.json +69 -0
- package/fixtures/obsidian/acceptance/receipts/G14.valid.v1.json +62 -0
- package/fixtures/obsidian/acceptance/receipts/G15.valid.v1.json +56 -0
- package/fixtures/obsidian/acceptance/receipts/G16.valid.v1.json +73 -0
- package/fixtures/obsidian/acceptance/receipts/G17.valid.v1.json +75 -0
- package/fixtures/obsidian/acceptance/receipts/G18.valid.v1.json +64 -0
- package/fixtures/obsidian/acceptance/service-sentinels.json +10 -0
- package/fixtures/obsidian/contracts/acceptance-receipt/invalid/duplicate-evidence-name.v1.json +39 -0
- package/fixtures/obsidian/contracts/acceptance-receipt/invalid/evidence-by-absolute-path.v1.json +34 -0
- package/fixtures/obsidian/contracts/acceptance-receipt/invalid/missing-candidate-tree.v1.json +33 -0
- package/fixtures/obsidian/contracts/acceptance-receipt/invalid/no-evidence.v1.json +28 -0
- package/fixtures/obsidian/contracts/acceptance-receipt/invalid/unknown-outcome.v1.json +34 -0
- package/fixtures/obsidian/contracts/acceptance-receipt/invalid/unknown-top-level-field.v1.json +35 -0
- package/fixtures/obsidian/contracts/acceptance-receipt/valid/node-gate.v1.json +34 -0
- package/fixtures/obsidian/contracts/apply-policy/invalid/automatic-without-edit-class.v1.json +27 -0
- package/fixtures/obsidian/contracts/apply-policy/invalid/conflict-overwrite.v1.json +29 -0
- package/fixtures/obsidian/contracts/apply-policy/invalid/missing-policy-digest.v1.json +28 -0
- package/fixtures/obsidian/contracts/apply-policy/invalid/unbounded-batch.v1.json +29 -0
- package/fixtures/obsidian/contracts/apply-policy/invalid/unimplemented-edit-class.v1.json +30 -0
- package/fixtures/obsidian/contracts/apply-policy/invalid/unknown-mode.v1.json +29 -0
- package/fixtures/obsidian/contracts/apply-policy/invalid/unknown-selector-operator.v1.json +22 -0
- package/fixtures/obsidian/contracts/apply-policy/invalid/unknown-top-level-field.v1.json +30 -0
- package/fixtures/obsidian/contracts/apply-policy/valid/automatic-scoped.v1.json +29 -0
- package/fixtures/obsidian/contracts/apply-policy/valid/manual-default.v1.json +20 -0
- package/fixtures/obsidian/contracts/corpus-profile/invalid/absolute-path-in-ext.v1.json +30 -0
- package/fixtures/obsidian/contracts/corpus-profile/invalid/absolute-repository-root.v1.json +27 -0
- package/fixtures/obsidian/contracts/corpus-profile/invalid/duplicate-repository-id.v1.json +27 -0
- package/fixtures/obsidian/contracts/corpus-profile/invalid/overlapping-managed-roots.v1.json +27 -0
- package/fixtures/obsidian/contracts/corpus-profile/invalid/unknown-enrollment.v1.json +27 -0
- package/fixtures/obsidian/contracts/corpus-profile/invalid/unknown-top-level-field.v1.json +28 -0
- package/fixtures/obsidian/contracts/corpus-profile/valid/three-repositories.v1.json +27 -0
- package/fixtures/obsidian/contracts/edit-operation/invalid/absolute-recovery-ref.v1.json +21 -0
- package/fixtures/obsidian/contracts/edit-operation/invalid/inline-observed-bytes.v1.json +22 -0
- package/fixtures/obsidian/contracts/edit-operation/invalid/missing-base-digest.v1.json +20 -0
- package/fixtures/obsidian/contracts/edit-operation/invalid/short-idempotency-key.v1.json +21 -0
- package/fixtures/obsidian/contracts/edit-operation/invalid/unknown-kind.v1.json +21 -0
- package/fixtures/obsidian/contracts/edit-operation/valid/pending-body-replacement.v1.json +21 -0
- package/fixtures/obsidian/contracts/ext-settings/invalid/absolute-path-prefix.v1.json +28 -0
- package/fixtures/obsidian/contracts/ext-settings/invalid/apply-policy-in-portable-settings.v1.json +30 -0
- package/fixtures/obsidian/contracts/ext-settings/invalid/duplicate-scope-id.v1.json +27 -0
- package/fixtures/obsidian/contracts/ext-settings/invalid/machine-local-vault-path.v1.json +28 -0
- package/fixtures/obsidian/contracts/ext-settings/invalid/service-port-in-portable-settings.v1.json +28 -0
- package/fixtures/obsidian/contracts/ext-settings/invalid/unknown-default-scope.v1.json +27 -0
- package/fixtures/obsidian/contracts/ext-settings/valid/disabled.v1.json +5 -0
- package/fixtures/obsidian/contracts/ext-settings/valid/enabled-with-scopes.v1.json +27 -0
- package/fixtures/obsidian/contracts/generation-manifest/invalid/absolute-note-path.v1.json +114 -0
- package/fixtures/obsidian/contracts/generation-manifest/invalid/complete-with-unwritten-notes.v1.json +114 -0
- package/fixtures/obsidian/contracts/generation-manifest/invalid/derived-link-claimed-declared.v1.json +114 -0
- package/fixtures/obsidian/contracts/generation-manifest/invalid/duplicate-note-identity.v1.json +114 -0
- package/fixtures/obsidian/contracts/generation-manifest/invalid/in-scope-endpoint-missing.v1.json +114 -0
- package/fixtures/obsidian/contracts/generation-manifest/invalid/title-only-note-path.v1.json +114 -0
- package/fixtures/obsidian/contracts/generation-manifest/invalid/unknown-note-field.v1.json +115 -0
- package/fixtures/obsidian/contracts/generation-manifest/invalid/unknown-relation-type.v1.json +114 -0
- package/fixtures/obsidian/contracts/generation-manifest/invalid/withheld-endpoint.v1.json +114 -0
- package/fixtures/obsidian/contracts/generation-manifest/valid/two-notes.v1.json +114 -0
- package/fixtures/obsidian/contracts/oracles/scope-cases.json +412 -0
- package/fixtures/obsidian/contracts/proposal-receipt/invalid/accepted-without-proposal-id.v1.json +12 -0
- package/fixtures/obsidian/contracts/proposal-receipt/invalid/missing-adapter-operation-id.v1.json +11 -0
- package/fixtures/obsidian/contracts/proposal-receipt/invalid/unknown-backpressure-outcome.v1.json +12 -0
- package/fixtures/obsidian/contracts/proposal-receipt/invalid/unknown-top-level-field.v1.json +13 -0
- package/fixtures/obsidian/contracts/proposal-receipt/valid/accepted-new.v1.json +12 -0
- package/fixtures/obsidian/contracts/proposal-receipt/valid/deferred.v1.json +12 -0
- package/fixtures/obsidian/contracts/publication-journal/invalid/absolute-recovery-ref.v1.json +47 -0
- package/fixtures/obsidian/contracts/publication-journal/invalid/duplicate-sequence.v1.json +47 -0
- package/fixtures/obsidian/contracts/publication-journal/invalid/empty-protocol-id.v1.json +47 -0
- package/fixtures/obsidian/contracts/publication-journal/invalid/missing-protocol-id.v1.json +46 -0
- package/fixtures/obsidian/contracts/publication-journal/invalid/unknown-entry-field.v1.json +48 -0
- package/fixtures/obsidian/contracts/publication-journal/invalid/unknown-state.v1.json +47 -0
- package/fixtures/obsidian/contracts/publication-journal/valid/committed.v1.json +47 -0
- package/fixtures/obsidian/contracts/publication-journal/valid/updating-after-restart.v1.json +22 -0
- package/fixtures/obsidian/contracts/scope/invalid/absolute-path-prefix.v1.json +15 -0
- package/fixtures/obsidian/contracts/scope/invalid/duplicate-ids.v1.json +18 -0
- package/fixtures/obsidian/contracts/scope/invalid/expansion-without-node-budget.v1.json +40 -0
- package/fixtures/obsidian/contracts/scope/invalid/full-mode-with-subset.v1.json +8 -0
- package/fixtures/obsidian/contracts/scope/invalid/unknown-mode.v1.json +41 -0
- package/fixtures/obsidian/contracts/scope/invalid/unknown-selector-key.v1.json +15 -0
- package/fixtures/obsidian/contracts/scope/invalid/unknown-selector-operator.v1.json +14 -0
- package/fixtures/obsidian/contracts/scope/invalid/unknown-top-level-field.v1.json +42 -0
- package/fixtures/obsidian/contracts/scope/valid/explicit-empty.v1.json +8 -0
- package/fixtures/obsidian/contracts/scope/valid/focus.v1.json +11 -0
- package/fixtures/obsidian/contracts/scope/valid/full.v1.json +8 -0
- package/fixtures/obsidian/contracts/scope/valid/scoped-set-expression.v1.json +41 -0
- package/fixtures/obsidian/contracts/service-state/invalid/hostname-instead-of-literal-loopback.v1.json +23 -0
- package/fixtures/obsidian/contracts/service-state/invalid/missing-consent.v1.json +18 -0
- package/fixtures/obsidian/contracts/service-state/invalid/privileged-port.v1.json +23 -0
- package/fixtures/obsidian/contracts/service-state/invalid/unknown-top-level-field.v1.json +24 -0
- package/fixtures/obsidian/contracts/service-state/invalid/wildcard-bind.v1.json +23 -0
- package/fixtures/obsidian/contracts/service-state/valid/healthy.v1.json +23 -0
- package/fixtures/obsidian/contracts/source-snapshot/invalid/absolute-file-path.v1.json +48 -0
- package/fixtures/obsidian/contracts/source-snapshot/invalid/duplicate-repository-id.v1.json +48 -0
- package/fixtures/obsidian/contracts/source-snapshot/invalid/mixed-read.v1.json +48 -0
- package/fixtures/obsidian/contracts/source-snapshot/invalid/parent-traversal-path.v1.json +48 -0
- package/fixtures/obsidian/contracts/source-snapshot/invalid/unknown-file-field.v1.json +49 -0
- package/fixtures/obsidian/contracts/source-snapshot/valid/two-repositories.v1.json +48 -0
- package/fixtures/obsidian/edits/workspace.json +65 -0
- package/fixtures/obsidian/materialization/expected-full.json +99 -0
- package/fixtures/obsidian/materialization/expected-scoped.json +39 -0
- package/fixtures/obsidian/materialization/workspace.json +54 -0
- package/fixtures/obsidian/proposals/expected-shapes.json +11 -0
- package/fixtures/ui/presentation/pane.v1.json +7 -0
- package/fixtures/ui/presentation/reference.v1.json +293 -0
- package/package.json +57 -6
- package/skills/claude/atelier-guided-coauthor/SKILL.md +49 -0
- package/skills/claude/atelier-guided-upgrade/SKILL.md +97 -0
- package/skills/claude/atelier-open/SKILL.md +5 -0
- package/skills/claude/atelier-skill-steward/SKILL.md +62 -0
- package/skills/claude/mnstry-readiness/SKILL.md +5 -0
- package/skills/codex/atelier-guided-coauthor/SKILL.md +49 -0
- package/skills/codex/atelier-guided-upgrade/SKILL.md +97 -0
- package/skills/codex/atelier-open/SKILL.md +5 -0
- package/skills/codex/atelier-skill-steward/SKILL.md +62 -0
- package/skills/codex/mnstry-readiness/SKILL.md +5 -0
- package/src/access/preview-enforcer.mjs +84 -0
- package/src/boundary/policy.mjs +57 -25
- package/src/cli/project-options.mjs +58 -0
- package/src/cli/run.mjs +43 -3
- package/src/coauthor/session.mjs +161 -0
- package/src/coauthor/store.mjs +173 -0
- package/src/collaboration/event-ledger.mjs +16 -33
- package/src/collaboration/inspection-bundle.mjs +223 -0
- package/src/collaboration/review-contracts.mjs +25 -0
- package/src/collaboration/review-store.mjs +305 -0
- package/src/commands/coauthor.mjs +26 -0
- package/src/commands/config.mjs +6 -1
- package/src/commands/extension-pack.mjs +15 -8
- package/src/commands/init.mjs +44 -5
- package/src/commands/obsidian.mjs +368 -0
- package/src/commands/review.mjs +147 -0
- package/src/commands/setup.mjs +51 -14
- package/src/commands/skills.mjs +199 -0
- package/src/commands/sync.mjs +8 -1
- package/src/composition/registry.mjs +27 -0
- package/src/composition/wire.mjs +122 -0
- package/src/contracts/corpus.mjs +29 -0
- package/src/decisions/contracts.d.mts +96 -0
- package/src/decisions/contracts.mjs +321 -0
- package/src/disclosure/content-scan.mjs +13 -0
- package/src/export/atelier-export-contract.mjs +16 -1
- package/src/extension-packs/lifecycle.mjs +154 -0
- package/src/graph/graph.mjs +64 -2
- package/src/graph/knowledge-graph.mjs +548 -24
- package/src/guides/contracts.mjs +54 -0
- package/src/intake/store.mjs +119 -0
- package/src/preview/channel.mjs +89 -0
- package/src/project/config.mjs +26 -27
- package/src/project/durable-state.mjs +161 -0
- package/src/project/file-class.mjs +166 -0
- package/src/project/private-state.mjs +11 -1
- package/src/projection/obsidian/contracts.mjs +571 -0
- package/src/projection/obsidian/edits/align.mjs +169 -0
- package/src/projection/obsidian/edits/apply.mjs +889 -0
- package/src/projection/obsidian/edits/arbitrate.mjs +414 -0
- package/src/projection/obsidian/edits/contribution.mjs +108 -0
- package/src/projection/obsidian/edits/index.mjs +19 -0
- package/src/projection/obsidian/edits/object-identity.mjs +61 -0
- package/src/projection/obsidian/edits/object-store.mjs +517 -0
- package/src/projection/obsidian/edits/observe.mjs +123 -0
- package/src/projection/obsidian/edits/policy.mjs +123 -0
- package/src/projection/obsidian/edits/regions.mjs +648 -0
- package/src/projection/obsidian/materialize/byte-lens.mjs +98 -0
- package/src/projection/obsidian/materialize/index.mjs +7 -0
- package/src/projection/obsidian/materialize/path-registry.mjs +105 -0
- package/src/projection/obsidian/materialize/prepare-view.mjs +746 -0
- package/src/projection/obsidian/materialize/settings.mjs +57 -0
- package/src/projection/obsidian/materialize/stage.mjs +27 -0
- package/src/projection/obsidian/proposals/adapter.mjs +572 -0
- package/src/projection/obsidian/proposals/backpressure.mjs +113 -0
- package/src/projection/obsidian/proposals/contribution.mjs +55 -0
- package/src/projection/obsidian/proposals/index.mjs +23 -0
- package/src/projection/obsidian/proposals/observation.mjs +216 -0
- package/src/projection/obsidian/proposals/queue.mjs +277 -0
- package/src/projection/obsidian/proposals/router.mjs +168 -0
- package/src/projection/obsidian/publication/bridge-script.mjs +266 -0
- package/src/projection/obsidian/publication/exchange.mjs +117 -0
- package/src/projection/obsidian/publication/index.mjs +5 -0
- package/src/projection/obsidian/publication/publisher.mjs +588 -0
- package/src/projection/obsidian/publication/test-seam.mjs +16 -0
- package/src/projection/obsidian/publication/transport.mjs +139 -0
- package/src/projection/obsidian/recovery/index.mjs +6 -0
- package/src/projection/obsidian/recovery/journal.mjs +134 -0
- package/src/projection/obsidian/recovery/late-writer.mjs +46 -0
- package/src/projection/obsidian/recovery/restart.mjs +316 -0
- package/src/projection/obsidian/recovery/store.mjs +234 -0
- package/src/projection/obsidian/selection-ui/conflict-view.mjs +91 -0
- package/src/projection/obsidian/selection-ui/contribution.mjs +141 -0
- package/src/projection/obsidian/selection-ui/focus.mjs +82 -0
- package/src/projection/obsidian/selection-ui/index.mjs +12 -0
- package/src/projection/obsidian/selection-ui/policy-setup.mjs +107 -0
- package/src/projection/obsidian/selection-ui/receipt.mjs +173 -0
- package/src/projection/obsidian/selection-ui/selection-state.mjs +122 -0
- package/src/projection/obsidian/selection-ui/selection.mjs +109 -0
- package/src/projection/project.mjs +28 -19
- package/src/readiness-protocols/evidence.mjs +282 -0
- package/src/readiness-protocols/runtime.mjs +4 -3
- package/src/readiness-protocols/source-read.mjs +39 -0
- package/src/runtime/obsidian/app-capability.mjs +110 -0
- package/src/runtime/obsidian/app-production-seams.mjs +96 -0
- package/src/runtime/obsidian/contributions/proposal-adapter.mjs +4 -0
- package/src/runtime/obsidian/contributions/selection-ui.mjs +4 -0
- package/src/runtime/obsidian/contributions/source-apply.mjs +4 -0
- package/src/runtime/obsidian/contributions.mjs +27 -0
- package/src/runtime/obsidian/documents.mjs +37 -0
- package/src/runtime/obsidian/enablement.mjs +53 -0
- package/src/runtime/obsidian/engine.mjs +532 -0
- package/src/runtime/obsidian/errors.mjs +14 -0
- package/src/runtime/obsidian/extension-points.mjs +103 -0
- package/src/runtime/obsidian/index.mjs +34 -0
- package/src/runtime/obsidian/lifecycle.mjs +258 -0
- package/src/runtime/obsidian/machine-settings.mjs +260 -0
- package/src/runtime/obsidian/observation.mjs +158 -0
- package/src/runtime/obsidian/opening.mjs +243 -0
- package/src/runtime/obsidian/pending-edits.mjs +141 -0
- package/src/runtime/obsidian/pipeline.mjs +122 -0
- package/src/runtime/obsidian/private-lock.mjs +156 -0
- package/src/runtime/obsidian/process-identity.mjs +58 -0
- package/src/runtime/obsidian/service-client.mjs +66 -0
- package/src/runtime/obsidian/service-main.mjs +89 -0
- package/src/runtime/obsidian/service-record.mjs +169 -0
- package/src/runtime/obsidian/service-server.mjs +121 -0
- package/src/runtime/obsidian/service.mjs +216 -0
- package/src/runtime/obsidian/startup-adapters.mjs +87 -0
- package/src/runtime/obsidian/state-store.mjs +180 -0
- package/src/runtime/obsidian/sync-notice.mjs +33 -0
- package/src/runtime/obsidian/tick-loop.mjs +84 -0
- package/src/runtime/obsidian/watchers.mjs +36 -0
- package/src/runtime/supervisor.mjs +16 -1
- package/src/server/local-sidecar.mjs +44 -0
- package/src/server/server.mjs +1 -0
- package/src/skills/steward.mjs +780 -0
- package/src/ui/presentation/browser.mjs +278 -0
- package/src/ui/presentation/contract.mjs +116 -0
- package/src/ui/presentation/index.mjs +7 -0
- package/src/ui/presentation/native.mjs +153 -0
- package/src/ui/presentation/proof.mjs +57 -0
- package/src/ui/presentation/schema-check.mjs +30 -0
- package/src/ui/presentation/schema.generated.mjs +1371 -0
- package/src/ui/presentation/state.mjs +43 -0
- package/src/ui/presentation/styles.mjs +67 -0
- package/src/ui/presentation/tokens.mjs +74 -0
- package/src/ui/presentation/web.mjs +85 -0
- package/src/ui/review-page.mjs +32 -0
- package/src/upgrade/explanation.mjs +33 -0
- package/src/upgrade/provenance.mjs +338 -0
- package/src/upgrade/transaction-files.mjs +103 -0
- package/src/upgrade/transaction.mjs +475 -0
- package/src/upgrade/upgrade.mjs +63 -28
- package/src/vault/hosts.mjs +21 -0
- package/src/vault/identity.mjs +19 -0
- package/src/vault/index.mjs +7 -0
- package/src/vault/interface.mjs +11 -0
- package/src/vault/metadata.mjs +31 -0
- package/src/vault/privacy.mjs +148 -0
- package/src/vault/probe.mjs +89 -0
- package/src/vault/service.mjs +131 -0
- package/src/vault/source.mjs +45 -0
- package/src/vault/storage.mjs +23 -0
- package/templates/distribution-workspace/.claude/launch.json +6 -2
- package/templates/distribution-workspace/gitignore +1 -0
- package/templates/distribution-workspace/project/README.md +2 -2
- package/templates/external-project-workspace/README.md +45 -0
- package/templates/external-project-workspace/answers.example.json +4 -0
- package/templates/external-project-workspace/atelier.project.json +40 -0
- package/templates/external-project-workspace/boundary-policy.v1.json +60 -0
- package/templates/external-project-workspace/gitignore +8 -0
- package/templates/external-project-workspace/pack-lifecycle.json +14 -0
- package/templates/external-project-workspace/packs/protocols/contract-gate.v1.json +109 -0
- package/templates/external-project-workspace/packs/sample-pack.v1.json +48 -0
- package/templates/external-project-workspace/repo-access.v1.json +9 -0
- package/templates/external-project-workspace/source/README.md +11 -0
- package/templates/launch.json +6 -2
- package/templates/private-domain-workspace/.claude/launch.json +6 -2
- package/templates/private-domain-workspace/domain/README.md +2 -2
- package/templates/private-domain-workspace/gitignore +1 -0
- package/templates/shared-project-workspace/.claude/launch.json +6 -2
- package/templates/shared-project-workspace/gitignore +1 -0
- package/templates/shared-project-workspace/project/README.md +2 -2
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Calls one `tick` again and again, never two at a time.
|
|
2
|
+
//
|
|
3
|
+
// The next tick is scheduled only when the previous one has settled, so ticks
|
|
4
|
+
// cannot overlap however long one takes. A tick that throws does not end the
|
|
5
|
+
// loop and does not change the next tick: the error is handed to `onOutcome`,
|
|
6
|
+
// and the delay before the next attempt doubles per consecutive failure up to
|
|
7
|
+
// a ceiling, so a disk that stays full is retried slowly instead of in a tight
|
|
8
|
+
// loop. One success returns the loop to its interval.
|
|
9
|
+
//
|
|
10
|
+
// `tickNow()` asks for a tick that starts after the request: while a tick is
|
|
11
|
+
// in flight the request is answered by one follow-up tick, shared by everyone
|
|
12
|
+
// who asked meanwhile.
|
|
13
|
+
|
|
14
|
+
export const DEFAULT_TICK_INTERVAL_MS = 30 * 1000
|
|
15
|
+
export const DEFAULT_MAX_BACKOFF_MS = 15 * 60 * 1000
|
|
16
|
+
|
|
17
|
+
export const TICK_LOOP_PRIMITIVES = Object.freeze({
|
|
18
|
+
// Whether the loop goes on after a tick threw.
|
|
19
|
+
continuesAfterError: () => true,
|
|
20
|
+
delayAfter: ({ intervalMs, maxBackoffMs, consecutiveFailures }) => (consecutiveFailures === 0 ? intervalMs : Math.min(maxBackoffMs, intervalMs * 2 ** Math.min(consecutiveFailures, 20))),
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
export function createTickLoopForOracleTests({ tick, intervalMs = DEFAULT_TICK_INTERVAL_MS, maxBackoffMs = DEFAULT_MAX_BACKOFF_MS, setTimer = setTimeout, clearTimer = clearTimeout, onOutcome = () => {} }, primitives = TICK_LOOP_PRIMITIVES) {
|
|
24
|
+
if (typeof tick !== 'function') throw new TypeError('the tick loop needs a tick')
|
|
25
|
+
if (!Number.isInteger(intervalMs) || intervalMs < 1 || !Number.isInteger(maxBackoffMs) || maxBackoffMs < intervalMs) throw new TypeError('the tick loop needs a positive interval and a backoff ceiling no smaller than it')
|
|
26
|
+
const rules = { ...TICK_LOOP_PRIMITIVES, ...primitives }
|
|
27
|
+
let timer = null
|
|
28
|
+
let inFlight = null
|
|
29
|
+
let followUp = null // { promise, resolve } while somebody waits for a tick that starts after now
|
|
30
|
+
let started = false
|
|
31
|
+
let stopped = false
|
|
32
|
+
let consecutiveFailures = 0
|
|
33
|
+
let ticks = 0
|
|
34
|
+
|
|
35
|
+
function schedule() {
|
|
36
|
+
if (stopped || !started || timer !== null) return
|
|
37
|
+
timer = setTimer(() => { timer = null; void run() }, rules.delayAfter({ intervalMs, maxBackoffMs, consecutiveFailures }))
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function once() {
|
|
41
|
+
let outcome
|
|
42
|
+
try { outcome = { ok: true, report: await tick() } } catch (error) { outcome = { ok: false, error } }
|
|
43
|
+
ticks += 1
|
|
44
|
+
consecutiveFailures = outcome.ok ? 0 : consecutiveFailures + 1
|
|
45
|
+
try { await onOutcome({ ...outcome, consecutiveFailures }) } catch { /* recording an outcome never ends the loop */ }
|
|
46
|
+
if (!outcome.ok && !rules.continuesAfterError()) stopped = true
|
|
47
|
+
return outcome
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function run() {
|
|
51
|
+
if (stopped) return Promise.resolve({ ok: false, stopped: true })
|
|
52
|
+
if (inFlight) return inFlight
|
|
53
|
+
if (timer !== null) { clearTimer(timer); timer = null }
|
|
54
|
+
inFlight = once().finally(() => {
|
|
55
|
+
inFlight = null
|
|
56
|
+
const waiting = followUp
|
|
57
|
+
followUp = null
|
|
58
|
+
if (waiting) run().then(waiting.resolve)
|
|
59
|
+
else schedule()
|
|
60
|
+
})
|
|
61
|
+
return inFlight
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
start() { if (!started && !stopped) { started = true; void run() } },
|
|
66
|
+
tickNow() {
|
|
67
|
+
if (stopped) return Promise.resolve({ ok: false, stopped: true })
|
|
68
|
+
if (!inFlight) return run()
|
|
69
|
+
if (!followUp) { let resolve; const promise = new Promise((settle) => { resolve = settle }); followUp = { promise, resolve } }
|
|
70
|
+
return followUp.promise
|
|
71
|
+
},
|
|
72
|
+
// Lets the tick in flight finish; starts no other.
|
|
73
|
+
async stop() {
|
|
74
|
+
stopped = true
|
|
75
|
+
if (timer !== null) { clearTimer(timer); timer = null }
|
|
76
|
+
if (inFlight) await inFlight.catch(() => {})
|
|
77
|
+
},
|
|
78
|
+
state: () => ({ started, stopped, ticking: inFlight !== null, ticks, consecutiveFailures, nextDelayMs: rules.delayAfter({ intervalMs, maxBackoffMs, consecutiveFailures }) }),
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function createTickLoop(options) {
|
|
83
|
+
return createTickLoopForOracleTests(options, TICK_LOOP_PRIMITIVES)
|
|
84
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
|
|
3
|
+
// Filesystem watchers, as hints only.
|
|
4
|
+
//
|
|
5
|
+
// factory({ roots: [{ id, path, recursive }], onEvent }) -> { close() }
|
|
6
|
+
// onEvent({ rootId, relative }) relative is a '/'-separated path under the
|
|
7
|
+
// root, or null for "something under it"
|
|
8
|
+
//
|
|
9
|
+
// A watcher may drop, repeat or delay events and may fail to start at all; the
|
|
10
|
+
// engine never depends on one. It only hashes a named file sooner than the
|
|
11
|
+
// next stat scan would have. Tests inject a factory they drive by hand.
|
|
12
|
+
|
|
13
|
+
export function createNullWatcherFactory() {
|
|
14
|
+
return () => ({ close() {} })
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// fs.watch, recursive where the platform supports it. It does not keep the
|
|
18
|
+
// process alive, and a root that cannot be watched is reported, not thrown:
|
|
19
|
+
// digest reconciliation still covers it.
|
|
20
|
+
export function createFsWatcherFactory({ watch = fs.watch, onUnavailable = () => {} } = {}) {
|
|
21
|
+
return ({ roots, onEvent }) => {
|
|
22
|
+
const watchers = []
|
|
23
|
+
for (const root of roots) {
|
|
24
|
+
try {
|
|
25
|
+
const watcher = watch(root.path, { recursive: root.recursive !== false, persistent: false }, (_eventType, filename) => {
|
|
26
|
+
onEvent({ rootId: root.id, relative: typeof filename === 'string' && filename !== '' ? filename.split('\\').join('/') : null })
|
|
27
|
+
})
|
|
28
|
+
watcher.on('error', () => onUnavailable({ rootId: root.id }))
|
|
29
|
+
watchers.push(watcher)
|
|
30
|
+
} catch {
|
|
31
|
+
onUnavailable({ rootId: root.id })
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return { close() { for (const watcher of watchers.splice(0)) try { watcher.close() } catch { /* already closed */ } } }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -2,7 +2,7 @@ import crypto from 'node:crypto'
|
|
|
2
2
|
import fs from 'node:fs'
|
|
3
3
|
import path from 'node:path'
|
|
4
4
|
import { checkBoundaryPolicy, loadBoundaryPolicy } from '../boundary/policy.mjs'
|
|
5
|
-
import { commandProject } from '../project/config.mjs'
|
|
5
|
+
import { commandProject, resolveProjectConfig } from '../project/config.mjs'
|
|
6
6
|
import { classifyRemoteAuthentication, inspectGitEngine, redactGitDiagnostic, resolveGitExecutable, runGit, sanitizeRemoteUrl } from './git-adapter.mjs'
|
|
7
7
|
import {
|
|
8
8
|
ATELIER_RUNTIME_ENROLLMENT_SCHEMA,
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
writeRuntimeState,
|
|
24
24
|
} from './local-state.mjs'
|
|
25
25
|
import { observeRepository, resolveRepositoryRoot } from './repository-observation.mjs'
|
|
26
|
+
import { maintenanceNoticeFor } from './obsidian/sync-notice.mjs'
|
|
26
27
|
|
|
27
28
|
export const ATELIER_COMMIT_PLAN_SCHEMA = 'atelier-commit-plan@v1'
|
|
28
29
|
|
|
@@ -786,3 +787,17 @@ export function operationTrace({ repoPath = process.cwd() } = {}) {
|
|
|
786
787
|
const { paths } = loadEnrollment(repoPath)
|
|
787
788
|
return readOperationTrace(paths.trace)
|
|
788
789
|
}
|
|
790
|
+
|
|
791
|
+
// Report only. Git synchronization cannot maintain an external Obsidian vault and does not try: when the enrolled
|
|
792
|
+
// project enables that integration, `sync` repeats what maintenance last persisted and points at its own command.
|
|
793
|
+
// Null when the project is not configured for it or has it off, and then the output of `sync` is unchanged.
|
|
794
|
+
export function obsidianMaintenanceNotice({ repoPath = process.cwd(), env = process.env } = {}) {
|
|
795
|
+
try {
|
|
796
|
+
const { enrollment } = loadEnrollment(repoPath, { env })
|
|
797
|
+
if (!enrollment.projectConfig) return null
|
|
798
|
+
return maintenanceNoticeFor(resolveProjectConfig({ argv: [`--project=${enrollment.projectConfig}`], cwd: enrollment.repoRoot, env, writeLocalState: false }), { env })
|
|
799
|
+
} catch {
|
|
800
|
+
// A report must never change what sync does or whether it succeeds.
|
|
801
|
+
return null
|
|
802
|
+
}
|
|
803
|
+
}
|
|
@@ -30,6 +30,10 @@ import {
|
|
|
30
30
|
renderProposalListPageHtml,
|
|
31
31
|
} from '../ui/html-primitives.mjs'
|
|
32
32
|
|
|
33
|
+
import { createReviewStore } from '../collaboration/review-store.mjs'
|
|
34
|
+
import { loadBoundRun, currentRunEligibility } from '../readiness-protocols/evidence.mjs'
|
|
35
|
+
import { renderReviewPage } from '../ui/review-page.mjs'
|
|
36
|
+
|
|
33
37
|
export const ATELIER_CONTEXT_SCHEMA = 'atelier-context@v1'
|
|
34
38
|
export const ATELIER_PRESENCE_SCHEMA = 'atelier-presence@v1'
|
|
35
39
|
export const ATELIER_RESOLVE_SCHEMA = 'atelier-resolve@v1'
|
|
@@ -206,6 +210,7 @@ function doctorEnvelope() {
|
|
|
206
210
|
export function createAtelierSidecarServer({
|
|
207
211
|
workspaceRoot = process.cwd(),
|
|
208
212
|
stateDir = workspaceRoot,
|
|
213
|
+
reviewProject = null,
|
|
209
214
|
port = 0,
|
|
210
215
|
presenceTtlMs = Number(process.env.ATELIER_PRESENCE_TTL_MS || 5 * 60 * 1000),
|
|
211
216
|
} = {}) {
|
|
@@ -217,6 +222,7 @@ export function createAtelierSidecarServer({
|
|
|
217
222
|
label: 'Atelier state directory',
|
|
218
223
|
})
|
|
219
224
|
const publication = loadPublishedWorkspaceManifest(root)
|
|
225
|
+
const review = reviewProject ? createReviewStore(reviewProject) : null
|
|
220
226
|
const workspaceId = workspaceIdForRoot(root)
|
|
221
227
|
const noncePath = path.join(stateDirReal, '.atelier-nonce')
|
|
222
228
|
const presencePath = path.join(stateDirReal, '.atelier-presence.json')
|
|
@@ -366,12 +372,31 @@ export function createAtelierSidecarServer({
|
|
|
366
372
|
json(res, 400, { ok: false, error: error.message })
|
|
367
373
|
return
|
|
368
374
|
}
|
|
375
|
+
// Browsers send Origin on POST; same-origin GET normally omits it. Keep
|
|
376
|
+
// the strict origin gate for nonce disclosure instead of relaxing the
|
|
377
|
+
// existing session-auth GET contract or accepting unclassified reads.
|
|
378
|
+
if (review && url.pathname === '/api/review/session') {
|
|
379
|
+
if (!trustedMutationRequest(req.headers) || !body || Array.isArray(body) || Object.keys(body).length) {
|
|
380
|
+
json(res, 403, { ok: false, error: 'review session requires a same-origin empty request' })
|
|
381
|
+
return
|
|
382
|
+
}
|
|
383
|
+
const published = resolvePublishedPath({ rel: 'index.html', requireHtml: true })
|
|
384
|
+
if (!published.ok) { json(res, 404, { ok: false, error: 'published workspace unavailable' }); return }
|
|
385
|
+
json(res, 200, { ok: true, schema: ATELIER_SESSION_AUTH_SCHEMA, workspaceId, mutationNonce })
|
|
386
|
+
return
|
|
387
|
+
}
|
|
369
388
|
const auth = requireMutationAuth(req, body, mutationNonce)
|
|
370
389
|
if (!auth.ok) {
|
|
371
390
|
json(res, auth.status, { ok: false, error: auth.error })
|
|
372
391
|
return
|
|
373
392
|
}
|
|
374
393
|
|
|
394
|
+
if (review && url.pathname === '/api/review/contributions') {
|
|
395
|
+
const result = review.contribute(body)
|
|
396
|
+
json(res, result.status, result)
|
|
397
|
+
return
|
|
398
|
+
}
|
|
399
|
+
|
|
375
400
|
if (url.pathname === '/api/seen') {
|
|
376
401
|
const result = recordView(body.rel || body.path, body)
|
|
377
402
|
json(res, 200, result.ok ? { ok: true, entry: result.entry } : result)
|
|
@@ -483,6 +508,25 @@ export function createAtelierSidecarServer({
|
|
|
483
508
|
return
|
|
484
509
|
}
|
|
485
510
|
|
|
511
|
+
if (review && url.pathname === '/review') {
|
|
512
|
+
const body = renderReviewPage()
|
|
513
|
+
res.writeHead(200, htmlDocumentHeaders(Buffer.byteLength(body)))
|
|
514
|
+
res.end(body)
|
|
515
|
+
return
|
|
516
|
+
}
|
|
517
|
+
if (review && url.pathname.startsWith('/api/review/')) {
|
|
518
|
+
let result
|
|
519
|
+
if (url.pathname === '/api/review/records') result = review.records()
|
|
520
|
+
else if (url.pathname === '/api/review/document') result = review.document(url.searchParams.get('repo'), url.searchParams.get('path'))
|
|
521
|
+
else if (url.pathname === '/api/review/run') {
|
|
522
|
+
const bound = loadBoundRun(reviewProject, url.searchParams.get('id'))
|
|
523
|
+
result = bound.ok ? {...bound, current:currentRunEligibility(reviewProject,bound)} : bound
|
|
524
|
+
} else if (url.pathname === '/api/review/handoff') result = review.handoff(url.searchParams.get('id'))
|
|
525
|
+
else result = {ok:false,status:404,error:'unknown review action'}
|
|
526
|
+
json(res, result.status, result)
|
|
527
|
+
return
|
|
528
|
+
}
|
|
529
|
+
|
|
486
530
|
if (url.pathname === '/api/health') {
|
|
487
531
|
json(res, 200, { ok: true, workspaceId })
|
|
488
532
|
return
|
package/src/server/server.mjs
CHANGED
|
@@ -17,6 +17,7 @@ export async function runServerCommand(argv = process.argv.slice(2)) {
|
|
|
17
17
|
const sidecar = createAtelierSidecarServer({
|
|
18
18
|
workspaceRoot: project.outputRoot,
|
|
19
19
|
stateDir: project.outputRoot,
|
|
20
|
+
reviewProject: argv.includes('--review') ? project : null,
|
|
20
21
|
// argv > PORT env > default. Supervisors that assign a free port (preview
|
|
21
22
|
// panes, dev harnesses) pass it via PORT, and an Atelier that ignores that
|
|
22
23
|
// fights whatever already holds the canonical port instead of coexisting.
|