@virune/compiler 1.1.0-rc.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/LICENSE +201 -0
- package/NOTICE +2 -0
- package/dist/src/analysis/control-flow.d.ts +9 -0
- package/dist/src/analysis/control-flow.d.ts.map +1 -0
- package/dist/src/analysis/control-flow.js +47 -0
- package/dist/src/analysis/control-flow.js.map +1 -0
- package/dist/src/ast/nodes.d.ts +495 -0
- package/dist/src/ast/nodes.d.ts.map +1 -0
- package/dist/src/ast/nodes.js +2 -0
- package/dist/src/ast/nodes.js.map +1 -0
- package/dist/src/binder/symbols.d.ts +36 -0
- package/dist/src/binder/symbols.d.ts.map +1 -0
- package/dist/src/binder/symbols.js +30 -0
- package/dist/src/binder/symbols.js.map +1 -0
- package/dist/src/checker/builtin-members.d.ts +4 -0
- package/dist/src/checker/builtin-members.d.ts.map +1 -0
- package/dist/src/checker/builtin-members.js +175 -0
- package/dist/src/checker/builtin-members.js.map +1 -0
- package/dist/src/checker/checker.d.ts +148 -0
- package/dist/src/checker/checker.d.ts.map +1 -0
- package/dist/src/checker/checker.js +2985 -0
- package/dist/src/checker/checker.js.map +1 -0
- package/dist/src/checker/effect-registry.d.ts +14 -0
- package/dist/src/checker/effect-registry.d.ts.map +1 -0
- package/dist/src/checker/effect-registry.js +11 -0
- package/dist/src/checker/effect-registry.js.map +1 -0
- package/dist/src/checker/type-operations.d.ts +27 -0
- package/dist/src/checker/type-operations.d.ts.map +1 -0
- package/dist/src/checker/type-operations.js +268 -0
- package/dist/src/checker/type-operations.js.map +1 -0
- package/dist/src/codegen/emitter.d.ts +83 -0
- package/dist/src/codegen/emitter.d.ts.map +1 -0
- package/dist/src/codegen/emitter.js +1029 -0
- package/dist/src/codegen/emitter.js.map +1 -0
- package/dist/src/codegen/helpers.d.ts +7 -0
- package/dist/src/codegen/helpers.d.ts.map +1 -0
- package/dist/src/codegen/helpers.js +48 -0
- package/dist/src/codegen/helpers.js.map +1 -0
- package/dist/src/codegen/runtime-imports.d.ts +6 -0
- package/dist/src/codegen/runtime-imports.d.ts.map +1 -0
- package/dist/src/codegen/runtime-imports.js +45 -0
- package/dist/src/codegen/runtime-imports.js.map +1 -0
- package/dist/src/codegen/writer.d.ts +14 -0
- package/dist/src/codegen/writer.d.ts.map +1 -0
- package/dist/src/codegen/writer.js +56 -0
- package/dist/src/codegen/writer.js.map +1 -0
- package/dist/src/compiler.d.ts +24 -0
- package/dist/src/compiler.d.ts.map +1 -0
- package/dist/src/compiler.js +97 -0
- package/dist/src/compiler.js.map +1 -0
- package/dist/src/diagnostics/codes.d.ts +18 -0
- package/dist/src/diagnostics/codes.d.ts.map +1 -0
- package/dist/src/diagnostics/codes.js +43 -0
- package/dist/src/diagnostics/codes.js.map +1 -0
- package/dist/src/diagnostics/diagnostic.d.ts +41 -0
- package/dist/src/diagnostics/diagnostic.d.ts.map +1 -0
- package/dist/src/diagnostics/diagnostic.js +50 -0
- package/dist/src/diagnostics/diagnostic.js.map +1 -0
- package/dist/src/diagnostics/render.d.ts +44 -0
- package/dist/src/diagnostics/render.d.ts.map +1 -0
- package/dist/src/diagnostics/render.js +44 -0
- package/dist/src/diagnostics/render.js.map +1 -0
- package/dist/src/experimental-api.d.ts +19 -0
- package/dist/src/experimental-api.d.ts.map +1 -0
- package/dist/src/experimental-api.js +17 -0
- package/dist/src/experimental-api.js.map +1 -0
- package/dist/src/hir/lower.d.ts +6 -0
- package/dist/src/hir/lower.d.ts.map +1 -0
- package/dist/src/hir/lower.js +124 -0
- package/dist/src/hir/lower.js.map +1 -0
- package/dist/src/hir/nodes.d.ts +12 -0
- package/dist/src/hir/nodes.d.ts.map +1 -0
- package/dist/src/hir/nodes.js +2 -0
- package/dist/src/hir/nodes.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/interop/checked-api.d.ts +21 -0
- package/dist/src/interop/checked-api.d.ts.map +1 -0
- package/dist/src/interop/checked-api.js +46 -0
- package/dist/src/interop/checked-api.js.map +1 -0
- package/dist/src/interop/decision.d.ts +24 -0
- package/dist/src/interop/decision.d.ts.map +1 -0
- package/dist/src/interop/decision.js +96 -0
- package/dist/src/interop/decision.js.map +1 -0
- package/dist/src/interop/frontend-component-emission.d.ts +17 -0
- package/dist/src/interop/frontend-component-emission.d.ts.map +1 -0
- package/dist/src/interop/frontend-component-emission.js +271 -0
- package/dist/src/interop/frontend-component-emission.js.map +1 -0
- package/dist/src/interop/jsx-view-validation.d.ts +20 -0
- package/dist/src/interop/jsx-view-validation.d.ts.map +1 -0
- package/dist/src/interop/jsx-view-validation.js +847 -0
- package/dist/src/interop/jsx-view-validation.js.map +1 -0
- package/dist/src/interop/operation-api.d.ts +32 -0
- package/dist/src/interop/operation-api.d.ts.map +1 -0
- package/dist/src/interop/operation-api.js +61 -0
- package/dist/src/interop/operation-api.js.map +1 -0
- package/dist/src/interop/operation.d.ts +136 -0
- package/dist/src/interop/operation.d.ts.map +1 -0
- package/dist/src/interop/operation.js +575 -0
- package/dist/src/interop/operation.js.map +1 -0
- package/dist/src/interop/repetition-host-locator.d.ts +25 -0
- package/dist/src/interop/repetition-host-locator.d.ts.map +1 -0
- package/dist/src/interop/repetition-host-locator.js +61 -0
- package/dist/src/interop/repetition-host-locator.js.map +1 -0
- package/dist/src/interop/repetition-host-usage-validation.d.ts +11 -0
- package/dist/src/interop/repetition-host-usage-validation.d.ts.map +1 -0
- package/dist/src/interop/repetition-host-usage-validation.js +89 -0
- package/dist/src/interop/repetition-host-usage-validation.js.map +1 -0
- package/dist/src/interop/types.d.ts +365 -0
- package/dist/src/interop/types.d.ts.map +1 -0
- package/dist/src/interop/types.js +2 -0
- package/dist/src/interop/types.js.map +1 -0
- package/dist/src/mir/lower.d.ts +4 -0
- package/dist/src/mir/lower.d.ts.map +1 -0
- package/dist/src/mir/lower.js +131 -0
- package/dist/src/mir/lower.js.map +1 -0
- package/dist/src/mir/nodes.d.ts +36 -0
- package/dist/src/mir/nodes.d.ts.map +1 -0
- package/dist/src/mir/nodes.js +2 -0
- package/dist/src/mir/nodes.js.map +1 -0
- package/dist/src/project/incremental.d.ts +9 -0
- package/dist/src/project/incremental.d.ts.map +1 -0
- package/dist/src/project/incremental.js +15 -0
- package/dist/src/project/incremental.js.map +1 -0
- package/dist/src/project/project.d.ts +98 -0
- package/dist/src/project/project.d.ts.map +1 -0
- package/dist/src/project/project.js +884 -0
- package/dist/src/project/project.js.map +1 -0
- package/dist/src/public-api.d.ts +45 -0
- package/dist/src/public-api.d.ts.map +1 -0
- package/dist/src/public-api.js +37 -0
- package/dist/src/public-api.js.map +1 -0
- package/dist/src/reference/evaluator.d.ts +13 -0
- package/dist/src/reference/evaluator.d.ts.map +1 -0
- package/dist/src/reference/evaluator.js +304 -0
- package/dist/src/reference/evaluator.js.map +1 -0
- package/dist/src/selfhost/bootstrap-artifact-normalizer.d.ts +65 -0
- package/dist/src/selfhost/bootstrap-artifact-normalizer.d.ts.map +1 -0
- package/dist/src/selfhost/bootstrap-artifact-normalizer.js +226 -0
- package/dist/src/selfhost/bootstrap-artifact-normalizer.js.map +1 -0
- package/dist/src/selfhost/bootstrap-artifact-snapshot.d.ts +23 -0
- package/dist/src/selfhost/bootstrap-artifact-snapshot.d.ts.map +1 -0
- package/dist/src/selfhost/bootstrap-artifact-snapshot.js +122 -0
- package/dist/src/selfhost/bootstrap-artifact-snapshot.js.map +1 -0
- package/dist/src/selfhost/bootstrap-compiler-selection.d.ts +36 -0
- package/dist/src/selfhost/bootstrap-compiler-selection.d.ts.map +1 -0
- package/dist/src/selfhost/bootstrap-compiler-selection.js +52 -0
- package/dist/src/selfhost/bootstrap-compiler-selection.js.map +1 -0
- package/dist/src/selfhost/bootstrap-execution-probe.d.ts +42 -0
- package/dist/src/selfhost/bootstrap-execution-probe.d.ts.map +1 -0
- package/dist/src/selfhost/bootstrap-execution-probe.js +115 -0
- package/dist/src/selfhost/bootstrap-execution-probe.js.map +1 -0
- package/dist/src/selfhost/bootstrap-rollback-decision.d.ts +40 -0
- package/dist/src/selfhost/bootstrap-rollback-decision.d.ts.map +1 -0
- package/dist/src/selfhost/bootstrap-rollback-decision.js +144 -0
- package/dist/src/selfhost/bootstrap-rollback-decision.js.map +1 -0
- package/dist/src/selfhost/bootstrap-shadow-history.d.ts +49 -0
- package/dist/src/selfhost/bootstrap-shadow-history.d.ts.map +1 -0
- package/dist/src/selfhost/bootstrap-shadow-history.js +348 -0
- package/dist/src/selfhost/bootstrap-shadow-history.js.map +1 -0
- package/dist/src/selfhost/bootstrap-shadow-report.d.ts +43 -0
- package/dist/src/selfhost/bootstrap-shadow-report.d.ts.map +1 -0
- package/dist/src/selfhost/bootstrap-shadow-report.js +94 -0
- package/dist/src/selfhost/bootstrap-shadow-report.js.map +1 -0
- package/dist/src/selfhost/bootstrap-stage-executor.d.ts +53 -0
- package/dist/src/selfhost/bootstrap-stage-executor.d.ts.map +1 -0
- package/dist/src/selfhost/bootstrap-stage-executor.js +159 -0
- package/dist/src/selfhost/bootstrap-stage-executor.js.map +1 -0
- package/dist/src/selfhost/bootstrap-stage-loader.d.ts +14 -0
- package/dist/src/selfhost/bootstrap-stage-loader.d.ts.map +1 -0
- package/dist/src/selfhost/bootstrap-stage-loader.js +112 -0
- package/dist/src/selfhost/bootstrap-stage-loader.js.map +1 -0
- package/dist/src/selfhost/bootstrap-stage-pipeline.d.ts +8 -0
- package/dist/src/selfhost/bootstrap-stage-pipeline.d.ts.map +1 -0
- package/dist/src/selfhost/bootstrap-stage-pipeline.js +85 -0
- package/dist/src/selfhost/bootstrap-stage-pipeline.js.map +1 -0
- package/dist/src/selfhost/bootstrap-stage-runner.d.ts +47 -0
- package/dist/src/selfhost/bootstrap-stage-runner.d.ts.map +1 -0
- package/dist/src/selfhost/bootstrap-stage-runner.js +106 -0
- package/dist/src/selfhost/bootstrap-stage-runner.js.map +1 -0
- package/dist/src/selfhost/clean-bootstrap-evidence.d.ts +83 -0
- package/dist/src/selfhost/clean-bootstrap-evidence.d.ts.map +1 -0
- package/dist/src/selfhost/clean-bootstrap-evidence.js +233 -0
- package/dist/src/selfhost/clean-bootstrap-evidence.js.map +1 -0
- package/dist/src/selfhost/compiler-facade.d.ts +33 -0
- package/dist/src/selfhost/compiler-facade.d.ts.map +1 -0
- package/dist/src/selfhost/compiler-facade.js +65 -0
- package/dist/src/selfhost/compiler-facade.js.map +1 -0
- package/dist/src/selfhost/contract.d.ts +151 -0
- package/dist/src/selfhost/contract.d.ts.map +1 -0
- package/dist/src/selfhost/contract.js +335 -0
- package/dist/src/selfhost/contract.js.map +1 -0
- package/dist/src/selfhost/differential-artifacts.d.ts +8 -0
- package/dist/src/selfhost/differential-artifacts.d.ts.map +1 -0
- package/dist/src/selfhost/differential-artifacts.js +50 -0
- package/dist/src/selfhost/differential-artifacts.js.map +1 -0
- package/dist/src/selfhost/differential-harness.d.ts +91 -0
- package/dist/src/selfhost/differential-harness.d.ts.map +1 -0
- package/dist/src/selfhost/differential-harness.js +246 -0
- package/dist/src/selfhost/differential-harness.js.map +1 -0
- package/dist/src/selfhost/full-language-inventory-runner.d.ts +49 -0
- package/dist/src/selfhost/full-language-inventory-runner.d.ts.map +1 -0
- package/dist/src/selfhost/full-language-inventory-runner.js +225 -0
- package/dist/src/selfhost/full-language-inventory-runner.js.map +1 -0
- package/dist/src/selfhost/full-language-inventory.d.ts +42 -0
- package/dist/src/selfhost/full-language-inventory.d.ts.map +1 -0
- package/dist/src/selfhost/full-language-inventory.js +163 -0
- package/dist/src/selfhost/full-language-inventory.js.map +1 -0
- package/dist/src/selfhost/interop-resolution-witness.d.ts +35 -0
- package/dist/src/selfhost/interop-resolution-witness.d.ts.map +1 -0
- package/dist/src/selfhost/interop-resolution-witness.js +186 -0
- package/dist/src/selfhost/interop-resolution-witness.js.map +1 -0
- package/dist/src/selfhost/kernel-model-host-adapter.d.ts +28 -0
- package/dist/src/selfhost/kernel-model-host-adapter.d.ts.map +1 -0
- package/dist/src/selfhost/kernel-model-host-adapter.js +36 -0
- package/dist/src/selfhost/kernel-model-host-adapter.js.map +1 -0
- package/dist/src/selfhost/legacy-adapter.d.ts +8 -0
- package/dist/src/selfhost/legacy-adapter.d.ts.map +1 -0
- package/dist/src/selfhost/legacy-adapter.js +186 -0
- package/dist/src/selfhost/legacy-adapter.js.map +1 -0
- package/dist/src/selfhost/module-graph.d.ts +57 -0
- package/dist/src/selfhost/module-graph.d.ts.map +1 -0
- package/dist/src/selfhost/module-graph.js +267 -0
- package/dist/src/selfhost/module-graph.js.map +1 -0
- package/dist/src/selfhost/mvp-adapter.d.ts +19 -0
- package/dist/src/selfhost/mvp-adapter.d.ts.map +1 -0
- package/dist/src/selfhost/mvp-adapter.js +186 -0
- package/dist/src/selfhost/mvp-adapter.js.map +1 -0
- package/dist/src/selfhost/node-executor.d.ts +6 -0
- package/dist/src/selfhost/node-executor.d.ts.map +1 -0
- package/dist/src/selfhost/node-executor.js +138 -0
- package/dist/src/selfhost/node-executor.js.map +1 -0
- package/dist/src/selfhost/project-compiler-adapter.d.ts +77 -0
- package/dist/src/selfhost/project-compiler-adapter.d.ts.map +1 -0
- package/dist/src/selfhost/project-compiler-adapter.js +358 -0
- package/dist/src/selfhost/project-compiler-adapter.js.map +1 -0
- package/dist/src/selfhost/project-differential-adapter.d.ts +15 -0
- package/dist/src/selfhost/project-differential-adapter.d.ts.map +1 -0
- package/dist/src/selfhost/project-differential-adapter.js +65 -0
- package/dist/src/selfhost/project-differential-adapter.js.map +1 -0
- package/dist/src/selfhost/promotion-evidence.d.ts +62 -0
- package/dist/src/selfhost/promotion-evidence.d.ts.map +1 -0
- package/dist/src/selfhost/promotion-evidence.js +332 -0
- package/dist/src/selfhost/promotion-evidence.js.map +1 -0
- package/dist/src/selfhost/promotion-policy-replay-v2.d.ts +54 -0
- package/dist/src/selfhost/promotion-policy-replay-v2.d.ts.map +1 -0
- package/dist/src/selfhost/promotion-policy-replay-v2.js +343 -0
- package/dist/src/selfhost/promotion-policy-replay-v2.js.map +1 -0
- package/dist/src/selfhost/promotion-shadow-history-v2.d.ts +55 -0
- package/dist/src/selfhost/promotion-shadow-history-v2.d.ts.map +1 -0
- package/dist/src/selfhost/promotion-shadow-history-v2.js +227 -0
- package/dist/src/selfhost/promotion-shadow-history-v2.js.map +1 -0
- package/dist/src/selfhost/promotion-subject.d.ts +34 -0
- package/dist/src/selfhost/promotion-subject.d.ts.map +1 -0
- package/dist/src/selfhost/promotion-subject.js +141 -0
- package/dist/src/selfhost/promotion-subject.js.map +1 -0
- package/dist/src/selfhost/source-manifest.d.ts +31 -0
- package/dist/src/selfhost/source-manifest.d.ts.map +1 -0
- package/dist/src/selfhost/source-manifest.js +194 -0
- package/dist/src/selfhost/source-manifest.js.map +1 -0
- package/dist/src/selfhost/stage-compiler-facade.d.ts +25 -0
- package/dist/src/selfhost/stage-compiler-facade.d.ts.map +1 -0
- package/dist/src/selfhost/stage-compiler-facade.js +100 -0
- package/dist/src/selfhost/stage-compiler-facade.js.map +1 -0
- package/dist/src/semantic-evidence/snapshot.d.ts +114 -0
- package/dist/src/semantic-evidence/snapshot.d.ts.map +1 -0
- package/dist/src/semantic-evidence/snapshot.js +336 -0
- package/dist/src/semantic-evidence/snapshot.js.map +1 -0
- package/dist/src/source.d.ts +25 -0
- package/dist/src/source.d.ts.map +1 -0
- package/dist/src/source.js +10 -0
- package/dist/src/source.js.map +1 -0
- package/dist/src/syntax/cst-to-ast.d.ts +108 -0
- package/dist/src/syntax/cst-to-ast.d.ts.map +1 -0
- package/dist/src/syntax/cst-to-ast.js +383 -0
- package/dist/src/syntax/cst-to-ast.js.map +1 -0
- package/dist/src/syntax/documentation.d.ts +11 -0
- package/dist/src/syntax/documentation.d.ts.map +1 -0
- package/dist/src/syntax/documentation.js +261 -0
- package/dist/src/syntax/documentation.js.map +1 -0
- package/dist/src/syntax/parser.d.ts +114 -0
- package/dist/src/syntax/parser.d.ts.map +1 -0
- package/dist/src/syntax/parser.js +970 -0
- package/dist/src/syntax/parser.js.map +1 -0
- package/dist/src/syntax/syntax-metadata.d.ts +8 -0
- package/dist/src/syntax/syntax-metadata.d.ts.map +1 -0
- package/dist/src/syntax/syntax-metadata.js +14 -0
- package/dist/src/syntax/syntax-metadata.js.map +1 -0
- package/dist/src/syntax/tokens.d.ts +96 -0
- package/dist/src/syntax/tokens.d.ts.map +1 -0
- package/dist/src/syntax/tokens.js +260 -0
- package/dist/src/syntax/tokens.js.map +1 -0
- package/dist/src/types/types.d.ts +97 -0
- package/dist/src/types/types.d.ts.map +1 -0
- package/dist/src/types/types.js +105 -0
- package/dist/src/types/types.js.map +1 -0
- package/package.json +47 -0
- package/schema/diagnostics-v1.schema.json +75 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { createPromotionShadowHistoryV2, } from './promotion-shadow-history-v2.js';
|
|
2
|
+
export const PROMOTION_POLICY_REPLAY_VERSION = 2;
|
|
3
|
+
const requiredEvidenceFloorByStage = {
|
|
4
|
+
'required-selfhost': [
|
|
5
|
+
'bootstrap-smoke',
|
|
6
|
+
'differential-smoke',
|
|
7
|
+
'format-check',
|
|
8
|
+
'performance-smoke',
|
|
9
|
+
'type-check',
|
|
10
|
+
'unit-tests',
|
|
11
|
+
'binding-corpus',
|
|
12
|
+
'browser-integration',
|
|
13
|
+
'clean-bootstrap',
|
|
14
|
+
'cross-evidence-generation-binding',
|
|
15
|
+
'environment-perturbation',
|
|
16
|
+
'exact-head-evidence-binding',
|
|
17
|
+
'fixed-seed-verification',
|
|
18
|
+
'full-conformance',
|
|
19
|
+
'full-differential',
|
|
20
|
+
'fuzz-regression',
|
|
21
|
+
'independent-runner-reproducibility',
|
|
22
|
+
'legacy-rollback',
|
|
23
|
+
'performance-budget',
|
|
24
|
+
'stage1-stage2-transition',
|
|
25
|
+
'stage2-stage3-fixed-point',
|
|
26
|
+
],
|
|
27
|
+
'required-compiler': [
|
|
28
|
+
'bootstrap-smoke',
|
|
29
|
+
'differential-smoke',
|
|
30
|
+
'format-check',
|
|
31
|
+
'performance-smoke',
|
|
32
|
+
'type-check',
|
|
33
|
+
'unit-tests',
|
|
34
|
+
'binding-corpus',
|
|
35
|
+
'browser-integration',
|
|
36
|
+
'clean-bootstrap',
|
|
37
|
+
'cross-evidence-generation-binding',
|
|
38
|
+
'environment-perturbation',
|
|
39
|
+
'exact-head-evidence-binding',
|
|
40
|
+
'fixed-seed-verification',
|
|
41
|
+
'full-conformance',
|
|
42
|
+
'full-differential',
|
|
43
|
+
'fuzz-regression',
|
|
44
|
+
'independent-runner-reproducibility',
|
|
45
|
+
'legacy-rollback',
|
|
46
|
+
'performance-budget',
|
|
47
|
+
'stage1-stage2-transition',
|
|
48
|
+
'stage2-stage3-fixed-point',
|
|
49
|
+
'compiler-api-compatibility',
|
|
50
|
+
'interop-abi-compatibility',
|
|
51
|
+
'runtime-abi-compatibility',
|
|
52
|
+
],
|
|
53
|
+
'production-default': [
|
|
54
|
+
'bootstrap-smoke',
|
|
55
|
+
'differential-smoke',
|
|
56
|
+
'format-check',
|
|
57
|
+
'performance-smoke',
|
|
58
|
+
'type-check',
|
|
59
|
+
'unit-tests',
|
|
60
|
+
'binding-corpus',
|
|
61
|
+
'browser-integration',
|
|
62
|
+
'clean-bootstrap',
|
|
63
|
+
'cross-evidence-generation-binding',
|
|
64
|
+
'environment-perturbation',
|
|
65
|
+
'exact-head-evidence-binding',
|
|
66
|
+
'fixed-seed-verification',
|
|
67
|
+
'full-conformance',
|
|
68
|
+
'full-differential',
|
|
69
|
+
'fuzz-regression',
|
|
70
|
+
'independent-runner-reproducibility',
|
|
71
|
+
'legacy-rollback',
|
|
72
|
+
'performance-budget',
|
|
73
|
+
'stage1-stage2-transition',
|
|
74
|
+
'stage2-stage3-fixed-point',
|
|
75
|
+
'compiler-api-compatibility',
|
|
76
|
+
'interop-abi-compatibility',
|
|
77
|
+
'runtime-abi-compatibility',
|
|
78
|
+
'release-reproducibility',
|
|
79
|
+
'stable-release-cycle',
|
|
80
|
+
],
|
|
81
|
+
};
|
|
82
|
+
const promotionRequirementFloorByStage = {
|
|
83
|
+
'required-selfhost': {
|
|
84
|
+
minimumConsecutiveSuccessfulRuns: 14,
|
|
85
|
+
minimumObservationDays: 14,
|
|
86
|
+
rollbackEvidenceRequired: false,
|
|
87
|
+
minimumStableReleaseCycles: 0,
|
|
88
|
+
},
|
|
89
|
+
'required-compiler': {
|
|
90
|
+
minimumConsecutiveSuccessfulRuns: 28,
|
|
91
|
+
minimumObservationDays: 28,
|
|
92
|
+
rollbackEvidenceRequired: false,
|
|
93
|
+
minimumStableReleaseCycles: 0,
|
|
94
|
+
},
|
|
95
|
+
'production-default': {
|
|
96
|
+
minimumConsecutiveSuccessfulRuns: 30,
|
|
97
|
+
minimumObservationDays: 30,
|
|
98
|
+
rollbackEvidenceRequired: true,
|
|
99
|
+
minimumStableReleaseCycles: 1,
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
export class PromotionPolicyReplayError extends Error {
|
|
103
|
+
path;
|
|
104
|
+
name = 'PromotionPolicyReplayError';
|
|
105
|
+
constructor(path, message) {
|
|
106
|
+
super(`${path}: ${message}`);
|
|
107
|
+
this.path = path;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export function evaluatePromotionObservationSourceV2(sourceValue, trustedValue) {
|
|
111
|
+
const source = parseSource(sourceValue, '$.source');
|
|
112
|
+
const trusted = parseTrustedSource(trustedValue, '$.trusted');
|
|
113
|
+
const reasons = [];
|
|
114
|
+
if (source.repository !== trusted.repository)
|
|
115
|
+
reasons.push('repository-mismatch');
|
|
116
|
+
if (source.workflow !== trusted.workflow)
|
|
117
|
+
reasons.push('workflow-mismatch');
|
|
118
|
+
if (source.ref !== trusted.ref)
|
|
119
|
+
reasons.push('ref-mismatch');
|
|
120
|
+
if (source.eventName !== trusted.eventName)
|
|
121
|
+
reasons.push('event-mismatch');
|
|
122
|
+
if (source.fork)
|
|
123
|
+
reasons.push('fork-source');
|
|
124
|
+
return { countable: reasons.length === 0, reasons };
|
|
125
|
+
}
|
|
126
|
+
export function replayPromotionHistoryAgainstPolicyV2(policyValue, stage, historyValue) {
|
|
127
|
+
const policyStage = parsePolicyStage(policyValue, stage);
|
|
128
|
+
const canonicalHistory = createPromotionShadowHistoryV2(historyValue).history;
|
|
129
|
+
if (canonicalHistory.stage !== stage) {
|
|
130
|
+
throw new PromotionPolicyReplayError('history.stage', `expected ${stage}, received ${canonicalHistory.stage}`);
|
|
131
|
+
}
|
|
132
|
+
const currentSubjectId = canonicalHistory.promotionSubjectId;
|
|
133
|
+
const formalEntries = canonicalHistory.entries.filter(entry => entry.countsTowardPromotion);
|
|
134
|
+
const currentSegment = formalEntries.length === 0
|
|
135
|
+
? []
|
|
136
|
+
: trailingSubjectSegment(formalEntries, currentSubjectId);
|
|
137
|
+
const excludedRuns = [];
|
|
138
|
+
const disposition = currentSegment.map(entry => {
|
|
139
|
+
const evidence = new Map(entry.evidence.map(item => [item.id, item.status]));
|
|
140
|
+
const missingEvidence = policyStage.requiredEvidence.filter(id => !evidence.has(id));
|
|
141
|
+
const failedEvidence = policyStage.requiredEvidence.filter(id => evidence.get(id) === 'failed');
|
|
142
|
+
const evidenceQualifies = missingEvidence.length === 0 && failedEvidence.length === 0;
|
|
143
|
+
if (entry.countsTowardPromotion && entry.outcome === 'passed' && !evidenceQualifies) {
|
|
144
|
+
const reasons = [];
|
|
145
|
+
if (missingEvidence.length > 0)
|
|
146
|
+
reasons.push('missing-current-required-evidence');
|
|
147
|
+
if (failedEvidence.length > 0)
|
|
148
|
+
reasons.push('failed-current-required-evidence');
|
|
149
|
+
excludedRuns.push({ runId: entry.runId, missingEvidence, failedEvidence, reasons });
|
|
150
|
+
}
|
|
151
|
+
return { entry, evidenceQualifies };
|
|
152
|
+
});
|
|
153
|
+
const successful = canonicalHistory.productInvalidated ? [] : trailingPolicySuccesses(disposition);
|
|
154
|
+
const qualifyingRunIds = successful.map(item => item.entry.runId);
|
|
155
|
+
const successfulRuns = successful.length;
|
|
156
|
+
const observationDays = new Set(successful.map(item => item.entry.completedAt.slice(0, 10))).size;
|
|
157
|
+
const firstSuccessfulAt = successful[0]?.entry.completedAt ?? null;
|
|
158
|
+
const productInvalidated = canonicalHistory.productInvalidated;
|
|
159
|
+
const unexplainedDifferentials = canonicalHistory.unexplainedDifferentials;
|
|
160
|
+
const historyThresholdsSatisfied = !productInvalidated
|
|
161
|
+
&& successfulRuns >= policyStage.minimumConsecutiveSuccessfulRuns
|
|
162
|
+
&& observationDays >= policyStage.minimumObservationDays
|
|
163
|
+
&& unexplainedDifferentials <= policyStage.maximumUnexplainedDifferentials;
|
|
164
|
+
return {
|
|
165
|
+
version: PROMOTION_POLICY_REPLAY_VERSION,
|
|
166
|
+
stage,
|
|
167
|
+
promotionSubjectId: currentSubjectId,
|
|
168
|
+
requiredEvidence: policyStage.requiredEvidence,
|
|
169
|
+
successfulRuns,
|
|
170
|
+
observationDays,
|
|
171
|
+
firstSuccessfulAt,
|
|
172
|
+
productInvalidated,
|
|
173
|
+
unexplainedDifferentials,
|
|
174
|
+
minimumConsecutiveSuccessfulRuns: policyStage.minimumConsecutiveSuccessfulRuns,
|
|
175
|
+
minimumObservationDays: policyStage.minimumObservationDays,
|
|
176
|
+
maximumUnexplainedDifferentials: policyStage.maximumUnexplainedDifferentials,
|
|
177
|
+
manualApprovalRequired: policyStage.manualApprovalRequired,
|
|
178
|
+
rollbackEvidenceRequired: policyStage.rollbackEvidenceRequired,
|
|
179
|
+
minimumStableReleaseCycles: policyStage.minimumStableReleaseCycles,
|
|
180
|
+
historyThresholdsSatisfied,
|
|
181
|
+
qualifyingRunIds,
|
|
182
|
+
excludedRuns,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function trailingSubjectSegment(entries, promotionSubjectId) {
|
|
186
|
+
let first = entries.length - 1;
|
|
187
|
+
for (let index = entries.length - 2; index >= 0; index -= 1) {
|
|
188
|
+
if (entries[index].promotionSubjectId !== promotionSubjectId)
|
|
189
|
+
break;
|
|
190
|
+
first = index;
|
|
191
|
+
}
|
|
192
|
+
return entries.slice(first);
|
|
193
|
+
}
|
|
194
|
+
function trailingPolicySuccesses(entries) {
|
|
195
|
+
const formal = entries.filter(item => item.entry.countsTowardPromotion);
|
|
196
|
+
if (formal.length === 0)
|
|
197
|
+
return [];
|
|
198
|
+
let first = formal.length;
|
|
199
|
+
for (let index = formal.length - 1; index >= 0; index -= 1) {
|
|
200
|
+
const item = formal[index];
|
|
201
|
+
if (item.entry.outcome !== 'passed' || !item.evidenceQualifies)
|
|
202
|
+
break;
|
|
203
|
+
first = index;
|
|
204
|
+
}
|
|
205
|
+
return formal.slice(first);
|
|
206
|
+
}
|
|
207
|
+
function parsePolicyStage(value, stageId) {
|
|
208
|
+
const policy = record(value, 'policy');
|
|
209
|
+
exactKeys(policy, ['schemaVersion', 'automaticPromotionAllowed', 'stages'], 'policy');
|
|
210
|
+
if (policy.schemaVersion !== 1)
|
|
211
|
+
throw new PromotionPolicyReplayError('policy.schemaVersion', 'expected 1');
|
|
212
|
+
if (policy.automaticPromotionAllowed !== false) {
|
|
213
|
+
throw new PromotionPolicyReplayError('policy.automaticPromotionAllowed', 'automatic promotion must remain disabled');
|
|
214
|
+
}
|
|
215
|
+
const stages = array(policy.stages, 'policy.stages');
|
|
216
|
+
const matches = stages.filter(item => recordOrNull(item)?.id === stageId);
|
|
217
|
+
if (matches.length !== 1)
|
|
218
|
+
throw new PromotionPolicyReplayError('policy.stages', `expected exactly one ${stageId} stage`);
|
|
219
|
+
const stagePath = `policy.stage.${stageId}`;
|
|
220
|
+
const stage = record(matches[0], stagePath);
|
|
221
|
+
exactKeys(stage, ['id', 'blocking', 'scope', 'productionDefault', 'requiredEvidence', 'promotionRequirements'], stagePath);
|
|
222
|
+
const expectedScope = stageId === 'required-selfhost' ? 'selfhost-related' : stageId === 'required-compiler' ? 'compiler-changes' : 'production';
|
|
223
|
+
if (stage.blocking !== true || stage.scope !== expectedScope || stage.productionDefault !== (stageId === 'production-default')) {
|
|
224
|
+
throw new PromotionPolicyReplayError(stagePath, 'stage blocking/scope/productionDefault contract is invalid');
|
|
225
|
+
}
|
|
226
|
+
const requiredEvidence = uniqueStrings(stage.requiredEvidence, `${stagePath}.requiredEvidence`).sort(compareText);
|
|
227
|
+
const missingEvidenceFloor = requiredEvidenceFloorByStage[stageId].filter(id => !requiredEvidence.includes(id));
|
|
228
|
+
if (missingEvidenceFloor.length > 0) {
|
|
229
|
+
throw new PromotionPolicyReplayError(`${stagePath}.requiredEvidence`, `required evidence is below the canonical safety floor: ${missingEvidenceFloor.join(', ')}`);
|
|
230
|
+
}
|
|
231
|
+
const requirementsPath = `${stagePath}.promotionRequirements`;
|
|
232
|
+
const requirements = record(stage.promotionRequirements, requirementsPath);
|
|
233
|
+
exactKeys(requirements, [
|
|
234
|
+
'minimumConsecutiveSuccessfulRuns',
|
|
235
|
+
'minimumObservationDays',
|
|
236
|
+
'maximumUnexplainedDifferentials',
|
|
237
|
+
'manualApprovalRequired',
|
|
238
|
+
'rollbackEvidenceRequired',
|
|
239
|
+
'minimumStableReleaseCycles',
|
|
240
|
+
], requirementsPath);
|
|
241
|
+
const minimumConsecutiveSuccessfulRuns = nonNegativeInteger(requirements.minimumConsecutiveSuccessfulRuns, 'minimumConsecutiveSuccessfulRuns');
|
|
242
|
+
const minimumObservationDays = nonNegativeInteger(requirements.minimumObservationDays, 'minimumObservationDays');
|
|
243
|
+
const maximumUnexplainedDifferentials = nonNegativeInteger(requirements.maximumUnexplainedDifferentials, 'maximumUnexplainedDifferentials');
|
|
244
|
+
const manualApprovalRequired = bool(requirements.manualApprovalRequired, 'manualApprovalRequired');
|
|
245
|
+
const rollbackEvidenceRequired = bool(requirements.rollbackEvidenceRequired, 'rollbackEvidenceRequired');
|
|
246
|
+
const minimumStableReleaseCycles = nonNegativeInteger(requirements.minimumStableReleaseCycles, 'minimumStableReleaseCycles');
|
|
247
|
+
const floor = promotionRequirementFloorByStage[stageId];
|
|
248
|
+
if (minimumConsecutiveSuccessfulRuns < floor.minimumConsecutiveSuccessfulRuns) {
|
|
249
|
+
throw new PromotionPolicyReplayError('minimumConsecutiveSuccessfulRuns', `must be at least ${floor.minimumConsecutiveSuccessfulRuns} for ${stageId}`);
|
|
250
|
+
}
|
|
251
|
+
if (minimumObservationDays < floor.minimumObservationDays) {
|
|
252
|
+
throw new PromotionPolicyReplayError('minimumObservationDays', `must be at least ${floor.minimumObservationDays} for ${stageId}`);
|
|
253
|
+
}
|
|
254
|
+
if (maximumUnexplainedDifferentials !== 0) {
|
|
255
|
+
throw new PromotionPolicyReplayError('maximumUnexplainedDifferentials', 'must remain 0 for blocking promotion stages');
|
|
256
|
+
}
|
|
257
|
+
if (!manualApprovalRequired)
|
|
258
|
+
throw new PromotionPolicyReplayError('manualApprovalRequired', 'blocking promotion stages must require manual approval');
|
|
259
|
+
if (floor.rollbackEvidenceRequired && !rollbackEvidenceRequired) {
|
|
260
|
+
throw new PromotionPolicyReplayError('rollbackEvidenceRequired', `${stageId} must require rollback evidence`);
|
|
261
|
+
}
|
|
262
|
+
if (minimumStableReleaseCycles < floor.minimumStableReleaseCycles) {
|
|
263
|
+
throw new PromotionPolicyReplayError('minimumStableReleaseCycles', `must be at least ${floor.minimumStableReleaseCycles} for ${stageId}`);
|
|
264
|
+
}
|
|
265
|
+
return {
|
|
266
|
+
requiredEvidence,
|
|
267
|
+
minimumConsecutiveSuccessfulRuns,
|
|
268
|
+
minimumObservationDays,
|
|
269
|
+
maximumUnexplainedDifferentials,
|
|
270
|
+
manualApprovalRequired,
|
|
271
|
+
rollbackEvidenceRequired,
|
|
272
|
+
minimumStableReleaseCycles,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function parseSource(value, path) {
|
|
276
|
+
const source = record(value, path);
|
|
277
|
+
exactKeys(source, ['repository', 'workflow', 'ref', 'eventName', 'fork'], path);
|
|
278
|
+
return {
|
|
279
|
+
repository: text(source.repository, `${path}.repository`),
|
|
280
|
+
workflow: text(source.workflow, `${path}.workflow`),
|
|
281
|
+
ref: text(source.ref, `${path}.ref`),
|
|
282
|
+
eventName: text(source.eventName, `${path}.eventName`),
|
|
283
|
+
fork: bool(source.fork, `${path}.fork`),
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
function parseTrustedSource(value, path) {
|
|
287
|
+
const source = record(value, path);
|
|
288
|
+
exactKeys(source, ['repository', 'workflow', 'ref', 'eventName'], path);
|
|
289
|
+
const eventName = text(source.eventName, `${path}.eventName`);
|
|
290
|
+
if (eventName !== 'schedule') {
|
|
291
|
+
throw new PromotionPolicyReplayError(`${path}.eventName`, 'trusted event must be schedule');
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
repository: text(source.repository, `${path}.repository`),
|
|
295
|
+
workflow: text(source.workflow, `${path}.workflow`),
|
|
296
|
+
ref: text(source.ref, `${path}.ref`),
|
|
297
|
+
eventName,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function uniqueStrings(value, path) {
|
|
301
|
+
const values = array(value, path).map((item, index) => text(item, `${path}[${index}]`));
|
|
302
|
+
if (new Set(values).size !== values.length)
|
|
303
|
+
throw new PromotionPolicyReplayError(path, 'duplicate values are not allowed');
|
|
304
|
+
return values;
|
|
305
|
+
}
|
|
306
|
+
function record(value, path) {
|
|
307
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
308
|
+
throw new PromotionPolicyReplayError(path, 'expected object');
|
|
309
|
+
return value;
|
|
310
|
+
}
|
|
311
|
+
function recordOrNull(value) {
|
|
312
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value) ? value : null;
|
|
313
|
+
}
|
|
314
|
+
function array(value, path) {
|
|
315
|
+
if (!Array.isArray(value))
|
|
316
|
+
throw new PromotionPolicyReplayError(path, 'expected array');
|
|
317
|
+
return value;
|
|
318
|
+
}
|
|
319
|
+
function text(value, path) {
|
|
320
|
+
if (typeof value !== 'string' || value.length === 0 || value.trim() !== value)
|
|
321
|
+
throw new PromotionPolicyReplayError(path, 'expected non-empty canonical string');
|
|
322
|
+
return value;
|
|
323
|
+
}
|
|
324
|
+
function bool(value, path) {
|
|
325
|
+
if (typeof value !== 'boolean')
|
|
326
|
+
throw new PromotionPolicyReplayError(path, 'expected boolean');
|
|
327
|
+
return value;
|
|
328
|
+
}
|
|
329
|
+
function nonNegativeInteger(value, path) {
|
|
330
|
+
if (!Number.isSafeInteger(value) || value < 0)
|
|
331
|
+
throw new PromotionPolicyReplayError(path, 'expected non-negative safe integer');
|
|
332
|
+
return value;
|
|
333
|
+
}
|
|
334
|
+
function exactKeys(value, expected, path) {
|
|
335
|
+
const actual = Object.keys(value).sort(compareText);
|
|
336
|
+
const wanted = [...expected].sort(compareText);
|
|
337
|
+
if (JSON.stringify(actual) !== JSON.stringify(wanted))
|
|
338
|
+
throw new PromotionPolicyReplayError(path, `expected exactly keys ${wanted.join(', ')}`);
|
|
339
|
+
}
|
|
340
|
+
function compareText(left, right) {
|
|
341
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=promotion-policy-replay-v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promotion-policy-replay-v2.js","sourceRoot":"","sources":["../../../src/selfhost/promotion-policy-replay-v2.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { PromotionSubjectStage } from './promotion-subject.js';
|
|
2
|
+
export declare const PROMOTION_SHADOW_HISTORY_VERSION: 2;
|
|
3
|
+
export type PromotionObservationOutcome = 'passed' | 'product-failed' | 'infrastructure-failed' | 'cancelled';
|
|
4
|
+
export type PromotionObservationEvidenceStatus = 'passed' | 'failed';
|
|
5
|
+
export interface PromotionObservationEvidenceInputV2 {
|
|
6
|
+
readonly id: string;
|
|
7
|
+
readonly status: PromotionObservationEvidenceStatus;
|
|
8
|
+
readonly sha256: string;
|
|
9
|
+
}
|
|
10
|
+
export interface PromotionShadowHistoryEntryInputV2 {
|
|
11
|
+
readonly version: typeof PROMOTION_SHADOW_HISTORY_VERSION;
|
|
12
|
+
readonly runId: string;
|
|
13
|
+
readonly stage: PromotionSubjectStage;
|
|
14
|
+
readonly executionCommit: string;
|
|
15
|
+
readonly promotionSubjectId: string;
|
|
16
|
+
readonly completedAt: string;
|
|
17
|
+
readonly outcome: PromotionObservationOutcome;
|
|
18
|
+
readonly countsTowardPromotion: boolean;
|
|
19
|
+
readonly unexplainedDifferentials: number;
|
|
20
|
+
readonly evidence: readonly PromotionObservationEvidenceInputV2[];
|
|
21
|
+
}
|
|
22
|
+
export interface PromotionShadowHistoryInputV2 {
|
|
23
|
+
readonly version: typeof PROMOTION_SHADOW_HISTORY_VERSION;
|
|
24
|
+
readonly stage: PromotionSubjectStage;
|
|
25
|
+
readonly entries: readonly PromotionShadowHistoryEntryInputV2[];
|
|
26
|
+
}
|
|
27
|
+
export interface PromotionObservationEvidenceV2 extends PromotionObservationEvidenceInputV2 {
|
|
28
|
+
}
|
|
29
|
+
export interface PromotionShadowHistoryEntryV2 extends Omit<PromotionShadowHistoryEntryInputV2, 'evidence'> {
|
|
30
|
+
readonly evidence: readonly PromotionObservationEvidenceV2[];
|
|
31
|
+
}
|
|
32
|
+
export interface PromotionShadowHistoryV2 {
|
|
33
|
+
readonly version: typeof PROMOTION_SHADOW_HISTORY_VERSION;
|
|
34
|
+
readonly stage: PromotionSubjectStage;
|
|
35
|
+
readonly promotionSubjectId: string;
|
|
36
|
+
readonly successfulRuns: number;
|
|
37
|
+
readonly observationDays: number;
|
|
38
|
+
readonly firstSuccessfulAt: string | null;
|
|
39
|
+
readonly latestCompletedAt: string;
|
|
40
|
+
readonly productInvalidated: boolean;
|
|
41
|
+
readonly unexplainedDifferentials: number;
|
|
42
|
+
readonly entries: readonly PromotionShadowHistoryEntryV2[];
|
|
43
|
+
}
|
|
44
|
+
export interface PromotionShadowHistoryResultV2 {
|
|
45
|
+
readonly history: PromotionShadowHistoryV2;
|
|
46
|
+
readonly serialized: string;
|
|
47
|
+
readonly sha256: string;
|
|
48
|
+
}
|
|
49
|
+
export declare class PromotionShadowHistoryError extends Error {
|
|
50
|
+
readonly path: string;
|
|
51
|
+
readonly name = "PromotionShadowHistoryError";
|
|
52
|
+
constructor(path: string, message: string);
|
|
53
|
+
}
|
|
54
|
+
export declare function createPromotionShadowHistoryV2(value: unknown): PromotionShadowHistoryResultV2;
|
|
55
|
+
//# sourceMappingURL=promotion-shadow-history-v2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promotion-shadow-history-v2.d.ts","sourceRoot":"","sources":["../../../src/selfhost/promotion-shadow-history-v2.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE,eAAO,MAAM,gCAAgC,EAAG,CAAU,CAAC;AAE3D,MAAM,MAAM,2BAA2B,GACpC,QAAQ,GACR,gBAAgB,GAChB,uBAAuB,GACvB,WAAW,CAAC;AAEf,MAAM,MAAM,kCAAkC,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErE,MAAM,WAAW,mCAAmC;IACnD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,kCAAkC,CAAC;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,kCAAkC;IAClD,QAAQ,CAAC,OAAO,EAAE,OAAO,gCAAgC,CAAC;IAC1D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IACtC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,2BAA2B,CAAC;IAC9C,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAC;IACxC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,SAAS,mCAAmC,EAAE,CAAC;CAClE;AAED,MAAM,WAAW,6BAA6B;IAC7C,QAAQ,CAAC,OAAO,EAAE,OAAO,gCAAgC,CAAC;IAC1D,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS,kCAAkC,EAAE,CAAC;CAChE;AAED,MAAM,WAAW,8BAA+B,SAAQ,mCAAmC;CAAG;AAE9F,MAAM,WAAW,6BAA8B,SAAQ,IAAI,CAAC,kCAAkC,EAAE,UAAU,CAAC;IAC1G,QAAQ,CAAC,QAAQ,EAAE,SAAS,8BAA8B,EAAE,CAAC;CAC7D;AAED,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,OAAO,EAAE,OAAO,gCAAgC,CAAC;IAC1D,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IACtC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,SAAS,6BAA6B,EAAE,CAAC;CAC3D;AAED,MAAM,WAAW,8BAA8B;IAC9C,QAAQ,CAAC,OAAO,EAAE,wBAAwB,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,2BAA4B,SAAQ,KAAK;aAElB,IAAI,EAAE,MAAM;IAD/C,SAAyB,IAAI,iCAAiC;gBAC3B,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAGhE;AAMD,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,8BAA8B,CA8C7F"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
export const PROMOTION_SHADOW_HISTORY_VERSION = 2;
|
|
3
|
+
export class PromotionShadowHistoryError extends Error {
|
|
4
|
+
path;
|
|
5
|
+
name = 'PromotionShadowHistoryError';
|
|
6
|
+
constructor(path, message) {
|
|
7
|
+
super(`${path}: ${message}`);
|
|
8
|
+
this.path = path;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const gitShaPattern = /^[0-9a-f]{40}$/u;
|
|
12
|
+
const sha256Pattern = /^[0-9a-f]{64}$/u;
|
|
13
|
+
const timestampPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/u;
|
|
14
|
+
export function createPromotionShadowHistoryV2(value) {
|
|
15
|
+
const input = record(value, '$');
|
|
16
|
+
exactKeys(input, ['version', 'stage', 'entries'], '$');
|
|
17
|
+
literal(input.version, PROMOTION_SHADOW_HISTORY_VERSION, '$.version');
|
|
18
|
+
const stage = promotionStage(input.stage, '$.stage');
|
|
19
|
+
const entryValues = array(input.entries, '$.entries');
|
|
20
|
+
if (entryValues.length === 0)
|
|
21
|
+
throw new PromotionShadowHistoryError('$.entries', 'at least one observation is required');
|
|
22
|
+
const seenRunIds = new Set();
|
|
23
|
+
const entries = entryValues.map((entry, index) => parseEntry(entry, index, stage, seenRunIds));
|
|
24
|
+
for (let index = 1; index < entries.length; index += 1) {
|
|
25
|
+
if (compareEntryOrder(entries[index - 1], entries[index]) >= 0) {
|
|
26
|
+
throw new PromotionShadowHistoryError(`$.entries[${index}]`, 'entries must be strictly ordered by completedAt and runId');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const latest = entries.at(-1);
|
|
30
|
+
const countingEntries = entries.filter(entry => entry.countsTowardPromotion);
|
|
31
|
+
const currentSubjectId = countingEntries.at(-1)?.promotionSubjectId ?? latest.promotionSubjectId;
|
|
32
|
+
const currentSegment = countingEntries.length === 0
|
|
33
|
+
? []
|
|
34
|
+
: trailingSubjectSegment(countingEntries, currentSubjectId);
|
|
35
|
+
const countingCurrentSubjectEntries = countingEntries.filter(entry => entry.promotionSubjectId === currentSubjectId);
|
|
36
|
+
const productInvalidated = countingCurrentSubjectEntries.some(entry => entry.outcome === 'product-failed');
|
|
37
|
+
const unexplainedDifferentials = countingCurrentSubjectEntries.reduce((total, entry) => {
|
|
38
|
+
const next = total + entry.unexplainedDifferentials;
|
|
39
|
+
if (!Number.isSafeInteger(next)) {
|
|
40
|
+
throw new PromotionShadowHistoryError('$.entries', 'aggregate unexplained differentials exceed safe integer range');
|
|
41
|
+
}
|
|
42
|
+
return next;
|
|
43
|
+
}, 0);
|
|
44
|
+
const trailingSuccessful = productInvalidated ? [] : trailingCountingSuccesses(currentSegment);
|
|
45
|
+
const history = {
|
|
46
|
+
version: PROMOTION_SHADOW_HISTORY_VERSION,
|
|
47
|
+
stage,
|
|
48
|
+
promotionSubjectId: currentSubjectId,
|
|
49
|
+
successfulRuns: trailingSuccessful.length,
|
|
50
|
+
observationDays: distinctUtcDays(trailingSuccessful),
|
|
51
|
+
firstSuccessfulAt: trailingSuccessful[0]?.completedAt ?? null,
|
|
52
|
+
latestCompletedAt: latest.completedAt,
|
|
53
|
+
productInvalidated,
|
|
54
|
+
unexplainedDifferentials,
|
|
55
|
+
entries,
|
|
56
|
+
};
|
|
57
|
+
const serialized = JSON.stringify(history);
|
|
58
|
+
return { history, serialized, sha256: sha256(serialized) };
|
|
59
|
+
}
|
|
60
|
+
function parseEntry(value, index, expectedStage, seenRunIds) {
|
|
61
|
+
const path = `$.entries[${index}]`;
|
|
62
|
+
const entry = record(value, path);
|
|
63
|
+
exactKeys(entry, [
|
|
64
|
+
'version', 'runId', 'stage', 'executionCommit', 'promotionSubjectId', 'completedAt',
|
|
65
|
+
'outcome', 'countsTowardPromotion', 'unexplainedDifferentials', 'evidence',
|
|
66
|
+
], path);
|
|
67
|
+
literal(entry.version, PROMOTION_SHADOW_HISTORY_VERSION, `${path}.version`);
|
|
68
|
+
const runId = nonEmptyString(entry.runId, `${path}.runId`);
|
|
69
|
+
if (seenRunIds.has(runId))
|
|
70
|
+
throw new PromotionShadowHistoryError(`${path}.runId`, `duplicate runId ${runId}`);
|
|
71
|
+
seenRunIds.add(runId);
|
|
72
|
+
const stage = promotionStage(entry.stage, `${path}.stage`);
|
|
73
|
+
if (stage !== expectedStage)
|
|
74
|
+
throw new PromotionShadowHistoryError(`${path}.stage`, `expected ${expectedStage}, received ${stage}`);
|
|
75
|
+
const executionCommit = canonicalGitSha(entry.executionCommit, `${path}.executionCommit`);
|
|
76
|
+
const promotionSubjectId = canonicalSha256(entry.promotionSubjectId, `${path}.promotionSubjectId`);
|
|
77
|
+
const completedAt = canonicalTimestamp(entry.completedAt, `${path}.completedAt`);
|
|
78
|
+
const outcome = observationOutcome(entry.outcome, `${path}.outcome`);
|
|
79
|
+
const countsTowardPromotion = boolean(entry.countsTowardPromotion, `${path}.countsTowardPromotion`);
|
|
80
|
+
const unexplainedDifferentials = nonNegativeSafeInteger(entry.unexplainedDifferentials, `${path}.unexplainedDifferentials`);
|
|
81
|
+
if (outcome !== 'product-failed' && unexplainedDifferentials !== 0) {
|
|
82
|
+
throw new PromotionShadowHistoryError(`${path}.unexplainedDifferentials`, 'only product-failed observations may have unexplained differentials');
|
|
83
|
+
}
|
|
84
|
+
const evidence = parseEvidence(entry.evidence, `${path}.evidence`);
|
|
85
|
+
if (outcome === 'passed' && evidence.some(item => item.status !== 'passed')) {
|
|
86
|
+
throw new PromotionShadowHistoryError(`${path}.evidence`, 'passed observations cannot contain failed evidence');
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
version: PROMOTION_SHADOW_HISTORY_VERSION,
|
|
90
|
+
runId,
|
|
91
|
+
stage,
|
|
92
|
+
executionCommit,
|
|
93
|
+
promotionSubjectId,
|
|
94
|
+
completedAt,
|
|
95
|
+
outcome,
|
|
96
|
+
countsTowardPromotion,
|
|
97
|
+
unexplainedDifferentials,
|
|
98
|
+
evidence,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function parseEvidence(value, path) {
|
|
102
|
+
const values = array(value, path);
|
|
103
|
+
if (values.length === 0)
|
|
104
|
+
throw new PromotionShadowHistoryError(path, 'at least one evidence item is required');
|
|
105
|
+
const seen = new Set();
|
|
106
|
+
const evidence = values.map((item, index) => {
|
|
107
|
+
const itemPath = `${path}[${index}]`;
|
|
108
|
+
const recordValue = record(item, itemPath);
|
|
109
|
+
exactKeys(recordValue, ['id', 'status', 'sha256'], itemPath);
|
|
110
|
+
const id = nonEmptyString(recordValue.id, `${itemPath}.id`);
|
|
111
|
+
if (seen.has(id))
|
|
112
|
+
throw new PromotionShadowHistoryError(`${itemPath}.id`, `duplicate evidence id ${id}`);
|
|
113
|
+
seen.add(id);
|
|
114
|
+
const status = evidenceStatus(recordValue.status, `${itemPath}.status`);
|
|
115
|
+
const itemSha256 = canonicalSha256(recordValue.sha256, `${itemPath}.sha256`);
|
|
116
|
+
return { id, status, sha256: itemSha256 };
|
|
117
|
+
}).sort((left, right) => compareText(left.id, right.id));
|
|
118
|
+
return evidence;
|
|
119
|
+
}
|
|
120
|
+
function trailingSubjectSegment(entries, promotionSubjectId) {
|
|
121
|
+
let first = entries.length - 1;
|
|
122
|
+
for (let index = entries.length - 2; index >= 0; index -= 1) {
|
|
123
|
+
if (entries[index].promotionSubjectId !== promotionSubjectId)
|
|
124
|
+
break;
|
|
125
|
+
first = index;
|
|
126
|
+
}
|
|
127
|
+
return entries.slice(first);
|
|
128
|
+
}
|
|
129
|
+
function trailingCountingSuccesses(entries) {
|
|
130
|
+
const counting = entries.filter(entry => entry.countsTowardPromotion);
|
|
131
|
+
if (counting.length === 0 || counting.at(-1).outcome !== 'passed')
|
|
132
|
+
return [];
|
|
133
|
+
let first = counting.length - 1;
|
|
134
|
+
for (let index = counting.length - 2; index >= 0; index -= 1) {
|
|
135
|
+
if (counting[index].outcome !== 'passed')
|
|
136
|
+
break;
|
|
137
|
+
first = index;
|
|
138
|
+
}
|
|
139
|
+
return counting.slice(first);
|
|
140
|
+
}
|
|
141
|
+
function distinctUtcDays(entries) {
|
|
142
|
+
return new Set(entries.map(entry => entry.completedAt.slice(0, 10))).size;
|
|
143
|
+
}
|
|
144
|
+
function promotionStage(value, path) {
|
|
145
|
+
if (value === 'required-selfhost' || value === 'required-compiler' || value === 'production-default')
|
|
146
|
+
return value;
|
|
147
|
+
throw new PromotionShadowHistoryError(path, 'invalid promotion stage');
|
|
148
|
+
}
|
|
149
|
+
function observationOutcome(value, path) {
|
|
150
|
+
if (value === 'passed' || value === 'product-failed' || value === 'infrastructure-failed' || value === 'cancelled')
|
|
151
|
+
return value;
|
|
152
|
+
throw new PromotionShadowHistoryError(path, 'invalid observation outcome');
|
|
153
|
+
}
|
|
154
|
+
function evidenceStatus(value, path) {
|
|
155
|
+
if (value === 'passed' || value === 'failed')
|
|
156
|
+
return value;
|
|
157
|
+
throw new PromotionShadowHistoryError(path, 'invalid evidence status');
|
|
158
|
+
}
|
|
159
|
+
function canonicalTimestamp(value, path) {
|
|
160
|
+
if (typeof value !== 'string' || !timestampPattern.test(value)) {
|
|
161
|
+
throw new PromotionShadowHistoryError(path, 'expected canonical UTC ISO timestamp');
|
|
162
|
+
}
|
|
163
|
+
const parsed = new Date(value);
|
|
164
|
+
if (Number.isNaN(parsed.getTime()) || parsed.toISOString() !== value) {
|
|
165
|
+
throw new PromotionShadowHistoryError(path, 'expected canonical UTC ISO timestamp');
|
|
166
|
+
}
|
|
167
|
+
return value;
|
|
168
|
+
}
|
|
169
|
+
function canonicalGitSha(value, path) {
|
|
170
|
+
if (typeof value !== 'string' || !gitShaPattern.test(value)) {
|
|
171
|
+
throw new PromotionShadowHistoryError(path, 'expected lowercase 40-character Git SHA');
|
|
172
|
+
}
|
|
173
|
+
return value;
|
|
174
|
+
}
|
|
175
|
+
function canonicalSha256(value, path) {
|
|
176
|
+
if (typeof value !== 'string' || !sha256Pattern.test(value)) {
|
|
177
|
+
throw new PromotionShadowHistoryError(path, 'expected lowercase 64-character SHA-256');
|
|
178
|
+
}
|
|
179
|
+
return value;
|
|
180
|
+
}
|
|
181
|
+
function nonNegativeSafeInteger(value, path) {
|
|
182
|
+
if (!Number.isSafeInteger(value) || value < 0)
|
|
183
|
+
throw new PromotionShadowHistoryError(path, 'expected a non-negative safe integer');
|
|
184
|
+
return value;
|
|
185
|
+
}
|
|
186
|
+
function boolean(value, path) {
|
|
187
|
+
if (typeof value !== 'boolean')
|
|
188
|
+
throw new PromotionShadowHistoryError(path, 'expected a boolean');
|
|
189
|
+
return value;
|
|
190
|
+
}
|
|
191
|
+
function literal(value, expected, path) {
|
|
192
|
+
if (value !== expected)
|
|
193
|
+
throw new PromotionShadowHistoryError(path, `expected ${expected}`);
|
|
194
|
+
}
|
|
195
|
+
function record(value, path) {
|
|
196
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
197
|
+
throw new PromotionShadowHistoryError(path, 'expected an object');
|
|
198
|
+
return value;
|
|
199
|
+
}
|
|
200
|
+
function array(value, path) {
|
|
201
|
+
if (!Array.isArray(value))
|
|
202
|
+
throw new PromotionShadowHistoryError(path, 'expected an array');
|
|
203
|
+
return value;
|
|
204
|
+
}
|
|
205
|
+
function nonEmptyString(value, path) {
|
|
206
|
+
if (typeof value !== 'string' || value.length === 0 || value.trim() !== value) {
|
|
207
|
+
throw new PromotionShadowHistoryError(path, 'expected a non-empty canonical string');
|
|
208
|
+
}
|
|
209
|
+
return value;
|
|
210
|
+
}
|
|
211
|
+
function exactKeys(value, expected, path) {
|
|
212
|
+
const actual = Object.keys(value).sort(compareText);
|
|
213
|
+
const wanted = [...expected].sort(compareText);
|
|
214
|
+
if (JSON.stringify(actual) !== JSON.stringify(wanted)) {
|
|
215
|
+
throw new PromotionShadowHistoryError(path, `expected exactly keys ${wanted.join(', ')}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function compareEntryOrder(left, right) {
|
|
219
|
+
return compareText(left.completedAt, right.completedAt) || compareText(left.runId, right.runId);
|
|
220
|
+
}
|
|
221
|
+
function sha256(value) {
|
|
222
|
+
return createHash('sha256').update(value, 'utf8').digest('hex');
|
|
223
|
+
}
|
|
224
|
+
function compareText(left, right) {
|
|
225
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=promotion-shadow-history-v2.js.map
|