@usefragments/core 1.10.2 → 1.11.0

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