@mnstry/atelier 0.2.0-alpha.12 → 0.2.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +661 -0
- package/README.md +142 -6
- package/contracts/atelier-adoption-policy.v2.schema.json +55 -0
- package/contracts/atelier-architecture.v1.schema.json +258 -0
- package/contracts/atelier-boundary-delegations.v1.schema.json +161 -0
- package/contracts/atelier-boundary-owner-keys.v1.schema.json +98 -0
- package/contracts/atelier-build.v1.schema.json +1076 -0
- package/contracts/atelier-capability.v1.schema.json +1252 -0
- package/contracts/atelier-coordination.v1.schema.json +1050 -0
- package/contracts/atelier-evidence-navigation.v1.schema.json +603 -0
- package/contracts/atelier-harness.v1.schema.json +234 -0
- package/contracts/atelier-ingestion.v1.schema.json +806 -0
- package/contracts/atelier-inquiry.v1.schema.json +1772 -0
- package/contracts/atelier-instruction-adoption.v1.schema.json +490 -0
- package/contracts/atelier-interaction.v1.schema.json +553 -0
- package/contracts/atelier-judgment.v1.schema.json +690 -0
- package/contracts/atelier-knowledge.v1.schema.json +1512 -0
- package/contracts/atelier-learning.v1.schema.json +1095 -0
- package/contracts/atelier-migration.v3.schema.json +64 -0
- package/contracts/atelier-personal-workspace-manifest.v1.schema.json +87 -0
- package/contracts/atelier-personal-workspace-overlay.v1.schema.json +299 -0
- package/contracts/atelier-template-adoption.v1.schema.json +223 -0
- package/contracts/atelier-template-profile.v1.schema.json +1168 -0
- package/contracts/atelier-trackable.v1.schema.json +781 -0
- package/contracts/atelier-upgrade-plan.v3.schema.json +532 -0
- package/docs/architecture.md +89 -0
- package/docs/assurance-controls.md +2 -2
- package/docs/blocks/capability-stewardship.md +17 -0
- package/docs/blocks/claims.md +16 -3
- package/docs/blocks/inquiry-harnesses.md +19 -0
- package/docs/blocks/learning-harnesses.md +17 -0
- package/docs/capability-stewardship.md +269 -0
- package/docs/coordination.md +51 -0
- package/docs/decision-practices.md +111 -0
- package/docs/decisions.md +29 -0
- package/docs/evidence-navigation.md +237 -0
- package/docs/exact-upgrades.md +3 -2
- package/docs/ingestion.md +181 -0
- package/docs/inquiry-harnesses.md +211 -0
- package/docs/install.md +80 -3
- package/docs/intake-and-guides.md +5 -0
- package/docs/integration-contract-decisions.md +24 -2
- package/docs/interaction-and-reflection.md +72 -0
- package/docs/knowledge-graph.md +20 -0
- package/docs/knowledge-health/api.md +30 -0
- package/docs/knowledge-health/assessment/api.md +96 -0
- package/docs/knowledge-health/assessment/capabilities.md +40 -0
- package/docs/knowledge-health/assessment/evaluation.md +27 -0
- package/docs/knowledge-health/assessment/facilitator.md +30 -0
- package/docs/knowledge-health/assessment/quickstart.md +61 -0
- package/docs/knowledge-health/assessment/troubleshooting.md +23 -0
- package/docs/knowledge-health/devday/facilitator.md +16 -0
- package/docs/knowledge-health/devday/participant-response.md +22 -0
- package/docs/knowledge-health/devday/public-default.md +107 -0
- package/docs/knowledge-health/devday/quickstart.md +18 -0
- package/docs/knowledge-health/devday/support.md +22 -0
- package/docs/knowledge-health/exercise.md +17 -0
- package/docs/knowledge-health/facilitator.md +20 -0
- package/docs/knowledge-health/quickstart.md +94 -0
- package/docs/knowledge-health/readme.md +15 -0
- package/docs/knowledge-health/support.md +34 -0
- package/docs/knowledge-setup.md +248 -0
- package/docs/knowledge-workspace.md +264 -0
- package/docs/learning-harnesses.md +238 -0
- package/docs/learning.md +215 -0
- package/docs/local-services.md +181 -16
- package/docs/obsidian-contract.md +223 -15
- package/docs/obsidian-plugin.md +38 -4
- package/docs/obsidian.md +613 -51
- package/docs/optional-ingestion.md +83 -0
- package/docs/personal-workspace.md +257 -0
- package/docs/practical-judgment.md +92 -0
- package/docs/progressive-ingestion-acceptance.md +89 -0
- package/docs/progressive-ingestion.md +235 -0
- package/docs/project-command-inventory.md +1 -0
- package/docs/release-engineering.md +49 -0
- package/docs/repo-boundary-guard.md +94 -0
- package/docs/research-starter-quickstart.md +66 -0
- package/docs/research-starter.md +114 -0
- package/docs/semantic-ingestion.md +198 -0
- package/docs/semantic-operation.md +317 -0
- package/docs/skill-steward.md +6 -0
- package/docs/template-profile.md +164 -0
- package/docs/template-upgrades.md +114 -0
- package/docs/trackables.md +111 -0
- package/docs/upgrade.md +47 -2
- package/fixtures/atelier-architecture/binding/invalid/document.json +19 -0
- package/fixtures/atelier-architecture/binding/valid/document.json +19 -0
- package/fixtures/atelier-architecture/catalog/invalid/document.json +290 -0
- package/fixtures/atelier-architecture/catalog/valid/document.json +343 -0
- package/fixtures/atelier-build-contract/attempt/invalid/document.json +20 -0
- package/fixtures/atelier-build-contract/attempt/valid/document.json +19 -0
- package/fixtures/atelier-build-contract/candidate/invalid/document.json +24 -0
- package/fixtures/atelier-build-contract/candidate/valid/document.json +23 -0
- package/fixtures/atelier-build-contract/decision/invalid/document.json +31 -0
- package/fixtures/atelier-build-contract/decision/valid/document.json +30 -0
- package/fixtures/atelier-build-contract/delivery/invalid/document.json +18 -0
- package/fixtures/atelier-build-contract/delivery/valid/document.json +17 -0
- package/fixtures/atelier-build-contract/gate/invalid/document.json +22 -0
- package/fixtures/atelier-build-contract/gate/valid/document.json +21 -0
- package/fixtures/atelier-build-contract/ledger/invalid/document.json +270 -0
- package/fixtures/atelier-build-contract/ledger/valid/document.json +269 -0
- package/fixtures/atelier-build-contract/objective/invalid/document.json +73 -0
- package/fixtures/atelier-build-contract/objective/valid/document.json +72 -0
- package/fixtures/atelier-build-contract/progress/invalid/document.json +18 -0
- package/fixtures/atelier-build-contract/progress/valid/document.json +17 -0
- package/fixtures/atelier-capability-contract/adoption/invalid/document.json +71 -0
- package/fixtures/atelier-capability-contract/adoption/valid/document.json +70 -0
- package/fixtures/atelier-capability-contract/event/invalid/document.json +18 -0
- package/fixtures/atelier-capability-contract/event/valid/document.json +17 -0
- package/fixtures/atelier-capability-contract/journal/invalid/document.json +382 -0
- package/fixtures/atelier-capability-contract/journal/valid/document.json +381 -0
- package/fixtures/atelier-capability-contract/notice/invalid/document.json +8 -0
- package/fixtures/atelier-capability-contract/notice/valid/document.json +7 -0
- package/fixtures/atelier-capability-contract/package/invalid/document.json +59 -0
- package/fixtures/atelier-capability-contract/package/valid/document.json +58 -0
- package/fixtures/atelier-capability-contract/plan/invalid/document.json +107 -0
- package/fixtures/atelier-capability-contract/plan/valid/document.json +106 -0
- package/fixtures/atelier-capability-contract/release/invalid/document.json +85 -0
- package/fixtures/atelier-capability-contract/release/valid/document.json +84 -0
- package/fixtures/atelier-capability-contract/state/invalid/document.json +316 -0
- package/fixtures/atelier-capability-contract/state/valid/document.json +315 -0
- package/fixtures/atelier-coordination/dependency/invalid/document.json +37 -0
- package/fixtures/atelier-coordination/dependency/valid/document.json +36 -0
- package/fixtures/atelier-coordination/directive/invalid/document.json +25 -0
- package/fixtures/atelier-coordination/directive/valid/document.json +24 -0
- package/fixtures/atelier-coordination/disposition/invalid/document.json +34 -0
- package/fixtures/atelier-coordination/disposition/valid/document.json +33 -0
- package/fixtures/atelier-coordination/outcome/invalid/document.json +39 -0
- package/fixtures/atelier-coordination/outcome/valid/document.json +38 -0
- package/fixtures/atelier-coordination/recovery/invalid/document.json +34 -0
- package/fixtures/atelier-coordination/recovery/valid/document.json +33 -0
- package/fixtures/atelier-harness-contract/handoff/invalid/document.json +25 -0
- package/fixtures/atelier-harness-contract/handoff/valid/document.json +24 -0
- package/fixtures/atelier-ingestion/invalid/authority.json +19 -0
- package/fixtures/atelier-ingestion/semantic-baseline.json +26 -0
- package/fixtures/atelier-ingestion/semantic-operation.json +75 -0
- package/fixtures/atelier-ingestion/valid/plan-input.json +18 -0
- package/fixtures/atelier-inquiry-contract/assessment/invalid/document.json +41 -0
- package/fixtures/atelier-inquiry-contract/assessment/valid/document.json +40 -0
- package/fixtures/atelier-inquiry-contract/bundle/invalid/document.json +51 -0
- package/fixtures/atelier-inquiry-contract/bundle/valid/document.json +50 -0
- package/fixtures/atelier-inquiry-contract/campaign/invalid/document.json +17 -0
- package/fixtures/atelier-inquiry-contract/campaign/valid/document.json +16 -0
- package/fixtures/atelier-inquiry-contract/decision/invalid/document.json +22 -0
- package/fixtures/atelier-inquiry-contract/decision/valid/document.json +21 -0
- package/fixtures/atelier-inquiry-contract/feedback/invalid/document.json +19 -0
- package/fixtures/atelier-inquiry-contract/feedback/valid/document.json +18 -0
- package/fixtures/atelier-inquiry-contract/handoff/invalid/document.json +92 -0
- package/fixtures/atelier-inquiry-contract/handoff/valid/document.json +91 -0
- package/fixtures/atelier-inquiry-contract/hypothesis/invalid/document.json +20 -0
- package/fixtures/atelier-inquiry-contract/hypothesis/valid/document.json +19 -0
- package/fixtures/atelier-inquiry-contract/ledger/invalid/document.json +680 -0
- package/fixtures/atelier-inquiry-contract/ledger/valid/document.json +679 -0
- package/fixtures/atelier-inquiry-contract/legacy-assessment/invalid/document.json +19 -0
- package/fixtures/atelier-inquiry-contract/legacy-assessment/valid/document.json +18 -0
- package/fixtures/atelier-inquiry-contract/request/invalid/document.json +50 -0
- package/fixtures/atelier-inquiry-contract/request/valid/document.json +49 -0
- package/fixtures/atelier-inquiry-contract/source/invalid/document.json +18 -0
- package/fixtures/atelier-inquiry-contract/source/valid/document.json +17 -0
- package/fixtures/atelier-inquiry-contract/withdrawal/invalid/document.json +16 -0
- package/fixtures/atelier-inquiry-contract/withdrawal/valid/document.json +15 -0
- package/fixtures/atelier-instruction-adoption/context-receipt/invalid/document.json +18 -0
- package/fixtures/atelier-instruction-adoption/context-receipt/valid/document.json +17 -0
- package/fixtures/atelier-instruction-adoption/plan/invalid/document.json +63 -0
- package/fixtures/atelier-instruction-adoption/plan/valid/document.json +62 -0
- package/fixtures/atelier-instruction-adoption/receipt/invalid/document.json +22 -0
- package/fixtures/atelier-instruction-adoption/receipt/valid/document.json +21 -0
- package/fixtures/atelier-instruction-adoption/state/invalid/document.json +30 -0
- package/fixtures/atelier-instruction-adoption/state/valid/document.json +29 -0
- package/fixtures/atelier-interaction/act/invalid/document.json +25 -0
- package/fixtures/atelier-interaction/act/valid/document.json +24 -0
- package/fixtures/atelier-interaction/assessment/invalid/document.json +32 -0
- package/fixtures/atelier-interaction/assessment/valid/document.json +31 -0
- package/fixtures/atelier-interaction/observation/invalid/document.json +22 -0
- package/fixtures/atelier-interaction/observation/valid/document.json +21 -0
- package/fixtures/atelier-interaction/policy/invalid/document.json +20 -0
- package/fixtures/atelier-interaction/policy/valid/document.json +19 -0
- package/fixtures/atelier-judgment/case/invalid/document.json +76 -0
- package/fixtures/atelier-judgment/case/valid/document.json +75 -0
- package/fixtures/atelier-judgment/decision/invalid/document.json +38 -0
- package/fixtures/atelier-judgment/decision/valid/document.json +37 -0
- package/fixtures/atelier-judgment/native-decision.md +3 -0
- package/fixtures/atelier-judgment/practice-reconsideration/definition.json +92 -0
- package/fixtures/atelier-judgment/practice-reconsideration/scenario.json +435 -0
- package/fixtures/atelier-knowledge-contract/activation/invalid/document.json +26 -0
- package/fixtures/atelier-knowledge-contract/activation/valid/document.json +25 -0
- package/fixtures/atelier-knowledge-contract/contribution/invalid/document.json +34 -0
- package/fixtures/atelier-knowledge-contract/contribution/valid/document.json +33 -0
- package/fixtures/atelier-knowledge-contract/domain/invalid/document.json +41 -0
- package/fixtures/atelier-knowledge-contract/domain/valid/document.json +40 -0
- package/fixtures/atelier-knowledge-contract/domain-revision/invalid/document.json +46 -0
- package/fixtures/atelier-knowledge-contract/domain-revision/valid/document.json +45 -0
- package/fixtures/atelier-knowledge-contract/evaluation/invalid/document.json +21 -0
- package/fixtures/atelier-knowledge-contract/evaluation/valid/document.json +20 -0
- package/fixtures/atelier-knowledge-contract/ledger/invalid/document.json +318 -0
- package/fixtures/atelier-knowledge-contract/ledger/valid/document.json +317 -0
- package/fixtures/atelier-knowledge-contract/relation/invalid/document.json +25 -0
- package/fixtures/atelier-knowledge-contract/relation/valid/document.json +24 -0
- package/fixtures/atelier-knowledge-contract/review/invalid/document.json +18 -0
- package/fixtures/atelier-knowledge-contract/review/valid/document.json +17 -0
- package/fixtures/atelier-knowledge-contract/withdrawal/invalid/document.json +16 -0
- package/fixtures/atelier-knowledge-contract/withdrawal/valid/document.json +15 -0
- package/fixtures/atelier-learning/invalid/authority.json +14 -0
- package/fixtures/atelier-learning/valid/capture.json +13 -0
- package/fixtures/atelier-personal-workspace-contract/manifest/invalid/authority-key.json +17 -0
- package/fixtures/atelier-personal-workspace-contract/manifest/invalid/nonempty-ext.json +25 -0
- package/fixtures/atelier-personal-workspace-contract/manifest/invalid/wrong-schema.json +22 -0
- package/fixtures/atelier-personal-workspace-contract/manifest/valid/manifest.json +22 -0
- package/fixtures/atelier-personal-workspace-contract/overlay/invalid/authority-key.json +25 -0
- package/fixtures/atelier-personal-workspace-contract/overlay/invalid/unknown-top-level-field.json +27 -0
- package/fixtures/atelier-personal-workspace-contract/overlay/invalid/wrong-schema.json +24 -0
- package/fixtures/atelier-trackable/definition/invalid/document.json +15 -0
- package/fixtures/atelier-trackable/definition/valid/document.json +14 -0
- package/fixtures/atelier-trackable/request/invalid/document.json +23 -0
- package/fixtures/atelier-trackable/request/valid/document.json +22 -0
- package/fixtures/boundary-delegations/invalid/authority-key.v1.json +30 -0
- package/fixtures/boundary-delegations/invalid/push-operation.v1.json +28 -0
- package/fixtures/boundary-delegations/invalid/unsigned.v1.json +25 -0
- package/fixtures/boundary-delegations/valid/empty.v1.json +4 -0
- package/fixtures/boundary-delegations/valid/signed-operator.v1.json +30 -0
- package/fixtures/boundary-owner-keys/invalid/wrong-algorithm.v1.json +15 -0
- package/fixtures/boundary-owner-keys/invalid/wrong-curve.v1.json +15 -0
- package/fixtures/boundary-owner-keys/valid/one-owner.v1.json +17 -0
- package/fixtures/capability-packages/adoption.example.json +70 -0
- package/fixtures/capability-packages/evidence-review/capability-package.json +58 -0
- package/fixtures/capability-packages/evidence-review/capability-release.json +84 -0
- package/fixtures/capability-packages/evidence-review/evaluation.md +15 -0
- package/fixtures/capability-packages/evidence-review/skills/evidence-review/SKILL.md +22 -0
- package/fixtures/capability-packages/evidence-review/skills/evidence-review/references/ledger.md +7 -0
- package/fixtures/capability-packages/research/capability-package.json +88 -0
- package/fixtures/capability-packages/research/capability-release.json +134 -0
- package/fixtures/capability-packages/research/evaluation.md +15 -0
- package/fixtures/capability-packages/research/skills/research-integrate/SKILL.md +29 -0
- package/fixtures/capability-packages/research/skills/research-integrate/references/integration.md +10 -0
- package/fixtures/capability-packages/research/skills/research-plan/SKILL.md +27 -0
- package/fixtures/capability-packages/research/skills/research-plan/references/inquiries.md +26 -0
- package/fixtures/capability-packages/research/skills/research-synthesize/SKILL.md +23 -0
- package/fixtures/capability-packages/research/skills/research-synthesize/references/synthesis.md +12 -0
- package/fixtures/evidence-navigation/invalid/duplicate-operation.json +16 -0
- package/fixtures/evidence-navigation/invalid/instruction-kind.json +36 -0
- package/fixtures/evidence-navigation/invalid/invalid-digest.json +36 -0
- package/fixtures/evidence-navigation/invalid/invalid-time.json +36 -0
- package/fixtures/evidence-navigation/invalid/missing-attribution.json +35 -0
- package/fixtures/evidence-navigation/invalid/reserved-extension.json +19 -0
- package/fixtures/evidence-navigation/invalid/unattributed-acceptance.json +36 -0
- package/fixtures/evidence-navigation/invalid/uncoerced-version.json +16 -0
- package/fixtures/evidence-navigation/invalid/unknown-currency.json +17 -0
- package/fixtures/evidence-navigation/invalid/unknown-selector-field.json +37 -0
- package/fixtures/evidence-navigation/invalid/unsupported-operation.json +15 -0
- package/fixtures/evidence-navigation/valid/claim.json +36 -0
- package/fixtures/evidence-navigation/valid/host.json +16 -0
- package/fixtures/evidence-navigation/valid/profile.json +16 -0
- package/fixtures/evidence-navigation/valid/snapshot.json +17 -0
- package/fixtures/harness-packages/build-harness/capability-package.json +61 -0
- package/fixtures/harness-packages/build-harness/capability-release.json +82 -0
- package/fixtures/harness-packages/build-harness/evaluation.md +3 -0
- package/fixtures/harness-packages/build-harness/skills/atelier-build-harness/SKILL.md +59 -0
- package/fixtures/harness-packages/knowledge-harness/capability-package.json +61 -0
- package/fixtures/harness-packages/knowledge-harness/capability-release.json +82 -0
- package/fixtures/harness-packages/knowledge-harness/evaluation.md +3 -0
- package/fixtures/harness-packages/knowledge-harness/skills/atelier-knowledge-harness/SKILL.md +60 -0
- package/fixtures/harnesses/learning-cycle.json +780 -0
- package/fixtures/inquiry/workshop.json +675 -0
- package/fixtures/inquiry-packages/discovery-harness/capability-package.json +61 -0
- package/fixtures/inquiry-packages/discovery-harness/capability-release.json +82 -0
- package/fixtures/inquiry-packages/discovery-harness/evaluation.md +3 -0
- package/fixtures/inquiry-packages/discovery-harness/skills/atelier-discovery-harness/SKILL.md +48 -0
- package/fixtures/inquiry-packages/research-harness/capability-package.json +61 -0
- package/fixtures/inquiry-packages/research-harness/capability-release.json +82 -0
- package/fixtures/inquiry-packages/research-harness/evaluation.md +3 -0
- package/fixtures/inquiry-packages/research-harness/skills/atelier-research-harness/SKILL.md +43 -0
- package/fixtures/knowledge-health/calibration-suite.json +26 -0
- package/fixtures/knowledge-health/calibration-trial.json +37 -0
- package/fixtures/knowledge-health/corrected/checklist.md +18 -0
- package/fixtures/knowledge-health/devday/participant-record.json +19 -0
- package/fixtures/knowledge-health/expected-summary.json +27 -0
- package/fixtures/knowledge-health/workshop/README.md +20 -0
- package/fixtures/knowledge-health/workshop/atelier.project.json +7 -0
- package/fixtures/knowledge-health/workshop/knowledge-plan.json +65 -0
- package/fixtures/knowledge-health/workshop/records/checklist.md +18 -0
- package/fixtures/knowledge-health/workshop/records/workshop.md +18 -0
- package/fixtures/knowledge-health/workshop/repo-access.v1.json +5 -0
- package/fixtures/knowledge-health/workspace/atelier.project.json +18 -0
- package/fixtures/knowledge-health/workspace/knowledge-plan.json +74 -0
- package/fixtures/knowledge-health/workspace/records/checklist.md +18 -0
- package/fixtures/knowledge-health/workspace/records/pilot.md +16 -0
- package/fixtures/knowledge-health/workspace/repo-access.v1.json +9 -0
- package/fixtures/personal-workspace/overlay.json +24 -0
- package/fixtures/templates/local-library.v1.json +75 -0
- package/fixtures/templates/upgrade-contracts/adoption-policy.v2/invalid.json +16 -0
- package/fixtures/templates/upgrade-contracts/adoption-policy.v2/valid.json +13 -0
- package/fixtures/templates/upgrade-contracts/migration.v3/invalid.json +24 -0
- package/fixtures/templates/upgrade-contracts/migration.v3/valid.json +21 -0
- package/fixtures/templates/upgrade-contracts/template-adoption.v1/invalid.json +60 -0
- package/fixtures/templates/upgrade-contracts/template-adoption.v1/valid.json +57 -0
- package/fixtures/templates/upgrade-contracts/upgrade-plan.v3/invalid.json +85 -0
- package/fixtures/templates/upgrade-contracts/upgrade-plan.v3/valid.json +82 -0
- package/package.json +59 -5
- package/skills/claude/atelier-build-harness/SKILL.md +59 -0
- package/skills/claude/atelier-coordination/SKILL.md +32 -0
- package/skills/claude/atelier-discovery-harness/SKILL.md +48 -0
- package/skills/claude/atelier-guided-upgrade/SKILL.md +29 -0
- package/skills/claude/atelier-interaction/SKILL.md +34 -0
- package/skills/claude/atelier-knowledge-harness/SKILL.md +60 -0
- package/skills/claude/atelier-knowledge-setup/SKILL.md +72 -0
- package/skills/claude/atelier-practical-judgment/SKILL.md +64 -0
- package/skills/claude/atelier-research-harness/SKILL.md +43 -0
- package/skills/claude/atelier-skill-steward/SKILL.md +53 -0
- package/skills/claude/atelier-trackables/SKILL.md +40 -0
- package/skills/codex/atelier-build-harness/SKILL.md +59 -0
- package/skills/codex/atelier-coordination/SKILL.md +32 -0
- package/skills/codex/atelier-discovery-harness/SKILL.md +48 -0
- package/skills/codex/atelier-guided-upgrade/SKILL.md +29 -0
- package/skills/codex/atelier-interaction/SKILL.md +34 -0
- package/skills/codex/atelier-knowledge-harness/SKILL.md +60 -0
- package/skills/codex/atelier-knowledge-setup/SKILL.md +72 -0
- package/skills/codex/atelier-practical-judgment/SKILL.md +64 -0
- package/skills/codex/atelier-research-harness/SKILL.md +43 -0
- package/skills/codex/atelier-skill-steward/SKILL.md +53 -0
- package/skills/codex/atelier-trackables/SKILL.md +40 -0
- package/src/architecture/catalog.mjs +355 -0
- package/src/architecture/index.mjs +93 -0
- package/src/boundary/content-rules.mjs +4 -2
- package/src/boundary/delegation-command.mjs +158 -0
- package/src/boundary/delegation.mjs +396 -0
- package/src/boundary/policy.mjs +52 -10
- package/src/build/git.mjs +18 -0
- package/src/build/index.mjs +3 -0
- package/src/build/ledger.mjs +88 -0
- package/src/capabilities/adoption.mjs +381 -0
- package/src/capabilities/evidence.mjs +140 -0
- package/src/capabilities/files.mjs +124 -0
- package/src/capabilities/index.mjs +4 -0
- package/src/capabilities/instructions.mjs +250 -0
- package/src/capabilities/package.mjs +136 -0
- package/src/cli/command-failure.mjs +36 -0
- package/src/cli/execute-command.mjs +16 -2
- package/src/cli/run.mjs +65 -9
- package/src/coauthor/store.mjs +43 -2
- package/src/collaboration/proposals.mjs +189 -0
- package/src/commands/architecture.mjs +27 -0
- package/src/commands/boundary.mjs +3 -0
- package/src/commands/capability.mjs +73 -0
- package/src/commands/enroll.mjs +3 -0
- package/src/commands/harness.mjs +79 -0
- package/src/commands/ingest.mjs +39 -0
- package/src/commands/init.mjs +4 -1
- package/src/commands/inquiry.mjs +66 -0
- package/src/commands/knowledge-semantic.mjs +128 -0
- package/src/commands/knowledge.mjs +119 -0
- package/src/commands/learn.mjs +61 -0
- package/src/commands/obsidian.mjs +754 -63
- package/src/commands/practice.mjs +24 -0
- package/src/commands/setup.mjs +22 -2
- package/src/commands/trackable.mjs +19 -0
- package/src/contracts/corpus.mjs +30 -0
- package/src/coordination/index.mjs +110 -0
- package/src/evidence-navigation/contracts.mjs +60 -0
- package/src/evidence-navigation/evaluate.mjs +69 -0
- package/src/evidence-navigation/generation.mjs +22 -0
- package/src/evidence-navigation/index.mjs +2 -0
- package/src/evidence-navigation/local.mjs +167 -0
- package/src/evidence-navigation/schema.generated.mjs +604 -0
- package/src/evidence-navigation/types.mjs +12 -0
- package/src/export/atelier-export-contract.mjs +35 -8
- package/src/graph/enroll.mjs +248 -0
- package/src/graph/graph.mjs +17 -1
- package/src/graph/knowledge-graph.mjs +58 -8
- package/src/harnesses/contracts.mjs +41 -0
- package/src/harnesses/exchange.mjs +154 -0
- package/src/harnesses/feedback.mjs +16 -0
- package/src/harnesses/history.mjs +37 -0
- package/src/harnesses/index.mjs +4 -0
- package/src/harnesses/store.mjs +29 -0
- package/src/ingestion/contracts.mjs +41 -0
- package/src/ingestion/evaluation.mjs +119 -0
- package/src/ingestion/optional/composition/index.mjs +171 -0
- package/src/ingestion/optional/evaluation/index.mjs +219 -0
- package/src/ingestion/optional/graphify/composition-binding.mjs +60 -0
- package/src/ingestion/optional/graphify/composition_receiving.py +185 -0
- package/src/ingestion/optional/graphify/graphify_supplier.py +933 -0
- package/src/ingestion/optional/graphify/json_bridge.py +163 -0
- package/src/ingestion/optional/graphify/query_receiving.py +209 -0
- package/src/ingestion/optional/index.mjs +9 -0
- package/src/ingestion/optional/jev/bridge.mjs +166 -0
- package/src/ingestion/optional/jev/composition-binding.mjs +116 -0
- package/src/ingestion/optional/jev/judgments.mjs +174 -0
- package/src/ingestion/optional/jev/native-translation.mjs +32 -0
- package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/__init__.py +7 -0
- package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/adapter.py +966 -0
- package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/artifacts.py +101 -0
- package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/projection.py +146 -0
- package/src/ingestion/optional/lightrag/composition-binding.mjs +67 -0
- package/src/ingestion/optional/vanilla/composition-binding.mjs +102 -0
- package/src/ingestion/optional/vanilla/index.mjs +218 -0
- package/src/ingestion/optional/vanilla/native-normalization.mjs +187 -0
- package/src/ingestion/processors.mjs +218 -0
- package/src/ingestion/semantic.mjs +203 -0
- package/src/ingestion/store.mjs +372 -0
- package/src/inquiry/beliefs.mjs +32 -0
- package/src/inquiry/contracts.mjs +23 -0
- package/src/inquiry/index.mjs +5 -0
- package/src/inquiry/ledger.mjs +135 -0
- package/src/inquiry/lenses.mjs +15 -0
- package/src/inquiry/projection.mjs +77 -0
- package/src/inquiry/store.mjs +35 -0
- package/src/intake/read-scope.mjs +12 -0
- package/src/intake/store.mjs +69 -6
- package/src/interaction/index.mjs +91 -0
- package/src/judgment/index.mjs +82 -0
- package/src/judgment/practice-evaluation.mjs +70 -0
- package/src/judgment/practice.mjs +144 -0
- package/src/knowledge/context.mjs +217 -0
- package/src/knowledge/index.mjs +5 -0
- package/src/knowledge/ingestion.mjs +79 -0
- package/src/knowledge/intake.mjs +33 -0
- package/src/knowledge/ledger.mjs +110 -0
- package/src/knowledge/participatory/guidance.mjs +36 -0
- package/src/knowledge/participatory/guided-contribution.mjs +44 -0
- package/src/knowledge/participatory/index.mjs +2 -0
- package/src/knowledge/participatory/installed-workshop.mjs +108 -0
- package/src/knowledge/plan.mjs +67 -0
- package/src/knowledge/projection.mjs +43 -0
- package/src/knowledge/semantic-operation.mjs +567 -0
- package/src/knowledge/sessions.mjs +467 -0
- package/src/knowledge/workspace.mjs +295 -0
- package/src/knowledge-health/assessment.mjs +165 -0
- package/src/knowledge-health/capabilities.mjs +350 -0
- package/src/knowledge-health/context.mjs +62 -0
- package/src/knowledge-health/example.mjs +47 -0
- package/src/knowledge-health/index.mjs +10 -0
- package/src/knowledge-health/owner-join.mjs +88 -0
- package/src/knowledge-health/proof/common.mjs +24 -0
- package/src/knowledge-health/proof/installed-check.mjs +100 -0
- package/src/knowledge-health/proof/native-readback.mjs +37 -0
- package/src/knowledge-health/proof/rehearse.mjs +68 -0
- package/src/knowledge-health/proof/validate-participant.mjs +17 -0
- package/src/knowledge-health/proof/verify-native-capture.mjs +14 -0
- package/src/knowledge-health/proof/workshop-check.mjs +36 -0
- package/src/knowledge-health/rule-identity.mjs +44 -0
- package/src/knowledge-health/workshop-composition.mjs +19 -0
- package/src/knowledge-health/workshop-profile.mjs +176 -0
- package/src/knowledge-health/workshop.mjs +99 -0
- package/src/learning/adapters.mjs +68 -0
- package/src/learning/assistance.mjs +127 -0
- package/src/learning/contracts.mjs +65 -0
- package/src/learning/store.mjs +272 -0
- package/src/personal-workspace/index.mjs +391 -0
- package/src/personal-workspace/selection.mjs +385 -0
- package/src/project/config.mjs +8 -0
- package/src/project/durable-state.mjs +3 -1
- package/src/project/file-class.mjs +1 -1
- package/src/projection/obsidian/edits/apply.mjs +55 -16
- package/src/projection/obsidian/personal-workspace.mjs +436 -0
- package/src/projection/obsidian/proposals/adapter.mjs +47 -8
- package/src/projection/obsidian/proposals/observation.mjs +10 -2
- package/src/projection/obsidian/publication/publisher.mjs +142 -13
- package/src/projection/obsidian/publication/vault-list.mjs +4 -3
- package/src/projection/obsidian/recovery/index.mjs +4 -1
- package/src/projection/obsidian/recovery/store.mjs +160 -7
- package/src/projection/obsidian/selection-ui/contribution.mjs +6 -5
- package/src/readiness/readiness.mjs +10 -3
- package/src/reflection/index.mjs +56 -0
- package/src/runtime/obsidian/app-production-seams.mjs +48 -16
- package/src/runtime/obsidian/app-registration.mjs +175 -28
- package/src/runtime/obsidian/app-restart.mjs +154 -0
- package/src/runtime/obsidian/engine.mjs +163 -20
- package/src/runtime/obsidian/extension-points.mjs +1 -1
- package/src/runtime/obsidian/index.mjs +10 -7
- package/src/runtime/obsidian/launch-plan.mjs +7 -4
- package/src/runtime/obsidian/lifecycle.mjs +92 -12
- package/src/runtime/obsidian/login-item.mjs +332 -0
- package/src/runtime/obsidian/machine-settings.mjs +119 -12
- package/src/runtime/obsidian/opening.mjs +171 -37
- package/src/runtime/obsidian/pipeline.mjs +71 -3
- package/src/runtime/obsidian/plugin-channel.mjs +11 -3
- package/src/runtime/obsidian/plugin-choice.mjs +16 -4
- package/src/runtime/obsidian/plugin-drift.mjs +59 -11
- package/src/runtime/obsidian/plugin-presence.mjs +14 -1
- package/src/runtime/obsidian/process-identity.mjs +20 -10
- package/src/runtime/obsidian/project-views.mjs +282 -0
- package/src/runtime/obsidian/questions.mjs +48 -0
- package/src/runtime/obsidian/release-watch.mjs +56 -0
- package/src/runtime/obsidian/service-main.mjs +99 -16
- package/src/runtime/obsidian/service-manager-production.mjs +61 -0
- package/src/runtime/obsidian/service-managers.mjs +275 -0
- package/src/runtime/obsidian/service-record.mjs +87 -23
- package/src/runtime/obsidian/service.mjs +36 -3
- package/src/runtime/obsidian/startup-adapters.mjs +59 -21
- package/src/runtime/obsidian/unheld-evidence.mjs +84 -0
- package/src/runtime/obsidian/vault-location.mjs +300 -0
- package/src/runtime/obsidian/view-counts.mjs +34 -0
- package/src/server/local-sidecar.mjs +169 -2
- package/src/server/server.mjs +28 -2
- package/src/template-bindings/project.mjs +92 -0
- package/src/templates/profile.mjs +225 -0
- package/src/trackables/domain.mjs +175 -0
- package/src/trackables/store.mjs +114 -0
- package/src/ui/knowledge-page.mjs +1388 -0
- package/src/upgrade/explanation.mjs +1 -1
- package/src/upgrade/template-participant.mjs +171 -0
- package/src/upgrade/transaction.mjs +72 -25
- package/src/upgrade/upgrade.mjs +1 -0
- package/templates/external-project-workspace/pack-lifecycle.json +6 -1
- package/templates/knowledge-workspace/.gitattributes +2 -0
- package/templates/knowledge-workspace/AGENTS.md +27 -0
- package/templates/knowledge-workspace/README.md +44 -0
- package/templates/knowledge-workspace/atelier.project.json +22 -0
- package/templates/knowledge-workspace/gitignore +6 -0
- package/templates/knowledge-workspace/knowledge-plan.json +111 -0
- package/templates/knowledge-workspace/knowledge-plan.schema.json +281 -0
- package/templates/knowledge-workspace/records/forecast.md +22 -0
- package/templates/knowledge-workspace/records/inspection.md +25 -0
- package/templates/knowledge-workspace/records/telescope.md +24 -0
- package/templates/knowledge-workspace/repo-access.v1.json +9 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import assert from 'node:assert/strict';
|
|
4
|
+
import {createHash} from 'node:crypto';
|
|
5
|
+
import {spawnSync} from 'node:child_process';
|
|
6
|
+
import {fileURLToPath} from 'node:url';
|
|
7
|
+
import {verifyNativeReadback} from './native-readback.mjs';
|
|
8
|
+
import {checkInstalledWorkshop} from './workshop-check.mjs';
|
|
9
|
+
const root=process.cwd(),packageRoot=path.join(root,'node_modules/@mnstry/atelier'),pkg=JSON.parse(fs.readFileSync(path.join(packageRoot,'package.json'),'utf8')),profile=JSON.parse(fs.readFileSync(process.argv[2],'utf8'));
|
|
10
|
+
const digest=b=>createHash('sha256').update(b).digest('hex'),cases=[],commands=[],gaps=[];
|
|
11
|
+
function cli(args,{cwd=root,input,accept=[0]}={}){
|
|
12
|
+
const bin=typeof pkg.bin==='string'?pkg.bin:pkg.bin.atelier;assert.ok(bin,'Declared atelier bin required');const full=path.resolve(packageRoot,bin);assert.ok(full.startsWith(packageRoot+path.sep));
|
|
13
|
+
const o=spawnSync(process.execPath,[full,...args],{cwd,input,encoding:'utf8',timeout:30000,maxBuffer:2*1024*1024});const observed={args,status:o.status,signal:o.signal,stdout:o.stdout??'',stderr:o.stderr??''};commands.push(observed);assert.ok(accept.includes(o.status),JSON.stringify(observed));return observed;
|
|
14
|
+
}
|
|
15
|
+
function gap(id,action){const e=Error(action);e.actionableGap=true;e.gap={id,owner:'Foundation through Reliability and existing KH/AW source owners',action};throw e;}
|
|
16
|
+
async function scenario(id,fn){if(profile.onlyChecks&&!profile.onlyChecks.includes(id))return;try{cases.push({id,status:'passed',observations:await fn()});}catch(e){if(e.actionableGap){gaps.push(e.gap);cases.push({id,status:'actionable-gap',gap:e.gap});}else cases.push({id,status:'failed',error:{name:e.name,message:e.message,stack:e.stack}});}}
|
|
17
|
+
await scenario('declared-exports',async()=>{
|
|
18
|
+
const resolved=[];
|
|
19
|
+
for(const [subpath] of Object.entries(pkg.exports)){
|
|
20
|
+
if(subpath.includes('*')){gaps.push({id:'wildcard-export-enumeration',owner:'Foundation',action:'Provide exact wildcard sample subpaths in release receiving'});continue;}
|
|
21
|
+
const specifier=subpath==='.'?pkg.name:pkg.name+'/'+subpath.slice(2),url=import.meta.resolve(specifier),file=fileURLToPath(url);assert.ok(fs.realpathSync(file).startsWith(fs.realpathSync(packageRoot)+path.sep));
|
|
22
|
+
const b=fs.readFileSync(file);if(file.endsWith('.json'))JSON.parse(b);else await import(specifier);resolved.push({specifier,relativePath:path.relative(packageRoot,file),sha256:digest(b)});
|
|
23
|
+
}
|
|
24
|
+
return {resolved,count:resolved.length};
|
|
25
|
+
});
|
|
26
|
+
await scenario('declared-bin-and-help',async()=>{assert.equal(cli(['--version']).stdout.trim(),pkg.version);return {version:pkg.version,help:cli(['--help']).stdout};});
|
|
27
|
+
await scenario('public-quickstart',async()=>{
|
|
28
|
+
assert.equal(process.platform,'darwin','The published shell sequence is qualified here only on macOS');
|
|
29
|
+
const bin=path.join(root,'node_modules/.bin/atelier');assert.equal(fs.realpathSync(bin),fs.realpathSync(path.resolve(packageRoot,pkg.bin.atelier)));
|
|
30
|
+
const shellBin=(args,cwd=root)=>{const o=spawnSync(bin,args,{cwd,encoding:'utf8',timeout:30000,maxBuffer:2*1024*1024});const observed={invocation:'installed npm bin symlink',args,status:o.status,signal:o.signal,stdout:o.stdout??'',stderr:o.stderr??''};commands.push(observed);assert.equal(o.status,0,JSON.stringify(observed));return observed;};
|
|
31
|
+
assert.equal(shellBin(['--version']).stdout.trim(),pkg.version);
|
|
32
|
+
const init=shellBin(['init','--template','sample-workspace','--target','example']),workspace=path.join(root,'example');
|
|
33
|
+
return {init,graph:shellBin(['graph'],workspace),project:shellBin(['project'],workspace),scope:'Exact macOS public quickstart command sequence, supported baseline only'};
|
|
34
|
+
});
|
|
35
|
+
await scenario('installed-document-references',async()=>{
|
|
36
|
+
const references=['README.md','docs/knowledge-graph.md','docs/coauthor-session.md'];
|
|
37
|
+
const documents=references.map(relativePath=>{const file=fs.realpathSync(path.join(packageRoot,relativePath));assert.ok(file.startsWith(fs.realpathSync(packageRoot)+path.sep));const bytes=fs.readFileSync(file);return {relativePath,bytes:bytes.length,sha256:digest(bytes)};});
|
|
38
|
+
for(const subpath of ['./graph','./project','./coauthor']){assert.ok(pkg.exports[subpath]);await import(pkg.name+'/'+subpath.slice(2));}
|
|
39
|
+
return {documents,apiReferences:['@mnstry/atelier/graph','@mnstry/atelier/project','@mnstry/atelier/coauthor'],scope:'Public quickstart references resolve in the actual installed package'};
|
|
40
|
+
});
|
|
41
|
+
await scenario('public-export-fixture',async()=>{const api=await import('@mnstry/atelier'),file=fileURLToPath(import.meta.resolve('@mnstry/atelier/fixtures/atelier-export/sample-studio-offer.v1.json')),value=JSON.parse(fs.readFileSync(file));const report=api.validateAtelierExportDryRun(value);assert.equal(report.accepted,true);assert.equal(report.importable,false);return {fixturePath:path.relative(packageRoot,file),report};});
|
|
42
|
+
await scenario('installed-coauthor-save-reopen-and-drift',async()=>{
|
|
43
|
+
// Reuses the established Foundation coauthor consumer smoke's CLI sequence,
|
|
44
|
+
// with only the declared bin and public invented consumer source.
|
|
45
|
+
const workspace=path.join(root,'coauthor-example');fs.mkdirSync(workspace);assert.equal(spawnSync('git',['init','--quiet',workspace]).status,0);fs.writeFileSync(path.join(workspace,'.gitignore'),'.atelier-local/\n');
|
|
46
|
+
const source='An invented authoring packet.\n',sourceFile=path.join(workspace,'packet.md');fs.writeFileSync(sourceFile,source);
|
|
47
|
+
const good=(op,input)=>JSON.parse(cli(['coauthor',op],{cwd:workspace,input:JSON.stringify(input)}).stdout).state;
|
|
48
|
+
const config={id:'public-devday-baseline',fields:[{id:'example-answer',source:{ref:'packet.md',digest:digest(source)}}]};
|
|
49
|
+
const initial=good('start',{config}),answer=good('event',{sessionId:config.id,event:{id:'original-answer',expectedRevision:0,type:'answer',text:'Fixture participant: please preserve these original words.'}}),saved=good('event',{sessionId:config.id,event:{id:'save-original',expectedRevision:1,type:'save'}});assert.equal(saved.phase,'saved');
|
|
50
|
+
const reopened=good('read',{sessionId:config.id});assert.deepEqual(reopened,saved);assert.equal(fs.readFileSync(sourceFile,'utf8'),source);
|
|
51
|
+
const stale=cli(['coauthor','event'],{cwd:workspace,input:JSON.stringify({sessionId:config.id,event:{id:'stale',expectedRevision:0,type:'advance'}}),accept:[1]});
|
|
52
|
+
fs.writeFileSync(sourceFile,'Fixture revised source.\n');const drift=cli(['coauthor','event'],{cwd:workspace,input:JSON.stringify({sessionId:config.id,event:{id:'drift',expectedRevision:saved.revision,type:'advance'}}),accept:[1]});assert.deepEqual(good('read',{sessionId:config.id}),saved);
|
|
53
|
+
return {initial,answer,saved,reopened,stale,drift,sourceOwnerApplication:false,nativeWorkbench:false};
|
|
54
|
+
});
|
|
55
|
+
await scenario('installed-knowledge-example-and-agent-output',async()=>{
|
|
56
|
+
if(!pkg.exports['./knowledge']||!profile.knowledgeExample)gap('installed-knowledge-health-example','Published package lacks the required declared knowledge API or source-owner-bound normal example entry. Supply exact Dev Day release and knowledgeExample template/command bindings.');
|
|
57
|
+
const workspace=path.join(root,'knowledge-example'),init=cli(['init','--template',profile.knowledgeExample.template,'--target',workspace]);
|
|
58
|
+
const binding=profile.knowledgeExample;
|
|
59
|
+
for(const key of ['graphArgs','checkArgs','contextArgs'])assert.ok(Array.isArray(binding[key])&&binding[key].length,'Source owner must bind actual installed CLI arguments: '+key);
|
|
60
|
+
const graph=cli(binding.graphArgs,{cwd:workspace}),check=cli(binding.checkArgs,{cwd:workspace}),context=cli(binding.contextArgs,{cwd:workspace});
|
|
61
|
+
// Results are raw real package observations. Semantic applicability and human
|
|
62
|
+
// understanding are not inferred from successful subprocess exits.
|
|
63
|
+
assert.ok(graph.stdout.length+graph.stderr.length>0);assert.ok(check.stdout.length+check.stderr.length>0);assert.ok(context.stdout.length+context.stderr.length>0);
|
|
64
|
+
return {init,graph,check,context,scope:'Actual published invented template and installed CLI; raw statuses retained, no Dev Day guided-journey pass inferred.'};
|
|
65
|
+
});
|
|
66
|
+
await scenario('installed-public-graph-project-baseline',async()=>{
|
|
67
|
+
const workspace=path.join(root,'public-graph-example'),init=cli(['init','--template','sample-workspace','--target',workspace]);
|
|
68
|
+
const graphCommand=cli(['graph'],{cwd:workspace}),projectCommand=cli(['project'],{cwd:workspace});
|
|
69
|
+
const graphApi=await import('@mnstry/atelier/graph'),projectApi=await import('@mnstry/atelier/project');
|
|
70
|
+
if(typeof graphApi.buildCanonicalGraph!=='function'||typeof projectApi.resolveProjectConfig!=='function')gap('graph-agent-api-binding','Source owner must bind actual declared graph/project API names for this version.');
|
|
71
|
+
const project=projectApi.resolveProjectConfig({cwd:workspace,argv:['--project',path.join(workspace,'atelier.project.json')]}),graph=graphApi.buildCanonicalGraph(project);
|
|
72
|
+
assert.ok(Array.isArray(graph.nodes));assert.ok(Array.isArray(graph.edges));assert.ok(Array.isArray(graph.errors));assert.equal(graph.errors.length,0);
|
|
73
|
+
return {init,graphCommand,projectCommand,graph,agentCIOutput:'Actual machine-readable canonical graph; structural evidence only, no model/provider or semantic acceptance.'};
|
|
74
|
+
});
|
|
75
|
+
const docs=[];for(const candidate of ['README.md','docs/knowledge.md','docs/coauthor.md','docs/coauthor-session.md','docs/upgrade.md','docs/graph.md','docs/knowledge-graph.md','docs/release-engineering.md']){const full=path.join(packageRoot,candidate);if(fs.existsSync(full)){const b=fs.readFileSync(full);docs.push({path:candidate,sha256:digest(b),bytes:b.length});}}
|
|
76
|
+
for(const id of ['assessment-to-guided-authoring','full-native-finding-reference','preview-owning-source-correction-readback-reassessment','keyboard-focus-undo','native-withdrawal-recovery','participant-usefulness'])gaps.push({id,owner:id==='participant-usefulness'?'Facilitator/participant':'Foundation and existing AW Integration/Journey',action:'Receive exact public Dev Day installed entry/bindings and native allocation; inherited native or fixture proof cannot satisfy installed or human evidence.'});
|
|
77
|
+
const bindings=profile.deliveryBindings;
|
|
78
|
+
if(bindings){
|
|
79
|
+
await scenario('owner-installed-journey',async()=>{
|
|
80
|
+
assert.ok(pkg.exports[bindings.exportSubpath],'Journey must use a declared package export');const specifier=bindings.exportSubpath==='.'?pkg.name:pkg.name+'/'+bindings.exportSubpath.slice(2),api=await import(specifier);assert.equal(typeof api[bindings.functionName],'function');
|
|
81
|
+
const output=await api[bindings.functionName]({...bindings.publicInput,consumerRoot:root,publicInventedOnly:true,participantAssertions:'fixture'});
|
|
82
|
+
assert.equal(output.packageVersion,pkg.version);assert.ok(Array.isArray(output.steps));
|
|
83
|
+
const required=['assessment','evidence-orientation','original-contribution','interpretation-disagreement-perspective-pause','preview','owner-correction','exact-readback','reopen-reassessment'];
|
|
84
|
+
for(const id of required){const step=output.steps.find(s=>s.id===id);assert.ok(step,'Missing installed step '+id);assert.equal(step.status,'passed');assert.ok(step.evidence,'Independent command/readback evidence required for '+id);}
|
|
85
|
+
assert.equal(output.humanAcceptance,false);
|
|
86
|
+
if(!bindings.nativeExportSubpath||!pkg.exports[bindings.nativeExportSubpath])gap('installed-native-draft-export','Source owner must expose the actual received native Drafts API as a declared export for independent readback.');
|
|
87
|
+
const nativeSpecifier=bindings.nativeExportSubpath==='.'?pkg.name:pkg.name+'/'+bindings.nativeExportSubpath.slice(2),draft=await import(nativeSpecifier);
|
|
88
|
+
const nativeReadback=verifyNativeReadback(draft,output.nativeCapture,root);
|
|
89
|
+
if(!bindings.reassessmentExportSubpath||!pkg.exports[bindings.reassessmentExportSubpath])gap('independent-installed-reassessment','Source owner must bind an actual declared reassessment export for independent current-source evaluation.');
|
|
90
|
+
const reassessmentSpecifier=bindings.reassessmentExportSubpath==='.'?pkg.name:pkg.name+'/'+bindings.reassessmentExportSubpath.slice(2),assessor=await import(reassessmentSpecifier);assert.equal(typeof assessor[bindings.reassessmentFunctionName],'function');
|
|
91
|
+
const reassessed=await assessor[bindings.reassessmentFunctionName]({...bindings.publicInput,consumerRoot:root,workspaceRelative:output.nativeCapture.workspaceRelative,publicInventedOnly:true});
|
|
92
|
+
assert.deepEqual(reassessed,output.reassessment);assert.equal(reassessed.currency,'current');
|
|
93
|
+
return {output,nativeReadback,independentReassessment:reassessed,scope:'Installed runner plus independent native API/file readback and reassessment; rendered collector/verifier and human protocol remain separate'};
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
await scenario('aw-installed-workshop',()=>checkInstalledWorkshop({pkg,root,profile,gap}));
|
|
97
|
+
const deliveryQualified=false; // Never promote an installed runner's own claims to native/human acceptance.
|
|
98
|
+
const installedMachineJourneyQualified=cases.some(c=>c.id==='owner-installed-journey'&&c.status==='passed');
|
|
99
|
+
process.stdout.write(JSON.stringify({package:{name:pkg.name,version:pkg.version},selectedChecks:profile.onlyChecks??'all',cases,commands,docs,gaps,counts:{passed:cases.filter(c=>c.status==='passed').length,failed:cases.filter(c=>c.status==='failed').length,actionableGaps:cases.filter(c=>c.status==='actionable-gap').length},installedMachineJourneyQualified,deliveryQualified,humanAcceptance:false,nativeCaptureRequired:true,ownerBindingsSupplied:!!bindings})+'\n');
|
|
100
|
+
if(cases.some(c=>c.status==='failed'))process.exitCode=1;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import assert from 'node:assert/strict';
|
|
4
|
+
import {createHash} from 'node:crypto';
|
|
5
|
+
const sha=b=>createHash('sha256').update(b).digest('hex');
|
|
6
|
+
// These are the already received Drafts v1 command/v2 disposition identities.
|
|
7
|
+
// The release owner must expose the actual native supplier as a declared export.
|
|
8
|
+
// This verifier adds no store, model, application route or accepted canonical.
|
|
9
|
+
export function verifyNativeReadback(draft,capture,consumerRoot){
|
|
10
|
+
assert.equal(draft.DISPOSITION_VERSION,'authoring-workbench.contribution-disposition/v2');
|
|
11
|
+
assert.ok(capture&&capture.workspaceRelative&&capture.sourceRelative);
|
|
12
|
+
assert.equal(path.isAbsolute(capture.workspaceRelative),false);assert.equal(path.isAbsolute(capture.sourceRelative),false);
|
|
13
|
+
const root=fs.realpathSync(path.resolve(consumerRoot,capture.workspaceRelative));assert.ok(root.startsWith(fs.realpathSync(consumerRoot)+path.sep));
|
|
14
|
+
const source=fs.realpathSync(path.resolve(root,capture.sourceRelative));assert.ok(source.startsWith(root+path.sep));
|
|
15
|
+
const q=capture.contribution,record=capture.disposition;assert.deepEqual(record.contribution,q);assert.equal(record.schema,draft.DISPOSITION_VERSION);
|
|
16
|
+
assert.deepEqual(Object.keys(record.context.findingReference).sort(),['id','checkId','checkVersion','planSha256','readSetSha256','comparisonSha256'].sort());
|
|
17
|
+
const store=draft.createDraftStore({workspaceRoot:root,storeId:q.binding.storeId,actorBindingId:q.binding.actorBindingId,sourceReader:()=>({revision:capture.currentSourceRevision,digest:sha(fs.readFileSync(source))})});
|
|
18
|
+
try{
|
|
19
|
+
const original=store.readContribution(q.binding,q.id,q.revision),context=store.lookupDisposition(q.binding,record.id);
|
|
20
|
+
assert.deepEqual(original.contribution,q);assert.equal(context.status,'committed');assert.deepEqual(context.readback.record,record);
|
|
21
|
+
assert.equal(context.receipt.recordDigest,draft.commandDigest(record));assert.equal(context.receipt.contributionDigest,draft.commandDigest(q));assert.deepEqual(context.receipt.binding,q.binding);
|
|
22
|
+
assert.equal(context.readback.findingReferenceCoverage,'supplied-fingerprints');assert.deepEqual(context.readback.contributionReadback,original);
|
|
23
|
+
assert.equal(original.ledgerReadback.actor,q.binding.actorBindingId);assert.deepEqual(original.ledgerReadback.record,q);assert.notEqual(original.ledgerReadback.eventId,context.receipt.eventId);
|
|
24
|
+
assert.equal(original.draftReadback.draftRevision,q.draftRevision);assert.equal(original.draftReadback.value.digest,q.valueDigest);assert.equal(sha(original.draftReadback.value.text),q.valueDigest);assert.deepEqual(original.draftReadback.sourceBase,q.sourceBase);
|
|
25
|
+
const saves=[];
|
|
26
|
+
for(const operation of capture.operations??[]){
|
|
27
|
+
const command=operation.command,found=store.lookupOperation(q.binding,command.operationId);assert.equal(found.status,'committed');
|
|
28
|
+
assert.equal(found.receipt.commandDigest,draft.commandDigest(command));assert.equal(found.receipt.operationId,command.operationId);assert.equal(found.receipt.previousDraftRevision,command.expectedDraftRevision);assert.deepEqual(found.receipt.editor,command.editor);assert.deepEqual(found.receipt.sourceBase,command.sourceBase);
|
|
29
|
+
const readback=store.readRevision(q.binding,found.receipt.draftRevision);assert.equal(readback.value.text,command.value.text);assert.equal(readback.value.digest,sha(command.value.text));assert.equal(found.receipt.valueDigest,readback.value.digest);saves.push({command,found,readback});
|
|
30
|
+
}
|
|
31
|
+
assert.ok(saves.length,'Actual installed draft operation and independent original-ID readback required');
|
|
32
|
+
assert.ok(capture.sourceApply?.owningRoute,'Existing source-owning route must be identified');assert.equal(capture.sourceApply.participantAssertion,'fixture');assert.equal(sha(fs.readFileSync(source)),capture.sourceApply.afterSha256);
|
|
33
|
+
assert.equal(sha(capture.sourceApply.beforeBytes),capture.sourceApply.beforeSha256);assert.notEqual(capture.sourceApply.beforeSha256,capture.sourceApply.afterSha256);
|
|
34
|
+
assert.equal(capture.sourceApply.beforeSha256,q.sourceBase.digest);
|
|
35
|
+
return {result:'native-readback-consistent',original,context,saves,actualCurrentSourceSha256:sha(fs.readFileSync(source)),owningRoute:capture.sourceApply.owningRoute,scope:'Independent installed native API/file readback on this disposable consumer; does not certify rendered input, source applicability or participant acceptance.',humanAcceptance:false};
|
|
36
|
+
}finally{store.close();}
|
|
37
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import assert from 'node:assert/strict';
|
|
6
|
+
import {randomUUID} from 'node:crypto';
|
|
7
|
+
import {fileURLToPath} from 'node:url';
|
|
8
|
+
import {hash,readJson,pin,run,npm,files} from './common.mjs';
|
|
9
|
+
const [inputPath,outputPath]=process.argv.slice(2);assert.ok(inputPath&&outputPath,'Usage: node tools/rehearse.mjs EXACT_INPUT.json NEW_RESULT.json');
|
|
10
|
+
assert.equal(fs.existsSync(outputPath),false,'A prior result may not be overwritten');
|
|
11
|
+
const profile=readJson(inputPath),source=profile.source;
|
|
12
|
+
assert.ok(['baseline','delivery'].includes(profile.purpose));assert.equal(source.name,'@mnstry/atelier');assert.match(source.version,/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/);
|
|
13
|
+
assert.ok(['tarball','registry'].includes(source.kind));assert.match(source.integrity,/^sha512-[A-Za-z0-9+/]+={0,2}$/);
|
|
14
|
+
if(profile.captureTarball&&source.kind==='registry'){
|
|
15
|
+
const destination=path.join(path.dirname(path.resolve(outputPath)),'tarballs'),filename=source.name.replace(/^@/,'').replace('/','-')+'-'+source.version+'.tgz';
|
|
16
|
+
assert.equal(fs.existsSync(path.join(destination,filename)),false,'Retained tarball may not be overwritten; use a new result directory');
|
|
17
|
+
}
|
|
18
|
+
if(profile.purpose==='delivery'){assert.ok(profile.candidate?.commit&&profile.candidate?.tree,'Release owner candidate required');assert.match(profile.candidate.commit,/^[a-f0-9]{40}$/);assert.match(profile.candidate.tree,/^[a-f0-9]{40}$/);}
|
|
19
|
+
const toolHome=path.dirname(fileURLToPath(import.meta.url)),snapshot=path.resolve(outputPath)+'.harness-source';
|
|
20
|
+
assert.equal(fs.existsSync(snapshot),false,'A prior source snapshot may not be overwritten');fs.mkdirSync(snapshot,{recursive:true});
|
|
21
|
+
const harnessFiles=['rehearse.mjs','common.mjs','installed-check.mjs','native-readback.mjs','workshop-check.mjs'].map(name=>{const original=path.join(toolHome,name),retained=path.join(snapshot,name);fs.copyFileSync(original,retained);return {originalPath:original,...pin(retained)};});
|
|
22
|
+
const root=fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()),'atelier-devday-consumer-')),ownerMark=randomUUID(),observations=[];
|
|
23
|
+
fs.writeFileSync(path.join(root,'.devday-owner'),ownerMark);fs.mkdirSync(path.join(root,'config'));fs.mkdirSync(path.join(root,'cache'));
|
|
24
|
+
fs.writeFileSync(path.join(root,'config/user.npmrc'),'# Empty consumer configuration\n');fs.writeFileSync(path.join(root,'config/global.npmrc'),'# Empty consumer configuration\n');
|
|
25
|
+
fs.writeFileSync(path.join(root,'package.json'),JSON.stringify({name:'atelier-public-devday-consumer',private:true,type:'module'})+'\n');
|
|
26
|
+
const result={startedAt:new Date().toISOString(),input:pin(inputPath),harnessFiles,purpose:profile.purpose,source,host:{platform:process.platform,arch:process.arch,node:process.version},cacheInitiallyEmpty:files(path.join(root,'cache')).length===0,noPublisherNpmConfig:true,observations,claims:{registryInstall:false,tarballInstall:false,installedJourney:false,nativeInput:false,humanAcceptance:false,allPlatforms:false},deliveryQualified:false};
|
|
27
|
+
let retainedTarball=null;
|
|
28
|
+
try{
|
|
29
|
+
let target;
|
|
30
|
+
if(source.kind==='registry'){
|
|
31
|
+
assert.equal(source.registry,'https://registry.npmjs.org');
|
|
32
|
+
const viewed=npm(['view',source.name+'@'+source.version,'name','version','engines','bin','exports','dist','gitHead','--json'],root);observations.push({step:'registry-metadata',...viewed});
|
|
33
|
+
const metadata=JSON.parse(viewed.stdout);assert.equal(metadata.name,source.name);assert.equal(metadata.version,source.version);assert.equal(metadata.dist.integrity,source.integrity);
|
|
34
|
+
result.registryMetadata=metadata;result.registryMetadataSha256=hash(viewed.stdout);result.sourceIdentity={registryGitHead:metadata.gitHead??null,candidate:profile.candidate??null};
|
|
35
|
+
target=source.name+'@'+source.version;
|
|
36
|
+
}else{
|
|
37
|
+
assert.ok(source.path);assert.match(source.sha256,/^[a-f0-9]{64}$/);target=path.resolve(path.dirname(path.resolve(inputPath)),source.path);const b=fs.readFileSync(target);assert.equal(hash(b),source.sha256);assert.equal('sha512-'+hash(b,'sha512','base64'),source.integrity);
|
|
38
|
+
result.tarball=pin(target);result.sourceIdentity={candidate:profile.candidate??null};
|
|
39
|
+
}
|
|
40
|
+
const install=npm(['install',target,'--ignore-scripts','--no-audit','--no-fund','--save-exact','--prefer-online'],root);observations.push({step:'install',...install});
|
|
41
|
+
const installedRoot=path.join(root,'node_modules/@mnstry/atelier'),installed=readJson(path.join(installedRoot,'package.json')),consumer=readJson(path.join(root,'package.json')),lock=readJson(path.join(root,'package-lock.json'));
|
|
42
|
+
assert.equal(installed.name,source.name);assert.equal(installed.version,source.version);assert.equal('overrides' in consumer,false);assert.equal(lock.packages['node_modules/@mnstry/atelier'].integrity,source.integrity);
|
|
43
|
+
const tree=npm(['ls','--all','--json'],root);observations.push({step:'dependency-tree',...tree});assert.equal(JSON.parse(tree.stdout).problems?.length??0,0);
|
|
44
|
+
result.claims.registryInstall=source.kind==='registry';result.claims.tarballInstall=source.kind==='tarball';
|
|
45
|
+
result.installation={packageJson:pin(path.join(installedRoot,'package.json')),packageLock:pin(path.join(root,'package-lock.json')),exports:installed.exports,bin:installed.bin,engines:installed.engines,files:files(installedRoot),noOverrides:true,installScriptsRun:false};
|
|
46
|
+
fs.copyFileSync(path.join(snapshot,'installed-check.mjs'),path.join(root,'installed-check.mjs'));
|
|
47
|
+
fs.copyFileSync(path.join(snapshot,'native-readback.mjs'),path.join(root,'native-readback.mjs'));
|
|
48
|
+
fs.copyFileSync(path.join(snapshot,'workshop-check.mjs'),path.join(root,'workshop-check.mjs'));
|
|
49
|
+
fs.writeFileSync(path.join(root,'profile.json'),JSON.stringify(profile)+'\n');
|
|
50
|
+
const check=run(process.execPath,[path.join(root,'installed-check.mjs'),path.join(root,'profile.json')],{cwd:root,timeout:120000,accept:[0,1]});observations.push({step:'installed-check',...check});
|
|
51
|
+
result.installedChecks=JSON.parse(check.stdout);
|
|
52
|
+
assert.equal(check.status,0,'An actual installed check failed; see installedChecks and raw command output');
|
|
53
|
+
result.claims.registryInstall=source.kind==='registry';result.claims.tarballInstall=source.kind==='tarball';
|
|
54
|
+
if(profile.captureTarball&&source.kind==='registry'){
|
|
55
|
+
const destination=path.join(path.dirname(path.resolve(outputPath)),'tarballs');fs.mkdirSync(destination,{recursive:true});
|
|
56
|
+
const packed=npm(['pack',source.name+'@'+source.version,'--ignore-scripts','--json','--pack-destination='+destination],root);observations.push({step:'retain-published-tarball',...packed});
|
|
57
|
+
const packedRow=JSON.parse(packed.stdout)[0],p=path.join(destination,packedRow.filename),b=fs.readFileSync(p);assert.equal('sha512-'+hash(b,'sha512','base64'),source.integrity);
|
|
58
|
+
retainedTarball={...pin(p),integrity:source.integrity,origin:'Published registry baseline; not source-owner Dev Day candidate'};result.retainedTarball=retainedTarball;
|
|
59
|
+
}
|
|
60
|
+
result.deliveryQualified=profile.purpose==='delivery'&&result.installedChecks.deliveryQualified===true;
|
|
61
|
+
result.result='completed-with-gaps';if(result.deliveryQualified)result.result='delivery-qualified';
|
|
62
|
+
}catch(error){result.result='failed';result.error={name:error.name,message:error.message,observation:error.observation??null,stack:error.stack};}
|
|
63
|
+
finally{
|
|
64
|
+
assert.equal(fs.readFileSync(path.join(root,'.devday-owner'),'utf8'),ownerMark);fs.rmSync(root,{recursive:true});result.cleanup={root,removed:!fs.existsSync(root),scope:'Only marker-owned clean consumer and cache'};result.finishedAt=new Date().toISOString();
|
|
65
|
+
fs.mkdirSync(path.dirname(path.resolve(outputPath)),{recursive:true});fs.writeFileSync(outputPath,JSON.stringify(result,null,2)+'\n',{flag:'wx'});
|
|
66
|
+
}
|
|
67
|
+
process.stdout.write(JSON.stringify({output:path.resolve(outputPath),result:result.result,purpose:result.purpose,registryInstall:result.claims.registryInstall,tarballInstall:result.claims.tarballInstall,deliveryQualified:result.deliveryQualified,cleanup:result.cleanup,retainedTarball,error:result.error?.message??null},null,2)+'\n');
|
|
68
|
+
if(result.result==='failed')process.exitCode=1;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import {createHash} from 'node:crypto';
|
|
4
|
+
const [input,output]=process.argv.slice(2);assert.ok(input&&output);assert.equal(fs.existsSync(output),false,'Retain original report');
|
|
5
|
+
const bytes=fs.readFileSync(input),record=JSON.parse(bytes),issues=[];
|
|
6
|
+
assert.ok(['not-observed','observed'].includes(record.status));assert.equal(record.acceptance,'not-established');
|
|
7
|
+
if(record.status==='observed'){
|
|
8
|
+
for(const key of ['participantCode','recordingChoice','observedAt','packageVersion','packageIntegrity','exampleSourceBeforeSha256'])if(typeof record[key]!=='string'||!record[key].trim())issues.push('Missing actual '+key);
|
|
9
|
+
if(!record.evidenceRefs?.length)issues.push('No actual observation evidence references');
|
|
10
|
+
if(!record.baseline?.explanation)issues.push('Baseline explanation missing');
|
|
11
|
+
if(!record.understandingAfter?.explanation)issues.push('After-task explanation missing');
|
|
12
|
+
if(!record.contribution?.originalWords&&!record.contribution?.reason)issues.push('Contribution or refusal reason missing');
|
|
13
|
+
if(!record.usefulness?.participantWords&&!record.usefulness?.reason)issues.push('Participant usefulness judgment or non-observation reason missing');
|
|
14
|
+
if(record.reassessment?.observed&&!record.reassessment?.exactReadbackEvidence)issues.push('Reassessment marked observed without exact readback evidence');
|
|
15
|
+
}
|
|
16
|
+
const report={inputSha256:createHash('sha256').update(bytes).digest('hex'),status:record.status,result:issues.length?'incomplete':'record-shape-consistent',issues,humanAcceptance:'not-established',collectorAuthenticityVerified:false};
|
|
17
|
+
fs.writeFileSync(output,JSON.stringify(report,null,2)+'\n',{flag:'wx'});process.stdout.write(JSON.stringify(report)+'\n');if(issues.length)process.exitCode=2;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import {readJson,pin,run} from './common.mjs';
|
|
4
|
+
// Separate native receiving check; not a clean-consumer package import or a driver.
|
|
5
|
+
// Reuses the existing Authoring journey verifier at an exact supplied source hash.
|
|
6
|
+
const [bindingPath,output]=process.argv.slice(2);assert.ok(bindingPath&&output);assert.equal(fs.existsSync(output),false);
|
|
7
|
+
const b=readJson(bindingPath);assert.equal(pin(b.verifier.path).sha256,b.verifier.sha256);assert.equal(pin(b.capture.path).sha256,b.capture.sha256);
|
|
8
|
+
const capture=readJson(b.capture.path);assert.equal(capture.mode,'integrated-capture');assert.equal(capture.candidate.commit,b.candidate.commit);assert.equal(capture.candidate.tree,b.candidate.tree);assert.equal(capture.admission.installedCommit,b.candidate.commit);assert.equal(capture.admission.installedTree,b.candidate.tree);
|
|
9
|
+
assert.equal(capture.humanObservation.status,'not-observed','Automated rehearsal does not create human judgments');
|
|
10
|
+
const verifierReport=output+'.authoring-report.json';
|
|
11
|
+
let command,report,error;
|
|
12
|
+
try{command=run(process.execPath,[b.verifier.path,'--scenario',capture.scenario,'--candidate',b.candidate.commit,'--input',b.capture.path,'--report',verifierReport],{cwd:process.cwd(),accept:[0,1,2]});if(fs.existsSync(verifierReport))report=readJson(verifierReport);}catch(e){error=e.observation??{message:e.message};}
|
|
13
|
+
const out={binding:pin(bindingPath),verifier:b.verifier,capture:b.capture,candidate:b.candidate,package:b.package,command,error,verifierReport:report,checksConsistent:command?.status===0,productAcceptance:'not-established',humanAcceptance:'not-established',actualCollectorHonestyCertified:false};
|
|
14
|
+
fs.writeFileSync(output,JSON.stringify(out,null,2)+'\n',{flag:'wx'});process.stdout.write(JSON.stringify({output,checksConsistent:out.checksConsistent,productAcceptance:out.productAcceptance})+'\n');if(!out.checksConsistent)process.exitCode=2;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import assert from 'node:assert/strict';
|
|
4
|
+
import {createHash} from 'node:crypto';
|
|
5
|
+
import {fileURLToPath} from 'node:url';
|
|
6
|
+
const sha=value=>createHash('sha256').update(value).digest('hex');
|
|
7
|
+
|
|
8
|
+
// This receiving adapter calls the actual AW supplier signature after it is
|
|
9
|
+
// shipped. It never copies that supplier module or its examples into a consumer.
|
|
10
|
+
export async function checkInstalledWorkshop({pkg,root,profile,gap}){
|
|
11
|
+
const binding=profile.awWorkshop;
|
|
12
|
+
if(!binding||!pkg.exports[binding.exportSubpath])gap('aw-coherent-installed-entry','Foundation must first ship the received coherent AW exercise through an actual declared export. Supplier source qualification is not an installed entry.');
|
|
13
|
+
const specifier=binding.exportSubpath==='.'?pkg.name:pkg.name+'/'+binding.exportSubpath.slice(2),api=await import(specifier);
|
|
14
|
+
if(typeof api[binding.functionName]!=='function')gap('aw-coherent-installed-function','The actual installed export does not contain the received AW exercise function; return its exact version/entry to Foundation.');
|
|
15
|
+
const exportedFile=fs.realpathSync(fileURLToPath(import.meta.resolve(specifier))),packageRoot=fs.realpathSync(path.join(root,'node_modules/@mnstry/atelier'));assert.ok(exportedFile.startsWith(packageRoot+path.sep));
|
|
16
|
+
const graphAPI=await import('@mnstry/atelier/graph'),projectAPI=await import('@mnstry/atelier/project'),coauthorAPI=await import('@mnstry/atelier/coauthor/store'),rows=[];
|
|
17
|
+
assert.deepEqual(binding.outcomes.slice().sort(),['revision','note','disagreement','perspective-only','pause'].sort());
|
|
18
|
+
for(const outcome of binding.outcomes){
|
|
19
|
+
const workspace=path.join(root,'aw-workshop-'+outcome);assert.equal(fs.existsSync(workspace),false);
|
|
20
|
+
const output=await api[binding.functionName](workspace,{outcome});
|
|
21
|
+
assert.equal(output.packageVersion,pkg.version);assert.equal(output.outcome,outcome);assert.equal(output.publicInventedOnly,true);assert.equal(output.participantChoice,'fixture');assert.equal(output.humanAcceptance,false);
|
|
22
|
+
const actual=fs.realpathSync(workspace);assert.ok(actual.startsWith(fs.realpathSync(root)+path.sep));
|
|
23
|
+
const sourceFile=fs.realpathSync(path.join(actual,'records/checklist.md'));assert.ok(sourceFile.startsWith(actual+path.sep));const sourceBytes=fs.readFileSync(sourceFile);assert.equal(sha(sourceBytes),output.sourceReadbackSha256);
|
|
24
|
+
const store=coauthorAPI.createCoauthorStore({workspaceRoot:actual}),reopened=store.read('invented-workshop-'+outcome);
|
|
25
|
+
if(typeof store.close==='function')store.close();
|
|
26
|
+
assert.deepEqual(reopened.saved.map(s=>s.text),[output.originalWords,output.interpretation,outcome]);assert.notEqual(output.originalWords,output.interpretation);
|
|
27
|
+
const independentProject=projectAPI.resolveProjectConfig({cwd:actual,argv:['--project',path.join(actual,'atelier.project.json')],env:{},writeLocalState:false}),graph=graphAPI.buildCanonicalGraph(independentProject);assert.equal(graph.ok,true);
|
|
28
|
+
assert.equal(graph.nodes.length,output.afterGraph.nodes);assert.equal(graph.edges.length,output.afterGraph.edges);
|
|
29
|
+
assert.equal(output.ownerCorrection,outcome==='revision');assert.equal(output.reopenedSame,true);assert.equal(output.pauseRecoveryPreserved,true);assert.equal(output.unconfirmedInterpretationSaveRefused,true);assert.equal(output.duplicateSaveNoAdditionalEffect,true);
|
|
30
|
+
if(outcome==='revision'){assert.ok(sourceBytes.toString('utf8').includes(' supports: ["devday:workshop"]'));assert.ok(graph.edges.some(e=>e.source==='devday:checklist'&&e.type==='supports'&&e.target==='devday:workshop'));assert.equal(output.sourceDriftWriteRefused,true);}else assert.ok(sourceBytes.toString('utf8').includes(' supports: []'));
|
|
31
|
+
// Source runner reports do not substitute for independent native UI,
|
|
32
|
+
// same-check assessment and typed disposition evidence. Keep those gaps.
|
|
33
|
+
rows.push({outcome,output,independent:{sourceSha256:sha(sourceBytes),reopened,graph},scope:'Actual installed fixture exercise and independent current source/coauthor/graph readback; not native UI or semantic/human acceptance'});
|
|
34
|
+
}
|
|
35
|
+
return {installedExport:{specifier,path:path.relative(packageRoot,exportedFile),sha256:sha(fs.readFileSync(exportedFile))},rows,fullInstalledKnowledgeHealthJourneyQualified:false,nativeTypedDispositionQualified:false,humanAcceptance:false,remaining:['Actual same-check assessment/current evidence with owner-bound typed reference','Normal shipped guided host/native caller and keyboard/recovery capture','Actual human observations'],sourceModuleInjected:false};
|
|
36
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export const ruleIdentity = Object.freeze({
|
|
2
|
+
"profile": "source-qualified-required-direction/r1",
|
|
3
|
+
"commit": "fcfdbe5ded672d41c717f49e0cfdf68b6060834d",
|
|
4
|
+
"tree": "400e181cd0cb55976f3ef7ab1a1405531dacd521",
|
|
5
|
+
"files": [
|
|
6
|
+
{
|
|
7
|
+
"path": "src/knowledge/plan.mjs",
|
|
8
|
+
"bytes": 4609,
|
|
9
|
+
"sha256": "7ee8d7d20fcc85264dd484b129eae9a1ab4424b47aae0cce764f9e769fe32336",
|
|
10
|
+
"blob": "b029609a678354f188980acb8954030daa817582"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"path": "src/knowledge/context.mjs",
|
|
14
|
+
"bytes": 12590,
|
|
15
|
+
"sha256": "29a73bc8e1afa498f1ed11e158379317cf738a898a68930d95b90b1f1f395d0d",
|
|
16
|
+
"blob": "7d2be260883267277050c6f7f1f0b0cd6888e5a4"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"path": "src/graph/graph.mjs",
|
|
20
|
+
"bytes": 9934,
|
|
21
|
+
"sha256": "1f01fbeab7e6fcaed127c8fe84c9a48b08f1fec13d21f486c48726715a5bbb92",
|
|
22
|
+
"blob": "6bce4e1213098457097e025f8ead53e6b4403336"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"path": "src/graph/knowledge-graph.mjs",
|
|
26
|
+
"bytes": 65477,
|
|
27
|
+
"sha256": "94895598d388e80a70b7bbe92ad57138dccd94896699a6c472e635d885b1139f",
|
|
28
|
+
"blob": "283ef86ad08a6360bc006cc75ca5cedb2718e14d"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"path": "templates/knowledge-workspace/knowledge-plan.schema.json",
|
|
32
|
+
"bytes": 6557,
|
|
33
|
+
"sha256": "71a6777af291b20a90635be3d3d13fdb4a9bca1104b4ef364a7b7c0e8c8100a0",
|
|
34
|
+
"blob": "4781dcda5f91f450544fb37e30a48ce9db8a1d5a"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"releaseVersion": null,
|
|
38
|
+
"scope": "Native source authority only: the commit and tree name where these rule and schema files were read, and each file is pinned by its blob. This is not a release candidate identity; a package version label or a later commit is not implied.",
|
|
39
|
+
"supersededQualification": {
|
|
40
|
+
"commit": "b1bdc9279a99f7c884ddfdfe0e2a24315d6f3666",
|
|
41
|
+
"tree": "2797f44baf89007d3808675d897e55a943fc0d65",
|
|
42
|
+
"note": "The supplier qualified against this earlier commit. The five pinned files are byte-identical there and at the source authority above."
|
|
43
|
+
}
|
|
44
|
+
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import { resolveProjectConfig } from '../project/config.mjs'
|
|
3
|
+
import { createKnowledgeSessions } from '../knowledge/sessions.mjs'
|
|
4
|
+
import { inspectPublicWorkshop, publicWorkshopProfile, preparePublicWorkshopHandoff } from './workshop-profile.mjs'
|
|
5
|
+
|
|
6
|
+
// A callable default over the same session/store used by /knowledge. No new
|
|
7
|
+
// ledger, model, receipt algorithm, source writer, editor or server is opened.
|
|
8
|
+
export function createPublicWorkshopComposition({ workspaceRoot }) {
|
|
9
|
+
const project = resolveProjectConfig({ cwd: workspaceRoot,
|
|
10
|
+
argv: ['--project', path.join(workspaceRoot, 'atelier.project.json')], env: {}, writeLocalState: false })
|
|
11
|
+
const sessions = createKnowledgeSessions(project)
|
|
12
|
+
return { ...sessions,
|
|
13
|
+
inspect: () => inspectPublicWorkshop({ workspaceRoot }),
|
|
14
|
+
profile: () => sessions.workshopProfile(),
|
|
15
|
+
prepareHandoff: id => preparePublicWorkshopHandoff(sessions.read(id)),
|
|
16
|
+
authority: Object.freeze({ savedMeaning: 'private-draft-only', directWrite: false,
|
|
17
|
+
typedFindingDisposition: false, sourceEditsApplied: false }) }
|
|
18
|
+
}
|
|
19
|
+
export { inspectPublicWorkshop, publicWorkshopProfile, preparePublicWorkshopHandoff }
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { canonicalize } from '../attestation/jcs.mjs'
|
|
2
|
+
import { contentDigest } from '../coauthor/session.mjs'
|
|
3
|
+
import { assessKnowledgeHealthWorkshop } from './workshop.mjs'
|
|
4
|
+
|
|
5
|
+
// A consumer profile of the existing knowledge-session descriptor and coauthor
|
|
6
|
+
// fields. These are private drafts, not typed native finding-disposition receipts.
|
|
7
|
+
export const PUBLIC_WORKSHOP_FLOW = Object.freeze({
|
|
8
|
+
id: 'workshop', title: 'Workshop',
|
|
9
|
+
description: 'Read the finding, retain your words, and choose your response.',
|
|
10
|
+
prompts: [
|
|
11
|
+
['original-words', 'What do you make of this finding?', 'Your wording is retained exactly. A missing relationship does not decide readiness.'],
|
|
12
|
+
['interpretation', 'Optional interpretation', 'Leave it empty, or record a separate interpretation. Proposed wording requires confirmation.'],
|
|
13
|
+
['choice', 'Which response do you choose?', 'Choose note, perspective-only, disagreement or pause. Review is a separate optional action.'],
|
|
14
|
+
],
|
|
15
|
+
})
|
|
16
|
+
export const PUBLIC_WORKSHOP_CHOICES = Object.freeze(['note', 'perspective-only', 'disagreement', 'pause'])
|
|
17
|
+
const LEGACY_WORKSHOP_CHOICES = [...PUBLIC_WORKSHOP_CHOICES, 'revision']
|
|
18
|
+
export const PUBLIC_PARTICIPANT_PROFILE = 'four-choice-separate-review-r1'
|
|
19
|
+
export const PUBLIC_WORKSHOP_REVIEW_FLOW = Object.freeze({ id: 'workshop-review', title: 'Review selected declaration',
|
|
20
|
+
prompts: [['authored-revision', 'Selected draft declaration', 'Save the selected declaration as a private draft. Source-owner editing remains separate.']] })
|
|
21
|
+
|
|
22
|
+
export function inspectPublicWorkshop({ workspaceRoot }) {
|
|
23
|
+
return assessKnowledgeHealthWorkshop({ workspaceRoot })
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function publicWorkshopProfile(workspaceRoot) {
|
|
27
|
+
const observation = inspectPublicWorkshop({ workspaceRoot })
|
|
28
|
+
const a = observation.assessment, f = a.findings?.[0], e = a.evidence
|
|
29
|
+
if (a.status !== 'needs-attention' || a.coverage !== 'complete' || a.currency !== 'current'
|
|
30
|
+
|| a.refusal !== null || a.findings.length !== 1 || !f.actionable
|
|
31
|
+
|| f.source.id !== 'devday:checklist' || f.declaration.id !== 'kg.relations.supports'
|
|
32
|
+
|| e.relationId !== 'checklist-workshop' || e.questionId !== 'workshop-readiness'
|
|
33
|
+
|| f.declaration.quote !== '[]') throw new Error('public workshop finding unavailable')
|
|
34
|
+
const findingReference = { id: f.referenceKey, checkId: f.check.id, checkVersion: f.check.version,
|
|
35
|
+
planSha256: e.planSha256, readSetSha256: e.readSetSha256, comparisonSha256: e.comparisonSha256 }
|
|
36
|
+
if (Object.values(findingReference).some(v => typeof v !== 'string' || !v)
|
|
37
|
+
|| [e.planSha256, e.readSetSha256, e.comparisonSha256].some(v => !/^[a-f0-9]{64}$/.test(v)))
|
|
38
|
+
throw new Error('public workshop finding fingerprints unavailable')
|
|
39
|
+
const context = { ...structuredClone(observation.context), findingReference,
|
|
40
|
+
workshop: structuredClone(observation.workshop), finding: structuredClone(f),
|
|
41
|
+
meaning: 'ordinary-public-coauthor-drafts', participantResponseProfile: PUBLIC_PARTICIPANT_PROFILE, typedFindingDisposition: false,
|
|
42
|
+
sourceApply: 'source-owner-copy-only', semanticSupport: 'unassessed' }
|
|
43
|
+
return { flow: PUBLIC_WORKSHOP_FLOW, context, ref: 'records/checklist.md',
|
|
44
|
+
sourceDigest: f.source.sha256, contextDigest: contentDigest(canonicalize(context)) }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Validate only this consumer's ordinary draft fields. The owning engine still
|
|
48
|
+
// owns revisions, confirmation, event identity, saves, receipts and recovery.
|
|
49
|
+
function validateLegacyPublicWorkshopEvent(record, state, event) {
|
|
50
|
+
if (record.flow !== PUBLIC_WORKSHOP_FLOW.id || !['answer', 'propose'].includes(event?.type)) return
|
|
51
|
+
const field = state.fields[state.index]?.id
|
|
52
|
+
if (field === 'choice' && !LEGACY_WORKSHOP_CHOICES.includes(event.text))
|
|
53
|
+
throw new Error('choose an exact public workshop response')
|
|
54
|
+
if (field === 'authored-revision') {
|
|
55
|
+
const choice = state.saved.find(s => s.fieldId === 'choice')?.text
|
|
56
|
+
if (event.text !== (choice === 'revision' ? '["devday:workshop"]' : 'none'))
|
|
57
|
+
throw new Error('revision wording must match the retained explicit choice')
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function prepareLegacyPublicWorkshopHandoff(session) {
|
|
62
|
+
const { record, state, current } = session
|
|
63
|
+
if (!current || record.flow !== PUBLIC_WORKSHOP_FLOW.id || state.phase !== 'complete')
|
|
64
|
+
throw new Error('a complete current public workshop draft is required')
|
|
65
|
+
const values = Object.fromEntries(state.saved.map(s => [s.fieldId, s.text]))
|
|
66
|
+
if (values.choice !== 'revision' || values['authored-revision'] !== '["devday:workshop"]')
|
|
67
|
+
throw new Error('an explicitly retained revision choice is required')
|
|
68
|
+
const anchor = record.context.workshop.binding.field
|
|
69
|
+
return { sessionId: record.id, viewId: 'knowledge-workshop', path: 'records/checklist.md',
|
|
70
|
+
action: 'copy.repoPath', actor: record.author,
|
|
71
|
+
intent: 'Source owner reviews one supporting declaration.', directWrite: false, applyEndpoint: null,
|
|
72
|
+
diff: { source: record.context.workshop.binding.source, anchor, replacement: values['authored-revision'] },
|
|
73
|
+
proposal: { directWrite: false, applyEndpoint: null,
|
|
74
|
+
reason: 'Retained participant wording; source-owner editing and readback remain explicit.',
|
|
75
|
+
originalWords: values['original-words'], interpretation: values.interpretation, choice: values.choice,
|
|
76
|
+
authoredRevision: values['authored-revision'], findingReference: record.context.findingReference,
|
|
77
|
+
source: record.context.workshop.binding.source, anchor,
|
|
78
|
+
readSet: record.context.assessment.evidence.readSet,
|
|
79
|
+
savedDraftReceipts: state.saved.map(s => s.receipt), sourceEditsApplied: false,
|
|
80
|
+
typedFindingDisposition: false, semanticAcceptance: false } }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
// An inert consumer encoding lets the existing nonempty-text draft store retain
|
|
85
|
+
// an explicitly empty interpretation. It changes no owning draft schema.
|
|
86
|
+
export function encodePublicWorkshopInterpretation(text) {
|
|
87
|
+
checkWords(text, true)
|
|
88
|
+
return JSON.stringify({ text })
|
|
89
|
+
}
|
|
90
|
+
export function decodePublicWorkshopInterpretation(value) {
|
|
91
|
+
const parsed = JSON.parse(value)
|
|
92
|
+
if (!parsed || Array.isArray(parsed) || Object.keys(parsed).join(',') !== 'text')
|
|
93
|
+
throw new Error('one separately labeled interpretation required')
|
|
94
|
+
checkWords(parsed.text, true)
|
|
95
|
+
return parsed.text
|
|
96
|
+
}
|
|
97
|
+
function checkWords(text, optional = false) {
|
|
98
|
+
if (typeof text !== 'string' || (!optional && !text.trim())
|
|
99
|
+
|| Buffer.byteLength(text, 'utf8') > 512 || Buffer.from(text, 'utf8').toString('utf8') !== text)
|
|
100
|
+
throw new Error('lossless participant wording exceeds its 512 UTF-8 byte limit')
|
|
101
|
+
}
|
|
102
|
+
export function validatePublicWorkshopEvent(record, state, event) {
|
|
103
|
+
if (record.context?.participantResponseProfile !== PUBLIC_PARTICIPANT_PROFILE)
|
|
104
|
+
return validateLegacyPublicWorkshopEvent(record, state, event)
|
|
105
|
+
if (!['answer', 'propose'].includes(event?.type)) return
|
|
106
|
+
const field = state.fields[state.index]?.id
|
|
107
|
+
if (record.flow === 'workshop-review') {
|
|
108
|
+
if (field !== 'authored-revision' || event.text !== '["devday:workshop"]')
|
|
109
|
+
throw new Error('only the explicitly selected workshop declaration is supported')
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
if (record.flow !== 'workshop') throw new Error('unsupported participant flow')
|
|
113
|
+
if (field === 'original-words') {
|
|
114
|
+
if (event.type === 'propose') throw new Error('interpretation must not replace original words')
|
|
115
|
+
checkWords(event.text)
|
|
116
|
+
} else if (field === 'interpretation') decodePublicWorkshopInterpretation(event.text)
|
|
117
|
+
else if (field === 'choice' && (event.type === 'propose' || !PUBLIC_WORKSHOP_CHOICES.includes(event.text)))
|
|
118
|
+
throw new Error('choose one of the four participant responses yourself; Review is separate')
|
|
119
|
+
}
|
|
120
|
+
export function readPublicWorkshopContribution(session) {
|
|
121
|
+
const { record, state } = session
|
|
122
|
+
if (record.flow !== 'workshop' || record.context?.participantResponseProfile !== PUBLIC_PARTICIPANT_PROFILE)
|
|
123
|
+
throw new Error('four-response participant session required; legacy history stays readable')
|
|
124
|
+
const saved = Object.fromEntries(state.saved.map(value => [value.fieldId, value]))
|
|
125
|
+
const lastAnswer = field => state.answers.filter(value => value.fieldId === field).at(-1)
|
|
126
|
+
const currentChoice = state.fields[state.index]?.id === 'choice' ? state.proposal : null
|
|
127
|
+
return { sessionId: record.id, originalContributionId: lastAnswer('original-words')?.eventId ?? null,
|
|
128
|
+
originalChoiceId: lastAnswer('choice')?.eventId ?? null,
|
|
129
|
+
originalWords: saved['original-words']?.text ?? lastAnswer('original-words')?.text ?? null,
|
|
130
|
+
interpretation: saved.interpretation ? decodePublicWorkshopInterpretation(saved.interpretation.text) : null,
|
|
131
|
+
interpretationRecorded: Boolean(saved.interpretation),
|
|
132
|
+
choice: saved.choice?.text ?? currentChoice?.text ?? null,
|
|
133
|
+
choiceStatus: saved.choice && session.owningReadbacks?.verified === true ? 'confirmed'
|
|
134
|
+
: currentChoice ? 'unconfirmed' : 'not-recorded',
|
|
135
|
+
receipts: state.saved.map(value => value.receipt),
|
|
136
|
+
owningReadbacks: session.owningReadbacks ?? null,
|
|
137
|
+
findingReference: structuredClone(record.context.findingReference),
|
|
138
|
+
typedFindingDisposition: false, semanticAcceptance: false }
|
|
139
|
+
}
|
|
140
|
+
export function publicWorkshopReviewProfile(workspaceRoot, participant) {
|
|
141
|
+
const contribution = readPublicWorkshopContribution(participant)
|
|
142
|
+
if (!participant.current || participant.state.phase !== 'complete'
|
|
143
|
+
|| contribution.choiceStatus !== 'confirmed' || !PUBLIC_WORKSHOP_CHOICES.includes(contribution.choice)
|
|
144
|
+
|| !contribution.originalContributionId || !contribution.originalChoiceId)
|
|
145
|
+
throw new Error('current contribution and both owning readbacks required before separate Review')
|
|
146
|
+
const profile = publicWorkshopProfile(workspaceRoot)
|
|
147
|
+
if (canonicalize(profile.context.findingReference) !== canonicalize(participant.record.context.findingReference))
|
|
148
|
+
throw new Error('finding changed; refresh before selecting a new draft')
|
|
149
|
+
const context = { ...profile.context, participant: structuredClone(contribution) }
|
|
150
|
+
return { ...profile, flow: PUBLIC_WORKSHOP_REVIEW_FLOW, context,
|
|
151
|
+
contextDigest: contentDigest(canonicalize(context)) }
|
|
152
|
+
}
|
|
153
|
+
export function preparePublicWorkshopHandoff(session) {
|
|
154
|
+
if (session.record.flow !== 'workshop-review') return prepareLegacyPublicWorkshopHandoff(session)
|
|
155
|
+
const { record, state, current } = session
|
|
156
|
+
const selected = state.saved.find(value => value.fieldId === 'authored-revision')
|
|
157
|
+
const participant = record.context.participant
|
|
158
|
+
if (!current || state.phase !== 'complete' || session.owningReadbacks?.verified !== true
|
|
159
|
+
|| !participant || participant.choiceStatus !== 'confirmed'
|
|
160
|
+
|| !selected || selected.text !== '["devday:workshop"]')
|
|
161
|
+
throw new Error('current selected draft and both owning readbacks required')
|
|
162
|
+
const anchor = record.context.workshop.binding.field
|
|
163
|
+
return { sessionId: record.id, viewId: 'knowledge-workshop', path: 'records/checklist.md',
|
|
164
|
+
action: 'copy.repoPath', actor: record.author, intent: 'Source owner reviews one supporting declaration.',
|
|
165
|
+
directWrite: false, applyEndpoint: null,
|
|
166
|
+
diff: { source: record.context.workshop.binding.source, anchor, replacement: selected.text },
|
|
167
|
+
proposal: { directWrite: false, applyEndpoint: null, sourceEditsApplied: false,
|
|
168
|
+
originalWords: participant.originalWords, interpretation: participant.interpretation,
|
|
169
|
+
choice: participant.choice, originalContributionId: participant.originalContributionId,
|
|
170
|
+
originalChoiceId: participant.originalChoiceId, contributionSessionId: participant.sessionId,
|
|
171
|
+
authoredRevision: selected.text, findingReference: record.context.findingReference,
|
|
172
|
+
source: record.context.workshop.binding.source, anchor, readSet: record.context.assessment.evidence.readSet,
|
|
173
|
+
savedDraftReceipts: [...participant.receipts, selected.receipt],
|
|
174
|
+
selectedDraftReceipt: selected.receipt, declarationBytes: { encoding: 'utf8', before: anchor.quote, after: selected.text },
|
|
175
|
+
typedFindingDisposition: false, semanticAcceptance: false } }
|
|
176
|
+
}
|