@usefragments/core 1.10.2 → 2.0.0

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