worldvm 0.0.0-stage → 0.1.0
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/AUTHORING.md +833 -0
- package/README.md +154 -2
- package/bin/worldvm.mjs +3 -0
- package/dist/_internal/forma/index.d.ts +1 -0
- package/dist/_internal/forma/index.js +1 -0
- package/dist/_internal/forma/world/authoring-help.d.ts +25 -0
- package/dist/_internal/forma/world/authoring-help.js +130 -0
- package/dist/_internal/forma/world/citations.d.ts +3 -0
- package/dist/_internal/forma/world/citations.js +26 -0
- package/dist/_internal/forma/world/clock-bindings.d.ts +4 -0
- package/dist/_internal/forma/world/clock-bindings.js +45 -0
- package/dist/_internal/forma/world/compile.d.ts +13 -0
- package/dist/_internal/forma/world/compile.js +190 -0
- package/dist/_internal/forma/world/coverage.d.ts +10 -0
- package/dist/_internal/forma/world/coverage.js +242 -0
- package/dist/_internal/forma/world/digest.d.ts +1 -0
- package/dist/_internal/forma/world/digest.js +1 -0
- package/dist/_internal/forma/world/documentation.d.ts +3 -0
- package/dist/_internal/forma/world/documentation.js +38 -0
- package/dist/_internal/forma/world/homes.d.ts +4 -0
- package/dist/_internal/forma/world/homes.js +202 -0
- package/dist/_internal/forma/world/index.d.ts +6 -0
- package/dist/_internal/forma/world/index.js +5 -0
- package/dist/_internal/forma/world/lowering/accounts.d.ts +4 -0
- package/dist/_internal/forma/world/lowering/accounts.js +36 -0
- package/dist/_internal/forma/world/lowering/action-policy.d.ts +5 -0
- package/dist/_internal/forma/world/lowering/action-policy.js +16 -0
- package/dist/_internal/forma/world/lowering/agents.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/agents.js +116 -0
- package/dist/_internal/forma/world/lowering/bundles.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/bundles.js +13 -0
- package/dist/_internal/forma/world/lowering/child-parameters.d.ts +14 -0
- package/dist/_internal/forma/world/lowering/child-parameters.js +36 -0
- package/dist/_internal/forma/world/lowering/collects.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/collects.js +51 -0
- package/dist/_internal/forma/world/lowering/component-operations.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/component-operations.js +26 -0
- package/dist/_internal/forma/world/lowering/components.d.ts +7 -0
- package/dist/_internal/forma/world/lowering/components.js +236 -0
- package/dist/_internal/forma/world/lowering/connectors.d.ts +4 -0
- package/dist/_internal/forma/world/lowering/connectors.js +31 -0
- package/dist/_internal/forma/world/lowering/context.d.ts +80 -0
- package/dist/_internal/forma/world/lowering/context.js +316 -0
- package/dist/_internal/forma/world/lowering/contracts.d.ts +7 -0
- package/dist/_internal/forma/world/lowering/contracts.js +73 -0
- package/dist/_internal/forma/world/lowering/decisions.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/decisions.js +164 -0
- package/dist/_internal/forma/world/lowering/derives.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/derives.js +22 -0
- package/dist/_internal/forma/world/lowering/discretionary.d.ts +7 -0
- package/dist/_internal/forma/world/lowering/discretionary.js +15 -0
- package/dist/_internal/forma/world/lowering/documents.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/documents.js +68 -0
- package/dist/_internal/forma/world/lowering/effective.d.ts +5 -0
- package/dist/_internal/forma/world/lowering/effective.js +26 -0
- package/dist/_internal/forma/world/lowering/entities.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/entities.js +43 -0
- package/dist/_internal/forma/world/lowering/escalations.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/escalations.js +31 -0
- package/dist/_internal/forma/world/lowering/evidence.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/evidence.js +75 -0
- package/dist/_internal/forma/world/lowering/files.d.ts +4 -0
- package/dist/_internal/forma/world/lowering/files.js +56 -0
- package/dist/_internal/forma/world/lowering/holds.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/holds.js +35 -0
- package/dist/_internal/forma/world/lowering/index.d.ts +89 -0
- package/dist/_internal/forma/world/lowering/index.js +115 -0
- package/dist/_internal/forma/world/lowering/interactions.d.ts +7 -0
- package/dist/_internal/forma/world/lowering/interactions.js +190 -0
- package/dist/_internal/forma/world/lowering/library.d.ts +5 -0
- package/dist/_internal/forma/world/lowering/library.js +41 -0
- package/dist/_internal/forma/world/lowering/milestones.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/milestones.js +17 -0
- package/dist/_internal/forma/world/lowering/notices.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/notices.js +33 -0
- package/dist/_internal/forma/world/lowering/param-bounds.d.ts +15 -0
- package/dist/_internal/forma/world/lowering/param-bounds.js +71 -0
- package/dist/_internal/forma/world/lowering/policies.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/policies.js +95 -0
- package/dist/_internal/forma/world/lowering/principals.d.ts +62 -0
- package/dist/_internal/forma/world/lowering/principals.js +32 -0
- package/dist/_internal/forma/world/lowering/recurrences.d.ts +9 -0
- package/dist/_internal/forma/world/lowering/recurrences.js +56 -0
- package/dist/_internal/forma/world/lowering/renewal.d.ts +5 -0
- package/dist/_internal/forma/world/lowering/renewal.js +21 -0
- package/dist/_internal/forma/world/lowering/resources.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/resources.js +19 -0
- package/dist/_internal/forma/world/lowering/reuse.d.ts +5 -0
- package/dist/_internal/forma/world/lowering/reuse.js +75 -0
- package/dist/_internal/forma/world/lowering/sources.d.ts +10 -0
- package/dist/_internal/forma/world/lowering/sources.js +47 -0
- package/dist/_internal/forma/world/lowering/syntax.d.ts +84 -0
- package/dist/_internal/forma/world/lowering/syntax.js +94 -0
- package/dist/_internal/forma/world/lowering/vaults.d.ts +11 -0
- package/dist/_internal/forma/world/lowering/vaults.js +148 -0
- package/dist/_internal/forma/world/prelude.generated.d.ts +1 -0
- package/dist/_internal/forma/world/prelude.generated.js +2 -0
- package/dist/_internal/forma/world/properties.d.ts +9 -0
- package/dist/_internal/forma/world/properties.js +387 -0
- package/dist/_internal/forma/world/scenarios.d.ts +10 -0
- package/dist/_internal/forma/world/scenarios.js +757 -0
- package/dist/_internal/forma/world/sensitivity.d.ts +3 -0
- package/dist/_internal/forma/world/sensitivity.js +118 -0
- package/dist/_internal/forma/world/source-syntax.d.ts +6 -0
- package/dist/_internal/forma/world/source-syntax.js +27 -0
- package/dist/_internal/forma/world/status-handling.d.ts +3 -0
- package/dist/_internal/forma/world/status-handling.js +143 -0
- package/dist/_internal/forma/world/surface.d.ts +30 -0
- package/dist/_internal/forma/world/surface.js +213 -0
- package/dist/_internal/forma/world/table-expressions.d.ts +3 -0
- package/dist/_internal/forma/world/table-expressions.js +41 -0
- package/dist/_internal/forma-tools/index.d.ts +17 -0
- package/dist/_internal/forma-tools/index.js +124 -0
- package/dist/_internal/ir-checks/advances.d.ts +7 -0
- package/dist/_internal/ir-checks/advances.js +6 -0
- package/dist/_internal/ir-checks/agent-reads.d.ts +14 -0
- package/dist/_internal/ir-checks/agent-reads.js +118 -0
- package/dist/_internal/ir-checks/amendments.d.ts +3 -0
- package/dist/_internal/ir-checks/amendments.js +21 -0
- package/dist/_internal/ir-checks/canonical-json.d.ts +3 -0
- package/dist/_internal/ir-checks/canonical-json.js +85 -0
- package/dist/_internal/ir-checks/child-parameters.d.ts +2 -0
- package/dist/_internal/ir-checks/child-parameters.js +43 -0
- package/dist/_internal/ir-checks/clock-bindings.d.ts +3 -0
- package/dist/_internal/ir-checks/clock-bindings.js +43 -0
- package/dist/_internal/ir-checks/collect-types.d.ts +14 -0
- package/dist/_internal/ir-checks/collect-types.js +34 -0
- package/dist/_internal/ir-checks/component-operations.d.ts +4 -0
- package/dist/_internal/ir-checks/component-operations.js +23 -0
- package/dist/_internal/ir-checks/content-digest.d.ts +4 -0
- package/dist/_internal/ir-checks/content-digest.js +78 -0
- package/dist/_internal/ir-checks/contract-validation.d.ts +3 -0
- package/dist/_internal/ir-checks/contract-validation.js +307 -0
- package/dist/_internal/ir-checks/contracts.d.ts +25 -0
- package/dist/_internal/ir-checks/contracts.js +80 -0
- package/dist/_internal/ir-checks/dates.d.ts +2 -0
- package/dist/_internal/ir-checks/dates.js +7 -0
- package/dist/_internal/ir-checks/documents.d.ts +3 -0
- package/dist/_internal/ir-checks/documents.js +45 -0
- package/dist/_internal/ir-checks/evidence.d.ts +20 -0
- package/dist/_internal/ir-checks/evidence.js +56 -0
- package/dist/_internal/ir-checks/files.d.ts +7 -0
- package/dist/_internal/ir-checks/files.js +47 -0
- package/dist/_internal/ir-checks/index.d.ts +59 -0
- package/dist/_internal/ir-checks/index.js +166 -0
- package/dist/_internal/ir-checks/instants.d.ts +7 -0
- package/dist/_internal/ir-checks/instants.js +61 -0
- package/dist/_internal/ir-checks/notices.d.ts +4 -0
- package/dist/_internal/ir-checks/notices.js +58 -0
- package/dist/_internal/ir-checks/policy-bounds.d.ts +5 -0
- package/dist/_internal/ir-checks/policy-bounds.js +28 -0
- package/dist/_internal/ir-checks/principals.d.ts +26 -0
- package/dist/_internal/ir-checks/principals.js +162 -0
- package/dist/_internal/ir-checks/prior-cycle.d.ts +41 -0
- package/dist/_internal/ir-checks/prior-cycle.js +21 -0
- package/dist/_internal/ir-checks/read-classification.d.ts +12 -0
- package/dist/_internal/ir-checks/read-classification.js +67 -0
- package/dist/_internal/ir-checks/read-types.d.ts +2 -0
- package/dist/_internal/ir-checks/read-types.js +40 -0
- package/dist/_internal/ir-checks/resource-proofs.d.ts +4 -0
- package/dist/_internal/ir-checks/resource-proofs.js +98 -0
- package/dist/_internal/ir-checks/resources.d.ts +3 -0
- package/dist/_internal/ir-checks/resources.js +30 -0
- package/dist/_internal/ir-checks/reuse.d.ts +10 -0
- package/dist/_internal/ir-checks/reuse.js +99 -0
- package/dist/_internal/ir-checks/sealing.d.ts +14 -0
- package/dist/_internal/ir-checks/sealing.js +123 -0
- package/dist/_internal/ir-checks/sensitive-flow.d.ts +4 -0
- package/dist/_internal/ir-checks/sensitive-flow.js +240 -0
- package/dist/_internal/ir-checks/sensitivity.d.ts +19 -0
- package/dist/_internal/ir-checks/sensitivity.js +133 -0
- package/dist/_internal/ir-checks/signatures.d.ts +4 -0
- package/dist/_internal/ir-checks/signatures.js +22 -0
- package/dist/_internal/ir-checks/vaults.d.ts +10 -0
- package/dist/_internal/ir-checks/vaults.js +140 -0
- package/dist/_internal/protocol/index.d.ts +1234 -0
- package/dist/_internal/protocol/index.js +215 -0
- package/dist/_internal/reconciler/action-intents.d.ts +17 -0
- package/dist/_internal/reconciler/action-intents.js +161 -0
- package/dist/_internal/reconciler/actions.d.ts +7 -0
- package/dist/_internal/reconciler/actions.js +134 -0
- package/dist/_internal/reconciler/amendments.d.ts +12 -0
- package/dist/_internal/reconciler/amendments.js +52 -0
- package/dist/_internal/reconciler/basis.d.ts +253 -0
- package/dist/_internal/reconciler/basis.js +16 -0
- package/dist/_internal/reconciler/bundles.d.ts +22 -0
- package/dist/_internal/reconciler/bundles.js +110 -0
- package/dist/_internal/reconciler/change-detection.d.ts +5 -0
- package/dist/_internal/reconciler/change-detection.js +82 -0
- package/dist/_internal/reconciler/collection-rules.d.ts +7 -0
- package/dist/_internal/reconciler/collection-rules.js +46 -0
- package/dist/_internal/reconciler/collection-state.d.ts +11 -0
- package/dist/_internal/reconciler/collection-state.js +62 -0
- package/dist/_internal/reconciler/collection-values.d.ts +5 -0
- package/dist/_internal/reconciler/collection-values.js +60 -0
- package/dist/_internal/reconciler/collections.d.ts +35 -0
- package/dist/_internal/reconciler/collections.js +141 -0
- package/dist/_internal/reconciler/commands.d.ts +60 -0
- package/dist/_internal/reconciler/commands.js +468 -0
- package/dist/_internal/reconciler/component-operations.d.ts +48 -0
- package/dist/_internal/reconciler/component-operations.js +256 -0
- package/dist/_internal/reconciler/context.d.ts +38 -0
- package/dist/_internal/reconciler/context.js +44 -0
- package/dist/_internal/reconciler/coverage.d.ts +31 -0
- package/dist/_internal/reconciler/coverage.js +124 -0
- package/dist/_internal/reconciler/dates.d.ts +38 -0
- package/dist/_internal/reconciler/dates.js +121 -0
- package/dist/_internal/reconciler/decide.d.ts +25 -0
- package/dist/_internal/reconciler/decide.js +263 -0
- package/dist/_internal/reconciler/decision-evaluation.d.ts +9 -0
- package/dist/_internal/reconciler/decision-evaluation.js +67 -0
- package/dist/_internal/reconciler/decision-records.d.ts +14 -0
- package/dist/_internal/reconciler/decision-records.js +77 -0
- package/dist/_internal/reconciler/decision-release.d.ts +3 -0
- package/dist/_internal/reconciler/decision-release.js +12 -0
- package/dist/_internal/reconciler/dependencies.d.ts +179 -0
- package/dist/_internal/reconciler/dependencies.js +372 -0
- package/dist/_internal/reconciler/discovery.d.ts +9 -0
- package/dist/_internal/reconciler/discovery.js +65 -0
- package/dist/_internal/reconciler/document-corrections.d.ts +18 -0
- package/dist/_internal/reconciler/document-corrections.js +59 -0
- package/dist/_internal/reconciler/documents.d.ts +26 -0
- package/dist/_internal/reconciler/documents.js +88 -0
- package/dist/_internal/reconciler/effective.d.ts +6 -0
- package/dist/_internal/reconciler/effective.js +17 -0
- package/dist/_internal/reconciler/escalations.d.ts +4 -0
- package/dist/_internal/reconciler/escalations.js +76 -0
- package/dist/_internal/reconciler/evaluation.d.ts +56 -0
- package/dist/_internal/reconciler/evaluation.js +704 -0
- package/dist/_internal/reconciler/evidence-authority.d.ts +6 -0
- package/dist/_internal/reconciler/evidence-authority.js +70 -0
- package/dist/_internal/reconciler/evidence-history.d.ts +5 -0
- package/dist/_internal/reconciler/evidence-history.js +22 -0
- package/dist/_internal/reconciler/evidence-validity.d.ts +17 -0
- package/dist/_internal/reconciler/evidence-validity.js +135 -0
- package/dist/_internal/reconciler/fact-validation.d.ts +5 -0
- package/dist/_internal/reconciler/fact-validation.js +49 -0
- package/dist/_internal/reconciler/files.d.ts +9 -0
- package/dist/_internal/reconciler/files.js +56 -0
- package/dist/_internal/reconciler/graph.d.ts +40 -0
- package/dist/_internal/reconciler/graph.js +298 -0
- package/dist/_internal/reconciler/holds.d.ts +6 -0
- package/dist/_internal/reconciler/holds.js +18 -0
- package/dist/_internal/reconciler/home-definitions.d.ts +11 -0
- package/dist/_internal/reconciler/home-definitions.js +25 -0
- package/dist/_internal/reconciler/homes.d.ts +6 -0
- package/dist/_internal/reconciler/homes.js +32 -0
- package/dist/_internal/reconciler/index.d.ts +42 -0
- package/dist/_internal/reconciler/index.js +58 -0
- package/dist/_internal/reconciler/instants.d.ts +17 -0
- package/dist/_internal/reconciler/instants.js +56 -0
- package/dist/_internal/reconciler/interaction-fields.d.ts +10 -0
- package/dist/_internal/reconciler/interaction-fields.js +30 -0
- package/dist/_internal/reconciler/invariants.d.ts +8 -0
- package/dist/_internal/reconciler/invariants.js +34 -0
- package/dist/_internal/reconciler/journal.d.ts +3 -0
- package/dist/_internal/reconciler/journal.js +4 -0
- package/dist/_internal/reconciler/linking.d.ts +10 -0
- package/dist/_internal/reconciler/linking.js +259 -0
- package/dist/_internal/reconciler/memory.d.ts +32 -0
- package/dist/_internal/reconciler/memory.js +190 -0
- package/dist/_internal/reconciler/milestones.d.ts +7 -0
- package/dist/_internal/reconciler/milestones.js +58 -0
- package/dist/_internal/reconciler/missing.d.ts +18 -0
- package/dist/_internal/reconciler/missing.js +79 -0
- package/dist/_internal/reconciler/model.d.ts +350 -0
- package/dist/_internal/reconciler/model.js +9 -0
- package/dist/_internal/reconciler/notices.d.ts +14 -0
- package/dist/_internal/reconciler/notices.js +80 -0
- package/dist/_internal/reconciler/occurrences.d.ts +3 -0
- package/dist/_internal/reconciler/occurrences.js +30 -0
- package/dist/_internal/reconciler/outputs.d.ts +12 -0
- package/dist/_internal/reconciler/outputs.js +132 -0
- package/dist/_internal/reconciler/parameters.d.ts +4 -0
- package/dist/_internal/reconciler/parameters.js +27 -0
- package/dist/_internal/reconciler/policies.d.ts +22 -0
- package/dist/_internal/reconciler/policies.js +94 -0
- package/dist/_internal/reconciler/policy-edits.d.ts +11 -0
- package/dist/_internal/reconciler/policy-edits.js +42 -0
- package/dist/_internal/reconciler/policy-linking.d.ts +4 -0
- package/dist/_internal/reconciler/policy-linking.js +104 -0
- package/dist/_internal/reconciler/principal-types.d.ts +2 -0
- package/dist/_internal/reconciler/principal-types.js +38 -0
- package/dist/_internal/reconciler/prior-decisions.d.ts +3 -0
- package/dist/_internal/reconciler/prior-decisions.js +34 -0
- package/dist/_internal/reconciler/projections.d.ts +4 -0
- package/dist/_internal/reconciler/projections.js +85 -0
- package/dist/_internal/reconciler/proofs.d.ts +9 -0
- package/dist/_internal/reconciler/proofs.js +24 -0
- package/dist/_internal/reconciler/properties.d.ts +25 -0
- package/dist/_internal/reconciler/properties.js +67 -0
- package/dist/_internal/reconciler/property-eval.d.ts +5 -0
- package/dist/_internal/reconciler/property-eval.js +101 -0
- package/dist/_internal/reconciler/property-generator.d.ts +9 -0
- package/dist/_internal/reconciler/property-generator.js +288 -0
- package/dist/_internal/reconciler/property-shrink.d.ts +14 -0
- package/dist/_internal/reconciler/property-shrink.js +183 -0
- package/dist/_internal/reconciler/provenance.d.ts +8 -0
- package/dist/_internal/reconciler/provenance.js +61 -0
- package/dist/_internal/reconciler/reconcile.d.ts +32 -0
- package/dist/_internal/reconciler/reconcile.js +164 -0
- package/dist/_internal/reconciler/recurrence.d.ts +9 -0
- package/dist/_internal/reconciler/recurrence.js +44 -0
- package/dist/_internal/reconciler/requirements.d.ts +5 -0
- package/dist/_internal/reconciler/requirements.js +331 -0
- package/dist/_internal/reconciler/resource-generation.d.ts +9 -0
- package/dist/_internal/reconciler/resource-generation.js +17 -0
- package/dist/_internal/reconciler/resource-scenarios.d.ts +26 -0
- package/dist/_internal/reconciler/resource-scenarios.js +78 -0
- package/dist/_internal/reconciler/resources.d.ts +24 -0
- package/dist/_internal/reconciler/resources.js +178 -0
- package/dist/_internal/reconciler/result-digest.d.ts +13 -0
- package/dist/_internal/reconciler/result-digest.js +66 -0
- package/dist/_internal/reconciler/reuse.d.ts +16 -0
- package/dist/_internal/reconciler/reuse.js +119 -0
- package/dist/_internal/reconciler/scenarios.d.ts +32 -0
- package/dist/_internal/reconciler/scenarios.js +442 -0
- package/dist/_internal/reconciler/scheduling.d.ts +9 -0
- package/dist/_internal/reconciler/scheduling.js +203 -0
- package/dist/_internal/reconciler/sha256.d.ts +1 -0
- package/dist/_internal/reconciler/sha256.js +1 -0
- package/dist/_internal/reconciler/signatures.d.ts +13 -0
- package/dist/_internal/reconciler/signatures.js +37 -0
- package/dist/_internal/reconciler/temporal.d.ts +10 -0
- package/dist/_internal/reconciler/temporal.js +46 -0
- package/dist/_internal/reconciler/upgrades.d.ts +6 -0
- package/dist/_internal/reconciler/upgrades.js +65 -0
- package/dist/_internal/reconciler/wire.d.ts +2 -0
- package/dist/_internal/reconciler/wire.js +5 -0
- package/dist/_internal/reconciler/work.d.ts +32 -0
- package/dist/_internal/reconciler/work.js +101 -0
- package/dist/_internal/world-ir/schema.generated.d.ts +180 -0
- package/dist/_internal/world-ir/schema.generated.js +1127 -0
- package/dist/_internal/world-ir/types.generated.d.ts +1011 -0
- package/dist/_internal/world-ir/types.generated.js +1 -0
- package/dist/authoring.d.ts +9 -0
- package/dist/authoring.js +10 -0
- package/dist/catalogue.d.ts +20 -0
- package/dist/catalogue.js +531 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +553 -0
- package/dist/codegen.d.ts +6 -0
- package/dist/codegen.js +89 -0
- package/dist/coverage.d.ts +60 -0
- package/dist/coverage.js +128 -0
- package/dist/deploy.d.ts +21 -0
- package/dist/deploy.js +72 -0
- package/dist/diagnostics.d.ts +9 -0
- package/dist/diagnostics.js +37 -0
- package/dist/diff.d.ts +17 -0
- package/dist/diff.js +19 -0
- package/dist/durable-object.d.ts +14 -0
- package/dist/durable-object.js +30 -0
- package/dist/explain.d.ts +113 -0
- package/dist/explain.js +225 -0
- package/dist/fixes.d.ts +4 -0
- package/dist/fixes.js +70 -0
- package/dist/fmt.d.ts +12 -0
- package/dist/fmt.js +39 -0
- package/dist/handle/open.d.ts +18 -0
- package/dist/handle/open.js +28 -0
- package/dist/handle/protocol.d.ts +12 -0
- package/dist/handle/protocol.js +96 -0
- package/dist/handle/store.d.ts +31 -0
- package/dist/handle/store.js +11 -0
- package/dist/handle/types.d.ts +37 -0
- package/dist/handle/types.js +1 -0
- package/dist/handle/world.d.ts +190 -0
- package/dist/handle/world.js +533 -0
- package/dist/http.d.ts +3 -0
- package/dist/http.js +72 -0
- package/dist/impact.d.ts +21 -0
- package/dist/impact.js +57 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +43 -0
- package/dist/init.d.ts +13 -0
- package/dist/init.js +99 -0
- package/dist/ir-schema.json +4213 -0
- package/dist/lints.d.ts +8 -0
- package/dist/lints.js +154 -0
- package/dist/lsp.d.ts +14 -0
- package/dist/lsp.js +380 -0
- package/dist/manual/catalog.d.ts +12 -0
- package/dist/manual/catalog.js +23 -0
- package/dist/manual/examples.d.ts +15 -0
- package/dist/manual/examples.js +39 -0
- package/dist/manual/projections.d.ts +77 -0
- package/dist/manual/projections.js +344 -0
- package/dist/manual/prose.d.ts +19 -0
- package/dist/manual/prose.js +215 -0
- package/dist/manual/render.d.ts +76 -0
- package/dist/manual/render.js +250 -0
- package/dist/manual/text.d.ts +7 -0
- package/dist/manual/text.js +15 -0
- package/dist/mcp.d.ts +32 -0
- package/dist/mcp.js +269 -0
- package/dist/mutate.d.ts +36 -0
- package/dist/mutate.js +123 -0
- package/dist/project.d.ts +26 -0
- package/dist/project.js +80 -0
- package/dist/refine.d.ts +18 -0
- package/dist/refine.js +197 -0
- package/dist/release/diff.d.ts +45 -0
- package/dist/release/diff.js +103 -0
- package/dist/release/impact.d.ts +83 -0
- package/dist/release/impact.js +214 -0
- package/dist/release/nodes.d.ts +20 -0
- package/dist/release/nodes.js +118 -0
- package/dist/render.d.ts +19 -0
- package/dist/render.js +43 -0
- package/dist/serve.d.ts +18 -0
- package/dist/serve.js +140 -0
- package/dist/snapshot.d.ts +19 -0
- package/dist/snapshot.js +45 -0
- package/dist/sqlite.d.ts +16 -0
- package/dist/sqlite.js +151 -0
- package/dist/test.d.ts +54 -0
- package/dist/test.js +131 -0
- package/dist/world.d.ts +7 -0
- package/dist/world.js +5 -0
- package/docs/authoring/vendor-risk/example.forma +11 -0
- package/docs/authoring/vendor-risk/library/vendor.forma +76 -0
- package/docs/authoring/vendor-risk/scenarios/reviews.forma +107 -0
- package/docs/protocol.md +195 -0
- package/docs/reference.md +258 -0
- package/package.json +81 -3
package/dist/snapshot.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { sqlite } from "./sqlite.js";
|
|
4
|
+
/** Export committed records without opening a host or evaluating them under new rules. */
|
|
5
|
+
export const snapshotDatabase = async (filename, account) => {
|
|
6
|
+
const store = sqlite(filename, { readOnly: true });
|
|
7
|
+
try {
|
|
8
|
+
const state = await store.load();
|
|
9
|
+
if (!state)
|
|
10
|
+
throw new Error(`No committed world in ${filename}.`);
|
|
11
|
+
return {
|
|
12
|
+
format: "worldvm/world@1",
|
|
13
|
+
accounts: [account],
|
|
14
|
+
release: state.release,
|
|
15
|
+
world: state.records,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
await store.close();
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/** Reads a snapshot and checks that every world it will be evaluated under declares its accounts. */
|
|
23
|
+
export const readSnapshot = async (input, worlds, code) => {
|
|
24
|
+
const path = resolve(input);
|
|
25
|
+
const fail = (message, help) => ({
|
|
26
|
+
diagnostic: { code, severity: "error", message, at: null, help, fix: null },
|
|
27
|
+
});
|
|
28
|
+
let snapshot;
|
|
29
|
+
try {
|
|
30
|
+
snapshot = JSON.parse(await readFile(path, "utf8"));
|
|
31
|
+
if (snapshot.format !== "worldvm/world@1" ||
|
|
32
|
+
!Array.isArray(snapshot.accounts) ||
|
|
33
|
+
!snapshot.accounts.length)
|
|
34
|
+
throw new Error(`Expected format worldvm/world@1 with accounts in ${path}.`);
|
|
35
|
+
}
|
|
36
|
+
catch (cause) {
|
|
37
|
+
return fail(String(cause), "Pass a worldvm/world@1 JSON snapshot: { format, accounts, world }.");
|
|
38
|
+
}
|
|
39
|
+
for (const ir of worlds) {
|
|
40
|
+
const undeclared = snapshot.accounts.filter((n) => !ir.accounts.some((a) => a.name === n));
|
|
41
|
+
if (undeclared.length)
|
|
42
|
+
return fail(`Snapshot accounts ${undeclared.join(", ")} are not declared by this world.`, `Declared accounts: ${ir.accounts.map((a) => a.name).join(", ")}.`);
|
|
43
|
+
}
|
|
44
|
+
return { snapshot };
|
|
45
|
+
};
|
package/dist/sqlite.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IR } from "./_internal/reconciler/index.js";
|
|
2
|
+
import type { Store, StoreState } from "./handle/store.js";
|
|
3
|
+
export interface DeployedRelease {
|
|
4
|
+
readonly release: string;
|
|
5
|
+
readonly account: string;
|
|
6
|
+
readonly at: string;
|
|
7
|
+
readonly ir: IR.WorldIR;
|
|
8
|
+
}
|
|
9
|
+
export interface SQLiteStore extends Store {
|
|
10
|
+
readonly deployed: () => DeployedRelease | null;
|
|
11
|
+
readonly deploy: (release: DeployedRelease, state: StoreState) => void;
|
|
12
|
+
}
|
|
13
|
+
/** Durable single-file storage. Pass ":memory:" for a throwaway database. */
|
|
14
|
+
export declare const sqlite: (filename: string, options?: {
|
|
15
|
+
readonly readOnly?: boolean;
|
|
16
|
+
}) => SQLiteStore;
|
package/dist/sqlite.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
// One account in one SQLite file. Each record stream is stored one row per record, and a
|
|
3
|
+
// commit writes only the rows that changed, inside a single transaction. SQLite's journal
|
|
4
|
+
// makes the commit atomic: a crash leaves the previous state or the new one.
|
|
5
|
+
const FORMAT = "worldvm/sqlite-store@3";
|
|
6
|
+
/** Durable single-file storage. Pass ":memory:" for a throwaway database. */
|
|
7
|
+
export const sqlite = (filename, options = {}) => {
|
|
8
|
+
// Keep the synchronous store API without loading experimental SQLite for authoring commands.
|
|
9
|
+
const { DatabaseSync } = createRequire(import.meta.url)("node:sqlite");
|
|
10
|
+
const db = new DatabaseSync(filename, { readOnly: options.readOnly ?? false });
|
|
11
|
+
try {
|
|
12
|
+
const existing = db
|
|
13
|
+
.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'meta'")
|
|
14
|
+
.get();
|
|
15
|
+
if (existing) {
|
|
16
|
+
const format = db.prepare("SELECT value FROM meta WHERE key = 'format'").get()?.["value"];
|
|
17
|
+
if (format !== undefined && format !== FORMAT)
|
|
18
|
+
throw new Error(`${filename} uses ${String(format)}; expected ${FORMAT}. Create a new database; no migration is provided.`);
|
|
19
|
+
}
|
|
20
|
+
if (!options.readOnly)
|
|
21
|
+
db.exec(`
|
|
22
|
+
PRAGMA journal_mode = WAL;
|
|
23
|
+
PRAGMA synchronous = FULL;
|
|
24
|
+
CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT NOT NULL) STRICT;
|
|
25
|
+
CREATE TABLE IF NOT EXISTS records (
|
|
26
|
+
stream TEXT NOT NULL, idx INTEGER NOT NULL, body TEXT NOT NULL,
|
|
27
|
+
PRIMARY KEY (stream, idx)
|
|
28
|
+
) STRICT, WITHOUT ROWID;
|
|
29
|
+
CREATE TABLE IF NOT EXISTS releases (
|
|
30
|
+
seq INTEGER PRIMARY KEY, release TEXT NOT NULL, account TEXT NOT NULL,
|
|
31
|
+
deployed_at TEXT NOT NULL, ir TEXT NOT NULL
|
|
32
|
+
) STRICT;
|
|
33
|
+
CREATE TABLE IF NOT EXISTS receipts (id TEXT PRIMARY KEY, body TEXT NOT NULL) STRICT;
|
|
34
|
+
`);
|
|
35
|
+
const meta = db.prepare("SELECT value FROM meta WHERE key = ?"), setMeta = db.prepare("INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT (key) DO UPDATE SET value = excluded.value"), put = db.prepare("INSERT INTO records (stream, idx, body) VALUES (?, ?, ?) ON CONFLICT (stream, idx) DO UPDATE SET body = excluded.body"), truncate = db.prepare("DELETE FROM records WHERE stream = ? AND idx >= ?"), putReceipt = db.prepare("INSERT OR IGNORE INTO receipts (id, body) VALUES (?, ?)");
|
|
36
|
+
// What is on disk, so a commit can write only the difference.
|
|
37
|
+
let committed = null;
|
|
38
|
+
let deploying;
|
|
39
|
+
const store = {
|
|
40
|
+
deployed: () => {
|
|
41
|
+
const row = db.prepare("SELECT * FROM releases ORDER BY seq DESC LIMIT 1").get();
|
|
42
|
+
return row
|
|
43
|
+
? {
|
|
44
|
+
release: String(row["release"]),
|
|
45
|
+
account: String(row["account"]),
|
|
46
|
+
at: String(row["deployed_at"]),
|
|
47
|
+
ir: JSON.parse(String(row["ir"])),
|
|
48
|
+
}
|
|
49
|
+
: null;
|
|
50
|
+
},
|
|
51
|
+
deploy: (release, state) => {
|
|
52
|
+
deploying = release;
|
|
53
|
+
try {
|
|
54
|
+
store.commit(state);
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
deploying = undefined;
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
load: () => {
|
|
61
|
+
db.exec("BEGIN");
|
|
62
|
+
try {
|
|
63
|
+
const release = meta.get("release")?.["value"];
|
|
64
|
+
if (typeof release !== "string") {
|
|
65
|
+
db.exec("COMMIT");
|
|
66
|
+
committed = null;
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const streams = {};
|
|
70
|
+
for (const row of db
|
|
71
|
+
.prepare("SELECT stream, body FROM records ORDER BY stream, idx")
|
|
72
|
+
.all())
|
|
73
|
+
(streams[row["stream"]] ??= []).push(JSON.parse(row["body"]));
|
|
74
|
+
const receipts = Object.create(null);
|
|
75
|
+
for (const row of db.prepare("SELECT id, body FROM receipts").all())
|
|
76
|
+
receipts[row["id"]] = JSON.parse(row["body"]);
|
|
77
|
+
const loaded = {
|
|
78
|
+
release,
|
|
79
|
+
revision: Number(meta.get("revision")?.["value"] ?? 0),
|
|
80
|
+
// The kernel requires these streams to exist even when empty.
|
|
81
|
+
records: {
|
|
82
|
+
facts: [],
|
|
83
|
+
evidence: [],
|
|
84
|
+
acceptances: [],
|
|
85
|
+
signals: [],
|
|
86
|
+
dispatches: [],
|
|
87
|
+
journal: [],
|
|
88
|
+
...streams,
|
|
89
|
+
},
|
|
90
|
+
receipts,
|
|
91
|
+
proposals: JSON.parse(String(meta.get("proposals")?.["value"] ?? "{}")),
|
|
92
|
+
};
|
|
93
|
+
db.exec("COMMIT");
|
|
94
|
+
committed = loaded;
|
|
95
|
+
return committed;
|
|
96
|
+
}
|
|
97
|
+
catch (cause) {
|
|
98
|
+
db.exec("ROLLBACK");
|
|
99
|
+
throw cause;
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
commit: (next) => {
|
|
103
|
+
db.exec("BEGIN IMMEDIATE");
|
|
104
|
+
try {
|
|
105
|
+
if (deploying)
|
|
106
|
+
db.prepare("INSERT INTO releases (release, account, deployed_at, ir) VALUES (?, ?, ?, ?)").run(deploying.release, deploying.account, deploying.at, JSON.stringify(deploying.ir));
|
|
107
|
+
setMeta.run("format", FORMAT);
|
|
108
|
+
setMeta.run("release", next.release);
|
|
109
|
+
setMeta.run("revision", String(next.revision));
|
|
110
|
+
setMeta.run("proposals", JSON.stringify(next.proposals));
|
|
111
|
+
const streams = new Set([
|
|
112
|
+
...Object.keys(next.records),
|
|
113
|
+
...Object.keys(committed?.records ?? {}),
|
|
114
|
+
]);
|
|
115
|
+
for (const stream of streams) {
|
|
116
|
+
const before = committed?.records[stream] ?? [], after = next.records[stream] ?? [];
|
|
117
|
+
if (before === after)
|
|
118
|
+
continue;
|
|
119
|
+
// The kernel shares unchanged records by reference, so this scan is cheap.
|
|
120
|
+
for (let i = 0; i < after.length; i++) {
|
|
121
|
+
if (before[i] === after[i])
|
|
122
|
+
continue;
|
|
123
|
+
const body = JSON.stringify(after[i]);
|
|
124
|
+
if (i >= before.length || JSON.stringify(before[i]) !== body)
|
|
125
|
+
put.run(stream, i, body);
|
|
126
|
+
}
|
|
127
|
+
if (after.length < before.length)
|
|
128
|
+
truncate.run(stream, after.length);
|
|
129
|
+
}
|
|
130
|
+
for (const [id, receipt] of Object.entries(next.receipts))
|
|
131
|
+
if (committed?.receipts[id] !== receipt)
|
|
132
|
+
putReceipt.run(id, JSON.stringify(receipt));
|
|
133
|
+
db.exec("COMMIT");
|
|
134
|
+
}
|
|
135
|
+
catch (cause) {
|
|
136
|
+
db.exec("ROLLBACK");
|
|
137
|
+
throw cause;
|
|
138
|
+
}
|
|
139
|
+
committed = next;
|
|
140
|
+
},
|
|
141
|
+
close: () => db.close(),
|
|
142
|
+
};
|
|
143
|
+
return store;
|
|
144
|
+
}
|
|
145
|
+
catch (cause) {
|
|
146
|
+
db.close();
|
|
147
|
+
if (/locked|busy/i.test(String(cause)))
|
|
148
|
+
throw new Error("Database is locked. Stop worldvm serve before deploying.");
|
|
149
|
+
throw cause;
|
|
150
|
+
}
|
|
151
|
+
};
|
package/dist/test.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type IR, type WorldReconciliation, type CoverageReference } from "./_internal/reconciler/index.js";
|
|
2
|
+
import { type CliDiagnostic, type Project } from "./project.js";
|
|
3
|
+
export interface TestOptions {
|
|
4
|
+
readonly seed?: number;
|
|
5
|
+
readonly cases?: number;
|
|
6
|
+
readonly scenario?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface TestFailure extends CliDiagnostic {
|
|
9
|
+
readonly at: IR.Span;
|
|
10
|
+
readonly expected?: unknown;
|
|
11
|
+
readonly actual?: unknown;
|
|
12
|
+
}
|
|
13
|
+
export interface PropertyTestFailure extends CliDiagnostic {
|
|
14
|
+
readonly at: IR.Span;
|
|
15
|
+
readonly seed: number;
|
|
16
|
+
readonly index: number;
|
|
17
|
+
readonly binding: string;
|
|
18
|
+
readonly actual: "false" | "Unknown";
|
|
19
|
+
readonly counterexample: {
|
|
20
|
+
readonly source: string;
|
|
21
|
+
readonly attempts: number;
|
|
22
|
+
readonly complete: boolean;
|
|
23
|
+
readonly originalSize: number;
|
|
24
|
+
readonly shrunkSize: number;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export interface TestReport {
|
|
28
|
+
readonly format: "worldvm/test@1";
|
|
29
|
+
readonly command: "test";
|
|
30
|
+
readonly directory: string;
|
|
31
|
+
readonly ok: boolean;
|
|
32
|
+
readonly diagnostics: readonly CliDiagnostic[];
|
|
33
|
+
readonly scenarios: readonly {
|
|
34
|
+
readonly name: string;
|
|
35
|
+
readonly passed: boolean;
|
|
36
|
+
readonly assertions: number;
|
|
37
|
+
readonly failures: readonly TestFailure[];
|
|
38
|
+
}[];
|
|
39
|
+
readonly properties: readonly {
|
|
40
|
+
readonly name: string;
|
|
41
|
+
readonly passed: boolean;
|
|
42
|
+
readonly seed: number;
|
|
43
|
+
readonly cases: number;
|
|
44
|
+
readonly checks: number;
|
|
45
|
+
readonly antecedents: readonly {
|
|
46
|
+
readonly at: IR.Span;
|
|
47
|
+
readonly cases: number;
|
|
48
|
+
}[];
|
|
49
|
+
readonly failure?: PropertyTestFailure;
|
|
50
|
+
}[];
|
|
51
|
+
}
|
|
52
|
+
export declare const testDirectory: (directory: string, options?: TestOptions) => Promise<TestReport>;
|
|
53
|
+
/** The CLI commands share execution; coverage observes tests before any shrink replay. */
|
|
54
|
+
export declare const runTests: (project: Project, options?: TestOptions, observe?: (reconciliation: WorldReconciliation, reference: CoverageReference) => void) => TestReport;
|
package/dist/test.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { createScenarioRunner, checkProperty, shrinkPropertyFailure, validatePropertyOptions, Unknown, } from "./_internal/reconciler/index.js";
|
|
2
|
+
import { loadProject } from "./project.js";
|
|
3
|
+
const scenarioFailure = (f) => ({
|
|
4
|
+
code: f.code,
|
|
5
|
+
at: f.at,
|
|
6
|
+
message: f.message,
|
|
7
|
+
severity: "error",
|
|
8
|
+
help: "Inspect this expectation and its rule/proof, then correct the rule or example.",
|
|
9
|
+
fix: null,
|
|
10
|
+
...(f.expected === undefined ? {} : { expected: f.expected }),
|
|
11
|
+
...(f.actual === undefined ? {} : { actual: f.actual instanceof Unknown ? "Unknown" : f.actual }),
|
|
12
|
+
});
|
|
13
|
+
export const testDirectory = async (directory, options = {}) => {
|
|
14
|
+
validatePropertyOptions({ seed: options.seed ?? 0, cases: options.cases ?? 100 });
|
|
15
|
+
return runTests(await loadProject(directory), options);
|
|
16
|
+
};
|
|
17
|
+
/** The CLI commands share execution; coverage observes tests before any shrink replay. */
|
|
18
|
+
export const runTests = (project, options = {}, observe) => {
|
|
19
|
+
const budgets = { seed: options.seed ?? 0, cases: options.cases ?? 100 };
|
|
20
|
+
validatePropertyOptions(budgets);
|
|
21
|
+
const diagnostics = [...project.diagnostics];
|
|
22
|
+
const scenarios = [], properties = [];
|
|
23
|
+
const report = () => ({
|
|
24
|
+
format: "worldvm/test@1",
|
|
25
|
+
command: "test",
|
|
26
|
+
directory: project.directory,
|
|
27
|
+
ok: !!project.ir &&
|
|
28
|
+
!diagnostics.some((d) => d.severity === "error") &&
|
|
29
|
+
scenarios.every((s) => s.passed) &&
|
|
30
|
+
properties.every((p) => p.passed),
|
|
31
|
+
diagnostics,
|
|
32
|
+
scenarios,
|
|
33
|
+
properties,
|
|
34
|
+
});
|
|
35
|
+
if (!project.ir || diagnostics.some((d) => d.severity === "error"))
|
|
36
|
+
return report();
|
|
37
|
+
const ir = project.ir;
|
|
38
|
+
const run = createScenarioRunner(ir);
|
|
39
|
+
const selected = (ir.scenarios ?? []).filter((s) => options.scenario === undefined || s.name === options.scenario);
|
|
40
|
+
if (options.scenario !== undefined && !selected.length) {
|
|
41
|
+
diagnostics.push({
|
|
42
|
+
code: "E_SCENARIO_NOT_FOUND",
|
|
43
|
+
severity: "error",
|
|
44
|
+
message: `No scenario named ${options.scenario}.`,
|
|
45
|
+
at: null,
|
|
46
|
+
help: `Use one of: ${(ir.scenarios ?? []).map((s) => s.name).join(", ") || "no scenarios declared"}.`,
|
|
47
|
+
fix: null,
|
|
48
|
+
});
|
|
49
|
+
return report();
|
|
50
|
+
}
|
|
51
|
+
const runtimeError = (cause, at) => diagnostics.push({
|
|
52
|
+
code: "E_TEST_RUNTIME",
|
|
53
|
+
severity: "error",
|
|
54
|
+
message: String(cause),
|
|
55
|
+
at,
|
|
56
|
+
help: "Reduce this test-engine failure to its source example and report it.",
|
|
57
|
+
fix: null,
|
|
58
|
+
});
|
|
59
|
+
for (const scenario of selected) {
|
|
60
|
+
try {
|
|
61
|
+
const result = run(scenario);
|
|
62
|
+
for (const step of result.steps)
|
|
63
|
+
observe?.(step.reconciliation, { kind: "scenario", name: scenario.name });
|
|
64
|
+
scenarios.push({
|
|
65
|
+
name: result.name,
|
|
66
|
+
passed: result.passed,
|
|
67
|
+
assertions: result.assertions,
|
|
68
|
+
failures: result.failures.map(scenarioFailure),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
catch (cause) {
|
|
72
|
+
runtimeError(cause, scenario.at);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (options.scenario === undefined)
|
|
76
|
+
for (const property of ir.properties ?? []) {
|
|
77
|
+
try {
|
|
78
|
+
const result = checkProperty(ir, property, budgets, (observed) => {
|
|
79
|
+
for (const step of observed.steps)
|
|
80
|
+
observe?.(step.reconciliation, { kind: "property", name: property.name });
|
|
81
|
+
}, run), f = result.failure;
|
|
82
|
+
for (const antecedent of result.antecedents)
|
|
83
|
+
if (antecedent.cases === 0)
|
|
84
|
+
diagnostics.push({
|
|
85
|
+
code: "W_PROPERTY_VACUOUS",
|
|
86
|
+
severity: "warning",
|
|
87
|
+
message: `${property.name}: implication antecedent was true in 0 of ${result.cases} generated cases.`,
|
|
88
|
+
at: antecedent.at,
|
|
89
|
+
help: "Seed facts and evidence with a property given block so this antecedent is exercised.",
|
|
90
|
+
fix: null,
|
|
91
|
+
});
|
|
92
|
+
if (!f) {
|
|
93
|
+
properties.push({
|
|
94
|
+
name: result.name,
|
|
95
|
+
passed: result.passed,
|
|
96
|
+
seed: result.seed,
|
|
97
|
+
cases: result.cases,
|
|
98
|
+
checks: result.checks,
|
|
99
|
+
antecedents: result.antecedents,
|
|
100
|
+
});
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
const { source, attempts, complete, originalSize, shrunkSize } = shrinkPropertyFailure(ir, property, f);
|
|
104
|
+
properties.push({
|
|
105
|
+
name: result.name,
|
|
106
|
+
passed: false,
|
|
107
|
+
seed: result.seed,
|
|
108
|
+
cases: result.cases,
|
|
109
|
+
checks: result.checks,
|
|
110
|
+
antecedents: result.antecedents,
|
|
111
|
+
failure: {
|
|
112
|
+
code: "E_PROPERTY_ASSERT",
|
|
113
|
+
severity: "error",
|
|
114
|
+
message: `${property.name} was ${f.actual} for ${f.binding}, seed ${f.seed}, case ${f.index}.`,
|
|
115
|
+
at: f.at,
|
|
116
|
+
help: "Compile the counterexample with the original definitions/property to replay this failed claim.",
|
|
117
|
+
fix: null,
|
|
118
|
+
seed: f.seed,
|
|
119
|
+
index: f.index,
|
|
120
|
+
binding: f.binding,
|
|
121
|
+
actual: f.actual,
|
|
122
|
+
counterexample: { source, attempts, complete, originalSize, shrunkSize },
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
catch (cause) {
|
|
127
|
+
runtimeError(cause, property.predicate.at);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return report();
|
|
131
|
+
};
|
package/dist/world.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { open, type OpenOptions } from "./handle/open.js";
|
|
2
|
+
export { host, WorldError, type Actor, type Change, type HostOptions, type InstanceStatus, type Operation, type Outcome, type PerformOptions, type RequirementStatus, type Scalar, type Status, type Subject, type SubjectStatus, type WorkItem, type World, type WriteOptions, } from "./handle/world.js";
|
|
3
|
+
export { memory, type Receipt, type Store, type StoreState } from "./handle/store.js";
|
|
4
|
+
export type { ExplainedRequirement } from "./explain.js";
|
|
5
|
+
export type { WorldTypes, TypedWorld, TypedSubject, WorkId } from "./handle/types.js";
|
|
6
|
+
export { operate } from "./handle/protocol.js";
|
|
7
|
+
export type { Draft, Proposal, Verb, Request, Response, Result, ProtocolError, } from "./_internal/protocol/index.js";
|
package/dist/world.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
;; Synthetic example account; illustrative only.
|
|
2
|
+
(entity Person "A synthetic person." :ns :example.person :display name
|
|
3
|
+
:implements {vendor/person {:name name}} {:name String})
|
|
4
|
+
(entity Vendor "A synthetic vendor." :ns :example.vendor :display name
|
|
5
|
+
:implements {vendor/record {:name name :owner owner :cisos cisos :tier tier :status status
|
|
6
|
+
:opened opened}}
|
|
7
|
+
{:name String :owner (Id Person) :cisos Group :tier RiskTier :status VendorStatus
|
|
8
|
+
:opened Date})
|
|
9
|
+
(account example "An isolated synthetic vendor-risk account."
|
|
10
|
+
:requires {example.vendor-risk "1.0"} :package example
|
|
11
|
+
(for-each vendor/record VendorReview))
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
;; Vendor risk review, rewritten from the cold-author trial with the AUTHORING.md idioms.
|
|
2
|
+
;; Synthetic policy; illustrative, not legal or compliance advice.
|
|
3
|
+
(library example.vendor-risk
|
|
4
|
+
"Security review requirements for vendors that touch customer data."
|
|
5
|
+
:version "1.0" :subject vendor/record)
|
|
6
|
+
|
|
7
|
+
(type RiskTier (Union :high :standard :none))
|
|
8
|
+
(type VendorStatus (Union :onboarding :active))
|
|
9
|
+
(role vendor/person "A reviewer, CISO or procurement user." {:name String})
|
|
10
|
+
(role vendor/record "A vendor with a review owner, CISO group and lifecycle status."
|
|
11
|
+
{:name String :owner (Id vendor/person) :cisos Group :tier RiskTier
|
|
12
|
+
:status VendorStatus :opened Date})
|
|
13
|
+
|
|
14
|
+
(source vendor-policy
|
|
15
|
+
"Synthetic vendor-risk policy; not legal or compliance advice."
|
|
16
|
+
:kind :policy :url "https://example.invalid/vendor-policy" :as-of "2026-11-06")
|
|
17
|
+
|
|
18
|
+
(evidence SecurityQuestionnaire "A completed, signed vendor security questionnaire." :of VendorReview
|
|
19
|
+
:expires (months-after signed-on 12)
|
|
20
|
+
{:summary String}
|
|
21
|
+
(attest :signer vendor.owner :covers :all :method :otp))
|
|
22
|
+
(evidence Soc2Report "A SOC 2 Type II report, valid until the date its auditor states." :of VendorReview
|
|
23
|
+
:expires valid-until
|
|
24
|
+
{:summary String :valid-until Date}
|
|
25
|
+
(attest :signer vendor.owner :covers :all :method :otp))
|
|
26
|
+
(evidence DataProcessingAgreement "A signed data processing agreement." :of VendorReview
|
|
27
|
+
{:summary String}
|
|
28
|
+
(attest :signer vendor.owner :covers :all :method :otp))
|
|
29
|
+
|
|
30
|
+
(layout ReviewLayout "Record and sign a review artifact."
|
|
31
|
+
(step record "Record" (field summary) (sign)))
|
|
32
|
+
(layout Soc2Layout "Record the SOC 2 report and its validity."
|
|
33
|
+
(step record "Record" (field summary) (field valid-until) (sign)))
|
|
34
|
+
(interaction QuestionnaireEntry "Complete the questionnaire."
|
|
35
|
+
:actor vendor.owner :produces SecurityQuestionnaire :layout ReviewLayout)
|
|
36
|
+
(interaction Soc2Entry "Record the SOC 2 report."
|
|
37
|
+
:actor vendor.owner :produces Soc2Report :layout Soc2Layout)
|
|
38
|
+
(interaction DpaEntry "Record the DPA."
|
|
39
|
+
:actor vendor.owner :produces DataProcessingAgreement :layout ReviewLayout)
|
|
40
|
+
|
|
41
|
+
(component VendorReview "Track the security review of one vendor."
|
|
42
|
+
:key [vendor] :inputs {:vendor (Id vendor/record)}
|
|
43
|
+
:operations [submit-questionnaire submit-soc2 submit-dpa approve-exception]
|
|
44
|
+
(requirement questionnaire
|
|
45
|
+
:cites [(vendor-policy "1: completed security questionnaire, renewed every 12 months")]
|
|
46
|
+
:applies-when (!= vendor.tier :none)
|
|
47
|
+
:satisfied-by (valid SecurityQuestionnaire)
|
|
48
|
+
:renew-within (days 30))
|
|
49
|
+
(requirement soc2-or-exception
|
|
50
|
+
:cites [(vendor-policy "2: current SOC 2 Type II or an approved exception")]
|
|
51
|
+
:applies-when (!= vendor.tier :none)
|
|
52
|
+
:satisfied-by (or (valid Soc2Report) (decided approve-exception)))
|
|
53
|
+
(requirement dpa
|
|
54
|
+
:cites [(vendor-policy "3: high-risk vendors need a DPA")]
|
|
55
|
+
:applies-when (= vendor.tier :high)
|
|
56
|
+
:satisfied-by (attested DataProcessingAgreement))
|
|
57
|
+
(requirement active-only-if-reviewed
|
|
58
|
+
:cites [(vendor-policy "4: not active while the review is incomplete or expired")]
|
|
59
|
+
:applies-when (= vendor.status :active)
|
|
60
|
+
:satisfied-by (met? self.review-complete))
|
|
61
|
+
(invariant no-activation-before-review
|
|
62
|
+
:cites [(vendor-policy "4: not active while the review is incomplete or expired")]
|
|
63
|
+
:forbids (action-kind :activate :subject vendor)
|
|
64
|
+
:while (not (met? self.review-complete)))
|
|
65
|
+
(action submit-questionnaire :advances questionnaire :assignee vendor.owner
|
|
66
|
+
:via (interaction QuestionnaireEntry))
|
|
67
|
+
(action submit-soc2 :advances soc2-or-exception :assignee vendor.owner :via (interaction Soc2Entry))
|
|
68
|
+
(action submit-dpa :advances dpa :assignee vendor.owner :via (interaction DpaEntry))
|
|
69
|
+
(output review-complete (all-of questionnaire soc2-or-exception dpa))
|
|
70
|
+
(output reviewed (all-of review-complete active-only-if-reviewed)))
|
|
71
|
+
|
|
72
|
+
(decision approve-exception
|
|
73
|
+
"Only a CISO approves a SOC 2 exception, with a reason; it lasts six months."
|
|
74
|
+
:of VendorReview :applies soc2-or-exception :by (members vendor.cisos)
|
|
75
|
+
:effect :approve :reason String :expires (months 6)
|
|
76
|
+
:cites [(vendor-policy "5: CISO-only exceptions with a reason, expiring after six months")])
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
;; Synthetic scenarios; illustrative, not legal or compliance advice.
|
|
2
|
+
(scenario high-risk-complete "A high-risk vendor with every artifact is reviewed." :world example
|
|
3
|
+
(given (entity Person owner {:name "Owner"})
|
|
4
|
+
(entity Vendor v {:name "Acme Analytics" :owner owner :cisos "CISO" :tier :high
|
|
5
|
+
:status :onboarding :opened "2026-11-06"})
|
|
6
|
+
(actor owner))
|
|
7
|
+
(at "2026-11-06" (expect (status (VendorReview v) dpa) :Open))
|
|
8
|
+
(do (evidence SecurityQuestionnaire :for (VendorReview v) :requirement questionnaire :by owner
|
|
9
|
+
:values {:summary "Completed"})
|
|
10
|
+
(evidence Soc2Report :for (VendorReview v) :requirement soc2-or-exception :by owner
|
|
11
|
+
:values {:summary "SOC 2 Type II" :valid-until "2027-06-01"})
|
|
12
|
+
(evidence DataProcessingAgreement :for (VendorReview v) :requirement dpa :by owner
|
|
13
|
+
:values {:summary "DPA on file"}))
|
|
14
|
+
(at "2026-11-07" (expect (status (VendorReview v) review-complete) :Satisfied)))
|
|
15
|
+
|
|
16
|
+
(scenario standard-needs-no-dpa "A standard-risk vendor does not need a DPA." :world example
|
|
17
|
+
(given (entity Person owner {:name "Owner"})
|
|
18
|
+
(entity Vendor v {:name "Pencils Inc" :owner owner :cisos "CISO" :tier :standard
|
|
19
|
+
:status :onboarding :opened "2026-11-06"}))
|
|
20
|
+
(at "2026-11-06"
|
|
21
|
+
(expect (status (VendorReview v) dpa) :NotApplicable)
|
|
22
|
+
(expect (status (VendorReview v) questionnaire) :Open)))
|
|
23
|
+
|
|
24
|
+
(scenario no-customer-data "A vendor that touches no customer data owes no review." :world example
|
|
25
|
+
(given (entity Person owner {:name "Owner"})
|
|
26
|
+
(entity Vendor v {:name "Coffee Co" :owner owner :cisos "CISO" :tier :none
|
|
27
|
+
:status :onboarding :opened "2026-11-06"}))
|
|
28
|
+
(at "2026-11-06"
|
|
29
|
+
(expect (status (VendorReview v) questionnaire) :NotApplicable)
|
|
30
|
+
(expect (status (VendorReview v) soc2-or-exception) :NotApplicable)
|
|
31
|
+
(expect (status (VendorReview v) review-complete) :NotApplicable)))
|
|
32
|
+
|
|
33
|
+
(scenario no-data-vendor-can-be-active "A vendor that owes no review may be activated." :world example
|
|
34
|
+
(given (entity Person owner {:name "Owner"}) (entity Person buyer {:name "Buyer"})
|
|
35
|
+
(entity Vendor v {:name "Coffee Co" :owner owner :cisos "CISO" :tier :none
|
|
36
|
+
:status :onboarding :opened "2026-11-06"})
|
|
37
|
+
(actor buyer :groups ["Procurement"]))
|
|
38
|
+
(do (set v :status :active :kind :activate :subject v :by buyer))
|
|
39
|
+
(at "2026-11-06" (expect (status (VendorReview v) active-only-if-reviewed) :Satisfied)))
|
|
40
|
+
|
|
41
|
+
(scenario soc2-report-expires "A SOC 2 report counts until its stated validity date." :world example
|
|
42
|
+
(given (entity Person owner {:name "Owner"})
|
|
43
|
+
(entity Vendor v {:name "Acme Analytics" :owner owner :cisos "CISO" :tier :standard
|
|
44
|
+
:status :onboarding :opened "2026-11-06"})
|
|
45
|
+
(actor owner))
|
|
46
|
+
(do (evidence Soc2Report :for (VendorReview v) :requirement soc2-or-exception :by owner
|
|
47
|
+
:values {:summary "SOC 2 Type II" :valid-until "2027-06-01"}))
|
|
48
|
+
(at "2027-05-31" (expect (status (VendorReview v) soc2-or-exception) :Satisfied))
|
|
49
|
+
(at "2027-06-01" (expect (status (VendorReview v) soc2-or-exception) :Open)))
|
|
50
|
+
|
|
51
|
+
(scenario questionnaire-expires "A questionnaire lasts 12 months from signing, then reopens." :world example
|
|
52
|
+
(given (entity Person owner {:name "Owner"})
|
|
53
|
+
(entity Vendor v {:name "Acme Analytics" :owner owner :cisos "CISO" :tier :standard
|
|
54
|
+
:status :onboarding :opened "2026-11-06"})
|
|
55
|
+
(actor owner))
|
|
56
|
+
(do (evidence SecurityQuestionnaire :for (VendorReview v) :requirement questionnaire :by owner
|
|
57
|
+
:values {:summary "Completed"}))
|
|
58
|
+
(at "2026-11-07" (expect (status (VendorReview v) questionnaire) :Satisfied))
|
|
59
|
+
(at "2027-11-06" (expect (status (VendorReview v) questionnaire) :Satisfied))
|
|
60
|
+
(at "2027-11-07" (expect (status (VendorReview v) questionnaire) :Open)))
|
|
61
|
+
|
|
62
|
+
(scenario ciso-exception "Only a CISO approves an exception, and it expires after six months." :world example
|
|
63
|
+
(given (entity Person owner {:name "Owner"}) (entity Person ciso {:name "CISO"})
|
|
64
|
+
(entity Vendor v {:name "Acme Analytics" :owner owner :cisos "CISO" :tier :standard
|
|
65
|
+
:status :onboarding :opened "2026-11-06"})
|
|
66
|
+
(actor owner :groups ["Owners"]) (actor ciso :groups ["CISO"]))
|
|
67
|
+
(do (decide (VendorReview v) approve-exception :by owner :reason "I want it"))
|
|
68
|
+
(at "2026-11-06"
|
|
69
|
+
(expect (rejected 1) :decision-authority)
|
|
70
|
+
(expect (status (VendorReview v) soc2-or-exception) :Open))
|
|
71
|
+
(do (decide (VendorReview v) approve-exception :by ciso :reason "Compensating controls reviewed"))
|
|
72
|
+
(at "2026-11-07" (expect (status (VendorReview v) soc2-or-exception) :Satisfied))
|
|
73
|
+
(at "2027-05-06" (expect (status (VendorReview v) soc2-or-exception) :Satisfied))
|
|
74
|
+
(at "2027-05-07" (expect (status (VendorReview v) soc2-or-exception) :Open)))
|
|
75
|
+
|
|
76
|
+
(scenario activation-blocked "Procurement cannot activate a vendor until its review is complete." :world example
|
|
77
|
+
(given (entity Person owner {:name "Owner"}) (entity Person buyer {:name "Buyer"})
|
|
78
|
+
(entity Vendor v {:name "Acme Analytics" :owner owner :cisos "CISO" :tier :standard
|
|
79
|
+
:status :onboarding :opened "2026-11-06"})
|
|
80
|
+
(actor owner) (actor buyer :groups ["Procurement"]))
|
|
81
|
+
(do (set v :status :active :kind :activate :subject v :by buyer))
|
|
82
|
+
(at "2026-11-06"
|
|
83
|
+
(expect (rejected 1) :no-activation-before-review)
|
|
84
|
+
(expect (status (VendorReview v) active-only-if-reviewed) :NotApplicable))
|
|
85
|
+
(do (evidence SecurityQuestionnaire :for (VendorReview v) :requirement questionnaire :by owner
|
|
86
|
+
:values {:summary "Completed"})
|
|
87
|
+
(evidence Soc2Report :for (VendorReview v) :requirement soc2-or-exception :by owner
|
|
88
|
+
:values {:summary "SOC 2" :valid-until "2028-01-01"}))
|
|
89
|
+
(at "2026-11-07" (expect (status (VendorReview v) review-complete) :Satisfied))
|
|
90
|
+
(do (set v :status :active :kind :activate :subject v :by buyer))
|
|
91
|
+
(at "2026-11-08" (expect (status (VendorReview v) reviewed) :Satisfied)))
|
|
92
|
+
|
|
93
|
+
(scenario active-without-review "An active vendor with no review is flagged." :world example
|
|
94
|
+
(given (entity Person owner {:name "Owner"})
|
|
95
|
+
(entity Vendor v {:name "Rogue SaaS" :owner owner :cisos "CISO" :tier :standard
|
|
96
|
+
:status :active :opened "2026-11-06"}))
|
|
97
|
+
(at "2026-11-06" (expect (status (VendorReview v) active-only-if-reviewed) :Open)))
|
|
98
|
+
|
|
99
|
+
(property active-implies-reviewed "An active vendor that handles data is reviewed or flagged."
|
|
100
|
+
:world example :at "2026-11-06" :for-all (v Vendor)
|
|
101
|
+
(implies (and (known? v.status) (known? v.tier) (= v.status :active) (!= v.tier :none))
|
|
102
|
+
(or (= (status (VendorReview v) review-complete) :Satisfied)
|
|
103
|
+
(= (status (VendorReview v) active-only-if-reviewed) :Open))))
|
|
104
|
+
|
|
105
|
+
(property dpa-only-for-high "A vendor below high risk never owes a DPA."
|
|
106
|
+
:world example :at "2026-11-06" :for-all (v Vendor)
|
|
107
|
+
(implies (and (known? v.tier) (!= v.tier :high)) (met? (status (VendorReview v) dpa))))
|