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,25 @@
|
|
|
1
|
+
import { type LocalDate } from "./dates.js";
|
|
2
|
+
import type { DecisionRecord, Scalar } from "./basis.js";
|
|
3
|
+
import { type World } from "./memory.js";
|
|
4
|
+
import { type WorldReconciliation } from "./reconcile.js";
|
|
5
|
+
export interface DecisionRequest {
|
|
6
|
+
readonly id: string;
|
|
7
|
+
readonly instance: string;
|
|
8
|
+
readonly decision: string;
|
|
9
|
+
/** Trusted host identity and memberships, never an unverified form field. */
|
|
10
|
+
readonly actor: {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly kind: "human" | "agent";
|
|
13
|
+
readonly groups: readonly string[];
|
|
14
|
+
};
|
|
15
|
+
readonly reason?: Scalar | null;
|
|
16
|
+
readonly revoke?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface DecisionResult {
|
|
19
|
+
readonly world: World;
|
|
20
|
+
readonly accepted: boolean;
|
|
21
|
+
readonly codes: readonly string[];
|
|
22
|
+
readonly record?: DecisionRecord;
|
|
23
|
+
}
|
|
24
|
+
/** Pure admission against the supplied current reconciliation; no durable runtime or I/O. */
|
|
25
|
+
export declare const decide: (recon: WorldReconciliation, world: World, now: LocalDate, request: DecisionRequest) => DecisionResult;
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { instanceContext } from "./evaluation.js";
|
|
2
|
+
import { reusableProof } from "./reuse.js";
|
|
3
|
+
import { isInstant, isLocalDate } from "../ir-checks/index.js";
|
|
4
|
+
import { shiftTime, timeOrder, isPastDeadline } from "./instants.js";
|
|
5
|
+
import { decisionRelease } from "./decision-release.js";
|
|
6
|
+
import {} from "./dates.js";
|
|
7
|
+
import { canonicalJson } from "./result-digest.js";
|
|
8
|
+
import { sha256 } from "./sha256.js";
|
|
9
|
+
import { decisionHeads, validApprovalCount } from "./decision-records.js";
|
|
10
|
+
import { log } from "./journal.js";
|
|
11
|
+
import { basis } from "./memory.js";
|
|
12
|
+
import { admit, evaluateFor, programFor, Unknown, } from "./reconcile.js";
|
|
13
|
+
const isDate = (value) => isLocalDate(value) || isInstant(value);
|
|
14
|
+
const shifted = (date, duration) => {
|
|
15
|
+
if (!Number.isSafeInteger(duration.n) || duration.n < 0)
|
|
16
|
+
return undefined;
|
|
17
|
+
try {
|
|
18
|
+
const value = shiftTime(date.length === 10 && ["minutes", "hours"].includes(duration.unit)
|
|
19
|
+
? `${date}T00:00:00.000Z`
|
|
20
|
+
: date, duration.n, duration.unit);
|
|
21
|
+
return isDate(value) ? value : undefined;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const validReason = (type, value, aliases, seen = new Set()) => {
|
|
28
|
+
if (Array.isArray(type)) {
|
|
29
|
+
if (type[0] === "Option")
|
|
30
|
+
return value == null || validReason(type[1], value, aliases, seen);
|
|
31
|
+
if (type[0] === "Brand")
|
|
32
|
+
return validReason(type[1], value, aliases, seen);
|
|
33
|
+
if (type[0] === "Union")
|
|
34
|
+
return typeof value === "string" && type.slice(1).includes(`:${value}`);
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (typeof type !== "string" || seen.has(type))
|
|
38
|
+
return false;
|
|
39
|
+
const alias = aliases.find((a) => a.name === type);
|
|
40
|
+
if (alias)
|
|
41
|
+
return validReason(alias.type, value, aliases, new Set([...seen, type]));
|
|
42
|
+
if (type === "Bool")
|
|
43
|
+
return typeof value === "boolean";
|
|
44
|
+
if (type === "Int")
|
|
45
|
+
return typeof value === "number" && Number.isSafeInteger(value);
|
|
46
|
+
if (type === "Float")
|
|
47
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
48
|
+
if (type === "Date")
|
|
49
|
+
return (typeof value === "string" &&
|
|
50
|
+
/^\d{4}-\d{2}-\d{2}$/.test(value) &&
|
|
51
|
+
!Number.isNaN(Date.parse(value)) &&
|
|
52
|
+
new Date(value).toISOString().slice(0, 10) === value);
|
|
53
|
+
return (["String", "Keyword", "Group"].includes(type) &&
|
|
54
|
+
typeof value === "string" &&
|
|
55
|
+
value.trim().length > 0);
|
|
56
|
+
};
|
|
57
|
+
/** Pure admission against the supplied current reconciliation; no durable runtime or I/O. */
|
|
58
|
+
export const decide = (recon, world, now, request) => {
|
|
59
|
+
const rejected = (...codes) => ({
|
|
60
|
+
accepted: false,
|
|
61
|
+
codes,
|
|
62
|
+
world: log(world, {
|
|
63
|
+
at: now,
|
|
64
|
+
actor: request.actor.id,
|
|
65
|
+
title: `Rejected decision ${request.decision}`,
|
|
66
|
+
context: request.instance,
|
|
67
|
+
changes: [{ label: "admission", before: "requested", after: codes.join(", ") }],
|
|
68
|
+
}),
|
|
69
|
+
});
|
|
70
|
+
const commandDigest = sha256(canonicalJson({
|
|
71
|
+
instance: request.instance,
|
|
72
|
+
decision: request.decision,
|
|
73
|
+
actor: request.actor.id,
|
|
74
|
+
kind: request.actor.kind,
|
|
75
|
+
reason: request.reason ?? null,
|
|
76
|
+
revoke: request.revoke ?? null,
|
|
77
|
+
}));
|
|
78
|
+
const previous = world.decisions?.find((d) => d.id === request.id);
|
|
79
|
+
if (previous)
|
|
80
|
+
return previous.commandDigest === commandDigest
|
|
81
|
+
? { accepted: true, codes: [], world, record: previous }
|
|
82
|
+
: rejected("decision-duplicate");
|
|
83
|
+
if (recon.now !== now)
|
|
84
|
+
return rejected("decision-snapshot");
|
|
85
|
+
if (request.actor.kind !== "human")
|
|
86
|
+
return rejected("decision-authority");
|
|
87
|
+
const instance = recon.instances.get(request.instance), program = programFor(recon, request.instance);
|
|
88
|
+
const definition = program?.ir.decisions?.find((d) => d.name === request.decision && d.of === instance?.component);
|
|
89
|
+
if (!instance || !program || !definition || !request.id.trim())
|
|
90
|
+
return rejected("decision-target");
|
|
91
|
+
const target = recon.results
|
|
92
|
+
.get(instance.id)
|
|
93
|
+
?.requirements.find((r) => r.name === definition.applies);
|
|
94
|
+
const component = program.components.get(instance.component);
|
|
95
|
+
const addedItem = definition.effect === "add"
|
|
96
|
+
? [...component.requirements, ...component.slots.filter((s) => s.mode === "child")].find((item) => item.name === definition.applies && item.discretionary === definition.name)
|
|
97
|
+
: undefined;
|
|
98
|
+
if (definition.effect === "add" ? !addedItem : !target)
|
|
99
|
+
return rejected("decision-target");
|
|
100
|
+
const snapshot = basis(world, now), evaluate = (e) => {
|
|
101
|
+
try {
|
|
102
|
+
return evaluateFor(recon, snapshot, now, instance.id, e, target?.occurrence ?? `${instance.id}/${definition.applies}`);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return new Unknown("Decision expression failed");
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const who = evaluate(definition.by);
|
|
109
|
+
const group = definition.byKind === "group" ||
|
|
110
|
+
(definition.byKind === undefined &&
|
|
111
|
+
((definition.by.k === "call" && definition.by.fn === "members") ||
|
|
112
|
+
(typeof who === "string" && snapshot.nsOf(who) === undefined)));
|
|
113
|
+
if (typeof who !== "string" ||
|
|
114
|
+
!(group ? request.actor.groups.includes(who) : who === request.actor.id))
|
|
115
|
+
return rejected("decision-authority");
|
|
116
|
+
let home;
|
|
117
|
+
const homePath = component.home?.kind === "input"
|
|
118
|
+
? component.home.path
|
|
119
|
+
: component.home
|
|
120
|
+
? []
|
|
121
|
+
: [component.key[0]];
|
|
122
|
+
for (const [index, part] of homePath.entries()) {
|
|
123
|
+
home =
|
|
124
|
+
index === 0
|
|
125
|
+
? instance.inputs.get(part)
|
|
126
|
+
: home && typeof home === "object" && "inst" in home
|
|
127
|
+
? recon.instances.get(home.inst)?.inputs.get(part)
|
|
128
|
+
: undefined;
|
|
129
|
+
}
|
|
130
|
+
if (typeof home !== "string")
|
|
131
|
+
return rejected("decision-home");
|
|
132
|
+
if (admit(recon, snapshot, now, { kind: request.revoke ? "revoke" : "decide", subject: home })
|
|
133
|
+
.length)
|
|
134
|
+
return rejected("decision-invariant");
|
|
135
|
+
const heads = decisionHeads(snapshot.decisions?.(instance.id) ?? [], definition.name, definition.approvals !== undefined);
|
|
136
|
+
const head = request.revoke
|
|
137
|
+
? heads.find((r) => r.id === request.revoke)
|
|
138
|
+
: definition.approvals
|
|
139
|
+
? heads.find((r) => r.by === request.actor.id)
|
|
140
|
+
: heads[0];
|
|
141
|
+
if (request.revoke &&
|
|
142
|
+
(!head || head.kind !== "grant" || head.release !== decisionRelease(program)))
|
|
143
|
+
return rejected("decision-stale");
|
|
144
|
+
let approvals;
|
|
145
|
+
const distinctFrom = [];
|
|
146
|
+
if (!request.revoke) {
|
|
147
|
+
const count = definition.approvals ? evaluate(definition.approvals) : undefined;
|
|
148
|
+
if (definition.approvals && !validApprovalCount(count))
|
|
149
|
+
return rejected("decision-approvals");
|
|
150
|
+
if (validApprovalCount(count))
|
|
151
|
+
approvals = count;
|
|
152
|
+
for (const exclusion of definition.distinctFrom ?? []) {
|
|
153
|
+
const principal = evaluate(exclusion);
|
|
154
|
+
if (typeof principal !== "string" || principal === request.actor.id)
|
|
155
|
+
return rejected("decision-distinct");
|
|
156
|
+
distinctFrom.push(principal);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (!request.revoke && definition.when && evaluate(definition.when) !== true)
|
|
160
|
+
return rejected("decision-condition");
|
|
161
|
+
if (!validReason(definition.reason, request.reason, program.ir.types))
|
|
162
|
+
return rejected("decision-reason");
|
|
163
|
+
let expiresAt, deferredUntil, from, evidence;
|
|
164
|
+
if (!request.revoke && definition.expires) {
|
|
165
|
+
const duration = evaluate(definition.expires);
|
|
166
|
+
if (!duration ||
|
|
167
|
+
typeof duration !== "object" ||
|
|
168
|
+
!("n" in duration) ||
|
|
169
|
+
!Number.isSafeInteger(duration.n) ||
|
|
170
|
+
duration.n <= 0)
|
|
171
|
+
return rejected("decision-expiry");
|
|
172
|
+
expiresAt = shifted(now, duration);
|
|
173
|
+
if (!expiresAt)
|
|
174
|
+
return rejected("decision-expiry");
|
|
175
|
+
}
|
|
176
|
+
if (!request.revoke && definition.until && definition.effect !== "defer") {
|
|
177
|
+
const until = evaluate(definition.until);
|
|
178
|
+
if (!isDate(until) || timeOrder(until, now) <= 0)
|
|
179
|
+
return rejected("decision-expiry");
|
|
180
|
+
if (!expiresAt || timeOrder(until, expiresAt) < 0)
|
|
181
|
+
expiresAt = until;
|
|
182
|
+
}
|
|
183
|
+
if (!request.revoke && definition.effect === "defer") {
|
|
184
|
+
const target = recon.results
|
|
185
|
+
.get(instance.id)
|
|
186
|
+
.requirements.find((r) => r.name === definition.applies);
|
|
187
|
+
if (["Satisfied", "Waived", "NotApplicable"].includes(target.status))
|
|
188
|
+
return rejected("decision-state");
|
|
189
|
+
const until = definition.until ? evaluate(definition.until) : new Unknown("missing until");
|
|
190
|
+
const due = recon.results
|
|
191
|
+
.get(instance.id)
|
|
192
|
+
.requirements.find((r) => r.name === definition.applies).due;
|
|
193
|
+
if (!isDate(until) || isPastDeadline(now, until) || !due)
|
|
194
|
+
return rejected("decision-until");
|
|
195
|
+
deferredUntil = until;
|
|
196
|
+
}
|
|
197
|
+
if (!request.revoke && definition.effect === "accept") {
|
|
198
|
+
const requirement = program.components
|
|
199
|
+
.get(instance.component)
|
|
200
|
+
.requirements.find((r) => r.name === definition.applies);
|
|
201
|
+
if (requirement.reuse) {
|
|
202
|
+
const candidate = reusableProof({ ...instanceContext(recon, snapshot, instance), occurrence: target.occurrence }, requirement);
|
|
203
|
+
if (!candidate || candidate instanceof Unknown)
|
|
204
|
+
return rejected("decision-prior");
|
|
205
|
+
from = candidate.from;
|
|
206
|
+
evidence = candidate.record.id;
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
const accepts = requirement.accepts;
|
|
210
|
+
if (!accepts || !instance.prior)
|
|
211
|
+
return rejected("decision-prior");
|
|
212
|
+
const priorRequirement = recon.results
|
|
213
|
+
.get(instance.prior)
|
|
214
|
+
?.requirements.find((r) => r.name === (accepts.from ?? requirement.name));
|
|
215
|
+
const prior = priorRequirement?.status === "Satisfied" ? priorRequirement.evidence : null;
|
|
216
|
+
if (!prior || prior.status !== "attested")
|
|
217
|
+
return rejected("decision-prior");
|
|
218
|
+
if (accepts.within) {
|
|
219
|
+
const duration = evaluate(accepts.within);
|
|
220
|
+
if (!duration || typeof duration !== "object" || !("n" in duration))
|
|
221
|
+
return rejected("decision-prior");
|
|
222
|
+
const last = shifted(prior.at, duration);
|
|
223
|
+
if (!last || isPastDeadline(now, last))
|
|
224
|
+
return rejected("decision-prior");
|
|
225
|
+
}
|
|
226
|
+
from = instance.prior;
|
|
227
|
+
evidence = prior.id;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const record = {
|
|
231
|
+
id: request.id,
|
|
232
|
+
instance: instance.id,
|
|
233
|
+
decision: definition.name,
|
|
234
|
+
requirement: definition.applies,
|
|
235
|
+
effect: definition.effect,
|
|
236
|
+
kind: request.revoke ? "revoke" : "grant",
|
|
237
|
+
at: now,
|
|
238
|
+
by: request.actor.id,
|
|
239
|
+
reason: request.reason ?? null,
|
|
240
|
+
release: decisionRelease(program),
|
|
241
|
+
commandDigest,
|
|
242
|
+
authority: { kind: group ? "group" : "individual", principal: who },
|
|
243
|
+
...(approvals !== undefined ? { approvals } : {}),
|
|
244
|
+
...(!request.revoke && definition.distinctFrom ? { distinctFrom } : {}),
|
|
245
|
+
...(request.revoke ? { revokes: request.revoke } : {}),
|
|
246
|
+
...(expiresAt ? { expiresAt } : {}),
|
|
247
|
+
...(deferredUntil ? { deferredUntil } : {}),
|
|
248
|
+
...(from ? { from } : {}),
|
|
249
|
+
...(evidence ? { evidence } : {}),
|
|
250
|
+
};
|
|
251
|
+
return {
|
|
252
|
+
accepted: true,
|
|
253
|
+
codes: [],
|
|
254
|
+
record,
|
|
255
|
+
world: log({ ...world, decisions: [...(world.decisions ?? []), record] }, {
|
|
256
|
+
at: now,
|
|
257
|
+
actor: request.actor.id,
|
|
258
|
+
title: `${request.revoke ? "Revoked" : "Granted"} ${definition.name}`,
|
|
259
|
+
context: instance.id,
|
|
260
|
+
changes: [{ label: "decision", before: head?.id ?? "none", after: record.id }],
|
|
261
|
+
}),
|
|
262
|
+
};
|
|
263
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as IR from "../world-ir/types.generated.js";
|
|
2
|
+
import type { LocalDate } from "./dates.js";
|
|
3
|
+
import { type SelectedDecision } from "./decision-records.js";
|
|
4
|
+
import { type Cx, type Value } from "./model.js";
|
|
5
|
+
export declare const withinProofPeriod: (cx: Cx, at: LocalDate) => boolean;
|
|
6
|
+
export declare const decisionApprovalCount: (cx: Cx, definition: IR.Decision) => Value;
|
|
7
|
+
export declare const selectedDecision: (cx: Cx, requirement: string, boundary?: (date: LocalDate) => void) => SelectedDecision | null;
|
|
8
|
+
export declare const selectedAddition: (cx: Cx, target: string, boundary?: (date: LocalDate) => void) => SelectedDecision | null;
|
|
9
|
+
export declare const legacyAcceptance: (cx: Cx, requirement: IR.Component["requirements"][number]) => import("./basis.js").AcceptanceRecord | undefined;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { evidenceSuperseded, supersededEvidence } from "./evidence-history.js";
|
|
2
|
+
import { timeOrder } from "./instants.js";
|
|
3
|
+
import { selectDecision } from "./decision-records.js";
|
|
4
|
+
import { decisionRelease } from "./decision-release.js";
|
|
5
|
+
import { evaluateIn, isUnknown } from "./evaluation.js";
|
|
6
|
+
import { Unknown } from "./model.js";
|
|
7
|
+
export const withinProofPeriod = (cx, at) => !cx.proofPeriod ||
|
|
8
|
+
(timeOrder(at, cx.proofPeriod.start) >= 0 &&
|
|
9
|
+
(!cx.proofPeriod.next || timeOrder(at, cx.proofPeriod.next) < 0));
|
|
10
|
+
export const decisionApprovalCount = (cx, definition) => {
|
|
11
|
+
if (!definition.approvals)
|
|
12
|
+
return 1;
|
|
13
|
+
if (!cx.inst)
|
|
14
|
+
return new Unknown("Decision has no owning occurrence");
|
|
15
|
+
const requirement = cx.p.components
|
|
16
|
+
.get(cx.inst.component)
|
|
17
|
+
?.requirements.find((r) => r.name === definition.applies);
|
|
18
|
+
const cycle = requirement?.cycle ? evaluateIn(cx, requirement.cycle) : null;
|
|
19
|
+
const occurrence = cx.occurrence ??
|
|
20
|
+
`${cx.inst.id}/${definition.applies}${cycle !== null && !isUnknown(cycle) ? `@${String(cycle)}` : ""}`;
|
|
21
|
+
return evaluateIn({ ...cx, occurrence }, definition.approvals);
|
|
22
|
+
};
|
|
23
|
+
export const selectedDecision = (cx, requirement, boundary) => {
|
|
24
|
+
const definitions = cx.p.ir.decisions ?? [];
|
|
25
|
+
const alias = cx.inst
|
|
26
|
+
? cx.p.components.get(cx.inst.component)?.requirements.find((r) => r.name === requirement)
|
|
27
|
+
?.accepts?.with
|
|
28
|
+
: undefined;
|
|
29
|
+
const target = alias ?? requirement;
|
|
30
|
+
if (!cx.inst ||
|
|
31
|
+
!definitions.some((d) => d.of === cx.inst.component && d.applies === target && d.effect !== "add"))
|
|
32
|
+
return null;
|
|
33
|
+
const selected = selectDecision(definitions, cx.proofPeriod
|
|
34
|
+
? (cx.b.decisions?.(cx.inst.id) ?? []).filter((record) => withinProofPeriod(cx, record.at))
|
|
35
|
+
: (cx.b.decisions?.(cx.inst.id) ?? []), cx.inst.component, target, cx.b.now, decisionRelease(cx.p), boundary, (definition) => decisionApprovalCount(cx, definition));
|
|
36
|
+
if (selected?.record.effect === "accept" && selected.record.evidence && selected.record.from) {
|
|
37
|
+
const source = cx.b
|
|
38
|
+
.evidenceOf(selected.record.from)
|
|
39
|
+
.find((e) => e.id === selected.record.evidence);
|
|
40
|
+
if (source && evidenceSuperseded(cx.b, source))
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return alias && selected?.record.effect !== "accept" ? null : selected;
|
|
44
|
+
};
|
|
45
|
+
export const selectedAddition = (cx, target, boundary) => {
|
|
46
|
+
if (!cx.inst)
|
|
47
|
+
return null;
|
|
48
|
+
const component = cx.p.components.get(cx.inst.component);
|
|
49
|
+
const item = [...component.requirements, ...component.slots].find((item) => item.name === target);
|
|
50
|
+
if (!item?.discretionary)
|
|
51
|
+
return null;
|
|
52
|
+
return selectDecision((cx.p.ir.decisions ?? []).filter((d) => d.name === item.discretionary), cx.b.decisions?.(cx.inst.id) ?? [], cx.inst.component, target, cx.b.now, decisionRelease(cx.p), boundary, (definition) => decisionApprovalCount(cx, definition), "addition");
|
|
53
|
+
};
|
|
54
|
+
export const legacyAcceptance = (cx, requirement) => {
|
|
55
|
+
if (!cx.inst || !requirement.accepts)
|
|
56
|
+
return undefined;
|
|
57
|
+
const hasHistory = (cx.b.decisions?.(cx.inst.id) ?? []).some((record) => withinProofPeriod(cx, record.at) &&
|
|
58
|
+
record.requirement === (requirement.accepts?.with ?? requirement.name) &&
|
|
59
|
+
record.effect !== "add");
|
|
60
|
+
const accepted = hasHistory
|
|
61
|
+
? undefined
|
|
62
|
+
: cx.b.acceptance(cx.inst.id, requirement.accepts.with ?? requirement.name);
|
|
63
|
+
if (accepted &&
|
|
64
|
+
supersededEvidence(cx.b.evidence(`${accepted.from}/${requirement.accepts.from ?? requirement.name}`)).size)
|
|
65
|
+
return undefined;
|
|
66
|
+
return accepted && withinProofPeriod(cx, accepted.at) ? accepted : undefined;
|
|
67
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DecisionRecord } from "./basis.js";
|
|
2
|
+
import type * as IR from "../world-ir/types.generated.js";
|
|
3
|
+
import { type LocalDate } from "./dates.js";
|
|
4
|
+
export interface SelectedDecision {
|
|
5
|
+
readonly definition: IR.Decision;
|
|
6
|
+
readonly record: DecisionRecord;
|
|
7
|
+
readonly votes?: readonly DecisionRecord[];
|
|
8
|
+
}
|
|
9
|
+
export declare const validApprovalCount: (value: unknown) => value is number;
|
|
10
|
+
export declare const latestDecision: (records: readonly DecisionRecord[], name: string) => DecisionRecord | undefined;
|
|
11
|
+
/** A revocation replaces the target signer's head, even when another reviewer rescinds it. */
|
|
12
|
+
export declare const decisionHeads: (records: readonly DecisionRecord[], name: string, perSigner: boolean) => readonly DecisionRecord[];
|
|
13
|
+
/** Current heads only: an expired or revoked vote never exposes an older grant. */
|
|
14
|
+
export declare const selectDecision: (definitions: readonly IR.Decision[], records: readonly DecisionRecord[], component: string, requirement: string, now: LocalDate, release: string, boundary?: (date: LocalDate) => void, approvalCount?: (definition: IR.Decision) => unknown, mode?: "normal" | "addition") => SelectedDecision | null;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { timeOrder, nextTime } from "./instants.js";
|
|
2
|
+
import {} from "./dates.js";
|
|
3
|
+
export const validApprovalCount = (value) => typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
4
|
+
export const latestDecision = (records, name) => {
|
|
5
|
+
let latest;
|
|
6
|
+
for (const record of records)
|
|
7
|
+
if (record.decision === name && (!latest || timeOrder(latest.at, record.at) <= 0))
|
|
8
|
+
latest = record;
|
|
9
|
+
return latest;
|
|
10
|
+
};
|
|
11
|
+
/** A revocation replaces the target signer's head, even when another reviewer rescinds it. */
|
|
12
|
+
export const decisionHeads = (records, name, perSigner) => {
|
|
13
|
+
if (!perSigner) {
|
|
14
|
+
const head = latestDecision(records, name);
|
|
15
|
+
return head ? [head] : [];
|
|
16
|
+
}
|
|
17
|
+
const owned = records.filter((r) => r.decision === name);
|
|
18
|
+
const byId = new Map(owned.map((r) => [r.id, r]));
|
|
19
|
+
const heads = new Map();
|
|
20
|
+
for (const record of owned) {
|
|
21
|
+
const signer = record.kind === "grant" ? record.by : byId.get(record.revokes ?? "")?.by;
|
|
22
|
+
if (!signer)
|
|
23
|
+
continue;
|
|
24
|
+
const previous = heads.get(signer);
|
|
25
|
+
if (!previous || timeOrder(previous.at, record.at) <= 0)
|
|
26
|
+
heads.set(signer, record);
|
|
27
|
+
}
|
|
28
|
+
const current = new Set(heads.values());
|
|
29
|
+
return owned.filter((r) => current.has(r));
|
|
30
|
+
};
|
|
31
|
+
/** Current heads only: an expired or revoked vote never exposes an older grant. */
|
|
32
|
+
export const selectDecision = (definitions, records, component, requirement, now, release, boundary, approvalCount, mode = "normal") => {
|
|
33
|
+
const candidates = new Map();
|
|
34
|
+
for (const definition of definitions)
|
|
35
|
+
if (definition.of === component &&
|
|
36
|
+
definition.applies === requirement &&
|
|
37
|
+
(mode === "addition" ? definition.effect === "add" : definition.effect !== "add"))
|
|
38
|
+
candidates.set(definition.name, definition);
|
|
39
|
+
const visible = records.filter((r) => timeOrder(r.at, now) <= 0);
|
|
40
|
+
const qualified = new Map();
|
|
41
|
+
for (const definition of candidates.values()) {
|
|
42
|
+
const votes = decisionHeads(visible, definition.name, definition.approvals !== undefined).filter((record) => {
|
|
43
|
+
if (record.kind !== "grant" ||
|
|
44
|
+
record.release !== release ||
|
|
45
|
+
record.effect !== definition.effect ||
|
|
46
|
+
(record.authority !== undefined &&
|
|
47
|
+
definition.byKind !== undefined &&
|
|
48
|
+
record.authority.kind !== definition.byKind))
|
|
49
|
+
return false;
|
|
50
|
+
if (record.expiresAt)
|
|
51
|
+
boundary?.(record.expiresAt);
|
|
52
|
+
if (record.deferredUntil) {
|
|
53
|
+
const next = nextTime(record.deferredUntil);
|
|
54
|
+
if (next)
|
|
55
|
+
boundary?.(next);
|
|
56
|
+
}
|
|
57
|
+
return !record.expiresAt || timeOrder(now, record.expiresAt) < 0;
|
|
58
|
+
});
|
|
59
|
+
const count = definition.approvals ? approvalCount?.(definition) : 1;
|
|
60
|
+
if (!validApprovalCount(count) || votes.length < count)
|
|
61
|
+
continue;
|
|
62
|
+
const record = votes.reduce((latest, next) => timeOrder(latest.at, next.at) <= 0 ? next : latest);
|
|
63
|
+
qualified.set(definition.name, {
|
|
64
|
+
definition,
|
|
65
|
+
record,
|
|
66
|
+
...(definition.approvals ? { votes } : {}),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
let selected = null;
|
|
70
|
+
for (const record of records) {
|
|
71
|
+
const candidate = qualified.get(record.decision);
|
|
72
|
+
if (candidate?.record === record &&
|
|
73
|
+
(!selected || timeOrder(selected.record.at, record.at) <= 0))
|
|
74
|
+
selected = candidate;
|
|
75
|
+
}
|
|
76
|
+
return selected;
|
|
77
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { semanticJson } from "./result-digest.js";
|
|
2
|
+
import { sha256 } from "./sha256.js";
|
|
3
|
+
const releases = new WeakMap();
|
|
4
|
+
/** Grants bind to the immutable library and account release, excluding source spans. */
|
|
5
|
+
export const decisionRelease = (program) => {
|
|
6
|
+
let digest = releases.get(program);
|
|
7
|
+
if (!digest) {
|
|
8
|
+
digest = `sha256:${sha256(semanticJson([program.library.digest, program.account.name, program.account.package.digest, program.account.params, ...(program.account.policies?.length ? [program.account.policies] : [])]))}`;
|
|
9
|
+
releases.set(program, digest);
|
|
10
|
+
}
|
|
11
|
+
return digest;
|
|
12
|
+
};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import type { AcceptanceRecord, ConfirmationRecord, Basis, DispatchRecord, DecisionRecord, EvidenceRecord, Fact, FileRecord, DocumentRecord, NoticeDeliveryRecord, NoticeAcknowledgmentRecord, Scalar, SignalRecord, MilestoneRecord, LifecycleRecord, ResourceRecord } from "./basis.js";
|
|
2
|
+
import type { TimePoint } from "./instants.js";
|
|
3
|
+
import type { Program, Status, Truth, Value } from "./reconcile.js";
|
|
4
|
+
/** A query's identity and its observed value, including missing records. */
|
|
5
|
+
export type Dependency = {
|
|
6
|
+
readonly kind: "lifecycles";
|
|
7
|
+
readonly account: string;
|
|
8
|
+
readonly home: string;
|
|
9
|
+
readonly value: readonly LifecycleRecord[];
|
|
10
|
+
} | {
|
|
11
|
+
readonly kind: "lifecycle";
|
|
12
|
+
readonly account: string;
|
|
13
|
+
readonly instance: string;
|
|
14
|
+
readonly value: LifecycleRecord | null;
|
|
15
|
+
} | {
|
|
16
|
+
readonly kind: "resources";
|
|
17
|
+
readonly account: string;
|
|
18
|
+
readonly home: string;
|
|
19
|
+
readonly value: readonly ResourceRecord[];
|
|
20
|
+
} | {
|
|
21
|
+
readonly kind: "document";
|
|
22
|
+
readonly account: string;
|
|
23
|
+
readonly home: string;
|
|
24
|
+
readonly key: string;
|
|
25
|
+
readonly value: DocumentRecord | null;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: "notice-delivery";
|
|
28
|
+
readonly account: string;
|
|
29
|
+
readonly home: string;
|
|
30
|
+
readonly key: string;
|
|
31
|
+
readonly value: NoticeDeliveryRecord | null;
|
|
32
|
+
} | {
|
|
33
|
+
readonly kind: "notice-acknowledgment";
|
|
34
|
+
readonly account: string;
|
|
35
|
+
readonly home: string;
|
|
36
|
+
readonly key: string;
|
|
37
|
+
readonly value: NoticeAcknowledgmentRecord | null;
|
|
38
|
+
} | {
|
|
39
|
+
readonly kind: "file";
|
|
40
|
+
readonly account: string;
|
|
41
|
+
readonly home: string;
|
|
42
|
+
readonly digest: string;
|
|
43
|
+
readonly value: FileRecord | null;
|
|
44
|
+
} | {
|
|
45
|
+
readonly kind: "scoped-evidence";
|
|
46
|
+
readonly scope: string;
|
|
47
|
+
readonly value: readonly EvidenceRecord[];
|
|
48
|
+
} | {
|
|
49
|
+
readonly kind: "confirmation";
|
|
50
|
+
readonly entity: string;
|
|
51
|
+
readonly attribute: string;
|
|
52
|
+
readonly value: ConfirmationRecord | null;
|
|
53
|
+
} | {
|
|
54
|
+
readonly kind: "milestone";
|
|
55
|
+
readonly instance: string;
|
|
56
|
+
readonly name: string;
|
|
57
|
+
readonly value: MilestoneRecord | null;
|
|
58
|
+
} | {
|
|
59
|
+
readonly kind: "decisions";
|
|
60
|
+
readonly instance: string;
|
|
61
|
+
readonly value: readonly DecisionRecord[];
|
|
62
|
+
} | {
|
|
63
|
+
readonly kind: "fact";
|
|
64
|
+
readonly entity: string;
|
|
65
|
+
readonly attribute: string;
|
|
66
|
+
readonly value: Fact | null;
|
|
67
|
+
} | {
|
|
68
|
+
readonly kind: "entities";
|
|
69
|
+
readonly namespace: string | null;
|
|
70
|
+
readonly value: readonly string[];
|
|
71
|
+
} | {
|
|
72
|
+
readonly kind: "matching";
|
|
73
|
+
readonly attribute: string;
|
|
74
|
+
readonly where: Scalar;
|
|
75
|
+
readonly value: readonly string[];
|
|
76
|
+
} | {
|
|
77
|
+
readonly kind: "namespace";
|
|
78
|
+
readonly entity: string;
|
|
79
|
+
readonly value: string | null;
|
|
80
|
+
} | {
|
|
81
|
+
readonly kind: "evidence";
|
|
82
|
+
readonly occurrence: string;
|
|
83
|
+
readonly value: readonly EvidenceRecord[];
|
|
84
|
+
} | {
|
|
85
|
+
readonly kind: "instance-evidence";
|
|
86
|
+
readonly instance: string;
|
|
87
|
+
readonly value: readonly EvidenceRecord[];
|
|
88
|
+
} | {
|
|
89
|
+
readonly kind: "acceptance";
|
|
90
|
+
readonly instance: string;
|
|
91
|
+
readonly requirement: string;
|
|
92
|
+
readonly value: AcceptanceRecord | null;
|
|
93
|
+
} | {
|
|
94
|
+
readonly kind: "signals";
|
|
95
|
+
readonly instance: string;
|
|
96
|
+
readonly machine: string;
|
|
97
|
+
readonly value: readonly SignalRecord[];
|
|
98
|
+
} | {
|
|
99
|
+
readonly kind: "dispatch";
|
|
100
|
+
readonly key: string;
|
|
101
|
+
readonly value: DispatchRecord | null;
|
|
102
|
+
} | {
|
|
103
|
+
readonly kind: "clock";
|
|
104
|
+
readonly value: TimePoint;
|
|
105
|
+
} | {
|
|
106
|
+
readonly kind: "time";
|
|
107
|
+
readonly instance: string;
|
|
108
|
+
readonly path: readonly string[];
|
|
109
|
+
readonly value: {
|
|
110
|
+
readonly at: TimePoint;
|
|
111
|
+
readonly why: string;
|
|
112
|
+
} | null;
|
|
113
|
+
} | {
|
|
114
|
+
readonly kind: "program";
|
|
115
|
+
readonly account: string;
|
|
116
|
+
readonly value: {
|
|
117
|
+
readonly library: Program["library"];
|
|
118
|
+
readonly package: Program["account"]["package"];
|
|
119
|
+
readonly params: Program["account"]["params"];
|
|
120
|
+
readonly roots: Program["account"]["forEach"];
|
|
121
|
+
readonly policies?: Program["account"]["policies"];
|
|
122
|
+
readonly entities: Program["ir"]["entities"];
|
|
123
|
+
};
|
|
124
|
+
} | {
|
|
125
|
+
readonly kind: "input";
|
|
126
|
+
readonly instance: string;
|
|
127
|
+
readonly name: string;
|
|
128
|
+
readonly value: Value;
|
|
129
|
+
} | {
|
|
130
|
+
readonly kind: "members";
|
|
131
|
+
readonly instance: string;
|
|
132
|
+
readonly value: readonly string[];
|
|
133
|
+
} | {
|
|
134
|
+
readonly kind: "status";
|
|
135
|
+
readonly instance: string;
|
|
136
|
+
readonly name: string;
|
|
137
|
+
readonly value: Status;
|
|
138
|
+
} | {
|
|
139
|
+
readonly kind: "slot";
|
|
140
|
+
readonly instance: string;
|
|
141
|
+
readonly name: string;
|
|
142
|
+
readonly value: {
|
|
143
|
+
readonly applies: Truth;
|
|
144
|
+
readonly instances: readonly string[];
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
/** Tuple keys distinguish opaque ids and scalar types without delimiter collisions. */
|
|
148
|
+
export declare const dependencyKey: (d: Dependency) => string;
|
|
149
|
+
export declare const programDependency: (p: Program) => Dependency;
|
|
150
|
+
export declare class ReadSet {
|
|
151
|
+
private entriesByKey;
|
|
152
|
+
private cached;
|
|
153
|
+
add(d: Dependency, key?: string): void;
|
|
154
|
+
merge(entries: Iterable<readonly [string, Dependency]>, keep?: (d: Dependency) => boolean): void;
|
|
155
|
+
entries(): MapIterator<[string, Dependency]>;
|
|
156
|
+
values(): Iterable<Dependency>;
|
|
157
|
+
snapshot(): ReadonlyMap<string, Dependency>;
|
|
158
|
+
}
|
|
159
|
+
/** Internal projections can differ by consumer in cycles; keep them occurrence-local. */
|
|
160
|
+
export declare const isLocalDependency: (d: Dependency) => boolean;
|
|
161
|
+
/** Immutable union of sorted maps without copying shared observations into every result. */
|
|
162
|
+
export declare class DependencyMap implements ReadonlyMap<string, Dependency> {
|
|
163
|
+
readonly shared: ReadonlyMap<string, Dependency>;
|
|
164
|
+
readonly local: ReadonlyMap<string, Dependency>;
|
|
165
|
+
constructor(shared: ReadonlyMap<string, Dependency>, local: ReadonlyMap<string, Dependency>);
|
|
166
|
+
get size(): number;
|
|
167
|
+
get(key: string): Dependency | undefined;
|
|
168
|
+
has(key: string): boolean;
|
|
169
|
+
entries(): MapIterator<[string, Dependency]>;
|
|
170
|
+
[Symbol.iterator](): MapIterator<[string, Dependency]>;
|
|
171
|
+
keys(): MapIterator<string>;
|
|
172
|
+
values(): MapIterator<Dependency>;
|
|
173
|
+
forEach(callback: (value: Dependency, key: string, map: ReadonlyMap<string, Dependency>) => void, thisArg?: unknown): void;
|
|
174
|
+
toJSON(): [string, Dependency][];
|
|
175
|
+
}
|
|
176
|
+
/** Observe every query, interning identical observations without caching query results. */
|
|
177
|
+
export declare const observeBasis: (b: Basis, reads: ReadSet) => Basis;
|
|
178
|
+
/** Forecast time over the current snapshot, retaining its actual clock observation. */
|
|
179
|
+
export declare const forecastBasis: (b: Basis, now: TimePoint) => Basis;
|