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
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { sourceSyntax } from "../source-syntax.js";
|
|
2
|
+
import {} from "@forma-language/forma/reader";
|
|
3
|
+
import { children, headOf, items, LowerError, mapPairs, option, spanOf, symName, } from "./syntax.js";
|
|
4
|
+
const read = (form, at) => {
|
|
5
|
+
const value = option(form, "recur");
|
|
6
|
+
if (!value)
|
|
7
|
+
return undefined;
|
|
8
|
+
const pairs = mapPairs(value), keys = pairs.map(([k]) => symName(k));
|
|
9
|
+
const every = pairs.find(([k]) => symName(k) === ":every")?.[1];
|
|
10
|
+
const from = pairs.find(([k]) => symName(k) === ":from")?.[1];
|
|
11
|
+
if (value._tag !== "Map" || keys.length !== 2 || new Set(keys).size !== 2 || !every || !from)
|
|
12
|
+
throw new LowerError("E_RECUR_SHAPE", "Recurrence requires exactly :every and :from.", at(value), "Use :recur {:every (years N) :from date}, or (days N), with a positive fixed interval.");
|
|
13
|
+
const count = items(every)[1], n = count?._tag === "Num" ? Number(count.value) : NaN;
|
|
14
|
+
const unit = headOf(every);
|
|
15
|
+
if ((unit !== "days" && unit !== "years") ||
|
|
16
|
+
items(every).length !== 2 ||
|
|
17
|
+
!Number.isSafeInteger(n) ||
|
|
18
|
+
n <= 0)
|
|
19
|
+
throw new LowerError("E_RECUR_INTERVAL", "Recurrence intervals are fixed positive day or year counts.", at(every), "Use (days N) or (years N) with a positive safe-integer literal; dynamic or sub-day intervals are not supported.");
|
|
20
|
+
const cycle = option(form, "cycle");
|
|
21
|
+
if (cycle)
|
|
22
|
+
throw new LowerError("E_RECUR_CYCLE", "A requirement cannot combine :cycle and :recur.", at(cycle), "Choose :cycle for fact-keyed occurrences or :recur for anchored calendar periods.");
|
|
23
|
+
return { every: { n, unit }, from, at: at(value) };
|
|
24
|
+
};
|
|
25
|
+
/** Check closed syntax before nested Expr validation so malformed maps get actionable spans. */
|
|
26
|
+
export const recurrenceDiagnostics = (files) => {
|
|
27
|
+
for (const file of files) {
|
|
28
|
+
if (!file.text.includes(":recur"))
|
|
29
|
+
continue;
|
|
30
|
+
try {
|
|
31
|
+
for (const form of sourceSyntax(file).forms)
|
|
32
|
+
if (headOf(form) === "component")
|
|
33
|
+
for (const requirement of children(form, "requirement"))
|
|
34
|
+
read(requirement, (expr) => spanOf(file.id, expr));
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
// The normal descriptor pass owns malformed-reader diagnostics.
|
|
38
|
+
if (!(error instanceof LowerError))
|
|
39
|
+
return [];
|
|
40
|
+
return [
|
|
41
|
+
{
|
|
42
|
+
code: error.code,
|
|
43
|
+
severity: "error",
|
|
44
|
+
message: error.message,
|
|
45
|
+
at: error.at,
|
|
46
|
+
...(error.help ? { help: error.help } : {}),
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return [];
|
|
52
|
+
};
|
|
53
|
+
export const lowerRecurrence = (context, declaration, form, scope) => {
|
|
54
|
+
const value = read(form, (expr) => context.at(declaration, expr));
|
|
55
|
+
return value ? { ...value, from: context.lowerExpr(declaration, value.from, scope) } : undefined;
|
|
56
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ElaboratedDeclaration } from "@forma-language/forma/descriptor";
|
|
2
|
+
import type { SExpr } from "@forma-language/forma/reader";
|
|
3
|
+
import type * as IR from "../../../world-ir/types.generated.js";
|
|
4
|
+
import type { LoweringContext } from "./context.js";
|
|
5
|
+
export declare const lowerRenewal: (context: LoweringContext, declaration: ElaboratedDeclaration, form: SExpr) => IR.RenewalWindow | undefined;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { headOf, items, LowerError, option, symName } from "./syntax.js";
|
|
2
|
+
export const lowerRenewal = (context, declaration, form) => {
|
|
3
|
+
const value = option(form, "renew-within");
|
|
4
|
+
if (!value)
|
|
5
|
+
return undefined;
|
|
6
|
+
const count = items(value)[1], n = count?._tag === "Num" ? Number(count.value) : NaN, unit = headOf(value);
|
|
7
|
+
if ((unit !== "days" && unit !== "years") ||
|
|
8
|
+
items(value).length !== 2 ||
|
|
9
|
+
!Number.isSafeInteger(n) ||
|
|
10
|
+
n < 0)
|
|
11
|
+
throw new LowerError("E_RENEW_INTERVAL", "Renewal windows are fixed nonnegative day/year counts.", context.at(declaration, value), "Use (days N) or (years N) with a nonnegative safe-integer literal; dynamic/sub-day windows are not supported.");
|
|
12
|
+
const target = option(form, "satisfied-by"), name = symName(items(target)[1]);
|
|
13
|
+
const evidence = context.byForm("evidence").find((d) => d.summary.name === name);
|
|
14
|
+
if (headOf(target) !== "valid" ||
|
|
15
|
+
items(target).length !== 2 ||
|
|
16
|
+
!evidence ||
|
|
17
|
+
context.payload(evidence).of !== declaration.summary.name ||
|
|
18
|
+
!option(context.formOf(evidence), "expires"))
|
|
19
|
+
throw new LowerError("E_RENEW_TARGET", "Renewal requires one directly named expiring evidence type owned by this component.", context.at(declaration, target), "Use :satisfied-by (valid Evidence) with :expires on that evidence; compose additional conditions as separate requirements/outputs.");
|
|
20
|
+
return { n, unit, at: context.at(declaration, value) };
|
|
21
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ElaboratedDeclaration } from "@forma-language/forma/descriptor";
|
|
2
|
+
import type { SExpr } from "@forma-language/forma/reader";
|
|
3
|
+
import type * as IR from "../../../world-ir/types.generated.js";
|
|
4
|
+
import type { LoweringContext } from "./context.js";
|
|
5
|
+
import { type Scope } from "./syntax.js";
|
|
6
|
+
export declare const lowerResources: (context: LoweringContext, d: ElaboratedDeclaration, form: SExpr, scope: Scope) => IR.Resource[];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { children, items, LowerError, option, symName } from "./syntax.js";
|
|
2
|
+
export const lowerResources = (context, d, form, scope) => children(form, "resource").map((resource) => {
|
|
3
|
+
const call = (field) => {
|
|
4
|
+
const raw = option(resource, field);
|
|
5
|
+
if (!raw)
|
|
6
|
+
throw new LowerError("E_RESOURCE_CALL", "A resource requires acquire and release calls.", context.at(d, resource), "Use declared (connector capability) pairs for both calls.");
|
|
7
|
+
const xs = items(raw), connector = symName(xs[0]), capability = symName(xs[1]);
|
|
8
|
+
if (raw._tag !== "List" || xs.length !== 2 || !connector || !capability)
|
|
9
|
+
throw new LowerError("E_RESOURCE_CALL", "A resource call must name a connector and capability.", context.at(d, raw), "Use a declared (connector capability) pair.");
|
|
10
|
+
return { connector, capability, at: context.at(d, raw) };
|
|
11
|
+
};
|
|
12
|
+
return {
|
|
13
|
+
name: symName(items(resource)[1]),
|
|
14
|
+
acquire: call("acquire"),
|
|
15
|
+
release: call("release"),
|
|
16
|
+
releaseWhen: context.lowerExpr(d, option(resource, "release-when"), scope),
|
|
17
|
+
at: context.at(d, resource),
|
|
18
|
+
};
|
|
19
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ElaboratedDeclaration } from "@forma-language/forma/descriptor";
|
|
2
|
+
import type { SExpr } from "@forma-language/forma/reader";
|
|
3
|
+
import type * as IR from "../../../world-ir/types.generated.js";
|
|
4
|
+
import type { LoweringContext } from "./context.js";
|
|
5
|
+
export declare const lowerReuse: (cx: LoweringContext, d: ElaboratedDeclaration, form: SExpr) => IR.Reuse | undefined;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { principalActionKey, principalKinds } from "../../../ir-checks/index.js";
|
|
2
|
+
import { headOf, items, LowerError, mapPairs, option, symName } from "./syntax.js";
|
|
3
|
+
export const lowerReuse = (cx, d, form) => {
|
|
4
|
+
const value = option(form, "reuse");
|
|
5
|
+
if (!value)
|
|
6
|
+
return undefined;
|
|
7
|
+
const owner = d.summary.name, component = cx.components.get(owner);
|
|
8
|
+
const fail = (code, syntax, message, help) => {
|
|
9
|
+
throw new LowerError(code, message, cx.at(d, syntax), help);
|
|
10
|
+
};
|
|
11
|
+
const pairs = mapPairs(value), fields = new Map(pairs.map(([k, v]) => [symName(k), v]));
|
|
12
|
+
const scope = fields.get(":scope"), within = fields.get(":within"), confirm = fields.get(":confirm");
|
|
13
|
+
const scopeHelp = "Use a nonempty vector of distinct component key inputs including its direct entity home, for example [employee] in a component keyed by [employee employer]. Do not scan entities or read mutable facts for scope.";
|
|
14
|
+
if (value._tag !== "Map" ||
|
|
15
|
+
fields.size !== pairs.length ||
|
|
16
|
+
[...fields.keys()].some((k) => ![":scope", ":within", ":confirm"].includes(k ?? "")) ||
|
|
17
|
+
!scope ||
|
|
18
|
+
!within)
|
|
19
|
+
return fail("E_REUSE_SCOPE", value, "Reuse requires :scope and :within, with optional :confirm only.", scopeHelp);
|
|
20
|
+
const names = items(scope).map(symName), home = cx.homeOf(owner);
|
|
21
|
+
if (scope._tag !== "Vector" ||
|
|
22
|
+
!names.length ||
|
|
23
|
+
new Set(names).size !== names.length ||
|
|
24
|
+
names.some((n) => !n || !component.key.includes(n)) ||
|
|
25
|
+
home.path.length !== 1 ||
|
|
26
|
+
!names.includes(home.path[0]))
|
|
27
|
+
return fail("E_REUSE_SCOPE", scope, "Reuse scope must be stable, unique and contain its entity home.", scopeHelp);
|
|
28
|
+
const nValue = items(within)[1], n = nValue?._tag === "Num" ? Number(nValue.value) : NaN, unit = headOf(within);
|
|
29
|
+
if (!["days", "years", "hours", "minutes"].includes(unit ?? "") ||
|
|
30
|
+
items(within).length !== 2 ||
|
|
31
|
+
!Number.isSafeInteger(n) ||
|
|
32
|
+
n <= 0)
|
|
33
|
+
return fail("E_REUSE_INTERVAL", within, "Reuse needs a positive fixed safe-integer window.", "Use (days N), (years N), (hours N) or (minutes N) with a positive safe-integer literal.");
|
|
34
|
+
const proof = option(form, "satisfied-by"), evidenceName = symName(items(proof)[1]);
|
|
35
|
+
const evidence = cx.byForm("evidence").find((e) => e.summary.name === evidenceName);
|
|
36
|
+
if (!["attested", "valid"].includes(headOf(proof) ?? "") ||
|
|
37
|
+
items(proof).length !== 2 ||
|
|
38
|
+
!evidence ||
|
|
39
|
+
cx.payload(evidence).of !== owner ||
|
|
40
|
+
["accepts", "cycle", "recur", "renew-within"].some((k) => option(form, k)))
|
|
41
|
+
return fail("E_REUSE_TARGET", value, "Reuse needs one direct owned proof in an ordinary requirement context.", "Use (attested Evidence) or (valid Evidence) owned by this component; keep prior-cycle, recurrence and renewal in separate requirements.");
|
|
42
|
+
const env = cx.componentScope(owner);
|
|
43
|
+
let confirmation = {};
|
|
44
|
+
if (confirm) {
|
|
45
|
+
const expr = cx.lowerExpr(d, confirm, env);
|
|
46
|
+
const path = (e) => e.k === "var"
|
|
47
|
+
? component.key.includes(e.name)
|
|
48
|
+
: e.k === "read" || e.k === "attr"
|
|
49
|
+
? path(e.of)
|
|
50
|
+
: false;
|
|
51
|
+
const target = expr.k === "call" && expr.fn === "members" && expr.args.length === 1 ? expr.args[0] : expr;
|
|
52
|
+
if (!path(target))
|
|
53
|
+
return fail("E_REUSE_CONFIRM", confirm, "Confirmation must name a principal through keyed entity references.", "Use a keyed person or a group field such as employer.reviewers; literal labels and status/computed principals are unsupported.");
|
|
54
|
+
const kinds = principalKinds({
|
|
55
|
+
types: cx.authoredTypes,
|
|
56
|
+
derives: [],
|
|
57
|
+
roles: cx.byForm("role").map((e) => ({ name: e.summary.name, ...cx.payload(e) })),
|
|
58
|
+
entities: cx
|
|
59
|
+
.byForm("entity")
|
|
60
|
+
.map((e) => ({ name: e.summary.name, ...cx.payload(e) })),
|
|
61
|
+
components: [{ ...component, name: owner, actions: [{ name: "$reuse", assignee: expr }] }],
|
|
62
|
+
});
|
|
63
|
+
const kind = kinds.assignees.get(principalActionKey(owner, "$reuse"));
|
|
64
|
+
if (!kind || kinds.diagnostics.length)
|
|
65
|
+
return fail("E_REUSE_CONFIRM", confirm, "Confirmation has no proven principal kind.", "Use a keyed person or a group field such as employer.reviewers.");
|
|
66
|
+
confirmation = { confirm: expr, confirmKind: kind };
|
|
67
|
+
}
|
|
68
|
+
const expressions = items(scope).map((e) => cx.lowerExpr(d, e, env));
|
|
69
|
+
return {
|
|
70
|
+
scope: [expressions[0], ...expressions.slice(1)],
|
|
71
|
+
within: { n, unit: unit, at: cx.at(d, within) },
|
|
72
|
+
...confirmation,
|
|
73
|
+
at: cx.at(d, value),
|
|
74
|
+
};
|
|
75
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ElaboratedDeclaration } from "@forma-language/forma/descriptor";
|
|
2
|
+
import { type SExpr } from "@forma-language/forma/reader";
|
|
3
|
+
import type * as IR from "../../../world-ir/types.generated.js";
|
|
4
|
+
import { type SyntaxContext } from "./context.js";
|
|
5
|
+
export declare const sourceContext: (context: SyntaxContext) => {
|
|
6
|
+
references: IR.Source[];
|
|
7
|
+
citations: (d: ElaboratedDeclaration, form: SExpr) => {
|
|
8
|
+
cites?: readonly IR.Citation[];
|
|
9
|
+
};
|
|
10
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {} from "@forma-language/forma/descriptor";
|
|
2
|
+
import {} from "@forma-language/forma/reader";
|
|
3
|
+
import {} from "./context.js";
|
|
4
|
+
import { items, LowerError, option, symName } from "./syntax.js";
|
|
5
|
+
export const sourceContext = (context) => {
|
|
6
|
+
const { byForm, payload, at, formOf } = context;
|
|
7
|
+
const references = byForm("source").map((d) => {
|
|
8
|
+
const p = payload(d);
|
|
9
|
+
const date = p["as-of"], parsed = new Date(`${date}T00:00:00Z`);
|
|
10
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(date) ||
|
|
11
|
+
!Number.isFinite(parsed.getTime()) ||
|
|
12
|
+
parsed.toISOString().slice(0, 10) !== date)
|
|
13
|
+
throw new LowerError("E_SOURCE_DATE", "Source :as-of must be a real YYYY-MM-DD date.", at(d, option(formOf(d), "as-of")), "Use a real calendar date in YYYY-MM-DD form; record when the source was reviewed.");
|
|
14
|
+
return {
|
|
15
|
+
name: d.summary.name,
|
|
16
|
+
...(p.doc ? { doc: p.doc } : {}),
|
|
17
|
+
kind: p["source-kind"],
|
|
18
|
+
...(p.jurisdiction ? { jurisdiction: p.jurisdiction } : {}),
|
|
19
|
+
url: p.url,
|
|
20
|
+
asOf: date,
|
|
21
|
+
at: at(d, formOf(d)),
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
const sourceNames = new Set(references.map((s) => s.name));
|
|
25
|
+
const citations = (d, form) => {
|
|
26
|
+
const node = option(form, "cites");
|
|
27
|
+
if (!node)
|
|
28
|
+
return {};
|
|
29
|
+
const help = 'Use :cites [(named-source "specific clause")] with a declared source.';
|
|
30
|
+
if (node._tag !== "Vector")
|
|
31
|
+
throw new LowerError("E_CITATION", ":cites must be a vector of source/clause pairs.", at(d, node), help);
|
|
32
|
+
const cites = node.items.map((item) => {
|
|
33
|
+
const pair = items(item), name = symName(pair[0]), clause = pair[1];
|
|
34
|
+
if (item._tag !== "List" ||
|
|
35
|
+
pair.length !== 2 ||
|
|
36
|
+
!name ||
|
|
37
|
+
clause?._tag !== "Str" ||
|
|
38
|
+
!clause.value.trim())
|
|
39
|
+
throw new LowerError("E_CITATION", "A citation names a source and a nonempty clause string.", at(d, item), help);
|
|
40
|
+
if (!sourceNames.has(name))
|
|
41
|
+
throw new LowerError("E_UNKNOWN_SOURCE", `Unknown cited source ${name}.`, at(d, pair[0]), "Declare the source with (source name ...), then cite its specific clause.");
|
|
42
|
+
return { source: name, clause: clause.value, at: at(d, item) };
|
|
43
|
+
});
|
|
44
|
+
return cites.length ? { cites } : {};
|
|
45
|
+
};
|
|
46
|
+
return { references, citations };
|
|
47
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { type SExpr } from "@forma-language/forma/reader";
|
|
2
|
+
import type * as IR from "../../../world-ir/types.generated.js";
|
|
3
|
+
export declare const KERNEL_FUNCTIONS: Set<string>;
|
|
4
|
+
export declare class LowerError extends Error {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
readonly at: IR.Span;
|
|
7
|
+
readonly help?: string | undefined;
|
|
8
|
+
constructor(code: string, message: string, at: IR.Span, help?: string | undefined);
|
|
9
|
+
}
|
|
10
|
+
export type Sym = Extract<SExpr, {
|
|
11
|
+
_tag: "Sym";
|
|
12
|
+
}>;
|
|
13
|
+
export type ListNode = Extract<SExpr, {
|
|
14
|
+
_tag: "List";
|
|
15
|
+
}>;
|
|
16
|
+
export declare const isSym: (e: SExpr | undefined) => e is Sym;
|
|
17
|
+
export declare const symName: (e: SExpr | undefined) => string | undefined;
|
|
18
|
+
export declare const items: (e: SExpr | undefined) => readonly SExpr[];
|
|
19
|
+
export declare const headOf: (e: SExpr | undefined) => string | undefined;
|
|
20
|
+
export declare const option: (e: SExpr | undefined, key: string) => SExpr | undefined;
|
|
21
|
+
export declare const childNamed: (e: SExpr, head: string, name: string) => SExpr;
|
|
22
|
+
export declare const children: (e: SExpr, head: string) => SExpr[];
|
|
23
|
+
export declare const mapPairs: (e: SExpr | undefined) => readonly (readonly [SExpr, SExpr])[];
|
|
24
|
+
export type SType = {
|
|
25
|
+
readonly t: "role";
|
|
26
|
+
readonly name: string;
|
|
27
|
+
} | {
|
|
28
|
+
readonly t: "entity";
|
|
29
|
+
readonly name: string;
|
|
30
|
+
} | {
|
|
31
|
+
readonly t: "inst";
|
|
32
|
+
readonly name: string;
|
|
33
|
+
} | {
|
|
34
|
+
readonly t: "list";
|
|
35
|
+
readonly of: SType;
|
|
36
|
+
} | {
|
|
37
|
+
readonly t: "status";
|
|
38
|
+
} | {
|
|
39
|
+
readonly t: "machine";
|
|
40
|
+
} | {
|
|
41
|
+
readonly t: "value";
|
|
42
|
+
};
|
|
43
|
+
export declare const VALUE: SType;
|
|
44
|
+
export declare const spanOf: (src: string, e: SExpr) => IR.Span;
|
|
45
|
+
export declare const typeRef: (e: SExpr) => IR.TypeRef;
|
|
46
|
+
export type Fields = ReadonlyArray<{
|
|
47
|
+
name: string;
|
|
48
|
+
type: IR.TypeRef;
|
|
49
|
+
}>;
|
|
50
|
+
export interface ComponentPayload {
|
|
51
|
+
doc?: string;
|
|
52
|
+
key: string[];
|
|
53
|
+
inputs: Fields;
|
|
54
|
+
params: Fields;
|
|
55
|
+
requirements: ReadonlyArray<{
|
|
56
|
+
name: string;
|
|
57
|
+
label?: string;
|
|
58
|
+
}>;
|
|
59
|
+
actions: ReadonlyArray<{
|
|
60
|
+
name: string;
|
|
61
|
+
label?: string;
|
|
62
|
+
advances: string | readonly string[];
|
|
63
|
+
}>;
|
|
64
|
+
slots: ReadonlyArray<{
|
|
65
|
+
mode: "child" | "attach";
|
|
66
|
+
name: string;
|
|
67
|
+
component: string;
|
|
68
|
+
}>;
|
|
69
|
+
outputs: ReadonlyArray<{
|
|
70
|
+
name: string;
|
|
71
|
+
label?: string;
|
|
72
|
+
}>;
|
|
73
|
+
machines: ReadonlyArray<{
|
|
74
|
+
name: string;
|
|
75
|
+
protocol: string;
|
|
76
|
+
}>;
|
|
77
|
+
invariants: ReadonlyArray<{
|
|
78
|
+
name: string;
|
|
79
|
+
}>;
|
|
80
|
+
retention: ReadonlyArray<{
|
|
81
|
+
disposal: string;
|
|
82
|
+
}>;
|
|
83
|
+
}
|
|
84
|
+
export type Scope = ReadonlyMap<string, SType>;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {} from "@forma-language/forma/reader";
|
|
2
|
+
export const KERNEL_FUNCTIONS = new Set([
|
|
3
|
+
"=",
|
|
4
|
+
"table",
|
|
5
|
+
"instant",
|
|
6
|
+
"hours-after",
|
|
7
|
+
"minutes-after",
|
|
8
|
+
"hours",
|
|
9
|
+
"minutes",
|
|
10
|
+
"not=",
|
|
11
|
+
"<",
|
|
12
|
+
"<=",
|
|
13
|
+
">",
|
|
14
|
+
">=",
|
|
15
|
+
"in?",
|
|
16
|
+
"all?",
|
|
17
|
+
"any?",
|
|
18
|
+
"negate",
|
|
19
|
+
"true?",
|
|
20
|
+
"false?",
|
|
21
|
+
"unknown?",
|
|
22
|
+
"known?",
|
|
23
|
+
"earliest",
|
|
24
|
+
"latest",
|
|
25
|
+
"days",
|
|
26
|
+
"years",
|
|
27
|
+
"months",
|
|
28
|
+
"years-after",
|
|
29
|
+
"months-after",
|
|
30
|
+
"days-after",
|
|
31
|
+
"days-before",
|
|
32
|
+
"business-days-after",
|
|
33
|
+
"before?",
|
|
34
|
+
"on-or-after?",
|
|
35
|
+
"asserted-at",
|
|
36
|
+
"spells",
|
|
37
|
+
"attested",
|
|
38
|
+
"resource-generation",
|
|
39
|
+
"entered-at",
|
|
40
|
+
"attested-for",
|
|
41
|
+
"notice-delivered?",
|
|
42
|
+
"notice-acknowledged?",
|
|
43
|
+
"valid",
|
|
44
|
+
"decided",
|
|
45
|
+
"added-on",
|
|
46
|
+
"status-is?",
|
|
47
|
+
"satisfied?",
|
|
48
|
+
"met?",
|
|
49
|
+
"carried-over?",
|
|
50
|
+
"started?",
|
|
51
|
+
"final?",
|
|
52
|
+
"in-state?",
|
|
53
|
+
"members",
|
|
54
|
+
"map",
|
|
55
|
+
"filter",
|
|
56
|
+
"count",
|
|
57
|
+
]);
|
|
58
|
+
export class LowerError extends Error {
|
|
59
|
+
code;
|
|
60
|
+
at;
|
|
61
|
+
help;
|
|
62
|
+
constructor(code, message, at, help) {
|
|
63
|
+
super(message);
|
|
64
|
+
this.code = code;
|
|
65
|
+
this.at = at;
|
|
66
|
+
this.help = help;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export const isSym = (e) => e?._tag === "Sym";
|
|
70
|
+
export const symName = (e) => isSym(e) ? e.name : undefined;
|
|
71
|
+
export const items = (e) => e && (e._tag === "List" || e._tag === "Vector") ? e.items : [];
|
|
72
|
+
export const headOf = (e) => e?._tag === "List" ? symName(e.items[0]) : undefined;
|
|
73
|
+
export const option = (e, key) => {
|
|
74
|
+
const list = items(e);
|
|
75
|
+
const index = list.findIndex((x) => symName(x) === `:${key}`);
|
|
76
|
+
return index >= 0 ? list[index + 1] : undefined;
|
|
77
|
+
};
|
|
78
|
+
export const childNamed = (e, head, name) => {
|
|
79
|
+
const found = items(e).find((x) => headOf(x) === head && symName(items(x)[1]) === name);
|
|
80
|
+
if (!found)
|
|
81
|
+
throw new Error(`Missing (${head} ${name}) in syntax`);
|
|
82
|
+
return found;
|
|
83
|
+
};
|
|
84
|
+
export const children = (e, head) => items(e).filter((x) => headOf(x) === head);
|
|
85
|
+
export const mapPairs = (e) => (e?._tag === "Map" ? e.pairs : []);
|
|
86
|
+
export const VALUE = { t: "value" };
|
|
87
|
+
export const spanOf = (src, e) => ({
|
|
88
|
+
src,
|
|
89
|
+
from: e.loc.start,
|
|
90
|
+
to: e.loc.end,
|
|
91
|
+
line: e.loc.line,
|
|
92
|
+
col: e.loc.col,
|
|
93
|
+
});
|
|
94
|
+
export const typeRef = (e) => e._tag === "List" || e._tag === "Vector" ? e.items.map(typeRef) : isSym(e) ? e.name : String(e);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ElaboratedDeclaration } from "@forma-language/forma/descriptor";
|
|
2
|
+
import type * as IR from "../../../world-ir/types.generated.js";
|
|
3
|
+
import type { SourceFile } from "../compile.js";
|
|
4
|
+
import type { LoweringContext } from "./context.js";
|
|
5
|
+
/** Invalid keys must be located before selecting the native expression scope. */
|
|
6
|
+
export declare const vaultSourceDiagnostics: (files: readonly SourceFile[]) => IR.Diagnostic[];
|
|
7
|
+
export declare const lowerRecordSeal: (cx: LoweringContext, d: ElaboratedDeclaration) => {
|
|
8
|
+
sealedBy?: IR.Seal;
|
|
9
|
+
};
|
|
10
|
+
export declare const lowerSealedFields: <F extends IR.Field>(cx: LoweringContext, d: ElaboratedDeclaration, fields: readonly F[]) => F[];
|
|
11
|
+
export declare const lowerVaults: (cx: LoweringContext, model: Pick<IR.WorldIR, "types" | "roles" | "entities" | "components" | "derives">) => IR.Vault[];
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { sourceSyntax } from "../source-syntax.js";
|
|
2
|
+
import {} from "@forma-language/forma/reader";
|
|
3
|
+
import { sensitiveClasses, vaultHelp, vaultAuthority } from "../../../ir-checks/index.js";
|
|
4
|
+
import { headOf, items, mapPairs, option, symName, spanOf, LowerError } from "./syntax.js";
|
|
5
|
+
/** Invalid keys must be located before selecting the native expression scope. */
|
|
6
|
+
export const vaultSourceDiagnostics = (files) => {
|
|
7
|
+
if (!files.some((f) => f.text.includes("vault")))
|
|
8
|
+
return [];
|
|
9
|
+
const forms = files.flatMap((file) => {
|
|
10
|
+
const parsed = sourceSyntax(file);
|
|
11
|
+
return parsed.errors.length ? [] : parsed.forms.map((node) => ({ file, node }));
|
|
12
|
+
}), diagnostics = [], names = new Set();
|
|
13
|
+
for (const { file, node } of forms.filter(({ node }) => headOf(node) === "vault")) {
|
|
14
|
+
const parts = items(node), name = symName(parts[1]) ?? "", seen = new Set();
|
|
15
|
+
if (!name)
|
|
16
|
+
continue;
|
|
17
|
+
if (names.has(name))
|
|
18
|
+
diagnostics.push({
|
|
19
|
+
code: "E_VAULT_POLICY",
|
|
20
|
+
severity: "error",
|
|
21
|
+
message: "Vault names must be unique.",
|
|
22
|
+
at: spanOf(file.id, parts[1]),
|
|
23
|
+
help: vaultHelp,
|
|
24
|
+
});
|
|
25
|
+
names.add(name);
|
|
26
|
+
for (let i = parts[2]?._tag === "Str" ? 3 : 2; i < parts.length; i += 2) {
|
|
27
|
+
const key = symName(parts[i]) ?? "";
|
|
28
|
+
if (!parts[i + 1] ||
|
|
29
|
+
![":key", ":holds", ":retain", ":cites", ":erasure", ":dispose"].includes(key) ||
|
|
30
|
+
seen.has(key))
|
|
31
|
+
diagnostics.push({
|
|
32
|
+
code: "E_VAULT_POLICY",
|
|
33
|
+
severity: "error",
|
|
34
|
+
message: "Vault options must be supported, unique pairs.",
|
|
35
|
+
at: spanOf(file.id, parts[i]),
|
|
36
|
+
help: vaultHelp,
|
|
37
|
+
});
|
|
38
|
+
seen.add(key);
|
|
39
|
+
}
|
|
40
|
+
const key = option(node, "key"), keyParts = items(key), kind = headOf(key), target = symName(keyParts[1]);
|
|
41
|
+
const valid = keyParts.length === 2 &&
|
|
42
|
+
target &&
|
|
43
|
+
["per-occurrence", "per-subject"].includes(kind ?? "") &&
|
|
44
|
+
forms.some(({ node }) => headOf(node) === (kind === "per-occurrence" ? "component" : "role") &&
|
|
45
|
+
symName(items(node)[1]) === target);
|
|
46
|
+
if (!valid)
|
|
47
|
+
diagnostics.push({
|
|
48
|
+
code: "E_VAULT_SCOPE",
|
|
49
|
+
severity: "error",
|
|
50
|
+
message: "Choose a declared component or role for the vault key.",
|
|
51
|
+
at: spanOf(file.id, kind === "per-occurrence" && target ? keyParts[1] : (key ?? node)),
|
|
52
|
+
help: vaultHelp,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return diagnostics;
|
|
56
|
+
};
|
|
57
|
+
export const lowerRecordSeal = (cx, d) => {
|
|
58
|
+
const node = option(cx.formOf(d), "sealed-by");
|
|
59
|
+
if (!node)
|
|
60
|
+
return {};
|
|
61
|
+
const vault = symName(node);
|
|
62
|
+
if (!vault || vault.startsWith(":"))
|
|
63
|
+
throw new LowerError("E_VAULT_SEAL", "A record seal names one vault.", cx.at(d, node), vaultHelp);
|
|
64
|
+
return { sealedBy: { vault, at: cx.at(d, node) } };
|
|
65
|
+
};
|
|
66
|
+
export const lowerSealedFields = (cx, d, fields) => {
|
|
67
|
+
const node = option(cx.formOf(d), "sealed-by");
|
|
68
|
+
if (!node)
|
|
69
|
+
return [...fields];
|
|
70
|
+
const fail = (at) => {
|
|
71
|
+
throw new LowerError("E_VAULT_SEAL", "Use a unique field-to-vault map over declared fields.", cx.at(d, at), vaultHelp);
|
|
72
|
+
};
|
|
73
|
+
if (node._tag !== "Map")
|
|
74
|
+
return fail(node);
|
|
75
|
+
const seals = new Map();
|
|
76
|
+
for (const [key, value] of mapPairs(node)) {
|
|
77
|
+
const field = symName(key)?.replace(/^:/, ""), vault = symName(value);
|
|
78
|
+
if (!field || !fields.some((f) => f.name === field) || seals.has(field))
|
|
79
|
+
return fail(key);
|
|
80
|
+
if (!vault || vault.startsWith(":"))
|
|
81
|
+
return fail(value);
|
|
82
|
+
seals.set(field, { vault, at: cx.at(d, value) });
|
|
83
|
+
}
|
|
84
|
+
return fields.map((f) => (seals.has(f.name) ? { ...f, sealedBy: seals.get(f.name) } : f));
|
|
85
|
+
};
|
|
86
|
+
export const lowerVaults = (cx, model) => cx.byForm("vault").map((d) => {
|
|
87
|
+
const form = cx.formOf(d), fail = (code, node, message) => {
|
|
88
|
+
throw new LowerError(code, message, cx.at(d, node ?? form), vaultHelp);
|
|
89
|
+
}, key = option(form, "key"), target = symName(items(key)[1]), kind = headOf(key) === "per-occurrence" ? "occurrence" : "subject", scope = kind === "occurrence"
|
|
90
|
+
? cx.componentScope(target)
|
|
91
|
+
: new Map([
|
|
92
|
+
["subject", { t: "role", name: target }],
|
|
93
|
+
["today", { t: "value" }],
|
|
94
|
+
["now", { t: "value" }],
|
|
95
|
+
]), holds = option(form, "holds"), retain = option(form, "retain"), erasure = option(form, "erasure"), dispose = option(form, "dispose"), quorum = option(dispose, "approvals"), by = option(dispose, "by");
|
|
96
|
+
if (holds?._tag !== "Vector" || !holds.items.length)
|
|
97
|
+
return fail("E_VAULT_POLICY", holds, "Declare nonempty held classes.");
|
|
98
|
+
const classes = [];
|
|
99
|
+
for (const node of holds.items) {
|
|
100
|
+
const value = symName(node)?.slice(1);
|
|
101
|
+
if (!symName(node)?.startsWith(":") || !sensitiveClasses.some((c) => c === value))
|
|
102
|
+
return fail("E_VAULT_POLICY", node, "Use a supported literal class.");
|
|
103
|
+
classes.push(value);
|
|
104
|
+
}
|
|
105
|
+
if (new Set(classes).size !== classes.length)
|
|
106
|
+
return fail("E_VAULT_POLICY", holds, "Held classes must be unique.");
|
|
107
|
+
if (!retain)
|
|
108
|
+
return fail("E_VAULT_POLICY", form, "Declare a finite retention date.");
|
|
109
|
+
const cites = cx.citations(d, form).cites;
|
|
110
|
+
if (!cites?.length)
|
|
111
|
+
return fail("E_VAULT_UNCITED", form, "Vault retention needs cited authority.");
|
|
112
|
+
const erasureKind = symName(erasure)?.slice(1);
|
|
113
|
+
if (erasureKind !== "on-request" && erasureKind !== "held-until-retained")
|
|
114
|
+
return fail("E_VAULT_POLICY", erasure, "Choose a supported erasure policy.");
|
|
115
|
+
const disposalParts = items(dispose), disposalOptions = [symName(disposalParts[2]), symName(disposalParts[4])];
|
|
116
|
+
if (headOf(dispose) !== "decision" ||
|
|
117
|
+
!symName(disposalParts[1]) ||
|
|
118
|
+
symName(disposalParts[1]).startsWith(":") ||
|
|
119
|
+
!by ||
|
|
120
|
+
disposalParts.length !== 6 ||
|
|
121
|
+
new Set(disposalOptions).size !== 2 ||
|
|
122
|
+
disposalOptions.some((k) => k !== ":by" && k !== ":approvals"))
|
|
123
|
+
return fail("E_VAULT_POLICY", dispose, "Declare a named disposal decision with unique authority and approval options.");
|
|
124
|
+
if (quorum?._tag !== "Num" ||
|
|
125
|
+
!Number.isSafeInteger(Number(quorum.value)) ||
|
|
126
|
+
Number(quorum.value) < 1)
|
|
127
|
+
return fail("E_VAULT_POLICY", quorum ?? dispose, "Use a positive fixed approval count.");
|
|
128
|
+
const policyKey = { kind, target, at: cx.at(d, key) }, authority = cx.lowerExpr(d, by, scope), checked = vaultAuthority(model, policyKey, authority);
|
|
129
|
+
if (!checked.kind || checked.diagnostics.length)
|
|
130
|
+
return fail("E_VAULT_AUTHORITY", by, "Use one proven entity or group authority.");
|
|
131
|
+
return {
|
|
132
|
+
name: d.summary.name,
|
|
133
|
+
...cx.docOf(cx.payload(d).doc),
|
|
134
|
+
key: policyKey,
|
|
135
|
+
holds: classes.sort(),
|
|
136
|
+
retain: cx.lowerExpr(d, retain, scope),
|
|
137
|
+
cites: cites,
|
|
138
|
+
erasure: { kind: erasureKind, at: cx.at(d, erasure) },
|
|
139
|
+
dispose: {
|
|
140
|
+
name: symName(items(dispose)[1]),
|
|
141
|
+
by: authority,
|
|
142
|
+
byKind: checked.kind === "entity" ? "individual" : "group",
|
|
143
|
+
approvals: Number(quorum.value),
|
|
144
|
+
at: cx.at(d, dispose),
|
|
145
|
+
},
|
|
146
|
+
at: cx.at(d, form),
|
|
147
|
+
};
|
|
148
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const worldPrelude: string;
|