-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathcatalog.mjs
More file actions
347 lines (328 loc) · 8.8 KB
/
Copy pathcatalog.mjs
File metadata and controls
347 lines (328 loc) · 8.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
// Copyright (c) Meta Platforms, Inc. and affiliates.
/**
* @file catalog.mjs
* @description The lab graduation rubric: the five lifecycle stages and the 31
* checks a lab component must pass before it can be promoted into
* `@astryxdesign/core`. This is the schema the Storybook readiness panel and
* `apps/storybook/.lab-readiness/latest.json` are built against.
* @input none — static data
* @output STAGE_DEFINITIONS, CHECK_CATALOG, SCHEMA_VERSION, REPORT_KIND, and
* lookup helpers
* @position Shared vocabulary for the readiness tooling. `automated.mjs`
* derives the checks it can prove from the repo; `manifest.mjs` declares the
* rest; `audit.mjs` merges and scores them against this catalog.
*
* A check belongs to exactly one stage and one section. Sections exist so the
* hardening stage can separate what a machine proved (`automatedAudit`) from
* what a person had to fix by hand (`objectiveFixes`) and from what only a
* person can sign off (`humanReview`).
*
* SYNC: When adding or renaming a check, bump SCHEMA_VERSION and update the
* Storybook readiness panel that reads the emitted report.
*/
export const SCHEMA_VERSION = 2;
export const REPORT_KIND = 'astryx-lab-readiness-report';
const SPEC_PROTOCOL =
'https://github.com/facebook/astryx/wiki/Component-Specification-Protocol';
const BUILD_PROTOCOL =
'https://github.com/facebook/astryx/wiki/Component-Build-Protocol';
const HARDEN_PROTOCOL =
'https://github.com/facebook/astryx/wiki/Component-Hardening-Protocol';
/** @typedef {'not_started' | 'in_progress' | 'passed' | 'blocked'} CheckState */
export const STAGE_DEFINITIONS = [
{key: 'research', label: 'Research'},
{key: 'spec', label: 'Spec'},
{key: 'build', label: 'Build'},
{key: 'hardenChecks', label: 'Harden checks'},
{key: 'hardenReview', label: 'Harden review'},
];
/**
* Terse per-stage metadata so a check entry only has to name its stage and
* section rather than repeat the labels and protocol URL.
*/
const STAGE_META = {
research: {
label: 'Research',
protocolUrl: SPEC_PROTOCOL,
sections: {research: 'Research'},
},
spec: {
label: 'Spec',
protocolUrl: SPEC_PROTOCOL,
sections: {spec: 'Specification'},
},
build: {
label: 'Build',
protocolUrl: BUILD_PROTOCOL,
sections: {build: 'Build'},
},
hardenChecks: {
label: 'Harden checks',
protocolUrl: HARDEN_PROTOCOL,
sections: {
automatedAudit: 'Automated audit',
objectiveFixes: 'Objective fixes',
},
},
hardenReview: {
label: 'Harden review',
protocolUrl: HARDEN_PROTOCOL,
sections: {humanReview: 'Human review'},
},
};
/**
* `[stageKey, sectionKey, key, label, description]`. Order is the order the
* readiness panel renders them in, and it is also lifecycle order.
*/
const CHECKS = [
[
'research',
'research',
'triage',
'Triage',
'A named owner has confirmed the problem and scope.',
],
[
'research',
'research',
'internalResearch',
'Internal research',
'Existing Astryx and internal patterns have been audited.',
],
[
'research',
'research',
'externalResearch',
'External research',
'Relevant design-system and web precedents have been compared.',
],
[
'research',
'research',
'useCases',
'Use cases',
'Primary use cases, non-goals, and constraints are documented.',
],
[
'spec',
'spec',
'draftSpec',
'Draft spec',
'An RFC describes the component contract and intended behavior.',
],
[
'spec',
'spec',
'surfaceAudit',
'Surface audit',
'Composition, naming, variants, states, and tokens are enumerated.',
],
[
'spec',
'spec',
'specReview',
'Spec review',
'Design and engineering reviewers have resolved blocking feedback.',
],
[
'spec',
'spec',
'apiArbitration',
'API arbitration',
'Competing APIs were evaluated when the choice was non-obvious.',
],
[
'spec',
'spec',
'finalizedSpec',
'Finalized spec',
'The accepted contract is recorded as the build baseline.',
],
[
'build',
'build',
'implementation',
'Implementation',
'The component implements the agreed public contract.',
],
[
'build',
'build',
'systemIntegration',
'System integration',
'Tokens, themes, composition, and shared primitives are integrated.',
],
[
'build',
'build',
'stories',
'Stories',
'Storybook demonstrates representative states and composition.',
],
[
'build',
'build',
'tests',
'Tests',
'Focused behavioral and contract tests cover the implementation.',
],
[
'build',
'build',
'documentation',
'Documentation',
'The public API, usage, and important constraints are documented.',
],
[
'build',
'build',
'reviewAndCI',
'Review and CI',
'Code review and required automated checks are complete.',
],
[
'build',
'build',
'mergedPR',
'Merged PR',
'The build is merged into the lab package.',
],
[
'hardenChecks',
'automatedAudit',
'tokensTheming',
'Tokens and theming',
'Token usage and theme integration pass the automated audit.',
],
[
'hardenChecks',
'automatedAudit',
'reuseNaming',
'Reuse and naming',
'Existing primitives are reused and public names follow conventions.',
],
[
'hardenChecks',
'automatedAudit',
'structureTypes',
'Structure and types',
'File structure, exports, and TypeScript contracts pass inspection.',
],
[
'hardenChecks',
'automatedAudit',
'accessibilityContracts',
'Accessibility contracts',
'Static and automated accessibility requirements pass.',
],
[
'hardenChecks',
'automatedAudit',
'exportsAuditCI',
'Exports and CI',
'Public exports, builds, tests, and required CI checks are green.',
],
[
'hardenChecks',
'objectiveFixes',
'stateCoverage',
'State coverage',
'All supported interaction and semantic states are covered.',
],
[
'hardenChecks',
'objectiveFixes',
'visualThemes',
'Visual themes',
'Light, dark, and nested-theme rendering is verified.',
],
[
'hardenChecks',
'objectiveFixes',
'keyboardAccessibility',
'Keyboard and accessibility',
'Keyboard, focus, semantics, naming, and contrast are verified.',
],
[
'hardenChecks',
'objectiveFixes',
'edgeCases',
'Edge cases',
'Empty, overflow, loading, disabled, and stress cases are resolved.',
],
[
'hardenChecks',
'objectiveFixes',
'storyCompleteness',
'Story completeness',
'Stories make the completed state and edge-case matrix reviewable.',
],
[
'hardenReview',
'humanReview',
'visualQuality',
'Visual quality',
'A human reviewer has approved polish and visual consistency.',
],
[
'hardenReview',
'humanReview',
'compositionQuality',
'Composition quality',
'Real compositions confirm the API works beyond isolated demos.',
],
[
'hardenReview',
'humanReview',
'scopeBoundary',
'Scope boundary',
'The component\u2019s responsibilities and non-goals remain coherent.',
],
[
'hardenReview',
'humanReview',
'responsiveInteractionReadiness',
'Responsive and Interaction Readiness',
'The reusable Responsive and Interaction Readiness rubric records Pass, Fail, or N/A with evidence for adaptive presentation choice, transient and queued UI, viewport obstruction and placement, input, gesture, mobile viewport, and WCAG 2.2 AA contracts.',
],
[
'hardenReview',
'humanReview',
'archivedReview',
'Archived review',
'The final checklist, decision, and follow-ups are linked.',
],
];
export const CHECK_CATALOG = CHECKS.map(
([stageKey, sectionKey, key, label, description]) => {
const stage = STAGE_META[stageKey];
return {
key,
label,
description,
stageKey,
stageLabel: stage.label,
sectionKey,
sectionLabel: stage.sections[sectionKey],
protocolUrl: stage.protocolUrl,
humanReview: stageKey === 'hardenReview',
};
},
);
const BY_KEY = new Map(CHECK_CATALOG.map(check => [check.key, check]));
/** Every check key, in lifecycle order. */
export const CHECK_KEYS = CHECK_CATALOG.map(check => check.key);
/** Check keys a human must sign off — no automation may propose these. */
export const HUMAN_REVIEW_KEYS = CHECK_CATALOG.filter(c => c.humanReview).map(
c => c.key,
);
/** @param {string} key */
export function getCheck(key) {
const check = BY_KEY.get(key);
if (!check) throw new Error(`Unknown readiness check: ${key}`);
return check;
}
/** A check counts toward a passing grade only in the `passed` state. */
export const PASSING_STATE = 'passed';
/** @type {readonly CheckState[]} */
export const CHECK_STATES = ['not_started', 'in_progress', 'passed', 'blocked'];