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,256 @@
|
|
|
1
|
+
import { amendmentAction } from "./amendments.js";
|
|
2
|
+
import { canAttestEvidence } from "./evidence-authority.js";
|
|
3
|
+
import { instanceContext } from "./evaluation.js";
|
|
4
|
+
import { decisionRelease } from "./decision-release.js";
|
|
5
|
+
import { collectionValue } from "./collection-values.js";
|
|
6
|
+
import { advanceTargets, componentOperationNames } from "../ir-checks/index.js";
|
|
7
|
+
import { timeOrder } from "./instants.js";
|
|
8
|
+
import { perform, amendEvidence } from "./commands.js";
|
|
9
|
+
import { decide } from "./decide.js";
|
|
10
|
+
import { occurrenceHome } from "./homes.js";
|
|
11
|
+
import { admit } from "./invariants.js";
|
|
12
|
+
import { basis } from "./memory.js";
|
|
13
|
+
import { programFor } from "./reconcile.js";
|
|
14
|
+
import { permitsConstraints } from "./policies.js";
|
|
15
|
+
import { canonicalJson } from "./result-digest.js";
|
|
16
|
+
import { sha256 } from "./sha256.js";
|
|
17
|
+
import { workKey } from "./work.js";
|
|
18
|
+
const resolve = (recon, account, target) => {
|
|
19
|
+
let parent, instance;
|
|
20
|
+
if ("parent" in target) {
|
|
21
|
+
parent = recon.instances.get(target.parent);
|
|
22
|
+
const slot = parent?.children.find((s) => s.name === target.slot);
|
|
23
|
+
if (!parent || parent.account !== account || !slot || slot.applies !== true)
|
|
24
|
+
return;
|
|
25
|
+
const ids = [...new Set(slot.instances)];
|
|
26
|
+
const selected = target.instance ?? (ids.length === 1 ? ids[0] : undefined);
|
|
27
|
+
if (!selected || !ids.includes(selected))
|
|
28
|
+
return;
|
|
29
|
+
instance = recon.instances.get(selected);
|
|
30
|
+
if (!instance?.parents.has(parent.id))
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
else
|
|
34
|
+
instance = recon.instances.get(target.instance);
|
|
35
|
+
if (!instance || instance.account !== account || !recon.results.has(instance.id))
|
|
36
|
+
return;
|
|
37
|
+
const program = programFor(recon, instance.id);
|
|
38
|
+
if (!program)
|
|
39
|
+
return;
|
|
40
|
+
const candidates = (program.ir.componentContracts ?? []).filter((c) => c.component === instance.component);
|
|
41
|
+
let contract;
|
|
42
|
+
if (parent) {
|
|
43
|
+
const consumer = program.components.get(parent.component).library ?? program.library.name;
|
|
44
|
+
const imported = program.ir.componentImports?.find((i) => i.library === consumer && candidates.some((c) => c.name === i.contract));
|
|
45
|
+
contract = imported
|
|
46
|
+
? candidates.find((c) => c.name === imported.contract)
|
|
47
|
+
: candidates.length === 1 && candidates[0].library === consumer
|
|
48
|
+
? candidates[0]
|
|
49
|
+
: undefined;
|
|
50
|
+
const provider = program.components.get(instance.component).library;
|
|
51
|
+
if ((candidates.length && !contract) || (provider && provider !== consumer && !contract))
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
if (candidates.length > 1)
|
|
56
|
+
return;
|
|
57
|
+
contract = candidates[0];
|
|
58
|
+
}
|
|
59
|
+
return { instance, program, contract };
|
|
60
|
+
};
|
|
61
|
+
/** Structural projection only; command admission still checks the trusted actor and current work. */
|
|
62
|
+
export const operationsFor = (recon, account, target) => {
|
|
63
|
+
const found = resolve(recon, account, target);
|
|
64
|
+
if (!found)
|
|
65
|
+
return { instance: null, operations: [], codes: ["operation-target"] };
|
|
66
|
+
const { instance, program, contract } = found, component = program.components.get(instance.component);
|
|
67
|
+
const names = componentOperationNames(program.ir, component).filter((n) => !contract || contract.operations.some((o) => o.name === n));
|
|
68
|
+
const operations = names.map((name) => {
|
|
69
|
+
const definition = component.actions.find((a) => a.name === name);
|
|
70
|
+
if (definition) {
|
|
71
|
+
const action = recon.results.get(instance.id)?.actions.find((a) => a.action === name);
|
|
72
|
+
const evidence = definition.via.kind === "interaction"
|
|
73
|
+
? program.evidence.get(program.interactions.get(definition.via.name).produces)
|
|
74
|
+
: undefined;
|
|
75
|
+
return {
|
|
76
|
+
name,
|
|
77
|
+
kind: "action",
|
|
78
|
+
...(evidence?.amend && evidence.of === component.name ? { amendable: true } : {}),
|
|
79
|
+
state: action?.state ??
|
|
80
|
+
(advanceTargets(definition).every((name) => recon.results.get(instance.id).requirements.find((r) => r.name === name)?.status ===
|
|
81
|
+
"NotApplicable")
|
|
82
|
+
? "not-applicable"
|
|
83
|
+
: "complete"),
|
|
84
|
+
...(action ? { workKey: workKey(account, action.idempotencyKey) } : {}),
|
|
85
|
+
at: definition.at,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
name,
|
|
90
|
+
kind: "decision",
|
|
91
|
+
state: "decision",
|
|
92
|
+
at: program.ir.decisions.find((d) => d.of === component.name && d.name === name).at,
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
return {
|
|
96
|
+
instance: instance.id,
|
|
97
|
+
operations: operations.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0)),
|
|
98
|
+
codes: [],
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
/** The host supplies a current reconciliation/basis pair and verified identity; M16 serializes it. */
|
|
102
|
+
export const invokeOperation = (recon, world, now, request) => {
|
|
103
|
+
const reject = (...codes) => ({ accepted: false, codes, world });
|
|
104
|
+
const program = recon.programs.find((p) => p.account.name === request.account);
|
|
105
|
+
if (!program || !request.id.trim() || !request.actor.id.trim())
|
|
106
|
+
return reject("operation-target");
|
|
107
|
+
const digest = sha256(canonicalJson({
|
|
108
|
+
account: request.account,
|
|
109
|
+
id: request.id,
|
|
110
|
+
target: request.target,
|
|
111
|
+
operation: request.operation,
|
|
112
|
+
actor: { ...request.actor, groups: [...request.actor.groups].sort() },
|
|
113
|
+
values: request.values ?? null,
|
|
114
|
+
unsigned: request.unsigned ?? false,
|
|
115
|
+
...(request.signature ? { signature: request.signature } : {}),
|
|
116
|
+
...(request.amend ? { amend: request.amend } : {}),
|
|
117
|
+
reason: request.reason ?? null,
|
|
118
|
+
revoke: request.revoke ?? null,
|
|
119
|
+
release: decisionRelease(program),
|
|
120
|
+
}));
|
|
121
|
+
const previous = world.operationReceipts?.find((r) => r.account === request.account && r.id === request.id);
|
|
122
|
+
if (previous) {
|
|
123
|
+
if (previous.digest !== digest)
|
|
124
|
+
return reject("operation-duplicate");
|
|
125
|
+
if (timeOrder(previous.at, now) > 0)
|
|
126
|
+
return reject("operation-snapshot");
|
|
127
|
+
return { accepted: true, codes: [], world, instance: previous.instance };
|
|
128
|
+
}
|
|
129
|
+
if (recon.now !== now)
|
|
130
|
+
return reject("operation-snapshot");
|
|
131
|
+
const projection = operationsFor(recon, request.account, request.target);
|
|
132
|
+
if (!projection.instance)
|
|
133
|
+
return reject(...projection.codes);
|
|
134
|
+
const operation = projection.operations.find((o) => o.name === request.operation);
|
|
135
|
+
if (!operation)
|
|
136
|
+
return reject("E_NOT_AN_OPERATION");
|
|
137
|
+
const instance = recon.instances.get(projection.instance), p = programFor(recon, instance.id);
|
|
138
|
+
const home = occurrenceHome(p, instance, recon.instances);
|
|
139
|
+
if (!home)
|
|
140
|
+
return reject("operation-target");
|
|
141
|
+
let next;
|
|
142
|
+
if (operation.kind === "decision") {
|
|
143
|
+
if (request.actor.kind !== "human")
|
|
144
|
+
return reject("decision-authority");
|
|
145
|
+
if (request.unsigned || request.values || request.signature || request.amend)
|
|
146
|
+
return reject("operation-input");
|
|
147
|
+
const result = decide(recon, world, now, {
|
|
148
|
+
id: JSON.stringify(["worldvm/operation", request.account, request.id]),
|
|
149
|
+
instance: instance.id,
|
|
150
|
+
decision: operation.name,
|
|
151
|
+
actor: request.actor,
|
|
152
|
+
...(request.reason === undefined ? {} : { reason: request.reason }),
|
|
153
|
+
...(request.revoke ? { revoke: request.revoke } : {}),
|
|
154
|
+
});
|
|
155
|
+
if (!result.accepted)
|
|
156
|
+
return { accepted: false, codes: result.codes, world: result.world, instance: instance.id };
|
|
157
|
+
next = result.world;
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
if (request.amend && request.actor.kind !== "human")
|
|
161
|
+
return reject("human-required");
|
|
162
|
+
if (request.amend &&
|
|
163
|
+
(request.unsigned ||
|
|
164
|
+
!request.amend.previous.trim() ||
|
|
165
|
+
!request.amend.reason.trim() ||
|
|
166
|
+
request.amend.reason.length > 2000))
|
|
167
|
+
return reject("amendment-input");
|
|
168
|
+
const prepared = request.amend
|
|
169
|
+
? amendmentAction(recon, world, now, instance.id, operation.name, request.amend.previous)
|
|
170
|
+
: undefined;
|
|
171
|
+
if (prepared?.code)
|
|
172
|
+
return reject(prepared.code);
|
|
173
|
+
const actions = prepared?.action
|
|
174
|
+
? [prepared.action]
|
|
175
|
+
: recon.results.get(instance.id).actions.filter((a) => a.action === operation.name), action = actions[0];
|
|
176
|
+
if (actions.length !== 1 ||
|
|
177
|
+
!action ||
|
|
178
|
+
action.kind === "decision" ||
|
|
179
|
+
(action.state !== "eligible" && action.state !== "dispatched"))
|
|
180
|
+
return reject("operation-not-eligible");
|
|
181
|
+
const who = request.actor, allowed = action.kind === "connector"
|
|
182
|
+
? (who.kind === "service" || who.kind === "connector") && who.id === action.assigneeId
|
|
183
|
+
: (who.kind === "human" || who.kind === "agent") &&
|
|
184
|
+
action.assigneeId != null &&
|
|
185
|
+
(action.assigneeKind === "group"
|
|
186
|
+
? who.groups.includes(action.assigneeId)
|
|
187
|
+
: who.id === action.assigneeId);
|
|
188
|
+
if (!allowed || !permitsConstraints(action.authorityConstraints ?? [], who))
|
|
189
|
+
return reject("operation-authority");
|
|
190
|
+
if (who.kind === "agent" && !request.unsigned)
|
|
191
|
+
return reject("human-required");
|
|
192
|
+
if (request.signature && (who.kind !== "human" || request.unsigned))
|
|
193
|
+
return reject("human-required");
|
|
194
|
+
if (request.revoke || request.reason !== undefined)
|
|
195
|
+
return reject("operation-input");
|
|
196
|
+
const values = {};
|
|
197
|
+
if (action.kind === "connector" &&
|
|
198
|
+
(request.unsigned || Object.keys(request.values ?? {}).length))
|
|
199
|
+
return reject("operation-input");
|
|
200
|
+
const interaction = action.interaction ? p.interactions.get(action.interaction) : undefined;
|
|
201
|
+
const evidence = interaction ? p.evidence.get(interaction.produces) : undefined;
|
|
202
|
+
if (evidence &&
|
|
203
|
+
!request.unsigned &&
|
|
204
|
+
!canAttestEvidence(instanceContext(recon, basis(world, now), instance), evidence.name, who))
|
|
205
|
+
return reject("operation-authority");
|
|
206
|
+
if (request.signature && !evidence?.attest?.audit)
|
|
207
|
+
return reject("operation-input");
|
|
208
|
+
for (const [name, value] of Object.entries(request.values ?? {})) {
|
|
209
|
+
const field = evidence?.fields.find((f) => f.name === name);
|
|
210
|
+
if (!field)
|
|
211
|
+
return reject("operation-input");
|
|
212
|
+
const parsed = request.unsigned && value === "" ? "" : collectionValue(p, field.type, value);
|
|
213
|
+
if (parsed === undefined)
|
|
214
|
+
return reject("operation-input");
|
|
215
|
+
values[name] = parsed;
|
|
216
|
+
}
|
|
217
|
+
if ([operation.name, "perform"].some((kind) => admit(recon, basis(world, now), now, { kind, subject: home.id }).length))
|
|
218
|
+
return reject("operation-invariant");
|
|
219
|
+
const write = {
|
|
220
|
+
instance: instance.id,
|
|
221
|
+
action: operation.name,
|
|
222
|
+
by: who.id,
|
|
223
|
+
actor: who,
|
|
224
|
+
connectorAcknowledgement: "deferred",
|
|
225
|
+
...(request.signature ? { signature: request.signature } : {}),
|
|
226
|
+
...(request.values ? { values } : {}),
|
|
227
|
+
...(request.unsigned === undefined ? {} : { unsigned: request.unsigned }),
|
|
228
|
+
};
|
|
229
|
+
next = request.amend
|
|
230
|
+
? amendEvidence(recon, world, now, { ...write, amend: request.amend })
|
|
231
|
+
: perform(recon, world, now, write);
|
|
232
|
+
if (next === world &&
|
|
233
|
+
!(action.kind === "connector" && world.dispatches.some((d) => d.key === action.idempotencyKey)))
|
|
234
|
+
return reject("evidence-invalid");
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
accepted: true,
|
|
238
|
+
codes: [],
|
|
239
|
+
instance: instance.id,
|
|
240
|
+
world: {
|
|
241
|
+
...next,
|
|
242
|
+
operationReceipts: [
|
|
243
|
+
...(next.operationReceipts ?? []),
|
|
244
|
+
{
|
|
245
|
+
account: request.account,
|
|
246
|
+
id: request.id,
|
|
247
|
+
digest,
|
|
248
|
+
instance: instance.id,
|
|
249
|
+
operation: operation.name,
|
|
250
|
+
kind: operation.kind,
|
|
251
|
+
at: now,
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Basis } from "./basis.js";
|
|
2
|
+
import { type TimePoint } from "./instants.js";
|
|
3
|
+
import { ReadSet, type Dependency } from "./dependencies.js";
|
|
4
|
+
import { type Cx, type EvaluationResult, type Instance, type KernelState, type Program, type ReconcileScope, type RequirementResult, type Status } from "./model.js";
|
|
5
|
+
export declare const contextOf: (ctx: EvaluationContext, inst: Instance) => Cx;
|
|
6
|
+
export interface PredictedStatus {
|
|
7
|
+
readonly value: Status;
|
|
8
|
+
readonly cutoffs: ReadonlySet<TimePoint>;
|
|
9
|
+
readonly reads: ReadonlyMap<string, Dependency>;
|
|
10
|
+
readonly cyclic?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface EvaluationContext {
|
|
13
|
+
readonly programs: readonly Program[];
|
|
14
|
+
readonly b: Basis;
|
|
15
|
+
readonly now: TimePoint;
|
|
16
|
+
readonly scope: ReconcileScope | undefined;
|
|
17
|
+
readonly instances: Map<string, Instance>;
|
|
18
|
+
readonly programOf: Map<string, Program>;
|
|
19
|
+
readonly results: Map<string, EvaluationResult>;
|
|
20
|
+
readonly evaluating: Map<string, Map<string, RequirementResult>>;
|
|
21
|
+
readonly resolvingOutputs: Set<string>;
|
|
22
|
+
readonly roots: Array<{
|
|
23
|
+
subject: string;
|
|
24
|
+
account: string;
|
|
25
|
+
instance: string;
|
|
26
|
+
}>;
|
|
27
|
+
readonly rootFocus: Map<string, string>;
|
|
28
|
+
blockedTotal: number;
|
|
29
|
+
readonly temporalJobs: (() => void)[];
|
|
30
|
+
readonly discoveryJobs: (() => void)[];
|
|
31
|
+
discoveryReadSets: ReadonlyMap<string, ReadSet>;
|
|
32
|
+
readonly state: KernelState;
|
|
33
|
+
readonly contexts: Map<string, Cx>;
|
|
34
|
+
readonly observations: Map<string, ReadSet>;
|
|
35
|
+
readonly predictions: Map<string, PredictedStatus>;
|
|
36
|
+
readonly predicting: Set<string>;
|
|
37
|
+
}
|
|
38
|
+
export declare const createEvaluationContext: (programs: readonly Program[], b: Basis, now: TimePoint, scope: ReconcileScope | undefined) => EvaluationContext;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {} from "./basis.js";
|
|
2
|
+
import {} from "./instants.js";
|
|
3
|
+
import { observeBasis, programDependency, ReadSet } from "./dependencies.js";
|
|
4
|
+
import { instanceEnv } from "./evaluation.js";
|
|
5
|
+
import {} from "./model.js";
|
|
6
|
+
import { readStatus, requirementStatus } from "./outputs.js";
|
|
7
|
+
export const contextOf = (ctx, inst) => {
|
|
8
|
+
const cached = ctx.contexts.get(inst.id);
|
|
9
|
+
if (cached)
|
|
10
|
+
return cached;
|
|
11
|
+
const p = ctx.programOf.get(inst.id);
|
|
12
|
+
const reads = new ReadSet();
|
|
13
|
+
reads.add(programDependency(p));
|
|
14
|
+
const env = instanceEnv(p, inst, (name) => requirementStatus(ctx, inst, name), reads);
|
|
15
|
+
const cx = { p, b: observeBasis(ctx.b, reads), inst, env, k: ctx.state, reads };
|
|
16
|
+
ctx.contexts.set(inst.id, cx);
|
|
17
|
+
return cx;
|
|
18
|
+
};
|
|
19
|
+
export const createEvaluationContext = (programs, b, now, scope) => {
|
|
20
|
+
const instances = new Map();
|
|
21
|
+
const ctx = {
|
|
22
|
+
programs,
|
|
23
|
+
b,
|
|
24
|
+
now,
|
|
25
|
+
scope,
|
|
26
|
+
instances,
|
|
27
|
+
programOf: new Map(),
|
|
28
|
+
results: new Map(),
|
|
29
|
+
evaluating: new Map(),
|
|
30
|
+
resolvingOutputs: new Set(),
|
|
31
|
+
roots: [],
|
|
32
|
+
rootFocus: new Map(),
|
|
33
|
+
blockedTotal: 0,
|
|
34
|
+
temporalJobs: [],
|
|
35
|
+
discoveryJobs: [],
|
|
36
|
+
discoveryReadSets: new Map(),
|
|
37
|
+
contexts: new Map(),
|
|
38
|
+
observations: new Map(),
|
|
39
|
+
predictions: new Map(),
|
|
40
|
+
predicting: new Set(),
|
|
41
|
+
state: { instances, status: (inst, name) => readStatus(ctx, inst, name) },
|
|
42
|
+
};
|
|
43
|
+
return ctx;
|
|
44
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type * as IR from "../world-ir/types.generated.js";
|
|
2
|
+
import type { Status, WorldReconciliation } from "./reconcile.js";
|
|
3
|
+
export type CoverageTruth = "true" | "false" | "Unknown";
|
|
4
|
+
export interface CoverageReference {
|
|
5
|
+
readonly kind: "scenario" | "property";
|
|
6
|
+
readonly name: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CoverageOutcomes<T extends string> {
|
|
9
|
+
readonly expected: readonly T[];
|
|
10
|
+
readonly seen: readonly T[];
|
|
11
|
+
readonly missing: readonly T[];
|
|
12
|
+
}
|
|
13
|
+
export interface RequirementCoverage {
|
|
14
|
+
readonly key: string;
|
|
15
|
+
readonly at: IR.Span;
|
|
16
|
+
readonly observations: number;
|
|
17
|
+
readonly references: readonly CoverageReference[];
|
|
18
|
+
readonly applicability: CoverageOutcomes<CoverageTruth>;
|
|
19
|
+
readonly statuses: CoverageOutcomes<Status>;
|
|
20
|
+
readonly due: {
|
|
21
|
+
readonly outcomes: CoverageOutcomes<"date" | "Unknown">;
|
|
22
|
+
readonly branches: readonly (CoverageOutcomes<CoverageTruth> & {
|
|
23
|
+
readonly at: IR.Span;
|
|
24
|
+
})[];
|
|
25
|
+
} | null;
|
|
26
|
+
}
|
|
27
|
+
/** An explicit, bounded accumulator over supplied reconciliations; no clock or I/O. */
|
|
28
|
+
export declare const createCoverageCollector: (ir: IR.WorldIR) => {
|
|
29
|
+
observe(recon: WorldReconciliation, reference: CoverageReference): void;
|
|
30
|
+
report(): RequirementCoverage[];
|
|
31
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
const truthValues = ["true", "false", "Unknown"];
|
|
2
|
+
const statuses = [
|
|
3
|
+
"NotApplicable",
|
|
4
|
+
"Unknown",
|
|
5
|
+
"Open",
|
|
6
|
+
"Overdue",
|
|
7
|
+
"Satisfied",
|
|
8
|
+
"Waived",
|
|
9
|
+
];
|
|
10
|
+
const location = (at) => JSON.stringify([at.src, at.from, at.to]);
|
|
11
|
+
const outcomes = (expected, seen) => ({
|
|
12
|
+
expected: [...expected],
|
|
13
|
+
seen: [
|
|
14
|
+
...expected.filter((v) => seen.has(v)),
|
|
15
|
+
...[...seen].filter((v) => !expected.includes(v)).sort(),
|
|
16
|
+
],
|
|
17
|
+
missing: expected.filter((v) => !seen.has(v)),
|
|
18
|
+
});
|
|
19
|
+
/** Walk only due expressions and their called derives; keep unvisited branches in the report. */
|
|
20
|
+
const dueBranches = (ir, expr) => {
|
|
21
|
+
const found = new Map(), visited = new Set();
|
|
22
|
+
const visit = (e) => {
|
|
23
|
+
switch (e.k) {
|
|
24
|
+
case "if":
|
|
25
|
+
found.set(location(e.at), e.at);
|
|
26
|
+
visit(e.test);
|
|
27
|
+
visit(e.then);
|
|
28
|
+
visit(e.else);
|
|
29
|
+
break;
|
|
30
|
+
case "call":
|
|
31
|
+
e.args.forEach(visit);
|
|
32
|
+
if (e.derive && !visited.has(e.fn)) {
|
|
33
|
+
visited.add(e.fn);
|
|
34
|
+
const d = ir.derives.find((d) => d.name === e.fn);
|
|
35
|
+
if (d)
|
|
36
|
+
visit(d.body);
|
|
37
|
+
}
|
|
38
|
+
break;
|
|
39
|
+
case "fn":
|
|
40
|
+
visit(e.body);
|
|
41
|
+
break;
|
|
42
|
+
case "list":
|
|
43
|
+
e.items.forEach(visit);
|
|
44
|
+
break;
|
|
45
|
+
case "attr":
|
|
46
|
+
case "read":
|
|
47
|
+
case "inst":
|
|
48
|
+
visit(e.of);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
visit(expr);
|
|
53
|
+
return [...found.values()].sort((a, b) => a.src.localeCompare(b.src) || a.from - b.from || a.to - b.to);
|
|
54
|
+
};
|
|
55
|
+
/** An explicit, bounded accumulator over supplied reconciliations; no clock or I/O. */
|
|
56
|
+
export const createCoverageCollector = (ir) => {
|
|
57
|
+
const rows = ir.components.flatMap((component) => component.requirements.map((requirement) => ({
|
|
58
|
+
key: `${component.name}/${requirement.name}`,
|
|
59
|
+
requirement,
|
|
60
|
+
observations: 0,
|
|
61
|
+
refs: new Map(),
|
|
62
|
+
applicability: new Set(),
|
|
63
|
+
statuses: new Set(),
|
|
64
|
+
due: new Set(),
|
|
65
|
+
branches: (requirement.due ? dueBranches(ir, requirement.due) : []).map((at) => ({
|
|
66
|
+
at,
|
|
67
|
+
seen: new Set(),
|
|
68
|
+
})),
|
|
69
|
+
})));
|
|
70
|
+
const byKey = new Map(rows.map((row) => [row.key, row]));
|
|
71
|
+
return {
|
|
72
|
+
observe(recon, reference) {
|
|
73
|
+
for (const result of recon.results.values())
|
|
74
|
+
for (const requirement of result.requirements) {
|
|
75
|
+
const row = byKey.get(`${result.component}/${requirement.name}`);
|
|
76
|
+
if (!row)
|
|
77
|
+
continue;
|
|
78
|
+
row.observations++;
|
|
79
|
+
row.refs.set(JSON.stringify([reference.kind, reference.name]), { ...reference });
|
|
80
|
+
row.statuses.add(requirement.status);
|
|
81
|
+
const applies = requirement.reasons.find((r) => r.label === "Applies when");
|
|
82
|
+
row.applicability.add(!applies || applies.outcome === "passed"
|
|
83
|
+
? "true"
|
|
84
|
+
: applies.outcome === "failed"
|
|
85
|
+
? "false"
|
|
86
|
+
: "Unknown");
|
|
87
|
+
if (!row.requirement.due)
|
|
88
|
+
continue;
|
|
89
|
+
if (requirement.due !== null)
|
|
90
|
+
row.due.add("date");
|
|
91
|
+
else if (requirement.dueUnknown !== null)
|
|
92
|
+
row.due.add("Unknown");
|
|
93
|
+
for (const step of requirement.dueSteps)
|
|
94
|
+
if (step.branch) {
|
|
95
|
+
row.branches
|
|
96
|
+
.find((branch) => location(branch.at) === location(step.at))
|
|
97
|
+
?.seen.add(step.branch);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
report() {
|
|
102
|
+
return rows
|
|
103
|
+
.map((row) => ({
|
|
104
|
+
key: row.key,
|
|
105
|
+
at: row.requirement.at,
|
|
106
|
+
observations: row.observations,
|
|
107
|
+
references: [...row.refs.values()].sort((a, b) => a.kind.localeCompare(b.kind) || a.name.localeCompare(b.name)),
|
|
108
|
+
applicability: outcomes(row.requirement.appliesWhen ? truthValues : ["true"], row.applicability),
|
|
109
|
+
statuses: outcomes(statuses, row.statuses),
|
|
110
|
+
due: row.requirement.due
|
|
111
|
+
? {
|
|
112
|
+
outcomes: outcomes(["date", "Unknown"], row.due),
|
|
113
|
+
// Authored if tests require Bool: true?/false?/unknown? make absence explicit.
|
|
114
|
+
branches: row.branches.map((branch) => ({
|
|
115
|
+
at: branch.at,
|
|
116
|
+
...outcomes(["true", "false"], branch.seen),
|
|
117
|
+
})),
|
|
118
|
+
}
|
|
119
|
+
: null,
|
|
120
|
+
}))
|
|
121
|
+
.sort((a, b) => a.key.localeCompare(b.key));
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type LocalDate = string;
|
|
2
|
+
export declare const addDays: (date: LocalDate, days: number) => LocalDate;
|
|
3
|
+
export declare const addYears: (date: LocalDate, years: number) => LocalDate;
|
|
4
|
+
/** Calendar months; a day past the target month's end clamps to its last day (Jan 31 + 1 = Feb 28/29). */
|
|
5
|
+
export declare const addMonths: (date: LocalDate, months: number) => LocalDate;
|
|
6
|
+
export declare const daysBetween: (from: LocalDate, to: LocalDate) => number;
|
|
7
|
+
export declare const weekday: (date: LocalDate) => number;
|
|
8
|
+
export declare const latest: (...dates: LocalDate[]) => string;
|
|
9
|
+
export declare const earliest: (...dates: LocalDate[]) => string;
|
|
10
|
+
/** A holiday rule as a calendar declares it: a fixed day, or the nth (−1: last) weekday. */
|
|
11
|
+
export interface HolidayRule {
|
|
12
|
+
readonly label: string;
|
|
13
|
+
readonly month: number;
|
|
14
|
+
readonly day?: number;
|
|
15
|
+
readonly weekday?: string;
|
|
16
|
+
readonly nth?: number;
|
|
17
|
+
readonly observed: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const holidayDate: (rule: HolidayRule, year: number) => LocalDate;
|
|
20
|
+
export interface Calendar {
|
|
21
|
+
readonly id: string;
|
|
22
|
+
readonly version: string;
|
|
23
|
+
readonly isBusinessDay: (date: LocalDate) => boolean;
|
|
24
|
+
readonly holiday: (date: LocalDate) => string | undefined;
|
|
25
|
+
}
|
|
26
|
+
/** A versioned business-day calendar from its declared weekend and holiday rules. */
|
|
27
|
+
export declare const makeCalendar: (id: string, version: string, weekend: readonly string[], rules: readonly HolidayRule[]) => Calendar;
|
|
28
|
+
type BusinessDays = {
|
|
29
|
+
readonly date: LocalDate;
|
|
30
|
+
readonly skipped: ReadonlyArray<{
|
|
31
|
+
date: LocalDate;
|
|
32
|
+
why: string;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
35
|
+
/** Memoize by pinned calendar object: distinct releases can reuse a calendar label/version. */
|
|
36
|
+
export declare const businessDaysAfter: (date: LocalDate, days: number, calendar: Calendar) => BusinessDays;
|
|
37
|
+
export declare const formatDate: (date: LocalDate, withWeekday?: boolean) => string;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { isInstant } from "../ir-checks/index.js";
|
|
2
|
+
const toUtc = (date) => Date.parse(`${date}T00:00:00Z`);
|
|
3
|
+
const fromUtc = (ms) => new Date(ms).toISOString().slice(0, 10);
|
|
4
|
+
const DAY = 86_400_000;
|
|
5
|
+
const shifted = new Map();
|
|
6
|
+
export const addDays = (date, days) => {
|
|
7
|
+
const key = `${date}|${days}`;
|
|
8
|
+
let result = shifted.get(key);
|
|
9
|
+
if (result === undefined) {
|
|
10
|
+
result = fromUtc(toUtc(date) + days * DAY);
|
|
11
|
+
shifted.set(key, result);
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
};
|
|
15
|
+
export const addYears = (date, years) => {
|
|
16
|
+
const year = Number(date.slice(0, 4)) + years;
|
|
17
|
+
const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
18
|
+
const suffix = date.endsWith("-02-29") && !leap ? "-02-28" : date.slice(4);
|
|
19
|
+
return `${String(year).padStart(4, "0")}${suffix}`;
|
|
20
|
+
};
|
|
21
|
+
/** Calendar months; a day past the target month's end clamps to its last day (Jan 31 + 1 = Feb 28/29). */
|
|
22
|
+
export const addMonths = (date, months) => {
|
|
23
|
+
const index = Number(date.slice(0, 4)) * 12 + Number(date.slice(5, 7)) - 1 + months;
|
|
24
|
+
const year = Math.floor(index / 12), month = index - year * 12 + 1;
|
|
25
|
+
const last = new Date(Date.UTC(year, month, 0)).getUTCDate();
|
|
26
|
+
const day = Math.min(Number(date.slice(8, 10)), last);
|
|
27
|
+
return `${String(year).padStart(4, "0")}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
|
28
|
+
};
|
|
29
|
+
export const daysBetween = (from, to) => Math.round((toUtc(to) - toUtc(from)) / DAY);
|
|
30
|
+
const weekdays = new Map();
|
|
31
|
+
export const weekday = (date) => {
|
|
32
|
+
let day = weekdays.get(date);
|
|
33
|
+
if (day === undefined) {
|
|
34
|
+
day = new Date(toUtc(date)).getUTCDay();
|
|
35
|
+
weekdays.set(date, day);
|
|
36
|
+
}
|
|
37
|
+
return day;
|
|
38
|
+
};
|
|
39
|
+
export const latest = (...dates) => dates.reduce((a, b) => (a > b ? a : b));
|
|
40
|
+
export const earliest = (...dates) => dates.reduce((a, b) => (a < b ? a : b));
|
|
41
|
+
const nth = (year, month, day, n) => {
|
|
42
|
+
const first = `${year}-${String(month).padStart(2, "0")}-01`;
|
|
43
|
+
const offset = (day - weekday(first) + 7) % 7;
|
|
44
|
+
return addDays(first, offset + (n - 1) * 7);
|
|
45
|
+
};
|
|
46
|
+
const last = (year, month, day) => {
|
|
47
|
+
const end = addDays(`${month === 12 ? year + 1 : year}-${String((month % 12) + 1).padStart(2, "0")}-01`, -1);
|
|
48
|
+
return addDays(end, -((weekday(end) - day + 7) % 7));
|
|
49
|
+
};
|
|
50
|
+
// A fixed-date holiday that falls on a weekend is observed on the nearest weekday.
|
|
51
|
+
const observed = (date) => weekday(date) === 6 ? addDays(date, -1) : weekday(date) === 0 ? addDays(date, 1) : date;
|
|
52
|
+
const WEEKDAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
|
|
53
|
+
export const holidayDate = (rule, year) => {
|
|
54
|
+
if (rule.day !== undefined) {
|
|
55
|
+
const date = `${year}-${String(rule.month).padStart(2, "0")}-${String(rule.day).padStart(2, "0")}`;
|
|
56
|
+
return rule.observed ? observed(date) : date;
|
|
57
|
+
}
|
|
58
|
+
const day = WEEKDAYS.indexOf(rule.weekday ?? "mon");
|
|
59
|
+
return rule.nth === -1 ? last(year, rule.month, day) : nth(year, rule.month, day, rule.nth ?? 1);
|
|
60
|
+
};
|
|
61
|
+
/** A versioned business-day calendar from its declared weekend and holiday rules. */
|
|
62
|
+
export const makeCalendar = (id, version, weekend, rules) => {
|
|
63
|
+
const closed = new Set(weekend.map((d) => WEEKDAYS.indexOf(d)));
|
|
64
|
+
const years = new Map();
|
|
65
|
+
// A December 31 observance of next year's New Year's Day belongs to this year.
|
|
66
|
+
const holidaysOf = (year) => {
|
|
67
|
+
let found = years.get(year);
|
|
68
|
+
if (!found) {
|
|
69
|
+
found = new Map([year, year + 1].flatMap((y) => rules.map((r) => [holidayDate(r, y), r.label])));
|
|
70
|
+
years.set(year, found);
|
|
71
|
+
}
|
|
72
|
+
return found;
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
id,
|
|
76
|
+
version,
|
|
77
|
+
holiday: (date) => holidaysOf(Number(date.slice(0, 4))).get(date),
|
|
78
|
+
isBusinessDay: (date) => !closed.has(weekday(date)) && !holidaysOf(Number(date.slice(0, 4))).has(date),
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
const businessCache = new WeakMap();
|
|
82
|
+
/** Memoize by pinned calendar object: distinct releases can reuse a calendar label/version. */
|
|
83
|
+
export const businessDaysAfter = (date, days, calendar) => {
|
|
84
|
+
let cache = businessCache.get(calendar);
|
|
85
|
+
if (!cache)
|
|
86
|
+
businessCache.set(calendar, (cache = new Map()));
|
|
87
|
+
const key = `${date}|${days}`;
|
|
88
|
+
const hit = cache.get(key);
|
|
89
|
+
if (hit)
|
|
90
|
+
return hit;
|
|
91
|
+
let cursor = date;
|
|
92
|
+
let counted = 0;
|
|
93
|
+
const skipped = [];
|
|
94
|
+
while (counted < days) {
|
|
95
|
+
cursor = addDays(cursor, 1);
|
|
96
|
+
if (calendar.isBusinessDay(cursor))
|
|
97
|
+
counted++;
|
|
98
|
+
else {
|
|
99
|
+
const holiday = calendar.holiday(cursor);
|
|
100
|
+
if (holiday)
|
|
101
|
+
skipped.push({ date: cursor, why: holiday });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const result = { date: cursor, skipped };
|
|
105
|
+
cache.set(key, result);
|
|
106
|
+
return result;
|
|
107
|
+
};
|
|
108
|
+
const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
109
|
+
const DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
110
|
+
const formatted = new Map();
|
|
111
|
+
export const formatDate = (date, withWeekday = true) => {
|
|
112
|
+
if (date.length > 10 && isInstant(date))
|
|
113
|
+
return `${formatDate(date.slice(0, 10), withWeekday)} at ${date.slice(11, 23)} UTC`;
|
|
114
|
+
const key = `${date}|${withWeekday}`;
|
|
115
|
+
let text = formatted.get(key);
|
|
116
|
+
if (text === undefined) {
|
|
117
|
+
text = `${withWeekday ? `${DAYS[weekday(date)]}, ` : ""}${MONTHS[Number(date.slice(5, 7)) - 1]} ${Number(date.slice(8, 10))}, ${date.slice(0, 4)}`;
|
|
118
|
+
formatted.set(key, text);
|
|
119
|
+
}
|
|
120
|
+
return text;
|
|
121
|
+
};
|