@usefragments/core 1.10.2 → 2.0.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/dist/{chunk-MZ4SW3TP.js → chunk-3IOWHECM.js} +8 -1
- package/dist/{chunk-MZ4SW3TP.js.map → chunk-3IOWHECM.js.map} +1 -1
- package/dist/chunk-7ULGH74M.js +66 -0
- package/dist/chunk-7ULGH74M.js.map +1 -0
- package/dist/{chunk-XN3LSDPY.js → chunk-BMPYIUZE.js} +612 -344
- package/dist/chunk-BMPYIUZE.js.map +1 -0
- package/dist/{chunk-YF65VYRY.js → chunk-ML5S6QNU.js} +191 -169
- package/dist/chunk-ML5S6QNU.js.map +1 -0
- package/dist/{chunk-3LLRNCPX.js → chunk-MZ2FS7U4.js} +1 -1
- package/dist/chunk-MZ2FS7U4.js.map +1 -0
- package/dist/chunk-PWIJMOI4.js +202 -0
- package/dist/chunk-PWIJMOI4.js.map +1 -0
- package/dist/chunk-RYFULE43.js +578 -0
- package/dist/chunk-RYFULE43.js.map +1 -0
- package/dist/codes/index.d.ts +2 -2
- package/dist/codes/index.js +3 -2
- package/dist/compiled-types/index.d.ts +327 -2
- package/dist/compiled-types/index.js +1 -1
- package/dist/generate/index.d.ts +3 -2
- package/dist/{governance-CLk_wkP9.d.ts → governance-hOPXGbbs.d.ts} +474 -515
- package/dist/governance-telemetry.d.ts +6 -0
- package/dist/governance-telemetry.js +1 -1
- package/dist/{index-_sxhUNqx.d.ts → index-C8bcXVav.d.ts} +448 -448
- package/dist/index.d.ts +3280 -1305
- package/dist/index.js +2414 -350
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +228 -0
- package/dist/manifest.js +24 -0
- package/dist/manifest.js.map +1 -0
- package/dist/preview/index.js +45 -1
- package/dist/preview/index.js.map +1 -1
- package/dist/preview-runtime.d.ts +1 -2
- package/dist/preview-runtime.js +150 -14
- package/dist/preview-runtime.js.map +1 -1
- package/dist/react-types.d.ts +1 -2
- package/dist/registry.d.ts +1412 -203
- package/dist/registry.js +30 -3
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.js +3 -2
- package/dist/storyAdapter.d.ts +1 -2
- package/dist/storyAdapter.js +11 -49
- package/dist/storyAdapter.js.map +1 -1
- package/dist/test-utils.d.ts +3 -2
- package/dist/topology/index.d.ts +1 -1
- package/dist/topology/index.js +1 -1
- package/package.json +8 -2
- package/src/__tests__/contract-parser.test.ts +318 -277
- package/src/__tests__/preview-runtime-hook.test.tsx +315 -0
- package/src/__tests__/preview-runtime.test.tsx +30 -8
- package/src/__tests__/schema.test.ts +191 -14
- package/src/analysis-plan/analysis-plan-v1.test.ts +320 -0
- package/src/analysis-plan/coverage.ts +181 -0
- package/src/analysis-plan/digest.ts +141 -0
- package/src/analysis-plan/index.ts +34 -0
- package/src/analysis-plan/types.ts +207 -0
- package/src/approved-contract-tokens.test.ts +39 -0
- package/src/approved-contract-tokens.ts +18 -0
- package/src/codes/__tests__/codes.test.ts +13 -0
- package/src/codes/codes.ts +40 -0
- package/src/compiled-types/index.ts +640 -39
- package/src/compiled-types/parse.test.ts +145 -4
- package/src/component-contract.ts +95 -53
- package/src/composition.ts +7 -13
- package/src/constants.ts +3 -6
- package/src/contract/hash.test.ts +20 -0
- package/src/contract/hash.ts +66 -9
- package/src/contract/index.ts +24 -1
- package/src/contract/manifest.test.ts +94 -0
- package/src/contract/manifest.ts +68 -0
- package/src/contract/preimage.test.ts +219 -1
- package/src/contract/preimage.ts +326 -6
- package/src/contract/stamp.test.ts +3 -0
- package/src/contract/stamp.ts +1 -1
- package/src/contract-parser.ts +54 -30
- package/src/defineFragment.test.ts +476 -91
- package/src/defineFragment.ts +204 -114
- package/src/domain-ids.test.ts +35 -0
- package/src/domain-ids.ts +61 -0
- package/src/evaluation/evaluate.test.ts +522 -0
- package/src/evaluation/evaluate.ts +690 -0
- package/src/evaluation/evaluation-v2-receipt-v1.test.ts +772 -0
- package/src/evaluation/index.ts +58 -0
- package/src/evaluation/receipt.ts +753 -0
- package/src/evaluation/types.ts +406 -0
- package/src/facts/builders.ts +2 -0
- package/src/facts/compile.ts +29 -6
- package/src/facts/fact-index.ts +13 -3
- package/src/facts/fact-integrity-v1.test.ts +172 -0
- package/src/facts/facts.test.ts +15 -0
- package/src/facts/ids.ts +46 -3
- package/src/facts/index.ts +14 -1
- package/src/facts/integrity.ts +134 -0
- package/src/facts/types.ts +36 -0
- package/src/governance-integrity.test.ts +1 -0
- package/src/governance-integrity.ts +5 -3
- package/src/governance-telemetry.ts +8 -0
- package/src/governance.ts +70 -8
- package/src/index.ts +230 -37
- package/src/preview/validation.test.ts +62 -0
- package/src/preview/validation.ts +48 -2
- package/src/preview-runtime.tsx +227 -20
- package/src/registry-install-plan.ts +200 -109
- package/src/registry-shards.test.ts +263 -0
- package/src/registry.ts +237 -0
- package/src/repository-binding.test.ts +50 -0
- package/src/repository-binding.ts +96 -0
- package/src/rules/families.test.ts +36 -0
- package/src/rules/finding.ts +7 -2
- package/src/rules/index.ts +17 -1
- package/src/rules/rule-config.test.ts +66 -0
- package/src/rules/rule-config.ts +73 -0
- package/src/rules/rules.test.ts +26 -0
- package/src/rules/tokens-css-vars-must-be-defined.test.ts +51 -2
- package/src/rules/tokens-css-vars-must-be-defined.ts +34 -1
- package/src/schema.ts +293 -113
- package/src/schemas/index.ts +1 -1
- package/src/storyAdapter.test.ts +68 -12
- package/src/storyAdapter.ts +44 -75
- package/src/topology/resolve-area.ts +1 -1
- package/src/types.ts +258 -40
- package/dist/chunk-3LLRNCPX.js.map +0 -1
- package/dist/chunk-RANPUC6C.js +0 -72
- package/dist/chunk-RANPUC6C.js.map +0 -1
- package/dist/chunk-XN3LSDPY.js.map +0 -1
- package/dist/chunk-YF65VYRY.js.map +0 -1
- package/src/fragment-types.ts +0 -214
- package/src/react-create-element.test.ts +0 -22
- package/src/react-create-element.ts +0 -12
- package/src/storyFilters.test.ts +0 -350
- package/src/storyFilters.ts +0 -253
package/dist/index.js
CHANGED
|
@@ -1,15 +1,80 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FRAGMENTS_MANIFEST_FILENAME,
|
|
3
|
+
FRAGMENTS_MANIFEST_SCHEMA_VERSION,
|
|
4
|
+
FRAGMENTS_MANIFEST_TOKEN_RULE,
|
|
5
|
+
fragmentsManifestFcid,
|
|
6
|
+
fragmentsManifestGrammarSchema,
|
|
7
|
+
fragmentsManifestPatternSchema,
|
|
8
|
+
fragmentsManifestPrimitiveSchema,
|
|
9
|
+
fragmentsManifestSchema,
|
|
10
|
+
parseFragmentsManifest
|
|
11
|
+
} from "./chunk-7ULGH74M.js";
|
|
12
|
+
import {
|
|
13
|
+
REGISTRY_ARTIFACT_SCHEMA_VERSION,
|
|
14
|
+
REGISTRY_INDEX_SCHEMA_VERSION,
|
|
15
|
+
REGISTRY_INSTALL_RECEIPT_SCHEMA_VERSION,
|
|
16
|
+
REGISTRY_MANIFEST_SCHEMA_VERSION,
|
|
17
|
+
REGISTRY_POINTER_SCHEMA_VERSION,
|
|
18
|
+
REGISTRY_SHARD_SCHEMA_VERSION,
|
|
19
|
+
assembleRegistryArtifact,
|
|
20
|
+
assertValidRegistryArtifact,
|
|
21
|
+
buildRegistryArtifact,
|
|
22
|
+
buildRegistryFile,
|
|
23
|
+
buildRegistryPointer,
|
|
24
|
+
computeRegistryHash,
|
|
25
|
+
defaultRegistryShardPath,
|
|
26
|
+
finalizeRegistryManifest,
|
|
27
|
+
hashRegistryFileContent,
|
|
28
|
+
registryArtifactDigest,
|
|
29
|
+
registryArtifactSchema,
|
|
30
|
+
registryComponentExportSchema,
|
|
31
|
+
registryComponentSchema,
|
|
32
|
+
registryDependencySchema,
|
|
33
|
+
registryDependencyTypeSchema,
|
|
34
|
+
registryEntrypointSchema,
|
|
35
|
+
registryFileContentSchema,
|
|
36
|
+
registryFileRoleSchema,
|
|
37
|
+
registryFileSchema,
|
|
38
|
+
registryFileSize,
|
|
39
|
+
registryIndexSchema,
|
|
40
|
+
registryInstallProfileSchema,
|
|
41
|
+
registryInstallReceiptComponentSchema,
|
|
42
|
+
registryInstallReceiptFileSchema,
|
|
43
|
+
registryInstallReceiptSchema,
|
|
44
|
+
registryManifestCanonicalPreimage,
|
|
45
|
+
registryManifestDraftSchema,
|
|
46
|
+
registryManifestFileMetadata,
|
|
47
|
+
registryManifestFilePaths,
|
|
48
|
+
registryManifestSchema,
|
|
49
|
+
registryPointerSchema,
|
|
50
|
+
registryShardSchema,
|
|
51
|
+
registryShardsForPaths,
|
|
52
|
+
registrySourceSchema,
|
|
53
|
+
shardRegistryArtifact
|
|
54
|
+
} from "./chunk-ML5S6QNU.js";
|
|
55
|
+
import {
|
|
56
|
+
GOVERNANCE_TELEMETRY_FIELDS,
|
|
57
|
+
GOVERNANCE_TELEMETRY_SOURCE_DISCLOSURE,
|
|
58
|
+
GOVERNANCE_TELEMETRY_TOP_LEVEL_FIELDS
|
|
59
|
+
} from "./chunk-3IOWHECM.js";
|
|
1
60
|
import {
|
|
2
61
|
CompiledFragmentsFileValidationError,
|
|
3
62
|
parseCompiledFragmentsFile
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import {
|
|
6
|
-
generateContext
|
|
7
|
-
} from "./chunk-X34IA4LR.js";
|
|
63
|
+
} from "./chunk-RYFULE43.js";
|
|
8
64
|
import {
|
|
9
65
|
ComponentGraphEngine
|
|
10
66
|
} from "./chunk-SH4KPIYH.js";
|
|
67
|
+
import {
|
|
68
|
+
resolveArea
|
|
69
|
+
} from "./chunk-MZ2FS7U4.js";
|
|
70
|
+
import {
|
|
71
|
+
generateContext
|
|
72
|
+
} from "./chunk-X34IA4LR.js";
|
|
11
73
|
import {
|
|
12
74
|
AGENT_FORMAT_SCHEMA_VERSION,
|
|
75
|
+
CANONICAL_FACT_MAX_CONFLICTS_V1,
|
|
76
|
+
CANONICAL_FACT_MAX_PROVENANCE_PER_VALUE_V1,
|
|
77
|
+
CANONICAL_FACT_MAX_VALUES_PER_CONFLICT_V1,
|
|
13
78
|
CODES,
|
|
14
79
|
EXPLAIN_URL_BASE,
|
|
15
80
|
FactIndex,
|
|
@@ -19,12 +84,18 @@ import {
|
|
|
19
84
|
agentFormatSchema,
|
|
20
85
|
agentIntegritySchema,
|
|
21
86
|
agentOutputSchema,
|
|
87
|
+
analysisPlanIdFromDigest,
|
|
88
|
+
analysisPlanIdSchema,
|
|
89
|
+
analysisPlanIdStringSchema,
|
|
22
90
|
asComponentId,
|
|
23
91
|
bridgeSourceViolation,
|
|
24
92
|
bridgeSourceViolations,
|
|
25
93
|
byCode,
|
|
26
94
|
byRuleId,
|
|
27
95
|
canonicalBridgeV1Schema,
|
|
96
|
+
canonicalFactConflictV1Schema,
|
|
97
|
+
canonicalFactConflictValueV1Schema,
|
|
98
|
+
canonicalFactIntegrityV1Schema,
|
|
28
99
|
canonicalJson,
|
|
29
100
|
compileComponentFacts,
|
|
30
101
|
compileGlobalGovernanceFacts,
|
|
@@ -32,6 +103,11 @@ import {
|
|
|
32
103
|
componentGovernanceRecordsSchema,
|
|
33
104
|
componentId,
|
|
34
105
|
describePolicyExclude,
|
|
106
|
+
digestHexSchema,
|
|
107
|
+
digestHexStringSchema,
|
|
108
|
+
evaluationReceiptIdFromDigest,
|
|
109
|
+
evaluationReceiptIdSchema,
|
|
110
|
+
evaluationReceiptIdStringSchema,
|
|
35
111
|
excludeGlobToRegExp,
|
|
36
112
|
explainUrlForCode,
|
|
37
113
|
factEvidenceSchema,
|
|
@@ -100,6 +176,8 @@ import {
|
|
|
100
176
|
markPresetSourcedRules,
|
|
101
177
|
matchPolicyExclude,
|
|
102
178
|
matchesGlob,
|
|
179
|
+
mintEvaluationReceiptId,
|
|
180
|
+
normalizeCanonicalFactIntegrityV1,
|
|
103
181
|
normalizeExcludePath,
|
|
104
182
|
normalizeFinding,
|
|
105
183
|
normalizeGovernanceConfig,
|
|
@@ -109,24 +187,36 @@ import {
|
|
|
109
187
|
ownedComponentIdsEqual,
|
|
110
188
|
ownedImportMatchesRoot,
|
|
111
189
|
ownedImportsEqual,
|
|
190
|
+
parseAnalysisPlanId,
|
|
191
|
+
parseComponentGovernancePolicyJson,
|
|
192
|
+
parseDigestHex,
|
|
193
|
+
parseEvaluationReceiptId,
|
|
112
194
|
policyExcludeMatchesPath,
|
|
113
195
|
policyExcludeSchema,
|
|
114
196
|
projectSupersededImportPathPreferences,
|
|
115
197
|
resolveComponentGovernance,
|
|
198
|
+
resolveGovernanceRecordsForIdentity,
|
|
116
199
|
ruleFamilyMembers,
|
|
117
200
|
scaleGovernanceRecordSchema,
|
|
118
201
|
suppressionDirectiveSchema,
|
|
119
202
|
validatorResultSchema,
|
|
120
203
|
violationSchema
|
|
121
|
-
} from "./chunk-
|
|
204
|
+
} from "./chunk-BMPYIUZE.js";
|
|
122
205
|
import {
|
|
123
|
-
|
|
124
|
-
|
|
206
|
+
isPortableRepoPath,
|
|
207
|
+
normalizeConfigPath,
|
|
208
|
+
portableRepoPathError,
|
|
209
|
+
resolveConfiguredAppPath,
|
|
210
|
+
tokenIncludesFromConfig,
|
|
211
|
+
topologyBase
|
|
212
|
+
} from "./chunk-EIYNNS77.js";
|
|
125
213
|
import {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
214
|
+
artifactContentHash,
|
|
215
|
+
canonicalPreimage,
|
|
216
|
+
compareCanonicalStrings,
|
|
217
|
+
contractHash,
|
|
218
|
+
sha256Hex
|
|
219
|
+
} from "./chunk-PWIJMOI4.js";
|
|
130
220
|
import {
|
|
131
221
|
OWNED_PACKAGE_IDENTITY_EPOCH,
|
|
132
222
|
OWNED_PACKAGE_IDENTITY_SOURCE_SHA256,
|
|
@@ -138,53 +228,13 @@ import {
|
|
|
138
228
|
projectV1OwnedImportIdentity,
|
|
139
229
|
resolveOwnedPackageImport
|
|
140
230
|
} from "./chunk-JNBFJ34I.js";
|
|
141
|
-
import {
|
|
142
|
-
REGISTRY_ARTIFACT_SCHEMA_VERSION,
|
|
143
|
-
REGISTRY_INSTALL_RECEIPT_SCHEMA_VERSION,
|
|
144
|
-
REGISTRY_MANIFEST_SCHEMA_VERSION,
|
|
145
|
-
assertValidRegistryArtifact,
|
|
146
|
-
buildRegistryArtifact,
|
|
147
|
-
buildRegistryFile,
|
|
148
|
-
canonicalPreimage,
|
|
149
|
-
computeRegistryHash,
|
|
150
|
-
contractHash,
|
|
151
|
-
finalizeRegistryManifest,
|
|
152
|
-
hashRegistryFileContent,
|
|
153
|
-
registryArtifactDigest,
|
|
154
|
-
registryArtifactSchema,
|
|
155
|
-
registryComponentExportSchema,
|
|
156
|
-
registryComponentSchema,
|
|
157
|
-
registryDependencySchema,
|
|
158
|
-
registryDependencyTypeSchema,
|
|
159
|
-
registryEntrypointSchema,
|
|
160
|
-
registryFileContentSchema,
|
|
161
|
-
registryFileRoleSchema,
|
|
162
|
-
registryFileSchema,
|
|
163
|
-
registryFileSize,
|
|
164
|
-
registryInstallProfileSchema,
|
|
165
|
-
registryInstallReceiptComponentSchema,
|
|
166
|
-
registryInstallReceiptFileSchema,
|
|
167
|
-
registryInstallReceiptSchema,
|
|
168
|
-
registryManifestCanonicalPreimage,
|
|
169
|
-
registryManifestDraftSchema,
|
|
170
|
-
registryManifestSchema,
|
|
171
|
-
registrySourceSchema,
|
|
172
|
-
sha256Hex
|
|
173
|
-
} from "./chunk-YF65VYRY.js";
|
|
174
|
-
import {
|
|
175
|
-
isPortableRepoPath,
|
|
176
|
-
normalizeConfigPath,
|
|
177
|
-
portableRepoPathError,
|
|
178
|
-
resolveConfiguredAppPath,
|
|
179
|
-
tokenIncludesFromConfig,
|
|
180
|
-
topologyBase
|
|
181
|
-
} from "./chunk-EIYNNS77.js";
|
|
182
231
|
import {
|
|
183
232
|
SEVERITIES,
|
|
184
233
|
SEVERITY_RANK,
|
|
185
234
|
SEVERITY_WEIGHTS,
|
|
186
235
|
compareSeverity,
|
|
187
236
|
maxSeverity,
|
|
237
|
+
severityFromLevel,
|
|
188
238
|
severityLevel,
|
|
189
239
|
severitySchema,
|
|
190
240
|
sortBySeverity
|
|
@@ -200,8 +250,6 @@ var BRAND = {
|
|
|
200
250
|
fileExtension: ".contract.json",
|
|
201
251
|
/** Legacy file extension for segments (still supported for migration) */
|
|
202
252
|
legacyFileExtension: ".segment.tsx",
|
|
203
|
-
/** JSON file extension for compiled output */
|
|
204
|
-
jsonExtension: ".fragment.json",
|
|
205
253
|
/** Default output file name (e.g., "fragments.json") */
|
|
206
254
|
outFile: "fragments.json",
|
|
207
255
|
/** Config file name (e.g., "fragments.config.ts") */
|
|
@@ -238,11 +286,10 @@ var BRAND = {
|
|
|
238
286
|
mcpToolPrefix: "fragments_",
|
|
239
287
|
/** File extension for block definition files */
|
|
240
288
|
blockFileExtension: ".block.ts",
|
|
241
|
-
/** @deprecated Use blockFileExtension instead */
|
|
242
|
-
recipeFileExtension: ".recipe.ts",
|
|
243
289
|
/** Vite plugin namespace */
|
|
244
290
|
vitePluginNamespace: "fragments-core-shim"
|
|
245
291
|
};
|
|
292
|
+
var FRAGMENT_V3_SCHEMA_URL = "https://usefragments.com/schemas/fragment.v3.json";
|
|
246
293
|
var DEFAULTS = {
|
|
247
294
|
/** Default viewport dimensions */
|
|
248
295
|
viewport: {
|
|
@@ -741,6 +788,9 @@ function assertPortableRegistryPath(path, label) {
|
|
|
741
788
|
function joinRegistryPath(...parts) {
|
|
742
789
|
return normalizeRegistryRepoPath(parts.filter(Boolean).join("/"));
|
|
743
790
|
}
|
|
791
|
+
function sortStrings(values) {
|
|
792
|
+
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
793
|
+
}
|
|
744
794
|
function sourceToRegistryTargetPath(targetRoot, sourcePath) {
|
|
745
795
|
const source = normalizeRegistryRepoPath(sourcePath);
|
|
746
796
|
const withoutSrc = source.startsWith("src/") ? source.slice("src/".length) : source;
|
|
@@ -749,37 +799,69 @@ function sourceToRegistryTargetPath(targetRoot, sourcePath) {
|
|
|
749
799
|
"Registry install target"
|
|
750
800
|
);
|
|
751
801
|
}
|
|
752
|
-
function
|
|
753
|
-
if (
|
|
754
|
-
|
|
755
|
-
|
|
802
|
+
function resolveRegistryComponentId(manifest, requested) {
|
|
803
|
+
if (manifest.components[requested]) return requested;
|
|
804
|
+
const lowered = requested.toLowerCase();
|
|
805
|
+
const matches = Object.keys(manifest.components).filter((name) => name.toLowerCase() === lowered);
|
|
806
|
+
if (matches.length === 1) return matches[0];
|
|
807
|
+
if (matches.length > 1) {
|
|
808
|
+
throw new Error(
|
|
809
|
+
`Ambiguous registry component ${requested}: matches ${matches.sort().join(", ")}`
|
|
756
810
|
);
|
|
757
811
|
}
|
|
758
|
-
|
|
759
|
-
|
|
812
|
+
throw new Error(`Unknown registry component ${requested}`);
|
|
813
|
+
}
|
|
814
|
+
function expandRegistryComponentClosure(manifest, names) {
|
|
815
|
+
const closure = /* @__PURE__ */ new Set();
|
|
816
|
+
const queue = [...names];
|
|
817
|
+
while (queue.length > 0) {
|
|
818
|
+
const name = queue.shift();
|
|
819
|
+
if (closure.has(name)) continue;
|
|
820
|
+
const component = manifest.components[name];
|
|
821
|
+
if (!component) throw new Error(`Unknown registry component ${name}`);
|
|
822
|
+
closure.add(name);
|
|
823
|
+
queue.push(...component.internalDependencies);
|
|
760
824
|
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
825
|
+
return sortStrings(closure);
|
|
826
|
+
}
|
|
827
|
+
function resolveRegistryInstallSelection(input) {
|
|
828
|
+
const { manifest } = input;
|
|
829
|
+
if (input.all || input.requestedComponents.includes("*")) {
|
|
830
|
+
const components2 = sortStrings(Object.keys(manifest.components));
|
|
831
|
+
return { requested: components2, implied: [], components: components2 };
|
|
832
|
+
}
|
|
833
|
+
if (input.requestedComponents.length === 0) {
|
|
834
|
+
throw new Error("Choose at least one registry component to install.");
|
|
765
835
|
}
|
|
766
|
-
|
|
836
|
+
const requested = sortStrings(
|
|
837
|
+
input.requestedComponents.map((name) => resolveRegistryComponentId(manifest, name))
|
|
838
|
+
);
|
|
839
|
+
const components = expandRegistryComponentClosure(manifest, requested);
|
|
840
|
+
const requestedSet = new Set(requested);
|
|
841
|
+
return {
|
|
842
|
+
requested,
|
|
843
|
+
implied: components.filter((name) => !requestedSet.has(name)),
|
|
844
|
+
components
|
|
845
|
+
};
|
|
767
846
|
}
|
|
768
|
-
function installsCompleteRegistry(
|
|
769
|
-
const allComponents = Object.keys(
|
|
847
|
+
function installsCompleteRegistry(manifest, componentNames) {
|
|
848
|
+
const allComponents = Object.keys(manifest.components);
|
|
770
849
|
return componentNames.length === allComponents.length && allComponents.every((name) => componentNames.includes(name));
|
|
771
850
|
}
|
|
851
|
+
var AUTHORING_ROLES = /* @__PURE__ */ new Set(["test", "story", "example"]);
|
|
772
852
|
function shouldInstallFile(file, includeTests) {
|
|
773
853
|
if (includeTests) return true;
|
|
774
|
-
return
|
|
854
|
+
return !AUTHORING_ROLES.has(file.role);
|
|
775
855
|
}
|
|
776
856
|
function dependencyKey(dependency) {
|
|
777
857
|
return `${dependency.type}:${dependency.name}:${dependency.versionRange}:${dependency.optional ? 1 : 0}`;
|
|
778
858
|
}
|
|
779
859
|
function collectRegistryInstallDependencies(artifact, componentNames) {
|
|
780
860
|
const dependencies = /* @__PURE__ */ new Map();
|
|
781
|
-
|
|
782
|
-
|
|
861
|
+
if (installsCompleteRegistry(artifact.manifest, componentNames)) {
|
|
862
|
+
for (const dependency of artifact.manifest.dependencies) {
|
|
863
|
+
dependencies.set(dependencyKey(dependency), dependency);
|
|
864
|
+
}
|
|
783
865
|
}
|
|
784
866
|
for (const name of componentNames) {
|
|
785
867
|
const component = artifact.manifest.components[name];
|
|
@@ -789,24 +871,44 @@ function collectRegistryInstallDependencies(artifact, componentNames) {
|
|
|
789
871
|
}
|
|
790
872
|
return [...dependencies.values()].sort((left, right) => left.name.localeCompare(right.name));
|
|
791
873
|
}
|
|
792
|
-
function
|
|
793
|
-
const
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
874
|
+
function packageFileEntries(manifest) {
|
|
875
|
+
const packageFiles = new Map(
|
|
876
|
+
manifest.packageFiles.map((file) => [file.path, file])
|
|
877
|
+
);
|
|
878
|
+
for (const entrypoint of manifest.entrypoints) {
|
|
879
|
+
if (!packageFiles.has(entrypoint.sourcePath)) packageFiles.set(entrypoint.sourcePath, null);
|
|
880
|
+
}
|
|
881
|
+
return packageFiles;
|
|
882
|
+
}
|
|
883
|
+
function resolveRegistryInstallSources(input) {
|
|
884
|
+
const { manifest } = input;
|
|
885
|
+
const selection = resolveRegistryInstallSelection(input);
|
|
886
|
+
const complete = installsCompleteRegistry(manifest, selection.components);
|
|
887
|
+
const files = /* @__PURE__ */ new Map();
|
|
888
|
+
const paths = /* @__PURE__ */ new Set();
|
|
889
|
+
const add = (file, componentId2) => {
|
|
890
|
+
if (!shouldInstallFile(file, input.includeTests)) return;
|
|
891
|
+
if (!files.has(file.path)) files.set(file.path, { file, componentId: componentId2 });
|
|
892
|
+
paths.add(file.path);
|
|
893
|
+
};
|
|
894
|
+
if (complete) {
|
|
895
|
+
for (const [path, file] of packageFileEntries(manifest)) {
|
|
896
|
+
if (file) add(file);
|
|
897
|
+
else paths.add(path);
|
|
807
898
|
}
|
|
899
|
+
} else {
|
|
900
|
+
for (const file of manifest.baseFiles) add(file);
|
|
808
901
|
}
|
|
809
|
-
|
|
902
|
+
for (const name of selection.components) {
|
|
903
|
+
const component = manifest.components[name];
|
|
904
|
+
for (const file of component.files) add(file, component.componentId);
|
|
905
|
+
}
|
|
906
|
+
return {
|
|
907
|
+
selection,
|
|
908
|
+
complete,
|
|
909
|
+
files: [...files.values()].sort((left, right) => left.file.path.localeCompare(right.file.path)),
|
|
910
|
+
paths: sortStrings(paths)
|
|
911
|
+
};
|
|
810
912
|
}
|
|
811
913
|
function rewriteInstalledPackagePath(value) {
|
|
812
914
|
if (value.startsWith("./src/")) return `./${value.slice("./src/".length)}`;
|
|
@@ -843,41 +945,14 @@ function rewriteInstalledPackageJson(content) {
|
|
|
843
945
|
return `${JSON.stringify(installed, null, 2)}
|
|
844
946
|
`;
|
|
845
947
|
}
|
|
846
|
-
function
|
|
847
|
-
const
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
);
|
|
851
|
-
for (const entrypoint of args.artifact.manifest.entrypoints) {
|
|
852
|
-
const file = packageFiles.get(entrypoint.sourcePath);
|
|
853
|
-
if (file) continue;
|
|
854
|
-
const content = args.artifact.files[entrypoint.sourcePath];
|
|
855
|
-
if (!content) throw new Error(`Artifact is missing file content for ${entrypoint.sourcePath}`);
|
|
856
|
-
packageFiles.set(entrypoint.sourcePath, {
|
|
857
|
-
path: entrypoint.sourcePath,
|
|
858
|
-
role: "barrel",
|
|
859
|
-
sha256: content.sha256,
|
|
860
|
-
size: content.size,
|
|
861
|
-
contentType: content.contentType,
|
|
862
|
-
contentRef: `sha256:${content.sha256}`
|
|
863
|
-
});
|
|
864
|
-
}
|
|
865
|
-
for (const file of packageFiles.values()) {
|
|
866
|
-
if (!shouldInstallFile(file, args.includeTests)) continue;
|
|
867
|
-
const content = args.artifact.files[file.path];
|
|
868
|
-
if (!content) throw new Error(`Artifact is missing file content for ${file.path}`);
|
|
869
|
-
const target = sourceToRegistryTargetPath(args.targetPath, file.path);
|
|
870
|
-
writes.set(target, {
|
|
871
|
-
path: target,
|
|
872
|
-
sourcePath: file.path,
|
|
873
|
-
content: file.path === "package.json" ? rewriteInstalledPackageJson(content.content) : content.content
|
|
874
|
-
});
|
|
875
|
-
}
|
|
876
|
-
return [...writes.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
948
|
+
function contentFor(artifact, path) {
|
|
949
|
+
const content = artifact.files[path];
|
|
950
|
+
if (!content) throw new Error(`Artifact is missing file content for ${path}`);
|
|
951
|
+
return content.content;
|
|
877
952
|
}
|
|
878
953
|
function generatedIndexPlan(args) {
|
|
879
954
|
const lines = args.componentNames.map((name) => {
|
|
880
|
-
const component = args.
|
|
955
|
+
const component = args.manifest.components[name];
|
|
881
956
|
const exportName = component.exports[0]?.name ?? component.name;
|
|
882
957
|
return `export { ${exportName} } from "./components/${component.componentId}";`;
|
|
883
958
|
});
|
|
@@ -903,32 +978,47 @@ function dedupePlans(plans) {
|
|
|
903
978
|
return [...byPath.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
904
979
|
}
|
|
905
980
|
function buildRegistryInstallPlan(input) {
|
|
981
|
+
const { manifest } = input.artifact;
|
|
906
982
|
const targetPath = assertPortableRegistryPath(input.targetPath, "Registry target");
|
|
907
|
-
const
|
|
908
|
-
|
|
909
|
-
input.requestedComponents,
|
|
910
|
-
input.all
|
|
911
|
-
|
|
983
|
+
const sources = resolveRegistryInstallSources({
|
|
984
|
+
manifest,
|
|
985
|
+
requestedComponents: input.requestedComponents,
|
|
986
|
+
all: input.all,
|
|
987
|
+
includeTests: input.includeTests
|
|
988
|
+
});
|
|
989
|
+
const componentNames = sources.selection.components;
|
|
912
990
|
const dependencies = collectRegistryInstallDependencies(input.artifact, componentNames);
|
|
913
|
-
const
|
|
914
|
-
const
|
|
915
|
-
|
|
916
|
-
|
|
991
|
+
const hasPackageRoot = manifest.entrypoints.some((entrypoint) => entrypoint.specifier === ".");
|
|
992
|
+
const writes = sources.files.map(({ file, componentId: componentId2 }) => {
|
|
993
|
+
const raw = contentFor(input.artifact, file.path);
|
|
994
|
+
return {
|
|
995
|
+
path: sourceToRegistryTargetPath(targetPath, file.path),
|
|
996
|
+
sourcePath: file.path,
|
|
997
|
+
content: sources.complete && file.path === "package.json" ? rewriteInstalledPackageJson(raw) : raw,
|
|
998
|
+
...componentId2 && { componentId: componentId2 }
|
|
999
|
+
};
|
|
1000
|
+
});
|
|
1001
|
+
if (sources.complete) {
|
|
1002
|
+
for (const entrypoint of manifest.entrypoints) {
|
|
1003
|
+
if (writes.some((plan) => plan.sourcePath === entrypoint.sourcePath)) continue;
|
|
1004
|
+
writes.push({
|
|
1005
|
+
path: sourceToRegistryTargetPath(targetPath, entrypoint.sourcePath),
|
|
1006
|
+
sourcePath: entrypoint.sourcePath,
|
|
1007
|
+
content: contentFor(input.artifact, entrypoint.sourcePath)
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
917
1011
|
const plans = dedupePlans([
|
|
918
|
-
...
|
|
919
|
-
|
|
920
|
-
targetPath,
|
|
921
|
-
includeTests: input.includeTests
|
|
922
|
-
}) : [],
|
|
923
|
-
...collectComponentWritePlan({
|
|
924
|
-
artifact: input.artifact,
|
|
925
|
-
componentNames,
|
|
926
|
-
targetPath,
|
|
927
|
-
includeTests: input.includeTests
|
|
928
|
-
}),
|
|
929
|
-
...isCompleteInstall && hasPackageRoot ? [] : [generatedIndexPlan({ artifact: input.artifact, componentNames, targetPath })]
|
|
1012
|
+
...writes,
|
|
1013
|
+
...sources.complete && hasPackageRoot ? [] : [generatedIndexPlan({ manifest, componentNames, targetPath })]
|
|
930
1014
|
]);
|
|
931
|
-
return {
|
|
1015
|
+
return {
|
|
1016
|
+
componentNames,
|
|
1017
|
+
requestedComponents: sources.selection.requested,
|
|
1018
|
+
impliedComponents: sources.selection.implied,
|
|
1019
|
+
plans,
|
|
1020
|
+
dependencies
|
|
1021
|
+
};
|
|
932
1022
|
}
|
|
933
1023
|
function buildRegistryInstallReceipt(args) {
|
|
934
1024
|
const installedComponents = args.componentNames.map((name) => {
|
|
@@ -1249,14 +1339,14 @@ function rgbToLab(rgb) {
|
|
|
1249
1339
|
b = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
|
|
1250
1340
|
let x = (r * 0.4124564 + g2 * 0.3575761 + b * 0.1804375) / 0.95047;
|
|
1251
1341
|
let y = r * 0.2126729 + g2 * 0.7151522 + b * 0.072175;
|
|
1252
|
-
let
|
|
1342
|
+
let z11 = (r * 0.0193339 + g2 * 0.119192 + b * 0.9503041) / 1.08883;
|
|
1253
1343
|
x = x > 8856e-6 ? Math.pow(x, 1 / 3) : 7.787 * x + 16 / 116;
|
|
1254
1344
|
y = y > 8856e-6 ? Math.pow(y, 1 / 3) : 7.787 * y + 16 / 116;
|
|
1255
|
-
|
|
1345
|
+
z11 = z11 > 8856e-6 ? Math.pow(z11, 1 / 3) : 7.787 * z11 + 16 / 116;
|
|
1256
1346
|
return {
|
|
1257
1347
|
l: 116 * y - 16,
|
|
1258
1348
|
a: 500 * (x - y),
|
|
1259
|
-
b: 200 * (y -
|
|
1349
|
+
b: 200 * (y - z11)
|
|
1260
1350
|
};
|
|
1261
1351
|
}
|
|
1262
1352
|
|
|
@@ -1521,10 +1611,14 @@ var figmaStringMappingSchema = z4.object({
|
|
|
1521
1611
|
__type: z4.literal("figma-string"),
|
|
1522
1612
|
figmaProperty: z4.string().min(1)
|
|
1523
1613
|
});
|
|
1614
|
+
var requiredUnknownSchema = z4.custom(
|
|
1615
|
+
(value) => value !== void 0,
|
|
1616
|
+
"Expected an explicitly present value"
|
|
1617
|
+
);
|
|
1524
1618
|
var figmaBooleanMappingSchema = z4.object({
|
|
1525
1619
|
__type: z4.literal("figma-boolean"),
|
|
1526
1620
|
figmaProperty: z4.string().min(1),
|
|
1527
|
-
valueMapping: z4.object({ true:
|
|
1621
|
+
valueMapping: z4.object({ true: requiredUnknownSchema, false: requiredUnknownSchema }).optional()
|
|
1528
1622
|
});
|
|
1529
1623
|
var figmaEnumMappingSchema = z4.object({
|
|
1530
1624
|
__type: z4.literal("figma-enum"),
|
|
@@ -1629,7 +1723,7 @@ var fragmentContractSchema = z4.object({
|
|
|
1629
1723
|
a11yRules: z4.array(z4.string()).optional(),
|
|
1630
1724
|
bans: z4.array(fragmentBanSchema).optional(),
|
|
1631
1725
|
scenarioTags: z4.array(z4.string()).optional(),
|
|
1632
|
-
performanceBudget: z4.number().positive().optional(),
|
|
1726
|
+
performanceBudget: z4.number().positive().finite().optional(),
|
|
1633
1727
|
compoundChildren: z4.record(
|
|
1634
1728
|
z4.object({
|
|
1635
1729
|
required: z4.boolean().optional(),
|
|
@@ -1643,10 +1737,20 @@ var fragmentContractSchema = z4.object({
|
|
|
1643
1737
|
// `CompositionPattern[]` the composition/* rules read from policy.
|
|
1644
1738
|
composition: z4.array(compositionAuthoringEntrySchema).optional()
|
|
1645
1739
|
});
|
|
1740
|
+
var fragmentSourceValues = [
|
|
1741
|
+
"storybook",
|
|
1742
|
+
"manual",
|
|
1743
|
+
"ai",
|
|
1744
|
+
"scan",
|
|
1745
|
+
"extracted",
|
|
1746
|
+
"merged",
|
|
1747
|
+
"migrated"
|
|
1748
|
+
];
|
|
1646
1749
|
var fragmentGeneratedSchema = z4.object({
|
|
1647
|
-
source: z4.enum(
|
|
1750
|
+
source: z4.enum(fragmentSourceValues),
|
|
1648
1751
|
sourceFile: z4.string().optional(),
|
|
1649
1752
|
confidence: z4.number().min(0).max(1).optional(),
|
|
1753
|
+
verified: z4.boolean().optional(),
|
|
1650
1754
|
timestamp: z4.string().datetime().optional()
|
|
1651
1755
|
});
|
|
1652
1756
|
var aiMetadataSchema = z4.object({
|
|
@@ -1785,14 +1889,6 @@ var fragmentsConfigSchema = z4.object({
|
|
|
1785
1889
|
}).optional()
|
|
1786
1890
|
})
|
|
1787
1891
|
]).optional(),
|
|
1788
|
-
storybook: z4.object({
|
|
1789
|
-
exclude: z4.array(z4.string()).optional(),
|
|
1790
|
-
include: z4.array(z4.string()).optional(),
|
|
1791
|
-
excludeDeprecated: z4.boolean().optional(),
|
|
1792
|
-
excludeTests: z4.boolean().optional(),
|
|
1793
|
-
excludeSvgIcons: z4.boolean().optional(),
|
|
1794
|
-
excludeSubComponents: z4.boolean().optional()
|
|
1795
|
-
}).optional(),
|
|
1796
1892
|
topology: topologySchema.optional(),
|
|
1797
1893
|
govern: governanceConfigSchema.optional(),
|
|
1798
1894
|
inspect: z4.object({
|
|
@@ -1830,10 +1926,13 @@ var compositionMetadataSchema = z4.object({
|
|
|
1830
1926
|
commonPatterns: z4.array(z4.string()).optional()
|
|
1831
1927
|
});
|
|
1832
1928
|
var fragmentProvenanceSchema = z4.object({
|
|
1833
|
-
source: z4.enum(
|
|
1929
|
+
source: z4.enum(fragmentSourceValues),
|
|
1834
1930
|
sourceFile: z4.string().optional(),
|
|
1835
1931
|
confidence: z4.number().min(0).max(1).optional(),
|
|
1836
|
-
|
|
1932
|
+
verified: z4.boolean().optional(),
|
|
1933
|
+
frameworkSupport: z4.enum(["native", "manual-only"]).optional(),
|
|
1934
|
+
sourceHash: z4.string().optional(),
|
|
1935
|
+
timestamp: z4.string().datetime({ offset: true }).optional(),
|
|
1837
1936
|
autoFields: z4.array(z4.string()).optional(),
|
|
1838
1937
|
humanFields: z4.array(z4.string()).optional()
|
|
1839
1938
|
});
|
|
@@ -1860,8 +1959,119 @@ var governedFragmentDefinitionSchema = z4.object({
|
|
|
1860
1959
|
_provenance: fragmentProvenanceSchema.optional(),
|
|
1861
1960
|
govern: z4.function().optional(),
|
|
1862
1961
|
governance: z4.array(componentGovernanceRecordSchema).optional()
|
|
1962
|
+
}).superRefine((def, ctx) => {
|
|
1963
|
+
if (def.govern === void 0 && def.governance === void 0) {
|
|
1964
|
+
ctx.addIssue({
|
|
1965
|
+
code: z4.ZodIssueCode.custom,
|
|
1966
|
+
message: "Governed definitions require `govern` or `governance`",
|
|
1967
|
+
path: ["govern"]
|
|
1968
|
+
});
|
|
1969
|
+
}
|
|
1863
1970
|
});
|
|
1864
|
-
var
|
|
1971
|
+
var fragmentRenderSchema = z4.custom(
|
|
1972
|
+
(value) => value !== void 0 && typeof value !== "string",
|
|
1973
|
+
"Expected JSX/render value, not a code string"
|
|
1974
|
+
);
|
|
1975
|
+
var fragmentMetaV3Schema = z4.object({
|
|
1976
|
+
name: z4.string().min(1),
|
|
1977
|
+
purpose: z4.string().min(1),
|
|
1978
|
+
category: z4.string().min(1),
|
|
1979
|
+
status: z4.enum(["stable", "beta", "deprecated", "experimental"]).optional(),
|
|
1980
|
+
aliases: z4.array(z4.string().min(1)).optional(),
|
|
1981
|
+
tags: z4.array(z4.string()).optional(),
|
|
1982
|
+
since: z4.string().optional(),
|
|
1983
|
+
dependencies: z4.array(
|
|
1984
|
+
z4.object({
|
|
1985
|
+
name: z4.string().min(1),
|
|
1986
|
+
version: z4.string().min(1),
|
|
1987
|
+
reason: z4.string().optional()
|
|
1988
|
+
}).strict()
|
|
1989
|
+
).optional(),
|
|
1990
|
+
figma: z4.string().url().optional(),
|
|
1991
|
+
figmaProps: z4.record(figmaPropMappingSchema).optional()
|
|
1992
|
+
}).strict();
|
|
1993
|
+
var fragmentStateV3Schema = z4.object({
|
|
1994
|
+
render: fragmentRenderSchema,
|
|
1995
|
+
note: z4.string().optional(),
|
|
1996
|
+
canonical: z4.boolean().optional()
|
|
1997
|
+
}).strict();
|
|
1998
|
+
var fragmentDontExampleV3Schema = z4.object({
|
|
1999
|
+
reason: z4.string().min(1),
|
|
2000
|
+
bad: z4.string().min(1),
|
|
2001
|
+
good: fragmentRenderSchema
|
|
2002
|
+
}).strict();
|
|
2003
|
+
var fragmentGuidanceV3Schema = z4.object({
|
|
2004
|
+
when: z4.array(z4.string()),
|
|
2005
|
+
whenNot: z4.array(z4.string()),
|
|
2006
|
+
choose: z4.record(z4.string()).optional(),
|
|
2007
|
+
dont: z4.array(fragmentDontExampleV3Schema).optional(),
|
|
2008
|
+
guidelines: z4.array(z4.string()).optional(),
|
|
2009
|
+
accessibility: z4.array(z4.string()).optional()
|
|
2010
|
+
}).strict();
|
|
2011
|
+
var fragmentMatrixV3Schema = z4.object({
|
|
2012
|
+
axes: z4.record(z4.union([z4.literal("auto"), z4.array(z4.string().min(1)).readonly()])).optional(),
|
|
2013
|
+
forced: z4.array(z4.string().min(1)).optional(),
|
|
2014
|
+
worstCase: z4.record(z4.unknown()).optional()
|
|
2015
|
+
}).strict();
|
|
2016
|
+
var fragmentPreviewV3Schema = z4.object({
|
|
2017
|
+
providers: z4.array(z4.unknown()).optional(),
|
|
2018
|
+
dynamicRegions: z4.array(z4.string()).optional()
|
|
2019
|
+
}).strict();
|
|
2020
|
+
var fragmentDesignV3Schema = z4.object({
|
|
2021
|
+
figmaNode: z4.string().min(1).optional()
|
|
2022
|
+
}).strict();
|
|
2023
|
+
var propAnnotationSchema = z4.object({
|
|
2024
|
+
description: z4.string().optional(),
|
|
2025
|
+
controlType: z4.enum([
|
|
2026
|
+
"text",
|
|
2027
|
+
"number",
|
|
2028
|
+
"range",
|
|
2029
|
+
"boolean",
|
|
2030
|
+
"select",
|
|
2031
|
+
"multi-select",
|
|
2032
|
+
"radio",
|
|
2033
|
+
"inline-radio",
|
|
2034
|
+
"check",
|
|
2035
|
+
"inline-check",
|
|
2036
|
+
"object",
|
|
2037
|
+
"file",
|
|
2038
|
+
"color",
|
|
2039
|
+
"date"
|
|
2040
|
+
]).optional(),
|
|
2041
|
+
controlOptions: z4.record(z4.unknown()).optional(),
|
|
2042
|
+
visibility: z4.enum(["public", "internal", "hidden"]).optional(),
|
|
2043
|
+
constraints: z4.array(z4.string()).optional()
|
|
2044
|
+
}).strict();
|
|
2045
|
+
var fragmentAnnotationsV3Schema = z4.object({
|
|
2046
|
+
notes: z4.array(z4.string()).optional(),
|
|
2047
|
+
review: z4.array(z4.string()).optional()
|
|
2048
|
+
}).passthrough();
|
|
2049
|
+
var fragmentDefinitionV3BodyShape = {
|
|
2050
|
+
meta: fragmentMetaV3Schema,
|
|
2051
|
+
states: z4.record(fragmentStateV3Schema).refine((states) => Object.keys(states).length > 0, {
|
|
2052
|
+
message: "At least one state is required"
|
|
2053
|
+
}),
|
|
2054
|
+
guidance: fragmentGuidanceV3Schema,
|
|
2055
|
+
matrix: fragmentMatrixV3Schema.optional(),
|
|
2056
|
+
preview: fragmentPreviewV3Schema.optional(),
|
|
2057
|
+
design: fragmentDesignV3Schema.optional(),
|
|
2058
|
+
annotations: fragmentAnnotationsV3Schema.optional(),
|
|
2059
|
+
props: z4.record(propAnnotationSchema).optional(),
|
|
2060
|
+
relations: z4.array(componentRelationSchema.strict()).optional(),
|
|
2061
|
+
composition: compositionMetadataSchema.strict().optional(),
|
|
2062
|
+
contract: fragmentContractSchema.optional(),
|
|
2063
|
+
_provenance: fragmentProvenanceSchema.optional(),
|
|
2064
|
+
govern: z4.function().optional(),
|
|
2065
|
+
governance: z4.array(componentGovernanceRecordSchema).optional()
|
|
2066
|
+
};
|
|
2067
|
+
var fragmentDefinitionV3BodySchema = z4.object(fragmentDefinitionV3BodyShape).strict();
|
|
2068
|
+
var fragmentDefinitionV3Schema = z4.object({
|
|
2069
|
+
...fragmentDefinitionV3BodyShape,
|
|
2070
|
+
component: z4.unknown().refine((component) => component !== void 0, {
|
|
2071
|
+
message: "Component is required"
|
|
2072
|
+
}),
|
|
2073
|
+
governance: z4.array(componentGovernanceRecordSchema)
|
|
2074
|
+
}).strict();
|
|
1865
2075
|
|
|
1866
2076
|
// src/config.ts
|
|
1867
2077
|
var RAW_CONFIG_DECLARATION = /* @__PURE__ */ Symbol.for("@usefragments/core/raw-config-declaration");
|
|
@@ -1890,11 +2100,51 @@ ${formatZodErrors(result.error.errors)}`);
|
|
|
1890
2100
|
|
|
1891
2101
|
// src/defineFragment.ts
|
|
1892
2102
|
function isGovernedDefinition(def) {
|
|
1893
|
-
|
|
2103
|
+
if (!def || typeof def !== "object") return false;
|
|
2104
|
+
const record = def;
|
|
2105
|
+
return typeof record.govern === "function" || Array.isArray(record.governance);
|
|
1894
2106
|
}
|
|
1895
2107
|
function isV2Definition(def) {
|
|
2108
|
+
if (!def || typeof def !== "object") return false;
|
|
1896
2109
|
return !isGovernedDefinition(def) && ("guidance" in def || "examples" in def);
|
|
1897
2110
|
}
|
|
2111
|
+
function rejectInvalidGovernanceDiscriminants(definition) {
|
|
2112
|
+
if (!definition || typeof definition !== "object") return;
|
|
2113
|
+
const record = definition;
|
|
2114
|
+
const hasOwn = (key) => Object.prototype.hasOwnProperty.call(record, key);
|
|
2115
|
+
const errors = [];
|
|
2116
|
+
if (hasOwn("govern") && typeof record.govern !== "function") {
|
|
2117
|
+
errors.push({ path: ["govern"], message: "Expected a governance authoring function" });
|
|
2118
|
+
}
|
|
2119
|
+
if (hasOwn("governance") && !Array.isArray(record.governance)) {
|
|
2120
|
+
errors.push({ path: ["governance"], message: "Expected an array of governance records" });
|
|
2121
|
+
}
|
|
2122
|
+
if (errors.length > 0) {
|
|
2123
|
+
const name = record.meta && typeof record.meta === "object" && "name" in record.meta ? String(record.meta.name) : "unknown";
|
|
2124
|
+
throwInvalidFragment(name, "governed", errors);
|
|
2125
|
+
}
|
|
2126
|
+
}
|
|
2127
|
+
var InvalidFragmentDefinitionError = class _InvalidFragmentDefinitionError extends Error {
|
|
2128
|
+
code = "FUI9010";
|
|
2129
|
+
source = "@usefragments/core/defineFragment";
|
|
2130
|
+
api;
|
|
2131
|
+
issues;
|
|
2132
|
+
constructor(name, api, errors) {
|
|
2133
|
+
const issues = errors.map((error) => `${error.path.join(".") || "(root)"}: ${error.message}`).sort();
|
|
2134
|
+
super(
|
|
2135
|
+
[
|
|
2136
|
+
`${_InvalidFragmentDefinitionError.name}: Invalid fragment definition for "${name}":`,
|
|
2137
|
+
...issues.map((issue) => ` - ${issue}`)
|
|
2138
|
+
].join("\n")
|
|
2139
|
+
);
|
|
2140
|
+
this.name = _InvalidFragmentDefinitionError.name;
|
|
2141
|
+
this.api = api;
|
|
2142
|
+
this.issues = issues;
|
|
2143
|
+
}
|
|
2144
|
+
};
|
|
2145
|
+
function throwInvalidFragment(name, api, errors) {
|
|
2146
|
+
throw new InvalidFragmentDefinitionError(name, api, errors);
|
|
2147
|
+
}
|
|
1898
2148
|
function normalizeToV1(def) {
|
|
1899
2149
|
let ai;
|
|
1900
2150
|
if (def.composition) {
|
|
@@ -1908,9 +2158,10 @@ function normalizeToV1(def) {
|
|
|
1908
2158
|
let generated;
|
|
1909
2159
|
if (def._provenance) {
|
|
1910
2160
|
generated = {
|
|
1911
|
-
source: def._provenance.source
|
|
2161
|
+
source: def._provenance.source,
|
|
1912
2162
|
sourceFile: def._provenance.sourceFile,
|
|
1913
2163
|
confidence: def._provenance.confidence,
|
|
2164
|
+
verified: def._provenance.verified,
|
|
1914
2165
|
timestamp: def._provenance.timestamp
|
|
1915
2166
|
};
|
|
1916
2167
|
}
|
|
@@ -1926,18 +2177,60 @@ function normalizeToV1(def) {
|
|
|
1926
2177
|
_generated: generated
|
|
1927
2178
|
};
|
|
1928
2179
|
}
|
|
1929
|
-
function
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
2180
|
+
function defineFragmentV3(component, definition) {
|
|
2181
|
+
const result = fragmentDefinitionV3BodySchema.safeParse(definition);
|
|
2182
|
+
if (!result.success) {
|
|
2183
|
+
throwInvalidFragment(
|
|
2184
|
+
definition?.meta?.name || "unknown",
|
|
2185
|
+
"v3",
|
|
2186
|
+
result.error.errors.map((e) => ({ path: e.path, message: e.message }))
|
|
2187
|
+
);
|
|
2188
|
+
}
|
|
2189
|
+
const governance = typeof definition.govern === "function" || Array.isArray(definition.governance) ? resolveComponentGovernance({
|
|
2190
|
+
component,
|
|
2191
|
+
meta: {
|
|
2192
|
+
name: definition.meta.name,
|
|
2193
|
+
description: definition.meta.purpose,
|
|
2194
|
+
category: definition.meta.category,
|
|
2195
|
+
status: definition.meta.status,
|
|
2196
|
+
tags: definition.meta.tags,
|
|
2197
|
+
since: definition.meta.since,
|
|
2198
|
+
dependencies: definition.meta.dependencies,
|
|
2199
|
+
figma: definition.meta.figma,
|
|
2200
|
+
figmaProps: definition.meta.figmaProps
|
|
2201
|
+
},
|
|
2202
|
+
guidance: {
|
|
2203
|
+
when: definition.guidance.when,
|
|
2204
|
+
whenNot: definition.guidance.whenNot,
|
|
2205
|
+
guidelines: definition.guidance.guidelines,
|
|
2206
|
+
accessibility: definition.guidance.accessibility
|
|
2207
|
+
},
|
|
2208
|
+
govern: definition.govern,
|
|
2209
|
+
governance: definition.governance
|
|
2210
|
+
}) : [];
|
|
2211
|
+
return {
|
|
2212
|
+
...definition,
|
|
2213
|
+
component,
|
|
2214
|
+
governance
|
|
2215
|
+
};
|
|
2216
|
+
}
|
|
2217
|
+
function defineFragmentOneArg(definition) {
|
|
2218
|
+
if (!definition || typeof definition !== "object") {
|
|
2219
|
+
throwInvalidFragment("unknown", "unknown", [
|
|
2220
|
+
{ path: [], message: "Expected a fragment definition object" }
|
|
2221
|
+
]);
|
|
2222
|
+
}
|
|
2223
|
+
rejectInvalidGovernanceDiscriminants(definition);
|
|
2224
|
+
const governed = isGovernedDefinition(definition);
|
|
2225
|
+
const v2 = isV2Definition(definition);
|
|
2226
|
+
const schema = governed ? governedFragmentDefinitionSchema : v2 ? fragmentDefinitionV2Schema : fragmentDefinitionSchema;
|
|
2227
|
+
const result = schema.safeParse(definition);
|
|
2228
|
+
if (!result.success) {
|
|
2229
|
+
throwInvalidFragment(
|
|
2230
|
+
definition?.meta?.name || "unknown",
|
|
2231
|
+
governed ? "governed" : v2 ? "v2" : "v1",
|
|
2232
|
+
result.error.errors.map((e) => ({ path: e.path, message: e.message }))
|
|
2233
|
+
);
|
|
1941
2234
|
}
|
|
1942
2235
|
if (isGovernedDefinition(definition)) {
|
|
1943
2236
|
const governance = resolveComponentGovernance(definition);
|
|
@@ -1948,6 +2241,17 @@ ${errors}`);
|
|
|
1948
2241
|
}
|
|
1949
2242
|
return definition;
|
|
1950
2243
|
}
|
|
2244
|
+
function defineFragment(componentOrDefinition, maybeDefinition) {
|
|
2245
|
+
if (arguments.length >= 2) {
|
|
2246
|
+
return defineFragmentV3(
|
|
2247
|
+
componentOrDefinition,
|
|
2248
|
+
maybeDefinition
|
|
2249
|
+
);
|
|
2250
|
+
}
|
|
2251
|
+
return defineFragmentOneArg(
|
|
2252
|
+
componentOrDefinition
|
|
2253
|
+
);
|
|
2254
|
+
}
|
|
1951
2255
|
function compileFragment(definition, filePath) {
|
|
1952
2256
|
const v1 = isGovernedDefinition(definition) ? {
|
|
1953
2257
|
component: definition.component,
|
|
@@ -1957,10 +2261,17 @@ function compileFragment(definition, filePath) {
|
|
|
1957
2261
|
relations: definition.relations,
|
|
1958
2262
|
variants: definition.examples ?? [],
|
|
1959
2263
|
contract: definition.contract,
|
|
2264
|
+
ai: definition.composition ? {
|
|
2265
|
+
compositionPattern: definition.composition.pattern,
|
|
2266
|
+
subComponents: definition.composition.subComponents,
|
|
2267
|
+
requiredChildren: definition.composition.requiredChildren,
|
|
2268
|
+
commonPatterns: definition.composition.commonPatterns
|
|
2269
|
+
} : void 0,
|
|
1960
2270
|
_generated: definition._provenance ? {
|
|
1961
|
-
source: definition._provenance.source
|
|
2271
|
+
source: definition._provenance.source,
|
|
1962
2272
|
sourceFile: definition._provenance.sourceFile,
|
|
1963
2273
|
confidence: definition._provenance.confidence,
|
|
2274
|
+
verified: definition._provenance.verified,
|
|
1964
2275
|
timestamp: definition._provenance.timestamp
|
|
1965
2276
|
} : void 0
|
|
1966
2277
|
} : isV2Definition(definition) ? normalizeToV1(definition) : definition;
|
|
@@ -1986,17 +2297,14 @@ function compileFragment(definition, filePath) {
|
|
|
1986
2297
|
};
|
|
1987
2298
|
}
|
|
1988
2299
|
function defineBlock(definition) {
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
throw new Error(`Invalid block definition for "${definition.name || "unknown"}":
|
|
2300
|
+
const result = blockDefinitionSchema.safeParse(definition);
|
|
2301
|
+
if (!result.success) {
|
|
2302
|
+
const errors = result.error.errors.map((e) => `${e.path.join(".") || "(root)"}: ${e.message}`).sort().map((issue) => ` - ${issue}`).join("\n");
|
|
2303
|
+
throw new Error(`Invalid block definition for "${definition.name || "unknown"}":
|
|
1994
2304
|
${errors}`);
|
|
1995
|
-
}
|
|
1996
2305
|
}
|
|
1997
2306
|
return definition;
|
|
1998
2307
|
}
|
|
1999
|
-
var defineRecipe = defineBlock;
|
|
2000
2308
|
function compileBlock(definition, filePath) {
|
|
2001
2309
|
return {
|
|
2002
2310
|
filePath,
|
|
@@ -2008,129 +2316,6 @@ function compileBlock(definition, filePath) {
|
|
|
2008
2316
|
tags: definition.tags
|
|
2009
2317
|
};
|
|
2010
2318
|
}
|
|
2011
|
-
var compileRecipe = compileBlock;
|
|
2012
|
-
|
|
2013
|
-
// src/storyFilters.ts
|
|
2014
|
-
var EXCLUDED_TAGS = /* @__PURE__ */ new Set(["hidden", "internal", "no-fragment"]);
|
|
2015
|
-
var SVG_ICON_RE = /^Svg[A-Z]/;
|
|
2016
|
-
var TEST_TITLE_RE = /\/tests?$/i;
|
|
2017
|
-
var TEST_FILE_RE = /\.test\.stories\./;
|
|
2018
|
-
var DEPRECATED_TITLE_RE = /\bDeprecated\b/i;
|
|
2019
|
-
function checkStoryExclusion(opts) {
|
|
2020
|
-
const { config } = opts;
|
|
2021
|
-
if (isForceIncluded(opts.componentName, config)) {
|
|
2022
|
-
return { excluded: false };
|
|
2023
|
-
}
|
|
2024
|
-
if (isConfigExcluded(opts.componentName, config)) {
|
|
2025
|
-
return {
|
|
2026
|
-
excluded: true,
|
|
2027
|
-
reason: "config-excluded",
|
|
2028
|
-
detail: `'${opts.componentName}' matches storybook.exclude pattern`
|
|
2029
|
-
};
|
|
2030
|
-
}
|
|
2031
|
-
if (config.excludeDeprecated !== false && opts.storybookTitle && DEPRECATED_TITLE_RE.test(opts.storybookTitle)) {
|
|
2032
|
-
return {
|
|
2033
|
-
excluded: true,
|
|
2034
|
-
reason: "deprecated",
|
|
2035
|
-
detail: `Title "${opts.storybookTitle}" contains "Deprecated"`
|
|
2036
|
-
};
|
|
2037
|
-
}
|
|
2038
|
-
if (config.excludeTests !== false) {
|
|
2039
|
-
if (opts.storybookTitle && TEST_TITLE_RE.test(opts.storybookTitle)) {
|
|
2040
|
-
return {
|
|
2041
|
-
excluded: true,
|
|
2042
|
-
reason: "test-story",
|
|
2043
|
-
detail: `Title "${opts.storybookTitle}" ends with /test(s)`
|
|
2044
|
-
};
|
|
2045
|
-
}
|
|
2046
|
-
if (TEST_FILE_RE.test(opts.filePath)) {
|
|
2047
|
-
return {
|
|
2048
|
-
excluded: true,
|
|
2049
|
-
reason: "test-story",
|
|
2050
|
-
detail: `File path matches *.test.stories.*`
|
|
2051
|
-
};
|
|
2052
|
-
}
|
|
2053
|
-
}
|
|
2054
|
-
if (config.excludeSvgIcons !== false) {
|
|
2055
|
-
const names = [opts.componentName, opts.componentDisplayName, opts.componentFunctionName].filter(Boolean);
|
|
2056
|
-
for (const name of names) {
|
|
2057
|
-
if (SVG_ICON_RE.test(name)) {
|
|
2058
|
-
return {
|
|
2059
|
-
excluded: true,
|
|
2060
|
-
reason: "svg-icon",
|
|
2061
|
-
detail: `Component name "${name}" matches Svg[A-Z] pattern`
|
|
2062
|
-
};
|
|
2063
|
-
}
|
|
2064
|
-
}
|
|
2065
|
-
}
|
|
2066
|
-
if (opts.tags?.length) {
|
|
2067
|
-
const hit = opts.tags.find((t) => EXCLUDED_TAGS.has(t));
|
|
2068
|
-
if (hit) {
|
|
2069
|
-
return {
|
|
2070
|
-
excluded: true,
|
|
2071
|
-
reason: "tag-excluded",
|
|
2072
|
-
detail: `Tag "${hit}" is in the exclusion set`
|
|
2073
|
-
};
|
|
2074
|
-
}
|
|
2075
|
-
}
|
|
2076
|
-
if (opts.variantCount === 0) {
|
|
2077
|
-
return {
|
|
2078
|
-
excluded: true,
|
|
2079
|
-
reason: "empty-variants",
|
|
2080
|
-
detail: "Zero renderable story exports"
|
|
2081
|
-
};
|
|
2082
|
-
}
|
|
2083
|
-
return { excluded: false };
|
|
2084
|
-
}
|
|
2085
|
-
function detectSubComponentPaths(storyFiles) {
|
|
2086
|
-
const byDir = /* @__PURE__ */ new Map();
|
|
2087
|
-
for (const file of storyFiles) {
|
|
2088
|
-
const parts = file.relativePath.split("/");
|
|
2089
|
-
if (parts.length < 2) continue;
|
|
2090
|
-
const fileName = parts[parts.length - 1];
|
|
2091
|
-
const baseMatch = fileName.match(/^([^.]+)\.stories\./);
|
|
2092
|
-
if (!baseMatch) continue;
|
|
2093
|
-
const dir = parts.slice(0, -1).join("/");
|
|
2094
|
-
const baseName = baseMatch[1];
|
|
2095
|
-
if (!byDir.has(dir)) byDir.set(dir, []);
|
|
2096
|
-
byDir.get(dir).push({ relativePath: file.relativePath, baseName });
|
|
2097
|
-
}
|
|
2098
|
-
const subComponentMap = /* @__PURE__ */ new Map();
|
|
2099
|
-
for (const [dir, files] of byDir) {
|
|
2100
|
-
if (files.length <= 1) continue;
|
|
2101
|
-
const dirName = dir.split("/").pop();
|
|
2102
|
-
const primary = files.find((f) => f.baseName === dirName);
|
|
2103
|
-
if (!primary) continue;
|
|
2104
|
-
for (const file of files) {
|
|
2105
|
-
if (file.relativePath === primary.relativePath) continue;
|
|
2106
|
-
subComponentMap.set(file.relativePath, primary.baseName);
|
|
2107
|
-
}
|
|
2108
|
-
}
|
|
2109
|
-
return subComponentMap;
|
|
2110
|
-
}
|
|
2111
|
-
function isForceIncluded(name, config) {
|
|
2112
|
-
if (!config.include?.length) return false;
|
|
2113
|
-
return config.include.some((pattern) => matchesPattern(name, pattern));
|
|
2114
|
-
}
|
|
2115
|
-
function isConfigExcluded(name, config) {
|
|
2116
|
-
if (!config.exclude?.length) return false;
|
|
2117
|
-
return config.exclude.some((pattern) => matchesPattern(name, pattern));
|
|
2118
|
-
}
|
|
2119
|
-
function matchesPattern(name, pattern) {
|
|
2120
|
-
if (!pattern.includes("*")) {
|
|
2121
|
-
return name === pattern;
|
|
2122
|
-
}
|
|
2123
|
-
const parts = pattern.split("*");
|
|
2124
|
-
if (parts.length === 2) {
|
|
2125
|
-
const [prefix, suffix] = parts;
|
|
2126
|
-
if (prefix && suffix) return name.startsWith(prefix) && name.endsWith(suffix);
|
|
2127
|
-
if (prefix) return name.startsWith(prefix);
|
|
2128
|
-
if (suffix) return name.endsWith(suffix);
|
|
2129
|
-
return true;
|
|
2130
|
-
}
|
|
2131
|
-
const escaped = parts.map((p) => p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join(".*");
|
|
2132
|
-
return new RegExp(`^${escaped}$`).test(name);
|
|
2133
|
-
}
|
|
2134
2319
|
|
|
2135
2320
|
// src/figma.ts
|
|
2136
2321
|
function string(figmaProperty) {
|
|
@@ -3694,24 +3879,37 @@ var contractExampleSchema = z6.object({
|
|
|
3694
3879
|
});
|
|
3695
3880
|
var contractRelationSchema = z6.object({
|
|
3696
3881
|
component: z6.string(),
|
|
3697
|
-
relationship: z6.enum([
|
|
3882
|
+
relationship: z6.enum([
|
|
3883
|
+
"alternative",
|
|
3884
|
+
"parent",
|
|
3885
|
+
"child",
|
|
3886
|
+
"sibling",
|
|
3887
|
+
"composition",
|
|
3888
|
+
"complementary",
|
|
3889
|
+
"used-by"
|
|
3890
|
+
]),
|
|
3698
3891
|
note: z6.string()
|
|
3699
3892
|
});
|
|
3700
3893
|
var contractContractSchema = z6.object({
|
|
3701
3894
|
propsSummary: z6.array(z6.string()).optional(),
|
|
3702
3895
|
scenarioTags: z6.array(z6.string()).optional(),
|
|
3703
3896
|
a11yRules: z6.array(z6.string()).optional(),
|
|
3704
|
-
bans: z6.array(
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3897
|
+
bans: z6.array(
|
|
3898
|
+
z6.object({
|
|
3899
|
+
pattern: z6.string(),
|
|
3900
|
+
message: z6.string()
|
|
3901
|
+
})
|
|
3902
|
+
).optional(),
|
|
3903
|
+
compoundChildren: z6.record(
|
|
3904
|
+
z6.string(),
|
|
3905
|
+
z6.object({
|
|
3906
|
+
required: z6.boolean().optional(),
|
|
3907
|
+
accepts: z6.array(z6.string()).optional(),
|
|
3908
|
+
description: z6.string().optional()
|
|
3909
|
+
})
|
|
3910
|
+
).optional(),
|
|
3713
3911
|
canonicalUsage: z6.array(z6.string()).optional(),
|
|
3714
|
-
performanceBudget: z6.number().optional()
|
|
3912
|
+
performanceBudget: z6.number().positive().finite().optional()
|
|
3715
3913
|
});
|
|
3716
3914
|
var contractAiSchema = z6.object({
|
|
3717
3915
|
compositionPattern: z6.enum(["compound", "simple", "controlled", "wrapper"]).optional(),
|
|
@@ -3735,11 +3933,14 @@ var contractProvenanceSchema = z6.object({
|
|
|
3735
3933
|
});
|
|
3736
3934
|
var contractFigmaSchema = z6.object({
|
|
3737
3935
|
nodeUrl: z6.string().optional(),
|
|
3738
|
-
propMappings: z6.record(
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3936
|
+
propMappings: z6.record(
|
|
3937
|
+
z6.string(),
|
|
3938
|
+
z6.object({
|
|
3939
|
+
type: z6.enum(["string", "boolean", "enum", "instance", "children", "textContent"]),
|
|
3940
|
+
figmaProperty: z6.string(),
|
|
3941
|
+
values: z6.record(z6.string(), z6.string()).optional()
|
|
3942
|
+
})
|
|
3943
|
+
).optional()
|
|
3743
3944
|
});
|
|
3744
3945
|
var componentContractSchema = z6.object({
|
|
3745
3946
|
$schema: z6.string(),
|
|
@@ -3749,11 +3950,13 @@ var componentContractSchema = z6.object({
|
|
|
3749
3950
|
tags: z6.array(z6.string()).optional(),
|
|
3750
3951
|
status: z6.enum(["stable", "beta", "deprecated", "experimental"]).optional(),
|
|
3751
3952
|
framework: z6.enum(["react", "vue", "svelte", "web-components", "angular"]).optional(),
|
|
3752
|
-
dependencies: z6.array(
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3953
|
+
dependencies: z6.array(
|
|
3954
|
+
z6.object({
|
|
3955
|
+
name: z6.string(),
|
|
3956
|
+
version: z6.string(),
|
|
3957
|
+
reason: z6.string().optional()
|
|
3958
|
+
})
|
|
3959
|
+
).optional(),
|
|
3757
3960
|
sourcePath: z6.string(),
|
|
3758
3961
|
exportName: z6.string(),
|
|
3759
3962
|
propsSummary: z6.array(z6.string()),
|
|
@@ -3804,6 +4007,8 @@ function parseComponentContract(content, filePath) {
|
|
|
3804
4007
|
} : {
|
|
3805
4008
|
propsSummary: validated.propsSummary
|
|
3806
4009
|
},
|
|
4010
|
+
preview: validated.preview,
|
|
4011
|
+
tokens: validated.tokens,
|
|
3807
4012
|
framework: validated.framework,
|
|
3808
4013
|
ai: validated.ai,
|
|
3809
4014
|
propsSummary: validated.propsSummary,
|
|
@@ -4015,6 +4220,7 @@ function parseFigmaValue(cssValue, category) {
|
|
|
4015
4220
|
// src/composition.ts
|
|
4016
4221
|
var CATEGORY_AFFINITIES = {
|
|
4017
4222
|
forms: ["feedback"],
|
|
4223
|
+
inputs: ["feedback"],
|
|
4018
4224
|
actions: ["feedback"]
|
|
4019
4225
|
};
|
|
4020
4226
|
function analyzeComposition(fragments, componentNames, _context, options) {
|
|
@@ -4120,9 +4326,7 @@ function analyzeComposition(fragments, componentNames, _context, options) {
|
|
|
4120
4326
|
});
|
|
4121
4327
|
}
|
|
4122
4328
|
}
|
|
4123
|
-
const selectedCategories = new Set(
|
|
4124
|
-
components.map((name) => fragments[name].meta.category)
|
|
4125
|
-
);
|
|
4329
|
+
const selectedCategories = new Set(components.map((name) => fragments[name].meta.category));
|
|
4126
4330
|
for (const [category, affinities] of Object.entries(CATEGORY_AFFINITIES)) {
|
|
4127
4331
|
if (!selectedCategories.has(category)) continue;
|
|
4128
4332
|
for (const neededCategory of affinities) {
|
|
@@ -4138,9 +4342,7 @@ function analyzeComposition(fragments, componentNames, _context, options) {
|
|
|
4138
4342
|
component: candidate,
|
|
4139
4343
|
reason: `Compositions using "${category}" components often benefit from a "${neededCategory}" component`,
|
|
4140
4344
|
relationship: "category_gap",
|
|
4141
|
-
sourceComponent: components.find(
|
|
4142
|
-
(n) => fragments[n].meta.category === category
|
|
4143
|
-
)
|
|
4345
|
+
sourceComponent: components.find((n) => fragments[n].meta.category === category)
|
|
4144
4346
|
});
|
|
4145
4347
|
suggestedSet.add(candidate);
|
|
4146
4348
|
}
|
|
@@ -4263,7 +4465,7 @@ function makeFinding(input) {
|
|
|
4263
4465
|
canonicalJson({ ruleId: input.ruleId, ...input.fingerprintIdentity })
|
|
4264
4466
|
);
|
|
4265
4467
|
const previousFingerprint = input.previousFingerprintIdentity ? hash64Hex(canonicalJson({ ruleId: input.ruleId, ...input.previousFingerprintIdentity })) : void 0;
|
|
4266
|
-
const code = byRuleId.get(input.ruleId);
|
|
4468
|
+
const code = input.code ? byCode.get(input.code) : byRuleId.get(input.ruleId);
|
|
4267
4469
|
return normalizeFinding({
|
|
4268
4470
|
ruleId: input.ruleId,
|
|
4269
4471
|
ruleVersion: input.ruleVersion,
|
|
@@ -8374,6 +8576,14 @@ function indexTokensByCssVariable(tokens) {
|
|
|
8374
8576
|
// src/rules/tokens-css-vars-must-be-defined.ts
|
|
8375
8577
|
var RULE_ID22 = "tokens/css-vars-must-be-defined";
|
|
8376
8578
|
var RULE_VERSION23 = "1";
|
|
8579
|
+
var EMPTY_VOCABULARY_CODE = "FUI2018";
|
|
8580
|
+
var EMPTY_VOCABULARY_MESSAGE = "token sources resolved to 0 tokens \u2014 rule inert";
|
|
8581
|
+
var EMPTY_VOCABULARY_CONFIG_FALLBACK = "your fragments config";
|
|
8582
|
+
function emptyVocabularyConfigFile(configPath2) {
|
|
8583
|
+
if (!configPath2) return EMPTY_VOCABULARY_CONFIG_FALLBACK;
|
|
8584
|
+
const base = configPath2.replaceAll("\\", "/").replace(/\/+$/u, "").split("/").pop();
|
|
8585
|
+
return base && base.length > 0 ? base : EMPTY_VOCABULARY_CONFIG_FALLBACK;
|
|
8586
|
+
}
|
|
8377
8587
|
var CSS_VAR_REFERENCE = /var\(\s*(--[A-Za-z0-9_-]+)/gi;
|
|
8378
8588
|
function contractVocabularyContext(ix) {
|
|
8379
8589
|
if (!ix.policy.cssVarsMustBeDefined()) return void 0;
|
|
@@ -8395,7 +8605,7 @@ function ruleTokensCssVarsMustBeDefined(ix) {
|
|
|
8395
8605
|
const policy = ix.policy.cssVarsMustBeDefined();
|
|
8396
8606
|
if (!policy) return [];
|
|
8397
8607
|
const context = contractVocabularyContext(ix);
|
|
8398
|
-
if (!context) return [];
|
|
8608
|
+
if (!context) return [emptyVocabularyFinding(ix, policy)];
|
|
8399
8609
|
const { vocabulary } = context;
|
|
8400
8610
|
const findings = [];
|
|
8401
8611
|
for (const decl of ix.byKind("style_declaration")) {
|
|
@@ -8436,6 +8646,27 @@ function ruleTokensCssVarsMustBeDefined(ix) {
|
|
|
8436
8646
|
}
|
|
8437
8647
|
return findings;
|
|
8438
8648
|
}
|
|
8649
|
+
function emptyVocabularyFinding(ix, policy) {
|
|
8650
|
+
return makeFinding({
|
|
8651
|
+
ruleId: RULE_ID22,
|
|
8652
|
+
ruleVersion: RULE_VERSION23,
|
|
8653
|
+
severity: "error",
|
|
8654
|
+
code: EMPTY_VOCABULARY_CODE,
|
|
8655
|
+
message: EMPTY_VOCABULARY_MESSAGE,
|
|
8656
|
+
location: {
|
|
8657
|
+
file: policy.configPath ?? EMPTY_VOCABULARY_CONFIG_FALLBACK,
|
|
8658
|
+
line: 0,
|
|
8659
|
+
column: 0
|
|
8660
|
+
},
|
|
8661
|
+
evidence: ix.evidence([policy.id]),
|
|
8662
|
+
fingerprintIdentity: { reason: "empty-vocabulary" },
|
|
8663
|
+
attributes: {
|
|
8664
|
+
source: "config",
|
|
8665
|
+
inert: true,
|
|
8666
|
+
tokenCount: 0
|
|
8667
|
+
}
|
|
8668
|
+
});
|
|
8669
|
+
}
|
|
8439
8670
|
function sharesContractPrefix(name, prefixes) {
|
|
8440
8671
|
for (const prefix of prefixes) {
|
|
8441
8672
|
if (name.startsWith(prefix)) return true;
|
|
@@ -8526,6 +8757,30 @@ function ruleTokensUpstreamDrift(ix) {
|
|
|
8526
8757
|
return findings;
|
|
8527
8758
|
}
|
|
8528
8759
|
|
|
8760
|
+
// src/rules/rule-config.ts
|
|
8761
|
+
function readRuleConfig(ix) {
|
|
8762
|
+
const disabled = /* @__PURE__ */ new Set();
|
|
8763
|
+
const severities = /* @__PURE__ */ new Map();
|
|
8764
|
+
for (const fact of ix.byKind("governance_rule_config")) {
|
|
8765
|
+
if (!fact.enabled) {
|
|
8766
|
+
disabled.add(fact.ruleId);
|
|
8767
|
+
continue;
|
|
8768
|
+
}
|
|
8769
|
+
if (fact.severity) severities.set(fact.ruleId, fact.severity);
|
|
8770
|
+
}
|
|
8771
|
+
return { disabled, severities };
|
|
8772
|
+
}
|
|
8773
|
+
function capConfiguredSeverity(finding, configured) {
|
|
8774
|
+
if (finding.attributes?.advisory === true && severityLevel(configured) === "error") {
|
|
8775
|
+
return severityLevel(finding.severity) === "error" ? severityFromLevel("warn") : finding.severity;
|
|
8776
|
+
}
|
|
8777
|
+
return configured;
|
|
8778
|
+
}
|
|
8779
|
+
function configuredFindingSeverity(finding, config) {
|
|
8780
|
+
const configured = config.severities.get(finding.ruleId);
|
|
8781
|
+
return configured ? capConfiguredSeverity(finding, severityFromLevel(configured)) : finding.severity;
|
|
8782
|
+
}
|
|
8783
|
+
|
|
8529
8784
|
// src/rules/emit-gate.ts
|
|
8530
8785
|
var BLOCKING_RULE_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
8531
8786
|
"styles/no-raw-color",
|
|
@@ -8778,8 +9033,12 @@ var RULES = [
|
|
|
8778
9033
|
}
|
|
8779
9034
|
];
|
|
8780
9035
|
function runRules(ix) {
|
|
9036
|
+
const { disabled } = readRuleConfig(ix);
|
|
8781
9037
|
const findings = [];
|
|
8782
|
-
for (const rule of RULES)
|
|
9038
|
+
for (const rule of RULES) {
|
|
9039
|
+
if (disabled.has(rule.id)) continue;
|
|
9040
|
+
findings.push(...rule.run(ix));
|
|
9041
|
+
}
|
|
8783
9042
|
return sortFindings(findings);
|
|
8784
9043
|
}
|
|
8785
9044
|
function sortFindings(findings) {
|
|
@@ -8869,7 +9128,7 @@ var PASSTHROUGH_KEYS = [
|
|
|
8869
9128
|
},
|
|
8870
9129
|
{
|
|
8871
9130
|
path: ["registry"],
|
|
8872
|
-
keys: ["requireStory", "publicOnly", "categoryDepth", "includeProps"
|
|
9131
|
+
keys: ["requireStory", "publicOnly", "categoryDepth", "includeProps"]
|
|
8873
9132
|
},
|
|
8874
9133
|
{
|
|
8875
9134
|
path: ["govern", "tailwind"],
|
|
@@ -9123,11 +9382,11 @@ function collectPassthroughRecordValues(authored, path, allowed, diagnostics) {
|
|
|
9123
9382
|
}
|
|
9124
9383
|
}
|
|
9125
9384
|
function stableConfigDiagnostics(diagnostics) {
|
|
9126
|
-
const
|
|
9385
|
+
const unique2 = /* @__PURE__ */ new Map();
|
|
9127
9386
|
for (const diagnostic of diagnostics) {
|
|
9128
|
-
|
|
9387
|
+
unique2.set(`${diagnostic.code}\0${diagnostic.path}`, diagnostic);
|
|
9129
9388
|
}
|
|
9130
|
-
return [...
|
|
9389
|
+
return [...unique2.values()].sort(
|
|
9131
9390
|
(left, right) => left.path.localeCompare(right.path) || left.code.localeCompare(right.code) || left.message.localeCompare(right.message)
|
|
9132
9391
|
);
|
|
9133
9392
|
}
|
|
@@ -9353,10 +9612,11 @@ function evaluateGovernanceIntegrity(input) {
|
|
|
9353
9612
|
const activeRuleCount = [...configs.entries()].filter(
|
|
9354
9613
|
([ruleId, config]) => CONSUMED_RULE_IDS.has(ruleId) && config.enabled
|
|
9355
9614
|
).length;
|
|
9615
|
+
const tokensVocabularyInert = !tokensArmed && tokensFamily.reason === "no token vocabulary" ? 1 : 0;
|
|
9356
9616
|
const roster = {
|
|
9357
9617
|
configured: configuredRuleCount + configDiagnostics.length,
|
|
9358
|
-
active: activeRuleCount,
|
|
9359
|
-
inert: configDiagnostics.length
|
|
9618
|
+
active: Math.max(0, activeRuleCount - tokensVocabularyInert),
|
|
9619
|
+
inert: configDiagnostics.length + tokensVocabularyInert
|
|
9360
9620
|
};
|
|
9361
9621
|
return {
|
|
9362
9622
|
status,
|
|
@@ -9454,7 +9714,30 @@ function sortRecords(values) {
|
|
|
9454
9714
|
}
|
|
9455
9715
|
|
|
9456
9716
|
// src/contract/preimage.ts
|
|
9717
|
+
var CONTRACT_ENFORCEMENT_FIELDS = [
|
|
9718
|
+
"a11yRules",
|
|
9719
|
+
"bans",
|
|
9720
|
+
"performanceBudget",
|
|
9721
|
+
"compoundChildren",
|
|
9722
|
+
"composition"
|
|
9723
|
+
];
|
|
9724
|
+
var CONTRACT_DISPLAY_ONLY_FIELDS = [
|
|
9725
|
+
"propsSummary",
|
|
9726
|
+
"canonicalUsage",
|
|
9727
|
+
"scenarioTags",
|
|
9728
|
+
"states",
|
|
9729
|
+
"variants"
|
|
9730
|
+
];
|
|
9457
9731
|
var CONTRACT_DOMAINS = ["components", "tokens", "canonicalMap", "policy"];
|
|
9732
|
+
var ContractCatalogValidationError = class extends TypeError {
|
|
9733
|
+
issues;
|
|
9734
|
+
constructor(issues) {
|
|
9735
|
+
const sortedIssues = [...issues].sort();
|
|
9736
|
+
super(["Invalid contract catalog:", ...sortedIssues.map((issue) => ` - ${issue}`)].join("\n"));
|
|
9737
|
+
this.name = "ContractCatalogValidationError";
|
|
9738
|
+
this.issues = sortedIssues;
|
|
9739
|
+
}
|
|
9740
|
+
};
|
|
9458
9741
|
var CONTRACT_PREIMAGE_SCHEMA = "fcid-preimage:v1";
|
|
9459
9742
|
var CONTRACT_PREIMAGE_CAPABILITY_HEADER = "X-Fragments-Contract-Preimage";
|
|
9460
9743
|
var SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/u;
|
|
@@ -9482,13 +9765,225 @@ function verifiedContractPreimageFromPin(pin) {
|
|
|
9482
9765
|
function sortCanonical(items) {
|
|
9483
9766
|
return items.map((item) => ({ item, key: canonicalPreimage(item) })).sort((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0).map(({ item }) => item);
|
|
9484
9767
|
}
|
|
9768
|
+
function isPlainRecord(value) {
|
|
9769
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
9770
|
+
const prototype = Object.getPrototypeOf(value);
|
|
9771
|
+
return prototype === Object.prototype || prototype === null;
|
|
9772
|
+
}
|
|
9773
|
+
function requireNonEmptyString(value, path, issues) {
|
|
9774
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
9775
|
+
issues.push(`${path}: expected a non-empty string`);
|
|
9776
|
+
}
|
|
9777
|
+
}
|
|
9778
|
+
function validateStringArray(value, path, issues) {
|
|
9779
|
+
if (!Array.isArray(value)) {
|
|
9780
|
+
issues.push(`${path}: expected an array`);
|
|
9781
|
+
return;
|
|
9782
|
+
}
|
|
9783
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9784
|
+
for (const [index, entry] of value.entries()) {
|
|
9785
|
+
requireNonEmptyString(entry, `${path}[${index}]`, issues);
|
|
9786
|
+
if (typeof entry === "string" && entry.length > 0) {
|
|
9787
|
+
if (seen.has(entry)) issues.push(`${path}: duplicate value "${entry}"`);
|
|
9788
|
+
seen.add(entry);
|
|
9789
|
+
}
|
|
9790
|
+
}
|
|
9791
|
+
}
|
|
9792
|
+
function validateContractCatalog(catalog) {
|
|
9793
|
+
const issues = [];
|
|
9794
|
+
if (!isPlainRecord(catalog)) {
|
|
9795
|
+
throw new ContractCatalogValidationError(["(root): expected a plain object"]);
|
|
9796
|
+
}
|
|
9797
|
+
const componentIdentities = /* @__PURE__ */ new Set();
|
|
9798
|
+
if (catalog.components !== void 0) {
|
|
9799
|
+
if (!Array.isArray(catalog.components)) {
|
|
9800
|
+
issues.push("components: expected an array");
|
|
9801
|
+
} else {
|
|
9802
|
+
for (const [index, value] of catalog.components.entries()) {
|
|
9803
|
+
const path = `components[${index}]`;
|
|
9804
|
+
if (!isPlainRecord(value)) {
|
|
9805
|
+
issues.push(`${path}: expected a plain object`);
|
|
9806
|
+
continue;
|
|
9807
|
+
}
|
|
9808
|
+
requireNonEmptyString(value.name, `${path}.name`, issues);
|
|
9809
|
+
if (value.parentName !== void 0) {
|
|
9810
|
+
requireNonEmptyString(value.parentName, `${path}.parentName`, issues);
|
|
9811
|
+
}
|
|
9812
|
+
if (typeof value.name === "string" && value.name.length > 0) {
|
|
9813
|
+
const identity = `${typeof value.parentName === "string" ? value.parentName : ""}#${value.name}`;
|
|
9814
|
+
if (componentIdentities.has(identity)) {
|
|
9815
|
+
issues.push(`components: duplicate identity "${identity}"`);
|
|
9816
|
+
}
|
|
9817
|
+
componentIdentities.add(identity);
|
|
9818
|
+
}
|
|
9819
|
+
if (value.props !== void 0) validateStringArray(value.props, `${path}.props`, issues);
|
|
9820
|
+
if (value.compoundChildren !== void 0) {
|
|
9821
|
+
validateStringArray(value.compoundChildren, `${path}.compoundChildren`, issues);
|
|
9822
|
+
}
|
|
9823
|
+
if (value.contract !== void 0 && !isPlainRecord(value.contract)) {
|
|
9824
|
+
issues.push(`${path}.contract: expected a plain object`);
|
|
9825
|
+
}
|
|
9826
|
+
if (value.governance !== void 0 && !Array.isArray(value.governance)) {
|
|
9827
|
+
issues.push(`${path}.governance: expected an array`);
|
|
9828
|
+
}
|
|
9829
|
+
}
|
|
9830
|
+
}
|
|
9831
|
+
}
|
|
9832
|
+
const tokenNames = /* @__PURE__ */ new Set();
|
|
9833
|
+
if (catalog.tokens !== void 0) {
|
|
9834
|
+
if (!Array.isArray(catalog.tokens)) {
|
|
9835
|
+
issues.push("tokens: expected an array");
|
|
9836
|
+
} else {
|
|
9837
|
+
for (const [index, value] of catalog.tokens.entries()) {
|
|
9838
|
+
const path = `tokens[${index}]`;
|
|
9839
|
+
if (!isPlainRecord(value)) {
|
|
9840
|
+
issues.push(`${path}: expected a plain object`);
|
|
9841
|
+
continue;
|
|
9842
|
+
}
|
|
9843
|
+
requireNonEmptyString(value.name, `${path}.name`, issues);
|
|
9844
|
+
if (typeof value.name === "string" && value.name.length > 0) {
|
|
9845
|
+
if (tokenNames.has(value.name)) issues.push(`tokens: duplicate identity "${value.name}"`);
|
|
9846
|
+
tokenNames.add(value.name);
|
|
9847
|
+
}
|
|
9848
|
+
if (typeof value.value !== "string" && typeof value.value !== "number" || typeof value.value === "number" && !Number.isFinite(value.value)) {
|
|
9849
|
+
issues.push(`${path}.value: expected a finite number or string`);
|
|
9850
|
+
}
|
|
9851
|
+
if (value.type !== void 0) requireNonEmptyString(value.type, `${path}.type`, issues);
|
|
9852
|
+
}
|
|
9853
|
+
}
|
|
9854
|
+
}
|
|
9855
|
+
const confirmedMappings = /* @__PURE__ */ new Set();
|
|
9856
|
+
if (catalog.canonicalMappings !== void 0) {
|
|
9857
|
+
if (!Array.isArray(catalog.canonicalMappings)) {
|
|
9858
|
+
issues.push("canonicalMappings: expected an array");
|
|
9859
|
+
} else {
|
|
9860
|
+
for (const [index, value] of catalog.canonicalMappings.entries()) {
|
|
9861
|
+
const path = `canonicalMappings[${index}]`;
|
|
9862
|
+
if (!isPlainRecord(value)) {
|
|
9863
|
+
issues.push(`${path}: expected a plain object`);
|
|
9864
|
+
continue;
|
|
9865
|
+
}
|
|
9866
|
+
requireNonEmptyString(value.component, `${path}.component`, issues);
|
|
9867
|
+
requireNonEmptyString(value.canonical, `${path}.canonical`, issues);
|
|
9868
|
+
if (!["confirmed", "proposed", "unknown"].includes(value.status)) {
|
|
9869
|
+
issues.push(`${path}.status: expected confirmed, proposed, or unknown`);
|
|
9870
|
+
}
|
|
9871
|
+
if (value.status === "confirmed" && typeof value.component === "string") {
|
|
9872
|
+
if (confirmedMappings.has(value.component)) {
|
|
9873
|
+
issues.push(`canonicalMappings: duplicate confirmed identity "${value.component}"`);
|
|
9874
|
+
}
|
|
9875
|
+
confirmedMappings.add(value.component);
|
|
9876
|
+
}
|
|
9877
|
+
if (value.importPath !== void 0) {
|
|
9878
|
+
requireNonEmptyString(value.importPath, `${path}.importPath`, issues);
|
|
9879
|
+
}
|
|
9880
|
+
if (value.propMapping !== void 0 && !Array.isArray(value.propMapping)) {
|
|
9881
|
+
issues.push(`${path}.propMapping: expected an array`);
|
|
9882
|
+
}
|
|
9883
|
+
if (value.resolves !== void 0 && !Array.isArray(value.resolves)) {
|
|
9884
|
+
issues.push(`${path}.resolves: expected an array`);
|
|
9885
|
+
}
|
|
9886
|
+
if (value.bridge !== void 0 && !isPlainRecord(value.bridge)) {
|
|
9887
|
+
issues.push(`${path}.bridge: expected a plain object`);
|
|
9888
|
+
}
|
|
9889
|
+
}
|
|
9890
|
+
}
|
|
9891
|
+
}
|
|
9892
|
+
if (catalog.policy !== void 0 && catalog.policy !== null) {
|
|
9893
|
+
if (!isPlainRecord(catalog.policy)) {
|
|
9894
|
+
issues.push("policy: expected a plain object or null");
|
|
9895
|
+
} else {
|
|
9896
|
+
if (catalog.policy.rules !== void 0 && !isPlainRecord(catalog.policy.rules)) {
|
|
9897
|
+
issues.push("policy.rules: expected a plain object");
|
|
9898
|
+
}
|
|
9899
|
+
if (catalog.policy.codes !== void 0 && !isPlainRecord(catalog.policy.codes)) {
|
|
9900
|
+
issues.push("policy.codes: expected a plain object");
|
|
9901
|
+
}
|
|
9902
|
+
if (catalog.policy.compositionPatterns !== void 0 && !Array.isArray(catalog.policy.compositionPatterns)) {
|
|
9903
|
+
issues.push("policy.compositionPatterns: expected an array");
|
|
9904
|
+
}
|
|
9905
|
+
if (catalog.policy.waivers !== void 0) {
|
|
9906
|
+
if (!Array.isArray(catalog.policy.waivers)) {
|
|
9907
|
+
issues.push("policy.waivers: expected an array");
|
|
9908
|
+
} else {
|
|
9909
|
+
const waiverIds = /* @__PURE__ */ new Set();
|
|
9910
|
+
for (const [index, value] of catalog.policy.waivers.entries()) {
|
|
9911
|
+
const path = `policy.waivers[${index}]`;
|
|
9912
|
+
if (!isPlainRecord(value)) {
|
|
9913
|
+
issues.push(`${path}: expected a plain object`);
|
|
9914
|
+
continue;
|
|
9915
|
+
}
|
|
9916
|
+
requireNonEmptyString(value.id, `${path}.id`, issues);
|
|
9917
|
+
requireNonEmptyString(value.target, `${path}.target`, issues);
|
|
9918
|
+
requireNonEmptyString(value.reason, `${path}.reason`, issues);
|
|
9919
|
+
if (value.expiresOn !== void 0) {
|
|
9920
|
+
requireNonEmptyString(value.expiresOn, `${path}.expiresOn`, issues);
|
|
9921
|
+
}
|
|
9922
|
+
if (typeof value.id === "string" && value.id.length > 0) {
|
|
9923
|
+
if (waiverIds.has(value.id)) {
|
|
9924
|
+
issues.push(`policy.waivers: duplicate identity "${value.id}"`);
|
|
9925
|
+
}
|
|
9926
|
+
waiverIds.add(value.id);
|
|
9927
|
+
}
|
|
9928
|
+
}
|
|
9929
|
+
}
|
|
9930
|
+
}
|
|
9931
|
+
}
|
|
9932
|
+
}
|
|
9933
|
+
if (issues.length > 0) throw new ContractCatalogValidationError(issues);
|
|
9934
|
+
}
|
|
9935
|
+
function projectEnforcementContract(contract) {
|
|
9936
|
+
if (!contract || typeof contract !== "object" || Array.isArray(contract)) {
|
|
9937
|
+
return void 0;
|
|
9938
|
+
}
|
|
9939
|
+
const source = contract;
|
|
9940
|
+
const projected = {};
|
|
9941
|
+
if (Array.isArray(source.a11yRules)) {
|
|
9942
|
+
projected.a11yRules = sortCanonical([...source.a11yRules]);
|
|
9943
|
+
}
|
|
9944
|
+
if (Array.isArray(source.bans)) {
|
|
9945
|
+
projected.bans = sortCanonical([...source.bans]);
|
|
9946
|
+
}
|
|
9947
|
+
if (typeof source.performanceBudget === "number") {
|
|
9948
|
+
projected.performanceBudget = source.performanceBudget;
|
|
9949
|
+
}
|
|
9950
|
+
if (Array.isArray(source.composition)) {
|
|
9951
|
+
projected.composition = sortCanonical([...source.composition]);
|
|
9952
|
+
}
|
|
9953
|
+
const compoundChildren = projectContractCompoundChildren(source.compoundChildren);
|
|
9954
|
+
if (compoundChildren !== void 0) {
|
|
9955
|
+
projected.compoundChildren = compoundChildren;
|
|
9956
|
+
}
|
|
9957
|
+
return Object.keys(projected).length > 0 ? projected : void 0;
|
|
9958
|
+
}
|
|
9959
|
+
function projectContractCompoundChildren(value) {
|
|
9960
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
9961
|
+
const entries = Object.entries(value).map(([name, raw]) => {
|
|
9962
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
9963
|
+
return [name, {}];
|
|
9964
|
+
}
|
|
9965
|
+
const child = raw;
|
|
9966
|
+
const projected = {};
|
|
9967
|
+
if (typeof child.required === "boolean") projected.required = child.required;
|
|
9968
|
+
if (Array.isArray(child.accepts)) {
|
|
9969
|
+
projected.accepts = [...child.accepts].filter((entry) => typeof entry === "string").sort();
|
|
9970
|
+
}
|
|
9971
|
+
return [name, projected];
|
|
9972
|
+
}).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
9973
|
+
return Object.fromEntries(entries);
|
|
9974
|
+
}
|
|
9975
|
+
function projectGovernanceRecords(records) {
|
|
9976
|
+
if (!records || records.length === 0) return void 0;
|
|
9977
|
+
return sortCanonical([...records]);
|
|
9978
|
+
}
|
|
9485
9979
|
function projectComponents(components) {
|
|
9486
9980
|
return sortCanonical(
|
|
9487
9981
|
(components ?? []).map((component) => ({
|
|
9488
9982
|
name: component.name,
|
|
9489
9983
|
parentName: component.parentName,
|
|
9490
9984
|
props: component.props ? [...component.props].sort() : void 0,
|
|
9491
|
-
contract: component.contract,
|
|
9985
|
+
contract: projectEnforcementContract(component.contract),
|
|
9986
|
+
governance: projectGovernanceRecords(component.governance),
|
|
9492
9987
|
compoundChildren: component.compoundChildren ? [...component.compoundChildren].sort() : void 0
|
|
9493
9988
|
}))
|
|
9494
9989
|
);
|
|
@@ -9570,6 +10065,7 @@ function projectPolicy(policy) {
|
|
|
9570
10065
|
};
|
|
9571
10066
|
}
|
|
9572
10067
|
function projectContractPreimage(catalog) {
|
|
10068
|
+
validateContractCatalog(catalog);
|
|
9573
10069
|
return {
|
|
9574
10070
|
schema: CONTRACT_PREIMAGE_SCHEMA,
|
|
9575
10071
|
domains: {
|
|
@@ -9609,16 +10105,31 @@ function contractComponentsFromFragments(fragments) {
|
|
|
9609
10105
|
const parentName = fragment?.meta?.parentComponentName;
|
|
9610
10106
|
const rawChildren = fragment?.structure?.compoundChildren;
|
|
9611
10107
|
const compoundChildren = Array.isArray(rawChildren) ? rawChildren.map((child) => child?.name).filter((childName) => typeof childName === "string") : void 0;
|
|
10108
|
+
const governance = resolveGovernanceRecordsForIdentity({
|
|
10109
|
+
governance: Array.isArray(fragment?.governance) ? fragment.governance : void 0,
|
|
10110
|
+
govern: typeof fragment?.govern === "function" ? fragment.govern : void 0
|
|
10111
|
+
});
|
|
9612
10112
|
components.push({
|
|
9613
10113
|
name,
|
|
9614
10114
|
parentName: typeof parentName === "string" ? parentName : void 0,
|
|
9615
10115
|
props: Object.keys(fragment?.props ?? {}),
|
|
9616
10116
|
contract: fragment?.contract,
|
|
10117
|
+
governance,
|
|
9617
10118
|
compoundChildren
|
|
9618
10119
|
});
|
|
9619
10120
|
}
|
|
9620
10121
|
return components;
|
|
9621
10122
|
}
|
|
10123
|
+
function deriveArtifactId(content) {
|
|
10124
|
+
return artifactContentHash({
|
|
10125
|
+
schema: "artifact-content:v1",
|
|
10126
|
+
modules: content.modules,
|
|
10127
|
+
states: content.states,
|
|
10128
|
+
guidance: content.guidance,
|
|
10129
|
+
render: content.render,
|
|
10130
|
+
runtime: content.runtime
|
|
10131
|
+
});
|
|
10132
|
+
}
|
|
9622
10133
|
|
|
9623
10134
|
// src/contract/stamp.ts
|
|
9624
10135
|
var AGENT_CONTEXT_RELATIVE_PATH = ".fragments/agent-context.md";
|
|
@@ -9650,7 +10161,7 @@ function parseContractStamp(text) {
|
|
|
9650
10161
|
const fcidLine = STAMP_FCID_LINE.exec(text);
|
|
9651
10162
|
if (!header || !fcidLine) return null;
|
|
9652
10163
|
const contractVersion = Number(header[1]);
|
|
9653
|
-
if (!Number.isSafeInteger(contractVersion)) return null;
|
|
10164
|
+
if (!Number.isSafeInteger(contractVersion) || contractVersion < 1) return null;
|
|
9654
10165
|
const fcid = fcidLine[1];
|
|
9655
10166
|
if (!fcid.startsWith(header[2])) return null;
|
|
9656
10167
|
const domainsLine = STAMP_DOMAINS_LINE.exec(text);
|
|
@@ -9936,24 +10447,1492 @@ function strongOverlap(overlap) {
|
|
|
9936
10447
|
function withTarget(state, confidence, canonicalTarget) {
|
|
9937
10448
|
return canonicalTarget ? { state, confidence, canonicalTarget } : { state, confidence };
|
|
9938
10449
|
}
|
|
10450
|
+
|
|
10451
|
+
// src/repository-binding.ts
|
|
10452
|
+
import { z as z8 } from "zod";
|
|
10453
|
+
var REPOSITORY_BINDING_ID_MAX_BYTES_V1 = 256;
|
|
10454
|
+
var PROVIDER_ID_MAX_BYTES_V1 = 64;
|
|
10455
|
+
var utf8Length = (value) => new TextEncoder().encode(value).byteLength;
|
|
10456
|
+
var boundedString = (label, maxBytes) => z8.string().min(1, `${label} is required`).refine((value) => utf8Length(value) <= maxBytes, `${label} exceeds ${maxBytes} UTF-8 bytes`);
|
|
10457
|
+
var providerSchema = boundedString("provider", PROVIDER_ID_MAX_BYTES_V1).transform((value) => value.trim().toLowerCase()).refine(
|
|
10458
|
+
(value) => /^[a-z][a-z0-9_-]*$/u.test(value),
|
|
10459
|
+
"provider must be a bounded lowercase identifier"
|
|
10460
|
+
);
|
|
10461
|
+
function normalizeProviderInstanceId(value) {
|
|
10462
|
+
const trimmed = value.trim();
|
|
10463
|
+
if (trimmed.length === 0) throw new TypeError("providerInstanceId is required");
|
|
10464
|
+
if (trimmed.includes("://")) {
|
|
10465
|
+
const url = new URL(trimmed);
|
|
10466
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
10467
|
+
throw new TypeError("providerInstanceId URL must use http or https");
|
|
10468
|
+
}
|
|
10469
|
+
if (url.username || url.password || url.search || url.hash || url.pathname !== "" && url.pathname !== "/") {
|
|
10470
|
+
throw new TypeError("providerInstanceId must identify an origin, not a path or credential");
|
|
10471
|
+
}
|
|
10472
|
+
return url.host.toLowerCase().replace(/\.$/u, "");
|
|
10473
|
+
}
|
|
10474
|
+
const normalized = trimmed.toLowerCase().replace(/\.$/u, "");
|
|
10475
|
+
if (!/^[a-z0-9](?:[a-z0-9._:-]*[a-z0-9])?$/u.test(normalized)) {
|
|
10476
|
+
throw new TypeError("providerInstanceId must be a normalized origin or tenant key");
|
|
10477
|
+
}
|
|
10478
|
+
return normalized;
|
|
10479
|
+
}
|
|
10480
|
+
var providerInstanceSchema = boundedString(
|
|
10481
|
+
"providerInstanceId",
|
|
10482
|
+
REPOSITORY_BINDING_ID_MAX_BYTES_V1
|
|
10483
|
+
).transform((value, context) => {
|
|
10484
|
+
try {
|
|
10485
|
+
return normalizeProviderInstanceId(value);
|
|
10486
|
+
} catch (error) {
|
|
10487
|
+
context.addIssue({
|
|
10488
|
+
code: z8.ZodIssueCode.custom,
|
|
10489
|
+
message: error instanceof Error ? error.message : String(error)
|
|
10490
|
+
});
|
|
10491
|
+
return z8.NEVER;
|
|
10492
|
+
}
|
|
10493
|
+
});
|
|
10494
|
+
var repositoryBindingKeyV1Schema = z8.object({
|
|
10495
|
+
provider: providerSchema,
|
|
10496
|
+
providerInstanceId: providerInstanceSchema,
|
|
10497
|
+
repositoryExternalId: boundedString("repositoryExternalId", REPOSITORY_BINDING_ID_MAX_BYTES_V1),
|
|
10498
|
+
bindingId: boundedString("bindingId", REPOSITORY_BINDING_ID_MAX_BYTES_V1)
|
|
10499
|
+
}).strict();
|
|
10500
|
+
function normalizeRepositoryBindingKeyV1(value) {
|
|
10501
|
+
return repositoryBindingKeyV1Schema.parse(value);
|
|
10502
|
+
}
|
|
10503
|
+
function repositoryBindingDigestV1(value) {
|
|
10504
|
+
const binding = normalizeRepositoryBindingKeyV1(value);
|
|
10505
|
+
return digestHexSchema.parse(
|
|
10506
|
+
sha256Hex(
|
|
10507
|
+
canonicalPreimage({
|
|
10508
|
+
schema: "repository-binding.v1",
|
|
10509
|
+
provider: binding.provider,
|
|
10510
|
+
providerInstanceId: binding.providerInstanceId,
|
|
10511
|
+
repositoryExternalId: binding.repositoryExternalId,
|
|
10512
|
+
bindingId: binding.bindingId
|
|
10513
|
+
})
|
|
10514
|
+
)
|
|
10515
|
+
);
|
|
10516
|
+
}
|
|
10517
|
+
|
|
10518
|
+
// src/analysis-plan/types.ts
|
|
10519
|
+
import { z as z9 } from "zod";
|
|
10520
|
+
var ANALYSIS_PLAN_MAX_REGIONS_V1 = 1e3;
|
|
10521
|
+
var ANALYSIS_PLAN_MAX_CAPABILITIES_V1 = 256;
|
|
10522
|
+
var ANALYSIS_PLAN_MAX_DIALECTS_PER_REGION_V1 = 64;
|
|
10523
|
+
var ANALYSIS_LIMIT_CEILINGS_V1 = {
|
|
10524
|
+
maxSourceFiles: 1e5,
|
|
10525
|
+
maxSourceBytes: 1073741824,
|
|
10526
|
+
maxFileBytes: 10485760,
|
|
10527
|
+
maxFacts: 1e6,
|
|
10528
|
+
maxRegions: ANALYSIS_PLAN_MAX_REGIONS_V1,
|
|
10529
|
+
maxDiagnostics: 1e5,
|
|
10530
|
+
maxDurationMs: 9e5
|
|
10531
|
+
};
|
|
10532
|
+
var bounded = (max) => z9.string().min(1).max(max);
|
|
10533
|
+
var positiveBoundedInteger = (max) => z9.number().int().positive().max(max);
|
|
10534
|
+
var uniqueStrings = (values) => new Set(values).size === values.length;
|
|
10535
|
+
var coverageStateV1Schema = z9.enum([
|
|
10536
|
+
"analyzed",
|
|
10537
|
+
"unsupported",
|
|
10538
|
+
"excluded_by_contract",
|
|
10539
|
+
"skipped_limit",
|
|
10540
|
+
"failed"
|
|
10541
|
+
]);
|
|
10542
|
+
var analysisLimitsV1Schema = z9.object({
|
|
10543
|
+
maxSourceFiles: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxSourceFiles),
|
|
10544
|
+
maxSourceBytes: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxSourceBytes),
|
|
10545
|
+
maxFileBytes: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxFileBytes),
|
|
10546
|
+
maxFacts: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxFacts),
|
|
10547
|
+
maxRegions: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxRegions),
|
|
10548
|
+
maxDiagnostics: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxDiagnostics),
|
|
10549
|
+
maxDurationMs: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxDurationMs)
|
|
10550
|
+
}).strict();
|
|
10551
|
+
var analysisRegionV1Schema = z9.object({
|
|
10552
|
+
regionId: bounded(256),
|
|
10553
|
+
pathPattern: bounded(4096),
|
|
10554
|
+
kind: z9.enum(["component_source", "style_source", "token_source", "config"]),
|
|
10555
|
+
language: bounded(64),
|
|
10556
|
+
required: z9.boolean(),
|
|
10557
|
+
requiredDialects: z9.array(bounded(128)).max(ANALYSIS_PLAN_MAX_DIALECTS_PER_REGION_V1).refine(uniqueStrings, "requiredDialects must be unique"),
|
|
10558
|
+
analyzer: z9.object({
|
|
10559
|
+
id: bounded(256),
|
|
10560
|
+
interfaceVersion: bounded(128),
|
|
10561
|
+
implementationVersion: bounded(128)
|
|
10562
|
+
}).strict()
|
|
10563
|
+
}).strict();
|
|
10564
|
+
var coverageRegionV1Schema = z9.object({
|
|
10565
|
+
regionId: bounded(256),
|
|
10566
|
+
state: coverageStateV1Schema,
|
|
10567
|
+
fileCount: z9.number().int().nonnegative().max(ANALYSIS_LIMIT_CEILINGS_V1.maxSourceFiles),
|
|
10568
|
+
byteCount: z9.number().int().nonnegative().max(ANALYSIS_LIMIT_CEILINGS_V1.maxSourceBytes),
|
|
10569
|
+
diagnosticIds: z9.array(bounded(256)).max(ANALYSIS_LIMIT_CEILINGS_V1.maxDiagnostics).refine(uniqueStrings, "diagnosticIds must be unique")
|
|
10570
|
+
}).strict();
|
|
10571
|
+
var coverageCountsV1Schema = z9.object({
|
|
10572
|
+
analyzed: z9.number().int().nonnegative(),
|
|
10573
|
+
unsupported: z9.number().int().nonnegative(),
|
|
10574
|
+
excluded_by_contract: z9.number().int().nonnegative(),
|
|
10575
|
+
skipped_limit: z9.number().int().nonnegative(),
|
|
10576
|
+
failed: z9.number().int().nonnegative()
|
|
10577
|
+
}).strict();
|
|
10578
|
+
var coverageSummaryV1Schema = z9.object({
|
|
10579
|
+
plannedRegions: z9.number().int().nonnegative(),
|
|
10580
|
+
observedRegions: z9.number().int().nonnegative(),
|
|
10581
|
+
requiredRegions: z9.number().int().nonnegative(),
|
|
10582
|
+
requiredByState: coverageCountsV1Schema,
|
|
10583
|
+
optionalByState: coverageCountsV1Schema,
|
|
10584
|
+
eligibleFiles: z9.number().int().nonnegative(),
|
|
10585
|
+
analyzedFiles: z9.number().int().nonnegative(),
|
|
10586
|
+
analyzedBytes: z9.number().int().nonnegative()
|
|
10587
|
+
}).strict();
|
|
10588
|
+
var analysisPlanBaseShape = {
|
|
10589
|
+
binding: repositoryBindingKeyV1Schema,
|
|
10590
|
+
source: z9.object({
|
|
10591
|
+
commitId: bounded(256),
|
|
10592
|
+
treeId: bounded(256).optional(),
|
|
10593
|
+
defaultBranch: bounded(256),
|
|
10594
|
+
acquiredBy: z9.enum(["github_app", "local_worktree", "ci_attested"])
|
|
10595
|
+
}).strict(),
|
|
10596
|
+
contract: z9.object({
|
|
10597
|
+
fcid: digestHexStringSchema,
|
|
10598
|
+
artifactDigest: digestHexStringSchema
|
|
10599
|
+
}).strict(),
|
|
10600
|
+
config: z9.object({
|
|
10601
|
+
path: bounded(4096).refine(
|
|
10602
|
+
(value) => !value.startsWith("/") && !value.includes("\\") && !value.split("/").includes(".."),
|
|
10603
|
+
"config path must be a portable repository-relative path"
|
|
10604
|
+
),
|
|
10605
|
+
digest: digestHexStringSchema
|
|
10606
|
+
}).strict(),
|
|
10607
|
+
profile: z9.object({
|
|
10608
|
+
id: z9.literal("react-web-v1"),
|
|
10609
|
+
version: bounded(128),
|
|
10610
|
+
capabilities: z9.array(bounded(128)).max(ANALYSIS_PLAN_MAX_CAPABILITIES_V1).refine(uniqueStrings, "capabilities must be unique")
|
|
10611
|
+
}).strict(),
|
|
10612
|
+
regions: z9.array(analysisRegionV1Schema).max(ANALYSIS_PLAN_MAX_REGIONS_V1).refine(
|
|
10613
|
+
(regions) => new Set(regions.map((region) => region.regionId)).size === regions.length,
|
|
10614
|
+
"regionId values must be unique"
|
|
10615
|
+
),
|
|
10616
|
+
limits: analysisLimitsV1Schema,
|
|
10617
|
+
evaluatorVersion: bounded(128),
|
|
10618
|
+
createdAt: z9.string().datetime({ offset: true })
|
|
10619
|
+
};
|
|
10620
|
+
function validatePlanLimits(plan, context) {
|
|
10621
|
+
if (plan.regions.length > plan.limits.maxRegions) {
|
|
10622
|
+
context.addIssue({
|
|
10623
|
+
code: z9.ZodIssueCode.custom,
|
|
10624
|
+
path: ["regions"],
|
|
10625
|
+
message: "Planned regions exceed the plan's maxRegions limit"
|
|
10626
|
+
});
|
|
10627
|
+
}
|
|
10628
|
+
if (plan.limits.maxFileBytes > plan.limits.maxSourceBytes) {
|
|
10629
|
+
context.addIssue({
|
|
10630
|
+
code: z9.ZodIssueCode.custom,
|
|
10631
|
+
path: ["limits", "maxFileBytes"],
|
|
10632
|
+
message: "maxFileBytes cannot exceed maxSourceBytes"
|
|
10633
|
+
});
|
|
10634
|
+
}
|
|
10635
|
+
}
|
|
10636
|
+
var analysisPlanInputV1Schema = z9.object(analysisPlanBaseShape).strict().superRefine(validatePlanLimits);
|
|
10637
|
+
var analysisPlanV1Schema = z9.object({
|
|
10638
|
+
schemaVersion: z9.literal(1),
|
|
10639
|
+
analysisPlanId: analysisPlanIdStringSchema,
|
|
10640
|
+
...analysisPlanBaseShape,
|
|
10641
|
+
obligationsDigest: digestHexStringSchema,
|
|
10642
|
+
digest: digestHexStringSchema
|
|
10643
|
+
}).strict().superRefine(validatePlanLimits);
|
|
10644
|
+
|
|
10645
|
+
// src/analysis-plan/digest.ts
|
|
10646
|
+
var sortedUnique = (values) => [...new Set(values)].sort();
|
|
10647
|
+
function semanticInput(input) {
|
|
10648
|
+
return {
|
|
10649
|
+
binding: input.binding,
|
|
10650
|
+
source: input.source,
|
|
10651
|
+
contract: input.contract,
|
|
10652
|
+
config: input.config,
|
|
10653
|
+
profile: input.profile,
|
|
10654
|
+
regions: input.regions,
|
|
10655
|
+
limits: input.limits,
|
|
10656
|
+
evaluatorVersion: input.evaluatorVersion,
|
|
10657
|
+
createdAt: input.createdAt
|
|
10658
|
+
};
|
|
10659
|
+
}
|
|
10660
|
+
function normalizeRegion(region) {
|
|
10661
|
+
return {
|
|
10662
|
+
...region,
|
|
10663
|
+
requiredDialects: sortedUnique(region.requiredDialects),
|
|
10664
|
+
analyzer: { ...region.analyzer }
|
|
10665
|
+
};
|
|
10666
|
+
}
|
|
10667
|
+
function normalizeAnalysisPlanInputV1(input) {
|
|
10668
|
+
const semantic = semanticInput(input);
|
|
10669
|
+
const normalized = {
|
|
10670
|
+
...semantic,
|
|
10671
|
+
binding: normalizeRepositoryBindingKeyV1(semantic.binding),
|
|
10672
|
+
source: { ...semantic.source },
|
|
10673
|
+
contract: { ...semantic.contract },
|
|
10674
|
+
config: { ...semantic.config },
|
|
10675
|
+
profile: {
|
|
10676
|
+
...semantic.profile,
|
|
10677
|
+
capabilities: sortedUnique(semantic.profile.capabilities)
|
|
10678
|
+
},
|
|
10679
|
+
regions: semantic.regions.map(normalizeRegion).sort((left, right) => compareCanonicalStrings(left.regionId, right.regionId)),
|
|
10680
|
+
limits: { ...semantic.limits }
|
|
10681
|
+
};
|
|
10682
|
+
return analysisPlanInputV1Schema.parse(normalized);
|
|
10683
|
+
}
|
|
10684
|
+
function obligationsProjection(normalized) {
|
|
10685
|
+
return {
|
|
10686
|
+
schema: "analysis-obligations.v1",
|
|
10687
|
+
bindingDigest: repositoryBindingDigestV1(normalized.binding),
|
|
10688
|
+
contract: normalized.contract,
|
|
10689
|
+
config: normalized.config,
|
|
10690
|
+
profile: normalized.profile,
|
|
10691
|
+
regions: normalized.regions,
|
|
10692
|
+
limits: normalized.limits,
|
|
10693
|
+
evaluatorVersion: normalized.evaluatorVersion
|
|
10694
|
+
};
|
|
10695
|
+
}
|
|
10696
|
+
function exactPlanProjection(normalized) {
|
|
10697
|
+
return {
|
|
10698
|
+
schema: "analysis-plan.v1",
|
|
10699
|
+
bindingDigest: repositoryBindingDigestV1(normalized.binding),
|
|
10700
|
+
source: {
|
|
10701
|
+
commitId: normalized.source.commitId,
|
|
10702
|
+
treeId: normalized.source.treeId,
|
|
10703
|
+
acquiredBy: normalized.source.acquiredBy
|
|
10704
|
+
},
|
|
10705
|
+
contract: normalized.contract,
|
|
10706
|
+
config: normalized.config,
|
|
10707
|
+
profile: normalized.profile,
|
|
10708
|
+
regions: normalized.regions,
|
|
10709
|
+
limits: normalized.limits,
|
|
10710
|
+
evaluatorVersion: normalized.evaluatorVersion
|
|
10711
|
+
};
|
|
10712
|
+
}
|
|
10713
|
+
function analysisObligationsDigestV1(input) {
|
|
10714
|
+
const normalized = normalizeAnalysisPlanInputV1(input);
|
|
10715
|
+
return digestHexSchema.parse(sha256Hex(canonicalPreimage(obligationsProjection(normalized))));
|
|
10716
|
+
}
|
|
10717
|
+
function analysisPlanDigestV1(input) {
|
|
10718
|
+
const normalized = normalizeAnalysisPlanInputV1(input);
|
|
10719
|
+
return digestHexSchema.parse(sha256Hex(canonicalPreimage(exactPlanProjection(normalized))));
|
|
10720
|
+
}
|
|
10721
|
+
function buildAnalysisPlanV1(input) {
|
|
10722
|
+
const normalized = normalizeAnalysisPlanInputV1(input);
|
|
10723
|
+
const digest = digestHexSchema.parse(
|
|
10724
|
+
sha256Hex(canonicalPreimage(exactPlanProjection(normalized)))
|
|
10725
|
+
);
|
|
10726
|
+
return analysisPlanV1Schema.parse({
|
|
10727
|
+
schemaVersion: 1,
|
|
10728
|
+
analysisPlanId: analysisPlanIdFromDigest(digest),
|
|
10729
|
+
...normalized,
|
|
10730
|
+
obligationsDigest: digestHexSchema.parse(
|
|
10731
|
+
sha256Hex(canonicalPreimage(obligationsProjection(normalized)))
|
|
10732
|
+
),
|
|
10733
|
+
digest
|
|
10734
|
+
});
|
|
10735
|
+
}
|
|
10736
|
+
function parseAnalysisPlanV1(value) {
|
|
10737
|
+
const parsed = analysisPlanV1Schema.parse(value);
|
|
10738
|
+
const rebuilt = buildAnalysisPlanV1({
|
|
10739
|
+
binding: parsed.binding,
|
|
10740
|
+
source: parsed.source,
|
|
10741
|
+
contract: parsed.contract,
|
|
10742
|
+
config: parsed.config,
|
|
10743
|
+
profile: parsed.profile,
|
|
10744
|
+
regions: parsed.regions,
|
|
10745
|
+
limits: parsed.limits,
|
|
10746
|
+
evaluatorVersion: parsed.evaluatorVersion,
|
|
10747
|
+
createdAt: parsed.createdAt
|
|
10748
|
+
});
|
|
10749
|
+
if (parsed.analysisPlanId !== rebuilt.analysisPlanId || parsed.digest !== rebuilt.digest || parsed.obligationsDigest !== rebuilt.obligationsDigest) {
|
|
10750
|
+
throw new TypeError("AnalysisPlanV1 derived identity does not match its semantic projection");
|
|
10751
|
+
}
|
|
10752
|
+
return rebuilt;
|
|
10753
|
+
}
|
|
10754
|
+
|
|
10755
|
+
// src/analysis-plan/coverage.ts
|
|
10756
|
+
var COVERAGE_STATES = [
|
|
10757
|
+
"analyzed",
|
|
10758
|
+
"unsupported",
|
|
10759
|
+
"excluded_by_contract",
|
|
10760
|
+
"skipped_limit",
|
|
10761
|
+
"failed"
|
|
10762
|
+
];
|
|
10763
|
+
function emptyCounts() {
|
|
10764
|
+
return {
|
|
10765
|
+
analyzed: 0,
|
|
10766
|
+
unsupported: 0,
|
|
10767
|
+
excluded_by_contract: 0,
|
|
10768
|
+
skipped_limit: 0,
|
|
10769
|
+
failed: 0
|
|
10770
|
+
};
|
|
10771
|
+
}
|
|
10772
|
+
var CoverageValidationErrorV1 = class extends TypeError {
|
|
10773
|
+
constructor(message, duplicateRegionIds = [], unknownRegionIds = [], missingRequiredRegionIds = [], missingOptionalRegionIds = []) {
|
|
10774
|
+
super(message);
|
|
10775
|
+
this.duplicateRegionIds = duplicateRegionIds;
|
|
10776
|
+
this.unknownRegionIds = unknownRegionIds;
|
|
10777
|
+
this.missingRequiredRegionIds = missingRequiredRegionIds;
|
|
10778
|
+
this.missingOptionalRegionIds = missingOptionalRegionIds;
|
|
10779
|
+
this.name = "CoverageValidationErrorV1";
|
|
10780
|
+
}
|
|
10781
|
+
duplicateRegionIds;
|
|
10782
|
+
unknownRegionIds;
|
|
10783
|
+
missingRequiredRegionIds;
|
|
10784
|
+
missingOptionalRegionIds;
|
|
10785
|
+
};
|
|
10786
|
+
function normalizeCoverage(coverage) {
|
|
10787
|
+
return coverage.map(
|
|
10788
|
+
(observation) => coverageRegionV1Schema.parse({
|
|
10789
|
+
...observation,
|
|
10790
|
+
diagnosticIds: [...observation.diagnosticIds].sort()
|
|
10791
|
+
})
|
|
10792
|
+
).sort((left, right) => compareCanonicalStrings(left.regionId, right.regionId));
|
|
10793
|
+
}
|
|
10794
|
+
function deriveCoverageSummaryFromNormalizedV1(plan, coverage) {
|
|
10795
|
+
const planned = new Map(plan.regions.map((region) => [region.regionId, region]));
|
|
10796
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10797
|
+
const duplicateRegionIds = /* @__PURE__ */ new Set();
|
|
10798
|
+
const unknownRegionIds = /* @__PURE__ */ new Set();
|
|
10799
|
+
for (const observation of coverage) {
|
|
10800
|
+
if (seen.has(observation.regionId)) duplicateRegionIds.add(observation.regionId);
|
|
10801
|
+
seen.add(observation.regionId);
|
|
10802
|
+
if (!planned.has(observation.regionId)) unknownRegionIds.add(observation.regionId);
|
|
10803
|
+
}
|
|
10804
|
+
const missingRequiredRegionIds = plan.regions.filter((region) => region.required && !seen.has(region.regionId)).map((region) => region.regionId);
|
|
10805
|
+
const missingOptionalRegionIds = plan.regions.filter((region) => !region.required && !seen.has(region.regionId)).map((region) => region.regionId);
|
|
10806
|
+
if (duplicateRegionIds.size > 0 || unknownRegionIds.size > 0 || missingRequiredRegionIds.length > 0 || missingOptionalRegionIds.length > 0) {
|
|
10807
|
+
throw new CoverageValidationErrorV1(
|
|
10808
|
+
"Coverage observations must join exactly once to every planned region",
|
|
10809
|
+
[...duplicateRegionIds].sort(),
|
|
10810
|
+
[...unknownRegionIds].sort(),
|
|
10811
|
+
missingRequiredRegionIds.sort(),
|
|
10812
|
+
missingOptionalRegionIds.sort()
|
|
10813
|
+
);
|
|
10814
|
+
}
|
|
10815
|
+
const requiredByState = emptyCounts();
|
|
10816
|
+
const optionalByState = emptyCounts();
|
|
10817
|
+
let eligibleFiles = 0;
|
|
10818
|
+
let analyzedFiles = 0;
|
|
10819
|
+
let analyzedBytes = 0;
|
|
10820
|
+
let observedBytes = 0;
|
|
10821
|
+
let diagnosticCount = 0;
|
|
10822
|
+
for (const observation of coverage) {
|
|
10823
|
+
const region = planned.get(observation.regionId);
|
|
10824
|
+
(region.required ? requiredByState : optionalByState)[observation.state] += 1;
|
|
10825
|
+
if (observation.state !== "excluded_by_contract") eligibleFiles += observation.fileCount;
|
|
10826
|
+
if (observation.state === "analyzed") {
|
|
10827
|
+
analyzedFiles += observation.fileCount;
|
|
10828
|
+
analyzedBytes += observation.byteCount;
|
|
10829
|
+
}
|
|
10830
|
+
observedBytes += observation.byteCount;
|
|
10831
|
+
diagnosticCount += observation.diagnosticIds.length;
|
|
10832
|
+
}
|
|
10833
|
+
if (!Number.isSafeInteger(eligibleFiles) || !Number.isSafeInteger(analyzedFiles) || !Number.isSafeInteger(analyzedBytes) || !Number.isSafeInteger(observedBytes) || !Number.isSafeInteger(diagnosticCount)) {
|
|
10834
|
+
throw new RangeError("Coverage totals exceeded the safe integer range");
|
|
10835
|
+
}
|
|
10836
|
+
if (eligibleFiles > plan.limits.maxSourceFiles) {
|
|
10837
|
+
throw new CoverageValidationErrorV1("Coverage file total exceeds the analysis-plan limit");
|
|
10838
|
+
}
|
|
10839
|
+
if (observedBytes > plan.limits.maxSourceBytes) {
|
|
10840
|
+
throw new CoverageValidationErrorV1("Coverage byte total exceeds the analysis-plan limit");
|
|
10841
|
+
}
|
|
10842
|
+
if (diagnosticCount > plan.limits.maxDiagnostics) {
|
|
10843
|
+
throw new CoverageValidationErrorV1(
|
|
10844
|
+
"Coverage diagnostic total exceeds the analysis-plan limit"
|
|
10845
|
+
);
|
|
10846
|
+
}
|
|
10847
|
+
for (const state of COVERAGE_STATES) {
|
|
10848
|
+
if (!Number.isSafeInteger(requiredByState[state]) || !Number.isSafeInteger(optionalByState[state])) {
|
|
10849
|
+
throw new RangeError("Coverage count exceeded the safe integer range");
|
|
10850
|
+
}
|
|
10851
|
+
}
|
|
10852
|
+
return coverageSummaryV1Schema.parse({
|
|
10853
|
+
plannedRegions: plan.regions.length,
|
|
10854
|
+
observedRegions: coverage.length,
|
|
10855
|
+
requiredRegions: plan.regions.filter((region) => region.required).length,
|
|
10856
|
+
requiredByState,
|
|
10857
|
+
optionalByState,
|
|
10858
|
+
eligibleFiles,
|
|
10859
|
+
analyzedFiles,
|
|
10860
|
+
analyzedBytes
|
|
10861
|
+
});
|
|
10862
|
+
}
|
|
10863
|
+
function deriveCoverageSummaryV1(rawPlan, rawCoverage) {
|
|
10864
|
+
return deriveCoverageSummaryFromNormalizedV1(
|
|
10865
|
+
parseAnalysisPlanV1(rawPlan),
|
|
10866
|
+
normalizeCoverage(rawCoverage)
|
|
10867
|
+
);
|
|
10868
|
+
}
|
|
10869
|
+
function coverageArtifactDigestV1(rawPlan, rawCoverage) {
|
|
10870
|
+
const plan = parseAnalysisPlanV1(rawPlan);
|
|
10871
|
+
const coverage = normalizeCoverage(rawCoverage);
|
|
10872
|
+
const summary = deriveCoverageSummaryFromNormalizedV1(plan, coverage);
|
|
10873
|
+
return digestHexSchema.parse(
|
|
10874
|
+
sha256Hex(
|
|
10875
|
+
canonicalPreimage({
|
|
10876
|
+
schema: "analysis-coverage.v1",
|
|
10877
|
+
analysisPlanDigest: plan.digest,
|
|
10878
|
+
coverage,
|
|
10879
|
+
summary
|
|
10880
|
+
})
|
|
10881
|
+
)
|
|
10882
|
+
);
|
|
10883
|
+
}
|
|
10884
|
+
|
|
10885
|
+
// src/evaluation/types.ts
|
|
10886
|
+
var EVALUATOR_VERSION = "evaluation-kernel:v1";
|
|
10887
|
+
var EVALUATOR_VERSION_V2 = "evaluation-kernel:v2";
|
|
10888
|
+
|
|
10889
|
+
// src/evaluation/receipt.ts
|
|
10890
|
+
import { z as z10 } from "zod";
|
|
10891
|
+
var EVALUATION_MAX_WAIVERS_V2 = 1e3;
|
|
10892
|
+
var EVALUATION_MAX_WAIVER_MATCHES_V2 = 1e4;
|
|
10893
|
+
var EVALUATION_MAX_FINDINGS_V2 = 1e4;
|
|
10894
|
+
var EVALUATION_MAX_REASON_CODES_V2 = 64;
|
|
10895
|
+
var EVALUATION_MAX_MAP_ENTRIES_V2 = 1e5;
|
|
10896
|
+
var EVALUATION_MAX_POLICY_RULES_V2 = 1e4;
|
|
10897
|
+
var EVALUATION_RECEIPT_STRING_MAX_BYTES_V1 = 4096;
|
|
10898
|
+
var utf8Length2 = (value) => new TextEncoder().encode(value).byteLength;
|
|
10899
|
+
var boundedString2 = (maxBytes = EVALUATION_RECEIPT_STRING_MAX_BYTES_V1) => z10.string().min(1).refine((value) => utf8Length2(value) <= maxBytes, `Value exceeds ${maxBytes} UTF-8 bytes`);
|
|
10900
|
+
var unique = (values) => new Set(values).size === values.length;
|
|
10901
|
+
var contractPreimageV1Schema = z10.object({
|
|
10902
|
+
schema: z10.literal(CONTRACT_PREIMAGE_SCHEMA),
|
|
10903
|
+
domains: z10.object({
|
|
10904
|
+
components: digestHexStringSchema,
|
|
10905
|
+
tokens: digestHexStringSchema,
|
|
10906
|
+
canonicalMap: digestHexStringSchema,
|
|
10907
|
+
policy: digestHexStringSchema
|
|
10908
|
+
}).strict()
|
|
10909
|
+
}).strict();
|
|
10910
|
+
var effectiveRulePolicySchema = z10.object({ trust: z10.enum(["canonical", "evidence", "none"]).optional() }).strict();
|
|
10911
|
+
var effectivePolicySchema = z10.object({
|
|
10912
|
+
failOnWarnings: z10.boolean(),
|
|
10913
|
+
failOnInert: z10.boolean().optional(),
|
|
10914
|
+
rules: z10.record(boundedString2(), effectiveRulePolicySchema).refine(
|
|
10915
|
+
(rules) => Object.keys(rules).length <= EVALUATION_MAX_POLICY_RULES_V2,
|
|
10916
|
+
"Policy rule map exceeds the V2 limit"
|
|
10917
|
+
).optional()
|
|
10918
|
+
}).strict();
|
|
10919
|
+
var evaluationTrustSchema = z10.object({
|
|
10920
|
+
source: z10.enum(["verified", "unverified", "unknown"]),
|
|
10921
|
+
sources: z10.record(boundedString2(), z10.enum(["verified", "unverified", "unknown"])).refine(
|
|
10922
|
+
(sources) => Object.keys(sources).length <= EVALUATION_MAX_MAP_ENTRIES_V2,
|
|
10923
|
+
"Source trust map exceeds the V2 limit"
|
|
10924
|
+
).optional(),
|
|
10925
|
+
mappings: z10.record(boundedString2(), z10.enum(["confirmed", "unconfirmed", "unknown"])).refine(
|
|
10926
|
+
(mappings) => Object.keys(mappings).length <= EVALUATION_MAX_MAP_ENTRIES_V2,
|
|
10927
|
+
"Mapping trust map exceeds the V2 limit"
|
|
10928
|
+
)
|
|
10929
|
+
}).strict();
|
|
10930
|
+
var waiverScopeSchema = z10.discriminatedUnion("kind", [
|
|
10931
|
+
z10.object({ kind: z10.literal("finding"), fingerprint: boundedString2() }).strict(),
|
|
10932
|
+
z10.object({ kind: z10.literal("rule"), ruleId: boundedString2() }).strict(),
|
|
10933
|
+
z10.object({ kind: z10.literal("path"), pathPattern: boundedString2() }).strict(),
|
|
10934
|
+
z10.object({ kind: z10.literal("rule_path"), ruleId: boundedString2(), pathPattern: boundedString2() }).strict()
|
|
10935
|
+
]);
|
|
10936
|
+
var effectiveEvaluationWaiverV2Schema = z10.object({
|
|
10937
|
+
waiverId: boundedString2(),
|
|
10938
|
+
scope: waiverScopeSchema,
|
|
10939
|
+
matchedFindingFingerprints: z10.array(boundedString2()).min(1).max(EVALUATION_MAX_WAIVER_MATCHES_V2).refine(unique, "matched finding fingerprints must be unique"),
|
|
10940
|
+
reason: boundedString2(),
|
|
10941
|
+
expiresAt: z10.number().finite().optional()
|
|
10942
|
+
}).strict();
|
|
10943
|
+
var evaluationIntegrityInputV2Schema = z10.object({
|
|
10944
|
+
governance: z10.enum(["healthy", "inert"]),
|
|
10945
|
+
inertConfigDiagnosticCount: z10.number().int().nonnegative(),
|
|
10946
|
+
profile: z10.discriminatedUnion("state", [
|
|
10947
|
+
z10.object({
|
|
10948
|
+
state: z10.literal("known"),
|
|
10949
|
+
profileId: boundedString2(),
|
|
10950
|
+
profileVersion: boundedString2()
|
|
10951
|
+
}).strict(),
|
|
10952
|
+
z10.object({
|
|
10953
|
+
state: z10.literal("unknown"),
|
|
10954
|
+
profileId: boundedString2(),
|
|
10955
|
+
profileVersion: boundedString2().optional()
|
|
10956
|
+
}).strict()
|
|
10957
|
+
]),
|
|
10958
|
+
facts: canonicalFactIntegrityV1Schema
|
|
10959
|
+
}).strict();
|
|
10960
|
+
var baselineSchema = z10.object({
|
|
10961
|
+
identity: z10.object({
|
|
10962
|
+
bindingDigest: digestHexStringSchema,
|
|
10963
|
+
repositoryExternalId: boundedString2(),
|
|
10964
|
+
fcid: digestHexStringSchema,
|
|
10965
|
+
sourceCommitId: boundedString2(),
|
|
10966
|
+
generationId: boundedString2()
|
|
10967
|
+
}).strict(),
|
|
10968
|
+
findingStates: z10.record(boundedString2(), z10.enum(["introduced", "existing", "unknown"])).refine(
|
|
10969
|
+
(states) => Object.keys(states).length <= EVALUATION_MAX_MAP_ENTRIES_V2,
|
|
10970
|
+
"Baseline finding-state map exceeds the V2 limit"
|
|
10971
|
+
)
|
|
10972
|
+
}).strict();
|
|
10973
|
+
var evaluationInputV2RawSchema = z10.object({
|
|
10974
|
+
schemaVersion: z10.literal(2),
|
|
10975
|
+
binding: repositoryBindingKeyV1Schema,
|
|
10976
|
+
analysisPlan: analysisPlanV1Schema,
|
|
10977
|
+
contract: z10.object({
|
|
10978
|
+
fcid: digestHexStringSchema,
|
|
10979
|
+
preimage: contractPreimageV1Schema,
|
|
10980
|
+
active: z10.boolean()
|
|
10981
|
+
}).strict(),
|
|
10982
|
+
factSchemaVersion: boundedString2(256),
|
|
10983
|
+
facts: z10.instanceof(FactIndex),
|
|
10984
|
+
factsDigest: digestHexStringSchema,
|
|
10985
|
+
coverage: z10.array(coverageRegionV1Schema).max(1e3),
|
|
10986
|
+
policy: effectivePolicySchema,
|
|
10987
|
+
baseline: baselineSchema.optional(),
|
|
10988
|
+
adoption: z10.union([z10.literal("unavailable"), z10.object({ regressed: z10.boolean() }).strict()]).optional(),
|
|
10989
|
+
trust: evaluationTrustSchema.optional(),
|
|
10990
|
+
waivers: z10.array(effectiveEvaluationWaiverV2Schema).max(EVALUATION_MAX_WAIVERS_V2).refine(
|
|
10991
|
+
(waivers) => new Set(waivers.map((waiver) => waiver.waiverId)).size === waivers.length,
|
|
10992
|
+
"waiver IDs must be unique"
|
|
10993
|
+
),
|
|
10994
|
+
integrity: evaluationIntegrityInputV2Schema,
|
|
10995
|
+
evaluatedAt: z10.number().finite(),
|
|
10996
|
+
evaluatorVersion: boundedString2(256)
|
|
10997
|
+
}).strict().superRefine((input, context) => {
|
|
10998
|
+
let plan;
|
|
10999
|
+
try {
|
|
11000
|
+
plan = parseAnalysisPlanV1(input.analysisPlan);
|
|
11001
|
+
} catch (error) {
|
|
11002
|
+
context.addIssue({
|
|
11003
|
+
code: z10.ZodIssueCode.custom,
|
|
11004
|
+
path: ["analysisPlan"],
|
|
11005
|
+
message: error instanceof Error ? error.message : "Invalid analysis plan identity"
|
|
11006
|
+
});
|
|
11007
|
+
return;
|
|
11008
|
+
}
|
|
11009
|
+
if (repositoryBindingDigestV1(plan.binding) !== repositoryBindingDigestV1(input.binding)) {
|
|
11010
|
+
context.addIssue({
|
|
11011
|
+
code: z10.ZodIssueCode.custom,
|
|
11012
|
+
path: ["binding"],
|
|
11013
|
+
message: "Evaluation binding does not match the analysis plan binding"
|
|
11014
|
+
});
|
|
11015
|
+
}
|
|
11016
|
+
if (plan.contract.fcid !== input.contract.fcid) {
|
|
11017
|
+
context.addIssue({
|
|
11018
|
+
code: z10.ZodIssueCode.custom,
|
|
11019
|
+
path: ["contract", "fcid"],
|
|
11020
|
+
message: "Evaluation FCID does not match the analysis plan"
|
|
11021
|
+
});
|
|
11022
|
+
}
|
|
11023
|
+
if (contractHash(input.contract.preimage) !== input.contract.fcid) {
|
|
11024
|
+
context.addIssue({
|
|
11025
|
+
code: z10.ZodIssueCode.custom,
|
|
11026
|
+
path: ["contract", "preimage"],
|
|
11027
|
+
message: "Contract preimage does not reproduce the pinned FCID"
|
|
11028
|
+
});
|
|
11029
|
+
}
|
|
11030
|
+
if (plan.evaluatorVersion !== input.evaluatorVersion) {
|
|
11031
|
+
context.addIssue({
|
|
11032
|
+
code: z10.ZodIssueCode.custom,
|
|
11033
|
+
path: ["evaluatorVersion"],
|
|
11034
|
+
message: "Evaluator version does not match the analysis plan"
|
|
11035
|
+
});
|
|
11036
|
+
}
|
|
11037
|
+
if (input.integrity.profile.state === "known" && (input.integrity.profile.profileId !== plan.profile.id || input.integrity.profile.profileVersion !== plan.profile.version)) {
|
|
11038
|
+
context.addIssue({
|
|
11039
|
+
code: z10.ZodIssueCode.custom,
|
|
11040
|
+
path: ["integrity", "profile"],
|
|
11041
|
+
message: "Known profile identity does not match the analysis plan"
|
|
11042
|
+
});
|
|
11043
|
+
}
|
|
11044
|
+
if (input.baseline) {
|
|
11045
|
+
const expectedBindingDigest = repositoryBindingDigestV1(input.binding);
|
|
11046
|
+
if (input.baseline.identity.bindingDigest !== expectedBindingDigest || input.baseline.identity.repositoryExternalId !== input.binding.repositoryExternalId || input.baseline.identity.fcid !== input.contract.fcid) {
|
|
11047
|
+
context.addIssue({
|
|
11048
|
+
code: z10.ZodIssueCode.custom,
|
|
11049
|
+
path: ["baseline", "identity"],
|
|
11050
|
+
message: "Baseline identity does not match the evaluation binding and FCID"
|
|
11051
|
+
});
|
|
11052
|
+
}
|
|
11053
|
+
}
|
|
11054
|
+
if (input.facts.size() > plan.limits.maxFacts) {
|
|
11055
|
+
context.addIssue({
|
|
11056
|
+
code: z10.ZodIssueCode.custom,
|
|
11057
|
+
path: ["facts"],
|
|
11058
|
+
message: "Fact count exceeds the analysis-plan limit"
|
|
11059
|
+
});
|
|
11060
|
+
}
|
|
11061
|
+
try {
|
|
11062
|
+
deriveCoverageSummaryV1(plan, input.coverage);
|
|
11063
|
+
} catch (error) {
|
|
11064
|
+
context.addIssue({
|
|
11065
|
+
code: z10.ZodIssueCode.custom,
|
|
11066
|
+
path: ["coverage"],
|
|
11067
|
+
message: error instanceof Error ? error.message : "Coverage does not match the plan"
|
|
11068
|
+
});
|
|
11069
|
+
}
|
|
11070
|
+
});
|
|
11071
|
+
var evaluationInputV2Schema = evaluationInputV2RawSchema.transform(
|
|
11072
|
+
(input) => ({
|
|
11073
|
+
...input,
|
|
11074
|
+
binding: normalizeRepositoryBindingKeyV1(input.binding),
|
|
11075
|
+
analysisPlan: parseAnalysisPlanV1(input.analysisPlan)
|
|
11076
|
+
})
|
|
11077
|
+
);
|
|
11078
|
+
var evaluationReasonV2Schema = z10.enum([
|
|
11079
|
+
"zeroFileScan",
|
|
11080
|
+
"governanceInert",
|
|
11081
|
+
"contractUnpinned",
|
|
11082
|
+
"contractStale",
|
|
11083
|
+
"contractIdentityMismatch",
|
|
11084
|
+
"inertConfigPresent",
|
|
11085
|
+
"unknownPresetPresent",
|
|
11086
|
+
"blockedFindings",
|
|
11087
|
+
"adoptionRegression",
|
|
11088
|
+
"expiredSuppression",
|
|
11089
|
+
"pendingCloudTrust",
|
|
11090
|
+
"adoptionBaselineUnavailable",
|
|
11091
|
+
"analysisPlanIdentityMismatch",
|
|
11092
|
+
"requiredCoverageMissing",
|
|
11093
|
+
"requiredCoverageIncomplete",
|
|
11094
|
+
"factConflict",
|
|
11095
|
+
"unknownAnalysisProfile"
|
|
11096
|
+
]);
|
|
11097
|
+
var evaluationResultV2Schema = z10.object({
|
|
11098
|
+
schemaVersion: z10.literal(2),
|
|
11099
|
+
verdict: z10.enum(["pass", "block", "indeterminate"]),
|
|
11100
|
+
reasons: z10.array(evaluationReasonV2Schema).max(EVALUATION_MAX_REASON_CODES_V2).refine(unique, "Evaluation reason codes must be unique"),
|
|
11101
|
+
findings: z10.array(
|
|
11102
|
+
z10.object({
|
|
11103
|
+
fingerprint: boundedString2(),
|
|
11104
|
+
ruleId: boundedString2(),
|
|
11105
|
+
severity: z10.enum(["error", "warn", "info"]),
|
|
11106
|
+
state: z10.enum(["blocked", "advisory", "pending_cloud_trust"]),
|
|
11107
|
+
stateReasons: z10.array(boundedString2()).max(256)
|
|
11108
|
+
}).strict()
|
|
11109
|
+
).max(EVALUATION_MAX_FINDINGS_V2),
|
|
11110
|
+
counts: z10.object({
|
|
11111
|
+
blocked: z10.number().int().nonnegative().max(EVALUATION_MAX_FINDINGS_V2),
|
|
11112
|
+
advisory: z10.number().int().nonnegative().max(EVALUATION_MAX_FINDINGS_V2),
|
|
11113
|
+
pendingCloudTrust: z10.number().int().nonnegative().max(EVALUATION_MAX_FINDINGS_V2)
|
|
11114
|
+
}).strict(),
|
|
11115
|
+
derived: z10.object({ warnPresent: z10.boolean(), gatingFindingsPresent: z10.boolean() }).strict(),
|
|
11116
|
+
coverageSummary: coverageSummaryV1Schema,
|
|
11117
|
+
integrity: z10.object({
|
|
11118
|
+
fcidVerified: z10.boolean(),
|
|
11119
|
+
analysisPlanVerified: z10.boolean(),
|
|
11120
|
+
factIntegrity: z10.enum(["healthy", "conflict"]),
|
|
11121
|
+
requiredCoverage: z10.enum(["complete", "incomplete", "no_required_regions"]),
|
|
11122
|
+
governance: z10.enum(["healthy", "inert"]),
|
|
11123
|
+
profile: z10.enum(["known", "unknown"])
|
|
11124
|
+
}).strict(),
|
|
11125
|
+
inputDigest: digestHexStringSchema,
|
|
11126
|
+
resultDigest: digestHexStringSchema
|
|
11127
|
+
}).strict().superRefine((result, context) => {
|
|
11128
|
+
const expectedCounts = { blocked: 0, advisory: 0, pendingCloudTrust: 0 };
|
|
11129
|
+
let emittedWarnPresent = false;
|
|
11130
|
+
for (const [index, finding] of result.findings.entries()) {
|
|
11131
|
+
if (finding.state === "blocked") expectedCounts.blocked += 1;
|
|
11132
|
+
else if (finding.state === "pending_cloud_trust") expectedCounts.pendingCloudTrust += 1;
|
|
11133
|
+
else expectedCounts.advisory += 1;
|
|
11134
|
+
if (finding.severity === "warn") emittedWarnPresent = true;
|
|
11135
|
+
if (new Set(finding.stateReasons).size !== finding.stateReasons.length) {
|
|
11136
|
+
context.addIssue({
|
|
11137
|
+
code: z10.ZodIssueCode.custom,
|
|
11138
|
+
path: ["findings", index, "stateReasons"],
|
|
11139
|
+
message: "Finding state reasons must be unique"
|
|
11140
|
+
});
|
|
11141
|
+
}
|
|
11142
|
+
}
|
|
11143
|
+
if (new Set(result.findings.map((finding) => finding.fingerprint)).size !== result.findings.length) {
|
|
11144
|
+
context.addIssue({
|
|
11145
|
+
code: z10.ZodIssueCode.custom,
|
|
11146
|
+
path: ["findings"],
|
|
11147
|
+
message: "Evaluation finding fingerprints must be unique"
|
|
11148
|
+
});
|
|
11149
|
+
}
|
|
11150
|
+
for (const key of ["blocked", "advisory", "pendingCloudTrust"]) {
|
|
11151
|
+
if (result.counts[key] !== expectedCounts[key]) {
|
|
11152
|
+
context.addIssue({
|
|
11153
|
+
code: z10.ZodIssueCode.custom,
|
|
11154
|
+
path: ["counts", key],
|
|
11155
|
+
message: `Evaluation ${key} count must match findings`
|
|
11156
|
+
});
|
|
11157
|
+
}
|
|
11158
|
+
}
|
|
11159
|
+
if (emittedWarnPresent && !result.derived.warnPresent) {
|
|
11160
|
+
context.addIssue({
|
|
11161
|
+
code: z10.ZodIssueCode.custom,
|
|
11162
|
+
path: ["derived", "warnPresent"],
|
|
11163
|
+
message: "An emitted warning finding requires warnPresent"
|
|
11164
|
+
});
|
|
11165
|
+
}
|
|
11166
|
+
if (result.derived.gatingFindingsPresent !== expectedCounts.blocked > 0) {
|
|
11167
|
+
context.addIssue({
|
|
11168
|
+
code: z10.ZodIssueCode.custom,
|
|
11169
|
+
path: ["derived", "gatingFindingsPresent"],
|
|
11170
|
+
message: "gatingFindingsPresent must match blocked findings"
|
|
11171
|
+
});
|
|
11172
|
+
}
|
|
11173
|
+
const coverageStates = [
|
|
11174
|
+
"analyzed",
|
|
11175
|
+
"unsupported",
|
|
11176
|
+
"excluded_by_contract",
|
|
11177
|
+
"skipped_limit",
|
|
11178
|
+
"failed"
|
|
11179
|
+
];
|
|
11180
|
+
const requiredCount = coverageStates.reduce(
|
|
11181
|
+
(total, state) => total + result.coverageSummary.requiredByState[state],
|
|
11182
|
+
0
|
|
11183
|
+
);
|
|
11184
|
+
const optionalCount = coverageStates.reduce(
|
|
11185
|
+
(total, state) => total + result.coverageSummary.optionalByState[state],
|
|
11186
|
+
0
|
|
11187
|
+
);
|
|
11188
|
+
if (requiredCount !== result.coverageSummary.requiredRegions || requiredCount + optionalCount !== result.coverageSummary.observedRegions || result.coverageSummary.observedRegions !== result.coverageSummary.plannedRegions) {
|
|
11189
|
+
context.addIssue({
|
|
11190
|
+
code: z10.ZodIssueCode.custom,
|
|
11191
|
+
path: ["coverageSummary"],
|
|
11192
|
+
message: "Coverage summary counts must reconcile with planned and observed regions"
|
|
11193
|
+
});
|
|
11194
|
+
}
|
|
11195
|
+
if (result.coverageSummary.analyzedFiles > result.coverageSummary.eligibleFiles) {
|
|
11196
|
+
context.addIssue({
|
|
11197
|
+
code: z10.ZodIssueCode.custom,
|
|
11198
|
+
path: ["coverageSummary", "analyzedFiles"],
|
|
11199
|
+
message: "Analyzed files cannot exceed eligible files"
|
|
11200
|
+
});
|
|
11201
|
+
}
|
|
11202
|
+
const expectedRequiredCoverage = result.coverageSummary.requiredRegions === 0 ? "no_required_regions" : result.coverageSummary.requiredByState.analyzed === result.coverageSummary.requiredRegions ? "complete" : "incomplete";
|
|
11203
|
+
if (result.integrity.requiredCoverage !== expectedRequiredCoverage) {
|
|
11204
|
+
context.addIssue({
|
|
11205
|
+
code: z10.ZodIssueCode.custom,
|
|
11206
|
+
path: ["integrity", "requiredCoverage"],
|
|
11207
|
+
message: "Required coverage integrity must match the derived coverage summary"
|
|
11208
|
+
});
|
|
11209
|
+
}
|
|
11210
|
+
const reasons = new Set(result.reasons);
|
|
11211
|
+
const requireReason = (reason, required, path) => {
|
|
11212
|
+
if (reasons.has(reason) !== required) {
|
|
11213
|
+
context.addIssue({
|
|
11214
|
+
code: z10.ZodIssueCode.custom,
|
|
11215
|
+
path,
|
|
11216
|
+
message: `${reason} must match the evaluation result`
|
|
11217
|
+
});
|
|
11218
|
+
}
|
|
11219
|
+
};
|
|
11220
|
+
requireReason("blockedFindings", expectedCounts.blocked > 0, ["reasons"]);
|
|
11221
|
+
requireReason("pendingCloudTrust", expectedCounts.pendingCloudTrust > 0, ["reasons"]);
|
|
11222
|
+
requireReason("contractIdentityMismatch", !result.integrity.fcidVerified, ["reasons"]);
|
|
11223
|
+
requireReason("analysisPlanIdentityMismatch", !result.integrity.analysisPlanVerified, [
|
|
11224
|
+
"reasons"
|
|
11225
|
+
]);
|
|
11226
|
+
requireReason("factConflict", result.integrity.factIntegrity === "conflict", ["reasons"]);
|
|
11227
|
+
requireReason("governanceInert", result.integrity.governance === "inert", ["reasons"]);
|
|
11228
|
+
requireReason("unknownAnalysisProfile", result.integrity.profile === "unknown", ["reasons"]);
|
|
11229
|
+
requireReason(
|
|
11230
|
+
"requiredCoverageIncomplete",
|
|
11231
|
+
result.integrity.requiredCoverage === "incomplete",
|
|
11232
|
+
["reasons"]
|
|
11233
|
+
);
|
|
11234
|
+
requireReason(
|
|
11235
|
+
"requiredCoverageMissing",
|
|
11236
|
+
result.integrity.requiredCoverage === "no_required_regions",
|
|
11237
|
+
["reasons"]
|
|
11238
|
+
);
|
|
11239
|
+
const integrityHealthy = result.integrity.fcidVerified && result.integrity.analysisPlanVerified && result.integrity.factIntegrity === "healthy" && result.integrity.requiredCoverage === "complete" && result.integrity.governance === "healthy" && result.integrity.profile === "known";
|
|
11240
|
+
const blockingReasons = /* @__PURE__ */ new Set([
|
|
11241
|
+
"blockedFindings",
|
|
11242
|
+
"adoptionRegression",
|
|
11243
|
+
"expiredSuppression"
|
|
11244
|
+
]);
|
|
11245
|
+
const integrityReasons = /* @__PURE__ */ new Set([
|
|
11246
|
+
"zeroFileScan",
|
|
11247
|
+
"governanceInert",
|
|
11248
|
+
"contractUnpinned",
|
|
11249
|
+
"contractStale",
|
|
11250
|
+
"contractIdentityMismatch",
|
|
11251
|
+
"inertConfigPresent",
|
|
11252
|
+
"unknownPresetPresent",
|
|
11253
|
+
"analysisPlanIdentityMismatch",
|
|
11254
|
+
"requiredCoverageMissing",
|
|
11255
|
+
"requiredCoverageIncomplete",
|
|
11256
|
+
"factConflict",
|
|
11257
|
+
"unknownAnalysisProfile"
|
|
11258
|
+
]);
|
|
11259
|
+
const expectedVerdict = !integrityHealthy || result.reasons.some((reason) => integrityReasons.has(reason)) ? "indeterminate" : result.reasons.some((reason) => blockingReasons.has(reason)) ? "block" : result.reasons.length > 0 ? "indeterminate" : "pass";
|
|
11260
|
+
if (result.verdict !== expectedVerdict) {
|
|
11261
|
+
context.addIssue({
|
|
11262
|
+
code: z10.ZodIssueCode.custom,
|
|
11263
|
+
path: ["verdict"],
|
|
11264
|
+
message: `Evaluation verdict must be ${expectedVerdict} for its reasons and integrity`
|
|
11265
|
+
});
|
|
11266
|
+
}
|
|
11267
|
+
});
|
|
11268
|
+
var providerProofSemanticV1Schema = z10.object({
|
|
11269
|
+
schemaVersion: z10.literal(1),
|
|
11270
|
+
adapterId: boundedString2(),
|
|
11271
|
+
adapterVersion: boundedString2(),
|
|
11272
|
+
providerInstanceId: boundedString2(),
|
|
11273
|
+
bindingDigest: digestHexStringSchema,
|
|
11274
|
+
repositoryExternalId: boundedString2(),
|
|
11275
|
+
sourceCommitId: boundedString2(),
|
|
11276
|
+
eventExternalId: boundedString2(),
|
|
11277
|
+
changeExternalId: boundedString2().optional(),
|
|
11278
|
+
publisherExternalId: boundedString2()
|
|
11279
|
+
}).strict();
|
|
11280
|
+
function providerProofDigestV1(value) {
|
|
11281
|
+
const proof = providerProofSemanticV1Schema.parse(value);
|
|
11282
|
+
return sha256Hex(canonicalPreimage({ schema: "provider-proof.v1", ...proof }));
|
|
11283
|
+
}
|
|
11284
|
+
var providerProofV1Schema = z10.object({
|
|
11285
|
+
schemaVersion: z10.literal(1),
|
|
11286
|
+
adapterId: boundedString2(),
|
|
11287
|
+
adapterVersion: boundedString2(),
|
|
11288
|
+
providerInstanceId: boundedString2(),
|
|
11289
|
+
bindingDigest: digestHexStringSchema,
|
|
11290
|
+
repositoryExternalId: boundedString2(),
|
|
11291
|
+
sourceCommitId: boundedString2(),
|
|
11292
|
+
eventExternalId: boundedString2(),
|
|
11293
|
+
changeExternalId: boundedString2().optional(),
|
|
11294
|
+
publisherExternalId: boundedString2(),
|
|
11295
|
+
proofDigest: digestHexStringSchema
|
|
11296
|
+
}).strict().superRefine((proof, context) => {
|
|
11297
|
+
const { proofDigest, ...semantic } = proof;
|
|
11298
|
+
if (providerProofDigestV1(semantic) !== proofDigest) {
|
|
11299
|
+
context.addIssue({
|
|
11300
|
+
code: z10.ZodIssueCode.custom,
|
|
11301
|
+
path: ["proofDigest"],
|
|
11302
|
+
message: "Provider proof digest mismatch"
|
|
11303
|
+
});
|
|
11304
|
+
}
|
|
11305
|
+
});
|
|
11306
|
+
var receiptSemanticShape = {
|
|
11307
|
+
schemaVersion: z10.literal(1),
|
|
11308
|
+
trust: z10.enum(["source_verified", "ci_attested", "local", "unknown"]),
|
|
11309
|
+
authority: z10.enum(["advisory", "enforcement_eligible"]),
|
|
11310
|
+
binding: repositoryBindingKeyV1Schema,
|
|
11311
|
+
sourceCommitId: boundedString2(),
|
|
11312
|
+
fcid: digestHexStringSchema,
|
|
11313
|
+
analysisPlanDigest: digestHexStringSchema,
|
|
11314
|
+
factsDigest: digestHexStringSchema,
|
|
11315
|
+
inputDigest: digestHexStringSchema,
|
|
11316
|
+
resultDigest: digestHexStringSchema,
|
|
11317
|
+
evaluatorVersion: boundedString2(),
|
|
11318
|
+
providerProof: providerProofV1Schema.optional()
|
|
11319
|
+
};
|
|
11320
|
+
function validateReceiptSemantics(receipt, context) {
|
|
11321
|
+
if (receipt.authority === "enforcement_eligible") {
|
|
11322
|
+
if (receipt.trust !== "source_verified") {
|
|
11323
|
+
context.addIssue({
|
|
11324
|
+
code: z10.ZodIssueCode.custom,
|
|
11325
|
+
path: ["authority"],
|
|
11326
|
+
message: "Only source-verified evidence can enforce"
|
|
11327
|
+
});
|
|
11328
|
+
}
|
|
11329
|
+
if (!receipt.providerProof) {
|
|
11330
|
+
context.addIssue({
|
|
11331
|
+
code: z10.ZodIssueCode.custom,
|
|
11332
|
+
path: ["providerProof"],
|
|
11333
|
+
message: "Source-verified enforcement requires provider proof"
|
|
11334
|
+
});
|
|
11335
|
+
}
|
|
11336
|
+
}
|
|
11337
|
+
if (receipt.trust === "source_verified" && !receipt.providerProof) {
|
|
11338
|
+
context.addIssue({
|
|
11339
|
+
code: z10.ZodIssueCode.custom,
|
|
11340
|
+
path: ["providerProof"],
|
|
11341
|
+
message: "Source-verified trust requires provider proof"
|
|
11342
|
+
});
|
|
11343
|
+
}
|
|
11344
|
+
if (receipt.trust !== "source_verified" && receipt.providerProof) {
|
|
11345
|
+
context.addIssue({
|
|
11346
|
+
code: z10.ZodIssueCode.custom,
|
|
11347
|
+
path: ["providerProof"],
|
|
11348
|
+
message: "Provider proof is reserved for source-verified trust"
|
|
11349
|
+
});
|
|
11350
|
+
}
|
|
11351
|
+
if (!receipt.providerProof) return;
|
|
11352
|
+
const proof = receipt.providerProof;
|
|
11353
|
+
const binding = normalizeRepositoryBindingKeyV1(receipt.binding);
|
|
11354
|
+
if (proof.bindingDigest !== repositoryBindingDigestV1(binding)) {
|
|
11355
|
+
context.addIssue({
|
|
11356
|
+
code: z10.ZodIssueCode.custom,
|
|
11357
|
+
path: ["providerProof", "bindingDigest"],
|
|
11358
|
+
message: "Provider proof binding mismatch"
|
|
11359
|
+
});
|
|
11360
|
+
}
|
|
11361
|
+
if (proof.providerInstanceId !== binding.providerInstanceId) {
|
|
11362
|
+
context.addIssue({
|
|
11363
|
+
code: z10.ZodIssueCode.custom,
|
|
11364
|
+
path: ["providerProof", "providerInstanceId"],
|
|
11365
|
+
message: "Provider proof instance mismatch"
|
|
11366
|
+
});
|
|
11367
|
+
}
|
|
11368
|
+
if (proof.repositoryExternalId !== binding.repositoryExternalId) {
|
|
11369
|
+
context.addIssue({
|
|
11370
|
+
code: z10.ZodIssueCode.custom,
|
|
11371
|
+
path: ["providerProof", "repositoryExternalId"],
|
|
11372
|
+
message: "Provider proof repository mismatch"
|
|
11373
|
+
});
|
|
11374
|
+
}
|
|
11375
|
+
if (proof.sourceCommitId !== receipt.sourceCommitId) {
|
|
11376
|
+
context.addIssue({
|
|
11377
|
+
code: z10.ZodIssueCode.custom,
|
|
11378
|
+
path: ["providerProof", "sourceCommitId"],
|
|
11379
|
+
message: "Provider proof source mismatch"
|
|
11380
|
+
});
|
|
11381
|
+
}
|
|
11382
|
+
}
|
|
11383
|
+
var evaluationReceiptSemanticV1Schema = z10.object(receiptSemanticShape).strict().superRefine(validateReceiptSemantics);
|
|
11384
|
+
function evaluationReceiptDigestV1(value) {
|
|
11385
|
+
const receipt = evaluationReceiptSemanticV1Schema.parse(value);
|
|
11386
|
+
return sha256Hex(
|
|
11387
|
+
canonicalPreimage({
|
|
11388
|
+
schema: "evaluation-receipt.v1",
|
|
11389
|
+
trust: receipt.trust,
|
|
11390
|
+
authority: receipt.authority,
|
|
11391
|
+
bindingDigest: repositoryBindingDigestV1(receipt.binding),
|
|
11392
|
+
sourceCommitId: receipt.sourceCommitId,
|
|
11393
|
+
fcid: receipt.fcid,
|
|
11394
|
+
analysisPlanDigest: receipt.analysisPlanDigest,
|
|
11395
|
+
factsDigest: receipt.factsDigest,
|
|
11396
|
+
inputDigest: receipt.inputDigest,
|
|
11397
|
+
resultDigest: receipt.resultDigest,
|
|
11398
|
+
evaluatorVersion: receipt.evaluatorVersion,
|
|
11399
|
+
providerProofDigest: receipt.providerProof?.proofDigest
|
|
11400
|
+
})
|
|
11401
|
+
);
|
|
11402
|
+
}
|
|
11403
|
+
var evaluationReceiptV1Schema = z10.object({
|
|
11404
|
+
receiptId: evaluationReceiptIdStringSchema,
|
|
11405
|
+
...receiptSemanticShape,
|
|
11406
|
+
mintedAt: z10.string().datetime({ offset: true }),
|
|
11407
|
+
digest: digestHexStringSchema
|
|
11408
|
+
}).strict().superRefine((receipt, context) => {
|
|
11409
|
+
validateReceiptSemantics(receipt, context);
|
|
11410
|
+
let digest;
|
|
11411
|
+
try {
|
|
11412
|
+
const { receiptId: _receiptId, mintedAt: _mintedAt, digest: _digest, ...semantic } = receipt;
|
|
11413
|
+
digest = evaluationReceiptDigestV1(semantic);
|
|
11414
|
+
} catch (error) {
|
|
11415
|
+
context.addIssue({
|
|
11416
|
+
code: z10.ZodIssueCode.custom,
|
|
11417
|
+
message: error instanceof Error ? error.message : "Invalid receipt semantics"
|
|
11418
|
+
});
|
|
11419
|
+
return;
|
|
11420
|
+
}
|
|
11421
|
+
if (digest !== receipt.digest) {
|
|
11422
|
+
context.addIssue({
|
|
11423
|
+
code: z10.ZodIssueCode.custom,
|
|
11424
|
+
path: ["digest"],
|
|
11425
|
+
message: "Receipt digest mismatch"
|
|
11426
|
+
});
|
|
11427
|
+
}
|
|
11428
|
+
if (evaluationReceiptIdFromDigest(digest) !== receipt.receiptId) {
|
|
11429
|
+
context.addIssue({
|
|
11430
|
+
code: z10.ZodIssueCode.custom,
|
|
11431
|
+
path: ["receiptId"],
|
|
11432
|
+
message: "Receipt ID mismatch"
|
|
11433
|
+
});
|
|
11434
|
+
}
|
|
11435
|
+
});
|
|
11436
|
+
function parseEvaluationReceiptV1(value) {
|
|
11437
|
+
return evaluationReceiptV1Schema.parse(value);
|
|
11438
|
+
}
|
|
11439
|
+
var evaluationReceiptMintInputV1Schema = z10.object({
|
|
11440
|
+
schemaVersion: z10.literal(1),
|
|
11441
|
+
trust: z10.enum(["ci_attested", "local", "unknown"]),
|
|
11442
|
+
binding: repositoryBindingKeyV1Schema,
|
|
11443
|
+
sourceCommitId: boundedString2(),
|
|
11444
|
+
fcid: digestHexStringSchema,
|
|
11445
|
+
analysisPlanDigest: digestHexStringSchema,
|
|
11446
|
+
factsDigest: digestHexStringSchema,
|
|
11447
|
+
inputDigest: digestHexStringSchema,
|
|
11448
|
+
resultDigest: digestHexStringSchema,
|
|
11449
|
+
evaluatorVersion: boundedString2()
|
|
11450
|
+
}).strict();
|
|
11451
|
+
|
|
11452
|
+
// src/evaluation/evaluate.ts
|
|
11453
|
+
var INTEGRITY_REASONS = /* @__PURE__ */ new Set([
|
|
11454
|
+
"zeroFileScan",
|
|
11455
|
+
"governanceInert",
|
|
11456
|
+
"contractUnpinned",
|
|
11457
|
+
"contractStale",
|
|
11458
|
+
"contractIdentityMismatch",
|
|
11459
|
+
"inertConfigPresent",
|
|
11460
|
+
"unknownPresetPresent"
|
|
11461
|
+
]);
|
|
11462
|
+
var BLOCK_REASONS = /* @__PURE__ */ new Set([
|
|
11463
|
+
"blockedFindings",
|
|
11464
|
+
"adoptionRegression",
|
|
11465
|
+
"expiredSuppression"
|
|
11466
|
+
]);
|
|
11467
|
+
var REASON_ORDER = [
|
|
11468
|
+
"zeroFileScan",
|
|
11469
|
+
"governanceInert",
|
|
11470
|
+
"contractUnpinned",
|
|
11471
|
+
"contractStale",
|
|
11472
|
+
"contractIdentityMismatch",
|
|
11473
|
+
"inertConfigPresent",
|
|
11474
|
+
"unknownPresetPresent",
|
|
11475
|
+
"blockedFindings",
|
|
11476
|
+
"adoptionRegression",
|
|
11477
|
+
"expiredSuppression",
|
|
11478
|
+
"pendingCloudTrust",
|
|
11479
|
+
"adoptionBaselineUnavailable"
|
|
11480
|
+
];
|
|
11481
|
+
function evaluate2(input) {
|
|
11482
|
+
return isEvaluationInputV2(input) ? evaluateV2(input) : evaluateV1(input);
|
|
11483
|
+
}
|
|
11484
|
+
function isEvaluationInputV2(input) {
|
|
11485
|
+
return "schemaVersion" in input && input.schemaVersion === 2;
|
|
11486
|
+
}
|
|
11487
|
+
function evaluateV1(input) {
|
|
11488
|
+
const reasons = /* @__PURE__ */ new Set();
|
|
11489
|
+
let fcidVerified = "unavailable";
|
|
11490
|
+
if (input.contract.state === "unpinned") {
|
|
11491
|
+
reasons.add("contractUnpinned");
|
|
11492
|
+
} else {
|
|
11493
|
+
if (input.contract.stale) reasons.add("contractStale");
|
|
11494
|
+
if (input.contract.preimage) {
|
|
11495
|
+
fcidVerified = contractHash(input.contract.preimage) === input.contract.fcid;
|
|
11496
|
+
if (!fcidVerified) reasons.add("contractIdentityMismatch");
|
|
11497
|
+
}
|
|
11498
|
+
}
|
|
11499
|
+
if (input.scope.kind === "full" && input.scope.coverage.filesScanned === 0) {
|
|
11500
|
+
reasons.add("zeroFileScan");
|
|
11501
|
+
}
|
|
11502
|
+
if (input.integrity.governance === "inert") {
|
|
11503
|
+
reasons.add("governanceInert");
|
|
11504
|
+
}
|
|
11505
|
+
if (input.policy.failOnInert === true && (input.integrity.inertConfigDiagnostics ?? 0) > 0) {
|
|
11506
|
+
reasons.add("inertConfigPresent");
|
|
11507
|
+
}
|
|
11508
|
+
if ((input.integrity.unknownPresets?.length ?? 0) > 0) {
|
|
11509
|
+
reasons.add("unknownPresetPresent");
|
|
11510
|
+
}
|
|
11511
|
+
if (input.adoption === "unavailable") {
|
|
11512
|
+
reasons.add("adoptionBaselineUnavailable");
|
|
11513
|
+
} else if (input.adoption?.regressed === true) {
|
|
11514
|
+
reasons.add("adoptionRegression");
|
|
11515
|
+
}
|
|
11516
|
+
const activeWaivers = /* @__PURE__ */ new Set();
|
|
11517
|
+
for (const waiver of input.waivers ?? []) {
|
|
11518
|
+
if (waiver.expiresAt !== void 0 && Number.isFinite(waiver.expiresAt) && waiver.expiresAt <= input.evaluatedAt) {
|
|
11519
|
+
reasons.add("expiredSuppression");
|
|
11520
|
+
} else {
|
|
11521
|
+
activeWaivers.add(waiver.fingerprint);
|
|
11522
|
+
}
|
|
11523
|
+
}
|
|
11524
|
+
const evidence = evidenceFindings(input);
|
|
11525
|
+
const findings = [...groupByFingerprint(evidence).values()].map((rows) => {
|
|
11526
|
+
const classified = rows.map((row) => classifyFinding(row, input, activeWaivers));
|
|
11527
|
+
return classified.reduce(
|
|
11528
|
+
(hardest, candidate) => STATE_RANK[candidate.state] < STATE_RANK[hardest.state] ? candidate : hardest
|
|
11529
|
+
);
|
|
11530
|
+
});
|
|
11531
|
+
const counts = { blocked: 0, advisory: 0, pendingCloudTrust: 0 };
|
|
11532
|
+
for (const finding of findings) {
|
|
11533
|
+
if (finding.state === "blocked") counts.blocked += 1;
|
|
11534
|
+
else if (finding.state === "pending_cloud_trust") counts.pendingCloudTrust += 1;
|
|
11535
|
+
else counts.advisory += 1;
|
|
11536
|
+
}
|
|
11537
|
+
if (counts.blocked > 0) reasons.add("blockedFindings");
|
|
11538
|
+
if (counts.pendingCloudTrust > 0) reasons.add("pendingCloudTrust");
|
|
11539
|
+
const ordered = REASON_ORDER.filter((reason) => reasons.has(reason));
|
|
11540
|
+
let verdict;
|
|
11541
|
+
if (ordered.some((reason) => INTEGRITY_REASONS.has(reason))) {
|
|
11542
|
+
verdict = "indeterminate";
|
|
11543
|
+
} else if (ordered.some((reason) => BLOCK_REASONS.has(reason))) {
|
|
11544
|
+
verdict = "block";
|
|
11545
|
+
} else if (ordered.length > 0) {
|
|
11546
|
+
verdict = "indeterminate";
|
|
11547
|
+
} else {
|
|
11548
|
+
verdict = "pass";
|
|
11549
|
+
}
|
|
11550
|
+
const derived = {
|
|
11551
|
+
warnPresent: evidence.some((finding) => finding.severity === "warn"),
|
|
11552
|
+
gatingFindingsPresent: counts.blocked > 0
|
|
11553
|
+
};
|
|
11554
|
+
const inputDigest = sha256Hex(canonicalPreimage(normalizeInputForDigest(input)));
|
|
11555
|
+
const partial = {
|
|
11556
|
+
evaluatorVersion: EVALUATOR_VERSION,
|
|
11557
|
+
verdict,
|
|
11558
|
+
reasons: ordered,
|
|
11559
|
+
findings,
|
|
11560
|
+
counts,
|
|
11561
|
+
derived,
|
|
11562
|
+
integrity: { fcidVerified }
|
|
11563
|
+
};
|
|
11564
|
+
return {
|
|
11565
|
+
...partial,
|
|
11566
|
+
inputDigest,
|
|
11567
|
+
resultDigest: sha256Hex(canonicalPreimage({ ...partial, inputDigest }))
|
|
11568
|
+
};
|
|
11569
|
+
}
|
|
11570
|
+
var V2_REASON_ORDER = [
|
|
11571
|
+
"analysisPlanIdentityMismatch",
|
|
11572
|
+
"requiredCoverageMissing",
|
|
11573
|
+
"requiredCoverageIncomplete",
|
|
11574
|
+
"factConflict",
|
|
11575
|
+
"unknownAnalysisProfile",
|
|
11576
|
+
...REASON_ORDER
|
|
11577
|
+
];
|
|
11578
|
+
var V2_INTEGRITY_REASONS = /* @__PURE__ */ new Set([
|
|
11579
|
+
...INTEGRITY_REASONS,
|
|
11580
|
+
"analysisPlanIdentityMismatch",
|
|
11581
|
+
"requiredCoverageMissing",
|
|
11582
|
+
"requiredCoverageIncomplete",
|
|
11583
|
+
"factConflict",
|
|
11584
|
+
"unknownAnalysisProfile"
|
|
11585
|
+
]);
|
|
11586
|
+
var SUPPORTED_FACT_SCHEMA_VERSIONS_V2 = /* @__PURE__ */ new Set(["facts:v1"]);
|
|
11587
|
+
var SUPPORTED_REACT_WEB_PROFILE_VERSIONS_V1 = /* @__PURE__ */ new Set(["1"]);
|
|
11588
|
+
function evaluateV2(rawInput) {
|
|
11589
|
+
if (rawInput.evaluatorVersion !== EVALUATOR_VERSION_V2) {
|
|
11590
|
+
throw new Error(`Unsupported evaluator version: ${rawInput.evaluatorVersion}`);
|
|
11591
|
+
}
|
|
11592
|
+
if (!SUPPORTED_FACT_SCHEMA_VERSIONS_V2.has(rawInput.factSchemaVersion)) {
|
|
11593
|
+
throw new Error(`Unsupported fact schema version: ${rawInput.factSchemaVersion}`);
|
|
11594
|
+
}
|
|
11595
|
+
const input = evaluationInputV2Schema.parse(rawInput);
|
|
11596
|
+
const coverageSummary = deriveCoverageSummaryV1(input.analysisPlan, input.coverage);
|
|
11597
|
+
const profileKnown = input.integrity.profile.state === "known" && input.analysisPlan.profile.id === "react-web-v1" && SUPPORTED_REACT_WEB_PROFILE_VERSIONS_V1.has(input.analysisPlan.profile.version);
|
|
11598
|
+
const compatibilityInput = {
|
|
11599
|
+
contract: {
|
|
11600
|
+
state: "pinned",
|
|
11601
|
+
fcid: input.contract.fcid,
|
|
11602
|
+
preimage: input.contract.preimage,
|
|
11603
|
+
...!input.contract.active ? { stale: true } : {}
|
|
11604
|
+
},
|
|
11605
|
+
scope: { kind: "full", coverage: { filesScanned: coverageSummary.analyzedFiles } },
|
|
11606
|
+
evidence: { kind: "facts", facts: input.facts },
|
|
11607
|
+
policy: input.policy,
|
|
11608
|
+
...input.baseline ? {
|
|
11609
|
+
baseline: {
|
|
11610
|
+
identityVerified: true,
|
|
11611
|
+
findingStates: input.baseline.findingStates
|
|
11612
|
+
}
|
|
11613
|
+
} : {},
|
|
11614
|
+
...input.adoption !== void 0 ? { adoption: input.adoption } : {},
|
|
11615
|
+
...input.trust !== void 0 ? { trust: input.trust } : {},
|
|
11616
|
+
waivers: input.waivers.flatMap(
|
|
11617
|
+
(waiver) => waiver.matchedFindingFingerprints.map((fingerprint) => ({
|
|
11618
|
+
fingerprint,
|
|
11619
|
+
...waiver.expiresAt !== void 0 ? { expiresAt: waiver.expiresAt } : {}
|
|
11620
|
+
}))
|
|
11621
|
+
),
|
|
11622
|
+
integrity: {
|
|
11623
|
+
governance: input.integrity.governance,
|
|
11624
|
+
...input.integrity.inertConfigDiagnosticCount > 0 ? { inertConfigDiagnostics: input.integrity.inertConfigDiagnosticCount } : {}
|
|
11625
|
+
},
|
|
11626
|
+
evaluatedAt: input.evaluatedAt
|
|
11627
|
+
};
|
|
11628
|
+
const compatibilityResult = evaluateV1(compatibilityInput);
|
|
11629
|
+
const requiredCoverage = coverageSummary.requiredRegions === 0 ? "no_required_regions" : coverageSummary.requiredByState.analyzed === coverageSummary.requiredRegions ? "complete" : "incomplete";
|
|
11630
|
+
const integrity = {
|
|
11631
|
+
fcidVerified: compatibilityResult.integrity.fcidVerified === true,
|
|
11632
|
+
analysisPlanVerified: true,
|
|
11633
|
+
factIntegrity: input.integrity.facts.state,
|
|
11634
|
+
requiredCoverage,
|
|
11635
|
+
governance: input.integrity.governance,
|
|
11636
|
+
profile: profileKnown ? "known" : "unknown"
|
|
11637
|
+
};
|
|
11638
|
+
const reasons = new Set(compatibilityResult.reasons);
|
|
11639
|
+
if (requiredCoverage === "no_required_regions") reasons.add("requiredCoverageMissing");
|
|
11640
|
+
if (requiredCoverage === "incomplete") reasons.add("requiredCoverageIncomplete");
|
|
11641
|
+
if (integrity.factIntegrity === "conflict") reasons.add("factConflict");
|
|
11642
|
+
if (integrity.profile === "unknown") reasons.add("unknownAnalysisProfile");
|
|
11643
|
+
const orderedReasons = V2_REASON_ORDER.filter((reason) => reasons.has(reason));
|
|
11644
|
+
let verdict = compatibilityResult.verdict;
|
|
11645
|
+
if (orderedReasons.some((reason) => V2_INTEGRITY_REASONS.has(reason))) {
|
|
11646
|
+
verdict = "indeterminate";
|
|
11647
|
+
}
|
|
11648
|
+
const inputDigest = evaluationInputDigestV2(input);
|
|
11649
|
+
const partial = {
|
|
11650
|
+
schemaVersion: 2,
|
|
11651
|
+
verdict,
|
|
11652
|
+
reasons: orderedReasons,
|
|
11653
|
+
findings: compatibilityResult.findings.map((finding) => ({
|
|
11654
|
+
...finding,
|
|
11655
|
+
stateReasons: [...finding.stateReasons]
|
|
11656
|
+
})),
|
|
11657
|
+
counts: { ...compatibilityResult.counts },
|
|
11658
|
+
derived: { ...compatibilityResult.derived },
|
|
11659
|
+
coverageSummary,
|
|
11660
|
+
integrity
|
|
11661
|
+
};
|
|
11662
|
+
const resultDigest = evaluationResultDigestV2({ ...partial, inputDigest });
|
|
11663
|
+
return evaluationResultV2Schema.parse({ ...partial, inputDigest, resultDigest });
|
|
11664
|
+
}
|
|
11665
|
+
function evaluationInputDigestV2(input) {
|
|
11666
|
+
return sha256Hex(
|
|
11667
|
+
canonicalPreimage(
|
|
11668
|
+
normalizeInputV2ForDigest(input, deriveCoverageSummaryV1(input.analysisPlan, input.coverage))
|
|
11669
|
+
)
|
|
11670
|
+
);
|
|
11671
|
+
}
|
|
11672
|
+
function evaluationResultDigestV2(result) {
|
|
11673
|
+
return sha256Hex(canonicalPreimage({ schema: "evaluation-result:v2", ...result }));
|
|
11674
|
+
}
|
|
11675
|
+
function normalizeInputV2ForDigest(input, coverageSummary) {
|
|
11676
|
+
const {
|
|
11677
|
+
analysisPlanId: _analysisPlanId,
|
|
11678
|
+
createdAt: _createdAt,
|
|
11679
|
+
digest: _planDigest,
|
|
11680
|
+
obligationsDigest: _obligationsDigest,
|
|
11681
|
+
...analysisPlanSemantic
|
|
11682
|
+
} = input.analysisPlan;
|
|
11683
|
+
return {
|
|
11684
|
+
schema: "evaluation-input:v2",
|
|
11685
|
+
binding: input.binding,
|
|
11686
|
+
analysisPlan: {
|
|
11687
|
+
...analysisPlanSemantic,
|
|
11688
|
+
analysisPlanDigest: input.analysisPlan.digest,
|
|
11689
|
+
obligationsDigest: input.analysisPlan.obligationsDigest
|
|
11690
|
+
},
|
|
11691
|
+
contract: input.contract,
|
|
11692
|
+
factSchemaVersion: input.factSchemaVersion,
|
|
11693
|
+
factsDigest: input.factsDigest,
|
|
11694
|
+
coverage: [...input.coverage].map((region) => ({
|
|
11695
|
+
...region,
|
|
11696
|
+
diagnosticIds: [...region.diagnosticIds].sort(compareCanonicalStrings)
|
|
11697
|
+
})).sort((left, right) => compareCanonicalStrings(left.regionId, right.regionId)),
|
|
11698
|
+
coverageSummary,
|
|
11699
|
+
policy: input.policy,
|
|
11700
|
+
baseline: input.baseline,
|
|
11701
|
+
adoption: input.adoption,
|
|
11702
|
+
trust: input.trust,
|
|
11703
|
+
waivers: input.waivers.map((waiver) => ({
|
|
11704
|
+
...waiver,
|
|
11705
|
+
matchedFindingFingerprints: [...waiver.matchedFindingFingerprints].sort(
|
|
11706
|
+
compareCanonicalStrings
|
|
11707
|
+
)
|
|
11708
|
+
})).sort((left, right) => compareCanonicalStrings(left.waiverId, right.waiverId)),
|
|
11709
|
+
integrity: input.integrity,
|
|
11710
|
+
evaluatedAt: input.evaluatedAt,
|
|
11711
|
+
evaluatorVersion: input.evaluatorVersion
|
|
11712
|
+
};
|
|
11713
|
+
}
|
|
11714
|
+
function evidenceFindings(input) {
|
|
11715
|
+
if (input.evidence.kind === "findings") return [...input.evidence.findings];
|
|
11716
|
+
const ruleConfig = readRuleConfig(input.evidence.facts);
|
|
11717
|
+
return runRules(input.evidence.facts).map((finding) => ({
|
|
11718
|
+
fingerprint: finding.fingerprint,
|
|
11719
|
+
ruleId: finding.ruleId,
|
|
11720
|
+
severity: severityLevel(configuredFindingSeverity(finding, ruleConfig)),
|
|
11721
|
+
advisory: finding.attributes?.advisory === true,
|
|
11722
|
+
evidenceGrade: finding.evidenceGrade
|
|
11723
|
+
}));
|
|
11724
|
+
}
|
|
11725
|
+
var STATE_RANK = { blocked: 0, pending_cloud_trust: 1, advisory: 2 };
|
|
11726
|
+
var SEVERITY_RANK2 = { error: 0, warn: 1, info: 2 };
|
|
11727
|
+
function canonicalRow(finding) {
|
|
11728
|
+
return {
|
|
11729
|
+
fingerprint: finding.fingerprint,
|
|
11730
|
+
ruleId: finding.ruleId,
|
|
11731
|
+
severity: finding.severity,
|
|
11732
|
+
advisory: finding.advisory === true,
|
|
11733
|
+
evidenceGrade: coerceEvidenceGrade(finding.evidenceGrade),
|
|
11734
|
+
waived: finding.waived === true,
|
|
11735
|
+
...finding.sourceTrust !== void 0 ? { sourceTrust: finding.sourceTrust } : {},
|
|
11736
|
+
...finding.mappingTrust !== void 0 ? { mappingTrust: finding.mappingTrust } : {},
|
|
11737
|
+
...finding.baselineState !== void 0 ? { baselineState: finding.baselineState } : {}
|
|
11738
|
+
};
|
|
11739
|
+
}
|
|
11740
|
+
function compareStrings(a, b) {
|
|
11741
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
11742
|
+
}
|
|
11743
|
+
function compareRows(a, b) {
|
|
11744
|
+
return compareStrings(a.fingerprint, b.fingerprint) || SEVERITY_RANK2[a.severity] - SEVERITY_RANK2[b.severity] || compareStrings(a.ruleId, b.ruleId) || Number(a.advisory ?? false) - Number(b.advisory ?? false) || compareStrings(a.evidenceGrade ?? "", b.evidenceGrade ?? "") || Number(a.waived ?? false) - Number(b.waived ?? false) || compareStrings(a.sourceTrust ?? "", b.sourceTrust ?? "") || compareStrings(a.mappingTrust ?? "", b.mappingTrust ?? "") || compareStrings(a.baselineState ?? "", b.baselineState ?? "");
|
|
11745
|
+
}
|
|
11746
|
+
function canonicalRows(findings) {
|
|
11747
|
+
const sorted = findings.map(canonicalRow).sort(compareRows);
|
|
11748
|
+
return sorted.filter((row, index) => index === 0 || compareRows(row, sorted[index - 1]) !== 0);
|
|
11749
|
+
}
|
|
11750
|
+
function groupByFingerprint(findings) {
|
|
11751
|
+
const groups = /* @__PURE__ */ new Map();
|
|
11752
|
+
for (const row of canonicalRows(findings)) {
|
|
11753
|
+
const group = groups.get(row.fingerprint);
|
|
11754
|
+
if (group) group.push(row);
|
|
11755
|
+
else groups.set(row.fingerprint, [row]);
|
|
11756
|
+
}
|
|
11757
|
+
return groups;
|
|
11758
|
+
}
|
|
11759
|
+
function classifyFinding(finding, input, activeWaivers) {
|
|
11760
|
+
const base = {
|
|
11761
|
+
fingerprint: finding.fingerprint,
|
|
11762
|
+
ruleId: finding.ruleId,
|
|
11763
|
+
severity: finding.severity
|
|
11764
|
+
};
|
|
11765
|
+
if (activeWaivers.has(finding.fingerprint) || finding.waived === true) {
|
|
11766
|
+
return { ...base, state: "advisory", stateReasons: ["waived"] };
|
|
11767
|
+
}
|
|
11768
|
+
const eligibility = eligibilityFor(finding, input.policy);
|
|
11769
|
+
if (eligibility !== null) {
|
|
11770
|
+
return { ...base, state: "advisory", stateReasons: [eligibility] };
|
|
11771
|
+
}
|
|
11772
|
+
const introduced = introducedFactFor(finding, input);
|
|
11773
|
+
if (introduced.state === "negative") {
|
|
11774
|
+
return { ...base, state: "advisory", stateReasons: ["baseline:existing"] };
|
|
11775
|
+
}
|
|
11776
|
+
const requirement = input.policy.rules?.[finding.ruleId]?.trust ?? defaultTrustRequirement(finding.ruleId);
|
|
11777
|
+
const mappingBinds = requirement === "canonical" || defaultTrustRequirement(finding.ruleId) === "canonical";
|
|
11778
|
+
if (requirement === "none") {
|
|
11779
|
+
const definitives = [sourceFact(finding, input)];
|
|
11780
|
+
if (mappingBinds) definitives.push(mappingFact(finding, input));
|
|
11781
|
+
const definitiveNegative = definitives.find(([, state]) => state === "negative");
|
|
11782
|
+
if (definitiveNegative) {
|
|
11783
|
+
return { ...base, state: "advisory", stateReasons: [`trust:${definitiveNegative[0]}`] };
|
|
11784
|
+
}
|
|
11785
|
+
return { ...base, state: "blocked", stateReasons: [`eligible:${finding.severity}`] };
|
|
11786
|
+
}
|
|
11787
|
+
const facts = [
|
|
11788
|
+
[`introduced:${introduced.detail}`, introduced.state],
|
|
11789
|
+
sourceFact(finding, input)
|
|
11790
|
+
];
|
|
11791
|
+
if (requirement === "canonical") {
|
|
11792
|
+
facts.push(mappingFact(finding, input));
|
|
11793
|
+
} else if (mappingBinds) {
|
|
11794
|
+
const mapping = mappingFact(finding, input);
|
|
11795
|
+
if (mapping[1] === "negative") facts.push(mapping);
|
|
11796
|
+
}
|
|
11797
|
+
const negative = facts.find(([, state]) => state === "negative");
|
|
11798
|
+
if (negative) {
|
|
11799
|
+
return { ...base, state: "advisory", stateReasons: [`trust:${negative[0]}`] };
|
|
11800
|
+
}
|
|
11801
|
+
const unknowns = facts.filter(([, state]) => state === "unknown");
|
|
11802
|
+
if (unknowns.length > 0) {
|
|
11803
|
+
return {
|
|
11804
|
+
...base,
|
|
11805
|
+
state: "pending_cloud_trust",
|
|
11806
|
+
stateReasons: unknowns.map(([label]) => `trust:${label}`)
|
|
11807
|
+
};
|
|
11808
|
+
}
|
|
11809
|
+
return { ...base, state: "blocked", stateReasons: [`eligible:${finding.severity}`, "trust:all"] };
|
|
11810
|
+
}
|
|
11811
|
+
function eligibilityFor(finding, policy) {
|
|
11812
|
+
if (finding.advisory === true) return "ineligible:advisory-tier";
|
|
11813
|
+
if (!canBlock(coerceEvidenceGrade(finding.evidenceGrade))) return "ineligible:evidence-grade";
|
|
11814
|
+
if (finding.severity === "error") return null;
|
|
11815
|
+
if (finding.severity === "warn") {
|
|
11816
|
+
return policy.failOnWarnings ? null : "ineligible:warn-not-gated";
|
|
11817
|
+
}
|
|
11818
|
+
return "ineligible:info";
|
|
11819
|
+
}
|
|
11820
|
+
function coerceEvidenceGrade(grade) {
|
|
11821
|
+
if (grade === void 0) return "source_backed";
|
|
11822
|
+
return EVIDENCE_ORDER.includes(grade) ? grade : "none";
|
|
11823
|
+
}
|
|
11824
|
+
function defaultTrustRequirement(ruleId) {
|
|
11825
|
+
return tierFor(ruleId) === "contract" ? "canonical" : "evidence";
|
|
11826
|
+
}
|
|
11827
|
+
function introducedFactFor(finding, input) {
|
|
11828
|
+
const baseline = input.baseline;
|
|
11829
|
+
if (!baseline) return { state: "unknown", detail: "no-baseline" };
|
|
11830
|
+
if (!baseline.identityVerified) return { state: "unknown", detail: "identity-unverified" };
|
|
11831
|
+
const recorded = finding.baselineState ?? baseline.findingStates?.[finding.fingerprint] ?? "introduced";
|
|
11832
|
+
if (recorded === "existing") return { state: "negative", detail: "existing" };
|
|
11833
|
+
if (recorded === "introduced") return { state: "affirmative", detail: "introduced" };
|
|
11834
|
+
return { state: "unknown", detail: "unknown" };
|
|
11835
|
+
}
|
|
11836
|
+
function sourceFact(finding, input) {
|
|
11837
|
+
const source = finding.sourceTrust ?? input.trust?.sources?.[finding.fingerprint] ?? input.trust?.source ?? "unknown";
|
|
11838
|
+
if (source === "verified") return ["source:verified", "affirmative"];
|
|
11839
|
+
if (source === "unverified") return ["source:non-reproduction", "negative"];
|
|
11840
|
+
return ["source:unknown", "unknown"];
|
|
11841
|
+
}
|
|
11842
|
+
function mappingFact(finding, input) {
|
|
11843
|
+
const mapping = finding.mappingTrust ?? input.trust?.mappings[finding.fingerprint] ?? "unknown";
|
|
11844
|
+
if (mapping === "confirmed") return ["mapping:confirmed", "affirmative"];
|
|
11845
|
+
if (mapping === "unconfirmed") return ["mapping:unconfirmed", "negative"];
|
|
11846
|
+
return ["mapping:unknown", "unknown"];
|
|
11847
|
+
}
|
|
11848
|
+
function normalizeInputForDigest(input) {
|
|
11849
|
+
return {
|
|
11850
|
+
schema: "evaluation-input:v1",
|
|
11851
|
+
contract: input.contract,
|
|
11852
|
+
scope: input.scope,
|
|
11853
|
+
evidence: canonicalRows(evidenceFindings(input)),
|
|
11854
|
+
policy: input.policy,
|
|
11855
|
+
baseline: input.baseline,
|
|
11856
|
+
adoption: input.adoption,
|
|
11857
|
+
trust: input.trust,
|
|
11858
|
+
waivers: canonicalWaivers(input.waivers ?? []),
|
|
11859
|
+
integrity: {
|
|
11860
|
+
...input.integrity,
|
|
11861
|
+
...input.integrity.unknownPresets ? { unknownPresets: [...new Set(input.integrity.unknownPresets)].sort() } : {}
|
|
11862
|
+
},
|
|
11863
|
+
evaluatedAt: input.evaluatedAt
|
|
11864
|
+
};
|
|
11865
|
+
}
|
|
11866
|
+
function canonicalWaivers(waivers) {
|
|
11867
|
+
const expiryOf = (waiver) => waiver.expiresAt === void 0 || Number.isNaN(waiver.expiresAt) ? Number.POSITIVE_INFINITY : waiver.expiresAt;
|
|
11868
|
+
const canonical = waivers.map((waiver) => {
|
|
11869
|
+
const expiresAt = expiryOf(waiver);
|
|
11870
|
+
return expiresAt === Number.POSITIVE_INFINITY ? { fingerprint: waiver.fingerprint } : { fingerprint: waiver.fingerprint, expiresAt };
|
|
11871
|
+
});
|
|
11872
|
+
const sorted = canonical.sort((a, b) => {
|
|
11873
|
+
if (a.fingerprint !== b.fingerprint) return a.fingerprint < b.fingerprint ? -1 : 1;
|
|
11874
|
+
const ea = expiryOf(a);
|
|
11875
|
+
const eb = expiryOf(b);
|
|
11876
|
+
return ea === eb ? 0 : ea < eb ? -1 : 1;
|
|
11877
|
+
});
|
|
11878
|
+
return sorted.filter(
|
|
11879
|
+
(waiver, index) => index === 0 || waiver.fingerprint !== sorted[index - 1].fingerprint || expiryOf(waiver) !== expiryOf(sorted[index - 1])
|
|
11880
|
+
);
|
|
11881
|
+
}
|
|
11882
|
+
|
|
11883
|
+
// src/approved-contract-tokens.ts
|
|
11884
|
+
var APPROVED_CONTRACT_TOKEN_MAX_NAMES = 1e4;
|
|
11885
|
+
var APPROVED_CONTRACT_TOKEN_MAX_NAME_LENGTH = 512;
|
|
11886
|
+
function isApprovedContractTokenNames(value) {
|
|
11887
|
+
return Array.isArray(value) && value.length <= APPROVED_CONTRACT_TOKEN_MAX_NAMES && value.every(
|
|
11888
|
+
(name) => typeof name === "string" && name.startsWith("--") && name.length > 2 && name.length <= APPROVED_CONTRACT_TOKEN_MAX_NAME_LENGTH
|
|
11889
|
+
);
|
|
11890
|
+
}
|
|
9939
11891
|
export {
|
|
9940
11892
|
AGENT_CONTEXT_RELATIVE_PATH,
|
|
9941
11893
|
AGENT_FORMAT_SCHEMA_VERSION,
|
|
11894
|
+
ANALYSIS_LIMIT_CEILINGS_V1,
|
|
11895
|
+
ANALYSIS_PLAN_MAX_CAPABILITIES_V1,
|
|
11896
|
+
ANALYSIS_PLAN_MAX_DIALECTS_PER_REGION_V1,
|
|
11897
|
+
ANALYSIS_PLAN_MAX_REGIONS_V1,
|
|
11898
|
+
APPROVED_CONTRACT_TOKEN_MAX_NAMES,
|
|
11899
|
+
APPROVED_CONTRACT_TOKEN_MAX_NAME_LENGTH,
|
|
9942
11900
|
BLOCKING_RULE_ALLOWLIST,
|
|
9943
11901
|
BRAND,
|
|
11902
|
+
CANONICAL_FACT_MAX_CONFLICTS_V1,
|
|
11903
|
+
CANONICAL_FACT_MAX_PROVENANCE_PER_VALUE_V1,
|
|
11904
|
+
CANONICAL_FACT_MAX_VALUES_PER_CONFLICT_V1,
|
|
9944
11905
|
CATALOG_FIXTURE_A_FCID,
|
|
9945
11906
|
CODES,
|
|
11907
|
+
CONTRACT_DISPLAY_ONLY_FIELDS,
|
|
9946
11908
|
CONTRACT_DOMAINS,
|
|
11909
|
+
CONTRACT_ENFORCEMENT_FIELDS,
|
|
9947
11910
|
CONTRACT_PREIMAGE_CAPABILITY_HEADER,
|
|
9948
11911
|
CONTRACT_PREIMAGE_SCHEMA,
|
|
9949
11912
|
CompiledFragmentsFileValidationError,
|
|
11913
|
+
ContractCatalogValidationError,
|
|
11914
|
+
CoverageValidationErrorV1,
|
|
9950
11915
|
DEFAULTS,
|
|
9951
11916
|
DEFAULT_ENHANCED_STYLE_PROPERTIES,
|
|
9952
11917
|
DEFAULT_STYLE_PROPERTIES,
|
|
9953
11918
|
EFFECTIVE_GOVERNANCE_INPUTS_SCHEMA,
|
|
11919
|
+
EMPTY_VOCABULARY_MESSAGE,
|
|
11920
|
+
EVALUATION_MAX_FINDINGS_V2,
|
|
11921
|
+
EVALUATION_MAX_MAP_ENTRIES_V2,
|
|
11922
|
+
EVALUATION_MAX_POLICY_RULES_V2,
|
|
11923
|
+
EVALUATION_MAX_REASON_CODES_V2,
|
|
11924
|
+
EVALUATION_MAX_WAIVERS_V2,
|
|
11925
|
+
EVALUATION_MAX_WAIVER_MATCHES_V2,
|
|
11926
|
+
EVALUATION_RECEIPT_STRING_MAX_BYTES_V1,
|
|
11927
|
+
EVALUATOR_VERSION,
|
|
11928
|
+
EVALUATOR_VERSION_V2,
|
|
9954
11929
|
EVIDENCE_ORDER,
|
|
9955
11930
|
EXPLAIN_URL_BASE,
|
|
9956
11931
|
FRAGMENTS_INTERNAL_RULE_IDS,
|
|
11932
|
+
FRAGMENTS_MANIFEST_FILENAME,
|
|
11933
|
+
FRAGMENTS_MANIFEST_SCHEMA_VERSION,
|
|
11934
|
+
FRAGMENTS_MANIFEST_TOKEN_RULE,
|
|
11935
|
+
FRAGMENT_V3_SCHEMA_URL,
|
|
9957
11936
|
FactIndex,
|
|
9958
11937
|
GOVERNANCE_TELEMETRY_FIELDS,
|
|
9959
11938
|
GOVERNANCE_TELEMETRY_SOURCE_DISCLOSURE,
|
|
@@ -9963,13 +11942,18 @@ export {
|
|
|
9963
11942
|
PRESET_NAMES,
|
|
9964
11943
|
PROVE_DEFAULT_MAX_PASSES,
|
|
9965
11944
|
PROVE_MAX_PASSES,
|
|
11945
|
+
PROVIDER_ID_MAX_BYTES_V1,
|
|
9966
11946
|
RAW_HTML_ADVISORY_TAGS,
|
|
9967
11947
|
RAW_HTML_CANONICAL_TAGS,
|
|
9968
11948
|
RAW_HTML_INPUT_TYPE_CANONICALS,
|
|
9969
11949
|
RAW_HTML_ROLE_CANONICALS,
|
|
9970
11950
|
REGISTRY_ARTIFACT_SCHEMA_VERSION,
|
|
11951
|
+
REGISTRY_INDEX_SCHEMA_VERSION,
|
|
9971
11952
|
REGISTRY_INSTALL_RECEIPT_SCHEMA_VERSION,
|
|
9972
11953
|
REGISTRY_MANIFEST_SCHEMA_VERSION,
|
|
11954
|
+
REGISTRY_POINTER_SCHEMA_VERSION,
|
|
11955
|
+
REGISTRY_SHARD_SCHEMA_VERSION,
|
|
11956
|
+
REPOSITORY_BINDING_ID_MAX_BYTES_V1,
|
|
9973
11957
|
RULES,
|
|
9974
11958
|
RULE_FAMILY_IDS,
|
|
9975
11959
|
RULE_FAMILY_MEMBERS,
|
|
@@ -9982,8 +11966,19 @@ export {
|
|
|
9982
11966
|
agentIntegritySchema,
|
|
9983
11967
|
agentOutputSchema,
|
|
9984
11968
|
aiMetadataSchema,
|
|
11969
|
+
analysisLimitsV1Schema,
|
|
11970
|
+
analysisObligationsDigestV1,
|
|
11971
|
+
analysisPlanDigestV1,
|
|
11972
|
+
analysisPlanIdFromDigest,
|
|
11973
|
+
analysisPlanIdSchema,
|
|
11974
|
+
analysisPlanIdStringSchema,
|
|
11975
|
+
analysisPlanInputV1Schema,
|
|
11976
|
+
analysisPlanV1Schema,
|
|
11977
|
+
analysisRegionV1Schema,
|
|
9985
11978
|
analyzeComposition,
|
|
11979
|
+
artifactContentHash,
|
|
9986
11980
|
asComponentId,
|
|
11981
|
+
assembleRegistryArtifact,
|
|
9987
11982
|
assertPortableRegistryPath,
|
|
9988
11983
|
assertValidRegistryArtifact,
|
|
9989
11984
|
authorOwnedImport,
|
|
@@ -9992,11 +11987,13 @@ export {
|
|
|
9992
11987
|
bridgeSourceViolations,
|
|
9993
11988
|
budgetBar,
|
|
9994
11989
|
buildAgentFormat,
|
|
11990
|
+
buildAnalysisPlanV1,
|
|
9995
11991
|
buildComponentKey,
|
|
9996
11992
|
buildRegistryArtifact,
|
|
9997
11993
|
buildRegistryFile,
|
|
9998
11994
|
buildRegistryInstallPlan,
|
|
9999
11995
|
buildRegistryInstallReceipt,
|
|
11996
|
+
buildRegistryPointer,
|
|
10000
11997
|
buildSpacingTokenLookup,
|
|
10001
11998
|
bundleArtifactMetadataSchema,
|
|
10002
11999
|
bundleComponentShardSchema,
|
|
@@ -10014,14 +12011,17 @@ export {
|
|
|
10014
12011
|
canonicalBridgeIdentitySources,
|
|
10015
12012
|
canonicalBridgeV1Schema,
|
|
10016
12013
|
canonicalDirectionConflictsTarget,
|
|
12014
|
+
canonicalFactConflictV1Schema,
|
|
12015
|
+
canonicalFactConflictValueV1Schema,
|
|
12016
|
+
canonicalFactIntegrityV1Schema,
|
|
10017
12017
|
canonicalJson,
|
|
10018
12018
|
canonicalPreimage,
|
|
10019
12019
|
canonicalizeOwnedComponentId,
|
|
10020
12020
|
canonicalizeOwnedImport,
|
|
12021
|
+
capConfiguredSeverity,
|
|
10021
12022
|
catalogFixtureA,
|
|
10022
12023
|
catalogFixtureAContractPayload,
|
|
10023
12024
|
catalogFixtureATokensDtcg,
|
|
10024
|
-
checkStoryExclusion,
|
|
10025
12025
|
clampMaxPasses,
|
|
10026
12026
|
classifyComplexity,
|
|
10027
12027
|
classifyIdentity,
|
|
@@ -10041,7 +12041,6 @@ export {
|
|
|
10041
12041
|
compileEffectiveGovernanceInputs,
|
|
10042
12042
|
compileFragment,
|
|
10043
12043
|
compileGlobalGovernanceFacts,
|
|
10044
|
-
compileRecipe,
|
|
10045
12044
|
componentContractSchema,
|
|
10046
12045
|
componentGovernanceRecordSchema,
|
|
10047
12046
|
componentGovernanceRecordsSchema,
|
|
@@ -10053,28 +12052,50 @@ export {
|
|
|
10053
12052
|
computeRegistryHash,
|
|
10054
12053
|
configDeclarationForDiagnostics,
|
|
10055
12054
|
configRecordShape,
|
|
12055
|
+
configuredFindingSeverity,
|
|
10056
12056
|
containsTailwindV4Theme,
|
|
10057
12057
|
contractComponentsFromFragments,
|
|
10058
12058
|
contractHash,
|
|
10059
12059
|
contractPolicyFromGovernanceConfig,
|
|
10060
12060
|
contractTierRuleIds,
|
|
10061
12061
|
contractTokenReferenceCensus,
|
|
12062
|
+
coverageArtifactDigestV1,
|
|
12063
|
+
coverageRegionV1Schema,
|
|
12064
|
+
coverageStateV1Schema,
|
|
12065
|
+
coverageSummaryV1Schema,
|
|
10062
12066
|
customerDefaultRuleStates,
|
|
12067
|
+
defaultRegistryShardPath,
|
|
10063
12068
|
defineBlock,
|
|
10064
12069
|
defineConfig,
|
|
10065
12070
|
defineFragment,
|
|
10066
|
-
|
|
12071
|
+
deriveArtifactId,
|
|
12072
|
+
deriveCoverageSummaryV1,
|
|
10067
12073
|
describePolicyExclude,
|
|
10068
12074
|
detectOrphanGovernanceScales,
|
|
10069
|
-
detectSubComponentPaths,
|
|
10070
12075
|
detectUnconsumedConfigKeys,
|
|
10071
12076
|
detectUnmatchedPolicyExcludes,
|
|
10072
12077
|
diffContractDomains,
|
|
12078
|
+
digestHexSchema,
|
|
12079
|
+
digestHexStringSchema,
|
|
10073
12080
|
discoverComponents,
|
|
10074
12081
|
dtcgTokenFileSchema,
|
|
12082
|
+
effectiveEvaluationWaiverV2Schema,
|
|
10075
12083
|
emptyConformResult,
|
|
12084
|
+
emptyVocabularyConfigFile,
|
|
12085
|
+
evaluate2 as evaluate,
|
|
10076
12086
|
evaluateGovernanceIntegrity,
|
|
12087
|
+
evaluationInputDigestV2,
|
|
12088
|
+
evaluationInputV2Schema,
|
|
12089
|
+
evaluationReceiptDigestV1,
|
|
12090
|
+
evaluationReceiptIdFromDigest,
|
|
12091
|
+
evaluationReceiptIdSchema,
|
|
12092
|
+
evaluationReceiptIdStringSchema,
|
|
12093
|
+
evaluationReceiptMintInputV1Schema,
|
|
12094
|
+
evaluationReceiptV1Schema,
|
|
12095
|
+
evaluationResultDigestV2,
|
|
12096
|
+
evaluationResultV2Schema,
|
|
10077
12097
|
excludeGlobToRegExp,
|
|
12098
|
+
expandRegistryComponentClosure,
|
|
10078
12099
|
explainUrlForCode,
|
|
10079
12100
|
factEvidenceSchema,
|
|
10080
12101
|
factId,
|
|
@@ -10096,16 +12117,32 @@ export {
|
|
|
10096
12117
|
formatStampPin,
|
|
10097
12118
|
formatStampVersionHash,
|
|
10098
12119
|
formatTokenSummary,
|
|
12120
|
+
fragmentAnnotationsV3Schema,
|
|
10099
12121
|
fragmentBanSchema,
|
|
10100
12122
|
fragmentContractSchema,
|
|
10101
12123
|
fragmentDefinitionSchema,
|
|
10102
12124
|
fragmentDefinitionV2Schema,
|
|
12125
|
+
fragmentDefinitionV3BodySchema,
|
|
12126
|
+
fragmentDefinitionV3Schema,
|
|
12127
|
+
fragmentDesignV3Schema,
|
|
12128
|
+
fragmentDontExampleV3Schema,
|
|
10103
12129
|
fragmentGeneratedSchema,
|
|
12130
|
+
fragmentGuidanceV3Schema,
|
|
12131
|
+
fragmentMatrixV3Schema,
|
|
10104
12132
|
fragmentMetaSchema,
|
|
12133
|
+
fragmentMetaV3Schema,
|
|
12134
|
+
fragmentPreviewV3Schema,
|
|
10105
12135
|
fragmentProvenanceSchema,
|
|
12136
|
+
fragmentSourceValues,
|
|
12137
|
+
fragmentStateV3Schema,
|
|
10106
12138
|
fragmentUsageSchema,
|
|
10107
12139
|
fragmentVariantSchema,
|
|
10108
12140
|
fragmentsConfigSchema,
|
|
12141
|
+
fragmentsManifestFcid,
|
|
12142
|
+
fragmentsManifestGrammarSchema,
|
|
12143
|
+
fragmentsManifestPatternSchema,
|
|
12144
|
+
fragmentsManifestPrimitiveSchema,
|
|
12145
|
+
fragmentsManifestSchema,
|
|
10109
12146
|
fragmentsPresetRuleStates,
|
|
10110
12147
|
g,
|
|
10111
12148
|
gatesCi,
|
|
@@ -10132,9 +12169,9 @@ export {
|
|
|
10132
12169
|
indexComponentIdentityUsage,
|
|
10133
12170
|
inferTokenCategory,
|
|
10134
12171
|
inferTokenGroup,
|
|
12172
|
+
isApprovedContractTokenNames,
|
|
10135
12173
|
isColorLike,
|
|
10136
12174
|
isCompositionPattern,
|
|
10137
|
-
isConfigExcluded,
|
|
10138
12175
|
isContractFile,
|
|
10139
12176
|
isContractTierRule,
|
|
10140
12177
|
isDTCGFile,
|
|
@@ -10142,7 +12179,6 @@ export {
|
|
|
10142
12179
|
isEffectiveCanonicalSource,
|
|
10143
12180
|
isEnforceableHtmlEquivalent,
|
|
10144
12181
|
isFigmaPropMapping,
|
|
10145
|
-
isForceIncluded,
|
|
10146
12182
|
isPortableRepoPath,
|
|
10147
12183
|
isPresetSourcedRule,
|
|
10148
12184
|
isRawHtmlAdvisoryTier,
|
|
@@ -10215,8 +12251,11 @@ export {
|
|
|
10215
12251
|
mcpSourceTypeSchema,
|
|
10216
12252
|
mcpTokenDataSchema,
|
|
10217
12253
|
mcpTokenSchema,
|
|
12254
|
+
mintEvaluationReceiptId,
|
|
10218
12255
|
nearestByDeltaE,
|
|
10219
12256
|
nearestSignedScaleValue,
|
|
12257
|
+
normalizeAnalysisPlanInputV1,
|
|
12258
|
+
normalizeCanonicalFactIntegrityV1,
|
|
10220
12259
|
normalizeColor,
|
|
10221
12260
|
normalizeConfigPath,
|
|
10222
12261
|
normalizeExcludePath,
|
|
@@ -10224,6 +12263,7 @@ export {
|
|
|
10224
12263
|
normalizeGovernanceConfig,
|
|
10225
12264
|
normalizePolicyExcludes,
|
|
10226
12265
|
normalizeRegistryRepoPath,
|
|
12266
|
+
normalizeRepositoryBindingKeyV1,
|
|
10227
12267
|
normalizeSeverity,
|
|
10228
12268
|
normalizeStyleValue,
|
|
10229
12269
|
normalizeToV1,
|
|
@@ -10232,15 +12272,22 @@ export {
|
|
|
10232
12272
|
normalizeViolation,
|
|
10233
12273
|
overriddenRecordSeverityDiagnostic,
|
|
10234
12274
|
ownedImportEquivalents,
|
|
12275
|
+
parseAnalysisPlanId,
|
|
12276
|
+
parseAnalysisPlanV1,
|
|
10235
12277
|
parseColor,
|
|
10236
12278
|
parseColorToRgb,
|
|
10237
12279
|
parseCompiledFragmentsFile,
|
|
10238
12280
|
parseComponentContract,
|
|
12281
|
+
parseComponentGovernancePolicyJson,
|
|
10239
12282
|
parseContractStamp,
|
|
10240
12283
|
parseCssTokens,
|
|
10241
12284
|
parseDtcgTokens as parseDTCGFile,
|
|
10242
12285
|
parseDesignTokenContent,
|
|
12286
|
+
parseDigestHex,
|
|
10243
12287
|
parseDtcgTokens,
|
|
12288
|
+
parseEvaluationReceiptId,
|
|
12289
|
+
parseEvaluationReceiptV1,
|
|
12290
|
+
parseFragmentsManifest,
|
|
10244
12291
|
parseRgb,
|
|
10245
12292
|
parseScssTokens,
|
|
10246
12293
|
parseScssVariables,
|
|
@@ -10252,13 +12299,17 @@ export {
|
|
|
10252
12299
|
portableRepoPathError,
|
|
10253
12300
|
projectCanonicalDirectionConflicts,
|
|
10254
12301
|
projectContractPreimage,
|
|
12302
|
+
projectEnforcementContract,
|
|
10255
12303
|
projectSupersededImportPathPreferences,
|
|
10256
12304
|
projectV1OwnedComponentId,
|
|
10257
12305
|
projectV1OwnedImportIdentity,
|
|
12306
|
+
propAnnotationSchema,
|
|
10258
12307
|
propDefinitionSchema,
|
|
10259
12308
|
proveCompliant,
|
|
10260
12309
|
proveIssueCount,
|
|
10261
|
-
|
|
12310
|
+
providerProofDigestV1,
|
|
12311
|
+
providerProofV1Schema,
|
|
12312
|
+
readRuleConfig,
|
|
10262
12313
|
registryArtifactDigest,
|
|
10263
12314
|
registryArtifactSchema,
|
|
10264
12315
|
registryComponentExportSchema,
|
|
@@ -10270,23 +12321,36 @@ export {
|
|
|
10270
12321
|
registryFileRoleSchema,
|
|
10271
12322
|
registryFileSchema,
|
|
10272
12323
|
registryFileSize,
|
|
12324
|
+
registryIndexSchema,
|
|
10273
12325
|
registryInstallProfileSchema,
|
|
10274
12326
|
registryInstallReceiptComponentSchema,
|
|
10275
12327
|
registryInstallReceiptFileSchema,
|
|
10276
12328
|
registryInstallReceiptSchema,
|
|
10277
12329
|
registryManifestCanonicalPreimage,
|
|
10278
12330
|
registryManifestDraftSchema,
|
|
12331
|
+
registryManifestFileMetadata,
|
|
12332
|
+
registryManifestFilePaths,
|
|
10279
12333
|
registryManifestSchema,
|
|
12334
|
+
registryPointerSchema,
|
|
12335
|
+
registryShardSchema,
|
|
12336
|
+
registryShardsForPaths,
|
|
10280
12337
|
registrySourceSchema,
|
|
12338
|
+
repositoryBindingDigestV1,
|
|
12339
|
+
repositoryBindingKeyV1Schema,
|
|
10281
12340
|
resolveArea,
|
|
10282
12341
|
resolveCanonicalForAriaRole,
|
|
10283
12342
|
resolveCanonicalForRawHtml,
|
|
12343
|
+
resolveComponentGovernance,
|
|
10284
12344
|
resolveConfiguredAppPath,
|
|
10285
12345
|
resolveDesignTokenValue,
|
|
10286
12346
|
resolveFigmaMapping,
|
|
12347
|
+
resolveGovernanceRecordsForIdentity,
|
|
10287
12348
|
resolveOwnedPackageImport,
|
|
10288
12349
|
resolvePerformanceConfig,
|
|
10289
12350
|
resolveProveVerdict,
|
|
12351
|
+
resolveRegistryComponentId,
|
|
12352
|
+
resolveRegistryInstallSelection,
|
|
12353
|
+
resolveRegistryInstallSources,
|
|
10290
12354
|
resolveSpacingValue,
|
|
10291
12355
|
resolveTokenValue,
|
|
10292
12356
|
rgbToHex,
|
|
@@ -10314,11 +12378,11 @@ export {
|
|
|
10314
12378
|
ruleTokensRequireDualFallback,
|
|
10315
12379
|
runRules,
|
|
10316
12380
|
scaleGovernanceRecordSchema,
|
|
10317
|
-
selectedRegistryComponentNames,
|
|
10318
12381
|
serializeContractStamp,
|
|
10319
12382
|
severityLevel,
|
|
10320
12383
|
severitySchema,
|
|
10321
12384
|
sha256Hex,
|
|
12385
|
+
shardRegistryArtifact,
|
|
10322
12386
|
sortBySeverity,
|
|
10323
12387
|
sourceToRegistryTargetPath,
|
|
10324
12388
|
suppressionDirectiveSchema,
|