@usefragments/core 1.10.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-MZ4SW3TP.js → chunk-3IOWHECM.js} +8 -1
- package/dist/{chunk-MZ4SW3TP.js.map → chunk-3IOWHECM.js.map} +1 -1
- package/dist/chunk-7ULGH74M.js +66 -0
- package/dist/chunk-7ULGH74M.js.map +1 -0
- package/dist/{chunk-XN3LSDPY.js → chunk-BMPYIUZE.js} +612 -344
- package/dist/chunk-BMPYIUZE.js.map +1 -0
- package/dist/{chunk-YF65VYRY.js → chunk-ML5S6QNU.js} +191 -169
- package/dist/chunk-ML5S6QNU.js.map +1 -0
- package/dist/{chunk-3LLRNCPX.js → chunk-MZ2FS7U4.js} +1 -1
- package/dist/chunk-MZ2FS7U4.js.map +1 -0
- package/dist/chunk-PWIJMOI4.js +202 -0
- package/dist/chunk-PWIJMOI4.js.map +1 -0
- package/dist/chunk-RYFULE43.js +578 -0
- package/dist/chunk-RYFULE43.js.map +1 -0
- package/dist/codes/index.d.ts +2 -2
- package/dist/codes/index.js +3 -2
- package/dist/compiled-types/index.d.ts +327 -2
- package/dist/compiled-types/index.js +1 -1
- package/dist/generate/index.d.ts +3 -2
- package/dist/{governance-CLk_wkP9.d.ts → governance-hOPXGbbs.d.ts} +474 -515
- package/dist/governance-telemetry.d.ts +6 -0
- package/dist/governance-telemetry.js +1 -1
- package/dist/{index-_sxhUNqx.d.ts → index-C8bcXVav.d.ts} +448 -448
- package/dist/index.d.ts +3280 -1305
- package/dist/index.js +2414 -350
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +228 -0
- package/dist/manifest.js +24 -0
- package/dist/manifest.js.map +1 -0
- package/dist/preview/index.js +45 -1
- package/dist/preview/index.js.map +1 -1
- package/dist/preview-runtime.d.ts +1 -2
- package/dist/preview-runtime.js +150 -14
- package/dist/preview-runtime.js.map +1 -1
- package/dist/react-types.d.ts +1 -2
- package/dist/registry.d.ts +1412 -203
- package/dist/registry.js +30 -3
- package/dist/schemas/index.d.ts +1 -1
- package/dist/schemas/index.js +3 -2
- package/dist/storyAdapter.d.ts +1 -2
- package/dist/storyAdapter.js +11 -49
- package/dist/storyAdapter.js.map +1 -1
- package/dist/test-utils.d.ts +3 -2
- package/dist/topology/index.d.ts +1 -1
- package/dist/topology/index.js +1 -1
- package/package.json +8 -2
- package/src/__tests__/contract-parser.test.ts +318 -277
- package/src/__tests__/preview-runtime-hook.test.tsx +315 -0
- package/src/__tests__/preview-runtime.test.tsx +30 -8
- package/src/__tests__/schema.test.ts +191 -14
- package/src/analysis-plan/analysis-plan-v1.test.ts +320 -0
- package/src/analysis-plan/coverage.ts +181 -0
- package/src/analysis-plan/digest.ts +141 -0
- package/src/analysis-plan/index.ts +34 -0
- package/src/analysis-plan/types.ts +207 -0
- package/src/approved-contract-tokens.test.ts +39 -0
- package/src/approved-contract-tokens.ts +18 -0
- package/src/codes/__tests__/codes.test.ts +13 -0
- package/src/codes/codes.ts +40 -0
- package/src/compiled-types/index.ts +640 -39
- package/src/compiled-types/parse.test.ts +145 -4
- package/src/component-contract.ts +95 -53
- package/src/composition.ts +7 -13
- package/src/constants.ts +3 -6
- package/src/contract/hash.test.ts +20 -0
- package/src/contract/hash.ts +66 -9
- package/src/contract/index.ts +24 -1
- package/src/contract/manifest.test.ts +94 -0
- package/src/contract/manifest.ts +68 -0
- package/src/contract/preimage.test.ts +219 -1
- package/src/contract/preimage.ts +326 -6
- package/src/contract/stamp.test.ts +3 -0
- package/src/contract/stamp.ts +1 -1
- package/src/contract-parser.ts +54 -30
- package/src/defineFragment.test.ts +476 -91
- package/src/defineFragment.ts +204 -114
- package/src/domain-ids.test.ts +35 -0
- package/src/domain-ids.ts +61 -0
- package/src/evaluation/evaluate.test.ts +522 -0
- package/src/evaluation/evaluate.ts +690 -0
- package/src/evaluation/evaluation-v2-receipt-v1.test.ts +772 -0
- package/src/evaluation/index.ts +58 -0
- package/src/evaluation/receipt.ts +753 -0
- package/src/evaluation/types.ts +406 -0
- package/src/facts/builders.ts +2 -0
- package/src/facts/compile.ts +29 -6
- package/src/facts/fact-index.ts +13 -3
- package/src/facts/fact-integrity-v1.test.ts +172 -0
- package/src/facts/facts.test.ts +15 -0
- package/src/facts/ids.ts +46 -3
- package/src/facts/index.ts +14 -1
- package/src/facts/integrity.ts +134 -0
- package/src/facts/types.ts +36 -0
- package/src/governance-integrity.test.ts +1 -0
- package/src/governance-integrity.ts +5 -3
- package/src/governance-telemetry.ts +8 -0
- package/src/governance.ts +70 -8
- package/src/index.ts +230 -37
- package/src/preview/validation.test.ts +62 -0
- package/src/preview/validation.ts +48 -2
- package/src/preview-runtime.tsx +227 -20
- package/src/registry-install-plan.ts +200 -109
- package/src/registry-shards.test.ts +263 -0
- package/src/registry.ts +237 -0
- package/src/repository-binding.test.ts +50 -0
- package/src/repository-binding.ts +96 -0
- package/src/rules/families.test.ts +36 -0
- package/src/rules/finding.ts +7 -2
- package/src/rules/index.ts +17 -1
- package/src/rules/rule-config.test.ts +66 -0
- package/src/rules/rule-config.ts +73 -0
- package/src/rules/rules.test.ts +26 -0
- package/src/rules/tokens-css-vars-must-be-defined.test.ts +51 -2
- package/src/rules/tokens-css-vars-must-be-defined.ts +34 -1
- package/src/schema.ts +293 -113
- package/src/schemas/index.ts +1 -1
- package/src/storyAdapter.test.ts +68 -12
- package/src/storyAdapter.ts +44 -75
- package/src/topology/resolve-area.ts +1 -1
- package/src/types.ts +258 -40
- package/dist/chunk-3LLRNCPX.js.map +0 -1
- package/dist/chunk-RANPUC6C.js +0 -72
- package/dist/chunk-RANPUC6C.js.map +0 -1
- package/dist/chunk-XN3LSDPY.js.map +0 -1
- package/dist/chunk-YF65VYRY.js.map +0 -1
- package/src/fragment-types.ts +0 -214
- package/src/react-create-element.test.ts +0 -22
- package/src/react-create-element.ts +0 -12
- package/src/storyFilters.test.ts +0 -350
- package/src/storyFilters.ts +0 -253
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import {
|
|
3
|
+
analysisPlanIdStringSchema,
|
|
4
|
+
digestHexStringSchema,
|
|
5
|
+
type AnalysisPlanId,
|
|
6
|
+
type DigestHex,
|
|
7
|
+
} from "../domain-ids.js";
|
|
8
|
+
import {
|
|
9
|
+
repositoryBindingKeyV1Schema,
|
|
10
|
+
type RepositoryBindingKeyV1,
|
|
11
|
+
} from "../repository-binding.js";
|
|
12
|
+
|
|
13
|
+
export const ANALYSIS_PLAN_MAX_REGIONS_V1 = 1_000;
|
|
14
|
+
export const ANALYSIS_PLAN_MAX_CAPABILITIES_V1 = 256;
|
|
15
|
+
export const ANALYSIS_PLAN_MAX_DIALECTS_PER_REGION_V1 = 64;
|
|
16
|
+
|
|
17
|
+
export const ANALYSIS_LIMIT_CEILINGS_V1 = {
|
|
18
|
+
maxSourceFiles: 100_000,
|
|
19
|
+
maxSourceBytes: 1_073_741_824,
|
|
20
|
+
maxFileBytes: 10_485_760,
|
|
21
|
+
maxFacts: 1_000_000,
|
|
22
|
+
maxRegions: ANALYSIS_PLAN_MAX_REGIONS_V1,
|
|
23
|
+
maxDiagnostics: 100_000,
|
|
24
|
+
maxDurationMs: 900_000,
|
|
25
|
+
} as const;
|
|
26
|
+
|
|
27
|
+
const bounded = (max: number) => z.string().min(1).max(max);
|
|
28
|
+
const positiveBoundedInteger = (max: number) => z.number().int().positive().max(max);
|
|
29
|
+
const uniqueStrings = (values: readonly string[]): boolean =>
|
|
30
|
+
new Set(values).size === values.length;
|
|
31
|
+
|
|
32
|
+
export const coverageStateV1Schema = z.enum([
|
|
33
|
+
"analyzed",
|
|
34
|
+
"unsupported",
|
|
35
|
+
"excluded_by_contract",
|
|
36
|
+
"skipped_limit",
|
|
37
|
+
"failed",
|
|
38
|
+
]);
|
|
39
|
+
export type CoverageStateV1 = z.infer<typeof coverageStateV1Schema>;
|
|
40
|
+
|
|
41
|
+
export const analysisLimitsV1Schema = z
|
|
42
|
+
.object({
|
|
43
|
+
maxSourceFiles: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxSourceFiles),
|
|
44
|
+
maxSourceBytes: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxSourceBytes),
|
|
45
|
+
maxFileBytes: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxFileBytes),
|
|
46
|
+
maxFacts: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxFacts),
|
|
47
|
+
maxRegions: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxRegions),
|
|
48
|
+
maxDiagnostics: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxDiagnostics),
|
|
49
|
+
maxDurationMs: positiveBoundedInteger(ANALYSIS_LIMIT_CEILINGS_V1.maxDurationMs),
|
|
50
|
+
})
|
|
51
|
+
.strict();
|
|
52
|
+
export type AnalysisLimitsV1 = z.infer<typeof analysisLimitsV1Schema>;
|
|
53
|
+
|
|
54
|
+
export const analysisRegionV1Schema = z
|
|
55
|
+
.object({
|
|
56
|
+
regionId: bounded(256),
|
|
57
|
+
pathPattern: bounded(4_096),
|
|
58
|
+
kind: z.enum(["component_source", "style_source", "token_source", "config"]),
|
|
59
|
+
language: bounded(64),
|
|
60
|
+
required: z.boolean(),
|
|
61
|
+
requiredDialects: z
|
|
62
|
+
.array(bounded(128))
|
|
63
|
+
.max(ANALYSIS_PLAN_MAX_DIALECTS_PER_REGION_V1)
|
|
64
|
+
.refine(uniqueStrings, "requiredDialects must be unique"),
|
|
65
|
+
analyzer: z
|
|
66
|
+
.object({
|
|
67
|
+
id: bounded(256),
|
|
68
|
+
interfaceVersion: bounded(128),
|
|
69
|
+
implementationVersion: bounded(128),
|
|
70
|
+
})
|
|
71
|
+
.strict(),
|
|
72
|
+
})
|
|
73
|
+
.strict();
|
|
74
|
+
export type AnalysisRegionV1 = z.infer<typeof analysisRegionV1Schema>;
|
|
75
|
+
|
|
76
|
+
export const coverageRegionV1Schema = z
|
|
77
|
+
.object({
|
|
78
|
+
regionId: bounded(256),
|
|
79
|
+
state: coverageStateV1Schema,
|
|
80
|
+
fileCount: z.number().int().nonnegative().max(ANALYSIS_LIMIT_CEILINGS_V1.maxSourceFiles),
|
|
81
|
+
byteCount: z.number().int().nonnegative().max(ANALYSIS_LIMIT_CEILINGS_V1.maxSourceBytes),
|
|
82
|
+
diagnosticIds: z
|
|
83
|
+
.array(bounded(256))
|
|
84
|
+
.max(ANALYSIS_LIMIT_CEILINGS_V1.maxDiagnostics)
|
|
85
|
+
.refine(uniqueStrings, "diagnosticIds must be unique"),
|
|
86
|
+
})
|
|
87
|
+
.strict();
|
|
88
|
+
export type CoverageRegionV1 = z.infer<typeof coverageRegionV1Schema>;
|
|
89
|
+
|
|
90
|
+
const coverageCountsV1Schema = z
|
|
91
|
+
.object({
|
|
92
|
+
analyzed: z.number().int().nonnegative(),
|
|
93
|
+
unsupported: z.number().int().nonnegative(),
|
|
94
|
+
excluded_by_contract: z.number().int().nonnegative(),
|
|
95
|
+
skipped_limit: z.number().int().nonnegative(),
|
|
96
|
+
failed: z.number().int().nonnegative(),
|
|
97
|
+
})
|
|
98
|
+
.strict();
|
|
99
|
+
|
|
100
|
+
export const coverageSummaryV1Schema = z
|
|
101
|
+
.object({
|
|
102
|
+
plannedRegions: z.number().int().nonnegative(),
|
|
103
|
+
observedRegions: z.number().int().nonnegative(),
|
|
104
|
+
requiredRegions: z.number().int().nonnegative(),
|
|
105
|
+
requiredByState: coverageCountsV1Schema,
|
|
106
|
+
optionalByState: coverageCountsV1Schema,
|
|
107
|
+
eligibleFiles: z.number().int().nonnegative(),
|
|
108
|
+
analyzedFiles: z.number().int().nonnegative(),
|
|
109
|
+
analyzedBytes: z.number().int().nonnegative(),
|
|
110
|
+
})
|
|
111
|
+
.strict();
|
|
112
|
+
export type CoverageSummaryV1 = z.infer<typeof coverageSummaryV1Schema>;
|
|
113
|
+
|
|
114
|
+
const analysisPlanBaseShape = {
|
|
115
|
+
binding: repositoryBindingKeyV1Schema,
|
|
116
|
+
source: z
|
|
117
|
+
.object({
|
|
118
|
+
commitId: bounded(256),
|
|
119
|
+
treeId: bounded(256).optional(),
|
|
120
|
+
defaultBranch: bounded(256),
|
|
121
|
+
acquiredBy: z.enum(["github_app", "local_worktree", "ci_attested"]),
|
|
122
|
+
})
|
|
123
|
+
.strict(),
|
|
124
|
+
contract: z
|
|
125
|
+
.object({
|
|
126
|
+
fcid: digestHexStringSchema,
|
|
127
|
+
artifactDigest: digestHexStringSchema,
|
|
128
|
+
})
|
|
129
|
+
.strict(),
|
|
130
|
+
config: z
|
|
131
|
+
.object({
|
|
132
|
+
path: bounded(4_096).refine(
|
|
133
|
+
(value) =>
|
|
134
|
+
!value.startsWith("/") && !value.includes("\\") && !value.split("/").includes(".."),
|
|
135
|
+
"config path must be a portable repository-relative path"
|
|
136
|
+
),
|
|
137
|
+
digest: digestHexStringSchema,
|
|
138
|
+
})
|
|
139
|
+
.strict(),
|
|
140
|
+
profile: z
|
|
141
|
+
.object({
|
|
142
|
+
id: z.literal("react-web-v1"),
|
|
143
|
+
version: bounded(128),
|
|
144
|
+
capabilities: z
|
|
145
|
+
.array(bounded(128))
|
|
146
|
+
.max(ANALYSIS_PLAN_MAX_CAPABILITIES_V1)
|
|
147
|
+
.refine(uniqueStrings, "capabilities must be unique"),
|
|
148
|
+
})
|
|
149
|
+
.strict(),
|
|
150
|
+
regions: z
|
|
151
|
+
.array(analysisRegionV1Schema)
|
|
152
|
+
.max(ANALYSIS_PLAN_MAX_REGIONS_V1)
|
|
153
|
+
.refine(
|
|
154
|
+
(regions) => new Set(regions.map((region) => region.regionId)).size === regions.length,
|
|
155
|
+
"regionId values must be unique"
|
|
156
|
+
),
|
|
157
|
+
limits: analysisLimitsV1Schema,
|
|
158
|
+
evaluatorVersion: bounded(128),
|
|
159
|
+
createdAt: z.string().datetime({ offset: true }),
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
function validatePlanLimits(
|
|
163
|
+
plan: { regions: readonly AnalysisRegionV1[]; limits: AnalysisLimitsV1 },
|
|
164
|
+
context: z.RefinementCtx
|
|
165
|
+
): void {
|
|
166
|
+
if (plan.regions.length > plan.limits.maxRegions) {
|
|
167
|
+
context.addIssue({
|
|
168
|
+
code: z.ZodIssueCode.custom,
|
|
169
|
+
path: ["regions"],
|
|
170
|
+
message: "Planned regions exceed the plan's maxRegions limit",
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
if (plan.limits.maxFileBytes > plan.limits.maxSourceBytes) {
|
|
174
|
+
context.addIssue({
|
|
175
|
+
code: z.ZodIssueCode.custom,
|
|
176
|
+
path: ["limits", "maxFileBytes"],
|
|
177
|
+
message: "maxFileBytes cannot exceed maxSourceBytes",
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export const analysisPlanInputV1Schema = z
|
|
183
|
+
.object(analysisPlanBaseShape)
|
|
184
|
+
.strict()
|
|
185
|
+
.superRefine(validatePlanLimits);
|
|
186
|
+
export type AnalysisPlanInputV1 = z.input<typeof analysisPlanInputV1Schema>;
|
|
187
|
+
|
|
188
|
+
export const analysisPlanV1Schema = z
|
|
189
|
+
.object({
|
|
190
|
+
schemaVersion: z.literal(1),
|
|
191
|
+
analysisPlanId: analysisPlanIdStringSchema,
|
|
192
|
+
...analysisPlanBaseShape,
|
|
193
|
+
obligationsDigest: digestHexStringSchema,
|
|
194
|
+
digest: digestHexStringSchema,
|
|
195
|
+
})
|
|
196
|
+
.strict()
|
|
197
|
+
.superRefine(validatePlanLimits);
|
|
198
|
+
|
|
199
|
+
export interface AnalysisPlanV1 extends Omit<
|
|
200
|
+
z.output<typeof analysisPlanV1Schema>,
|
|
201
|
+
"analysisPlanId" | "digest" | "obligationsDigest"
|
|
202
|
+
> {
|
|
203
|
+
analysisPlanId: AnalysisPlanId;
|
|
204
|
+
binding: RepositoryBindingKeyV1;
|
|
205
|
+
obligationsDigest: DigestHex;
|
|
206
|
+
digest: DigestHex;
|
|
207
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
APPROVED_CONTRACT_TOKEN_MAX_NAMES,
|
|
4
|
+
APPROVED_CONTRACT_TOKEN_MAX_NAME_LENGTH,
|
|
5
|
+
isApprovedContractTokenNames,
|
|
6
|
+
} from "./approved-contract-tokens.js";
|
|
7
|
+
import { parseComponentGovernancePolicyJson } from "./governance.js";
|
|
8
|
+
|
|
9
|
+
describe("approved token transport", () => {
|
|
10
|
+
it("distinguishes absent authority from an explicitly empty vocabulary", () => {
|
|
11
|
+
expect(isApprovedContractTokenNames(undefined)).toBe(false);
|
|
12
|
+
expect(isApprovedContractTokenNames(null)).toBe(false);
|
|
13
|
+
expect(isApprovedContractTokenNames([])).toBe(true);
|
|
14
|
+
expect(isApprovedContractTokenNames(["--approved"])).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
it("enforces the same bounded vocabulary on every consumer", () => {
|
|
17
|
+
expect(isApprovedContractTokenNames(Array(APPROVED_CONTRACT_TOKEN_MAX_NAMES).fill("--x"))).toBe(
|
|
18
|
+
true
|
|
19
|
+
);
|
|
20
|
+
expect(
|
|
21
|
+
isApprovedContractTokenNames(Array(APPROVED_CONTRACT_TOKEN_MAX_NAMES + 1).fill("--x"))
|
|
22
|
+
).toBe(false);
|
|
23
|
+
expect(
|
|
24
|
+
isApprovedContractTokenNames(["--" + "x".repeat(APPROVED_CONTRACT_TOKEN_MAX_NAME_LENGTH - 2)])
|
|
25
|
+
).toBe(true);
|
|
26
|
+
expect(
|
|
27
|
+
isApprovedContractTokenNames(["--" + "x".repeat(APPROVED_CONTRACT_TOKEN_MAX_NAME_LENGTH - 1)])
|
|
28
|
+
).toBe(false);
|
|
29
|
+
expect(isApprovedContractTokenNames(["--"])).toBe(false);
|
|
30
|
+
expect(isApprovedContractTokenNames(["local-token"])).toBe(false);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("normalizes supported policy envelopes without treating malformed authority as empty rules", () => {
|
|
35
|
+
for (const payload of ["[]", '{"governance":[]}', '{"rules":[]}'])
|
|
36
|
+
expect(parseComponentGovernancePolicyJson(payload)).toEqual([]);
|
|
37
|
+
for (const payload of ["null", "{}", "[{}]", "invalid", '{"governance":false}'])
|
|
38
|
+
expect(parseComponentGovernancePolicyJson(payload)).toBeNull();
|
|
39
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Portable bounds shared by contract authoring and first-party policy clients. */
|
|
2
|
+
export const APPROVED_CONTRACT_TOKEN_MAX_NAMES = 10_000;
|
|
3
|
+
export const APPROVED_CONTRACT_TOKEN_MAX_NAME_LENGTH = 512;
|
|
4
|
+
|
|
5
|
+
/** Empty is authored absence; missing is unavailable authority. */
|
|
6
|
+
export function isApprovedContractTokenNames(value: unknown): value is string[] {
|
|
7
|
+
return (
|
|
8
|
+
Array.isArray(value) &&
|
|
9
|
+
value.length <= APPROVED_CONTRACT_TOKEN_MAX_NAMES &&
|
|
10
|
+
value.every(
|
|
11
|
+
(name) =>
|
|
12
|
+
typeof name === "string" &&
|
|
13
|
+
name.startsWith("--") &&
|
|
14
|
+
name.length > 2 &&
|
|
15
|
+
name.length <= APPROVED_CONTRACT_TOKEN_MAX_NAME_LENGTH
|
|
16
|
+
)
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -24,6 +24,19 @@ const SUBSYSTEM_EMITTED_CODES = [
|
|
|
24
24
|
// sources are read before any rule runs, and an unreadable one aborts the
|
|
25
25
|
// scan rather than producing a finding.
|
|
26
26
|
"FUI9009",
|
|
27
|
+
// Emitted by the compiler, not the rule engine: a `.fragment` source whose
|
|
28
|
+
// definition fails Core's schema, or whose authored claims contradict the
|
|
29
|
+
// extracted component, is refused before any rule has a contract to run on.
|
|
30
|
+
"FUI9010",
|
|
31
|
+
"FUI9011",
|
|
32
|
+
// Emitted by Cloud's machine contract write path (CLI route + MCP tool) when
|
|
33
|
+
// the workspace plan does not include contract writes from machines; the CLI
|
|
34
|
+
// relays it. Not a rule.
|
|
35
|
+
"FUI9012",
|
|
36
|
+
// Emitted by tokens/css-vars-must-be-defined when the rule is active but the
|
|
37
|
+
// resolved contract vocabulary is empty — a config-level inert diagnostic,
|
|
38
|
+
// not a second rule id in RULES.
|
|
39
|
+
"FUI2018",
|
|
27
40
|
] as const;
|
|
28
41
|
|
|
29
42
|
const RESERVED_CODES = {
|
package/src/codes/codes.ts
CHANGED
|
@@ -273,6 +273,16 @@ export const CODES = [
|
|
|
273
273
|
lifecycle: "experimental",
|
|
274
274
|
evidenceRequired: true,
|
|
275
275
|
}),
|
|
276
|
+
code({
|
|
277
|
+
code: "FUI2018",
|
|
278
|
+
ruleId: "config/empty-token-vocabulary",
|
|
279
|
+
category: "system",
|
|
280
|
+
defaultSeverity: "serious",
|
|
281
|
+
title: "Token sources resolved to 0 tokens",
|
|
282
|
+
lifecycle: "experimental",
|
|
283
|
+
fixAvailable: false,
|
|
284
|
+
evidenceRequired: true,
|
|
285
|
+
}),
|
|
276
286
|
ruleCode({
|
|
277
287
|
code: "FUI3001",
|
|
278
288
|
ruleId: "a11y/required-accessible-name",
|
|
@@ -527,6 +537,36 @@ export const CODES = [
|
|
|
527
537
|
fixAvailable: false,
|
|
528
538
|
evidenceRequired: false,
|
|
529
539
|
}),
|
|
540
|
+
code({
|
|
541
|
+
code: "FUI9010",
|
|
542
|
+
ruleId: "fragment/invalid-definition",
|
|
543
|
+
category: "system",
|
|
544
|
+
defaultSeverity: "critical",
|
|
545
|
+
title: "Fragment definition is not valid",
|
|
546
|
+
lifecycle: "experimental",
|
|
547
|
+
fixAvailable: false,
|
|
548
|
+
evidenceRequired: false,
|
|
549
|
+
}),
|
|
550
|
+
code({
|
|
551
|
+
code: "FUI9011",
|
|
552
|
+
ruleId: "fragment/source-drift",
|
|
553
|
+
category: "system",
|
|
554
|
+
defaultSeverity: "critical",
|
|
555
|
+
title: "Fragment definition drifted from its component source",
|
|
556
|
+
lifecycle: "experimental",
|
|
557
|
+
fixAvailable: false,
|
|
558
|
+
evidenceRequired: false,
|
|
559
|
+
}),
|
|
560
|
+
code({
|
|
561
|
+
code: "FUI9012",
|
|
562
|
+
ruleId: "contract/write-not-entitled",
|
|
563
|
+
category: "system",
|
|
564
|
+
defaultSeverity: "critical",
|
|
565
|
+
title: "Contract write requires a paid workspace",
|
|
566
|
+
lifecycle: "experimental",
|
|
567
|
+
fixAvailable: false,
|
|
568
|
+
evidenceRequired: false,
|
|
569
|
+
}),
|
|
530
570
|
] as const satisfies readonly FuiCode[];
|
|
531
571
|
|
|
532
572
|
export const byCode: ReadonlyMap<string, FuiCode> = new Map(
|