@usefragments/core 1.10.1 → 1.11.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-YF65VYRY.js → chunk-ML5S6QNU.js} +191 -169
- package/dist/chunk-ML5S6QNU.js.map +1 -0
- package/dist/chunk-PWIJMOI4.js +202 -0
- package/dist/chunk-PWIJMOI4.js.map +1 -0
- package/dist/{chunk-XN3LSDPY.js → chunk-RPSEABY3.js} +622 -344
- package/dist/chunk-RPSEABY3.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-BAsy1k2H.d.ts} +472 -513
- 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 +9165 -1297
- package/dist/index.js +3044 -352
- 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/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/codes/__tests__/codes.test.ts +9 -0
- package/src/codes/codes.ts +30 -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 +52 -0
- package/src/domain-ids.ts +106 -0
- package/src/evaluation/evaluate.test.ts +522 -0
- package/src/evaluation/evaluate.ts +680 -0
- package/src/evaluation/evaluation-v2-receipt-v1.test.ts +760 -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/feature-plan/digest.ts +217 -0
- package/src/feature-plan/feature-plan-v1.test.ts +529 -0
- package/src/feature-plan/index.ts +65 -0
- package/src/feature-plan/types.ts +628 -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 +52 -8
- package/src/index.ts +299 -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/tokens/scss.test.ts +32 -1
- package/src/tokens/scss.ts +12 -7
- package/src/types.ts +258 -37
- 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-3LLRNCPX.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,11 +103,22 @@ 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,
|
|
38
114
|
factId,
|
|
39
115
|
factLocationSchema,
|
|
116
|
+
featurePlanIdFromEntropy,
|
|
117
|
+
featurePlanIdSchema,
|
|
118
|
+
featurePlanIdStringSchema,
|
|
119
|
+
featureRevisionIdFromDigest,
|
|
120
|
+
featureRevisionIdSchema,
|
|
121
|
+
featureRevisionIdStringSchema,
|
|
40
122
|
findingFixSchema,
|
|
41
123
|
findingReplaceClassTokenFixSchema,
|
|
42
124
|
findingReplaceComponentFixSchema,
|
|
@@ -100,6 +182,8 @@ import {
|
|
|
100
182
|
markPresetSourcedRules,
|
|
101
183
|
matchPolicyExclude,
|
|
102
184
|
matchesGlob,
|
|
185
|
+
mintEvaluationReceiptId,
|
|
186
|
+
normalizeCanonicalFactIntegrityV1,
|
|
103
187
|
normalizeExcludePath,
|
|
104
188
|
normalizeFinding,
|
|
105
189
|
normalizeGovernanceConfig,
|
|
@@ -109,24 +193,37 @@ import {
|
|
|
109
193
|
ownedComponentIdsEqual,
|
|
110
194
|
ownedImportMatchesRoot,
|
|
111
195
|
ownedImportsEqual,
|
|
196
|
+
parseAnalysisPlanId,
|
|
197
|
+
parseDigestHex,
|
|
198
|
+
parseEvaluationReceiptId,
|
|
199
|
+
parseFeaturePlanId,
|
|
200
|
+
parseFeatureRevisionId,
|
|
112
201
|
policyExcludeMatchesPath,
|
|
113
202
|
policyExcludeSchema,
|
|
114
203
|
projectSupersededImportPathPreferences,
|
|
115
204
|
resolveComponentGovernance,
|
|
205
|
+
resolveGovernanceRecordsForIdentity,
|
|
116
206
|
ruleFamilyMembers,
|
|
117
207
|
scaleGovernanceRecordSchema,
|
|
118
208
|
suppressionDirectiveSchema,
|
|
119
209
|
validatorResultSchema,
|
|
120
210
|
violationSchema
|
|
121
|
-
} from "./chunk-
|
|
211
|
+
} from "./chunk-RPSEABY3.js";
|
|
122
212
|
import {
|
|
123
|
-
|
|
124
|
-
|
|
213
|
+
isPortableRepoPath,
|
|
214
|
+
normalizeConfigPath,
|
|
215
|
+
portableRepoPathError,
|
|
216
|
+
resolveConfiguredAppPath,
|
|
217
|
+
tokenIncludesFromConfig,
|
|
218
|
+
topologyBase
|
|
219
|
+
} from "./chunk-EIYNNS77.js";
|
|
125
220
|
import {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
221
|
+
artifactContentHash,
|
|
222
|
+
canonicalPreimage,
|
|
223
|
+
compareCanonicalStrings,
|
|
224
|
+
contractHash,
|
|
225
|
+
sha256Hex
|
|
226
|
+
} from "./chunk-PWIJMOI4.js";
|
|
130
227
|
import {
|
|
131
228
|
OWNED_PACKAGE_IDENTITY_EPOCH,
|
|
132
229
|
OWNED_PACKAGE_IDENTITY_SOURCE_SHA256,
|
|
@@ -138,53 +235,13 @@ import {
|
|
|
138
235
|
projectV1OwnedImportIdentity,
|
|
139
236
|
resolveOwnedPackageImport
|
|
140
237
|
} 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
238
|
import {
|
|
183
239
|
SEVERITIES,
|
|
184
240
|
SEVERITY_RANK,
|
|
185
241
|
SEVERITY_WEIGHTS,
|
|
186
242
|
compareSeverity,
|
|
187
243
|
maxSeverity,
|
|
244
|
+
severityFromLevel,
|
|
188
245
|
severityLevel,
|
|
189
246
|
severitySchema,
|
|
190
247
|
sortBySeverity
|
|
@@ -200,8 +257,6 @@ var BRAND = {
|
|
|
200
257
|
fileExtension: ".contract.json",
|
|
201
258
|
/** Legacy file extension for segments (still supported for migration) */
|
|
202
259
|
legacyFileExtension: ".segment.tsx",
|
|
203
|
-
/** JSON file extension for compiled output */
|
|
204
|
-
jsonExtension: ".fragment.json",
|
|
205
260
|
/** Default output file name (e.g., "fragments.json") */
|
|
206
261
|
outFile: "fragments.json",
|
|
207
262
|
/** Config file name (e.g., "fragments.config.ts") */
|
|
@@ -238,11 +293,10 @@ var BRAND = {
|
|
|
238
293
|
mcpToolPrefix: "fragments_",
|
|
239
294
|
/** File extension for block definition files */
|
|
240
295
|
blockFileExtension: ".block.ts",
|
|
241
|
-
/** @deprecated Use blockFileExtension instead */
|
|
242
|
-
recipeFileExtension: ".recipe.ts",
|
|
243
296
|
/** Vite plugin namespace */
|
|
244
297
|
vitePluginNamespace: "fragments-core-shim"
|
|
245
298
|
};
|
|
299
|
+
var FRAGMENT_V3_SCHEMA_URL = "https://usefragments.com/schemas/fragment.v3.json";
|
|
246
300
|
var DEFAULTS = {
|
|
247
301
|
/** Default viewport dimensions */
|
|
248
302
|
viewport: {
|
|
@@ -741,6 +795,9 @@ function assertPortableRegistryPath(path, label) {
|
|
|
741
795
|
function joinRegistryPath(...parts) {
|
|
742
796
|
return normalizeRegistryRepoPath(parts.filter(Boolean).join("/"));
|
|
743
797
|
}
|
|
798
|
+
function sortStrings(values) {
|
|
799
|
+
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
800
|
+
}
|
|
744
801
|
function sourceToRegistryTargetPath(targetRoot, sourcePath) {
|
|
745
802
|
const source = normalizeRegistryRepoPath(sourcePath);
|
|
746
803
|
const withoutSrc = source.startsWith("src/") ? source.slice("src/".length) : source;
|
|
@@ -749,37 +806,69 @@ function sourceToRegistryTargetPath(targetRoot, sourcePath) {
|
|
|
749
806
|
"Registry install target"
|
|
750
807
|
);
|
|
751
808
|
}
|
|
752
|
-
function
|
|
753
|
-
if (
|
|
754
|
-
|
|
755
|
-
|
|
809
|
+
function resolveRegistryComponentId(manifest, requested) {
|
|
810
|
+
if (manifest.components[requested]) return requested;
|
|
811
|
+
const lowered = requested.toLowerCase();
|
|
812
|
+
const matches = Object.keys(manifest.components).filter((name) => name.toLowerCase() === lowered);
|
|
813
|
+
if (matches.length === 1) return matches[0];
|
|
814
|
+
if (matches.length > 1) {
|
|
815
|
+
throw new Error(
|
|
816
|
+
`Ambiguous registry component ${requested}: matches ${matches.sort().join(", ")}`
|
|
756
817
|
);
|
|
757
818
|
}
|
|
758
|
-
|
|
759
|
-
|
|
819
|
+
throw new Error(`Unknown registry component ${requested}`);
|
|
820
|
+
}
|
|
821
|
+
function expandRegistryComponentClosure(manifest, names) {
|
|
822
|
+
const closure = /* @__PURE__ */ new Set();
|
|
823
|
+
const queue = [...names];
|
|
824
|
+
while (queue.length > 0) {
|
|
825
|
+
const name = queue.shift();
|
|
826
|
+
if (closure.has(name)) continue;
|
|
827
|
+
const component = manifest.components[name];
|
|
828
|
+
if (!component) throw new Error(`Unknown registry component ${name}`);
|
|
829
|
+
closure.add(name);
|
|
830
|
+
queue.push(...component.internalDependencies);
|
|
760
831
|
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
832
|
+
return sortStrings(closure);
|
|
833
|
+
}
|
|
834
|
+
function resolveRegistryInstallSelection(input) {
|
|
835
|
+
const { manifest } = input;
|
|
836
|
+
if (input.all || input.requestedComponents.includes("*")) {
|
|
837
|
+
const components2 = sortStrings(Object.keys(manifest.components));
|
|
838
|
+
return { requested: components2, implied: [], components: components2 };
|
|
765
839
|
}
|
|
766
|
-
|
|
840
|
+
if (input.requestedComponents.length === 0) {
|
|
841
|
+
throw new Error("Choose at least one registry component to install.");
|
|
842
|
+
}
|
|
843
|
+
const requested = sortStrings(
|
|
844
|
+
input.requestedComponents.map((name) => resolveRegistryComponentId(manifest, name))
|
|
845
|
+
);
|
|
846
|
+
const components = expandRegistryComponentClosure(manifest, requested);
|
|
847
|
+
const requestedSet = new Set(requested);
|
|
848
|
+
return {
|
|
849
|
+
requested,
|
|
850
|
+
implied: components.filter((name) => !requestedSet.has(name)),
|
|
851
|
+
components
|
|
852
|
+
};
|
|
767
853
|
}
|
|
768
|
-
function installsCompleteRegistry(
|
|
769
|
-
const allComponents = Object.keys(
|
|
854
|
+
function installsCompleteRegistry(manifest, componentNames) {
|
|
855
|
+
const allComponents = Object.keys(manifest.components);
|
|
770
856
|
return componentNames.length === allComponents.length && allComponents.every((name) => componentNames.includes(name));
|
|
771
857
|
}
|
|
858
|
+
var AUTHORING_ROLES = /* @__PURE__ */ new Set(["test", "story", "example"]);
|
|
772
859
|
function shouldInstallFile(file, includeTests) {
|
|
773
860
|
if (includeTests) return true;
|
|
774
|
-
return
|
|
861
|
+
return !AUTHORING_ROLES.has(file.role);
|
|
775
862
|
}
|
|
776
863
|
function dependencyKey(dependency) {
|
|
777
864
|
return `${dependency.type}:${dependency.name}:${dependency.versionRange}:${dependency.optional ? 1 : 0}`;
|
|
778
865
|
}
|
|
779
866
|
function collectRegistryInstallDependencies(artifact, componentNames) {
|
|
780
867
|
const dependencies = /* @__PURE__ */ new Map();
|
|
781
|
-
|
|
782
|
-
|
|
868
|
+
if (installsCompleteRegistry(artifact.manifest, componentNames)) {
|
|
869
|
+
for (const dependency of artifact.manifest.dependencies) {
|
|
870
|
+
dependencies.set(dependencyKey(dependency), dependency);
|
|
871
|
+
}
|
|
783
872
|
}
|
|
784
873
|
for (const name of componentNames) {
|
|
785
874
|
const component = artifact.manifest.components[name];
|
|
@@ -789,24 +878,44 @@ function collectRegistryInstallDependencies(artifact, componentNames) {
|
|
|
789
878
|
}
|
|
790
879
|
return [...dependencies.values()].sort((left, right) => left.name.localeCompare(right.name));
|
|
791
880
|
}
|
|
792
|
-
function
|
|
793
|
-
const
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
881
|
+
function packageFileEntries(manifest) {
|
|
882
|
+
const packageFiles = new Map(
|
|
883
|
+
manifest.packageFiles.map((file) => [file.path, file])
|
|
884
|
+
);
|
|
885
|
+
for (const entrypoint of manifest.entrypoints) {
|
|
886
|
+
if (!packageFiles.has(entrypoint.sourcePath)) packageFiles.set(entrypoint.sourcePath, null);
|
|
887
|
+
}
|
|
888
|
+
return packageFiles;
|
|
889
|
+
}
|
|
890
|
+
function resolveRegistryInstallSources(input) {
|
|
891
|
+
const { manifest } = input;
|
|
892
|
+
const selection = resolveRegistryInstallSelection(input);
|
|
893
|
+
const complete = installsCompleteRegistry(manifest, selection.components);
|
|
894
|
+
const files = /* @__PURE__ */ new Map();
|
|
895
|
+
const paths = /* @__PURE__ */ new Set();
|
|
896
|
+
const add = (file, componentId2) => {
|
|
897
|
+
if (!shouldInstallFile(file, input.includeTests)) return;
|
|
898
|
+
if (!files.has(file.path)) files.set(file.path, { file, componentId: componentId2 });
|
|
899
|
+
paths.add(file.path);
|
|
900
|
+
};
|
|
901
|
+
if (complete) {
|
|
902
|
+
for (const [path, file] of packageFileEntries(manifest)) {
|
|
903
|
+
if (file) add(file);
|
|
904
|
+
else paths.add(path);
|
|
807
905
|
}
|
|
906
|
+
} else {
|
|
907
|
+
for (const file of manifest.baseFiles) add(file);
|
|
808
908
|
}
|
|
809
|
-
|
|
909
|
+
for (const name of selection.components) {
|
|
910
|
+
const component = manifest.components[name];
|
|
911
|
+
for (const file of component.files) add(file, component.componentId);
|
|
912
|
+
}
|
|
913
|
+
return {
|
|
914
|
+
selection,
|
|
915
|
+
complete,
|
|
916
|
+
files: [...files.values()].sort((left, right) => left.file.path.localeCompare(right.file.path)),
|
|
917
|
+
paths: sortStrings(paths)
|
|
918
|
+
};
|
|
810
919
|
}
|
|
811
920
|
function rewriteInstalledPackagePath(value) {
|
|
812
921
|
if (value.startsWith("./src/")) return `./${value.slice("./src/".length)}`;
|
|
@@ -843,41 +952,14 @@ function rewriteInstalledPackageJson(content) {
|
|
|
843
952
|
return `${JSON.stringify(installed, null, 2)}
|
|
844
953
|
`;
|
|
845
954
|
}
|
|
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));
|
|
955
|
+
function contentFor(artifact, path) {
|
|
956
|
+
const content = artifact.files[path];
|
|
957
|
+
if (!content) throw new Error(`Artifact is missing file content for ${path}`);
|
|
958
|
+
return content.content;
|
|
877
959
|
}
|
|
878
960
|
function generatedIndexPlan(args) {
|
|
879
961
|
const lines = args.componentNames.map((name) => {
|
|
880
|
-
const component = args.
|
|
962
|
+
const component = args.manifest.components[name];
|
|
881
963
|
const exportName = component.exports[0]?.name ?? component.name;
|
|
882
964
|
return `export { ${exportName} } from "./components/${component.componentId}";`;
|
|
883
965
|
});
|
|
@@ -903,32 +985,47 @@ function dedupePlans(plans) {
|
|
|
903
985
|
return [...byPath.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
904
986
|
}
|
|
905
987
|
function buildRegistryInstallPlan(input) {
|
|
988
|
+
const { manifest } = input.artifact;
|
|
906
989
|
const targetPath = assertPortableRegistryPath(input.targetPath, "Registry target");
|
|
907
|
-
const
|
|
908
|
-
|
|
909
|
-
input.requestedComponents,
|
|
910
|
-
input.all
|
|
911
|
-
|
|
990
|
+
const sources = resolveRegistryInstallSources({
|
|
991
|
+
manifest,
|
|
992
|
+
requestedComponents: input.requestedComponents,
|
|
993
|
+
all: input.all,
|
|
994
|
+
includeTests: input.includeTests
|
|
995
|
+
});
|
|
996
|
+
const componentNames = sources.selection.components;
|
|
912
997
|
const dependencies = collectRegistryInstallDependencies(input.artifact, componentNames);
|
|
913
|
-
const
|
|
914
|
-
const
|
|
915
|
-
|
|
916
|
-
|
|
998
|
+
const hasPackageRoot = manifest.entrypoints.some((entrypoint) => entrypoint.specifier === ".");
|
|
999
|
+
const writes = sources.files.map(({ file, componentId: componentId2 }) => {
|
|
1000
|
+
const raw = contentFor(input.artifact, file.path);
|
|
1001
|
+
return {
|
|
1002
|
+
path: sourceToRegistryTargetPath(targetPath, file.path),
|
|
1003
|
+
sourcePath: file.path,
|
|
1004
|
+
content: sources.complete && file.path === "package.json" ? rewriteInstalledPackageJson(raw) : raw,
|
|
1005
|
+
...componentId2 && { componentId: componentId2 }
|
|
1006
|
+
};
|
|
1007
|
+
});
|
|
1008
|
+
if (sources.complete) {
|
|
1009
|
+
for (const entrypoint of manifest.entrypoints) {
|
|
1010
|
+
if (writes.some((plan) => plan.sourcePath === entrypoint.sourcePath)) continue;
|
|
1011
|
+
writes.push({
|
|
1012
|
+
path: sourceToRegistryTargetPath(targetPath, entrypoint.sourcePath),
|
|
1013
|
+
sourcePath: entrypoint.sourcePath,
|
|
1014
|
+
content: contentFor(input.artifact, entrypoint.sourcePath)
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
917
1018
|
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 })]
|
|
1019
|
+
...writes,
|
|
1020
|
+
...sources.complete && hasPackageRoot ? [] : [generatedIndexPlan({ manifest, componentNames, targetPath })]
|
|
930
1021
|
]);
|
|
931
|
-
return {
|
|
1022
|
+
return {
|
|
1023
|
+
componentNames,
|
|
1024
|
+
requestedComponents: sources.selection.requested,
|
|
1025
|
+
impliedComponents: sources.selection.implied,
|
|
1026
|
+
plans,
|
|
1027
|
+
dependencies
|
|
1028
|
+
};
|
|
932
1029
|
}
|
|
933
1030
|
function buildRegistryInstallReceipt(args) {
|
|
934
1031
|
const installedComponents = args.componentNames.map((name) => {
|
|
@@ -1249,14 +1346,14 @@ function rgbToLab(rgb) {
|
|
|
1249
1346
|
b = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
|
|
1250
1347
|
let x = (r * 0.4124564 + g2 * 0.3575761 + b * 0.1804375) / 0.95047;
|
|
1251
1348
|
let y = r * 0.2126729 + g2 * 0.7151522 + b * 0.072175;
|
|
1252
|
-
let
|
|
1349
|
+
let z12 = (r * 0.0193339 + g2 * 0.119192 + b * 0.9503041) / 1.08883;
|
|
1253
1350
|
x = x > 8856e-6 ? Math.pow(x, 1 / 3) : 7.787 * x + 16 / 116;
|
|
1254
1351
|
y = y > 8856e-6 ? Math.pow(y, 1 / 3) : 7.787 * y + 16 / 116;
|
|
1255
|
-
|
|
1352
|
+
z12 = z12 > 8856e-6 ? Math.pow(z12, 1 / 3) : 7.787 * z12 + 16 / 116;
|
|
1256
1353
|
return {
|
|
1257
1354
|
l: 116 * y - 16,
|
|
1258
1355
|
a: 500 * (x - y),
|
|
1259
|
-
b: 200 * (y -
|
|
1356
|
+
b: 200 * (y - z12)
|
|
1260
1357
|
};
|
|
1261
1358
|
}
|
|
1262
1359
|
|
|
@@ -1521,10 +1618,14 @@ var figmaStringMappingSchema = z4.object({
|
|
|
1521
1618
|
__type: z4.literal("figma-string"),
|
|
1522
1619
|
figmaProperty: z4.string().min(1)
|
|
1523
1620
|
});
|
|
1621
|
+
var requiredUnknownSchema = z4.custom(
|
|
1622
|
+
(value) => value !== void 0,
|
|
1623
|
+
"Expected an explicitly present value"
|
|
1624
|
+
);
|
|
1524
1625
|
var figmaBooleanMappingSchema = z4.object({
|
|
1525
1626
|
__type: z4.literal("figma-boolean"),
|
|
1526
1627
|
figmaProperty: z4.string().min(1),
|
|
1527
|
-
valueMapping: z4.object({ true:
|
|
1628
|
+
valueMapping: z4.object({ true: requiredUnknownSchema, false: requiredUnknownSchema }).optional()
|
|
1528
1629
|
});
|
|
1529
1630
|
var figmaEnumMappingSchema = z4.object({
|
|
1530
1631
|
__type: z4.literal("figma-enum"),
|
|
@@ -1629,7 +1730,7 @@ var fragmentContractSchema = z4.object({
|
|
|
1629
1730
|
a11yRules: z4.array(z4.string()).optional(),
|
|
1630
1731
|
bans: z4.array(fragmentBanSchema).optional(),
|
|
1631
1732
|
scenarioTags: z4.array(z4.string()).optional(),
|
|
1632
|
-
performanceBudget: z4.number().positive().optional(),
|
|
1733
|
+
performanceBudget: z4.number().positive().finite().optional(),
|
|
1633
1734
|
compoundChildren: z4.record(
|
|
1634
1735
|
z4.object({
|
|
1635
1736
|
required: z4.boolean().optional(),
|
|
@@ -1643,10 +1744,20 @@ var fragmentContractSchema = z4.object({
|
|
|
1643
1744
|
// `CompositionPattern[]` the composition/* rules read from policy.
|
|
1644
1745
|
composition: z4.array(compositionAuthoringEntrySchema).optional()
|
|
1645
1746
|
});
|
|
1747
|
+
var fragmentSourceValues = [
|
|
1748
|
+
"storybook",
|
|
1749
|
+
"manual",
|
|
1750
|
+
"ai",
|
|
1751
|
+
"scan",
|
|
1752
|
+
"extracted",
|
|
1753
|
+
"merged",
|
|
1754
|
+
"migrated"
|
|
1755
|
+
];
|
|
1646
1756
|
var fragmentGeneratedSchema = z4.object({
|
|
1647
|
-
source: z4.enum(
|
|
1757
|
+
source: z4.enum(fragmentSourceValues),
|
|
1648
1758
|
sourceFile: z4.string().optional(),
|
|
1649
1759
|
confidence: z4.number().min(0).max(1).optional(),
|
|
1760
|
+
verified: z4.boolean().optional(),
|
|
1650
1761
|
timestamp: z4.string().datetime().optional()
|
|
1651
1762
|
});
|
|
1652
1763
|
var aiMetadataSchema = z4.object({
|
|
@@ -1785,14 +1896,6 @@ var fragmentsConfigSchema = z4.object({
|
|
|
1785
1896
|
}).optional()
|
|
1786
1897
|
})
|
|
1787
1898
|
]).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
1899
|
topology: topologySchema.optional(),
|
|
1797
1900
|
govern: governanceConfigSchema.optional(),
|
|
1798
1901
|
inspect: z4.object({
|
|
@@ -1830,10 +1933,13 @@ var compositionMetadataSchema = z4.object({
|
|
|
1830
1933
|
commonPatterns: z4.array(z4.string()).optional()
|
|
1831
1934
|
});
|
|
1832
1935
|
var fragmentProvenanceSchema = z4.object({
|
|
1833
|
-
source: z4.enum(
|
|
1936
|
+
source: z4.enum(fragmentSourceValues),
|
|
1834
1937
|
sourceFile: z4.string().optional(),
|
|
1835
1938
|
confidence: z4.number().min(0).max(1).optional(),
|
|
1836
|
-
|
|
1939
|
+
verified: z4.boolean().optional(),
|
|
1940
|
+
frameworkSupport: z4.enum(["native", "manual-only"]).optional(),
|
|
1941
|
+
sourceHash: z4.string().optional(),
|
|
1942
|
+
timestamp: z4.string().datetime({ offset: true }).optional(),
|
|
1837
1943
|
autoFields: z4.array(z4.string()).optional(),
|
|
1838
1944
|
humanFields: z4.array(z4.string()).optional()
|
|
1839
1945
|
});
|
|
@@ -1860,8 +1966,119 @@ var governedFragmentDefinitionSchema = z4.object({
|
|
|
1860
1966
|
_provenance: fragmentProvenanceSchema.optional(),
|
|
1861
1967
|
govern: z4.function().optional(),
|
|
1862
1968
|
governance: z4.array(componentGovernanceRecordSchema).optional()
|
|
1969
|
+
}).superRefine((def, ctx) => {
|
|
1970
|
+
if (def.govern === void 0 && def.governance === void 0) {
|
|
1971
|
+
ctx.addIssue({
|
|
1972
|
+
code: z4.ZodIssueCode.custom,
|
|
1973
|
+
message: "Governed definitions require `govern` or `governance`",
|
|
1974
|
+
path: ["govern"]
|
|
1975
|
+
});
|
|
1976
|
+
}
|
|
1863
1977
|
});
|
|
1864
|
-
var
|
|
1978
|
+
var fragmentRenderSchema = z4.custom(
|
|
1979
|
+
(value) => value !== void 0 && typeof value !== "string",
|
|
1980
|
+
"Expected JSX/render value, not a code string"
|
|
1981
|
+
);
|
|
1982
|
+
var fragmentMetaV3Schema = z4.object({
|
|
1983
|
+
name: z4.string().min(1),
|
|
1984
|
+
purpose: z4.string().min(1),
|
|
1985
|
+
category: z4.string().min(1),
|
|
1986
|
+
status: z4.enum(["stable", "beta", "deprecated", "experimental"]).optional(),
|
|
1987
|
+
aliases: z4.array(z4.string().min(1)).optional(),
|
|
1988
|
+
tags: z4.array(z4.string()).optional(),
|
|
1989
|
+
since: z4.string().optional(),
|
|
1990
|
+
dependencies: z4.array(
|
|
1991
|
+
z4.object({
|
|
1992
|
+
name: z4.string().min(1),
|
|
1993
|
+
version: z4.string().min(1),
|
|
1994
|
+
reason: z4.string().optional()
|
|
1995
|
+
}).strict()
|
|
1996
|
+
).optional(),
|
|
1997
|
+
figma: z4.string().url().optional(),
|
|
1998
|
+
figmaProps: z4.record(figmaPropMappingSchema).optional()
|
|
1999
|
+
}).strict();
|
|
2000
|
+
var fragmentStateV3Schema = z4.object({
|
|
2001
|
+
render: fragmentRenderSchema,
|
|
2002
|
+
note: z4.string().optional(),
|
|
2003
|
+
canonical: z4.boolean().optional()
|
|
2004
|
+
}).strict();
|
|
2005
|
+
var fragmentDontExampleV3Schema = z4.object({
|
|
2006
|
+
reason: z4.string().min(1),
|
|
2007
|
+
bad: z4.string().min(1),
|
|
2008
|
+
good: fragmentRenderSchema
|
|
2009
|
+
}).strict();
|
|
2010
|
+
var fragmentGuidanceV3Schema = z4.object({
|
|
2011
|
+
when: z4.array(z4.string()),
|
|
2012
|
+
whenNot: z4.array(z4.string()),
|
|
2013
|
+
choose: z4.record(z4.string()).optional(),
|
|
2014
|
+
dont: z4.array(fragmentDontExampleV3Schema).optional(),
|
|
2015
|
+
guidelines: z4.array(z4.string()).optional(),
|
|
2016
|
+
accessibility: z4.array(z4.string()).optional()
|
|
2017
|
+
}).strict();
|
|
2018
|
+
var fragmentMatrixV3Schema = z4.object({
|
|
2019
|
+
axes: z4.record(z4.union([z4.literal("auto"), z4.array(z4.string().min(1)).readonly()])).optional(),
|
|
2020
|
+
forced: z4.array(z4.string().min(1)).optional(),
|
|
2021
|
+
worstCase: z4.record(z4.unknown()).optional()
|
|
2022
|
+
}).strict();
|
|
2023
|
+
var fragmentPreviewV3Schema = z4.object({
|
|
2024
|
+
providers: z4.array(z4.unknown()).optional(),
|
|
2025
|
+
dynamicRegions: z4.array(z4.string()).optional()
|
|
2026
|
+
}).strict();
|
|
2027
|
+
var fragmentDesignV3Schema = z4.object({
|
|
2028
|
+
figmaNode: z4.string().min(1).optional()
|
|
2029
|
+
}).strict();
|
|
2030
|
+
var propAnnotationSchema = z4.object({
|
|
2031
|
+
description: z4.string().optional(),
|
|
2032
|
+
controlType: z4.enum([
|
|
2033
|
+
"text",
|
|
2034
|
+
"number",
|
|
2035
|
+
"range",
|
|
2036
|
+
"boolean",
|
|
2037
|
+
"select",
|
|
2038
|
+
"multi-select",
|
|
2039
|
+
"radio",
|
|
2040
|
+
"inline-radio",
|
|
2041
|
+
"check",
|
|
2042
|
+
"inline-check",
|
|
2043
|
+
"object",
|
|
2044
|
+
"file",
|
|
2045
|
+
"color",
|
|
2046
|
+
"date"
|
|
2047
|
+
]).optional(),
|
|
2048
|
+
controlOptions: z4.record(z4.unknown()).optional(),
|
|
2049
|
+
visibility: z4.enum(["public", "internal", "hidden"]).optional(),
|
|
2050
|
+
constraints: z4.array(z4.string()).optional()
|
|
2051
|
+
}).strict();
|
|
2052
|
+
var fragmentAnnotationsV3Schema = z4.object({
|
|
2053
|
+
notes: z4.array(z4.string()).optional(),
|
|
2054
|
+
review: z4.array(z4.string()).optional()
|
|
2055
|
+
}).passthrough();
|
|
2056
|
+
var fragmentDefinitionV3BodyShape = {
|
|
2057
|
+
meta: fragmentMetaV3Schema,
|
|
2058
|
+
states: z4.record(fragmentStateV3Schema).refine((states) => Object.keys(states).length > 0, {
|
|
2059
|
+
message: "At least one state is required"
|
|
2060
|
+
}),
|
|
2061
|
+
guidance: fragmentGuidanceV3Schema,
|
|
2062
|
+
matrix: fragmentMatrixV3Schema.optional(),
|
|
2063
|
+
preview: fragmentPreviewV3Schema.optional(),
|
|
2064
|
+
design: fragmentDesignV3Schema.optional(),
|
|
2065
|
+
annotations: fragmentAnnotationsV3Schema.optional(),
|
|
2066
|
+
props: z4.record(propAnnotationSchema).optional(),
|
|
2067
|
+
relations: z4.array(componentRelationSchema.strict()).optional(),
|
|
2068
|
+
composition: compositionMetadataSchema.strict().optional(),
|
|
2069
|
+
contract: fragmentContractSchema.optional(),
|
|
2070
|
+
_provenance: fragmentProvenanceSchema.optional(),
|
|
2071
|
+
govern: z4.function().optional(),
|
|
2072
|
+
governance: z4.array(componentGovernanceRecordSchema).optional()
|
|
2073
|
+
};
|
|
2074
|
+
var fragmentDefinitionV3BodySchema = z4.object(fragmentDefinitionV3BodyShape).strict();
|
|
2075
|
+
var fragmentDefinitionV3Schema = z4.object({
|
|
2076
|
+
...fragmentDefinitionV3BodyShape,
|
|
2077
|
+
component: z4.unknown().refine((component) => component !== void 0, {
|
|
2078
|
+
message: "Component is required"
|
|
2079
|
+
}),
|
|
2080
|
+
governance: z4.array(componentGovernanceRecordSchema)
|
|
2081
|
+
}).strict();
|
|
1865
2082
|
|
|
1866
2083
|
// src/config.ts
|
|
1867
2084
|
var RAW_CONFIG_DECLARATION = /* @__PURE__ */ Symbol.for("@usefragments/core/raw-config-declaration");
|
|
@@ -1890,11 +2107,51 @@ ${formatZodErrors(result.error.errors)}`);
|
|
|
1890
2107
|
|
|
1891
2108
|
// src/defineFragment.ts
|
|
1892
2109
|
function isGovernedDefinition(def) {
|
|
1893
|
-
|
|
2110
|
+
if (!def || typeof def !== "object") return false;
|
|
2111
|
+
const record = def;
|
|
2112
|
+
return typeof record.govern === "function" || Array.isArray(record.governance);
|
|
1894
2113
|
}
|
|
1895
2114
|
function isV2Definition(def) {
|
|
2115
|
+
if (!def || typeof def !== "object") return false;
|
|
1896
2116
|
return !isGovernedDefinition(def) && ("guidance" in def || "examples" in def);
|
|
1897
2117
|
}
|
|
2118
|
+
function rejectInvalidGovernanceDiscriminants(definition) {
|
|
2119
|
+
if (!definition || typeof definition !== "object") return;
|
|
2120
|
+
const record = definition;
|
|
2121
|
+
const hasOwn = (key) => Object.prototype.hasOwnProperty.call(record, key);
|
|
2122
|
+
const errors = [];
|
|
2123
|
+
if (hasOwn("govern") && typeof record.govern !== "function") {
|
|
2124
|
+
errors.push({ path: ["govern"], message: "Expected a governance authoring function" });
|
|
2125
|
+
}
|
|
2126
|
+
if (hasOwn("governance") && !Array.isArray(record.governance)) {
|
|
2127
|
+
errors.push({ path: ["governance"], message: "Expected an array of governance records" });
|
|
2128
|
+
}
|
|
2129
|
+
if (errors.length > 0) {
|
|
2130
|
+
const name = record.meta && typeof record.meta === "object" && "name" in record.meta ? String(record.meta.name) : "unknown";
|
|
2131
|
+
throwInvalidFragment(name, "governed", errors);
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2134
|
+
var InvalidFragmentDefinitionError = class _InvalidFragmentDefinitionError extends Error {
|
|
2135
|
+
code = "FUI9010";
|
|
2136
|
+
source = "@usefragments/core/defineFragment";
|
|
2137
|
+
api;
|
|
2138
|
+
issues;
|
|
2139
|
+
constructor(name, api, errors) {
|
|
2140
|
+
const issues = errors.map((error) => `${error.path.join(".") || "(root)"}: ${error.message}`).sort();
|
|
2141
|
+
super(
|
|
2142
|
+
[
|
|
2143
|
+
`${_InvalidFragmentDefinitionError.name}: Invalid fragment definition for "${name}":`,
|
|
2144
|
+
...issues.map((issue) => ` - ${issue}`)
|
|
2145
|
+
].join("\n")
|
|
2146
|
+
);
|
|
2147
|
+
this.name = _InvalidFragmentDefinitionError.name;
|
|
2148
|
+
this.api = api;
|
|
2149
|
+
this.issues = issues;
|
|
2150
|
+
}
|
|
2151
|
+
};
|
|
2152
|
+
function throwInvalidFragment(name, api, errors) {
|
|
2153
|
+
throw new InvalidFragmentDefinitionError(name, api, errors);
|
|
2154
|
+
}
|
|
1898
2155
|
function normalizeToV1(def) {
|
|
1899
2156
|
let ai;
|
|
1900
2157
|
if (def.composition) {
|
|
@@ -1908,9 +2165,10 @@ function normalizeToV1(def) {
|
|
|
1908
2165
|
let generated;
|
|
1909
2166
|
if (def._provenance) {
|
|
1910
2167
|
generated = {
|
|
1911
|
-
source: def._provenance.source
|
|
2168
|
+
source: def._provenance.source,
|
|
1912
2169
|
sourceFile: def._provenance.sourceFile,
|
|
1913
2170
|
confidence: def._provenance.confidence,
|
|
2171
|
+
verified: def._provenance.verified,
|
|
1914
2172
|
timestamp: def._provenance.timestamp
|
|
1915
2173
|
};
|
|
1916
2174
|
}
|
|
@@ -1926,18 +2184,60 @@ function normalizeToV1(def) {
|
|
|
1926
2184
|
_generated: generated
|
|
1927
2185
|
};
|
|
1928
2186
|
}
|
|
1929
|
-
function
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
2187
|
+
function defineFragmentV3(component, definition) {
|
|
2188
|
+
const result = fragmentDefinitionV3BodySchema.safeParse(definition);
|
|
2189
|
+
if (!result.success) {
|
|
2190
|
+
throwInvalidFragment(
|
|
2191
|
+
definition?.meta?.name || "unknown",
|
|
2192
|
+
"v3",
|
|
2193
|
+
result.error.errors.map((e) => ({ path: e.path, message: e.message }))
|
|
2194
|
+
);
|
|
2195
|
+
}
|
|
2196
|
+
const governance = typeof definition.govern === "function" || Array.isArray(definition.governance) ? resolveComponentGovernance({
|
|
2197
|
+
component,
|
|
2198
|
+
meta: {
|
|
2199
|
+
name: definition.meta.name,
|
|
2200
|
+
description: definition.meta.purpose,
|
|
2201
|
+
category: definition.meta.category,
|
|
2202
|
+
status: definition.meta.status,
|
|
2203
|
+
tags: definition.meta.tags,
|
|
2204
|
+
since: definition.meta.since,
|
|
2205
|
+
dependencies: definition.meta.dependencies,
|
|
2206
|
+
figma: definition.meta.figma,
|
|
2207
|
+
figmaProps: definition.meta.figmaProps
|
|
2208
|
+
},
|
|
2209
|
+
guidance: {
|
|
2210
|
+
when: definition.guidance.when,
|
|
2211
|
+
whenNot: definition.guidance.whenNot,
|
|
2212
|
+
guidelines: definition.guidance.guidelines,
|
|
2213
|
+
accessibility: definition.guidance.accessibility
|
|
2214
|
+
},
|
|
2215
|
+
govern: definition.govern,
|
|
2216
|
+
governance: definition.governance
|
|
2217
|
+
}) : [];
|
|
2218
|
+
return {
|
|
2219
|
+
...definition,
|
|
2220
|
+
component,
|
|
2221
|
+
governance
|
|
2222
|
+
};
|
|
2223
|
+
}
|
|
2224
|
+
function defineFragmentOneArg(definition) {
|
|
2225
|
+
if (!definition || typeof definition !== "object") {
|
|
2226
|
+
throwInvalidFragment("unknown", "unknown", [
|
|
2227
|
+
{ path: [], message: "Expected a fragment definition object" }
|
|
2228
|
+
]);
|
|
2229
|
+
}
|
|
2230
|
+
rejectInvalidGovernanceDiscriminants(definition);
|
|
2231
|
+
const governed = isGovernedDefinition(definition);
|
|
2232
|
+
const v2 = isV2Definition(definition);
|
|
2233
|
+
const schema = governed ? governedFragmentDefinitionSchema : v2 ? fragmentDefinitionV2Schema : fragmentDefinitionSchema;
|
|
2234
|
+
const result = schema.safeParse(definition);
|
|
2235
|
+
if (!result.success) {
|
|
2236
|
+
throwInvalidFragment(
|
|
2237
|
+
definition?.meta?.name || "unknown",
|
|
2238
|
+
governed ? "governed" : v2 ? "v2" : "v1",
|
|
2239
|
+
result.error.errors.map((e) => ({ path: e.path, message: e.message }))
|
|
2240
|
+
);
|
|
1941
2241
|
}
|
|
1942
2242
|
if (isGovernedDefinition(definition)) {
|
|
1943
2243
|
const governance = resolveComponentGovernance(definition);
|
|
@@ -1948,6 +2248,17 @@ ${errors}`);
|
|
|
1948
2248
|
}
|
|
1949
2249
|
return definition;
|
|
1950
2250
|
}
|
|
2251
|
+
function defineFragment(componentOrDefinition, maybeDefinition) {
|
|
2252
|
+
if (arguments.length >= 2) {
|
|
2253
|
+
return defineFragmentV3(
|
|
2254
|
+
componentOrDefinition,
|
|
2255
|
+
maybeDefinition
|
|
2256
|
+
);
|
|
2257
|
+
}
|
|
2258
|
+
return defineFragmentOneArg(
|
|
2259
|
+
componentOrDefinition
|
|
2260
|
+
);
|
|
2261
|
+
}
|
|
1951
2262
|
function compileFragment(definition, filePath) {
|
|
1952
2263
|
const v1 = isGovernedDefinition(definition) ? {
|
|
1953
2264
|
component: definition.component,
|
|
@@ -1957,10 +2268,17 @@ function compileFragment(definition, filePath) {
|
|
|
1957
2268
|
relations: definition.relations,
|
|
1958
2269
|
variants: definition.examples ?? [],
|
|
1959
2270
|
contract: definition.contract,
|
|
2271
|
+
ai: definition.composition ? {
|
|
2272
|
+
compositionPattern: definition.composition.pattern,
|
|
2273
|
+
subComponents: definition.composition.subComponents,
|
|
2274
|
+
requiredChildren: definition.composition.requiredChildren,
|
|
2275
|
+
commonPatterns: definition.composition.commonPatterns
|
|
2276
|
+
} : void 0,
|
|
1960
2277
|
_generated: definition._provenance ? {
|
|
1961
|
-
source: definition._provenance.source
|
|
2278
|
+
source: definition._provenance.source,
|
|
1962
2279
|
sourceFile: definition._provenance.sourceFile,
|
|
1963
2280
|
confidence: definition._provenance.confidence,
|
|
2281
|
+
verified: definition._provenance.verified,
|
|
1964
2282
|
timestamp: definition._provenance.timestamp
|
|
1965
2283
|
} : void 0
|
|
1966
2284
|
} : isV2Definition(definition) ? normalizeToV1(definition) : definition;
|
|
@@ -1986,17 +2304,14 @@ function compileFragment(definition, filePath) {
|
|
|
1986
2304
|
};
|
|
1987
2305
|
}
|
|
1988
2306
|
function defineBlock(definition) {
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
throw new Error(`Invalid block definition for "${definition.name || "unknown"}":
|
|
2307
|
+
const result = blockDefinitionSchema.safeParse(definition);
|
|
2308
|
+
if (!result.success) {
|
|
2309
|
+
const errors = result.error.errors.map((e) => `${e.path.join(".") || "(root)"}: ${e.message}`).sort().map((issue) => ` - ${issue}`).join("\n");
|
|
2310
|
+
throw new Error(`Invalid block definition for "${definition.name || "unknown"}":
|
|
1994
2311
|
${errors}`);
|
|
1995
|
-
}
|
|
1996
2312
|
}
|
|
1997
2313
|
return definition;
|
|
1998
2314
|
}
|
|
1999
|
-
var defineRecipe = defineBlock;
|
|
2000
2315
|
function compileBlock(definition, filePath) {
|
|
2001
2316
|
return {
|
|
2002
2317
|
filePath,
|
|
@@ -2008,129 +2323,6 @@ function compileBlock(definition, filePath) {
|
|
|
2008
2323
|
tags: definition.tags
|
|
2009
2324
|
};
|
|
2010
2325
|
}
|
|
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
2326
|
|
|
2135
2327
|
// src/figma.ts
|
|
2136
2328
|
function string(figmaProperty) {
|
|
@@ -2699,11 +2891,11 @@ function detectTokenPrefix(names) {
|
|
|
2699
2891
|
}
|
|
2700
2892
|
function parseScssVariables(content) {
|
|
2701
2893
|
const vars = /* @__PURE__ */ new Map();
|
|
2702
|
-
const scssVarRegex = /^\s*(\$[\w-]+)\s*:\s*(
|
|
2894
|
+
const scssVarRegex = /^\s*(\$[\w-]+)\s*:\s*([\s\S]*?)\s*(?:!default\s*)?;/gm;
|
|
2703
2895
|
let match;
|
|
2704
2896
|
while ((match = scssVarRegex.exec(content)) !== null) {
|
|
2705
2897
|
const name = match[1];
|
|
2706
|
-
const value = match[2].replace(/\s
|
|
2898
|
+
const value = match[2].replace(/\s*\/\/[^\n]*$/gm, "").replace(/\s+/g, " ").trim();
|
|
2707
2899
|
if (!vars.has(name)) {
|
|
2708
2900
|
vars.set(name, value);
|
|
2709
2901
|
}
|
|
@@ -2776,6 +2968,7 @@ function parseScssTokens(content, filePath = "tokens.scss") {
|
|
|
2776
2968
|
}
|
|
2777
2969
|
for (const [name, value] of scssVars) {
|
|
2778
2970
|
if (seenNames.has(name)) continue;
|
|
2971
|
+
if (value.startsWith("(")) continue;
|
|
2779
2972
|
seenNames.add(name);
|
|
2780
2973
|
tokens.push({
|
|
2781
2974
|
name,
|
|
@@ -3693,24 +3886,37 @@ var contractExampleSchema = z6.object({
|
|
|
3693
3886
|
});
|
|
3694
3887
|
var contractRelationSchema = z6.object({
|
|
3695
3888
|
component: z6.string(),
|
|
3696
|
-
relationship: z6.enum([
|
|
3889
|
+
relationship: z6.enum([
|
|
3890
|
+
"alternative",
|
|
3891
|
+
"parent",
|
|
3892
|
+
"child",
|
|
3893
|
+
"sibling",
|
|
3894
|
+
"composition",
|
|
3895
|
+
"complementary",
|
|
3896
|
+
"used-by"
|
|
3897
|
+
]),
|
|
3697
3898
|
note: z6.string()
|
|
3698
3899
|
});
|
|
3699
3900
|
var contractContractSchema = z6.object({
|
|
3700
3901
|
propsSummary: z6.array(z6.string()).optional(),
|
|
3701
3902
|
scenarioTags: z6.array(z6.string()).optional(),
|
|
3702
3903
|
a11yRules: z6.array(z6.string()).optional(),
|
|
3703
|
-
bans: z6.array(
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3904
|
+
bans: z6.array(
|
|
3905
|
+
z6.object({
|
|
3906
|
+
pattern: z6.string(),
|
|
3907
|
+
message: z6.string()
|
|
3908
|
+
})
|
|
3909
|
+
).optional(),
|
|
3910
|
+
compoundChildren: z6.record(
|
|
3911
|
+
z6.string(),
|
|
3912
|
+
z6.object({
|
|
3913
|
+
required: z6.boolean().optional(),
|
|
3914
|
+
accepts: z6.array(z6.string()).optional(),
|
|
3915
|
+
description: z6.string().optional()
|
|
3916
|
+
})
|
|
3917
|
+
).optional(),
|
|
3712
3918
|
canonicalUsage: z6.array(z6.string()).optional(),
|
|
3713
|
-
performanceBudget: z6.number().optional()
|
|
3919
|
+
performanceBudget: z6.number().positive().finite().optional()
|
|
3714
3920
|
});
|
|
3715
3921
|
var contractAiSchema = z6.object({
|
|
3716
3922
|
compositionPattern: z6.enum(["compound", "simple", "controlled", "wrapper"]).optional(),
|
|
@@ -3734,11 +3940,14 @@ var contractProvenanceSchema = z6.object({
|
|
|
3734
3940
|
});
|
|
3735
3941
|
var contractFigmaSchema = z6.object({
|
|
3736
3942
|
nodeUrl: z6.string().optional(),
|
|
3737
|
-
propMappings: z6.record(
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3943
|
+
propMappings: z6.record(
|
|
3944
|
+
z6.string(),
|
|
3945
|
+
z6.object({
|
|
3946
|
+
type: z6.enum(["string", "boolean", "enum", "instance", "children", "textContent"]),
|
|
3947
|
+
figmaProperty: z6.string(),
|
|
3948
|
+
values: z6.record(z6.string(), z6.string()).optional()
|
|
3949
|
+
})
|
|
3950
|
+
).optional()
|
|
3742
3951
|
});
|
|
3743
3952
|
var componentContractSchema = z6.object({
|
|
3744
3953
|
$schema: z6.string(),
|
|
@@ -3748,11 +3957,13 @@ var componentContractSchema = z6.object({
|
|
|
3748
3957
|
tags: z6.array(z6.string()).optional(),
|
|
3749
3958
|
status: z6.enum(["stable", "beta", "deprecated", "experimental"]).optional(),
|
|
3750
3959
|
framework: z6.enum(["react", "vue", "svelte", "web-components", "angular"]).optional(),
|
|
3751
|
-
dependencies: z6.array(
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3960
|
+
dependencies: z6.array(
|
|
3961
|
+
z6.object({
|
|
3962
|
+
name: z6.string(),
|
|
3963
|
+
version: z6.string(),
|
|
3964
|
+
reason: z6.string().optional()
|
|
3965
|
+
})
|
|
3966
|
+
).optional(),
|
|
3756
3967
|
sourcePath: z6.string(),
|
|
3757
3968
|
exportName: z6.string(),
|
|
3758
3969
|
propsSummary: z6.array(z6.string()),
|
|
@@ -3803,6 +4014,8 @@ function parseComponentContract(content, filePath) {
|
|
|
3803
4014
|
} : {
|
|
3804
4015
|
propsSummary: validated.propsSummary
|
|
3805
4016
|
},
|
|
4017
|
+
preview: validated.preview,
|
|
4018
|
+
tokens: validated.tokens,
|
|
3806
4019
|
framework: validated.framework,
|
|
3807
4020
|
ai: validated.ai,
|
|
3808
4021
|
propsSummary: validated.propsSummary,
|
|
@@ -4014,6 +4227,7 @@ function parseFigmaValue(cssValue, category) {
|
|
|
4014
4227
|
// src/composition.ts
|
|
4015
4228
|
var CATEGORY_AFFINITIES = {
|
|
4016
4229
|
forms: ["feedback"],
|
|
4230
|
+
inputs: ["feedback"],
|
|
4017
4231
|
actions: ["feedback"]
|
|
4018
4232
|
};
|
|
4019
4233
|
function analyzeComposition(fragments, componentNames, _context, options) {
|
|
@@ -4119,9 +4333,7 @@ function analyzeComposition(fragments, componentNames, _context, options) {
|
|
|
4119
4333
|
});
|
|
4120
4334
|
}
|
|
4121
4335
|
}
|
|
4122
|
-
const selectedCategories = new Set(
|
|
4123
|
-
components.map((name) => fragments[name].meta.category)
|
|
4124
|
-
);
|
|
4336
|
+
const selectedCategories = new Set(components.map((name) => fragments[name].meta.category));
|
|
4125
4337
|
for (const [category, affinities] of Object.entries(CATEGORY_AFFINITIES)) {
|
|
4126
4338
|
if (!selectedCategories.has(category)) continue;
|
|
4127
4339
|
for (const neededCategory of affinities) {
|
|
@@ -4137,9 +4349,7 @@ function analyzeComposition(fragments, componentNames, _context, options) {
|
|
|
4137
4349
|
component: candidate,
|
|
4138
4350
|
reason: `Compositions using "${category}" components often benefit from a "${neededCategory}" component`,
|
|
4139
4351
|
relationship: "category_gap",
|
|
4140
|
-
sourceComponent: components.find(
|
|
4141
|
-
(n) => fragments[n].meta.category === category
|
|
4142
|
-
)
|
|
4352
|
+
sourceComponent: components.find((n) => fragments[n].meta.category === category)
|
|
4143
4353
|
});
|
|
4144
4354
|
suggestedSet.add(candidate);
|
|
4145
4355
|
}
|
|
@@ -4262,7 +4472,7 @@ function makeFinding(input) {
|
|
|
4262
4472
|
canonicalJson({ ruleId: input.ruleId, ...input.fingerprintIdentity })
|
|
4263
4473
|
);
|
|
4264
4474
|
const previousFingerprint = input.previousFingerprintIdentity ? hash64Hex(canonicalJson({ ruleId: input.ruleId, ...input.previousFingerprintIdentity })) : void 0;
|
|
4265
|
-
const code = byRuleId.get(input.ruleId);
|
|
4475
|
+
const code = input.code ? byCode.get(input.code) : byRuleId.get(input.ruleId);
|
|
4266
4476
|
return normalizeFinding({
|
|
4267
4477
|
ruleId: input.ruleId,
|
|
4268
4478
|
ruleVersion: input.ruleVersion,
|
|
@@ -8373,6 +8583,14 @@ function indexTokensByCssVariable(tokens) {
|
|
|
8373
8583
|
// src/rules/tokens-css-vars-must-be-defined.ts
|
|
8374
8584
|
var RULE_ID22 = "tokens/css-vars-must-be-defined";
|
|
8375
8585
|
var RULE_VERSION23 = "1";
|
|
8586
|
+
var EMPTY_VOCABULARY_CODE = "FUI2018";
|
|
8587
|
+
var EMPTY_VOCABULARY_MESSAGE = "token sources resolved to 0 tokens \u2014 rule inert";
|
|
8588
|
+
var EMPTY_VOCABULARY_CONFIG_FALLBACK = "your fragments config";
|
|
8589
|
+
function emptyVocabularyConfigFile(configPath2) {
|
|
8590
|
+
if (!configPath2) return EMPTY_VOCABULARY_CONFIG_FALLBACK;
|
|
8591
|
+
const base = configPath2.replaceAll("\\", "/").replace(/\/+$/u, "").split("/").pop();
|
|
8592
|
+
return base && base.length > 0 ? base : EMPTY_VOCABULARY_CONFIG_FALLBACK;
|
|
8593
|
+
}
|
|
8376
8594
|
var CSS_VAR_REFERENCE = /var\(\s*(--[A-Za-z0-9_-]+)/gi;
|
|
8377
8595
|
function contractVocabularyContext(ix) {
|
|
8378
8596
|
if (!ix.policy.cssVarsMustBeDefined()) return void 0;
|
|
@@ -8394,7 +8612,7 @@ function ruleTokensCssVarsMustBeDefined(ix) {
|
|
|
8394
8612
|
const policy = ix.policy.cssVarsMustBeDefined();
|
|
8395
8613
|
if (!policy) return [];
|
|
8396
8614
|
const context = contractVocabularyContext(ix);
|
|
8397
|
-
if (!context) return [];
|
|
8615
|
+
if (!context) return [emptyVocabularyFinding(ix, policy)];
|
|
8398
8616
|
const { vocabulary } = context;
|
|
8399
8617
|
const findings = [];
|
|
8400
8618
|
for (const decl of ix.byKind("style_declaration")) {
|
|
@@ -8435,6 +8653,27 @@ function ruleTokensCssVarsMustBeDefined(ix) {
|
|
|
8435
8653
|
}
|
|
8436
8654
|
return findings;
|
|
8437
8655
|
}
|
|
8656
|
+
function emptyVocabularyFinding(ix, policy) {
|
|
8657
|
+
return makeFinding({
|
|
8658
|
+
ruleId: RULE_ID22,
|
|
8659
|
+
ruleVersion: RULE_VERSION23,
|
|
8660
|
+
severity: "error",
|
|
8661
|
+
code: EMPTY_VOCABULARY_CODE,
|
|
8662
|
+
message: EMPTY_VOCABULARY_MESSAGE,
|
|
8663
|
+
location: {
|
|
8664
|
+
file: policy.configPath ?? EMPTY_VOCABULARY_CONFIG_FALLBACK,
|
|
8665
|
+
line: 0,
|
|
8666
|
+
column: 0
|
|
8667
|
+
},
|
|
8668
|
+
evidence: ix.evidence([policy.id]),
|
|
8669
|
+
fingerprintIdentity: { reason: "empty-vocabulary" },
|
|
8670
|
+
attributes: {
|
|
8671
|
+
source: "config",
|
|
8672
|
+
inert: true,
|
|
8673
|
+
tokenCount: 0
|
|
8674
|
+
}
|
|
8675
|
+
});
|
|
8676
|
+
}
|
|
8438
8677
|
function sharesContractPrefix(name, prefixes) {
|
|
8439
8678
|
for (const prefix of prefixes) {
|
|
8440
8679
|
if (name.startsWith(prefix)) return true;
|
|
@@ -8525,6 +8764,30 @@ function ruleTokensUpstreamDrift(ix) {
|
|
|
8525
8764
|
return findings;
|
|
8526
8765
|
}
|
|
8527
8766
|
|
|
8767
|
+
// src/rules/rule-config.ts
|
|
8768
|
+
function readRuleConfig(ix) {
|
|
8769
|
+
const disabled = /* @__PURE__ */ new Set();
|
|
8770
|
+
const severities = /* @__PURE__ */ new Map();
|
|
8771
|
+
for (const fact of ix.byKind("governance_rule_config")) {
|
|
8772
|
+
if (!fact.enabled) {
|
|
8773
|
+
disabled.add(fact.ruleId);
|
|
8774
|
+
continue;
|
|
8775
|
+
}
|
|
8776
|
+
if (fact.severity) severities.set(fact.ruleId, fact.severity);
|
|
8777
|
+
}
|
|
8778
|
+
return { disabled, severities };
|
|
8779
|
+
}
|
|
8780
|
+
function capConfiguredSeverity(finding, configured) {
|
|
8781
|
+
if (finding.attributes?.advisory === true && severityLevel(configured) === "error") {
|
|
8782
|
+
return severityLevel(finding.severity) === "error" ? severityFromLevel("warn") : finding.severity;
|
|
8783
|
+
}
|
|
8784
|
+
return configured;
|
|
8785
|
+
}
|
|
8786
|
+
function configuredFindingSeverity(finding, config) {
|
|
8787
|
+
const configured = config.severities.get(finding.ruleId);
|
|
8788
|
+
return configured ? capConfiguredSeverity(finding, severityFromLevel(configured)) : finding.severity;
|
|
8789
|
+
}
|
|
8790
|
+
|
|
8528
8791
|
// src/rules/emit-gate.ts
|
|
8529
8792
|
var BLOCKING_RULE_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
8530
8793
|
"styles/no-raw-color",
|
|
@@ -8777,8 +9040,12 @@ var RULES = [
|
|
|
8777
9040
|
}
|
|
8778
9041
|
];
|
|
8779
9042
|
function runRules(ix) {
|
|
9043
|
+
const { disabled } = readRuleConfig(ix);
|
|
8780
9044
|
const findings = [];
|
|
8781
|
-
for (const rule of RULES)
|
|
9045
|
+
for (const rule of RULES) {
|
|
9046
|
+
if (disabled.has(rule.id)) continue;
|
|
9047
|
+
findings.push(...rule.run(ix));
|
|
9048
|
+
}
|
|
8782
9049
|
return sortFindings(findings);
|
|
8783
9050
|
}
|
|
8784
9051
|
function sortFindings(findings) {
|
|
@@ -8868,7 +9135,7 @@ var PASSTHROUGH_KEYS = [
|
|
|
8868
9135
|
},
|
|
8869
9136
|
{
|
|
8870
9137
|
path: ["registry"],
|
|
8871
|
-
keys: ["requireStory", "publicOnly", "categoryDepth", "includeProps"
|
|
9138
|
+
keys: ["requireStory", "publicOnly", "categoryDepth", "includeProps"]
|
|
8872
9139
|
},
|
|
8873
9140
|
{
|
|
8874
9141
|
path: ["govern", "tailwind"],
|
|
@@ -9122,11 +9389,11 @@ function collectPassthroughRecordValues(authored, path, allowed, diagnostics) {
|
|
|
9122
9389
|
}
|
|
9123
9390
|
}
|
|
9124
9391
|
function stableConfigDiagnostics(diagnostics) {
|
|
9125
|
-
const
|
|
9392
|
+
const unique3 = /* @__PURE__ */ new Map();
|
|
9126
9393
|
for (const diagnostic of diagnostics) {
|
|
9127
|
-
|
|
9394
|
+
unique3.set(`${diagnostic.code}\0${diagnostic.path}`, diagnostic);
|
|
9128
9395
|
}
|
|
9129
|
-
return [...
|
|
9396
|
+
return [...unique3.values()].sort(
|
|
9130
9397
|
(left, right) => left.path.localeCompare(right.path) || left.code.localeCompare(right.code) || left.message.localeCompare(right.message)
|
|
9131
9398
|
);
|
|
9132
9399
|
}
|
|
@@ -9352,10 +9619,11 @@ function evaluateGovernanceIntegrity(input) {
|
|
|
9352
9619
|
const activeRuleCount = [...configs.entries()].filter(
|
|
9353
9620
|
([ruleId, config]) => CONSUMED_RULE_IDS.has(ruleId) && config.enabled
|
|
9354
9621
|
).length;
|
|
9622
|
+
const tokensVocabularyInert = !tokensArmed && tokensFamily.reason === "no token vocabulary" ? 1 : 0;
|
|
9355
9623
|
const roster = {
|
|
9356
9624
|
configured: configuredRuleCount + configDiagnostics.length,
|
|
9357
|
-
active: activeRuleCount,
|
|
9358
|
-
inert: configDiagnostics.length
|
|
9625
|
+
active: Math.max(0, activeRuleCount - tokensVocabularyInert),
|
|
9626
|
+
inert: configDiagnostics.length + tokensVocabularyInert
|
|
9359
9627
|
};
|
|
9360
9628
|
return {
|
|
9361
9629
|
status,
|
|
@@ -9453,7 +9721,30 @@ function sortRecords(values) {
|
|
|
9453
9721
|
}
|
|
9454
9722
|
|
|
9455
9723
|
// src/contract/preimage.ts
|
|
9724
|
+
var CONTRACT_ENFORCEMENT_FIELDS = [
|
|
9725
|
+
"a11yRules",
|
|
9726
|
+
"bans",
|
|
9727
|
+
"performanceBudget",
|
|
9728
|
+
"compoundChildren",
|
|
9729
|
+
"composition"
|
|
9730
|
+
];
|
|
9731
|
+
var CONTRACT_DISPLAY_ONLY_FIELDS = [
|
|
9732
|
+
"propsSummary",
|
|
9733
|
+
"canonicalUsage",
|
|
9734
|
+
"scenarioTags",
|
|
9735
|
+
"states",
|
|
9736
|
+
"variants"
|
|
9737
|
+
];
|
|
9456
9738
|
var CONTRACT_DOMAINS = ["components", "tokens", "canonicalMap", "policy"];
|
|
9739
|
+
var ContractCatalogValidationError = class extends TypeError {
|
|
9740
|
+
issues;
|
|
9741
|
+
constructor(issues) {
|
|
9742
|
+
const sortedIssues = [...issues].sort();
|
|
9743
|
+
super(["Invalid contract catalog:", ...sortedIssues.map((issue) => ` - ${issue}`)].join("\n"));
|
|
9744
|
+
this.name = "ContractCatalogValidationError";
|
|
9745
|
+
this.issues = sortedIssues;
|
|
9746
|
+
}
|
|
9747
|
+
};
|
|
9457
9748
|
var CONTRACT_PREIMAGE_SCHEMA = "fcid-preimage:v1";
|
|
9458
9749
|
var CONTRACT_PREIMAGE_CAPABILITY_HEADER = "X-Fragments-Contract-Preimage";
|
|
9459
9750
|
var SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/u;
|
|
@@ -9481,13 +9772,225 @@ function verifiedContractPreimageFromPin(pin) {
|
|
|
9481
9772
|
function sortCanonical(items) {
|
|
9482
9773
|
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);
|
|
9483
9774
|
}
|
|
9775
|
+
function isPlainRecord(value) {
|
|
9776
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
9777
|
+
const prototype = Object.getPrototypeOf(value);
|
|
9778
|
+
return prototype === Object.prototype || prototype === null;
|
|
9779
|
+
}
|
|
9780
|
+
function requireNonEmptyString(value, path, issues) {
|
|
9781
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
9782
|
+
issues.push(`${path}: expected a non-empty string`);
|
|
9783
|
+
}
|
|
9784
|
+
}
|
|
9785
|
+
function validateStringArray(value, path, issues) {
|
|
9786
|
+
if (!Array.isArray(value)) {
|
|
9787
|
+
issues.push(`${path}: expected an array`);
|
|
9788
|
+
return;
|
|
9789
|
+
}
|
|
9790
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9791
|
+
for (const [index, entry] of value.entries()) {
|
|
9792
|
+
requireNonEmptyString(entry, `${path}[${index}]`, issues);
|
|
9793
|
+
if (typeof entry === "string" && entry.length > 0) {
|
|
9794
|
+
if (seen.has(entry)) issues.push(`${path}: duplicate value "${entry}"`);
|
|
9795
|
+
seen.add(entry);
|
|
9796
|
+
}
|
|
9797
|
+
}
|
|
9798
|
+
}
|
|
9799
|
+
function validateContractCatalog(catalog) {
|
|
9800
|
+
const issues = [];
|
|
9801
|
+
if (!isPlainRecord(catalog)) {
|
|
9802
|
+
throw new ContractCatalogValidationError(["(root): expected a plain object"]);
|
|
9803
|
+
}
|
|
9804
|
+
const componentIdentities = /* @__PURE__ */ new Set();
|
|
9805
|
+
if (catalog.components !== void 0) {
|
|
9806
|
+
if (!Array.isArray(catalog.components)) {
|
|
9807
|
+
issues.push("components: expected an array");
|
|
9808
|
+
} else {
|
|
9809
|
+
for (const [index, value] of catalog.components.entries()) {
|
|
9810
|
+
const path = `components[${index}]`;
|
|
9811
|
+
if (!isPlainRecord(value)) {
|
|
9812
|
+
issues.push(`${path}: expected a plain object`);
|
|
9813
|
+
continue;
|
|
9814
|
+
}
|
|
9815
|
+
requireNonEmptyString(value.name, `${path}.name`, issues);
|
|
9816
|
+
if (value.parentName !== void 0) {
|
|
9817
|
+
requireNonEmptyString(value.parentName, `${path}.parentName`, issues);
|
|
9818
|
+
}
|
|
9819
|
+
if (typeof value.name === "string" && value.name.length > 0) {
|
|
9820
|
+
const identity = `${typeof value.parentName === "string" ? value.parentName : ""}#${value.name}`;
|
|
9821
|
+
if (componentIdentities.has(identity)) {
|
|
9822
|
+
issues.push(`components: duplicate identity "${identity}"`);
|
|
9823
|
+
}
|
|
9824
|
+
componentIdentities.add(identity);
|
|
9825
|
+
}
|
|
9826
|
+
if (value.props !== void 0) validateStringArray(value.props, `${path}.props`, issues);
|
|
9827
|
+
if (value.compoundChildren !== void 0) {
|
|
9828
|
+
validateStringArray(value.compoundChildren, `${path}.compoundChildren`, issues);
|
|
9829
|
+
}
|
|
9830
|
+
if (value.contract !== void 0 && !isPlainRecord(value.contract)) {
|
|
9831
|
+
issues.push(`${path}.contract: expected a plain object`);
|
|
9832
|
+
}
|
|
9833
|
+
if (value.governance !== void 0 && !Array.isArray(value.governance)) {
|
|
9834
|
+
issues.push(`${path}.governance: expected an array`);
|
|
9835
|
+
}
|
|
9836
|
+
}
|
|
9837
|
+
}
|
|
9838
|
+
}
|
|
9839
|
+
const tokenNames = /* @__PURE__ */ new Set();
|
|
9840
|
+
if (catalog.tokens !== void 0) {
|
|
9841
|
+
if (!Array.isArray(catalog.tokens)) {
|
|
9842
|
+
issues.push("tokens: expected an array");
|
|
9843
|
+
} else {
|
|
9844
|
+
for (const [index, value] of catalog.tokens.entries()) {
|
|
9845
|
+
const path = `tokens[${index}]`;
|
|
9846
|
+
if (!isPlainRecord(value)) {
|
|
9847
|
+
issues.push(`${path}: expected a plain object`);
|
|
9848
|
+
continue;
|
|
9849
|
+
}
|
|
9850
|
+
requireNonEmptyString(value.name, `${path}.name`, issues);
|
|
9851
|
+
if (typeof value.name === "string" && value.name.length > 0) {
|
|
9852
|
+
if (tokenNames.has(value.name)) issues.push(`tokens: duplicate identity "${value.name}"`);
|
|
9853
|
+
tokenNames.add(value.name);
|
|
9854
|
+
}
|
|
9855
|
+
if (typeof value.value !== "string" && typeof value.value !== "number" || typeof value.value === "number" && !Number.isFinite(value.value)) {
|
|
9856
|
+
issues.push(`${path}.value: expected a finite number or string`);
|
|
9857
|
+
}
|
|
9858
|
+
if (value.type !== void 0) requireNonEmptyString(value.type, `${path}.type`, issues);
|
|
9859
|
+
}
|
|
9860
|
+
}
|
|
9861
|
+
}
|
|
9862
|
+
const confirmedMappings = /* @__PURE__ */ new Set();
|
|
9863
|
+
if (catalog.canonicalMappings !== void 0) {
|
|
9864
|
+
if (!Array.isArray(catalog.canonicalMappings)) {
|
|
9865
|
+
issues.push("canonicalMappings: expected an array");
|
|
9866
|
+
} else {
|
|
9867
|
+
for (const [index, value] of catalog.canonicalMappings.entries()) {
|
|
9868
|
+
const path = `canonicalMappings[${index}]`;
|
|
9869
|
+
if (!isPlainRecord(value)) {
|
|
9870
|
+
issues.push(`${path}: expected a plain object`);
|
|
9871
|
+
continue;
|
|
9872
|
+
}
|
|
9873
|
+
requireNonEmptyString(value.component, `${path}.component`, issues);
|
|
9874
|
+
requireNonEmptyString(value.canonical, `${path}.canonical`, issues);
|
|
9875
|
+
if (!["confirmed", "proposed", "unknown"].includes(value.status)) {
|
|
9876
|
+
issues.push(`${path}.status: expected confirmed, proposed, or unknown`);
|
|
9877
|
+
}
|
|
9878
|
+
if (value.status === "confirmed" && typeof value.component === "string") {
|
|
9879
|
+
if (confirmedMappings.has(value.component)) {
|
|
9880
|
+
issues.push(`canonicalMappings: duplicate confirmed identity "${value.component}"`);
|
|
9881
|
+
}
|
|
9882
|
+
confirmedMappings.add(value.component);
|
|
9883
|
+
}
|
|
9884
|
+
if (value.importPath !== void 0) {
|
|
9885
|
+
requireNonEmptyString(value.importPath, `${path}.importPath`, issues);
|
|
9886
|
+
}
|
|
9887
|
+
if (value.propMapping !== void 0 && !Array.isArray(value.propMapping)) {
|
|
9888
|
+
issues.push(`${path}.propMapping: expected an array`);
|
|
9889
|
+
}
|
|
9890
|
+
if (value.resolves !== void 0 && !Array.isArray(value.resolves)) {
|
|
9891
|
+
issues.push(`${path}.resolves: expected an array`);
|
|
9892
|
+
}
|
|
9893
|
+
if (value.bridge !== void 0 && !isPlainRecord(value.bridge)) {
|
|
9894
|
+
issues.push(`${path}.bridge: expected a plain object`);
|
|
9895
|
+
}
|
|
9896
|
+
}
|
|
9897
|
+
}
|
|
9898
|
+
}
|
|
9899
|
+
if (catalog.policy !== void 0 && catalog.policy !== null) {
|
|
9900
|
+
if (!isPlainRecord(catalog.policy)) {
|
|
9901
|
+
issues.push("policy: expected a plain object or null");
|
|
9902
|
+
} else {
|
|
9903
|
+
if (catalog.policy.rules !== void 0 && !isPlainRecord(catalog.policy.rules)) {
|
|
9904
|
+
issues.push("policy.rules: expected a plain object");
|
|
9905
|
+
}
|
|
9906
|
+
if (catalog.policy.codes !== void 0 && !isPlainRecord(catalog.policy.codes)) {
|
|
9907
|
+
issues.push("policy.codes: expected a plain object");
|
|
9908
|
+
}
|
|
9909
|
+
if (catalog.policy.compositionPatterns !== void 0 && !Array.isArray(catalog.policy.compositionPatterns)) {
|
|
9910
|
+
issues.push("policy.compositionPatterns: expected an array");
|
|
9911
|
+
}
|
|
9912
|
+
if (catalog.policy.waivers !== void 0) {
|
|
9913
|
+
if (!Array.isArray(catalog.policy.waivers)) {
|
|
9914
|
+
issues.push("policy.waivers: expected an array");
|
|
9915
|
+
} else {
|
|
9916
|
+
const waiverIds = /* @__PURE__ */ new Set();
|
|
9917
|
+
for (const [index, value] of catalog.policy.waivers.entries()) {
|
|
9918
|
+
const path = `policy.waivers[${index}]`;
|
|
9919
|
+
if (!isPlainRecord(value)) {
|
|
9920
|
+
issues.push(`${path}: expected a plain object`);
|
|
9921
|
+
continue;
|
|
9922
|
+
}
|
|
9923
|
+
requireNonEmptyString(value.id, `${path}.id`, issues);
|
|
9924
|
+
requireNonEmptyString(value.target, `${path}.target`, issues);
|
|
9925
|
+
requireNonEmptyString(value.reason, `${path}.reason`, issues);
|
|
9926
|
+
if (value.expiresOn !== void 0) {
|
|
9927
|
+
requireNonEmptyString(value.expiresOn, `${path}.expiresOn`, issues);
|
|
9928
|
+
}
|
|
9929
|
+
if (typeof value.id === "string" && value.id.length > 0) {
|
|
9930
|
+
if (waiverIds.has(value.id)) {
|
|
9931
|
+
issues.push(`policy.waivers: duplicate identity "${value.id}"`);
|
|
9932
|
+
}
|
|
9933
|
+
waiverIds.add(value.id);
|
|
9934
|
+
}
|
|
9935
|
+
}
|
|
9936
|
+
}
|
|
9937
|
+
}
|
|
9938
|
+
}
|
|
9939
|
+
}
|
|
9940
|
+
if (issues.length > 0) throw new ContractCatalogValidationError(issues);
|
|
9941
|
+
}
|
|
9942
|
+
function projectEnforcementContract(contract) {
|
|
9943
|
+
if (!contract || typeof contract !== "object" || Array.isArray(contract)) {
|
|
9944
|
+
return void 0;
|
|
9945
|
+
}
|
|
9946
|
+
const source = contract;
|
|
9947
|
+
const projected = {};
|
|
9948
|
+
if (Array.isArray(source.a11yRules)) {
|
|
9949
|
+
projected.a11yRules = sortCanonical([...source.a11yRules]);
|
|
9950
|
+
}
|
|
9951
|
+
if (Array.isArray(source.bans)) {
|
|
9952
|
+
projected.bans = sortCanonical([...source.bans]);
|
|
9953
|
+
}
|
|
9954
|
+
if (typeof source.performanceBudget === "number") {
|
|
9955
|
+
projected.performanceBudget = source.performanceBudget;
|
|
9956
|
+
}
|
|
9957
|
+
if (Array.isArray(source.composition)) {
|
|
9958
|
+
projected.composition = sortCanonical([...source.composition]);
|
|
9959
|
+
}
|
|
9960
|
+
const compoundChildren = projectContractCompoundChildren(source.compoundChildren);
|
|
9961
|
+
if (compoundChildren !== void 0) {
|
|
9962
|
+
projected.compoundChildren = compoundChildren;
|
|
9963
|
+
}
|
|
9964
|
+
return Object.keys(projected).length > 0 ? projected : void 0;
|
|
9965
|
+
}
|
|
9966
|
+
function projectContractCompoundChildren(value) {
|
|
9967
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
9968
|
+
const entries = Object.entries(value).map(([name, raw]) => {
|
|
9969
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
9970
|
+
return [name, {}];
|
|
9971
|
+
}
|
|
9972
|
+
const child = raw;
|
|
9973
|
+
const projected = {};
|
|
9974
|
+
if (typeof child.required === "boolean") projected.required = child.required;
|
|
9975
|
+
if (Array.isArray(child.accepts)) {
|
|
9976
|
+
projected.accepts = [...child.accepts].filter((entry) => typeof entry === "string").sort();
|
|
9977
|
+
}
|
|
9978
|
+
return [name, projected];
|
|
9979
|
+
}).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
9980
|
+
return Object.fromEntries(entries);
|
|
9981
|
+
}
|
|
9982
|
+
function projectGovernanceRecords(records) {
|
|
9983
|
+
if (!records || records.length === 0) return void 0;
|
|
9984
|
+
return sortCanonical([...records]);
|
|
9985
|
+
}
|
|
9484
9986
|
function projectComponents(components) {
|
|
9485
9987
|
return sortCanonical(
|
|
9486
9988
|
(components ?? []).map((component) => ({
|
|
9487
9989
|
name: component.name,
|
|
9488
9990
|
parentName: component.parentName,
|
|
9489
9991
|
props: component.props ? [...component.props].sort() : void 0,
|
|
9490
|
-
contract: component.contract,
|
|
9992
|
+
contract: projectEnforcementContract(component.contract),
|
|
9993
|
+
governance: projectGovernanceRecords(component.governance),
|
|
9491
9994
|
compoundChildren: component.compoundChildren ? [...component.compoundChildren].sort() : void 0
|
|
9492
9995
|
}))
|
|
9493
9996
|
);
|
|
@@ -9569,6 +10072,7 @@ function projectPolicy(policy) {
|
|
|
9569
10072
|
};
|
|
9570
10073
|
}
|
|
9571
10074
|
function projectContractPreimage(catalog) {
|
|
10075
|
+
validateContractCatalog(catalog);
|
|
9572
10076
|
return {
|
|
9573
10077
|
schema: CONTRACT_PREIMAGE_SCHEMA,
|
|
9574
10078
|
domains: {
|
|
@@ -9608,16 +10112,31 @@ function contractComponentsFromFragments(fragments) {
|
|
|
9608
10112
|
const parentName = fragment?.meta?.parentComponentName;
|
|
9609
10113
|
const rawChildren = fragment?.structure?.compoundChildren;
|
|
9610
10114
|
const compoundChildren = Array.isArray(rawChildren) ? rawChildren.map((child) => child?.name).filter((childName) => typeof childName === "string") : void 0;
|
|
10115
|
+
const governance = resolveGovernanceRecordsForIdentity({
|
|
10116
|
+
governance: Array.isArray(fragment?.governance) ? fragment.governance : void 0,
|
|
10117
|
+
govern: typeof fragment?.govern === "function" ? fragment.govern : void 0
|
|
10118
|
+
});
|
|
9611
10119
|
components.push({
|
|
9612
10120
|
name,
|
|
9613
10121
|
parentName: typeof parentName === "string" ? parentName : void 0,
|
|
9614
10122
|
props: Object.keys(fragment?.props ?? {}),
|
|
9615
10123
|
contract: fragment?.contract,
|
|
10124
|
+
governance,
|
|
9616
10125
|
compoundChildren
|
|
9617
10126
|
});
|
|
9618
10127
|
}
|
|
9619
10128
|
return components;
|
|
9620
10129
|
}
|
|
10130
|
+
function deriveArtifactId(content) {
|
|
10131
|
+
return artifactContentHash({
|
|
10132
|
+
schema: "artifact-content:v1",
|
|
10133
|
+
modules: content.modules,
|
|
10134
|
+
states: content.states,
|
|
10135
|
+
guidance: content.guidance,
|
|
10136
|
+
render: content.render,
|
|
10137
|
+
runtime: content.runtime
|
|
10138
|
+
});
|
|
10139
|
+
}
|
|
9621
10140
|
|
|
9622
10141
|
// src/contract/stamp.ts
|
|
9623
10142
|
var AGENT_CONTEXT_RELATIVE_PATH = ".fragments/agent-context.md";
|
|
@@ -9649,7 +10168,7 @@ function parseContractStamp(text) {
|
|
|
9649
10168
|
const fcidLine = STAMP_FCID_LINE.exec(text);
|
|
9650
10169
|
if (!header || !fcidLine) return null;
|
|
9651
10170
|
const contractVersion = Number(header[1]);
|
|
9652
|
-
if (!Number.isSafeInteger(contractVersion)) return null;
|
|
10171
|
+
if (!Number.isSafeInteger(contractVersion) || contractVersion < 1) return null;
|
|
9653
10172
|
const fcid = fcidLine[1];
|
|
9654
10173
|
if (!fcid.startsWith(header[2])) return null;
|
|
9655
10174
|
const domainsLine = STAMP_DOMAINS_LINE.exec(text);
|
|
@@ -9935,24 +10454,2078 @@ function strongOverlap(overlap) {
|
|
|
9935
10454
|
function withTarget(state, confidence, canonicalTarget) {
|
|
9936
10455
|
return canonicalTarget ? { state, confidence, canonicalTarget } : { state, confidence };
|
|
9937
10456
|
}
|
|
10457
|
+
|
|
10458
|
+
// src/repository-binding.ts
|
|
10459
|
+
import { z as z8 } from "zod";
|
|
10460
|
+
var REPOSITORY_BINDING_ID_MAX_BYTES_V1 = 256;
|
|
10461
|
+
var PROVIDER_ID_MAX_BYTES_V1 = 64;
|
|
10462
|
+
var utf8Length = (value) => new TextEncoder().encode(value).byteLength;
|
|
10463
|
+
var boundedString = (label, maxBytes) => z8.string().min(1, `${label} is required`).refine((value) => utf8Length(value) <= maxBytes, `${label} exceeds ${maxBytes} UTF-8 bytes`);
|
|
10464
|
+
var providerSchema = boundedString("provider", PROVIDER_ID_MAX_BYTES_V1).transform((value) => value.trim().toLowerCase()).refine(
|
|
10465
|
+
(value) => /^[a-z][a-z0-9_-]*$/u.test(value),
|
|
10466
|
+
"provider must be a bounded lowercase identifier"
|
|
10467
|
+
);
|
|
10468
|
+
function normalizeProviderInstanceId(value) {
|
|
10469
|
+
const trimmed = value.trim();
|
|
10470
|
+
if (trimmed.length === 0) throw new TypeError("providerInstanceId is required");
|
|
10471
|
+
if (trimmed.includes("://")) {
|
|
10472
|
+
const url = new URL(trimmed);
|
|
10473
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
10474
|
+
throw new TypeError("providerInstanceId URL must use http or https");
|
|
10475
|
+
}
|
|
10476
|
+
if (url.username || url.password || url.search || url.hash || url.pathname !== "" && url.pathname !== "/") {
|
|
10477
|
+
throw new TypeError("providerInstanceId must identify an origin, not a path or credential");
|
|
10478
|
+
}
|
|
10479
|
+
return url.host.toLowerCase().replace(/\.$/u, "");
|
|
10480
|
+
}
|
|
10481
|
+
const normalized = trimmed.toLowerCase().replace(/\.$/u, "");
|
|
10482
|
+
if (!/^[a-z0-9](?:[a-z0-9._:-]*[a-z0-9])?$/u.test(normalized)) {
|
|
10483
|
+
throw new TypeError("providerInstanceId must be a normalized origin or tenant key");
|
|
10484
|
+
}
|
|
10485
|
+
return normalized;
|
|
10486
|
+
}
|
|
10487
|
+
var providerInstanceSchema = boundedString(
|
|
10488
|
+
"providerInstanceId",
|
|
10489
|
+
REPOSITORY_BINDING_ID_MAX_BYTES_V1
|
|
10490
|
+
).transform((value, context) => {
|
|
10491
|
+
try {
|
|
10492
|
+
return normalizeProviderInstanceId(value);
|
|
10493
|
+
} catch (error) {
|
|
10494
|
+
context.addIssue({
|
|
10495
|
+
code: z8.ZodIssueCode.custom,
|
|
10496
|
+
message: error instanceof Error ? error.message : String(error)
|
|
10497
|
+
});
|
|
10498
|
+
return z8.NEVER;
|
|
10499
|
+
}
|
|
10500
|
+
});
|
|
10501
|
+
var repositoryBindingKeyV1Schema = z8.object({
|
|
10502
|
+
provider: providerSchema,
|
|
10503
|
+
providerInstanceId: providerInstanceSchema,
|
|
10504
|
+
repositoryExternalId: boundedString("repositoryExternalId", REPOSITORY_BINDING_ID_MAX_BYTES_V1),
|
|
10505
|
+
bindingId: boundedString("bindingId", REPOSITORY_BINDING_ID_MAX_BYTES_V1)
|
|
10506
|
+
}).strict();
|
|
10507
|
+
function normalizeRepositoryBindingKeyV1(value) {
|
|
10508
|
+
return repositoryBindingKeyV1Schema.parse(value);
|
|
10509
|
+
}
|
|
10510
|
+
function repositoryBindingDigestV1(value) {
|
|
10511
|
+
const binding = normalizeRepositoryBindingKeyV1(value);
|
|
10512
|
+
return digestHexSchema.parse(
|
|
10513
|
+
sha256Hex(
|
|
10514
|
+
canonicalPreimage({
|
|
10515
|
+
schema: "repository-binding.v1",
|
|
10516
|
+
provider: binding.provider,
|
|
10517
|
+
providerInstanceId: binding.providerInstanceId,
|
|
10518
|
+
repositoryExternalId: binding.repositoryExternalId,
|
|
10519
|
+
bindingId: binding.bindingId
|
|
10520
|
+
})
|
|
10521
|
+
)
|
|
10522
|
+
);
|
|
10523
|
+
}
|
|
10524
|
+
|
|
10525
|
+
// src/analysis-plan/types.ts
|
|
10526
|
+
import { z as z9 } from "zod";
|
|
10527
|
+
var ANALYSIS_PLAN_MAX_REGIONS_V1 = 1e3;
|
|
10528
|
+
var ANALYSIS_PLAN_MAX_CAPABILITIES_V1 = 256;
|
|
10529
|
+
var ANALYSIS_PLAN_MAX_DIALECTS_PER_REGION_V1 = 64;
|
|
10530
|
+
var ANALYSIS_LIMIT_CEILINGS_V1 = {
|
|
10531
|
+
maxSourceFiles: 1e5,
|
|
10532
|
+
maxSourceBytes: 1073741824,
|
|
10533
|
+
maxFileBytes: 10485760,
|
|
10534
|
+
maxFacts: 1e6,
|
|
10535
|
+
maxRegions: ANALYSIS_PLAN_MAX_REGIONS_V1,
|
|
10536
|
+
maxDiagnostics: 1e5,
|
|
10537
|
+
maxDurationMs: 9e5
|
|
10538
|
+
};
|
|
10539
|
+
var bounded = (max) => z9.string().min(1).max(max);
|
|
10540
|
+
var positiveBoundedInteger = (max) => z9.number().int().positive().max(max);
|
|
10541
|
+
var uniqueStrings = (values) => new Set(values).size === values.length;
|
|
10542
|
+
var coverageStateV1Schema = z9.enum([
|
|
10543
|
+
"analyzed",
|
|
10544
|
+
"unsupported",
|
|
10545
|
+
"excluded_by_contract",
|
|
10546
|
+
"skipped_limit",
|
|
10547
|
+
"failed"
|
|
10548
|
+
]);
|
|
10549
|
+
var analysisLimitsV1Schema = z9.object({
|
|
10550
|
+
maxSourceFiles: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxSourceFiles),
|
|
10551
|
+
maxSourceBytes: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxSourceBytes),
|
|
10552
|
+
maxFileBytes: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxFileBytes),
|
|
10553
|
+
maxFacts: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxFacts),
|
|
10554
|
+
maxRegions: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxRegions),
|
|
10555
|
+
maxDiagnostics: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxDiagnostics),
|
|
10556
|
+
maxDurationMs: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxDurationMs)
|
|
10557
|
+
}).strict();
|
|
10558
|
+
var analysisRegionV1Schema = z9.object({
|
|
10559
|
+
regionId: bounded(256),
|
|
10560
|
+
pathPattern: bounded(4096),
|
|
10561
|
+
kind: z9.enum(["component_source", "style_source", "token_source", "config"]),
|
|
10562
|
+
language: bounded(64),
|
|
10563
|
+
required: z9.boolean(),
|
|
10564
|
+
requiredDialects: z9.array(bounded(128)).max(ANALYSIS_PLAN_MAX_DIALECTS_PER_REGION_V1).refine(uniqueStrings, "requiredDialects must be unique"),
|
|
10565
|
+
analyzer: z9.object({
|
|
10566
|
+
id: bounded(256),
|
|
10567
|
+
interfaceVersion: bounded(128),
|
|
10568
|
+
implementationVersion: bounded(128)
|
|
10569
|
+
}).strict()
|
|
10570
|
+
}).strict();
|
|
10571
|
+
var coverageRegionV1Schema = z9.object({
|
|
10572
|
+
regionId: bounded(256),
|
|
10573
|
+
state: coverageStateV1Schema,
|
|
10574
|
+
fileCount: z9.number().int().nonnegative().max(ANALYSIS_LIMIT_CEILINGS_V1.maxSourceFiles),
|
|
10575
|
+
byteCount: z9.number().int().nonnegative().max(ANALYSIS_LIMIT_CEILINGS_V1.maxSourceBytes),
|
|
10576
|
+
diagnosticIds: z9.array(bounded(256)).max(ANALYSIS_LIMIT_CEILINGS_V1.maxDiagnostics).refine(uniqueStrings, "diagnosticIds must be unique")
|
|
10577
|
+
}).strict();
|
|
10578
|
+
var coverageCountsV1Schema = z9.object({
|
|
10579
|
+
analyzed: z9.number().int().nonnegative(),
|
|
10580
|
+
unsupported: z9.number().int().nonnegative(),
|
|
10581
|
+
excluded_by_contract: z9.number().int().nonnegative(),
|
|
10582
|
+
skipped_limit: z9.number().int().nonnegative(),
|
|
10583
|
+
failed: z9.number().int().nonnegative()
|
|
10584
|
+
}).strict();
|
|
10585
|
+
var coverageSummaryV1Schema = z9.object({
|
|
10586
|
+
plannedRegions: z9.number().int().nonnegative(),
|
|
10587
|
+
observedRegions: z9.number().int().nonnegative(),
|
|
10588
|
+
requiredRegions: z9.number().int().nonnegative(),
|
|
10589
|
+
requiredByState: coverageCountsV1Schema,
|
|
10590
|
+
optionalByState: coverageCountsV1Schema,
|
|
10591
|
+
eligibleFiles: z9.number().int().nonnegative(),
|
|
10592
|
+
analyzedFiles: z9.number().int().nonnegative(),
|
|
10593
|
+
analyzedBytes: z9.number().int().nonnegative()
|
|
10594
|
+
}).strict();
|
|
10595
|
+
var analysisPlanBaseShape = {
|
|
10596
|
+
binding: repositoryBindingKeyV1Schema,
|
|
10597
|
+
source: z9.object({
|
|
10598
|
+
commitId: bounded(256),
|
|
10599
|
+
treeId: bounded(256).optional(),
|
|
10600
|
+
defaultBranch: bounded(256),
|
|
10601
|
+
acquiredBy: z9.enum(["github_app", "local_worktree", "ci_attested"])
|
|
10602
|
+
}).strict(),
|
|
10603
|
+
contract: z9.object({
|
|
10604
|
+
fcid: digestHexStringSchema,
|
|
10605
|
+
artifactDigest: digestHexStringSchema
|
|
10606
|
+
}).strict(),
|
|
10607
|
+
config: z9.object({
|
|
10608
|
+
path: bounded(4096).refine(
|
|
10609
|
+
(value) => !value.startsWith("/") && !value.includes("\\") && !value.split("/").includes(".."),
|
|
10610
|
+
"config path must be a portable repository-relative path"
|
|
10611
|
+
),
|
|
10612
|
+
digest: digestHexStringSchema
|
|
10613
|
+
}).strict(),
|
|
10614
|
+
profile: z9.object({
|
|
10615
|
+
id: z9.literal("react-web-v1"),
|
|
10616
|
+
version: bounded(128),
|
|
10617
|
+
capabilities: z9.array(bounded(128)).max(ANALYSIS_PLAN_MAX_CAPABILITIES_V1).refine(uniqueStrings, "capabilities must be unique")
|
|
10618
|
+
}).strict(),
|
|
10619
|
+
regions: z9.array(analysisRegionV1Schema).max(ANALYSIS_PLAN_MAX_REGIONS_V1).refine(
|
|
10620
|
+
(regions) => new Set(regions.map((region) => region.regionId)).size === regions.length,
|
|
10621
|
+
"regionId values must be unique"
|
|
10622
|
+
),
|
|
10623
|
+
limits: analysisLimitsV1Schema,
|
|
10624
|
+
evaluatorVersion: bounded(128),
|
|
10625
|
+
createdAt: z9.string().datetime({ offset: true })
|
|
10626
|
+
};
|
|
10627
|
+
function validatePlanLimits(plan, context) {
|
|
10628
|
+
if (plan.regions.length > plan.limits.maxRegions) {
|
|
10629
|
+
context.addIssue({
|
|
10630
|
+
code: z9.ZodIssueCode.custom,
|
|
10631
|
+
path: ["regions"],
|
|
10632
|
+
message: "Planned regions exceed the plan's maxRegions limit"
|
|
10633
|
+
});
|
|
10634
|
+
}
|
|
10635
|
+
if (plan.limits.maxFileBytes > plan.limits.maxSourceBytes) {
|
|
10636
|
+
context.addIssue({
|
|
10637
|
+
code: z9.ZodIssueCode.custom,
|
|
10638
|
+
path: ["limits", "maxFileBytes"],
|
|
10639
|
+
message: "maxFileBytes cannot exceed maxSourceBytes"
|
|
10640
|
+
});
|
|
10641
|
+
}
|
|
10642
|
+
}
|
|
10643
|
+
var analysisPlanInputV1Schema = z9.object(analysisPlanBaseShape).strict().superRefine(validatePlanLimits);
|
|
10644
|
+
var analysisPlanV1Schema = z9.object({
|
|
10645
|
+
schemaVersion: z9.literal(1),
|
|
10646
|
+
analysisPlanId: analysisPlanIdStringSchema,
|
|
10647
|
+
...analysisPlanBaseShape,
|
|
10648
|
+
obligationsDigest: digestHexStringSchema,
|
|
10649
|
+
digest: digestHexStringSchema
|
|
10650
|
+
}).strict().superRefine(validatePlanLimits);
|
|
10651
|
+
|
|
10652
|
+
// src/analysis-plan/digest.ts
|
|
10653
|
+
var sortedUnique = (values) => [...new Set(values)].sort();
|
|
10654
|
+
function semanticInput(input) {
|
|
10655
|
+
return {
|
|
10656
|
+
binding: input.binding,
|
|
10657
|
+
source: input.source,
|
|
10658
|
+
contract: input.contract,
|
|
10659
|
+
config: input.config,
|
|
10660
|
+
profile: input.profile,
|
|
10661
|
+
regions: input.regions,
|
|
10662
|
+
limits: input.limits,
|
|
10663
|
+
evaluatorVersion: input.evaluatorVersion,
|
|
10664
|
+
createdAt: input.createdAt
|
|
10665
|
+
};
|
|
10666
|
+
}
|
|
10667
|
+
function normalizeRegion(region) {
|
|
10668
|
+
return {
|
|
10669
|
+
...region,
|
|
10670
|
+
requiredDialects: sortedUnique(region.requiredDialects),
|
|
10671
|
+
analyzer: { ...region.analyzer }
|
|
10672
|
+
};
|
|
10673
|
+
}
|
|
10674
|
+
function normalizeAnalysisPlanInputV1(input) {
|
|
10675
|
+
const semantic = semanticInput(input);
|
|
10676
|
+
const normalized = {
|
|
10677
|
+
...semantic,
|
|
10678
|
+
binding: normalizeRepositoryBindingKeyV1(semantic.binding),
|
|
10679
|
+
source: { ...semantic.source },
|
|
10680
|
+
contract: { ...semantic.contract },
|
|
10681
|
+
config: { ...semantic.config },
|
|
10682
|
+
profile: {
|
|
10683
|
+
...semantic.profile,
|
|
10684
|
+
capabilities: sortedUnique(semantic.profile.capabilities)
|
|
10685
|
+
},
|
|
10686
|
+
regions: semantic.regions.map(normalizeRegion).sort((left, right) => compareCanonicalStrings(left.regionId, right.regionId)),
|
|
10687
|
+
limits: { ...semantic.limits }
|
|
10688
|
+
};
|
|
10689
|
+
return analysisPlanInputV1Schema.parse(normalized);
|
|
10690
|
+
}
|
|
10691
|
+
function obligationsProjection(normalized) {
|
|
10692
|
+
return {
|
|
10693
|
+
schema: "analysis-obligations.v1",
|
|
10694
|
+
bindingDigest: repositoryBindingDigestV1(normalized.binding),
|
|
10695
|
+
contract: normalized.contract,
|
|
10696
|
+
config: normalized.config,
|
|
10697
|
+
profile: normalized.profile,
|
|
10698
|
+
regions: normalized.regions,
|
|
10699
|
+
limits: normalized.limits,
|
|
10700
|
+
evaluatorVersion: normalized.evaluatorVersion
|
|
10701
|
+
};
|
|
10702
|
+
}
|
|
10703
|
+
function exactPlanProjection(normalized) {
|
|
10704
|
+
return {
|
|
10705
|
+
schema: "analysis-plan.v1",
|
|
10706
|
+
bindingDigest: repositoryBindingDigestV1(normalized.binding),
|
|
10707
|
+
source: {
|
|
10708
|
+
commitId: normalized.source.commitId,
|
|
10709
|
+
treeId: normalized.source.treeId,
|
|
10710
|
+
acquiredBy: normalized.source.acquiredBy
|
|
10711
|
+
},
|
|
10712
|
+
contract: normalized.contract,
|
|
10713
|
+
config: normalized.config,
|
|
10714
|
+
profile: normalized.profile,
|
|
10715
|
+
regions: normalized.regions,
|
|
10716
|
+
limits: normalized.limits,
|
|
10717
|
+
evaluatorVersion: normalized.evaluatorVersion
|
|
10718
|
+
};
|
|
10719
|
+
}
|
|
10720
|
+
function analysisObligationsDigestV1(input) {
|
|
10721
|
+
const normalized = normalizeAnalysisPlanInputV1(input);
|
|
10722
|
+
return digestHexSchema.parse(sha256Hex(canonicalPreimage(obligationsProjection(normalized))));
|
|
10723
|
+
}
|
|
10724
|
+
function analysisPlanDigestV1(input) {
|
|
10725
|
+
const normalized = normalizeAnalysisPlanInputV1(input);
|
|
10726
|
+
return digestHexSchema.parse(sha256Hex(canonicalPreimage(exactPlanProjection(normalized))));
|
|
10727
|
+
}
|
|
10728
|
+
function buildAnalysisPlanV1(input) {
|
|
10729
|
+
const normalized = normalizeAnalysisPlanInputV1(input);
|
|
10730
|
+
const digest = digestHexSchema.parse(
|
|
10731
|
+
sha256Hex(canonicalPreimage(exactPlanProjection(normalized)))
|
|
10732
|
+
);
|
|
10733
|
+
return analysisPlanV1Schema.parse({
|
|
10734
|
+
schemaVersion: 1,
|
|
10735
|
+
analysisPlanId: analysisPlanIdFromDigest(digest),
|
|
10736
|
+
...normalized,
|
|
10737
|
+
obligationsDigest: digestHexSchema.parse(
|
|
10738
|
+
sha256Hex(canonicalPreimage(obligationsProjection(normalized)))
|
|
10739
|
+
),
|
|
10740
|
+
digest
|
|
10741
|
+
});
|
|
10742
|
+
}
|
|
10743
|
+
function parseAnalysisPlanV1(value) {
|
|
10744
|
+
const parsed = analysisPlanV1Schema.parse(value);
|
|
10745
|
+
const rebuilt = buildAnalysisPlanV1({
|
|
10746
|
+
binding: parsed.binding,
|
|
10747
|
+
source: parsed.source,
|
|
10748
|
+
contract: parsed.contract,
|
|
10749
|
+
config: parsed.config,
|
|
10750
|
+
profile: parsed.profile,
|
|
10751
|
+
regions: parsed.regions,
|
|
10752
|
+
limits: parsed.limits,
|
|
10753
|
+
evaluatorVersion: parsed.evaluatorVersion,
|
|
10754
|
+
createdAt: parsed.createdAt
|
|
10755
|
+
});
|
|
10756
|
+
if (parsed.analysisPlanId !== rebuilt.analysisPlanId || parsed.digest !== rebuilt.digest || parsed.obligationsDigest !== rebuilt.obligationsDigest) {
|
|
10757
|
+
throw new TypeError("AnalysisPlanV1 derived identity does not match its semantic projection");
|
|
10758
|
+
}
|
|
10759
|
+
return rebuilt;
|
|
10760
|
+
}
|
|
10761
|
+
|
|
10762
|
+
// src/analysis-plan/coverage.ts
|
|
10763
|
+
var COVERAGE_STATES = [
|
|
10764
|
+
"analyzed",
|
|
10765
|
+
"unsupported",
|
|
10766
|
+
"excluded_by_contract",
|
|
10767
|
+
"skipped_limit",
|
|
10768
|
+
"failed"
|
|
10769
|
+
];
|
|
10770
|
+
function emptyCounts() {
|
|
10771
|
+
return {
|
|
10772
|
+
analyzed: 0,
|
|
10773
|
+
unsupported: 0,
|
|
10774
|
+
excluded_by_contract: 0,
|
|
10775
|
+
skipped_limit: 0,
|
|
10776
|
+
failed: 0
|
|
10777
|
+
};
|
|
10778
|
+
}
|
|
10779
|
+
var CoverageValidationErrorV1 = class extends TypeError {
|
|
10780
|
+
constructor(message, duplicateRegionIds = [], unknownRegionIds = [], missingRequiredRegionIds = [], missingOptionalRegionIds = []) {
|
|
10781
|
+
super(message);
|
|
10782
|
+
this.duplicateRegionIds = duplicateRegionIds;
|
|
10783
|
+
this.unknownRegionIds = unknownRegionIds;
|
|
10784
|
+
this.missingRequiredRegionIds = missingRequiredRegionIds;
|
|
10785
|
+
this.missingOptionalRegionIds = missingOptionalRegionIds;
|
|
10786
|
+
this.name = "CoverageValidationErrorV1";
|
|
10787
|
+
}
|
|
10788
|
+
duplicateRegionIds;
|
|
10789
|
+
unknownRegionIds;
|
|
10790
|
+
missingRequiredRegionIds;
|
|
10791
|
+
missingOptionalRegionIds;
|
|
10792
|
+
};
|
|
10793
|
+
function normalizeCoverage(coverage) {
|
|
10794
|
+
return coverage.map(
|
|
10795
|
+
(observation) => coverageRegionV1Schema.parse({
|
|
10796
|
+
...observation,
|
|
10797
|
+
diagnosticIds: [...observation.diagnosticIds].sort()
|
|
10798
|
+
})
|
|
10799
|
+
).sort((left, right) => compareCanonicalStrings(left.regionId, right.regionId));
|
|
10800
|
+
}
|
|
10801
|
+
function deriveCoverageSummaryFromNormalizedV1(plan, coverage) {
|
|
10802
|
+
const planned = new Map(plan.regions.map((region) => [region.regionId, region]));
|
|
10803
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10804
|
+
const duplicateRegionIds = /* @__PURE__ */ new Set();
|
|
10805
|
+
const unknownRegionIds = /* @__PURE__ */ new Set();
|
|
10806
|
+
for (const observation of coverage) {
|
|
10807
|
+
if (seen.has(observation.regionId)) duplicateRegionIds.add(observation.regionId);
|
|
10808
|
+
seen.add(observation.regionId);
|
|
10809
|
+
if (!planned.has(observation.regionId)) unknownRegionIds.add(observation.regionId);
|
|
10810
|
+
}
|
|
10811
|
+
const missingRequiredRegionIds = plan.regions.filter((region) => region.required && !seen.has(region.regionId)).map((region) => region.regionId);
|
|
10812
|
+
const missingOptionalRegionIds = plan.regions.filter((region) => !region.required && !seen.has(region.regionId)).map((region) => region.regionId);
|
|
10813
|
+
if (duplicateRegionIds.size > 0 || unknownRegionIds.size > 0 || missingRequiredRegionIds.length > 0 || missingOptionalRegionIds.length > 0) {
|
|
10814
|
+
throw new CoverageValidationErrorV1(
|
|
10815
|
+
"Coverage observations must join exactly once to every planned region",
|
|
10816
|
+
[...duplicateRegionIds].sort(),
|
|
10817
|
+
[...unknownRegionIds].sort(),
|
|
10818
|
+
missingRequiredRegionIds.sort(),
|
|
10819
|
+
missingOptionalRegionIds.sort()
|
|
10820
|
+
);
|
|
10821
|
+
}
|
|
10822
|
+
const requiredByState = emptyCounts();
|
|
10823
|
+
const optionalByState = emptyCounts();
|
|
10824
|
+
let eligibleFiles = 0;
|
|
10825
|
+
let analyzedFiles = 0;
|
|
10826
|
+
let analyzedBytes = 0;
|
|
10827
|
+
let observedBytes = 0;
|
|
10828
|
+
let diagnosticCount = 0;
|
|
10829
|
+
for (const observation of coverage) {
|
|
10830
|
+
const region = planned.get(observation.regionId);
|
|
10831
|
+
(region.required ? requiredByState : optionalByState)[observation.state] += 1;
|
|
10832
|
+
if (observation.state !== "excluded_by_contract") eligibleFiles += observation.fileCount;
|
|
10833
|
+
if (observation.state === "analyzed") {
|
|
10834
|
+
analyzedFiles += observation.fileCount;
|
|
10835
|
+
analyzedBytes += observation.byteCount;
|
|
10836
|
+
}
|
|
10837
|
+
observedBytes += observation.byteCount;
|
|
10838
|
+
diagnosticCount += observation.diagnosticIds.length;
|
|
10839
|
+
}
|
|
10840
|
+
if (!Number.isSafeInteger(eligibleFiles) || !Number.isSafeInteger(analyzedFiles) || !Number.isSafeInteger(analyzedBytes) || !Number.isSafeInteger(observedBytes) || !Number.isSafeInteger(diagnosticCount)) {
|
|
10841
|
+
throw new RangeError("Coverage totals exceeded the safe integer range");
|
|
10842
|
+
}
|
|
10843
|
+
if (eligibleFiles > plan.limits.maxSourceFiles) {
|
|
10844
|
+
throw new CoverageValidationErrorV1("Coverage file total exceeds the analysis-plan limit");
|
|
10845
|
+
}
|
|
10846
|
+
if (observedBytes > plan.limits.maxSourceBytes) {
|
|
10847
|
+
throw new CoverageValidationErrorV1("Coverage byte total exceeds the analysis-plan limit");
|
|
10848
|
+
}
|
|
10849
|
+
if (diagnosticCount > plan.limits.maxDiagnostics) {
|
|
10850
|
+
throw new CoverageValidationErrorV1(
|
|
10851
|
+
"Coverage diagnostic total exceeds the analysis-plan limit"
|
|
10852
|
+
);
|
|
10853
|
+
}
|
|
10854
|
+
for (const state of COVERAGE_STATES) {
|
|
10855
|
+
if (!Number.isSafeInteger(requiredByState[state]) || !Number.isSafeInteger(optionalByState[state])) {
|
|
10856
|
+
throw new RangeError("Coverage count exceeded the safe integer range");
|
|
10857
|
+
}
|
|
10858
|
+
}
|
|
10859
|
+
return coverageSummaryV1Schema.parse({
|
|
10860
|
+
plannedRegions: plan.regions.length,
|
|
10861
|
+
observedRegions: coverage.length,
|
|
10862
|
+
requiredRegions: plan.regions.filter((region) => region.required).length,
|
|
10863
|
+
requiredByState,
|
|
10864
|
+
optionalByState,
|
|
10865
|
+
eligibleFiles,
|
|
10866
|
+
analyzedFiles,
|
|
10867
|
+
analyzedBytes
|
|
10868
|
+
});
|
|
10869
|
+
}
|
|
10870
|
+
function deriveCoverageSummaryV1(rawPlan, rawCoverage) {
|
|
10871
|
+
return deriveCoverageSummaryFromNormalizedV1(
|
|
10872
|
+
parseAnalysisPlanV1(rawPlan),
|
|
10873
|
+
normalizeCoverage(rawCoverage)
|
|
10874
|
+
);
|
|
10875
|
+
}
|
|
10876
|
+
function coverageArtifactDigestV1(rawPlan, rawCoverage) {
|
|
10877
|
+
const plan = parseAnalysisPlanV1(rawPlan);
|
|
10878
|
+
const coverage = normalizeCoverage(rawCoverage);
|
|
10879
|
+
const summary = deriveCoverageSummaryFromNormalizedV1(plan, coverage);
|
|
10880
|
+
return digestHexSchema.parse(
|
|
10881
|
+
sha256Hex(
|
|
10882
|
+
canonicalPreimage({
|
|
10883
|
+
schema: "analysis-coverage.v1",
|
|
10884
|
+
analysisPlanDigest: plan.digest,
|
|
10885
|
+
coverage,
|
|
10886
|
+
summary
|
|
10887
|
+
})
|
|
10888
|
+
)
|
|
10889
|
+
);
|
|
10890
|
+
}
|
|
10891
|
+
|
|
10892
|
+
// src/feature-plan/types.ts
|
|
10893
|
+
import { z as z10 } from "zod";
|
|
10894
|
+
var FEATURE_PLAN_MAX_EVIDENCE_REFS_V1 = 200;
|
|
10895
|
+
var FEATURE_PLAN_MAX_USES_PER_KIND_V1 = 100;
|
|
10896
|
+
var FEATURE_PLAN_MAX_GAPS_V1 = 50;
|
|
10897
|
+
var FEATURE_PLAN_MAX_DECISIONS_V1 = 50;
|
|
10898
|
+
var FEATURE_PLAN_MAX_SCENARIOS_V1 = 50;
|
|
10899
|
+
var FEATURE_PLAN_MAX_ACCEPTANCE_ITEMS_V1 = 100;
|
|
10900
|
+
var FEATURE_PLAN_MAX_TEXT_BYTES_V1 = 32 * 1024;
|
|
10901
|
+
var AGENT_FEATURE_CONTEXT_MAX_BYTES_V1 = 64 * 1024;
|
|
10902
|
+
var utf8Length2 = (value) => new TextEncoder().encode(value).byteLength;
|
|
10903
|
+
var boundedString2 = (maxBytes = FEATURE_PLAN_MAX_TEXT_BYTES_V1) => z10.string().min(1).refine((value) => utf8Length2(value) <= maxBytes, `Value exceeds ${maxBytes} UTF-8 bytes`);
|
|
10904
|
+
var shortString = () => boundedString2(4096);
|
|
10905
|
+
var unique = (values) => new Set(values).size === values.length;
|
|
10906
|
+
var uniqueIdArray = (max = FEATURE_PLAN_MAX_EVIDENCE_REFS_V1) => z10.array(shortString()).max(max).refine(unique, "ID references must be unique");
|
|
10907
|
+
var evidenceRefV1Schema = z10.object({
|
|
10908
|
+
evidenceId: shortString(),
|
|
10909
|
+
kind: z10.enum(["user_intent", "image", "source", "contract", "pattern", "model"]),
|
|
10910
|
+
authority: z10.enum(["user_asserted", "source_observed", "contract_approved", "model_inferred"]),
|
|
10911
|
+
ref: boundedString2(),
|
|
10912
|
+
digest: digestHexStringSchema
|
|
10913
|
+
}).strict();
|
|
10914
|
+
var placementDecisionV1Schema = z10.object({
|
|
10915
|
+
targetKind: z10.enum(["page", "section"]),
|
|
10916
|
+
targetRef: shortString(),
|
|
10917
|
+
routeRef: shortString().optional(),
|
|
10918
|
+
parentSlotRef: shortString(),
|
|
10919
|
+
evidenceRefIds: uniqueIdArray()
|
|
10920
|
+
}).strict();
|
|
10921
|
+
var propValueSchema = z10.union([boundedString2(), z10.number().finite(), z10.boolean(), z10.null()]);
|
|
10922
|
+
var componentUseDecisionV1Schema = z10.object({
|
|
10923
|
+
useId: shortString(),
|
|
10924
|
+
componentId: shortString(),
|
|
10925
|
+
importPath: shortString(),
|
|
10926
|
+
purpose: boundedString2(),
|
|
10927
|
+
props: z10.record(shortString(), propValueSchema).refine((props) => Object.keys(props).length <= 100, "Component props exceed V1 limit"),
|
|
10928
|
+
evidenceRefIds: uniqueIdArray()
|
|
10929
|
+
}).strict();
|
|
10930
|
+
var tokenUseDecisionV1Schema = z10.object({
|
|
10931
|
+
useId: shortString(),
|
|
10932
|
+
tokenId: shortString(),
|
|
10933
|
+
role: shortString(),
|
|
10934
|
+
evidenceRefIds: uniqueIdArray()
|
|
10935
|
+
}).strict();
|
|
10936
|
+
var patternStatusV1Schema = z10.enum([
|
|
10937
|
+
"observed",
|
|
10938
|
+
"candidate",
|
|
10939
|
+
"approved_guidance",
|
|
10940
|
+
"contract_canonical",
|
|
10941
|
+
"deprecated"
|
|
10942
|
+
]);
|
|
10943
|
+
var patternUseDecisionV1Schema = z10.object({
|
|
10944
|
+
useId: shortString(),
|
|
10945
|
+
patternId: shortString(),
|
|
10946
|
+
patternRevisionDigest: digestHexStringSchema,
|
|
10947
|
+
status: patternStatusV1Schema,
|
|
10948
|
+
disposition: z10.enum(["reuse", "reference", "reject"]),
|
|
10949
|
+
evidenceRefIds: uniqueIdArray()
|
|
10950
|
+
}).strict().superRefine((pattern, context) => {
|
|
10951
|
+
if (pattern.disposition === "reuse" && pattern.status !== "approved_guidance" && pattern.status !== "contract_canonical") {
|
|
10952
|
+
context.addIssue({
|
|
10953
|
+
code: z10.ZodIssueCode.custom,
|
|
10954
|
+
path: ["disposition"],
|
|
10955
|
+
message: "Only approved-guidance or contract-canonical patterns may be reused"
|
|
10956
|
+
});
|
|
10957
|
+
}
|
|
10958
|
+
});
|
|
10959
|
+
var layoutConcernV1Schema = z10.enum([
|
|
10960
|
+
"outer_inline_spacing",
|
|
10961
|
+
"outer_block_spacing",
|
|
10962
|
+
"inner_padding",
|
|
10963
|
+
"child_gap",
|
|
10964
|
+
"max_inline_size",
|
|
10965
|
+
"scroll_x",
|
|
10966
|
+
"scroll_y",
|
|
10967
|
+
"sticky_offset",
|
|
10968
|
+
"breakpoint_switching"
|
|
10969
|
+
]);
|
|
10970
|
+
var layoutConcernOwnerV1Schema = z10.object({
|
|
10971
|
+
concern: layoutConcernV1Schema,
|
|
10972
|
+
ownerLayer: z10.enum([
|
|
10973
|
+
"application_shell",
|
|
10974
|
+
"route_shell",
|
|
10975
|
+
"page",
|
|
10976
|
+
"section",
|
|
10977
|
+
"pattern",
|
|
10978
|
+
"primitive"
|
|
10979
|
+
]),
|
|
10980
|
+
ownerRef: shortString(),
|
|
10981
|
+
childAction: z10.enum(["consume", "own", "override"]),
|
|
10982
|
+
tokenRef: shortString().optional(),
|
|
10983
|
+
breakpointRef: shortString().optional(),
|
|
10984
|
+
evidenceRefIds: uniqueIdArray(),
|
|
10985
|
+
overrideDecisionId: shortString().optional()
|
|
10986
|
+
}).strict().superRefine((row, context) => {
|
|
10987
|
+
if (row.childAction === "override" && !row.overrideDecisionId) {
|
|
10988
|
+
context.addIssue({
|
|
10989
|
+
code: z10.ZodIssueCode.custom,
|
|
10990
|
+
path: ["overrideDecisionId"],
|
|
10991
|
+
message: "A layout override must reference an approved decision"
|
|
10992
|
+
});
|
|
10993
|
+
}
|
|
10994
|
+
if (row.childAction !== "override" && row.overrideDecisionId) {
|
|
10995
|
+
context.addIssue({
|
|
10996
|
+
code: z10.ZodIssueCode.custom,
|
|
10997
|
+
path: ["overrideDecisionId"],
|
|
10998
|
+
message: "Only an override may reference an override decision"
|
|
10999
|
+
});
|
|
11000
|
+
}
|
|
11001
|
+
});
|
|
11002
|
+
var layoutOwnershipV1Schema = z10.object({
|
|
11003
|
+
concerns: z10.array(layoutConcernOwnerV1Schema).max(32).refine(
|
|
11004
|
+
(rows) => new Set(rows.map((row) => row.concern)).size === rows.length,
|
|
11005
|
+
"Each layout concern must have exactly one owner"
|
|
11006
|
+
)
|
|
11007
|
+
}).strict();
|
|
11008
|
+
var responsiveDecisionV1Schema = z10.object({
|
|
11009
|
+
decisionId: shortString(),
|
|
11010
|
+
source: z10.enum(["contract", "observed", "desktop_only"]),
|
|
11011
|
+
breakpointRef: shortString().optional(),
|
|
11012
|
+
behavior: boundedString2(),
|
|
11013
|
+
evidenceRefIds: uniqueIdArray()
|
|
11014
|
+
}).strict().superRefine((decision, context) => {
|
|
11015
|
+
if (decision.source !== "desktop_only" && !decision.breakpointRef) {
|
|
11016
|
+
context.addIssue({
|
|
11017
|
+
code: z10.ZodIssueCode.custom,
|
|
11018
|
+
path: ["breakpointRef"],
|
|
11019
|
+
message: "Responsive contract/observed decisions must pin a breakpoint"
|
|
11020
|
+
});
|
|
11021
|
+
}
|
|
11022
|
+
});
|
|
11023
|
+
var scenarioRequirementV1Schema = z10.object({
|
|
11024
|
+
scenarioId: shortString(),
|
|
11025
|
+
viewportRef: shortString().optional(),
|
|
11026
|
+
themeRef: shortString().optional(),
|
|
11027
|
+
actorRole: shortString().optional(),
|
|
11028
|
+
dataState: z10.enum(["default", "loading", "empty", "partial", "error"]),
|
|
11029
|
+
interactionState: z10.enum(["pristine", "dirty", "validating", "saving", "saved", "disabled"]).optional(),
|
|
11030
|
+
acceptanceIds: uniqueIdArray(FEATURE_PLAN_MAX_ACCEPTANCE_ITEMS_V1)
|
|
11031
|
+
}).strict();
|
|
11032
|
+
var gapDispositionV1Schema = z10.enum([
|
|
11033
|
+
"canonical_reuse",
|
|
11034
|
+
"approved_pattern",
|
|
11035
|
+
"local_composition",
|
|
11036
|
+
"intentional_one_off",
|
|
11037
|
+
"proposed_contract_addition",
|
|
11038
|
+
"unresolved"
|
|
11039
|
+
]);
|
|
11040
|
+
var capabilityGapV1Schema = z10.object({
|
|
11041
|
+
gapId: shortString(),
|
|
11042
|
+
capability: boundedString2(),
|
|
11043
|
+
required: z10.boolean(),
|
|
11044
|
+
disposition: gapDispositionV1Schema,
|
|
11045
|
+
reason: boundedString2(),
|
|
11046
|
+
evidenceRefIds: uniqueIdArray(),
|
|
11047
|
+
proposedContractCandidateId: shortString().optional()
|
|
11048
|
+
}).strict().superRefine((gap, context) => {
|
|
11049
|
+
if (gap.disposition === "proposed_contract_addition" && !gap.proposedContractCandidateId) {
|
|
11050
|
+
context.addIssue({
|
|
11051
|
+
code: z10.ZodIssueCode.custom,
|
|
11052
|
+
path: ["proposedContractCandidateId"],
|
|
11053
|
+
message: "A proposed contract addition must pin its candidate"
|
|
11054
|
+
});
|
|
11055
|
+
}
|
|
11056
|
+
if (gap.disposition !== "proposed_contract_addition" && gap.proposedContractCandidateId) {
|
|
11057
|
+
context.addIssue({
|
|
11058
|
+
code: z10.ZodIssueCode.custom,
|
|
11059
|
+
path: ["proposedContractCandidateId"],
|
|
11060
|
+
message: "Only a proposed contract addition may carry a candidate ID"
|
|
11061
|
+
});
|
|
11062
|
+
}
|
|
11063
|
+
});
|
|
11064
|
+
var featureAcceptanceItemV1Schema = z10.object({
|
|
11065
|
+
acceptanceId: shortString(),
|
|
11066
|
+
statement: boundedString2(),
|
|
11067
|
+
proof: z10.enum(["unit", "integration", "browser", "governance", "manual"]),
|
|
11068
|
+
required: z10.boolean(),
|
|
11069
|
+
evidenceRefIds: uniqueIdArray()
|
|
11070
|
+
}).strict();
|
|
11071
|
+
var decisionOptionV1Schema = z10.object({ optionId: shortString(), label: boundedString2(), consequence: boundedString2() }).strict();
|
|
11072
|
+
var decisionRequestV1Schema = z10.object({
|
|
11073
|
+
decisionId: shortString(),
|
|
11074
|
+
kind: z10.enum(["placement", "reuse", "gap", "layout_override", "responsive", "scope"]),
|
|
11075
|
+
question: boundedString2(),
|
|
11076
|
+
options: z10.array(decisionOptionV1Schema).min(2).max(20).refine(
|
|
11077
|
+
(options) => new Set(options.map((option) => option.optionId)).size === options.length,
|
|
11078
|
+
"Decision option IDs must be unique"
|
|
11079
|
+
),
|
|
11080
|
+
recommendedOptionId: shortString().optional(),
|
|
11081
|
+
required: z10.boolean(),
|
|
11082
|
+
evidenceRefIds: uniqueIdArray()
|
|
11083
|
+
}).strict().superRefine((decision, context) => {
|
|
11084
|
+
if (decision.recommendedOptionId && !decision.options.some((option) => option.optionId === decision.recommendedOptionId)) {
|
|
11085
|
+
context.addIssue({
|
|
11086
|
+
code: z10.ZodIssueCode.custom,
|
|
11087
|
+
path: ["recommendedOptionId"],
|
|
11088
|
+
message: "Recommended option must resolve inside the decision"
|
|
11089
|
+
});
|
|
11090
|
+
}
|
|
11091
|
+
});
|
|
11092
|
+
var decisionResolutionV1Schema = z10.object({ decisionId: shortString(), selectedOptionId: shortString() }).strict();
|
|
11093
|
+
var featurePinsV1Schema = z10.object({
|
|
11094
|
+
bindingId: shortString(),
|
|
11095
|
+
grounding: z10.object({
|
|
11096
|
+
sourceCommitId: shortString(),
|
|
11097
|
+
analysisPlanDigest: digestHexStringSchema,
|
|
11098
|
+
contextSliceDigest: digestHexStringSchema
|
|
11099
|
+
}).strict(),
|
|
11100
|
+
authority: z10.object({
|
|
11101
|
+
fcid: digestHexStringSchema,
|
|
11102
|
+
contractArtifactDigest: digestHexStringSchema,
|
|
11103
|
+
analysisObligationsDigest: digestHexStringSchema
|
|
11104
|
+
}).strict(),
|
|
11105
|
+
evidenceDigest: digestHexStringSchema
|
|
11106
|
+
}).strict();
|
|
11107
|
+
var commonRevisionShape = {
|
|
11108
|
+
pins: featurePinsV1Schema,
|
|
11109
|
+
placement: placementDecisionV1Schema,
|
|
11110
|
+
componentUses: z10.array(componentUseDecisionV1Schema).max(FEATURE_PLAN_MAX_USES_PER_KIND_V1),
|
|
11111
|
+
tokenUses: z10.array(tokenUseDecisionV1Schema).max(FEATURE_PLAN_MAX_USES_PER_KIND_V1),
|
|
11112
|
+
patternUses: z10.array(patternUseDecisionV1Schema).max(FEATURE_PLAN_MAX_USES_PER_KIND_V1),
|
|
11113
|
+
layout: layoutOwnershipV1Schema,
|
|
11114
|
+
responsive: z10.array(responsiveDecisionV1Schema).max(FEATURE_PLAN_MAX_DECISIONS_V1),
|
|
11115
|
+
scenarios: z10.array(scenarioRequirementV1Schema).max(FEATURE_PLAN_MAX_SCENARIOS_V1),
|
|
11116
|
+
gaps: z10.array(capabilityGapV1Schema).max(FEATURE_PLAN_MAX_GAPS_V1),
|
|
11117
|
+
acceptance: z10.array(featureAcceptanceItemV1Schema).max(FEATURE_PLAN_MAX_ACCEPTANCE_ITEMS_V1),
|
|
11118
|
+
evidenceRefs: z10.array(evidenceRefV1Schema).max(FEATURE_PLAN_MAX_EVIDENCE_REFS_V1)
|
|
11119
|
+
};
|
|
11120
|
+
function addUniqueIdIssue(rows, key, path, context) {
|
|
11121
|
+
const values = rows.map((row) => row[key]).filter((value) => typeof value === "string");
|
|
11122
|
+
if (new Set(values).size !== values.length) {
|
|
11123
|
+
context.addIssue({
|
|
11124
|
+
code: z10.ZodIssueCode.custom,
|
|
11125
|
+
path: [path],
|
|
11126
|
+
message: `${path} IDs must be unique`
|
|
11127
|
+
});
|
|
11128
|
+
}
|
|
11129
|
+
}
|
|
11130
|
+
function validateCommonGraph(graph, context, decisionIds) {
|
|
11131
|
+
addUniqueIdIssue(graph.evidenceRefs, "evidenceId", "evidenceRefs", context);
|
|
11132
|
+
addUniqueIdIssue(graph.componentUses, "useId", "componentUses", context);
|
|
11133
|
+
addUniqueIdIssue(graph.tokenUses, "useId", "tokenUses", context);
|
|
11134
|
+
addUniqueIdIssue(graph.patternUses, "useId", "patternUses", context);
|
|
11135
|
+
addUniqueIdIssue(graph.responsive, "decisionId", "responsive", context);
|
|
11136
|
+
addUniqueIdIssue(graph.scenarios, "scenarioId", "scenarios", context);
|
|
11137
|
+
addUniqueIdIssue(graph.gaps, "gapId", "gaps", context);
|
|
11138
|
+
addUniqueIdIssue(graph.acceptance, "acceptanceId", "acceptance", context);
|
|
11139
|
+
const evidenceIds = new Set(graph.evidenceRefs.map((evidence) => evidence.evidenceId));
|
|
11140
|
+
const acceptanceIds = new Set(graph.acceptance.map((acceptance) => acceptance.acceptanceId));
|
|
11141
|
+
const evidenceReferences = [
|
|
11142
|
+
[graph.placement.evidenceRefIds, "placement.evidenceRefIds"],
|
|
11143
|
+
...graph.componentUses.map(
|
|
11144
|
+
(row, index) => [row.evidenceRefIds, `componentUses.${index}.evidenceRefIds`]
|
|
11145
|
+
),
|
|
11146
|
+
...graph.tokenUses.map(
|
|
11147
|
+
(row, index) => [row.evidenceRefIds, `tokenUses.${index}.evidenceRefIds`]
|
|
11148
|
+
),
|
|
11149
|
+
...graph.patternUses.map(
|
|
11150
|
+
(row, index) => [row.evidenceRefIds, `patternUses.${index}.evidenceRefIds`]
|
|
11151
|
+
),
|
|
11152
|
+
...graph.layout.concerns.map(
|
|
11153
|
+
(row, index) => [row.evidenceRefIds, `layout.concerns.${index}.evidenceRefIds`]
|
|
11154
|
+
),
|
|
11155
|
+
...graph.responsive.map(
|
|
11156
|
+
(row, index) => [row.evidenceRefIds, `responsive.${index}.evidenceRefIds`]
|
|
11157
|
+
),
|
|
11158
|
+
...graph.gaps.map(
|
|
11159
|
+
(row, index) => [row.evidenceRefIds, `gaps.${index}.evidenceRefIds`]
|
|
11160
|
+
),
|
|
11161
|
+
...graph.acceptance.map(
|
|
11162
|
+
(row, index) => [row.evidenceRefIds, `acceptance.${index}.evidenceRefIds`]
|
|
11163
|
+
)
|
|
11164
|
+
];
|
|
11165
|
+
for (const [references, path] of evidenceReferences) {
|
|
11166
|
+
for (const reference of references) {
|
|
11167
|
+
if (!evidenceIds.has(reference)) {
|
|
11168
|
+
context.addIssue({
|
|
11169
|
+
code: z10.ZodIssueCode.custom,
|
|
11170
|
+
path: path.split("."),
|
|
11171
|
+
message: `Unknown evidence reference: ${reference}`
|
|
11172
|
+
});
|
|
11173
|
+
}
|
|
11174
|
+
}
|
|
11175
|
+
}
|
|
11176
|
+
for (const [index, scenario] of graph.scenarios.entries()) {
|
|
11177
|
+
for (const acceptanceId of scenario.acceptanceIds) {
|
|
11178
|
+
if (!acceptanceIds.has(acceptanceId)) {
|
|
11179
|
+
context.addIssue({
|
|
11180
|
+
code: z10.ZodIssueCode.custom,
|
|
11181
|
+
path: ["scenarios", index, "acceptanceIds"],
|
|
11182
|
+
message: `Unknown acceptance reference: ${acceptanceId}`
|
|
11183
|
+
});
|
|
11184
|
+
}
|
|
11185
|
+
}
|
|
11186
|
+
}
|
|
11187
|
+
for (const [index, row] of graph.layout.concerns.entries()) {
|
|
11188
|
+
if (row.overrideDecisionId && !decisionIds.has(row.overrideDecisionId)) {
|
|
11189
|
+
context.addIssue({
|
|
11190
|
+
code: z10.ZodIssueCode.custom,
|
|
11191
|
+
path: ["layout", "concerns", index, "overrideDecisionId"],
|
|
11192
|
+
message: `Unknown decision reference: ${row.overrideDecisionId}`
|
|
11193
|
+
});
|
|
11194
|
+
}
|
|
11195
|
+
}
|
|
11196
|
+
}
|
|
11197
|
+
var proposalInputShape = {
|
|
11198
|
+
schemaVersion: z10.literal(1),
|
|
11199
|
+
kind: z10.literal("proposal"),
|
|
11200
|
+
planId: featurePlanIdStringSchema,
|
|
11201
|
+
parentRevisionDigest: digestHexStringSchema.optional(),
|
|
11202
|
+
...commonRevisionShape,
|
|
11203
|
+
questions: z10.array(decisionRequestV1Schema).max(FEATURE_PLAN_MAX_DECISIONS_V1)
|
|
11204
|
+
};
|
|
11205
|
+
function validateProposal(proposal, context) {
|
|
11206
|
+
addUniqueIdIssue(proposal.questions, "decisionId", "questions", context);
|
|
11207
|
+
const decisionIds = new Set(proposal.questions.map((question) => question.decisionId));
|
|
11208
|
+
validateCommonGraph(proposal, context, decisionIds);
|
|
11209
|
+
const evidenceIds = new Set(proposal.evidenceRefs.map((evidence) => evidence.evidenceId));
|
|
11210
|
+
for (const [index, question] of proposal.questions.entries()) {
|
|
11211
|
+
for (const reference of question.evidenceRefIds) {
|
|
11212
|
+
if (!evidenceIds.has(reference)) {
|
|
11213
|
+
context.addIssue({
|
|
11214
|
+
code: z10.ZodIssueCode.custom,
|
|
11215
|
+
path: ["questions", index, "evidenceRefIds"],
|
|
11216
|
+
message: `Unknown evidence reference: ${reference}`
|
|
11217
|
+
});
|
|
11218
|
+
}
|
|
11219
|
+
}
|
|
11220
|
+
}
|
|
11221
|
+
}
|
|
11222
|
+
var featureProposalInputV1Schema = z10.object(proposalInputShape).strict().superRefine(validateProposal);
|
|
11223
|
+
var featureProposalV1Schema = z10.object({
|
|
11224
|
+
...proposalInputShape,
|
|
11225
|
+
revisionId: featureRevisionIdStringSchema,
|
|
11226
|
+
revisionDigest: digestHexStringSchema
|
|
11227
|
+
}).strict().superRefine(validateProposal);
|
|
11228
|
+
var manifestInputShape = {
|
|
11229
|
+
schemaVersion: z10.literal(1),
|
|
11230
|
+
kind: z10.literal("approved_manifest"),
|
|
11231
|
+
planId: featurePlanIdStringSchema,
|
|
11232
|
+
parentRevisionDigest: digestHexStringSchema,
|
|
11233
|
+
proposalRevisionDigest: digestHexStringSchema,
|
|
11234
|
+
...commonRevisionShape,
|
|
11235
|
+
validatedGrounding: z10.object({
|
|
11236
|
+
sourceCommitId: shortString(),
|
|
11237
|
+
analysisPlanDigest: digestHexStringSchema,
|
|
11238
|
+
contextSliceDigest: digestHexStringSchema
|
|
11239
|
+
}).strict(),
|
|
11240
|
+
decisions: z10.array(decisionResolutionV1Schema).max(FEATURE_PLAN_MAX_DECISIONS_V1),
|
|
11241
|
+
approval: z10.object({
|
|
11242
|
+
approverUserId: shortString(),
|
|
11243
|
+
decisionDigest: digestHexStringSchema,
|
|
11244
|
+
approvedAt: z10.string().datetime({ offset: true }),
|
|
11245
|
+
expiresAt: z10.string().datetime({ offset: true }).optional()
|
|
11246
|
+
}).strict()
|
|
11247
|
+
};
|
|
11248
|
+
var portableRepositoryPathSchema = shortString().refine(
|
|
11249
|
+
(value) => !value.startsWith("/") && !value.includes("\\") && !value.split("/").includes(".."),
|
|
11250
|
+
"Expected a portable repository-relative path"
|
|
11251
|
+
);
|
|
11252
|
+
function validateManifest(manifest, context) {
|
|
11253
|
+
addUniqueIdIssue(manifest.decisions, "decisionId", "decisions", context);
|
|
11254
|
+
validateCommonGraph(manifest, context, new Set(manifest.decisions.map((row) => row.decisionId)));
|
|
11255
|
+
if (manifest.validatedGrounding.contextSliceDigest !== manifest.pins.grounding.contextSliceDigest) {
|
|
11256
|
+
context.addIssue({
|
|
11257
|
+
code: z10.ZodIssueCode.custom,
|
|
11258
|
+
path: ["validatedGrounding", "contextSliceDigest"],
|
|
11259
|
+
message: "Validated material context must match the pinned proposal context"
|
|
11260
|
+
});
|
|
11261
|
+
}
|
|
11262
|
+
for (const [index, gap] of manifest.gaps.entries()) {
|
|
11263
|
+
if (gap.required && (gap.disposition === "unresolved" || gap.disposition === "proposed_contract_addition")) {
|
|
11264
|
+
context.addIssue({
|
|
11265
|
+
code: z10.ZodIssueCode.custom,
|
|
11266
|
+
path: ["gaps", index, "disposition"],
|
|
11267
|
+
message: "A required unresolved or proposed-contract gap blocks approval until it is resolved"
|
|
11268
|
+
});
|
|
11269
|
+
}
|
|
11270
|
+
}
|
|
11271
|
+
}
|
|
11272
|
+
var approvedFeatureManifestInputV1Schema = z10.object(manifestInputShape).strict().superRefine(validateManifest);
|
|
11273
|
+
var approvedFeatureManifestV1Schema = z10.object({
|
|
11274
|
+
...manifestInputShape,
|
|
11275
|
+
revisionId: featureRevisionIdStringSchema,
|
|
11276
|
+
revisionDigest: digestHexStringSchema
|
|
11277
|
+
}).strict().superRefine(validateManifest);
|
|
11278
|
+
var agentFeatureContextV1Schema = z10.object({
|
|
11279
|
+
schemaVersion: z10.literal(1),
|
|
11280
|
+
planId: featurePlanIdStringSchema,
|
|
11281
|
+
manifestDigest: digestHexStringSchema,
|
|
11282
|
+
pins: featurePinsV1Schema,
|
|
11283
|
+
validatedGrounding: manifestInputShape.validatedGrounding,
|
|
11284
|
+
target: placementDecisionV1Schema,
|
|
11285
|
+
componentUses: commonRevisionShape.componentUses,
|
|
11286
|
+
tokenUses: commonRevisionShape.tokenUses,
|
|
11287
|
+
patternUses: commonRevisionShape.patternUses,
|
|
11288
|
+
layout: layoutOwnershipV1Schema,
|
|
11289
|
+
responsive: commonRevisionShape.responsive,
|
|
11290
|
+
scenarios: commonRevisionShape.scenarios,
|
|
11291
|
+
acceptedGaps: commonRevisionShape.gaps,
|
|
11292
|
+
acceptance: commonRevisionShape.acceptance,
|
|
11293
|
+
decisions: manifestInputShape.decisions,
|
|
11294
|
+
relevantFiles: z10.array(portableRepositoryPathSchema).max(500).refine(unique, "relevantFiles must be unique"),
|
|
11295
|
+
commands: z10.array(boundedString2()).max(100)
|
|
11296
|
+
}).strict().superRefine((contextValue, context) => {
|
|
11297
|
+
const graph = {
|
|
11298
|
+
pins: contextValue.pins,
|
|
11299
|
+
placement: contextValue.target,
|
|
11300
|
+
componentUses: contextValue.componentUses,
|
|
11301
|
+
tokenUses: contextValue.tokenUses,
|
|
11302
|
+
patternUses: contextValue.patternUses,
|
|
11303
|
+
layout: contextValue.layout,
|
|
11304
|
+
responsive: contextValue.responsive,
|
|
11305
|
+
scenarios: contextValue.scenarios,
|
|
11306
|
+
gaps: contextValue.acceptedGaps,
|
|
11307
|
+
acceptance: contextValue.acceptance,
|
|
11308
|
+
evidenceRefs: []
|
|
11309
|
+
};
|
|
11310
|
+
addUniqueIdIssue(contextValue.decisions, "decisionId", "decisions", context);
|
|
11311
|
+
addUniqueIdIssue(graph.componentUses, "useId", "componentUses", context);
|
|
11312
|
+
addUniqueIdIssue(graph.tokenUses, "useId", "tokenUses", context);
|
|
11313
|
+
addUniqueIdIssue(graph.patternUses, "useId", "patternUses", context);
|
|
11314
|
+
addUniqueIdIssue(graph.scenarios, "scenarioId", "scenarios", context);
|
|
11315
|
+
addUniqueIdIssue(graph.acceptance, "acceptanceId", "acceptance", context);
|
|
11316
|
+
const decisions = new Set(contextValue.decisions.map((row) => row.decisionId));
|
|
11317
|
+
for (const [index, row] of contextValue.layout.concerns.entries()) {
|
|
11318
|
+
if (row.overrideDecisionId && !decisions.has(row.overrideDecisionId)) {
|
|
11319
|
+
context.addIssue({
|
|
11320
|
+
code: z10.ZodIssueCode.custom,
|
|
11321
|
+
path: ["layout", "concerns", index, "overrideDecisionId"],
|
|
11322
|
+
message: `Unknown decision reference: ${row.overrideDecisionId}`
|
|
11323
|
+
});
|
|
11324
|
+
}
|
|
11325
|
+
}
|
|
11326
|
+
for (const [index, gap] of contextValue.acceptedGaps.entries()) {
|
|
11327
|
+
if (gap.required && (gap.disposition === "unresolved" || gap.disposition === "proposed_contract_addition")) {
|
|
11328
|
+
context.addIssue({
|
|
11329
|
+
code: z10.ZodIssueCode.custom,
|
|
11330
|
+
path: ["acceptedGaps", index],
|
|
11331
|
+
message: "Agent context cannot contain a required unresolved or proposed-contract gap"
|
|
11332
|
+
});
|
|
11333
|
+
}
|
|
11334
|
+
}
|
|
11335
|
+
});
|
|
11336
|
+
|
|
11337
|
+
// src/feature-plan/digest.ts
|
|
11338
|
+
var sortedUnique2 = (values) => [...new Set(values)].sort();
|
|
11339
|
+
function normalizeEvidenceRefs(row) {
|
|
11340
|
+
return { ...row, evidenceRefIds: sortedUnique2(row.evidenceRefIds) };
|
|
11341
|
+
}
|
|
11342
|
+
function normalizeCommon(value) {
|
|
11343
|
+
return {
|
|
11344
|
+
...value,
|
|
11345
|
+
placement: normalizeEvidenceRefs(value.placement),
|
|
11346
|
+
componentUses: value.componentUses.map(normalizeEvidenceRefs).sort((left, right) => compareCanonicalStrings(left.useId, right.useId)),
|
|
11347
|
+
tokenUses: value.tokenUses.map(normalizeEvidenceRefs).sort((left, right) => compareCanonicalStrings(left.useId, right.useId)),
|
|
11348
|
+
patternUses: value.patternUses.map(normalizeEvidenceRefs).sort((left, right) => compareCanonicalStrings(left.useId, right.useId)),
|
|
11349
|
+
layout: {
|
|
11350
|
+
concerns: value.layout.concerns.map(normalizeEvidenceRefs).sort((left, right) => compareCanonicalStrings(left.concern, right.concern))
|
|
11351
|
+
},
|
|
11352
|
+
responsive: value.responsive.map(normalizeEvidenceRefs).sort((left, right) => compareCanonicalStrings(left.decisionId, right.decisionId)),
|
|
11353
|
+
scenarios: value.scenarios.map((scenario) => ({ ...scenario, acceptanceIds: sortedUnique2(scenario.acceptanceIds) })).sort((left, right) => compareCanonicalStrings(left.scenarioId, right.scenarioId)),
|
|
11354
|
+
gaps: value.gaps.map(normalizeEvidenceRefs).sort((left, right) => compareCanonicalStrings(left.gapId, right.gapId)),
|
|
11355
|
+
acceptance: value.acceptance.map(normalizeEvidenceRefs).sort((left, right) => compareCanonicalStrings(left.acceptanceId, right.acceptanceId)),
|
|
11356
|
+
evidenceRefs: [...value.evidenceRefs].sort(
|
|
11357
|
+
(left, right) => compareCanonicalStrings(left.evidenceId, right.evidenceId)
|
|
11358
|
+
)
|
|
11359
|
+
};
|
|
11360
|
+
}
|
|
11361
|
+
function normalizeFeatureProposalInputV1(value) {
|
|
11362
|
+
const parsed = featureProposalInputV1Schema.parse(value);
|
|
11363
|
+
return normalizeCommon({
|
|
11364
|
+
...parsed,
|
|
11365
|
+
questions: parsed.questions.map((question) => ({ ...normalizeEvidenceRefs(question), options: [...question.options] })).sort((left, right) => compareCanonicalStrings(left.decisionId, right.decisionId))
|
|
11366
|
+
});
|
|
11367
|
+
}
|
|
11368
|
+
function proposalProjection(proposal) {
|
|
11369
|
+
return {
|
|
11370
|
+
schema: "feature-revision.v1",
|
|
11371
|
+
kind: proposal.kind,
|
|
11372
|
+
planId: proposal.planId,
|
|
11373
|
+
parentRevisionDigest: proposal.parentRevisionDigest,
|
|
11374
|
+
pins: proposal.pins,
|
|
11375
|
+
placement: proposal.placement,
|
|
11376
|
+
componentUses: proposal.componentUses,
|
|
11377
|
+
tokenUses: proposal.tokenUses,
|
|
11378
|
+
patternUses: proposal.patternUses,
|
|
11379
|
+
layout: proposal.layout,
|
|
11380
|
+
responsive: proposal.responsive,
|
|
11381
|
+
scenarios: proposal.scenarios,
|
|
11382
|
+
gaps: proposal.gaps,
|
|
11383
|
+
acceptance: proposal.acceptance,
|
|
11384
|
+
questions: proposal.questions,
|
|
11385
|
+
evidenceRefs: proposal.evidenceRefs
|
|
11386
|
+
};
|
|
11387
|
+
}
|
|
11388
|
+
function featureProposalRevisionDigestV1(value) {
|
|
11389
|
+
const proposal = normalizeFeatureProposalInputV1(value);
|
|
11390
|
+
return sha256Hex(canonicalPreimage(proposalProjection(proposal)));
|
|
11391
|
+
}
|
|
11392
|
+
function buildFeatureProposalV1(value) {
|
|
11393
|
+
const proposal = normalizeFeatureProposalInputV1(value);
|
|
11394
|
+
const revisionDigest = sha256Hex(canonicalPreimage(proposalProjection(proposal)));
|
|
11395
|
+
return featureProposalV1Schema.parse({
|
|
11396
|
+
...proposal,
|
|
11397
|
+
revisionId: featureRevisionIdFromDigest(revisionDigest),
|
|
11398
|
+
revisionDigest
|
|
11399
|
+
});
|
|
11400
|
+
}
|
|
11401
|
+
function parseFeatureProposalV1(value) {
|
|
11402
|
+
const parsed = featureProposalV1Schema.parse(value);
|
|
11403
|
+
const { revisionId, revisionDigest, ...input } = parsed;
|
|
11404
|
+
const rebuilt = buildFeatureProposalV1(input);
|
|
11405
|
+
if (revisionId !== rebuilt.revisionId || revisionDigest !== rebuilt.revisionDigest) {
|
|
11406
|
+
throw new TypeError("Feature proposal derived identity does not match its semantic projection");
|
|
11407
|
+
}
|
|
11408
|
+
return rebuilt;
|
|
11409
|
+
}
|
|
11410
|
+
function normalizeApprovedFeatureManifestInputV1(value) {
|
|
11411
|
+
const parsed = approvedFeatureManifestInputV1Schema.parse(value);
|
|
11412
|
+
return normalizeCommon({
|
|
11413
|
+
...parsed,
|
|
11414
|
+
decisions: [...parsed.decisions].sort(
|
|
11415
|
+
(left, right) => compareCanonicalStrings(left.decisionId, right.decisionId)
|
|
11416
|
+
),
|
|
11417
|
+
approval: { ...parsed.approval },
|
|
11418
|
+
validatedGrounding: { ...parsed.validatedGrounding }
|
|
11419
|
+
});
|
|
11420
|
+
}
|
|
11421
|
+
function manifestProjection(manifest) {
|
|
11422
|
+
return {
|
|
11423
|
+
schema: "feature-revision.v1",
|
|
11424
|
+
kind: manifest.kind,
|
|
11425
|
+
planId: manifest.planId,
|
|
11426
|
+
parentRevisionDigest: manifest.parentRevisionDigest,
|
|
11427
|
+
proposalRevisionDigest: manifest.proposalRevisionDigest,
|
|
11428
|
+
pins: manifest.pins,
|
|
11429
|
+
validatedGrounding: manifest.validatedGrounding,
|
|
11430
|
+
placement: manifest.placement,
|
|
11431
|
+
componentUses: manifest.componentUses,
|
|
11432
|
+
tokenUses: manifest.tokenUses,
|
|
11433
|
+
patternUses: manifest.patternUses,
|
|
11434
|
+
layout: manifest.layout,
|
|
11435
|
+
responsive: manifest.responsive,
|
|
11436
|
+
scenarios: manifest.scenarios,
|
|
11437
|
+
gaps: manifest.gaps,
|
|
11438
|
+
acceptance: manifest.acceptance,
|
|
11439
|
+
evidenceRefs: manifest.evidenceRefs,
|
|
11440
|
+
decisions: manifest.decisions,
|
|
11441
|
+
approval: {
|
|
11442
|
+
approverUserId: manifest.approval.approverUserId,
|
|
11443
|
+
decisionDigest: manifest.approval.decisionDigest,
|
|
11444
|
+
expiresAt: manifest.approval.expiresAt
|
|
11445
|
+
}
|
|
11446
|
+
};
|
|
11447
|
+
}
|
|
11448
|
+
function approvedFeatureManifestRevisionDigestV1(value) {
|
|
11449
|
+
const manifest = normalizeApprovedFeatureManifestInputV1(value);
|
|
11450
|
+
return sha256Hex(canonicalPreimage(manifestProjection(manifest)));
|
|
11451
|
+
}
|
|
11452
|
+
function buildApprovedFeatureManifestV1(value) {
|
|
11453
|
+
const manifest = normalizeApprovedFeatureManifestInputV1(value);
|
|
11454
|
+
const revisionDigest = sha256Hex(canonicalPreimage(manifestProjection(manifest)));
|
|
11455
|
+
return approvedFeatureManifestV1Schema.parse({
|
|
11456
|
+
...manifest,
|
|
11457
|
+
revisionId: featureRevisionIdFromDigest(revisionDigest),
|
|
11458
|
+
revisionDigest
|
|
11459
|
+
});
|
|
11460
|
+
}
|
|
11461
|
+
function parseApprovedFeatureManifestV1(value) {
|
|
11462
|
+
const parsed = approvedFeatureManifestV1Schema.parse(value);
|
|
11463
|
+
const { revisionId, revisionDigest, ...input } = parsed;
|
|
11464
|
+
const rebuilt = buildApprovedFeatureManifestV1(input);
|
|
11465
|
+
if (revisionId !== rebuilt.revisionId || revisionDigest !== rebuilt.revisionDigest) {
|
|
11466
|
+
throw new TypeError(
|
|
11467
|
+
"Approved manifest derived identity does not match its semantic projection"
|
|
11468
|
+
);
|
|
11469
|
+
}
|
|
11470
|
+
return rebuilt;
|
|
11471
|
+
}
|
|
11472
|
+
var agentFeatureContextV1Schema2 = agentFeatureContextV1Schema.superRefine(
|
|
11473
|
+
(value, context) => {
|
|
11474
|
+
const bytes = new TextEncoder().encode(canonicalPreimage(value)).byteLength;
|
|
11475
|
+
if (bytes > AGENT_FEATURE_CONTEXT_MAX_BYTES_V1) {
|
|
11476
|
+
context.addIssue({
|
|
11477
|
+
code: "custom",
|
|
11478
|
+
message: `Agent feature context exceeds ${AGENT_FEATURE_CONTEXT_MAX_BYTES_V1} UTF-8 bytes`
|
|
11479
|
+
});
|
|
11480
|
+
}
|
|
11481
|
+
}
|
|
11482
|
+
);
|
|
11483
|
+
function parseAgentFeatureContextV1(value) {
|
|
11484
|
+
return agentFeatureContextV1Schema2.parse(value);
|
|
11485
|
+
}
|
|
11486
|
+
|
|
11487
|
+
// src/evaluation/types.ts
|
|
11488
|
+
var EVALUATOR_VERSION = "evaluation-kernel:v1";
|
|
11489
|
+
var EVALUATOR_VERSION_V2 = "evaluation-kernel:v2";
|
|
11490
|
+
|
|
11491
|
+
// src/evaluation/receipt.ts
|
|
11492
|
+
import { z as z11 } from "zod";
|
|
11493
|
+
var EVALUATION_MAX_WAIVERS_V2 = 1e3;
|
|
11494
|
+
var EVALUATION_MAX_WAIVER_MATCHES_V2 = 1e4;
|
|
11495
|
+
var EVALUATION_MAX_FINDINGS_V2 = 1e4;
|
|
11496
|
+
var EVALUATION_MAX_REASON_CODES_V2 = 64;
|
|
11497
|
+
var EVALUATION_MAX_MAP_ENTRIES_V2 = 1e5;
|
|
11498
|
+
var EVALUATION_MAX_POLICY_RULES_V2 = 1e4;
|
|
11499
|
+
var EVALUATION_RECEIPT_STRING_MAX_BYTES_V1 = 4096;
|
|
11500
|
+
var utf8Length3 = (value) => new TextEncoder().encode(value).byteLength;
|
|
11501
|
+
var boundedString3 = (maxBytes = EVALUATION_RECEIPT_STRING_MAX_BYTES_V1) => z11.string().min(1).refine((value) => utf8Length3(value) <= maxBytes, `Value exceeds ${maxBytes} UTF-8 bytes`);
|
|
11502
|
+
var unique2 = (values) => new Set(values).size === values.length;
|
|
11503
|
+
var contractPreimageV1Schema = z11.object({
|
|
11504
|
+
schema: z11.literal(CONTRACT_PREIMAGE_SCHEMA),
|
|
11505
|
+
domains: z11.object({
|
|
11506
|
+
components: digestHexStringSchema,
|
|
11507
|
+
tokens: digestHexStringSchema,
|
|
11508
|
+
canonicalMap: digestHexStringSchema,
|
|
11509
|
+
policy: digestHexStringSchema
|
|
11510
|
+
}).strict()
|
|
11511
|
+
}).strict();
|
|
11512
|
+
var effectiveRulePolicySchema = z11.object({ trust: z11.enum(["canonical", "evidence", "none"]).optional() }).strict();
|
|
11513
|
+
var effectivePolicySchema = z11.object({
|
|
11514
|
+
failOnWarnings: z11.boolean(),
|
|
11515
|
+
failOnInert: z11.boolean().optional(),
|
|
11516
|
+
rules: z11.record(boundedString3(), effectiveRulePolicySchema).refine(
|
|
11517
|
+
(rules) => Object.keys(rules).length <= EVALUATION_MAX_POLICY_RULES_V2,
|
|
11518
|
+
"Policy rule map exceeds the V2 limit"
|
|
11519
|
+
).optional()
|
|
11520
|
+
}).strict();
|
|
11521
|
+
var evaluationTrustSchema = z11.object({
|
|
11522
|
+
source: z11.enum(["verified", "unverified", "unknown"]),
|
|
11523
|
+
sources: z11.record(boundedString3(), z11.enum(["verified", "unverified", "unknown"])).refine(
|
|
11524
|
+
(sources) => Object.keys(sources).length <= EVALUATION_MAX_MAP_ENTRIES_V2,
|
|
11525
|
+
"Source trust map exceeds the V2 limit"
|
|
11526
|
+
).optional(),
|
|
11527
|
+
mappings: z11.record(boundedString3(), z11.enum(["confirmed", "unconfirmed", "unknown"])).refine(
|
|
11528
|
+
(mappings) => Object.keys(mappings).length <= EVALUATION_MAX_MAP_ENTRIES_V2,
|
|
11529
|
+
"Mapping trust map exceeds the V2 limit"
|
|
11530
|
+
)
|
|
11531
|
+
}).strict();
|
|
11532
|
+
var waiverScopeSchema = z11.discriminatedUnion("kind", [
|
|
11533
|
+
z11.object({ kind: z11.literal("finding"), fingerprint: boundedString3() }).strict(),
|
|
11534
|
+
z11.object({ kind: z11.literal("rule"), ruleId: boundedString3() }).strict(),
|
|
11535
|
+
z11.object({ kind: z11.literal("path"), pathPattern: boundedString3() }).strict(),
|
|
11536
|
+
z11.object({ kind: z11.literal("rule_path"), ruleId: boundedString3(), pathPattern: boundedString3() }).strict()
|
|
11537
|
+
]);
|
|
11538
|
+
var effectiveEvaluationWaiverV2Schema = z11.object({
|
|
11539
|
+
waiverId: boundedString3(),
|
|
11540
|
+
scope: waiverScopeSchema,
|
|
11541
|
+
matchedFindingFingerprints: z11.array(boundedString3()).min(1).max(EVALUATION_MAX_WAIVER_MATCHES_V2).refine(unique2, "matched finding fingerprints must be unique"),
|
|
11542
|
+
reason: boundedString3(),
|
|
11543
|
+
expiresAt: z11.number().finite().optional()
|
|
11544
|
+
}).strict();
|
|
11545
|
+
var evaluationIntegrityInputV2Schema = z11.object({
|
|
11546
|
+
governance: z11.enum(["healthy", "inert"]),
|
|
11547
|
+
inertConfigDiagnosticCount: z11.number().int().nonnegative(),
|
|
11548
|
+
profile: z11.discriminatedUnion("state", [
|
|
11549
|
+
z11.object({
|
|
11550
|
+
state: z11.literal("known"),
|
|
11551
|
+
profileId: boundedString3(),
|
|
11552
|
+
profileVersion: boundedString3()
|
|
11553
|
+
}).strict(),
|
|
11554
|
+
z11.object({
|
|
11555
|
+
state: z11.literal("unknown"),
|
|
11556
|
+
profileId: boundedString3(),
|
|
11557
|
+
profileVersion: boundedString3().optional()
|
|
11558
|
+
}).strict()
|
|
11559
|
+
]),
|
|
11560
|
+
facts: canonicalFactIntegrityV1Schema
|
|
11561
|
+
}).strict();
|
|
11562
|
+
var baselineSchema = z11.object({
|
|
11563
|
+
identity: z11.object({
|
|
11564
|
+
bindingDigest: digestHexStringSchema,
|
|
11565
|
+
repositoryExternalId: boundedString3(),
|
|
11566
|
+
fcid: digestHexStringSchema,
|
|
11567
|
+
sourceCommitId: boundedString3(),
|
|
11568
|
+
generationId: boundedString3()
|
|
11569
|
+
}).strict(),
|
|
11570
|
+
findingStates: z11.record(boundedString3(), z11.enum(["introduced", "existing", "unknown"])).refine(
|
|
11571
|
+
(states) => Object.keys(states).length <= EVALUATION_MAX_MAP_ENTRIES_V2,
|
|
11572
|
+
"Baseline finding-state map exceeds the V2 limit"
|
|
11573
|
+
)
|
|
11574
|
+
}).strict();
|
|
11575
|
+
var evaluationInputV2RawSchema = z11.object({
|
|
11576
|
+
schemaVersion: z11.literal(2),
|
|
11577
|
+
binding: repositoryBindingKeyV1Schema,
|
|
11578
|
+
analysisPlan: analysisPlanV1Schema,
|
|
11579
|
+
contract: z11.object({
|
|
11580
|
+
fcid: digestHexStringSchema,
|
|
11581
|
+
preimage: contractPreimageV1Schema,
|
|
11582
|
+
active: z11.boolean()
|
|
11583
|
+
}).strict(),
|
|
11584
|
+
factSchemaVersion: boundedString3(256),
|
|
11585
|
+
facts: z11.instanceof(FactIndex),
|
|
11586
|
+
factsDigest: digestHexStringSchema,
|
|
11587
|
+
coverage: z11.array(coverageRegionV1Schema).max(1e3),
|
|
11588
|
+
policy: effectivePolicySchema,
|
|
11589
|
+
baseline: baselineSchema.optional(),
|
|
11590
|
+
adoption: z11.union([z11.literal("unavailable"), z11.object({ regressed: z11.boolean() }).strict()]).optional(),
|
|
11591
|
+
trust: evaluationTrustSchema.optional(),
|
|
11592
|
+
waivers: z11.array(effectiveEvaluationWaiverV2Schema).max(EVALUATION_MAX_WAIVERS_V2).refine(
|
|
11593
|
+
(waivers) => new Set(waivers.map((waiver) => waiver.waiverId)).size === waivers.length,
|
|
11594
|
+
"waiver IDs must be unique"
|
|
11595
|
+
),
|
|
11596
|
+
integrity: evaluationIntegrityInputV2Schema,
|
|
11597
|
+
evaluatedAt: z11.number().finite(),
|
|
11598
|
+
evaluatorVersion: boundedString3(256)
|
|
11599
|
+
}).strict().superRefine((input, context) => {
|
|
11600
|
+
let plan;
|
|
11601
|
+
try {
|
|
11602
|
+
plan = parseAnalysisPlanV1(input.analysisPlan);
|
|
11603
|
+
} catch (error) {
|
|
11604
|
+
context.addIssue({
|
|
11605
|
+
code: z11.ZodIssueCode.custom,
|
|
11606
|
+
path: ["analysisPlan"],
|
|
11607
|
+
message: error instanceof Error ? error.message : "Invalid analysis plan identity"
|
|
11608
|
+
});
|
|
11609
|
+
return;
|
|
11610
|
+
}
|
|
11611
|
+
if (repositoryBindingDigestV1(plan.binding) !== repositoryBindingDigestV1(input.binding)) {
|
|
11612
|
+
context.addIssue({
|
|
11613
|
+
code: z11.ZodIssueCode.custom,
|
|
11614
|
+
path: ["binding"],
|
|
11615
|
+
message: "Evaluation binding does not match the analysis plan binding"
|
|
11616
|
+
});
|
|
11617
|
+
}
|
|
11618
|
+
if (plan.contract.fcid !== input.contract.fcid) {
|
|
11619
|
+
context.addIssue({
|
|
11620
|
+
code: z11.ZodIssueCode.custom,
|
|
11621
|
+
path: ["contract", "fcid"],
|
|
11622
|
+
message: "Evaluation FCID does not match the analysis plan"
|
|
11623
|
+
});
|
|
11624
|
+
}
|
|
11625
|
+
if (contractHash(input.contract.preimage) !== input.contract.fcid) {
|
|
11626
|
+
context.addIssue({
|
|
11627
|
+
code: z11.ZodIssueCode.custom,
|
|
11628
|
+
path: ["contract", "preimage"],
|
|
11629
|
+
message: "Contract preimage does not reproduce the pinned FCID"
|
|
11630
|
+
});
|
|
11631
|
+
}
|
|
11632
|
+
if (plan.evaluatorVersion !== input.evaluatorVersion) {
|
|
11633
|
+
context.addIssue({
|
|
11634
|
+
code: z11.ZodIssueCode.custom,
|
|
11635
|
+
path: ["evaluatorVersion"],
|
|
11636
|
+
message: "Evaluator version does not match the analysis plan"
|
|
11637
|
+
});
|
|
11638
|
+
}
|
|
11639
|
+
if (input.integrity.profile.state === "known" && (input.integrity.profile.profileId !== plan.profile.id || input.integrity.profile.profileVersion !== plan.profile.version)) {
|
|
11640
|
+
context.addIssue({
|
|
11641
|
+
code: z11.ZodIssueCode.custom,
|
|
11642
|
+
path: ["integrity", "profile"],
|
|
11643
|
+
message: "Known profile identity does not match the analysis plan"
|
|
11644
|
+
});
|
|
11645
|
+
}
|
|
11646
|
+
if (input.baseline) {
|
|
11647
|
+
const expectedBindingDigest = repositoryBindingDigestV1(input.binding);
|
|
11648
|
+
if (input.baseline.identity.bindingDigest !== expectedBindingDigest || input.baseline.identity.repositoryExternalId !== input.binding.repositoryExternalId || input.baseline.identity.fcid !== input.contract.fcid) {
|
|
11649
|
+
context.addIssue({
|
|
11650
|
+
code: z11.ZodIssueCode.custom,
|
|
11651
|
+
path: ["baseline", "identity"],
|
|
11652
|
+
message: "Baseline identity does not match the evaluation binding and FCID"
|
|
11653
|
+
});
|
|
11654
|
+
}
|
|
11655
|
+
}
|
|
11656
|
+
if (input.facts.size() > plan.limits.maxFacts) {
|
|
11657
|
+
context.addIssue({
|
|
11658
|
+
code: z11.ZodIssueCode.custom,
|
|
11659
|
+
path: ["facts"],
|
|
11660
|
+
message: "Fact count exceeds the analysis-plan limit"
|
|
11661
|
+
});
|
|
11662
|
+
}
|
|
11663
|
+
try {
|
|
11664
|
+
deriveCoverageSummaryV1(plan, input.coverage);
|
|
11665
|
+
} catch (error) {
|
|
11666
|
+
context.addIssue({
|
|
11667
|
+
code: z11.ZodIssueCode.custom,
|
|
11668
|
+
path: ["coverage"],
|
|
11669
|
+
message: error instanceof Error ? error.message : "Coverage does not match the plan"
|
|
11670
|
+
});
|
|
11671
|
+
}
|
|
11672
|
+
});
|
|
11673
|
+
var evaluationInputV2Schema = evaluationInputV2RawSchema.transform(
|
|
11674
|
+
(input) => ({
|
|
11675
|
+
...input,
|
|
11676
|
+
binding: normalizeRepositoryBindingKeyV1(input.binding),
|
|
11677
|
+
analysisPlan: parseAnalysisPlanV1(input.analysisPlan)
|
|
11678
|
+
})
|
|
11679
|
+
);
|
|
11680
|
+
var evaluationReasonV2Schema = z11.enum([
|
|
11681
|
+
"zeroFileScan",
|
|
11682
|
+
"governanceInert",
|
|
11683
|
+
"contractUnpinned",
|
|
11684
|
+
"contractStale",
|
|
11685
|
+
"contractIdentityMismatch",
|
|
11686
|
+
"inertConfigPresent",
|
|
11687
|
+
"unknownPresetPresent",
|
|
11688
|
+
"blockedFindings",
|
|
11689
|
+
"adoptionRegression",
|
|
11690
|
+
"expiredSuppression",
|
|
11691
|
+
"pendingCloudTrust",
|
|
11692
|
+
"adoptionBaselineUnavailable",
|
|
11693
|
+
"analysisPlanIdentityMismatch",
|
|
11694
|
+
"requiredCoverageMissing",
|
|
11695
|
+
"requiredCoverageIncomplete",
|
|
11696
|
+
"factConflict",
|
|
11697
|
+
"unknownAnalysisProfile"
|
|
11698
|
+
]);
|
|
11699
|
+
var evaluationResultV2Schema = z11.object({
|
|
11700
|
+
schemaVersion: z11.literal(2),
|
|
11701
|
+
verdict: z11.enum(["pass", "block", "indeterminate"]),
|
|
11702
|
+
reasons: z11.array(evaluationReasonV2Schema).max(EVALUATION_MAX_REASON_CODES_V2).refine(unique2, "Evaluation reason codes must be unique"),
|
|
11703
|
+
findings: z11.array(
|
|
11704
|
+
z11.object({
|
|
11705
|
+
fingerprint: boundedString3(),
|
|
11706
|
+
ruleId: boundedString3(),
|
|
11707
|
+
severity: z11.enum(["error", "warn", "info"]),
|
|
11708
|
+
state: z11.enum(["blocked", "advisory", "pending_cloud_trust"]),
|
|
11709
|
+
stateReasons: z11.array(boundedString3()).max(256)
|
|
11710
|
+
}).strict()
|
|
11711
|
+
).max(EVALUATION_MAX_FINDINGS_V2),
|
|
11712
|
+
counts: z11.object({
|
|
11713
|
+
blocked: z11.number().int().nonnegative().max(EVALUATION_MAX_FINDINGS_V2),
|
|
11714
|
+
advisory: z11.number().int().nonnegative().max(EVALUATION_MAX_FINDINGS_V2),
|
|
11715
|
+
pendingCloudTrust: z11.number().int().nonnegative().max(EVALUATION_MAX_FINDINGS_V2)
|
|
11716
|
+
}).strict(),
|
|
11717
|
+
derived: z11.object({ warnPresent: z11.boolean(), gatingFindingsPresent: z11.boolean() }).strict(),
|
|
11718
|
+
coverageSummary: coverageSummaryV1Schema,
|
|
11719
|
+
integrity: z11.object({
|
|
11720
|
+
fcidVerified: z11.boolean(),
|
|
11721
|
+
analysisPlanVerified: z11.boolean(),
|
|
11722
|
+
factIntegrity: z11.enum(["healthy", "conflict"]),
|
|
11723
|
+
requiredCoverage: z11.enum(["complete", "incomplete", "no_required_regions"]),
|
|
11724
|
+
governance: z11.enum(["healthy", "inert"]),
|
|
11725
|
+
profile: z11.enum(["known", "unknown"])
|
|
11726
|
+
}).strict(),
|
|
11727
|
+
inputDigest: digestHexStringSchema,
|
|
11728
|
+
resultDigest: digestHexStringSchema
|
|
11729
|
+
}).strict().superRefine((result, context) => {
|
|
11730
|
+
const expectedCounts = { blocked: 0, advisory: 0, pendingCloudTrust: 0 };
|
|
11731
|
+
let emittedWarnPresent = false;
|
|
11732
|
+
for (const [index, finding] of result.findings.entries()) {
|
|
11733
|
+
if (finding.state === "blocked") expectedCounts.blocked += 1;
|
|
11734
|
+
else if (finding.state === "pending_cloud_trust") expectedCounts.pendingCloudTrust += 1;
|
|
11735
|
+
else expectedCounts.advisory += 1;
|
|
11736
|
+
if (finding.severity === "warn") emittedWarnPresent = true;
|
|
11737
|
+
if (new Set(finding.stateReasons).size !== finding.stateReasons.length) {
|
|
11738
|
+
context.addIssue({
|
|
11739
|
+
code: z11.ZodIssueCode.custom,
|
|
11740
|
+
path: ["findings", index, "stateReasons"],
|
|
11741
|
+
message: "Finding state reasons must be unique"
|
|
11742
|
+
});
|
|
11743
|
+
}
|
|
11744
|
+
}
|
|
11745
|
+
if (new Set(result.findings.map((finding) => finding.fingerprint)).size !== result.findings.length) {
|
|
11746
|
+
context.addIssue({
|
|
11747
|
+
code: z11.ZodIssueCode.custom,
|
|
11748
|
+
path: ["findings"],
|
|
11749
|
+
message: "Evaluation finding fingerprints must be unique"
|
|
11750
|
+
});
|
|
11751
|
+
}
|
|
11752
|
+
for (const key of ["blocked", "advisory", "pendingCloudTrust"]) {
|
|
11753
|
+
if (result.counts[key] !== expectedCounts[key]) {
|
|
11754
|
+
context.addIssue({
|
|
11755
|
+
code: z11.ZodIssueCode.custom,
|
|
11756
|
+
path: ["counts", key],
|
|
11757
|
+
message: `Evaluation ${key} count must match findings`
|
|
11758
|
+
});
|
|
11759
|
+
}
|
|
11760
|
+
}
|
|
11761
|
+
if (emittedWarnPresent && !result.derived.warnPresent) {
|
|
11762
|
+
context.addIssue({
|
|
11763
|
+
code: z11.ZodIssueCode.custom,
|
|
11764
|
+
path: ["derived", "warnPresent"],
|
|
11765
|
+
message: "An emitted warning finding requires warnPresent"
|
|
11766
|
+
});
|
|
11767
|
+
}
|
|
11768
|
+
if (result.derived.gatingFindingsPresent !== expectedCounts.blocked > 0) {
|
|
11769
|
+
context.addIssue({
|
|
11770
|
+
code: z11.ZodIssueCode.custom,
|
|
11771
|
+
path: ["derived", "gatingFindingsPresent"],
|
|
11772
|
+
message: "gatingFindingsPresent must match blocked findings"
|
|
11773
|
+
});
|
|
11774
|
+
}
|
|
11775
|
+
const coverageStates = [
|
|
11776
|
+
"analyzed",
|
|
11777
|
+
"unsupported",
|
|
11778
|
+
"excluded_by_contract",
|
|
11779
|
+
"skipped_limit",
|
|
11780
|
+
"failed"
|
|
11781
|
+
];
|
|
11782
|
+
const requiredCount = coverageStates.reduce(
|
|
11783
|
+
(total, state) => total + result.coverageSummary.requiredByState[state],
|
|
11784
|
+
0
|
|
11785
|
+
);
|
|
11786
|
+
const optionalCount = coverageStates.reduce(
|
|
11787
|
+
(total, state) => total + result.coverageSummary.optionalByState[state],
|
|
11788
|
+
0
|
|
11789
|
+
);
|
|
11790
|
+
if (requiredCount !== result.coverageSummary.requiredRegions || requiredCount + optionalCount !== result.coverageSummary.observedRegions || result.coverageSummary.observedRegions !== result.coverageSummary.plannedRegions) {
|
|
11791
|
+
context.addIssue({
|
|
11792
|
+
code: z11.ZodIssueCode.custom,
|
|
11793
|
+
path: ["coverageSummary"],
|
|
11794
|
+
message: "Coverage summary counts must reconcile with planned and observed regions"
|
|
11795
|
+
});
|
|
11796
|
+
}
|
|
11797
|
+
if (result.coverageSummary.analyzedFiles > result.coverageSummary.eligibleFiles) {
|
|
11798
|
+
context.addIssue({
|
|
11799
|
+
code: z11.ZodIssueCode.custom,
|
|
11800
|
+
path: ["coverageSummary", "analyzedFiles"],
|
|
11801
|
+
message: "Analyzed files cannot exceed eligible files"
|
|
11802
|
+
});
|
|
11803
|
+
}
|
|
11804
|
+
const expectedRequiredCoverage = result.coverageSummary.requiredRegions === 0 ? "no_required_regions" : result.coverageSummary.requiredByState.analyzed === result.coverageSummary.requiredRegions ? "complete" : "incomplete";
|
|
11805
|
+
if (result.integrity.requiredCoverage !== expectedRequiredCoverage) {
|
|
11806
|
+
context.addIssue({
|
|
11807
|
+
code: z11.ZodIssueCode.custom,
|
|
11808
|
+
path: ["integrity", "requiredCoverage"],
|
|
11809
|
+
message: "Required coverage integrity must match the derived coverage summary"
|
|
11810
|
+
});
|
|
11811
|
+
}
|
|
11812
|
+
const reasons = new Set(result.reasons);
|
|
11813
|
+
const requireReason = (reason, required, path) => {
|
|
11814
|
+
if (reasons.has(reason) !== required) {
|
|
11815
|
+
context.addIssue({
|
|
11816
|
+
code: z11.ZodIssueCode.custom,
|
|
11817
|
+
path,
|
|
11818
|
+
message: `${reason} must match the evaluation result`
|
|
11819
|
+
});
|
|
11820
|
+
}
|
|
11821
|
+
};
|
|
11822
|
+
requireReason("blockedFindings", expectedCounts.blocked > 0, ["reasons"]);
|
|
11823
|
+
requireReason("pendingCloudTrust", expectedCounts.pendingCloudTrust > 0, ["reasons"]);
|
|
11824
|
+
requireReason("contractIdentityMismatch", !result.integrity.fcidVerified, ["reasons"]);
|
|
11825
|
+
requireReason("analysisPlanIdentityMismatch", !result.integrity.analysisPlanVerified, [
|
|
11826
|
+
"reasons"
|
|
11827
|
+
]);
|
|
11828
|
+
requireReason("factConflict", result.integrity.factIntegrity === "conflict", ["reasons"]);
|
|
11829
|
+
requireReason("governanceInert", result.integrity.governance === "inert", ["reasons"]);
|
|
11830
|
+
requireReason("unknownAnalysisProfile", result.integrity.profile === "unknown", ["reasons"]);
|
|
11831
|
+
requireReason(
|
|
11832
|
+
"requiredCoverageIncomplete",
|
|
11833
|
+
result.integrity.requiredCoverage === "incomplete",
|
|
11834
|
+
["reasons"]
|
|
11835
|
+
);
|
|
11836
|
+
requireReason(
|
|
11837
|
+
"requiredCoverageMissing",
|
|
11838
|
+
result.integrity.requiredCoverage === "no_required_regions",
|
|
11839
|
+
["reasons"]
|
|
11840
|
+
);
|
|
11841
|
+
const integrityHealthy = result.integrity.fcidVerified && result.integrity.analysisPlanVerified && result.integrity.factIntegrity === "healthy" && result.integrity.requiredCoverage === "complete" && result.integrity.governance === "healthy" && result.integrity.profile === "known";
|
|
11842
|
+
const blockingReasons = /* @__PURE__ */ new Set([
|
|
11843
|
+
"blockedFindings",
|
|
11844
|
+
"adoptionRegression",
|
|
11845
|
+
"expiredSuppression"
|
|
11846
|
+
]);
|
|
11847
|
+
const integrityReasons = /* @__PURE__ */ new Set([
|
|
11848
|
+
"zeroFileScan",
|
|
11849
|
+
"governanceInert",
|
|
11850
|
+
"contractUnpinned",
|
|
11851
|
+
"contractStale",
|
|
11852
|
+
"contractIdentityMismatch",
|
|
11853
|
+
"inertConfigPresent",
|
|
11854
|
+
"unknownPresetPresent",
|
|
11855
|
+
"analysisPlanIdentityMismatch",
|
|
11856
|
+
"requiredCoverageMissing",
|
|
11857
|
+
"requiredCoverageIncomplete",
|
|
11858
|
+
"factConflict",
|
|
11859
|
+
"unknownAnalysisProfile"
|
|
11860
|
+
]);
|
|
11861
|
+
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";
|
|
11862
|
+
if (result.verdict !== expectedVerdict) {
|
|
11863
|
+
context.addIssue({
|
|
11864
|
+
code: z11.ZodIssueCode.custom,
|
|
11865
|
+
path: ["verdict"],
|
|
11866
|
+
message: `Evaluation verdict must be ${expectedVerdict} for its reasons and integrity`
|
|
11867
|
+
});
|
|
11868
|
+
}
|
|
11869
|
+
});
|
|
11870
|
+
var providerProofSemanticV1Schema = z11.object({
|
|
11871
|
+
schemaVersion: z11.literal(1),
|
|
11872
|
+
adapterId: boundedString3(),
|
|
11873
|
+
adapterVersion: boundedString3(),
|
|
11874
|
+
providerInstanceId: boundedString3(),
|
|
11875
|
+
bindingDigest: digestHexStringSchema,
|
|
11876
|
+
repositoryExternalId: boundedString3(),
|
|
11877
|
+
sourceCommitId: boundedString3(),
|
|
11878
|
+
eventExternalId: boundedString3(),
|
|
11879
|
+
changeExternalId: boundedString3().optional(),
|
|
11880
|
+
publisherExternalId: boundedString3()
|
|
11881
|
+
}).strict();
|
|
11882
|
+
function providerProofDigestV1(value) {
|
|
11883
|
+
const proof = providerProofSemanticV1Schema.parse(value);
|
|
11884
|
+
return sha256Hex(canonicalPreimage({ schema: "provider-proof.v1", ...proof }));
|
|
11885
|
+
}
|
|
11886
|
+
var providerProofV1Schema = z11.object({
|
|
11887
|
+
schemaVersion: z11.literal(1),
|
|
11888
|
+
adapterId: boundedString3(),
|
|
11889
|
+
adapterVersion: boundedString3(),
|
|
11890
|
+
providerInstanceId: boundedString3(),
|
|
11891
|
+
bindingDigest: digestHexStringSchema,
|
|
11892
|
+
repositoryExternalId: boundedString3(),
|
|
11893
|
+
sourceCommitId: boundedString3(),
|
|
11894
|
+
eventExternalId: boundedString3(),
|
|
11895
|
+
changeExternalId: boundedString3().optional(),
|
|
11896
|
+
publisherExternalId: boundedString3(),
|
|
11897
|
+
proofDigest: digestHexStringSchema
|
|
11898
|
+
}).strict().superRefine((proof, context) => {
|
|
11899
|
+
const { proofDigest, ...semantic } = proof;
|
|
11900
|
+
if (providerProofDigestV1(semantic) !== proofDigest) {
|
|
11901
|
+
context.addIssue({
|
|
11902
|
+
code: z11.ZodIssueCode.custom,
|
|
11903
|
+
path: ["proofDigest"],
|
|
11904
|
+
message: "Provider proof digest mismatch"
|
|
11905
|
+
});
|
|
11906
|
+
}
|
|
11907
|
+
});
|
|
11908
|
+
var receiptSemanticShape = {
|
|
11909
|
+
schemaVersion: z11.literal(1),
|
|
11910
|
+
trust: z11.enum(["source_verified", "ci_attested", "local", "unknown"]),
|
|
11911
|
+
authority: z11.enum(["advisory", "enforcement_eligible"]),
|
|
11912
|
+
binding: repositoryBindingKeyV1Schema,
|
|
11913
|
+
sourceCommitId: boundedString3(),
|
|
11914
|
+
fcid: digestHexStringSchema,
|
|
11915
|
+
analysisPlanDigest: digestHexStringSchema,
|
|
11916
|
+
factsDigest: digestHexStringSchema,
|
|
11917
|
+
inputDigest: digestHexStringSchema,
|
|
11918
|
+
resultDigest: digestHexStringSchema,
|
|
11919
|
+
evaluatorVersion: boundedString3(),
|
|
11920
|
+
providerProof: providerProofV1Schema.optional()
|
|
11921
|
+
};
|
|
11922
|
+
function validateReceiptSemantics(receipt, context) {
|
|
11923
|
+
if (receipt.authority === "enforcement_eligible") {
|
|
11924
|
+
if (receipt.trust !== "source_verified") {
|
|
11925
|
+
context.addIssue({
|
|
11926
|
+
code: z11.ZodIssueCode.custom,
|
|
11927
|
+
path: ["authority"],
|
|
11928
|
+
message: "Only source-verified evidence can enforce"
|
|
11929
|
+
});
|
|
11930
|
+
}
|
|
11931
|
+
if (!receipt.providerProof) {
|
|
11932
|
+
context.addIssue({
|
|
11933
|
+
code: z11.ZodIssueCode.custom,
|
|
11934
|
+
path: ["providerProof"],
|
|
11935
|
+
message: "Source-verified enforcement requires provider proof"
|
|
11936
|
+
});
|
|
11937
|
+
}
|
|
11938
|
+
}
|
|
11939
|
+
if (receipt.trust === "source_verified" && !receipt.providerProof) {
|
|
11940
|
+
context.addIssue({
|
|
11941
|
+
code: z11.ZodIssueCode.custom,
|
|
11942
|
+
path: ["providerProof"],
|
|
11943
|
+
message: "Source-verified trust requires provider proof"
|
|
11944
|
+
});
|
|
11945
|
+
}
|
|
11946
|
+
if (receipt.trust !== "source_verified" && receipt.providerProof) {
|
|
11947
|
+
context.addIssue({
|
|
11948
|
+
code: z11.ZodIssueCode.custom,
|
|
11949
|
+
path: ["providerProof"],
|
|
11950
|
+
message: "Provider proof is reserved for source-verified trust"
|
|
11951
|
+
});
|
|
11952
|
+
}
|
|
11953
|
+
if (!receipt.providerProof) return;
|
|
11954
|
+
const proof = receipt.providerProof;
|
|
11955
|
+
const binding = normalizeRepositoryBindingKeyV1(receipt.binding);
|
|
11956
|
+
if (proof.bindingDigest !== repositoryBindingDigestV1(binding)) {
|
|
11957
|
+
context.addIssue({
|
|
11958
|
+
code: z11.ZodIssueCode.custom,
|
|
11959
|
+
path: ["providerProof", "bindingDigest"],
|
|
11960
|
+
message: "Provider proof binding mismatch"
|
|
11961
|
+
});
|
|
11962
|
+
}
|
|
11963
|
+
if (proof.providerInstanceId !== binding.providerInstanceId) {
|
|
11964
|
+
context.addIssue({
|
|
11965
|
+
code: z11.ZodIssueCode.custom,
|
|
11966
|
+
path: ["providerProof", "providerInstanceId"],
|
|
11967
|
+
message: "Provider proof instance mismatch"
|
|
11968
|
+
});
|
|
11969
|
+
}
|
|
11970
|
+
if (proof.repositoryExternalId !== binding.repositoryExternalId) {
|
|
11971
|
+
context.addIssue({
|
|
11972
|
+
code: z11.ZodIssueCode.custom,
|
|
11973
|
+
path: ["providerProof", "repositoryExternalId"],
|
|
11974
|
+
message: "Provider proof repository mismatch"
|
|
11975
|
+
});
|
|
11976
|
+
}
|
|
11977
|
+
if (proof.sourceCommitId !== receipt.sourceCommitId) {
|
|
11978
|
+
context.addIssue({
|
|
11979
|
+
code: z11.ZodIssueCode.custom,
|
|
11980
|
+
path: ["providerProof", "sourceCommitId"],
|
|
11981
|
+
message: "Provider proof source mismatch"
|
|
11982
|
+
});
|
|
11983
|
+
}
|
|
11984
|
+
}
|
|
11985
|
+
var evaluationReceiptSemanticV1Schema = z11.object(receiptSemanticShape).strict().superRefine(validateReceiptSemantics);
|
|
11986
|
+
function evaluationReceiptDigestV1(value) {
|
|
11987
|
+
const receipt = evaluationReceiptSemanticV1Schema.parse(value);
|
|
11988
|
+
return sha256Hex(
|
|
11989
|
+
canonicalPreimage({
|
|
11990
|
+
schema: "evaluation-receipt.v1",
|
|
11991
|
+
trust: receipt.trust,
|
|
11992
|
+
authority: receipt.authority,
|
|
11993
|
+
bindingDigest: repositoryBindingDigestV1(receipt.binding),
|
|
11994
|
+
sourceCommitId: receipt.sourceCommitId,
|
|
11995
|
+
fcid: receipt.fcid,
|
|
11996
|
+
analysisPlanDigest: receipt.analysisPlanDigest,
|
|
11997
|
+
factsDigest: receipt.factsDigest,
|
|
11998
|
+
inputDigest: receipt.inputDigest,
|
|
11999
|
+
resultDigest: receipt.resultDigest,
|
|
12000
|
+
evaluatorVersion: receipt.evaluatorVersion,
|
|
12001
|
+
providerProofDigest: receipt.providerProof?.proofDigest
|
|
12002
|
+
})
|
|
12003
|
+
);
|
|
12004
|
+
}
|
|
12005
|
+
var evaluationReceiptV1Schema = z11.object({
|
|
12006
|
+
receiptId: evaluationReceiptIdStringSchema,
|
|
12007
|
+
...receiptSemanticShape,
|
|
12008
|
+
mintedAt: z11.string().datetime({ offset: true }),
|
|
12009
|
+
digest: digestHexStringSchema
|
|
12010
|
+
}).strict().superRefine((receipt, context) => {
|
|
12011
|
+
validateReceiptSemantics(receipt, context);
|
|
12012
|
+
let digest;
|
|
12013
|
+
try {
|
|
12014
|
+
const { receiptId: _receiptId, mintedAt: _mintedAt, digest: _digest, ...semantic } = receipt;
|
|
12015
|
+
digest = evaluationReceiptDigestV1(semantic);
|
|
12016
|
+
} catch (error) {
|
|
12017
|
+
context.addIssue({
|
|
12018
|
+
code: z11.ZodIssueCode.custom,
|
|
12019
|
+
message: error instanceof Error ? error.message : "Invalid receipt semantics"
|
|
12020
|
+
});
|
|
12021
|
+
return;
|
|
12022
|
+
}
|
|
12023
|
+
if (digest !== receipt.digest) {
|
|
12024
|
+
context.addIssue({
|
|
12025
|
+
code: z11.ZodIssueCode.custom,
|
|
12026
|
+
path: ["digest"],
|
|
12027
|
+
message: "Receipt digest mismatch"
|
|
12028
|
+
});
|
|
12029
|
+
}
|
|
12030
|
+
if (evaluationReceiptIdFromDigest(digest) !== receipt.receiptId) {
|
|
12031
|
+
context.addIssue({
|
|
12032
|
+
code: z11.ZodIssueCode.custom,
|
|
12033
|
+
path: ["receiptId"],
|
|
12034
|
+
message: "Receipt ID mismatch"
|
|
12035
|
+
});
|
|
12036
|
+
}
|
|
12037
|
+
});
|
|
12038
|
+
function parseEvaluationReceiptV1(value) {
|
|
12039
|
+
return evaluationReceiptV1Schema.parse(value);
|
|
12040
|
+
}
|
|
12041
|
+
var evaluationReceiptMintInputV1Schema = z11.object({
|
|
12042
|
+
schemaVersion: z11.literal(1),
|
|
12043
|
+
trust: z11.enum(["ci_attested", "local", "unknown"]),
|
|
12044
|
+
binding: repositoryBindingKeyV1Schema,
|
|
12045
|
+
sourceCommitId: boundedString3(),
|
|
12046
|
+
fcid: digestHexStringSchema,
|
|
12047
|
+
analysisPlanDigest: digestHexStringSchema,
|
|
12048
|
+
factsDigest: digestHexStringSchema,
|
|
12049
|
+
inputDigest: digestHexStringSchema,
|
|
12050
|
+
resultDigest: digestHexStringSchema,
|
|
12051
|
+
evaluatorVersion: boundedString3()
|
|
12052
|
+
}).strict();
|
|
12053
|
+
|
|
12054
|
+
// src/evaluation/evaluate.ts
|
|
12055
|
+
var INTEGRITY_REASONS = /* @__PURE__ */ new Set([
|
|
12056
|
+
"zeroFileScan",
|
|
12057
|
+
"governanceInert",
|
|
12058
|
+
"contractUnpinned",
|
|
12059
|
+
"contractStale",
|
|
12060
|
+
"contractIdentityMismatch",
|
|
12061
|
+
"inertConfigPresent",
|
|
12062
|
+
"unknownPresetPresent"
|
|
12063
|
+
]);
|
|
12064
|
+
var BLOCK_REASONS = /* @__PURE__ */ new Set([
|
|
12065
|
+
"blockedFindings",
|
|
12066
|
+
"adoptionRegression",
|
|
12067
|
+
"expiredSuppression"
|
|
12068
|
+
]);
|
|
12069
|
+
var REASON_ORDER = [
|
|
12070
|
+
"zeroFileScan",
|
|
12071
|
+
"governanceInert",
|
|
12072
|
+
"contractUnpinned",
|
|
12073
|
+
"contractStale",
|
|
12074
|
+
"contractIdentityMismatch",
|
|
12075
|
+
"inertConfigPresent",
|
|
12076
|
+
"unknownPresetPresent",
|
|
12077
|
+
"blockedFindings",
|
|
12078
|
+
"adoptionRegression",
|
|
12079
|
+
"expiredSuppression",
|
|
12080
|
+
"pendingCloudTrust",
|
|
12081
|
+
"adoptionBaselineUnavailable"
|
|
12082
|
+
];
|
|
12083
|
+
function evaluate2(input) {
|
|
12084
|
+
return isEvaluationInputV2(input) ? evaluateV2(input) : evaluateV1(input);
|
|
12085
|
+
}
|
|
12086
|
+
function isEvaluationInputV2(input) {
|
|
12087
|
+
return "schemaVersion" in input && input.schemaVersion === 2;
|
|
12088
|
+
}
|
|
12089
|
+
function evaluateV1(input) {
|
|
12090
|
+
const reasons = /* @__PURE__ */ new Set();
|
|
12091
|
+
let fcidVerified = "unavailable";
|
|
12092
|
+
if (input.contract.state === "unpinned") {
|
|
12093
|
+
reasons.add("contractUnpinned");
|
|
12094
|
+
} else {
|
|
12095
|
+
if (input.contract.stale) reasons.add("contractStale");
|
|
12096
|
+
if (input.contract.preimage) {
|
|
12097
|
+
fcidVerified = contractHash(input.contract.preimage) === input.contract.fcid;
|
|
12098
|
+
if (!fcidVerified) reasons.add("contractIdentityMismatch");
|
|
12099
|
+
}
|
|
12100
|
+
}
|
|
12101
|
+
if (input.scope.kind === "full" && input.scope.coverage.filesScanned === 0) {
|
|
12102
|
+
reasons.add("zeroFileScan");
|
|
12103
|
+
}
|
|
12104
|
+
if (input.integrity.governance === "inert") {
|
|
12105
|
+
reasons.add("governanceInert");
|
|
12106
|
+
}
|
|
12107
|
+
if (input.policy.failOnInert === true && (input.integrity.inertConfigDiagnostics ?? 0) > 0) {
|
|
12108
|
+
reasons.add("inertConfigPresent");
|
|
12109
|
+
}
|
|
12110
|
+
if ((input.integrity.unknownPresets?.length ?? 0) > 0) {
|
|
12111
|
+
reasons.add("unknownPresetPresent");
|
|
12112
|
+
}
|
|
12113
|
+
if (input.adoption === "unavailable") {
|
|
12114
|
+
reasons.add("adoptionBaselineUnavailable");
|
|
12115
|
+
} else if (input.adoption?.regressed === true) {
|
|
12116
|
+
reasons.add("adoptionRegression");
|
|
12117
|
+
}
|
|
12118
|
+
const activeWaivers = /* @__PURE__ */ new Set();
|
|
12119
|
+
for (const waiver of input.waivers ?? []) {
|
|
12120
|
+
if (waiver.expiresAt !== void 0 && Number.isFinite(waiver.expiresAt) && waiver.expiresAt <= input.evaluatedAt) {
|
|
12121
|
+
reasons.add("expiredSuppression");
|
|
12122
|
+
} else {
|
|
12123
|
+
activeWaivers.add(waiver.fingerprint);
|
|
12124
|
+
}
|
|
12125
|
+
}
|
|
12126
|
+
const evidence = evidenceFindings(input);
|
|
12127
|
+
const findings = [...groupByFingerprint(evidence).values()].map((rows) => {
|
|
12128
|
+
const classified = rows.map((row) => classifyFinding(row, input, activeWaivers));
|
|
12129
|
+
return classified.reduce(
|
|
12130
|
+
(hardest, candidate) => STATE_RANK[candidate.state] < STATE_RANK[hardest.state] ? candidate : hardest
|
|
12131
|
+
);
|
|
12132
|
+
});
|
|
12133
|
+
const counts = { blocked: 0, advisory: 0, pendingCloudTrust: 0 };
|
|
12134
|
+
for (const finding of findings) {
|
|
12135
|
+
if (finding.state === "blocked") counts.blocked += 1;
|
|
12136
|
+
else if (finding.state === "pending_cloud_trust") counts.pendingCloudTrust += 1;
|
|
12137
|
+
else counts.advisory += 1;
|
|
12138
|
+
}
|
|
12139
|
+
if (counts.blocked > 0) reasons.add("blockedFindings");
|
|
12140
|
+
if (counts.pendingCloudTrust > 0) reasons.add("pendingCloudTrust");
|
|
12141
|
+
const ordered = REASON_ORDER.filter((reason) => reasons.has(reason));
|
|
12142
|
+
let verdict;
|
|
12143
|
+
if (ordered.some((reason) => INTEGRITY_REASONS.has(reason))) {
|
|
12144
|
+
verdict = "indeterminate";
|
|
12145
|
+
} else if (ordered.some((reason) => BLOCK_REASONS.has(reason))) {
|
|
12146
|
+
verdict = "block";
|
|
12147
|
+
} else if (ordered.length > 0) {
|
|
12148
|
+
verdict = "indeterminate";
|
|
12149
|
+
} else {
|
|
12150
|
+
verdict = "pass";
|
|
12151
|
+
}
|
|
12152
|
+
const derived = {
|
|
12153
|
+
warnPresent: evidence.some((finding) => finding.severity === "warn"),
|
|
12154
|
+
gatingFindingsPresent: counts.blocked > 0
|
|
12155
|
+
};
|
|
12156
|
+
const inputDigest = sha256Hex(canonicalPreimage(normalizeInputForDigest(input)));
|
|
12157
|
+
const partial = {
|
|
12158
|
+
evaluatorVersion: EVALUATOR_VERSION,
|
|
12159
|
+
verdict,
|
|
12160
|
+
reasons: ordered,
|
|
12161
|
+
findings,
|
|
12162
|
+
counts,
|
|
12163
|
+
derived,
|
|
12164
|
+
integrity: { fcidVerified }
|
|
12165
|
+
};
|
|
12166
|
+
return {
|
|
12167
|
+
...partial,
|
|
12168
|
+
inputDigest,
|
|
12169
|
+
resultDigest: sha256Hex(canonicalPreimage({ ...partial, inputDigest }))
|
|
12170
|
+
};
|
|
12171
|
+
}
|
|
12172
|
+
var V2_REASON_ORDER = [
|
|
12173
|
+
"analysisPlanIdentityMismatch",
|
|
12174
|
+
"requiredCoverageMissing",
|
|
12175
|
+
"requiredCoverageIncomplete",
|
|
12176
|
+
"factConflict",
|
|
12177
|
+
"unknownAnalysisProfile",
|
|
12178
|
+
...REASON_ORDER
|
|
12179
|
+
];
|
|
12180
|
+
var V2_INTEGRITY_REASONS = /* @__PURE__ */ new Set([
|
|
12181
|
+
...INTEGRITY_REASONS,
|
|
12182
|
+
"analysisPlanIdentityMismatch",
|
|
12183
|
+
"requiredCoverageMissing",
|
|
12184
|
+
"requiredCoverageIncomplete",
|
|
12185
|
+
"factConflict",
|
|
12186
|
+
"unknownAnalysisProfile"
|
|
12187
|
+
]);
|
|
12188
|
+
var SUPPORTED_FACT_SCHEMA_VERSIONS_V2 = /* @__PURE__ */ new Set(["facts:v1"]);
|
|
12189
|
+
var SUPPORTED_REACT_WEB_PROFILE_VERSIONS_V1 = /* @__PURE__ */ new Set(["1"]);
|
|
12190
|
+
function evaluateV2(rawInput) {
|
|
12191
|
+
if (rawInput.evaluatorVersion !== EVALUATOR_VERSION_V2) {
|
|
12192
|
+
throw new Error(`Unsupported evaluator version: ${rawInput.evaluatorVersion}`);
|
|
12193
|
+
}
|
|
12194
|
+
if (!SUPPORTED_FACT_SCHEMA_VERSIONS_V2.has(rawInput.factSchemaVersion)) {
|
|
12195
|
+
throw new Error(`Unsupported fact schema version: ${rawInput.factSchemaVersion}`);
|
|
12196
|
+
}
|
|
12197
|
+
const input = evaluationInputV2Schema.parse(rawInput);
|
|
12198
|
+
const coverageSummary = deriveCoverageSummaryV1(input.analysisPlan, input.coverage);
|
|
12199
|
+
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);
|
|
12200
|
+
const compatibilityInput = {
|
|
12201
|
+
contract: {
|
|
12202
|
+
state: "pinned",
|
|
12203
|
+
fcid: input.contract.fcid,
|
|
12204
|
+
preimage: input.contract.preimage,
|
|
12205
|
+
...!input.contract.active ? { stale: true } : {}
|
|
12206
|
+
},
|
|
12207
|
+
scope: { kind: "full", coverage: { filesScanned: coverageSummary.analyzedFiles } },
|
|
12208
|
+
evidence: { kind: "facts", facts: input.facts },
|
|
12209
|
+
policy: input.policy,
|
|
12210
|
+
...input.baseline ? {
|
|
12211
|
+
baseline: {
|
|
12212
|
+
identityVerified: true,
|
|
12213
|
+
findingStates: input.baseline.findingStates
|
|
12214
|
+
}
|
|
12215
|
+
} : {},
|
|
12216
|
+
...input.adoption !== void 0 ? { adoption: input.adoption } : {},
|
|
12217
|
+
...input.trust !== void 0 ? { trust: input.trust } : {},
|
|
12218
|
+
waivers: input.waivers.flatMap(
|
|
12219
|
+
(waiver) => waiver.matchedFindingFingerprints.map((fingerprint) => ({
|
|
12220
|
+
fingerprint,
|
|
12221
|
+
...waiver.expiresAt !== void 0 ? { expiresAt: waiver.expiresAt } : {}
|
|
12222
|
+
}))
|
|
12223
|
+
),
|
|
12224
|
+
integrity: {
|
|
12225
|
+
governance: input.integrity.governance,
|
|
12226
|
+
...input.integrity.inertConfigDiagnosticCount > 0 ? { inertConfigDiagnostics: input.integrity.inertConfigDiagnosticCount } : {}
|
|
12227
|
+
},
|
|
12228
|
+
evaluatedAt: input.evaluatedAt
|
|
12229
|
+
};
|
|
12230
|
+
const compatibilityResult = evaluateV1(compatibilityInput);
|
|
12231
|
+
const requiredCoverage = coverageSummary.requiredRegions === 0 ? "no_required_regions" : coverageSummary.requiredByState.analyzed === coverageSummary.requiredRegions ? "complete" : "incomplete";
|
|
12232
|
+
const integrity = {
|
|
12233
|
+
fcidVerified: compatibilityResult.integrity.fcidVerified === true,
|
|
12234
|
+
analysisPlanVerified: true,
|
|
12235
|
+
factIntegrity: input.integrity.facts.state,
|
|
12236
|
+
requiredCoverage,
|
|
12237
|
+
governance: input.integrity.governance,
|
|
12238
|
+
profile: profileKnown ? "known" : "unknown"
|
|
12239
|
+
};
|
|
12240
|
+
const reasons = new Set(compatibilityResult.reasons);
|
|
12241
|
+
if (requiredCoverage === "no_required_regions") reasons.add("requiredCoverageMissing");
|
|
12242
|
+
if (requiredCoverage === "incomplete") reasons.add("requiredCoverageIncomplete");
|
|
12243
|
+
if (integrity.factIntegrity === "conflict") reasons.add("factConflict");
|
|
12244
|
+
if (integrity.profile === "unknown") reasons.add("unknownAnalysisProfile");
|
|
12245
|
+
const orderedReasons = V2_REASON_ORDER.filter((reason) => reasons.has(reason));
|
|
12246
|
+
let verdict = compatibilityResult.verdict;
|
|
12247
|
+
if (orderedReasons.some((reason) => V2_INTEGRITY_REASONS.has(reason))) {
|
|
12248
|
+
verdict = "indeterminate";
|
|
12249
|
+
}
|
|
12250
|
+
const inputDigest = sha256Hex(
|
|
12251
|
+
canonicalPreimage(normalizeInputV2ForDigest(input, coverageSummary))
|
|
12252
|
+
);
|
|
12253
|
+
const partial = {
|
|
12254
|
+
schemaVersion: 2,
|
|
12255
|
+
verdict,
|
|
12256
|
+
reasons: orderedReasons,
|
|
12257
|
+
findings: compatibilityResult.findings.map((finding) => ({
|
|
12258
|
+
...finding,
|
|
12259
|
+
stateReasons: [...finding.stateReasons]
|
|
12260
|
+
})),
|
|
12261
|
+
counts: { ...compatibilityResult.counts },
|
|
12262
|
+
derived: { ...compatibilityResult.derived },
|
|
12263
|
+
coverageSummary,
|
|
12264
|
+
integrity
|
|
12265
|
+
};
|
|
12266
|
+
const resultDigest = sha256Hex(
|
|
12267
|
+
canonicalPreimage({ schema: "evaluation-result:v2", ...partial, inputDigest })
|
|
12268
|
+
);
|
|
12269
|
+
return evaluationResultV2Schema.parse({ ...partial, inputDigest, resultDigest });
|
|
12270
|
+
}
|
|
12271
|
+
function normalizeInputV2ForDigest(input, coverageSummary) {
|
|
12272
|
+
const {
|
|
12273
|
+
analysisPlanId: _analysisPlanId,
|
|
12274
|
+
createdAt: _createdAt,
|
|
12275
|
+
digest: _planDigest,
|
|
12276
|
+
obligationsDigest: _obligationsDigest,
|
|
12277
|
+
...analysisPlanSemantic
|
|
12278
|
+
} = input.analysisPlan;
|
|
12279
|
+
return {
|
|
12280
|
+
schema: "evaluation-input:v2",
|
|
12281
|
+
binding: input.binding,
|
|
12282
|
+
analysisPlan: {
|
|
12283
|
+
...analysisPlanSemantic,
|
|
12284
|
+
analysisPlanDigest: input.analysisPlan.digest,
|
|
12285
|
+
obligationsDigest: input.analysisPlan.obligationsDigest
|
|
12286
|
+
},
|
|
12287
|
+
contract: input.contract,
|
|
12288
|
+
factSchemaVersion: input.factSchemaVersion,
|
|
12289
|
+
factsDigest: input.factsDigest,
|
|
12290
|
+
coverage: [...input.coverage].map((region) => ({
|
|
12291
|
+
...region,
|
|
12292
|
+
diagnosticIds: [...region.diagnosticIds].sort(compareCanonicalStrings)
|
|
12293
|
+
})).sort((left, right) => compareCanonicalStrings(left.regionId, right.regionId)),
|
|
12294
|
+
coverageSummary,
|
|
12295
|
+
policy: input.policy,
|
|
12296
|
+
baseline: input.baseline,
|
|
12297
|
+
adoption: input.adoption,
|
|
12298
|
+
trust: input.trust,
|
|
12299
|
+
waivers: input.waivers.map((waiver) => ({
|
|
12300
|
+
...waiver,
|
|
12301
|
+
matchedFindingFingerprints: [...waiver.matchedFindingFingerprints].sort(
|
|
12302
|
+
compareCanonicalStrings
|
|
12303
|
+
)
|
|
12304
|
+
})).sort((left, right) => compareCanonicalStrings(left.waiverId, right.waiverId)),
|
|
12305
|
+
integrity: input.integrity,
|
|
12306
|
+
evaluatedAt: input.evaluatedAt,
|
|
12307
|
+
evaluatorVersion: input.evaluatorVersion
|
|
12308
|
+
};
|
|
12309
|
+
}
|
|
12310
|
+
function evidenceFindings(input) {
|
|
12311
|
+
if (input.evidence.kind === "findings") return [...input.evidence.findings];
|
|
12312
|
+
const ruleConfig = readRuleConfig(input.evidence.facts);
|
|
12313
|
+
return runRules(input.evidence.facts).map((finding) => ({
|
|
12314
|
+
fingerprint: finding.fingerprint,
|
|
12315
|
+
ruleId: finding.ruleId,
|
|
12316
|
+
severity: severityLevel(configuredFindingSeverity(finding, ruleConfig)),
|
|
12317
|
+
advisory: finding.attributes?.advisory === true,
|
|
12318
|
+
evidenceGrade: finding.evidenceGrade
|
|
12319
|
+
}));
|
|
12320
|
+
}
|
|
12321
|
+
var STATE_RANK = { blocked: 0, pending_cloud_trust: 1, advisory: 2 };
|
|
12322
|
+
var SEVERITY_RANK2 = { error: 0, warn: 1, info: 2 };
|
|
12323
|
+
function canonicalRow(finding) {
|
|
12324
|
+
return {
|
|
12325
|
+
fingerprint: finding.fingerprint,
|
|
12326
|
+
ruleId: finding.ruleId,
|
|
12327
|
+
severity: finding.severity,
|
|
12328
|
+
advisory: finding.advisory === true,
|
|
12329
|
+
evidenceGrade: coerceEvidenceGrade(finding.evidenceGrade),
|
|
12330
|
+
waived: finding.waived === true,
|
|
12331
|
+
...finding.sourceTrust !== void 0 ? { sourceTrust: finding.sourceTrust } : {},
|
|
12332
|
+
...finding.mappingTrust !== void 0 ? { mappingTrust: finding.mappingTrust } : {},
|
|
12333
|
+
...finding.baselineState !== void 0 ? { baselineState: finding.baselineState } : {}
|
|
12334
|
+
};
|
|
12335
|
+
}
|
|
12336
|
+
function compareStrings(a, b) {
|
|
12337
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
12338
|
+
}
|
|
12339
|
+
function compareRows(a, b) {
|
|
12340
|
+
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 ?? "");
|
|
12341
|
+
}
|
|
12342
|
+
function canonicalRows(findings) {
|
|
12343
|
+
const sorted = findings.map(canonicalRow).sort(compareRows);
|
|
12344
|
+
return sorted.filter((row, index) => index === 0 || compareRows(row, sorted[index - 1]) !== 0);
|
|
12345
|
+
}
|
|
12346
|
+
function groupByFingerprint(findings) {
|
|
12347
|
+
const groups = /* @__PURE__ */ new Map();
|
|
12348
|
+
for (const row of canonicalRows(findings)) {
|
|
12349
|
+
const group = groups.get(row.fingerprint);
|
|
12350
|
+
if (group) group.push(row);
|
|
12351
|
+
else groups.set(row.fingerprint, [row]);
|
|
12352
|
+
}
|
|
12353
|
+
return groups;
|
|
12354
|
+
}
|
|
12355
|
+
function classifyFinding(finding, input, activeWaivers) {
|
|
12356
|
+
const base = {
|
|
12357
|
+
fingerprint: finding.fingerprint,
|
|
12358
|
+
ruleId: finding.ruleId,
|
|
12359
|
+
severity: finding.severity
|
|
12360
|
+
};
|
|
12361
|
+
if (activeWaivers.has(finding.fingerprint) || finding.waived === true) {
|
|
12362
|
+
return { ...base, state: "advisory", stateReasons: ["waived"] };
|
|
12363
|
+
}
|
|
12364
|
+
const eligibility = eligibilityFor(finding, input.policy);
|
|
12365
|
+
if (eligibility !== null) {
|
|
12366
|
+
return { ...base, state: "advisory", stateReasons: [eligibility] };
|
|
12367
|
+
}
|
|
12368
|
+
const introduced = introducedFactFor(finding, input);
|
|
12369
|
+
if (introduced.state === "negative") {
|
|
12370
|
+
return { ...base, state: "advisory", stateReasons: ["baseline:existing"] };
|
|
12371
|
+
}
|
|
12372
|
+
const requirement = input.policy.rules?.[finding.ruleId]?.trust ?? defaultTrustRequirement(finding.ruleId);
|
|
12373
|
+
const mappingBinds = requirement === "canonical" || defaultTrustRequirement(finding.ruleId) === "canonical";
|
|
12374
|
+
if (requirement === "none") {
|
|
12375
|
+
const definitives = [sourceFact(finding, input)];
|
|
12376
|
+
if (mappingBinds) definitives.push(mappingFact(finding, input));
|
|
12377
|
+
const definitiveNegative = definitives.find(([, state]) => state === "negative");
|
|
12378
|
+
if (definitiveNegative) {
|
|
12379
|
+
return { ...base, state: "advisory", stateReasons: [`trust:${definitiveNegative[0]}`] };
|
|
12380
|
+
}
|
|
12381
|
+
return { ...base, state: "blocked", stateReasons: [`eligible:${finding.severity}`] };
|
|
12382
|
+
}
|
|
12383
|
+
const facts = [
|
|
12384
|
+
[`introduced:${introduced.detail}`, introduced.state],
|
|
12385
|
+
sourceFact(finding, input)
|
|
12386
|
+
];
|
|
12387
|
+
if (requirement === "canonical") {
|
|
12388
|
+
facts.push(mappingFact(finding, input));
|
|
12389
|
+
} else if (mappingBinds) {
|
|
12390
|
+
const mapping = mappingFact(finding, input);
|
|
12391
|
+
if (mapping[1] === "negative") facts.push(mapping);
|
|
12392
|
+
}
|
|
12393
|
+
const negative = facts.find(([, state]) => state === "negative");
|
|
12394
|
+
if (negative) {
|
|
12395
|
+
return { ...base, state: "advisory", stateReasons: [`trust:${negative[0]}`] };
|
|
12396
|
+
}
|
|
12397
|
+
const unknowns = facts.filter(([, state]) => state === "unknown");
|
|
12398
|
+
if (unknowns.length > 0) {
|
|
12399
|
+
return {
|
|
12400
|
+
...base,
|
|
12401
|
+
state: "pending_cloud_trust",
|
|
12402
|
+
stateReasons: unknowns.map(([label]) => `trust:${label}`)
|
|
12403
|
+
};
|
|
12404
|
+
}
|
|
12405
|
+
return { ...base, state: "blocked", stateReasons: [`eligible:${finding.severity}`, "trust:all"] };
|
|
12406
|
+
}
|
|
12407
|
+
function eligibilityFor(finding, policy) {
|
|
12408
|
+
if (finding.advisory === true) return "ineligible:advisory-tier";
|
|
12409
|
+
if (!canBlock(coerceEvidenceGrade(finding.evidenceGrade))) return "ineligible:evidence-grade";
|
|
12410
|
+
if (finding.severity === "error") return null;
|
|
12411
|
+
if (finding.severity === "warn") {
|
|
12412
|
+
return policy.failOnWarnings ? null : "ineligible:warn-not-gated";
|
|
12413
|
+
}
|
|
12414
|
+
return "ineligible:info";
|
|
12415
|
+
}
|
|
12416
|
+
function coerceEvidenceGrade(grade) {
|
|
12417
|
+
if (grade === void 0) return "source_backed";
|
|
12418
|
+
return EVIDENCE_ORDER.includes(grade) ? grade : "none";
|
|
12419
|
+
}
|
|
12420
|
+
function defaultTrustRequirement(ruleId) {
|
|
12421
|
+
return tierFor(ruleId) === "contract" ? "canonical" : "evidence";
|
|
12422
|
+
}
|
|
12423
|
+
function introducedFactFor(finding, input) {
|
|
12424
|
+
const baseline = input.baseline;
|
|
12425
|
+
if (!baseline) return { state: "unknown", detail: "no-baseline" };
|
|
12426
|
+
if (!baseline.identityVerified) return { state: "unknown", detail: "identity-unverified" };
|
|
12427
|
+
const recorded = finding.baselineState ?? baseline.findingStates?.[finding.fingerprint] ?? "introduced";
|
|
12428
|
+
if (recorded === "existing") return { state: "negative", detail: "existing" };
|
|
12429
|
+
if (recorded === "introduced") return { state: "affirmative", detail: "introduced" };
|
|
12430
|
+
return { state: "unknown", detail: "unknown" };
|
|
12431
|
+
}
|
|
12432
|
+
function sourceFact(finding, input) {
|
|
12433
|
+
const source = finding.sourceTrust ?? input.trust?.sources?.[finding.fingerprint] ?? input.trust?.source ?? "unknown";
|
|
12434
|
+
if (source === "verified") return ["source:verified", "affirmative"];
|
|
12435
|
+
if (source === "unverified") return ["source:non-reproduction", "negative"];
|
|
12436
|
+
return ["source:unknown", "unknown"];
|
|
12437
|
+
}
|
|
12438
|
+
function mappingFact(finding, input) {
|
|
12439
|
+
const mapping = finding.mappingTrust ?? input.trust?.mappings[finding.fingerprint] ?? "unknown";
|
|
12440
|
+
if (mapping === "confirmed") return ["mapping:confirmed", "affirmative"];
|
|
12441
|
+
if (mapping === "unconfirmed") return ["mapping:unconfirmed", "negative"];
|
|
12442
|
+
return ["mapping:unknown", "unknown"];
|
|
12443
|
+
}
|
|
12444
|
+
function normalizeInputForDigest(input) {
|
|
12445
|
+
return {
|
|
12446
|
+
schema: "evaluation-input:v1",
|
|
12447
|
+
contract: input.contract,
|
|
12448
|
+
scope: input.scope,
|
|
12449
|
+
evidence: canonicalRows(evidenceFindings(input)),
|
|
12450
|
+
policy: input.policy,
|
|
12451
|
+
baseline: input.baseline,
|
|
12452
|
+
adoption: input.adoption,
|
|
12453
|
+
trust: input.trust,
|
|
12454
|
+
waivers: canonicalWaivers(input.waivers ?? []),
|
|
12455
|
+
integrity: {
|
|
12456
|
+
...input.integrity,
|
|
12457
|
+
...input.integrity.unknownPresets ? { unknownPresets: [...new Set(input.integrity.unknownPresets)].sort() } : {}
|
|
12458
|
+
},
|
|
12459
|
+
evaluatedAt: input.evaluatedAt
|
|
12460
|
+
};
|
|
12461
|
+
}
|
|
12462
|
+
function canonicalWaivers(waivers) {
|
|
12463
|
+
const expiryOf = (waiver) => waiver.expiresAt === void 0 || Number.isNaN(waiver.expiresAt) ? Number.POSITIVE_INFINITY : waiver.expiresAt;
|
|
12464
|
+
const canonical = waivers.map((waiver) => {
|
|
12465
|
+
const expiresAt = expiryOf(waiver);
|
|
12466
|
+
return expiresAt === Number.POSITIVE_INFINITY ? { fingerprint: waiver.fingerprint } : { fingerprint: waiver.fingerprint, expiresAt };
|
|
12467
|
+
});
|
|
12468
|
+
const sorted = canonical.sort((a, b) => {
|
|
12469
|
+
if (a.fingerprint !== b.fingerprint) return a.fingerprint < b.fingerprint ? -1 : 1;
|
|
12470
|
+
const ea = expiryOf(a);
|
|
12471
|
+
const eb = expiryOf(b);
|
|
12472
|
+
return ea === eb ? 0 : ea < eb ? -1 : 1;
|
|
12473
|
+
});
|
|
12474
|
+
return sorted.filter(
|
|
12475
|
+
(waiver, index) => index === 0 || waiver.fingerprint !== sorted[index - 1].fingerprint || expiryOf(waiver) !== expiryOf(sorted[index - 1])
|
|
12476
|
+
);
|
|
12477
|
+
}
|
|
9938
12478
|
export {
|
|
9939
12479
|
AGENT_CONTEXT_RELATIVE_PATH,
|
|
12480
|
+
AGENT_FEATURE_CONTEXT_MAX_BYTES_V1,
|
|
9940
12481
|
AGENT_FORMAT_SCHEMA_VERSION,
|
|
12482
|
+
ANALYSIS_LIMIT_CEILINGS_V1,
|
|
12483
|
+
ANALYSIS_PLAN_MAX_CAPABILITIES_V1,
|
|
12484
|
+
ANALYSIS_PLAN_MAX_DIALECTS_PER_REGION_V1,
|
|
12485
|
+
ANALYSIS_PLAN_MAX_REGIONS_V1,
|
|
9941
12486
|
BLOCKING_RULE_ALLOWLIST,
|
|
9942
12487
|
BRAND,
|
|
12488
|
+
CANONICAL_FACT_MAX_CONFLICTS_V1,
|
|
12489
|
+
CANONICAL_FACT_MAX_PROVENANCE_PER_VALUE_V1,
|
|
12490
|
+
CANONICAL_FACT_MAX_VALUES_PER_CONFLICT_V1,
|
|
9943
12491
|
CATALOG_FIXTURE_A_FCID,
|
|
9944
12492
|
CODES,
|
|
12493
|
+
CONTRACT_DISPLAY_ONLY_FIELDS,
|
|
9945
12494
|
CONTRACT_DOMAINS,
|
|
12495
|
+
CONTRACT_ENFORCEMENT_FIELDS,
|
|
9946
12496
|
CONTRACT_PREIMAGE_CAPABILITY_HEADER,
|
|
9947
12497
|
CONTRACT_PREIMAGE_SCHEMA,
|
|
9948
12498
|
CompiledFragmentsFileValidationError,
|
|
12499
|
+
ContractCatalogValidationError,
|
|
12500
|
+
CoverageValidationErrorV1,
|
|
9949
12501
|
DEFAULTS,
|
|
9950
12502
|
DEFAULT_ENHANCED_STYLE_PROPERTIES,
|
|
9951
12503
|
DEFAULT_STYLE_PROPERTIES,
|
|
9952
12504
|
EFFECTIVE_GOVERNANCE_INPUTS_SCHEMA,
|
|
12505
|
+
EMPTY_VOCABULARY_MESSAGE,
|
|
12506
|
+
EVALUATION_MAX_FINDINGS_V2,
|
|
12507
|
+
EVALUATION_MAX_MAP_ENTRIES_V2,
|
|
12508
|
+
EVALUATION_MAX_POLICY_RULES_V2,
|
|
12509
|
+
EVALUATION_MAX_REASON_CODES_V2,
|
|
12510
|
+
EVALUATION_MAX_WAIVERS_V2,
|
|
12511
|
+
EVALUATION_MAX_WAIVER_MATCHES_V2,
|
|
12512
|
+
EVALUATION_RECEIPT_STRING_MAX_BYTES_V1,
|
|
12513
|
+
EVALUATOR_VERSION,
|
|
12514
|
+
EVALUATOR_VERSION_V2,
|
|
9953
12515
|
EVIDENCE_ORDER,
|
|
9954
12516
|
EXPLAIN_URL_BASE,
|
|
12517
|
+
FEATURE_PLAN_MAX_ACCEPTANCE_ITEMS_V1,
|
|
12518
|
+
FEATURE_PLAN_MAX_DECISIONS_V1,
|
|
12519
|
+
FEATURE_PLAN_MAX_EVIDENCE_REFS_V1,
|
|
12520
|
+
FEATURE_PLAN_MAX_GAPS_V1,
|
|
12521
|
+
FEATURE_PLAN_MAX_SCENARIOS_V1,
|
|
12522
|
+
FEATURE_PLAN_MAX_TEXT_BYTES_V1,
|
|
12523
|
+
FEATURE_PLAN_MAX_USES_PER_KIND_V1,
|
|
9955
12524
|
FRAGMENTS_INTERNAL_RULE_IDS,
|
|
12525
|
+
FRAGMENTS_MANIFEST_FILENAME,
|
|
12526
|
+
FRAGMENTS_MANIFEST_SCHEMA_VERSION,
|
|
12527
|
+
FRAGMENTS_MANIFEST_TOKEN_RULE,
|
|
12528
|
+
FRAGMENT_V3_SCHEMA_URL,
|
|
9956
12529
|
FactIndex,
|
|
9957
12530
|
GOVERNANCE_TELEMETRY_FIELDS,
|
|
9958
12531
|
GOVERNANCE_TELEMETRY_SOURCE_DISCLOSURE,
|
|
@@ -9962,13 +12535,18 @@ export {
|
|
|
9962
12535
|
PRESET_NAMES,
|
|
9963
12536
|
PROVE_DEFAULT_MAX_PASSES,
|
|
9964
12537
|
PROVE_MAX_PASSES,
|
|
12538
|
+
PROVIDER_ID_MAX_BYTES_V1,
|
|
9965
12539
|
RAW_HTML_ADVISORY_TAGS,
|
|
9966
12540
|
RAW_HTML_CANONICAL_TAGS,
|
|
9967
12541
|
RAW_HTML_INPUT_TYPE_CANONICALS,
|
|
9968
12542
|
RAW_HTML_ROLE_CANONICALS,
|
|
9969
12543
|
REGISTRY_ARTIFACT_SCHEMA_VERSION,
|
|
12544
|
+
REGISTRY_INDEX_SCHEMA_VERSION,
|
|
9970
12545
|
REGISTRY_INSTALL_RECEIPT_SCHEMA_VERSION,
|
|
9971
12546
|
REGISTRY_MANIFEST_SCHEMA_VERSION,
|
|
12547
|
+
REGISTRY_POINTER_SCHEMA_VERSION,
|
|
12548
|
+
REGISTRY_SHARD_SCHEMA_VERSION,
|
|
12549
|
+
REPOSITORY_BINDING_ID_MAX_BYTES_V1,
|
|
9972
12550
|
RULES,
|
|
9973
12551
|
RULE_FAMILY_IDS,
|
|
9974
12552
|
RULE_FAMILY_MEMBERS,
|
|
@@ -9977,12 +12555,27 @@ export {
|
|
|
9977
12555
|
SEVERITY_RANK,
|
|
9978
12556
|
SEVERITY_WEIGHTS,
|
|
9979
12557
|
agentErrorEnvelopeSchema,
|
|
12558
|
+
agentFeatureContextV1Schema2 as agentFeatureContextV1Schema,
|
|
9980
12559
|
agentFormatSchema,
|
|
9981
12560
|
agentIntegritySchema,
|
|
9982
12561
|
agentOutputSchema,
|
|
9983
12562
|
aiMetadataSchema,
|
|
12563
|
+
analysisLimitsV1Schema,
|
|
12564
|
+
analysisObligationsDigestV1,
|
|
12565
|
+
analysisPlanDigestV1,
|
|
12566
|
+
analysisPlanIdFromDigest,
|
|
12567
|
+
analysisPlanIdSchema,
|
|
12568
|
+
analysisPlanIdStringSchema,
|
|
12569
|
+
analysisPlanInputV1Schema,
|
|
12570
|
+
analysisPlanV1Schema,
|
|
12571
|
+
analysisRegionV1Schema,
|
|
9984
12572
|
analyzeComposition,
|
|
12573
|
+
approvedFeatureManifestInputV1Schema,
|
|
12574
|
+
approvedFeatureManifestRevisionDigestV1,
|
|
12575
|
+
approvedFeatureManifestV1Schema,
|
|
12576
|
+
artifactContentHash,
|
|
9985
12577
|
asComponentId,
|
|
12578
|
+
assembleRegistryArtifact,
|
|
9986
12579
|
assertPortableRegistryPath,
|
|
9987
12580
|
assertValidRegistryArtifact,
|
|
9988
12581
|
authorOwnedImport,
|
|
@@ -9991,11 +12584,15 @@ export {
|
|
|
9991
12584
|
bridgeSourceViolations,
|
|
9992
12585
|
budgetBar,
|
|
9993
12586
|
buildAgentFormat,
|
|
12587
|
+
buildAnalysisPlanV1,
|
|
12588
|
+
buildApprovedFeatureManifestV1,
|
|
9994
12589
|
buildComponentKey,
|
|
12590
|
+
buildFeatureProposalV1,
|
|
9995
12591
|
buildRegistryArtifact,
|
|
9996
12592
|
buildRegistryFile,
|
|
9997
12593
|
buildRegistryInstallPlan,
|
|
9998
12594
|
buildRegistryInstallReceipt,
|
|
12595
|
+
buildRegistryPointer,
|
|
9999
12596
|
buildSpacingTokenLookup,
|
|
10000
12597
|
bundleArtifactMetadataSchema,
|
|
10001
12598
|
bundleComponentShardSchema,
|
|
@@ -10013,14 +12610,18 @@ export {
|
|
|
10013
12610
|
canonicalBridgeIdentitySources,
|
|
10014
12611
|
canonicalBridgeV1Schema,
|
|
10015
12612
|
canonicalDirectionConflictsTarget,
|
|
12613
|
+
canonicalFactConflictV1Schema,
|
|
12614
|
+
canonicalFactConflictValueV1Schema,
|
|
12615
|
+
canonicalFactIntegrityV1Schema,
|
|
10016
12616
|
canonicalJson,
|
|
10017
12617
|
canonicalPreimage,
|
|
10018
12618
|
canonicalizeOwnedComponentId,
|
|
10019
12619
|
canonicalizeOwnedImport,
|
|
12620
|
+
capConfiguredSeverity,
|
|
12621
|
+
capabilityGapV1Schema,
|
|
10020
12622
|
catalogFixtureA,
|
|
10021
12623
|
catalogFixtureAContractPayload,
|
|
10022
12624
|
catalogFixtureATokensDtcg,
|
|
10023
|
-
checkStoryExclusion,
|
|
10024
12625
|
clampMaxPasses,
|
|
10025
12626
|
classifyComplexity,
|
|
10026
12627
|
classifyIdentity,
|
|
@@ -10040,45 +12641,79 @@ export {
|
|
|
10040
12641
|
compileEffectiveGovernanceInputs,
|
|
10041
12642
|
compileFragment,
|
|
10042
12643
|
compileGlobalGovernanceFacts,
|
|
10043
|
-
compileRecipe,
|
|
10044
12644
|
componentContractSchema,
|
|
10045
12645
|
componentGovernanceRecordSchema,
|
|
10046
12646
|
componentGovernanceRecordsSchema,
|
|
10047
12647
|
componentId,
|
|
10048
12648
|
componentRelationSchema,
|
|
12649
|
+
componentUseDecisionV1Schema,
|
|
10049
12650
|
compositionAuthoringEntrySchema,
|
|
10050
12651
|
compositionMetadataSchema,
|
|
10051
12652
|
compositionPatternSchema,
|
|
10052
12653
|
computeRegistryHash,
|
|
10053
12654
|
configDeclarationForDiagnostics,
|
|
10054
12655
|
configRecordShape,
|
|
12656
|
+
configuredFindingSeverity,
|
|
10055
12657
|
containsTailwindV4Theme,
|
|
10056
12658
|
contractComponentsFromFragments,
|
|
10057
12659
|
contractHash,
|
|
10058
12660
|
contractPolicyFromGovernanceConfig,
|
|
10059
12661
|
contractTierRuleIds,
|
|
10060
12662
|
contractTokenReferenceCensus,
|
|
12663
|
+
coverageArtifactDigestV1,
|
|
12664
|
+
coverageRegionV1Schema,
|
|
12665
|
+
coverageStateV1Schema,
|
|
12666
|
+
coverageSummaryV1Schema,
|
|
10061
12667
|
customerDefaultRuleStates,
|
|
12668
|
+
decisionRequestV1Schema,
|
|
12669
|
+
decisionResolutionV1Schema,
|
|
12670
|
+
defaultRegistryShardPath,
|
|
10062
12671
|
defineBlock,
|
|
10063
12672
|
defineConfig,
|
|
10064
12673
|
defineFragment,
|
|
10065
|
-
|
|
12674
|
+
deriveArtifactId,
|
|
12675
|
+
deriveCoverageSummaryV1,
|
|
10066
12676
|
describePolicyExclude,
|
|
10067
12677
|
detectOrphanGovernanceScales,
|
|
10068
|
-
detectSubComponentPaths,
|
|
10069
12678
|
detectUnconsumedConfigKeys,
|
|
10070
12679
|
detectUnmatchedPolicyExcludes,
|
|
10071
12680
|
diffContractDomains,
|
|
12681
|
+
digestHexSchema,
|
|
12682
|
+
digestHexStringSchema,
|
|
10072
12683
|
discoverComponents,
|
|
10073
12684
|
dtcgTokenFileSchema,
|
|
12685
|
+
effectiveEvaluationWaiverV2Schema,
|
|
10074
12686
|
emptyConformResult,
|
|
12687
|
+
emptyVocabularyConfigFile,
|
|
12688
|
+
evaluate2 as evaluate,
|
|
10075
12689
|
evaluateGovernanceIntegrity,
|
|
12690
|
+
evaluationInputV2Schema,
|
|
12691
|
+
evaluationReceiptDigestV1,
|
|
12692
|
+
evaluationReceiptIdFromDigest,
|
|
12693
|
+
evaluationReceiptIdSchema,
|
|
12694
|
+
evaluationReceiptIdStringSchema,
|
|
12695
|
+
evaluationReceiptMintInputV1Schema,
|
|
12696
|
+
evaluationReceiptV1Schema,
|
|
12697
|
+
evaluationResultV2Schema,
|
|
12698
|
+
evidenceRefV1Schema,
|
|
10076
12699
|
excludeGlobToRegExp,
|
|
12700
|
+
expandRegistryComponentClosure,
|
|
10077
12701
|
explainUrlForCode,
|
|
10078
12702
|
factEvidenceSchema,
|
|
10079
12703
|
factId,
|
|
10080
12704
|
factLocationSchema,
|
|
10081
12705
|
familyDistance,
|
|
12706
|
+
featureAcceptanceItemV1Schema,
|
|
12707
|
+
featurePinsV1Schema,
|
|
12708
|
+
featurePlanIdFromEntropy,
|
|
12709
|
+
featurePlanIdSchema,
|
|
12710
|
+
featurePlanIdStringSchema,
|
|
12711
|
+
featureProposalInputV1Schema,
|
|
12712
|
+
featureProposalRevisionDigestV1,
|
|
12713
|
+
featureProposalV1Schema,
|
|
12714
|
+
featureRevisionIdFromDigest,
|
|
12715
|
+
featureRevisionIdSchema,
|
|
12716
|
+
featureRevisionIdStringSchema,
|
|
10082
12717
|
figma,
|
|
10083
12718
|
figmaPropMappingSchema,
|
|
10084
12719
|
finalizeRegistryManifest,
|
|
@@ -10095,18 +12730,35 @@ export {
|
|
|
10095
12730
|
formatStampPin,
|
|
10096
12731
|
formatStampVersionHash,
|
|
10097
12732
|
formatTokenSummary,
|
|
12733
|
+
fragmentAnnotationsV3Schema,
|
|
10098
12734
|
fragmentBanSchema,
|
|
10099
12735
|
fragmentContractSchema,
|
|
10100
12736
|
fragmentDefinitionSchema,
|
|
10101
12737
|
fragmentDefinitionV2Schema,
|
|
12738
|
+
fragmentDefinitionV3BodySchema,
|
|
12739
|
+
fragmentDefinitionV3Schema,
|
|
12740
|
+
fragmentDesignV3Schema,
|
|
12741
|
+
fragmentDontExampleV3Schema,
|
|
10102
12742
|
fragmentGeneratedSchema,
|
|
12743
|
+
fragmentGuidanceV3Schema,
|
|
12744
|
+
fragmentMatrixV3Schema,
|
|
10103
12745
|
fragmentMetaSchema,
|
|
12746
|
+
fragmentMetaV3Schema,
|
|
12747
|
+
fragmentPreviewV3Schema,
|
|
10104
12748
|
fragmentProvenanceSchema,
|
|
12749
|
+
fragmentSourceValues,
|
|
12750
|
+
fragmentStateV3Schema,
|
|
10105
12751
|
fragmentUsageSchema,
|
|
10106
12752
|
fragmentVariantSchema,
|
|
10107
12753
|
fragmentsConfigSchema,
|
|
12754
|
+
fragmentsManifestFcid,
|
|
12755
|
+
fragmentsManifestGrammarSchema,
|
|
12756
|
+
fragmentsManifestPatternSchema,
|
|
12757
|
+
fragmentsManifestPrimitiveSchema,
|
|
12758
|
+
fragmentsManifestSchema,
|
|
10108
12759
|
fragmentsPresetRuleStates,
|
|
10109
12760
|
g,
|
|
12761
|
+
gapDispositionV1Schema,
|
|
10110
12762
|
gatesCi,
|
|
10111
12763
|
generateCSSCustomProperties,
|
|
10112
12764
|
generateContext,
|
|
@@ -10133,7 +12785,6 @@ export {
|
|
|
10133
12785
|
inferTokenGroup,
|
|
10134
12786
|
isColorLike,
|
|
10135
12787
|
isCompositionPattern,
|
|
10136
|
-
isConfigExcluded,
|
|
10137
12788
|
isContractFile,
|
|
10138
12789
|
isContractTierRule,
|
|
10139
12790
|
isDTCGFile,
|
|
@@ -10141,12 +12792,13 @@ export {
|
|
|
10141
12792
|
isEffectiveCanonicalSource,
|
|
10142
12793
|
isEnforceableHtmlEquivalent,
|
|
10143
12794
|
isFigmaPropMapping,
|
|
10144
|
-
isForceIncluded,
|
|
10145
12795
|
isPortableRepoPath,
|
|
10146
12796
|
isPresetSourcedRule,
|
|
10147
12797
|
isRawHtmlAdvisoryTier,
|
|
10148
12798
|
isReactComponent,
|
|
10149
12799
|
isRuleFamilyId,
|
|
12800
|
+
layoutConcernV1Schema,
|
|
12801
|
+
layoutOwnershipV1Schema,
|
|
10150
12802
|
localCanonicalContractMappings,
|
|
10151
12803
|
lowerCompositionContract,
|
|
10152
12804
|
makeA11yNameRequiredFact,
|
|
@@ -10214,15 +12866,21 @@ export {
|
|
|
10214
12866
|
mcpSourceTypeSchema,
|
|
10215
12867
|
mcpTokenDataSchema,
|
|
10216
12868
|
mcpTokenSchema,
|
|
12869
|
+
mintEvaluationReceiptId,
|
|
10217
12870
|
nearestByDeltaE,
|
|
10218
12871
|
nearestSignedScaleValue,
|
|
12872
|
+
normalizeAnalysisPlanInputV1,
|
|
12873
|
+
normalizeApprovedFeatureManifestInputV1,
|
|
12874
|
+
normalizeCanonicalFactIntegrityV1,
|
|
10219
12875
|
normalizeColor,
|
|
10220
12876
|
normalizeConfigPath,
|
|
10221
12877
|
normalizeExcludePath,
|
|
12878
|
+
normalizeFeatureProposalInputV1,
|
|
10222
12879
|
normalizeFinding,
|
|
10223
12880
|
normalizeGovernanceConfig,
|
|
10224
12881
|
normalizePolicyExcludes,
|
|
10225
12882
|
normalizeRegistryRepoPath,
|
|
12883
|
+
normalizeRepositoryBindingKeyV1,
|
|
10226
12884
|
normalizeSeverity,
|
|
10227
12885
|
normalizeStyleValue,
|
|
10228
12886
|
normalizeToV1,
|
|
@@ -10231,6 +12889,10 @@ export {
|
|
|
10231
12889
|
normalizeViolation,
|
|
10232
12890
|
overriddenRecordSeverityDiagnostic,
|
|
10233
12891
|
ownedImportEquivalents,
|
|
12892
|
+
parseAgentFeatureContextV1,
|
|
12893
|
+
parseAnalysisPlanId,
|
|
12894
|
+
parseAnalysisPlanV1,
|
|
12895
|
+
parseApprovedFeatureManifestV1,
|
|
10234
12896
|
parseColor,
|
|
10235
12897
|
parseColorToRgb,
|
|
10236
12898
|
parseCompiledFragmentsFile,
|
|
@@ -10239,25 +12901,39 @@ export {
|
|
|
10239
12901
|
parseCssTokens,
|
|
10240
12902
|
parseDtcgTokens as parseDTCGFile,
|
|
10241
12903
|
parseDesignTokenContent,
|
|
12904
|
+
parseDigestHex,
|
|
10242
12905
|
parseDtcgTokens,
|
|
12906
|
+
parseEvaluationReceiptId,
|
|
12907
|
+
parseEvaluationReceiptV1,
|
|
12908
|
+
parseFeaturePlanId,
|
|
12909
|
+
parseFeatureProposalV1,
|
|
12910
|
+
parseFeatureRevisionId,
|
|
12911
|
+
parseFragmentsManifest,
|
|
10243
12912
|
parseRgb,
|
|
10244
12913
|
parseScssTokens,
|
|
10245
12914
|
parseScssVariables,
|
|
10246
12915
|
parseTailwindV4Theme,
|
|
10247
12916
|
parseTokenFile,
|
|
10248
12917
|
parseTokens,
|
|
12918
|
+
patternStatusV1Schema,
|
|
12919
|
+
patternUseDecisionV1Schema,
|
|
12920
|
+
placementDecisionV1Schema,
|
|
10249
12921
|
policyExcludeMatchesPath,
|
|
10250
12922
|
policyExcludeSchema,
|
|
10251
12923
|
portableRepoPathError,
|
|
10252
12924
|
projectCanonicalDirectionConflicts,
|
|
10253
12925
|
projectContractPreimage,
|
|
12926
|
+
projectEnforcementContract,
|
|
10254
12927
|
projectSupersededImportPathPreferences,
|
|
10255
12928
|
projectV1OwnedComponentId,
|
|
10256
12929
|
projectV1OwnedImportIdentity,
|
|
12930
|
+
propAnnotationSchema,
|
|
10257
12931
|
propDefinitionSchema,
|
|
10258
12932
|
proveCompliant,
|
|
10259
12933
|
proveIssueCount,
|
|
10260
|
-
|
|
12934
|
+
providerProofDigestV1,
|
|
12935
|
+
providerProofV1Schema,
|
|
12936
|
+
readRuleConfig,
|
|
10261
12937
|
registryArtifactDigest,
|
|
10262
12938
|
registryArtifactSchema,
|
|
10263
12939
|
registryComponentExportSchema,
|
|
@@ -10269,25 +12945,39 @@ export {
|
|
|
10269
12945
|
registryFileRoleSchema,
|
|
10270
12946
|
registryFileSchema,
|
|
10271
12947
|
registryFileSize,
|
|
12948
|
+
registryIndexSchema,
|
|
10272
12949
|
registryInstallProfileSchema,
|
|
10273
12950
|
registryInstallReceiptComponentSchema,
|
|
10274
12951
|
registryInstallReceiptFileSchema,
|
|
10275
12952
|
registryInstallReceiptSchema,
|
|
10276
12953
|
registryManifestCanonicalPreimage,
|
|
10277
12954
|
registryManifestDraftSchema,
|
|
12955
|
+
registryManifestFileMetadata,
|
|
12956
|
+
registryManifestFilePaths,
|
|
10278
12957
|
registryManifestSchema,
|
|
12958
|
+
registryPointerSchema,
|
|
12959
|
+
registryShardSchema,
|
|
12960
|
+
registryShardsForPaths,
|
|
10279
12961
|
registrySourceSchema,
|
|
12962
|
+
repositoryBindingDigestV1,
|
|
12963
|
+
repositoryBindingKeyV1Schema,
|
|
10280
12964
|
resolveArea,
|
|
10281
12965
|
resolveCanonicalForAriaRole,
|
|
10282
12966
|
resolveCanonicalForRawHtml,
|
|
12967
|
+
resolveComponentGovernance,
|
|
10283
12968
|
resolveConfiguredAppPath,
|
|
10284
12969
|
resolveDesignTokenValue,
|
|
10285
12970
|
resolveFigmaMapping,
|
|
12971
|
+
resolveGovernanceRecordsForIdentity,
|
|
10286
12972
|
resolveOwnedPackageImport,
|
|
10287
12973
|
resolvePerformanceConfig,
|
|
10288
12974
|
resolveProveVerdict,
|
|
12975
|
+
resolveRegistryComponentId,
|
|
12976
|
+
resolveRegistryInstallSelection,
|
|
12977
|
+
resolveRegistryInstallSources,
|
|
10289
12978
|
resolveSpacingValue,
|
|
10290
12979
|
resolveTokenValue,
|
|
12980
|
+
responsiveDecisionV1Schema,
|
|
10291
12981
|
rgbToHex,
|
|
10292
12982
|
ruleA11yRequiredAccessibleName,
|
|
10293
12983
|
ruleA11yStandard,
|
|
@@ -10313,16 +13003,18 @@ export {
|
|
|
10313
13003
|
ruleTokensRequireDualFallback,
|
|
10314
13004
|
runRules,
|
|
10315
13005
|
scaleGovernanceRecordSchema,
|
|
10316
|
-
|
|
13006
|
+
scenarioRequirementV1Schema,
|
|
10317
13007
|
serializeContractStamp,
|
|
10318
13008
|
severityLevel,
|
|
10319
13009
|
severitySchema,
|
|
10320
13010
|
sha256Hex,
|
|
13011
|
+
shardRegistryArtifact,
|
|
10321
13012
|
sortBySeverity,
|
|
10322
13013
|
sourceToRegistryTargetPath,
|
|
10323
13014
|
suppressionDirectiveSchema,
|
|
10324
13015
|
tierFor,
|
|
10325
13016
|
tokenIncludesFromConfig,
|
|
13017
|
+
tokenUseDecisionV1Schema,
|
|
10326
13018
|
topologyBase,
|
|
10327
13019
|
validatorResultSchema,
|
|
10328
13020
|
verifiedContractPreimageFromPin,
|